windowscodecs: Add a test for CreateBitmapFromHBITMAP.
[wine] / dlls / windowscodecs / tests / 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 static const char gif_global_palette[] = {
29 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0xa1,0x02,0x00,
30 /* palette */0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
31 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */
32 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
33 0x02,0x02,0x44,0x01,0x00,0x3b
34 };
35
36 /* frame 0, GCE transparent index 1
37  * frame 1, GCE transparent index 2
38  */
39 static const char gif_global_palette_2frames[] = {
40 /* LSD */'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xa1,0x02,0x00,
41 /* palette */0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
42 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */
43 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
44 0x02,0x02,0x44,0x01,0x00,
45 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x02,0x00, /* index 2 */
46 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
47 0x02,0x02,0x44,0x01,0x00,0x3b
48 };
49
50 static const char gif_local_palette[] = {
51 /* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x27,0x02,0x00,
52 /* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */
53 /* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
54 /* palette */0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
55 0x02,0x02,0x44,0x01,0x00,0x3b
56 };
57
58 static IWICImagingFactory *factory;
59
60 static const char *debugstr_guid(const GUID *guid)
61 {
62     static char buf[50];
63
64     if (!guid) return "(null)";
65     sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
66             guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
67             guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
68             guid->Data4[5], guid->Data4[6], guid->Data4[7]);
69     return buf;
70 }
71
72 static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size)
73 {
74     HGLOBAL hmem;
75     BYTE *data;
76     HRESULT hr;
77     IWICBitmapDecoder *decoder = NULL;
78     IStream *stream;
79     GUID format;
80
81     hmem = GlobalAlloc(0, image_size);
82     data = GlobalLock(hmem);
83     memcpy(data, image_data, image_size);
84     GlobalUnlock(hmem);
85
86     hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
87     ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
88
89     hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
90     ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
91
92     hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format);
93     ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
94     ok(IsEqualGUID(&format, &GUID_ContainerFormatGif),
95        "wrong container format %s\n", debugstr_guid(&format));
96
97     IStream_Release(stream);
98
99     return decoder;
100 }
101
102 static void test_global_gif_palette(void)
103 {
104     HRESULT hr;
105     IWICBitmapDecoder *decoder;
106     IWICBitmapFrameDecode *frame;
107     IWICPalette *palette;
108     GUID format;
109     UINT count, ret;
110     WICColor color[256];
111
112     decoder = create_decoder(gif_global_palette, sizeof(gif_global_palette));
113     ok(decoder != 0, "Failed to load GIF image data\n");
114
115     hr = IWICImagingFactory_CreatePalette(factory, &palette);
116     ok(hr == S_OK, "CreatePalette error %#x\n", hr);
117
118     /* global palette */
119     hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
120     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
121
122     hr = IWICPalette_GetColorCount(palette, &count);
123     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
124     ok(count == 4, "expected 4, got %u\n", count);
125
126     hr = IWICPalette_GetColors(palette, count, color, &ret);
127     ok(hr == S_OK, "GetColors error %#x\n", hr);
128     ok(ret == count, "expected %u, got %u\n", count, ret);
129     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
130     ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
131     ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
132     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
133
134     /* frame palette */
135     hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
136     ok(hr == S_OK, "GetFrame error %#x\n", hr);
137
138     hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
139     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
140     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
141        "wrong pixel format %s\n", debugstr_guid(&format));
142
143     hr = IWICBitmapFrameDecode_CopyPalette(frame, 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     IWICPalette_Release(palette);
159     IWICBitmapFrameDecode_Release(frame);
160     IWICBitmapDecoder_Release(decoder);
161 }
162
163 static void test_global_gif_palette_2frames(void)
164 {
165     HRESULT hr;
166     IWICBitmapDecoder *decoder;
167     IWICBitmapFrameDecode *frame;
168     IWICPalette *palette;
169     GUID format;
170     UINT count, ret;
171     WICColor color[256];
172
173     decoder = create_decoder(gif_global_palette_2frames, sizeof(gif_global_palette_2frames));
174     ok(decoder != 0, "Failed to load GIF image data\n");
175
176     /* active frame 0, GCE transparent index 1 */
177     hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
178     ok(hr == S_OK, "GetFrame error %#x\n", hr);
179
180     hr = IWICImagingFactory_CreatePalette(factory, &palette);
181     ok(hr == S_OK, "CreatePalette error %#x\n", hr);
182
183     /* global palette */
184     hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
185     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
186
187     hr = IWICPalette_GetColorCount(palette, &count);
188     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
189     ok(count == 4, "expected 4, got %u\n", count);
190
191     hr = IWICPalette_GetColors(palette, count, color, &ret);
192     ok(hr == S_OK, "GetColors error %#x\n", hr);
193     ok(ret == count, "expected %u, got %u\n", count, ret);
194     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
195     ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
196     ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
197     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
198
199     /* frame 0 palette */
200     hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
201     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
202     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
203        "wrong pixel format %s\n", debugstr_guid(&format));
204
205     hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
206     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
207
208     hr = IWICPalette_GetColorCount(palette, &count);
209     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
210     ok(count == 4, "expected 4, got %u\n", count);
211
212     hr = IWICPalette_GetColors(palette, count, color, &ret);
213     ok(hr == S_OK, "GetColors error %#x\n", hr);
214     ok(ret == count, "expected %u, got %u\n", count, ret);
215     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
216     ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
217     ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
218     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
219
220     IWICBitmapFrameDecode_Release(frame);
221
222     /* active frame 1, GCE transparent index 2 */
223     hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame);
224     ok(hr == S_OK, "GetFrame error %#x\n", hr);
225
226     /* global palette */
227     hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
228     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
229
230     hr = IWICPalette_GetColorCount(palette, &count);
231     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
232     ok(count == 4, "expected 4, got %u\n", count);
233
234     hr = IWICPalette_GetColors(palette, count, color, &ret);
235     ok(hr == S_OK, "GetColors error %#x\n", hr);
236     ok(ret == count, "expected %u, got %u\n", count, ret);
237     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
238     ok(color[1] == 0xff040506 || broken(color[1] == 0x00040506) /* XP */, "expected 0xff040506, got %#x\n", color[1]);
239     ok(color[2] == 0x00070809 || broken(color[2] == 0xff070809) /* XP */, "expected 0x00070809, got %#x\n", color[2]);
240     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
241
242     /* frame 1 palette */
243     hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
244     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
245     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
246        "wrong pixel format %s\n", debugstr_guid(&format));
247
248     hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
249     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
250
251     hr = IWICPalette_GetColorCount(palette, &count);
252     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
253     ok(count == 4, "expected 4, got %u\n", count);
254
255     hr = IWICPalette_GetColors(palette, count, color, &ret);
256     ok(hr == S_OK, "GetColors error %#x\n", hr);
257     ok(ret == count, "expected %u, got %u\n", count, ret);
258     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
259     ok(color[1] == 0xff040506, "expected 0xff040506, got %#x\n", color[1]);
260     ok(color[2] == 0x00070809, "expected 0x00070809, got %#x\n", color[2]);
261     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
262
263     IWICPalette_Release(palette);
264     IWICBitmapFrameDecode_Release(frame);
265     IWICBitmapDecoder_Release(decoder);
266 }
267
268 static void test_local_gif_palette(void)
269 {
270     HRESULT hr;
271     IWICBitmapDecoder *decoder;
272     IWICBitmapFrameDecode *frame;
273     IWICPalette *palette;
274     GUID format;
275     UINT count, ret;
276     WICColor color[256];
277
278     decoder = create_decoder(gif_local_palette, sizeof(gif_local_palette));
279     ok(decoder != 0, "Failed to load GIF image data\n");
280
281     hr = IWICImagingFactory_CreatePalette(factory, &palette);
282     ok(hr == S_OK, "CreatePalette error %#x\n", hr);
283
284     /* global palette */
285     hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
286     ok(hr == WINCODEC_ERR_FRAMEMISSING,
287        "expected WINCODEC_ERR_FRAMEMISSING, got %#x\n", hr);
288
289     /* frame palette */
290     hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
291     ok(hr == S_OK, "GetFrame error %#x\n", hr);
292
293     hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
294     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
295     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
296        "wrong pixel format %s\n", debugstr_guid(&format));
297
298     hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
299     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
300
301     hr = IWICPalette_GetColorCount(palette, &count);
302     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
303     ok(count == 4, "expected 4, got %u\n", count);
304
305     hr = IWICPalette_GetColors(palette, count, color, &ret);
306     ok(hr == S_OK, "GetColors error %#x\n", hr);
307     ok(ret == count, "expected %u, got %u\n", count, ret);
308     ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]);
309     ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]);
310     ok(color[2] == 0xff070809, "expected 0xff070809, got %#x\n", color[2]);
311     ok(color[3] == 0xff0a0b0c, "expected 0xff0a0b0c, got %#x\n", color[3]);
312
313     IWICPalette_Release(palette);
314     IWICBitmapFrameDecode_Release(frame);
315     IWICBitmapDecoder_Release(decoder);
316 }
317
318 START_TEST(gifformat)
319 {
320     HRESULT hr;
321
322     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
323     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
324                           &IID_IWICImagingFactory, (void **)&factory);
325     ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
326     if (FAILED(hr)) return;
327
328     test_global_gif_palette();
329     test_global_gif_palette_2frames();
330     test_local_gif_palette();
331
332     IWICImagingFactory_Release(factory);
333     CoUninitialize();
334 }