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 START_TEST(gifformat)
494 {
495     HRESULT hr;
496 
497     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
498     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
499                           &IID_IWICImagingFactory, (void **)&factory);
500     ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
501     if (FAILED(hr)) return;
502 
503     test_global_gif_palette();
504     test_global_gif_palette_2frames();
505     test_local_gif_palette();
506     test_gif_frame_sizes();
507 
508     IWICImagingFactory_Release(factory);
509     CoUninitialize();
510 
511     /* run the same tests with no COM initialization */
512     hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
513     ok(hr == S_OK, "WICCreateImagingFactory_Proxy error %#x\n", hr);
514 
515     test_global_gif_palette();
516     test_global_gif_palette_2frames();
517     test_local_gif_palette();
518     test_gif_frame_sizes();
519     test_truncated_gif();
520 
521     IWICImagingFactory_Release(factory);
522 }
523