mirror of
https://github.com/azure-rtos/guix.git
synced 2025-02-04 07:13:17 +08:00
225 lines
5.1 KiB
C++
225 lines
5.1 KiB
C++
|
|
||
|
#include "studiox_includes.h"
|
||
|
#include "image_reader.h"
|
||
|
#include "png.h"
|
||
|
|
||
|
extern png_structp png_instance;
|
||
|
extern png_infop png_info_ptr;
|
||
|
|
||
|
gif_reader::gif_reader() : png_reader()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
gif_reader::~gif_reader()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
BOOL gif_reader::CheckImageHasAlphaChannel(CString& path)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
int gif_reader::GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
|
||
|
{
|
||
|
UINT num = 0; // number of image encoders
|
||
|
UINT size = 0; // size of the image encoder array in bytes
|
||
|
|
||
|
ImageCodecInfo* pImageCodecInfo = NULL;
|
||
|
|
||
|
GetImageEncodersSize(&num, &size);
|
||
|
if (size == 0)
|
||
|
return -1; // Failure
|
||
|
|
||
|
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
|
||
|
if (pImageCodecInfo == NULL)
|
||
|
return -1; // Failure
|
||
|
|
||
|
GetImageEncoders(num, size, pImageCodecInfo);
|
||
|
|
||
|
for (UINT j = 0; j < num; ++j)
|
||
|
{
|
||
|
if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
|
||
|
{
|
||
|
*pClsid = pImageCodecInfo[j].Clsid;
|
||
|
free(pImageCodecInfo);
|
||
|
return j; // Success
|
||
|
}
|
||
|
}
|
||
|
|
||
|
free(pImageCodecInfo);
|
||
|
return -1; // Failure
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
INT gif_reader::GetFrameCount(CString& path)
|
||
|
{
|
||
|
Image img(path);
|
||
|
|
||
|
UINT count = img.GetFrameDimensionsCount();
|
||
|
if (count < 0)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
GUID* p_dimension_ids = new GUID[count];
|
||
|
img.GetFrameDimensionsList(p_dimension_ids, count);
|
||
|
int frame_count = img.GetFrameCount(&p_dimension_ids[0]);
|
||
|
|
||
|
if (p_dimension_ids)
|
||
|
{
|
||
|
delete[]p_dimension_ids;
|
||
|
}
|
||
|
|
||
|
return frame_count;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
INT gif_reader::GetDelayTime(int frame_id)
|
||
|
{
|
||
|
if (frame_id < mDelayTimeList.GetCount())
|
||
|
{
|
||
|
return mDelayTimeList.GetAt(frame_id);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL gif_reader::ReadImage(CString& path, int frame_id)
|
||
|
{
|
||
|
Image img(path);
|
||
|
|
||
|
UINT count = img.GetFrameDimensionsCount();
|
||
|
if (count < 0)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
GUID* p_dimension_ids = new GUID[count];
|
||
|
img.GetFrameDimensionsList(p_dimension_ids, count);
|
||
|
int frame_count = img.GetFrameCount(&p_dimension_ids[0]);
|
||
|
|
||
|
CLSID pngClsid;
|
||
|
GetEncoderClsid(L"image/png", &pngClsid);
|
||
|
|
||
|
IStorage* pIStorage = NULL;
|
||
|
IStream* pIStream = NULL;
|
||
|
HRESULT hr;
|
||
|
|
||
|
hr = CoInitialize(NULL);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Create a compound file object, and get
|
||
|
// a pointer to its IStorage interface.
|
||
|
|
||
|
hr = StgCreateDocfile(
|
||
|
NULL,
|
||
|
STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
|
||
|
0,
|
||
|
&pIStorage);
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Create a stream in the compound file.
|
||
|
hr = pIStorage->CreateStream(
|
||
|
L"StreamImage",
|
||
|
STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
|
||
|
0,
|
||
|
0,
|
||
|
&pIStream);
|
||
|
}
|
||
|
|
||
|
LARGE_INTEGER dlibMove = { 0 };
|
||
|
|
||
|
BOOL result = 0;
|
||
|
palette_info palinfo;
|
||
|
|
||
|
palinfo.total_size = image_reader::GetPalSize();
|
||
|
GX_COLOR *palette = image_reader::GetPalette();
|
||
|
|
||
|
UINT buffer_size = img.GetPropertyItemSize(PropertyTagFrameDelay);
|
||
|
PropertyItem* p_item = (PropertyItem*)(new byte[buffer_size]);
|
||
|
img.GetPropertyItem(PropertyTagFrameDelay, buffer_size, p_item);
|
||
|
|
||
|
mDelayTimeList.RemoveAll();
|
||
|
int delay;
|
||
|
int start_frame;
|
||
|
int end_frame;
|
||
|
BOOL copy_palette = FALSE;
|
||
|
|
||
|
if (palette && (GetDisplayFormat() > GX_COLOR_FORMAT_8BIT_PALETTE))
|
||
|
{
|
||
|
copy_palette = TRUE;
|
||
|
}
|
||
|
|
||
|
if (frame_id >= 0 && frame_id < frame_count)
|
||
|
{
|
||
|
start_frame = frame_id;
|
||
|
end_frame = frame_id;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
start_frame = 0;
|
||
|
end_frame = frame_count - 1;
|
||
|
}
|
||
|
|
||
|
for (int index = start_frame; index <= end_frame; index++)
|
||
|
{
|
||
|
delay = ((UINT*)p_item[0].value)[index] * 10;
|
||
|
mDelayTimeList.Add(delay);
|
||
|
|
||
|
if ((index != start_frame) && copy_palette)
|
||
|
{
|
||
|
palinfo.palette = new GX_COLOR[palinfo.total_size];
|
||
|
memcpy_s(palinfo.palette, palinfo.total_size * sizeof(GX_COLOR), palette, (palinfo.total_size * sizeof(GX_COLOR)));
|
||
|
SetPalette(palinfo.palette, palinfo.total_size, palinfo.total_size);
|
||
|
}
|
||
|
|
||
|
pIStream->Seek(dlibMove, STREAM_SEEK_SET, NULL);
|
||
|
|
||
|
img.SelectActiveFrame(&p_dimension_ids[0], index);
|
||
|
img.Save(pIStream, &pngClsid);
|
||
|
|
||
|
pIStream->Seek(dlibMove, STREAM_SEEK_SET, NULL);
|
||
|
|
||
|
result += png_reader::ReadImage(pIStream);
|
||
|
}
|
||
|
|
||
|
if (p_item)
|
||
|
{
|
||
|
delete p_item;
|
||
|
}
|
||
|
|
||
|
if (pIStream)
|
||
|
{
|
||
|
pIStream->Release();
|
||
|
}
|
||
|
|
||
|
if (pIStorage)
|
||
|
{
|
||
|
pIStorage->Release();
|
||
|
}
|
||
|
|
||
|
if (p_dimension_ids)
|
||
|
{
|
||
|
delete []p_dimension_ids;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL gif_reader::ReadImage(unsigned char* data, int data_size)
|
||
|
{
|
||
|
// This route is not needed at present, return FALSE directly.
|
||
|
return FALSE;
|
||
|
}
|