[WINDOWSCODECS_WINETEST] Sync with Wine Staging 3.9. CORE-14656
[reactos.git] / modules / rostests / winetests / windowscodecs / gifformat.c
1 /*
2 * Copyright 2012 Dmitry Timoshkov
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include <stdarg.h>
20 #include <stdio.h>
21
22 #define COBJMACROS
23
24 #include "windef.h"
25 #include "wincodec.h"
26 #include "wine/test.h"
27
28 HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**);
29
30 static const char gif_global_palette[] = {
31 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0xa1,0x02,0x00,
32 /* palette */0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
33 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */
34 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
35 0x02,0x02,0x44,0x01,0x00,0x3b
36 };
37
38 /* frame 0, GCE transparent index 1
39 * frame 1, GCE transparent index 2
40 */
41 static const char gif_global_palette_2frames[] = {
42 /* LSD */'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xa1,0x02,0x00,
43 /* palette */0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
44 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */
45 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
46 0x02,0x02,0x44,0x01,0x00,
47 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x02,0x00, /* index 2 */
48 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
49 0x02,0x02,0x44,0x01,0x00,0x3b
50 };
51
52 static const char gif_local_palette[] = {
53 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x27,0x02,0x00,
54 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */
55 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
56 /* palette */0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
57 0x02,0x02,0x44,0x01,0x00,0x3b
58 };
59
60 /* Generated with ImageMagick:
61 * convert -delay 100 -size 2x2 xc:red \
62 * -dispose none -page +0+0 -size 2x1 xc:white \
63 * test.gif
64 */
65 static const char gif_frame_sizes[] = {
66 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x02, 0x00,
67 0x02, 0x00, 0xf1, 0x00, 0x00, 0xff, 0x00, 0x00,
68 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
69 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64, 0x00, 0x00,
70 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45, 0x54, 0x53,
71 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e, 0x30, 0x03,
72 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
73 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x02, 0x03,
74 0x44, 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x04,
75 0x64, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
76 0x00, 0x02, 0x00, 0x01, 0x00, 0x80, 0xff, 0xff,
77 0xff, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x0a,
78 0x00, 0x3b
79 };
80
81 static IWICImagingFactory *factory;
82
83 static IStream *create_stream(const void *image_data, UINT image_size)
84 {
85 HGLOBAL hmem;
86 BYTE *data;
87 HRESULT hr;
88 IStream *stream;
89
90 hmem = GlobalAlloc(0, image_size);
91 data = GlobalLock(hmem);
92 memcpy(data, image_data, image_size);
93 GlobalUnlock(hmem);
94
95 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
96 ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
97
98 return stream;
99 }
100
101 static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size)
102 {
103 HRESULT hr;
104 IWICBitmapDecoder *decoder;
105 IStream *stream;
106 GUID format;
107 LONG refcount;
108
109 stream = create_stream(image_data, image_size);
110 if (!stream) return NULL;
111
112 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
113 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
114
115 hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
116 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
117 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
118 "wrong container format %s\n", wine_dbgstr_guid(&format));
119
120 refcount = IStream_Release(stream);
121 ok(refcount > 0, "expected stream refcount > 0\n");
122
123 return decoder;
124 }
125
126 static void test_global_gif_palette(void)
127 {
128 HRESULT hr;
129 IWICBitmapDecoder *decoder;
130 IWICBitmapFrameDecode *frame;
131 IWICPalette *palette;
132 GUID format;
133 UINT count, ret;
134 WICColor color[256];
135
136 decoder = create_decoder(gif_global_palette, sizeof(gif_global_palette));
137 ok(decoder != 0, "Failed to load GIF image data\n");
138
139 hr = IWICImagingFactory_CreatePalette(factory, &palette);
140 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
141
142 /* global palette */
143 hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
144 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
145
146 hr = IWICPalette_GetColorCount(palette, &count);
147 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
148 ok(count == 4, "expected 4, got %u\n", count);
149
150 hr = IWICPalette_GetColors(palette, count, color, &ret);
151 ok(hr == S_OK, "GetColors error %#x\n", hr);
152 ok(ret == count, "expected %u, got %u\n", count, ret);
153 ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
154 ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
155 ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
156 ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
157
158 /* frame palette */
159 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
160 ok(hr == S_OK, "GetFrame error %#x\n", hr);
161
162 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
163 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
164 ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
165 "wrong pixel format %s\n", wine_dbgstr_guid(&format));
166
167 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
168 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
169
170 hr = IWICPalette_GetColorCount(palette, &count);
171 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
172 ok(count == 4, "expected 4, got %u\n", count);
173
174 hr = IWICPalette_GetColors(palette, count, color, &ret);
175 ok(hr == S_OK, "GetColors error %#x\n", hr);
176 ok(ret == count, "expected %u, got %u\n", count, ret);
177 ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
178 ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
179 ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
180 ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
181
182 IWICPalette_Release(palette);
183 IWICBitmapFrameDecode_Release(frame);
184 IWICBitmapDecoder_Release(decoder);
185 }
186
187 static void test_global_gif_palette_2frames(void)
188 {
189 HRESULT hr;
190 IWICBitmapDecoder *decoder;
191 IWICBitmapFrameDecode *frame;
192 IWICPalette *palette;
193 GUID format;
194 UINT count, ret;
195 WICColor color[256];
196
197 decoder = create_decoder(gif_global_palette_2frames, sizeof(gif_global_palette_2frames));
198 ok(decoder != 0, "Failed to load GIF image data\n");
199
200 /* active frame 0, GCE transparent index 1 */
201 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
202 ok(hr == S_OK, "GetFrame error %#x\n", hr);
203
204 hr = IWICImagingFactory_CreatePalette(factory, &palette);
205 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
206
207 /* global palette */
208 hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
209 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
210
211 hr = IWICPalette_GetColorCount(palette, &count);
212 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
213 ok(count == 4, "expected 4, got %u\n", count);
214
215 hr = IWICPalette_GetColors(palette, count, color, &ret);
216 ok(hr == S_OK, "GetColors error %#x\n", hr);
217 ok(ret == count, "expected %u, got %u\n", count, ret);
218 ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
219 ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
220 ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
221 ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
222
223 /* frame 0 palette */
224 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
225 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
226 ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
227 "wrong pixel format %s\n", wine_dbgstr_guid(&format));
228
229 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
230 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
231
232 hr = IWICPalette_GetColorCount(palette, &count);
233 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
234 ok(count == 4, "expected 4, got %u\n", count);
235
236 hr = IWICPalette_GetColors(palette, count, color, &ret);
237 ok(hr == S_OK, "GetColors error %#x\n", hr);
238 ok(ret == count, "expected %u, got %u\n", count, ret);
239 ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
240 ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
241 ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
242 ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
243
244 IWICBitmapFrameDecode_Release(frame);
245
246 /* active frame 1, GCE transparent index 2 */
247 hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame);
248 ok(hr == S_OK, "GetFrame error %#x\n", hr);
249
250 /* global palette */
251 hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
252 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
253
254 hr = IWICPalette_GetColorCount(palette, &count);
255 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
256 ok(count == 4, "expected 4, got %u\n", count);
257
258 hr = IWICPalette_GetColors(palette, count, color, &ret);
259 ok(hr == S_OK, "GetColors error %#x\n", hr);
260 ok(ret == count, "expected %u, got %u\n", count, ret);
261 ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
262 ok(color[1] == 0xff040506 || broken(color[1] == 0x00040506) /* XP */, "expected 0xff040506, got %#x\n", color[1]);
263 ok(color[2] == 0x00070809 || broken(color[2] == 0xff070809) /* XP */, "expected 0x00070809, got %#x\n", color[2]);
264 ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
265
266 /* frame 1 palette */
267 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
268 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
269 ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
270 "wrong pixel format %s\n", wine_dbgstr_guid(&format));
271
272 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
273 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
274
275 hr = IWICPalette_GetColorCount(palette, &count);
276 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
277 ok(count == 4, "expected 4, got %u\n", count);
278
279 hr = IWICPalette_GetColors(palette, count, color, &ret);
280 ok(hr == S_OK, "GetColors error %#x\n", hr);
281 ok(ret == count, "expected %u, got %u\n", count, ret);
282 ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
283 ok(color[1] == 0xff040506, "expected 0xff040506, got %#x\n", color[1]);
284 ok(color[2] == 0x00070809, "expected 0x00070809, got %#x\n", color[2]);
285 ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
286
287 IWICPalette_Release(palette);
288 IWICBitmapFrameDecode_Release(frame);
289 IWICBitmapDecoder_Release(decoder);
290 }
291
292 static void test_local_gif_palette(void)
293 {
294 HRESULT hr;
295 IWICBitmapDecoder *decoder;
296 IWICBitmapFrameDecode *frame;
297 IWICPalette *palette;
298 WICBitmapPaletteType type;
299 GUID format;
300 UINT count, ret, i;
301 WICColor color[256];
302
303 decoder = create_decoder(gif_local_palette, sizeof(gif_local_palette));
304 ok(decoder != 0, "Failed to load GIF image data\n");
305
306 hr = IWICImagingFactory_CreatePalette(factory, &palette);
307 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
308
309 /* global palette */
310 hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
311 ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING), "CopyPalette %#x\n", hr);
312 if (hr == S_OK)
313 {
314 type = -1;
315 hr = IWICPalette_GetType(palette, &type);
316 ok(hr == S_OK, "GetType error %#x\n", hr);
317 ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
318
319 hr = IWICPalette_GetColorCount(palette, &count);
320 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
321 ok(count == 256, "expected 256, got %u\n", count);
322
323 hr = IWICPalette_GetColors(palette, count, color, &ret);
324 ok(hr == S_OK, "GetColors error %#x\n", hr);
325 ok(ret == count, "expected %u, got %u\n", count, ret);
326 ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]);
327 ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]);
328
329 for (i = 2; i < 256; i++)
330 ok(color[i] == 0xff000000, "expected 0xff000000, got %#x\n", color[i]);
331 }
332
333 /* frame palette */
334 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
335 ok(hr == S_OK, "GetFrame error %#x\n", hr);
336
337 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
338 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
339 ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
340 "wrong pixel format %s\n", wine_dbgstr_guid(&format));
341
342 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
343 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
344
345 hr = IWICPalette_GetColorCount(palette, &count);
346 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
347 ok(count == 4, "expected 4, got %u\n", count);
348
349 type = -1;
350 hr = IWICPalette_GetType(palette, &type);
351 ok(hr == S_OK, "GetType error %#x\n", hr);
352 ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
353
354 hr = IWICPalette_GetColors(palette, count, color, &ret);
355 ok(hr == S_OK, "GetColors error %#x\n", hr);
356 ok(ret == count, "expected %u, got %u\n", count, ret);
357 ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
358 ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
359 ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
360 ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
361
362 IWICPalette_Release(palette);
363 IWICBitmapFrameDecode_Release(frame);
364 IWICBitmapDecoder_Release(decoder);
365 }
366
367 static void test_gif_frame_sizes(void)
368 {
369 static const BYTE frame0[] = {0, 1, 0xfe, 0xfe, 2, 3, 0xfe, 0xfe};
370 static const BYTE frame1[] = {0, 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
371
372 IWICBitmapDecoder *decoder;
373 IWICBitmapFrameDecode *frame;
374 UINT width, height;
375 BYTE buf[8];
376 HRESULT hr;
377
378 decoder = create_decoder(gif_frame_sizes, sizeof(gif_frame_sizes));
379 ok(decoder != 0, "Failed to load GIF image data\n");
380
381 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
382 ok(hr == S_OK, "GetFrame error %#x\n", hr);
383
384 hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
385 ok(hr == S_OK, "GetSize error %x\n", hr);
386 ok(width == 2, "width = %d\n", width);
387 ok(height == 2, "height = %d\n", height);
388
389 memset(buf, 0xfe, sizeof(buf));
390 hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 4, sizeof(buf), buf);
391 ok(hr == S_OK, "CopyPixels error %x\n", hr);
392 ok(!memcmp(buf, frame0, sizeof(buf)), "buf = %x %x %x %x %x %x %x %x\n",
393 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
394
395 IWICBitmapFrameDecode_Release(frame);
396
397 hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame);
398 ok(hr == S_OK, "GetFrame error %#x\n", hr);
399
400 hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
401 ok(hr == S_OK, "GetSize error %x\n", hr);
402 ok(width == 2, "width = %d\n", width);
403 ok(height == 1, "height = %d\n", height);
404
405 memset(buf, 0xfe, sizeof(buf));
406 hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 4, sizeof(buf), buf);
407 ok(hr == S_OK, "CopyPixels error %x\n", hr);
408 ok(!memcmp(buf, frame1, sizeof(buf)), "buf = %x %x %x %x %x %x %x %x\n",
409 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
410
411 IWICBitmapFrameDecode_Release(frame);
412
413 IWICBitmapDecoder_Release(decoder);
414 }
415
416 static const char gif_with_trailer_1[] = {
417 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x80,0x00,0x00,
418 /* palette */0xff,0xff,0xff,0xff,0xff,0xff,
419 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
420 /* image data */0x02,0x02,0x44,0x01,0x00,0x3b
421 };
422 static const char gif_with_trailer_2[] = {
423 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x00,0x00,0x00,
424 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
425 /* image data */0x02,0x02,0x44,0x3b
426 };
427 static const char gif_without_trailer_1[] = {
428 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x80,0x00,0x00,
429 /* palette */0xff,0xff,0xff,0xff,0xff,0xff,
430 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
431 /* image data */0x02,0x02,0x44,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef
432 };
433
434 static const char gif_without_trailer_2[] = {
435 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x00,0x00,0x00,
436 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
437 /* image data */0x02,0x02,0x44,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef
438 };
439
440 static void test_truncated_gif(void)
441 {
442 HRESULT hr;
443 IStream *stream;
444 IWICBitmapDecoder *decoder;
445 GUID format;
446
447 stream = create_stream(gif_with_trailer_1, sizeof(gif_with_trailer_1));
448 if (!stream) return;
449
450 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
451 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
452 hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
453 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
454 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
455 "wrong container format %s\n", wine_dbgstr_guid(&format));
456 IWICBitmapDecoder_Release(decoder);
457 IStream_Release(stream);
458
459 stream = create_stream(gif_with_trailer_2, sizeof(gif_with_trailer_2));
460 if (!stream) return;
461 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
462 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
463 hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
464 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
465 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
466 "wrong container format %s\n", wine_dbgstr_guid(&format));
467 IWICBitmapDecoder_Release(decoder);
468 IStream_Release(stream);
469
470 stream = create_stream(gif_without_trailer_1, sizeof(gif_without_trailer_1));
471 if (!stream) return;
472 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
473 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
474 hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
475 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
476 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
477 "wrong container format %s\n", wine_dbgstr_guid(&format));
478 IWICBitmapDecoder_Release(decoder);
479 IStream_Release(stream);
480
481 stream = create_stream(gif_without_trailer_2, sizeof(gif_without_trailer_2));
482 if (!stream) return;
483 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
484 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
485 hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
486 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
487 ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
488 "wrong container format %s\n", wine_dbgstr_guid(&format));
489 IWICBitmapDecoder_Release(decoder);
490 IStream_Release(stream);
491 }
492
493 /* 1x1 pixel gif, missing trailer */
494 static unsigned char gifimage_notrailer[] = {
495 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x71,0xff,0xff,0xff,
496 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
497 0x01,0x00
498 };
499
500 static void test_gif_notrailer(void)
501 {
502 IWICBitmapDecoder *decoder;
503 IWICImagingFactory *factory;
504 HRESULT hr;
505 IWICStream *gifstream;
506 IWICBitmapFrameDecode *framedecode;
507 double dpiX = 0.0, dpiY = 0.0;
508 UINT framecount;
509
510 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
511 &IID_IWICImagingFactory, (void**)&factory);
512 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
513 if (FAILED(hr)) return;
514
515 hr = IWICImagingFactory_CreateStream(factory, &gifstream);
516 ok(hr == S_OK, "CreateStream failed, hr=%x\n", hr);
517 if (SUCCEEDED(hr))
518 {
519 hr = IWICStream_InitializeFromMemory(gifstream, gifimage_notrailer,
520 sizeof(gifimage_notrailer));
521 ok(hr == S_OK, "InitializeFromMemory failed, hr=%x\n", hr);
522
523 if (SUCCEEDED(hr))
524 {
525 hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER,
526 &IID_IWICBitmapDecoder, (void**)&decoder);
527 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
528 }
529
530 if (SUCCEEDED(hr))
531 {
532 hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)gifstream,
533 WICDecodeMetadataCacheOnDemand);
534 ok(hr == S_OK, "Initialize failed, hr=%x\n", hr);
535
536 if (SUCCEEDED(hr))
537 {
538 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode);
539 ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr);
540 if (SUCCEEDED(hr))
541 {
542 hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY);
543 ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr);
544 ok(dpiX == 48.0, "expected dpiX=48.0, got %f\n", dpiX);
545 ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY);
546
547 IWICBitmapFrameDecode_Release(framedecode);
548 }
549 }
550
551 if (SUCCEEDED(hr))
552 {
553 hr = IWICBitmapDecoder_GetFrameCount(decoder, &framecount);
554 ok(hr == S_OK, "GetFrameCount failed, hr=%x\n", hr);
555 ok(framecount == 1, "framecount=%u\n", framecount);
556 }
557
558 IWICBitmapDecoder_Release(decoder);
559 }
560
561 IWICStream_Release(gifstream);
562 }
563
564 IWICImagingFactory_Release(factory);
565 }
566
567 START_TEST(gifformat)
568 {
569 HRESULT hr;
570
571 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
572 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
573 &IID_IWICImagingFactory, (void **)&factory);
574 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
575 if (FAILED(hr)) return;
576
577 test_global_gif_palette();
578 test_global_gif_palette_2frames();
579 test_local_gif_palette();
580 test_gif_frame_sizes();
581 test_gif_notrailer();
582
583 IWICImagingFactory_Release(factory);
584 CoUninitialize();
585
586 /* run the same tests with no COM initialization */
587 hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
588 ok(hr == S_OK, "WICCreateImagingFactory_Proxy error %#x\n", hr);
589
590 test_global_gif_palette();
591 test_global_gif_palette_2frames();
592 test_local_gif_palette();
593 test_gif_frame_sizes();
594 test_truncated_gif();
595
596 IWICImagingFactory_Release(factory);
597 }