Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/graphics gif in png #1321

Open
wants to merge 14 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions DesktopEditor/cximage/CxImagePNG/CxImagePNG_Addon.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include "CxImagePNG_Addon.h"

bool CxImagePNG_Addon::GetSpecializedGIFInfo(FILE* hFile)
{
CxIOFile file(hFile);
return GetSpecializedGIFInfo(&file);
}
bool CxImagePNG_Addon::GetSpecializedGIFInfo(CxFile* hFile)
{
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (void *)NULL, NULL, NULL);
if (png_ptr == NULL) return false;

/* Allocate/initialize the memory for image information. REQUIRED. */
png_infop info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
return false;
}

/* Set error handling if you are using the setjmp/longjmp method (this is
* the normal method of doing things with libpng). REQUIRED unless you
* set up your own error handlers in the png_create_read_struct() earlier. */
if (setjmp(png_ptr->longjmp_buffer)) {
/* Free all of the memory associated with the png_ptr and info_ptr */
png_destroy_read_struct(&png_ptr, (png_infopp)&info_ptr, (png_infopp)NULL);
return false;
}

// use custom I/O functions
png_set_read_fn(png_ptr, hFile, /*(png_rw_ptr)*/user_read_data);
png_set_error_fn(png_ptr,error,/*(png_error_ptr)*/user_error_fn,NULL);

png_ptr->flags = 0x8000;

png_read_info(png_ptr, info_ptr);
uint8_t *row_pointers=NULL;
row_pointers = new uint8_t[info_ptr->rowbytes + 8];
int y = 0;
do
{
png_read_row(png_ptr, row_pointers, NULL);
y++;
} while(y < png_ptr->height);

png_read_end(png_ptr, info_ptr);

for (png_size_t i = 0; i < info_ptr->unknown_chunks_num; i++)
{
if(!strncmp("MSOFFICE9.0", (const char*)info_ptr->unknown_chunks[i].data, 11))
{
png_size_t length = info_ptr->unknown_chunks[i].size - 11;
png_int_32 gif_terminator = -1;
png_bytep data = (png_bytep)png_malloc(png_ptr, length + 1);

memcpy(data, info_ptr->unknown_chunks[i].data + 11, length);
data[length] = 0x00;
png_free(png_ptr, info_ptr->unknown_chunks[i].data);

for (int iter = 0; iter < length; iter++)
{
if (data[iter] == 0x3B)
{
gif_terminator = iter;
}
}

if (gif_terminator == -1)
{
png_free(png_ptr, data);
data = NULL;
strcpy(error, "No terminator in GIF imformation chunk");
return false;
}

data[gif_terminator + 1] = 0x00;
image_data_size = gif_terminator + 1;
image_data = (BYTE*)malloc(image_data_size);
memcpy(image_data, data, image_data_size);

png_free(png_ptr, data);
data = NULL;

return true;
} else {
png_free(png_ptr, info_ptr->unknown_chunks[i].data);
}
}

strcpy(error, "No GIF information chunk");
return false;
}
19 changes: 19 additions & 0 deletions DesktopEditor/cximage/CxImagePNG/CxImagePNG_Addon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef CXIMAGEPNG_ADDON_H
#define CXIMAGEPNG_ADDON_H


#include "CxImage_Addon.h"
#include "../../graphics/Image.h"
#include "../CxImage/ximapng.h"

class CxImagePNG_Addon: public CxImage_Addon, public CxImagePNG
{
public:
CxImagePNG_Addon(): CxImage_Addon() {}

bool GetSpecializedGIFInfo(FILE* hFile);
bool GetSpecializedGIFInfo(CxFile* hFile);
};


#endif // CXIMAGEPNG_ADDON_H
67 changes: 67 additions & 0 deletions DesktopEditor/cximage/CxImagePNG/CxImage_Addon.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "CxImage_Addon.h"
#include "CxImagePNG_Addon.h"

CxImage_Addon::CxImage_Addon()
{
image_data = NULL;
image_data_size = 0;
}

CxImage_Addon::~CxImage_Addon()
{
if(image_data != NULL)
{
free(image_data);
}
}

BYTE* CxImage_Addon::GetData() { return image_data; }
size_t CxImage_Addon::GetDataSize() const { return image_data_size; }
const char* CxImage_Addon::GetError() { return error; }

bool CxImage_Addon::GetSpecializedGIFInfo(FILE* hFile, uint32_t imagetype)
{
CxIOFile file(hFile);
return GetSpecializedGIFInfo(&file, imagetype);
}
bool CxImage_Addon::GetSpecializedGIFInfo(CxFile* hFile, uint32_t imagetype)
{
if (hFile == NULL){
strcpy(error,CXIMAGE_ERR_NOFILE);
return false;
}

uint32_t pos = hFile->Tell();

#ifdef CXIMAGE_SUPPORT_PNG
if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_PNG==imagetype){
CxImagePNG_Addon* newima = new CxImagePNG_Addon();
if (!newima)
return false;
if (newima->GetSpecializedGIFInfo(hFile))
{
Transfer(*newima);
delete newima;
return true;
} else {
strcpy(error, newima->GetError());
hFile->Seek(pos,SEEK_SET);
delete newima;
if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
return false;
}
}
#endif

strcpy(error, "GetInfo: Unknown wrong format");
return false;
}

void CxImage_Addon::Transfer(CxImage_Addon& from)
{
image_data_size = from.GetDataSize();
image_data = (BYTE*)malloc(image_data_size);

memcpy(image_data, from.GetData(), image_data_size);
strcpy(error, from.GetError());
}
26 changes: 26 additions & 0 deletions DesktopEditor/cximage/CxImagePNG/CxImage_Addon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef CXIMAGE_ADDON_H
#define CXIMAGE_ADDON_H

#include "../CxImage/ximage.h"
#include "../../graphics/Image.h"

class CxImage_Addon
{
public:
CxImage_Addon();
virtual ~CxImage_Addon();

BYTE* GetData();
size_t GetDataSize() const;
const char* GetError();
bool GetSpecializedGIFInfo(FILE* hFile, uint32_t imagetype);
bool GetSpecializedGIFInfo(CxFile* hFile, uint32_t imagetype);
void Transfer(CxImage_Addon& from);

protected:
BYTE* image_data;
size_t image_data_size;
char error[256];
};

#endif // CXIMAGE_ADDON_H
12 changes: 12 additions & 0 deletions DesktopEditor/graphics/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ namespace Aggplus
m_Status = Ok;
}

bool CImage::GetInsideFrom(const std::wstring &file_inp, const std::wstring &file_out)
{
Destroy();

CBgraFrame oFrame;

if (oFrame.GetSpecializedGIFInfo(file_inp))
return oFrame.SaveGetInsideFromFile(file_out);

return false;
}

bool CImage::SaveFile(const std::wstring& strFileName, UINT nFileType)
{
CBgraFrame oBgraFrame;
Expand Down
1 change: 1 addition & 0 deletions DesktopEditor/graphics/Image.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class GRAPHICS_DECL CImage : public IGrObject
void Create(const std::wstring& filename);
void Create(BYTE* pImgData, const DWORD& dwWidth, const DWORD& dwHeight, const long& nStride, bool bExternalBuffer = false);
void Decode(BYTE *pBuffer, unsigned int unSize);
bool GetInsideFrom(const std::wstring& file_inp, const std::wstring& file_out);
bool SaveFile(const std::wstring& strFileName, UINT nFileType);
void Destroy();

Expand Down
38 changes: 38 additions & 0 deletions DesktopEditor/graphics/tests/GifInPmgTest/GifInPmgTest.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#CONFIG += c++11 cmdline

#SOURCES += \
QT -= core

QT -= gui

TARGET = test
CONFIG += console
TEMPLATE = app

CORE_ROOT_DIR = $$PWD/../../../..
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)

ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)

GRAPHICS_AGG_PATH = $$PWD/../../../agg-2.4

INCLUDEPATH += \
$$GRAPHICS_AGG_PATH/include \
C:/Users/mrkir/core/DesktopEditor/cximage/zlib \
C:/Users/mrkir/core/OfficeUtils/src

SOURCES += main.cpp

DESTDIR = $$PWD_ROOT_DIR/build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX

DISTFILES += \
../../../../build/lib/win_64/debug/kernel.dll \
../../../../build/lib/win_64/debug/kernel.lib \
image1.png \
test.txt

SUBDIRS += \
../../pro/graphics.pro

67 changes: 67 additions & 0 deletions DesktopEditor/graphics/tests/GifInPmgTest/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include <fstream>
#include <stdio.h>
#include <iostream>
#include "../../pro/Graphics.h"
#include "../../Image.h"
#include "../../../raster/ImageFileFormatChecker.h"
#include "../../../common/File.h"
#include "../../../cximage/png/png.h"
#include "../../../cximage/CxImage/xiofile.h"
#include "../../../cximage/CxImage/ximapng.h"

void PNGAPI user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr);
if (hFile == NULL || hFile->Read(data,1,length) != length)
png_error(png_ptr, "Read Error");
}

int main(int argc, char *argv[])
{
std::string filepath = "C:\\Users\\mrkir\\core\\DesktopEditor\\graphics\\tests\\GifInPmgTest\\new.png";

std::FILE* hfile;
int err = fopen_s(&hfile, filepath.c_str(), "rb");
if (err != 0)
{
return -1;
}

png_struct * png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (png_ptr == NULL)
return -1;

png_info * png_info_ptr = png_create_info_struct(png_ptr);
if (png_info_ptr == NULL)
{
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
return -1;
}

if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
return -1;
}

png_set_sig_bytes(png_ptr, 8);
png_set_read_fn(png_ptr, hfile, user_read_data);

png_read_info(png_ptr, png_info_ptr);


std::string data = "heignt = " + std::to_string(png_get_image_height(png_ptr, png_info_ptr)) + '\n' + "widht = " +
std::to_string(png_get_image_width(png_ptr, png_info_ptr)) + '\n' + "color type = " +
std::to_string(png_get_color_type(png_ptr, png_info_ptr));

png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
fclose(hfile);


NSFile::CFileBinary Fres;
Fres.CreateFile(L"res.txt");
Fres.WriteFile(data.c_str(), data.size());
Fres.CloseFile();

return 0;
}
Loading