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 "precomp.h"
20 
21 HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**);
22 
23 static const char gif_global_palette[] = {
24 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0xa1,0x02,0x00,
25 /* palette */0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
26 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */
27 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
28 0x02,0x02,0x44,0x01,0x00,0x3b
29 };
30 
31 /* frame 0, GCE transparent index 1
32  * frame 1, GCE transparent index 2
33  */
34 static const char gif_global_palette_2frames[] = {
35 /* LSD */'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xa1,0x02,0x00,
36 /* palette */0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
37 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */
38 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
39 0x02,0x02,0x44,0x01,0x00,
40 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x02,0x00, /* index 2 */
41 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
42 0x02,0x02,0x44,0x01,0x00,0x3b
43 };
44 
45 static const char gif_local_palette[] = {
46 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x27,0x02,0x00,
47 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */
48 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
49 /* palette */0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
50 0x02,0x02,0x44,0x01,0x00,0x3b
51 };
52 
53 /* Generated with ImageMagick:
54  * convert -delay 100 -size 2x2 xc:red \
55  *     -dispose none -page +0+0 -size 2x1 xc:white \
56  *     test.gif
57  */
58 static const char gif_frame_sizes[] = {
59     0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x02, 0x00,
60     0x02, 0x00, 0xf1, 0x00, 0x00, 0xff, 0x00, 0x00,
61     0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
62     0x00, 0x21, 0xf9, 0x04, 0x00, 0x64, 0x00, 0x00,
63     0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45, 0x54, 0x53,
64     0x43, 0x41, 0x50, 0x45, 0x32, 0x2e, 0x30, 0x03,
65     0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
66     0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x02, 0x03,
67     0x44, 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x04,
68     0x64, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
69     0x00, 0x02, 0x00, 0x01, 0x00, 0x80, 0xff, 0xff,
70     0xff, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x0a,
71     0x00, 0x3b
72 };
73 
74 static IWICImagingFactory *factory;
75 
76 static IStream *create_stream(const void *image_data, UINT image_size)
77 {
78     HGLOBAL hmem;
79     BYTE *data;
80     HRESULT hr;
81     IStream *stream;
82 
83     hmem = GlobalAlloc(0, image_size);
84     data = GlobalLock(hmem);
85     memcpy(data, image_data, image_size);
86     GlobalUnlock(hmem);
87 
88     hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
89     ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
90 
91     return stream;
92 }
93 
94 static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size)
95 {
96     HRESULT hr;
97     IWICBitmapDecoder *decoder;
98     IStream *stream;
99     GUID format;
100     LONG refcount;
101 
102     stream = create_stream(image_data, image_size);
103     if (!stream) return NULL;
104 
105     hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
106     ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
107 
108     hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
109     ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
110     ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
111        "wrong container format %s\n", wine_dbgstr_guid(&format));
112 
113     refcount = IStream_Release(stream);
114     ok(refcount > 0, "expected stream refcount > 0\n");
115 
116     return decoder;
117 }
118 
119 static void test_global_gif_palette(void)
120 {
121     HRESULT hr;
122     IWICBitmapDecoder *decoder;
123     IWICBitmapFrameDecode *frame;
124     IWICPalette *palette;
125     GUID format;
126     UINT count, ret;
127     WICColor color[256];
128 
129     decoder = create_decoder(gif_global_palette, sizeof(gif_global_palette));
130     ok(decoder != 0, "Failed to load GIF image data\n");
131 
132     hr = IWICImagingFactory_CreatePalette(factory, &palette);
133     ok(hr == S_OK, "CreatePalette error %#x\n", hr);
134 
135     /* global palette */
136     hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
137     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
138 
139     hr = IWICPalette_GetColorCount(palette, &count);
140     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
141     ok(count == 4, "expected 4, got %u\n", count);
142 
143     hr = IWICPalette_GetColors(palette, count, color, &ret);
144     ok(hr == S_OK, "GetColors error %#x\n", hr);
145     ok(ret == count, "expected %u, got %u\n", count, ret);
146     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
147     ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
148     ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
149     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
150 
151     /* frame palette */
152     hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
153     ok(hr == S_OK, "GetFrame error %#x\n", hr);
154 
155     hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
156     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
157     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
158        "wrong pixel format %s\n", wine_dbgstr_guid(&format));
159 
160     hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
161     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
162 
163     hr = IWICPalette_GetColorCount(palette, &count);
164     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
165     ok(count == 4, "expected 4, got %u\n", count);
166 
167     hr = IWICPalette_GetColors(palette, count, color, &ret);
168     ok(hr == S_OK, "GetColors error %#x\n", hr);
169     ok(ret == count, "expected %u, got %u\n", count, ret);
170     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
171     ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
172     ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
173     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
174 
175     IWICPalette_Release(palette);
176     IWICBitmapFrameDecode_Release(frame);
177     IWICBitmapDecoder_Release(decoder);
178 }
179 
180 static void test_global_gif_palette_2frames(void)
181 {
182     HRESULT hr;
183     IWICBitmapDecoder *decoder;
184     IWICBitmapFrameDecode *frame;
185     IWICPalette *palette;
186     GUID format;
187     UINT count, ret;
188     WICColor color[256];
189 
190     decoder = create_decoder(gif_global_palette_2frames, sizeof(gif_global_palette_2frames));
191     ok(decoder != 0, "Failed to load GIF image data\n");
192 
193     /* active frame 0, GCE transparent index 1 */
194     hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
195     ok(hr == S_OK, "GetFrame error %#x\n", hr);
196 
197     hr = IWICImagingFactory_CreatePalette(factory, &palette);
198     ok(hr == S_OK, "CreatePalette error %#x\n", hr);
199 
200     /* global palette */
201     hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
202     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
203 
204     hr = IWICPalette_GetColorCount(palette, &count);
205     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
206     ok(count == 4, "expected 4, got %u\n", count);
207 
208     hr = IWICPalette_GetColors(palette, count, color, &ret);
209     ok(hr == S_OK, "GetColors error %#x\n", hr);
210     ok(ret == count, "expected %u, got %u\n", count, ret);
211     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
212     ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
213     ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
214     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
215 
216     /* frame 0 palette */
217     hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
218     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
219     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
220        "wrong pixel format %s\n", wine_dbgstr_guid(&format));
221 
222     hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
223     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
224 
225     hr = IWICPalette_GetColorCount(palette, &count);
226     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
227     ok(count == 4, "expected 4, got %u\n", count);
228 
229     hr = IWICPalette_GetColors(palette, count, color, &ret);
230     ok(hr == S_OK, "GetColors error %#x\n", hr);
231     ok(ret == count, "expected %u, got %u\n", count, ret);
232     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
233     ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
234     ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
235     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
236 
237     IWICBitmapFrameDecode_Release(frame);
238 
239     /* active frame 1, GCE transparent index 2 */
240     hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame);
241     ok(hr == S_OK, "GetFrame error %#x\n", hr);
242 
243     /* global palette */
244     hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
245     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
246 
247     hr = IWICPalette_GetColorCount(palette, &count);
248     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
249     ok(count == 4, "expected 4, got %u\n", count);
250 
251     hr = IWICPalette_GetColors(palette, count, color, &ret);
252     ok(hr == S_OK, "GetColors error %#x\n", hr);
253     ok(ret == count, "expected %u, got %u\n", count, ret);
254     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
255     ok(color[1] == 0xff040506 || broken(color[1] == 0x00040506) /* XP */, "expected 0xff040506, got %#x\n", color[1]);
256     ok(color[2] == 0x00070809 || broken(color[2] == 0xff070809) /* XP */, "expected 0x00070809, got %#x\n", color[2]);
257     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
258 
259     /* frame 1 palette */
260     hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
261     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
262     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
263        "wrong pixel format %s\n", wine_dbgstr_guid(&format));
264 
265     hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
266     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
267 
268     hr = IWICPalette_GetColorCount(palette, &count);
269     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
270     ok(count == 4, "expected 4, got %u\n", count);
271 
272     hr = IWICPalette_GetColors(palette, count, color, &ret);
273     ok(hr == S_OK, "GetColors error %#x\n", hr);
274     ok(ret == count, "expected %u, got %u\n", count, ret);
275     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
276     ok(color[1] == 0xff040506, "expected 0xff040506, got %#x\n", color[1]);
277     ok(color[2] == 0x00070809, "expected 0x00070809, got %#x\n", color[2]);
278     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
279 
280     IWICPalette_Release(palette);
281     IWICBitmapFrameDecode_Release(frame);
282     IWICBitmapDecoder_Release(decoder);
283 }
284 
285 static void test_local_gif_palette(void)
286 {
287     HRESULT hr;
288     IWICBitmapDecoder *decoder;
289     IWICBitmapFrameDecode *frame;
290     IWICPalette *palette;
291     WICBitmapPaletteType type;
292     GUID format;
293     UINT count, ret, i;
294     WICColor color[256];
295 
296     decoder = create_decoder(gif_local_palette, sizeof(gif_local_palette));
297     ok(decoder != 0, "Failed to load GIF image data\n");
298 
299     hr = IWICImagingFactory_CreatePalette(factory, &palette);
300     ok(hr == S_OK, "CreatePalette error %#x\n", hr);
301 
302     /* global palette */
303     hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
304     ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING), "CopyPalette %#x\n", hr);
305     if (hr == S_OK)
306     {
307         type = -1;
308         hr = IWICPalette_GetType(palette, &type);
309         ok(hr == S_OK, "GetType error %#x\n", hr);
310         ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
311 
312         hr = IWICPalette_GetColorCount(palette, &count);
313         ok(hr == S_OK, "GetColorCount error %#x\n", hr);
314         ok(count == 256, "expected 256, got %u\n", count);
315 
316         hr = IWICPalette_GetColors(palette, count, color, &ret);
317         ok(hr == S_OK, "GetColors error %#x\n", hr);
318         ok(ret == count, "expected %u, got %u\n", count, ret);
319         ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]);
320         ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]);
321 
322         for (i = 2; i < 256; i++)
323             ok(color[i] == 0xff000000, "expected 0xff000000, got %#x\n", color[i]);
324     }
325 
326     /* frame palette */
327     hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
328     ok(hr == S_OK, "GetFrame error %#x\n", hr);
329 
330     hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
331     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
332     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
333        "wrong pixel format %s\n", wine_dbgstr_guid(&format));
334 
335     hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
336     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
337 
338     hr = IWICPalette_GetColorCount(palette, &count);
339     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
340     ok(count == 4, "expected 4, got %u\n", count);
341 
342     type = -1;
343     hr = IWICPalette_GetType(palette, &type);
344     ok(hr == S_OK, "GetType error %#x\n", hr);
345     ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
346 
347     hr = IWICPalette_GetColors(palette, count, color, &ret);
348     ok(hr == S_OK, "GetColors error %#x\n", hr);
349     ok(ret == count, "expected %u, got %u\n", count, ret);
350     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
351     ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
352     ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
353     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
354 
355     IWICPalette_Release(palette);
356     IWICBitmapFrameDecode_Release(frame);
357     IWICBitmapDecoder_Release(decoder);
358 }
359 
360 static void test_gif_frame_sizes(void)
361 {
362     static const BYTE frame0[] = {0, 1, 0xfe, 0xfe, 2, 3, 0xfe, 0xfe};
363     static const BYTE frame1[] = {0, 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
364 
365     IWICBitmapDecoder *decoder;
366     IWICBitmapFrameDecode *frame;
367     UINT width, height;
368     BYTE buf[8];
369     HRESULT hr;
370 
371     decoder = create_decoder(gif_frame_sizes, sizeof(gif_frame_sizes));
372     ok(decoder != 0, "Failed to load GIF image data\n");
373 
374     hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
375     ok(hr == S_OK, "GetFrame error %#x\n", hr);
376 
377     hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
378     ok(hr == S_OK, "GetSize error %x\n", hr);
379     ok(width == 2, "width = %d\n", width);
380     ok(height == 2, "height = %d\n", height);
381 
382     memset(buf, 0xfe, sizeof(buf));
383     hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 4, sizeof(buf), buf);
384     ok(hr == S_OK, "CopyPixels error %x\n", hr);
385     ok(!memcmp(buf, frame0, sizeof(buf)), "buf = %x %x %x %x %x %x %x %x\n",
386             buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
387 
388     IWICBitmapFrameDecode_Release(frame);
389 
390     hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame);
391     ok(hr == S_OK, "GetFrame error %#x\n", hr);
392 
393     hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
394     ok(hr == S_OK, "GetSize error %x\n", hr);
395     ok(width == 2, "width = %d\n", width);
396     ok(height == 1, "height = %d\n", height);
397 
398     memset(buf, 0xfe, sizeof(buf));
399     hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 4, sizeof(buf), buf);
400     ok(hr == S_OK, "CopyPixels error %x\n", hr);
401     ok(!memcmp(buf, frame1, sizeof(buf)), "buf = %x %x %x %x %x %x %x %x\n",
402             buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
403 
404     IWICBitmapFrameDecode_Release(frame);
405 
406     IWICBitmapDecoder_Release(decoder);
407 }
408 
409 static const char gif_with_trailer_1[] = {
410 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x80,0x00,0x00,
411 /* palette */0xff,0xff,0xff,0xff,0xff,0xff,
412 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
413 /* image data */0x02,0x02,0x44,0x01,0x00,0x3b
414 };
415 static const char gif_with_trailer_2[] = {
416 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x00,0x00,0x00,
417 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
418 /* image data */0x02,0x02,0x44,0x3b
419 };
420 static const char gif_without_trailer_1[] = {
421 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x80,0x00,0x00,
422 /* palette */0xff,0xff,0xff,0xff,0xff,0xff,
423 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
424 /* image data */0x02,0x02,0x44,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef
425 };
426 
427 static const char gif_without_trailer_2[] = {
428 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x00,0x00,0x00,
429 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
430 /* image data */0x02,0x02,0x44,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef
431 };
432 
433 static void test_truncated_gif(void)
434 {
435     HRESULT hr;
436     IStream *stream;
437     IWICBitmapDecoder *decoder;
438     GUID format;
439 
440     stream = create_stream(gif_with_trailer_1, sizeof(gif_with_trailer_1));
441     if (!stream) return;
442 
443     hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
444     ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
445     hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
446     ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
447     ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
448        "wrong container format %s\n", wine_dbgstr_guid(&format));
449     IWICBitmapDecoder_Release(decoder);
450     IStream_Release(stream);
451 
452     stream = create_stream(gif_with_trailer_2, sizeof(gif_with_trailer_2));
453     if (!stream) return;
454     hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
455     ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
456     hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
457     ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
458     ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
459        "wrong container format %s\n", wine_dbgstr_guid(&format));
460     IWICBitmapDecoder_Release(decoder);
461     IStream_Release(stream);
462 
463     stream = create_stream(gif_without_trailer_1, sizeof(gif_without_trailer_1));
464     if (!stream) return;
465     hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
466     ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
467     hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
468     ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
469     ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
470        "wrong container format %s\n", wine_dbgstr_guid(&format));
471     IWICBitmapDecoder_Release(decoder);
472     IStream_Release(stream);
473 
474     stream = create_stream(gif_without_trailer_2, sizeof(gif_without_trailer_2));
475     if (!stream) return;
476     hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
477     ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
478     hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
479     ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
480     ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
481        "wrong container format %s\n", wine_dbgstr_guid(&format));
482     IWICBitmapDecoder_Release(decoder);
483     IStream_Release(stream);
484 }
485 
486 START_TEST(gifformat)
487 {
488     HRESULT hr;
489 
490     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
491     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
492                           &IID_IWICImagingFactory, (void **)&factory);
493     ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
494     if (FAILED(hr)) return;
495 
496     test_global_gif_palette();
497     test_global_gif_palette_2frames();
498     test_local_gif_palette();
499     test_gif_frame_sizes();
500 
501     IWICImagingFactory_Release(factory);
502     CoUninitialize();
503 
504     /* run the same tests with no COM initialization */
505     hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
506     ok(hr == S_OK, "WICCreateImagingFactory_Proxy error %#x\n", hr);
507 
508     test_global_gif_palette();
509     test_global_gif_palette_2frames();
510     test_local_gif_palette();
511     test_gif_frame_sizes();
512     test_truncated_gif();
513 
514     IWICImagingFactory_Release(factory);
515 }
516