1
2 #include "studiox_includes.h"
3 #include "image_reader.h"
4 #include "png.h"
5
6 extern png_structp png_instance;
7 extern png_infop png_info_ptr;
8
gif_reader()9 gif_reader::gif_reader() : png_reader()
10 {
11 }
12
~gif_reader()13 gif_reader::~gif_reader()
14 {
15 }
16
CheckImageHasAlphaChannel(CString & path)17 BOOL gif_reader::CheckImageHasAlphaChannel(CString& path)
18 {
19 return FALSE;
20 }
21
GetEncoderClsid(const WCHAR * format,CLSID * pClsid)22 int gif_reader::GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
23 {
24 UINT num = 0; // number of image encoders
25 UINT size = 0; // size of the image encoder array in bytes
26
27 ImageCodecInfo* pImageCodecInfo = NULL;
28
29 GetImageEncodersSize(&num, &size);
30 if (size == 0)
31 return -1; // Failure
32
33 pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
34 if (pImageCodecInfo == NULL)
35 return -1; // Failure
36
37 GetImageEncoders(num, size, pImageCodecInfo);
38
39 for (UINT j = 0; j < num; ++j)
40 {
41 if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
42 {
43 *pClsid = pImageCodecInfo[j].Clsid;
44 free(pImageCodecInfo);
45 return j; // Success
46 }
47 }
48
49 free(pImageCodecInfo);
50 return -1; // Failure
51 }
52
53 ///////////////////////////////////////////////////////////////////////////////
GetFrameCount(CString & path)54 INT gif_reader::GetFrameCount(CString& path)
55 {
56 Image img(path);
57
58 UINT count = img.GetFrameDimensionsCount();
59 if (count < 0)
60 {
61 return FALSE;
62 }
63
64 GUID* p_dimension_ids = new GUID[count];
65 img.GetFrameDimensionsList(p_dimension_ids, count);
66 int frame_count = img.GetFrameCount(&p_dimension_ids[0]);
67
68 if (p_dimension_ids)
69 {
70 delete[]p_dimension_ids;
71 }
72
73 return frame_count;
74 }
75
76 ///////////////////////////////////////////////////////////////////////////////
GetDelayTime(int frame_id)77 INT gif_reader::GetDelayTime(int frame_id)
78 {
79 if (frame_id < mDelayTimeList.GetCount())
80 {
81 return mDelayTimeList.GetAt(frame_id);
82 }
83 else
84 {
85 return 0;
86 }
87 }
88
89 ///////////////////////////////////////////////////////////////////////////////
ReadImage(CString & path,int frame_id)90 BOOL gif_reader::ReadImage(CString& path, int frame_id)
91 {
92 Image img(path);
93
94 UINT count = img.GetFrameDimensionsCount();
95 if (count < 0)
96 {
97 return FALSE;
98 }
99
100 GUID* p_dimension_ids = new GUID[count];
101 img.GetFrameDimensionsList(p_dimension_ids, count);
102 int frame_count = img.GetFrameCount(&p_dimension_ids[0]);
103
104 CLSID pngClsid;
105 GetEncoderClsid(L"image/png", &pngClsid);
106
107 IStorage* pIStorage = NULL;
108 IStream* pIStream = NULL;
109 HRESULT hr;
110
111 hr = CoInitialize(NULL);
112
113 if (FAILED(hr))
114 {
115 return FALSE;
116 }
117
118 if (SUCCEEDED(hr))
119 {
120 // Create a compound file object, and get
121 // a pointer to its IStorage interface.
122
123 hr = StgCreateDocfile(
124 NULL,
125 STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
126 0,
127 &pIStorage);
128 }
129
130 if (SUCCEEDED(hr))
131 {
132 // Create a stream in the compound file.
133 hr = pIStorage->CreateStream(
134 L"StreamImage",
135 STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
136 0,
137 0,
138 &pIStream);
139 }
140
141 LARGE_INTEGER dlibMove = { 0 };
142
143 BOOL result = 0;
144 palette_info palinfo;
145
146 palinfo.total_size = image_reader::GetPalSize();
147 GX_COLOR *palette = image_reader::GetPalette();
148
149 UINT buffer_size = img.GetPropertyItemSize(PropertyTagFrameDelay);
150 PropertyItem* p_item = (PropertyItem*)(new byte[buffer_size]);
151 img.GetPropertyItem(PropertyTagFrameDelay, buffer_size, p_item);
152
153 mDelayTimeList.RemoveAll();
154 int delay;
155 int start_frame;
156 int end_frame;
157 BOOL copy_palette = FALSE;
158
159 if (palette && (GetDisplayFormat() > GX_COLOR_FORMAT_8BIT_PALETTE))
160 {
161 copy_palette = TRUE;
162 }
163
164 if (frame_id >= 0 && frame_id < frame_count)
165 {
166 start_frame = frame_id;
167 end_frame = frame_id;
168 }
169 else
170 {
171 start_frame = 0;
172 end_frame = frame_count - 1;
173 }
174
175 for (int index = start_frame; index <= end_frame; index++)
176 {
177 delay = ((UINT*)p_item[0].value)[index] * 10;
178 mDelayTimeList.Add(delay);
179
180 if ((index != start_frame) && copy_palette)
181 {
182 palinfo.palette = new GX_COLOR[palinfo.total_size];
183 memcpy_s(palinfo.palette, palinfo.total_size * sizeof(GX_COLOR), palette, (palinfo.total_size * sizeof(GX_COLOR)));
184 SetPalette(palinfo.palette, palinfo.total_size, palinfo.total_size);
185 }
186
187 pIStream->Seek(dlibMove, STREAM_SEEK_SET, NULL);
188
189 img.SelectActiveFrame(&p_dimension_ids[0], index);
190 img.Save(pIStream, &pngClsid);
191
192 pIStream->Seek(dlibMove, STREAM_SEEK_SET, NULL);
193
194 result += png_reader::ReadImage(pIStream);
195 }
196
197 if (p_item)
198 {
199 delete p_item;
200 }
201
202 if (pIStream)
203 {
204 pIStream->Release();
205 }
206
207 if (pIStorage)
208 {
209 pIStorage->Release();
210 }
211
212 if (p_dimension_ids)
213 {
214 delete []p_dimension_ids;
215 }
216
217 return result;
218 }
219
220 ///////////////////////////////////////////////////////////////////////////////
ReadImage(unsigned char * data,int data_size)221 BOOL gif_reader::ReadImage(unsigned char* data, int data_size)
222 {
223 // This route is not needed at present, return FALSE directly.
224 return FALSE;
225 }