Release 1.5.29.
[wine] / dlls / windowscodecs / tests / bmpformat.c
1 /*
2  * Copyright 2009 Vincent Povirk for CodeWeavers
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 <math.h>
21
22 #define COBJMACROS
23
24 #include "windef.h"
25 #include "initguid.h"
26 #include "objbase.h"
27 #include "wincodec.h"
28 #include "wincodecsdk.h"
29 #include "wine/test.h"
30
31 static const char testbmp_24bpp[] = {
32     /* BITMAPFILEHEADER */
33     66,77, /* "BM" */
34     78,0,0,0, /* file size */
35     0,0,0,0, /* reserved */
36     54,0,0,0, /* offset to bits */
37     /* BITMAPINFOHEADER */
38     40,0,0,0, /* header size */
39     2,0,0,0, /* width */
40     3,0,0,0, /* height */
41     1,0, /* planes */
42     24,0, /* bit count */
43     0,0,0,0, /* compression */
44     0,0,0,0, /* image size */
45     0x74,0x12,0,0, /* X pels per meter => 120 dpi */
46     0,0,0,0, /* Y pels per meter */
47     0,0,0,0, /* colors used */
48     0,0,0,0, /* colors important */
49     /* bits */
50     0,0,0,     0,255,0,     0,0,
51     255,0,0,   255,255,0,   0,0,
52     255,0,255, 255,255,255, 0,0
53 };
54
55 static void test_decode_24bpp(void)
56 {
57     IWICBitmapDecoder *decoder, *decoder2;
58     IWICBitmapFrameDecode *framedecode;
59     IWICMetadataQueryReader *queryreader;
60     IWICColorContext *colorcontext;
61     IWICBitmapSource *thumbnail;
62     HRESULT hr;
63     HGLOBAL hbmpdata;
64     char *bmpdata;
65     IStream *bmpstream;
66     DWORD capability=0;
67     GUID guidresult;
68     UINT count=0, width=0, height=0;
69     double dpiX, dpiY;
70     BYTE imagedata[36] = {1};
71     const BYTE expected_imagedata[36] = {
72         255,0,255, 255,255,255,
73         255,0,0,   255,255,0,
74         0,0,0,     0,255,0};
75     WICRect rc;
76
77     hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
78         &IID_IWICBitmapDecoder, (void**)&decoder);
79     ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
80     if (FAILED(hr)) return;
81
82     hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_24bpp));
83     ok(hbmpdata != 0, "GlobalAlloc failed\n");
84     if (hbmpdata)
85     {
86         bmpdata = GlobalLock(hbmpdata);
87         memcpy(bmpdata, testbmp_24bpp, sizeof(testbmp_24bpp));
88         GlobalUnlock(hbmpdata);
89
90         hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream);
91         ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
92         if (SUCCEEDED(hr))
93         {
94             hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad);
95             ok(hr == S_OK || broken(hr == WINCODEC_ERR_BADIMAGE) /* XP */, "Initialize failed, hr=%x\n", hr);
96             if (FAILED(hr))
97             {
98                 win_skip("BMP decoder failed to initialize\n");
99                 GlobalFree(hbmpdata);
100                 IWICBitmapDecoder_Release(decoder);
101                 return;
102             }
103
104             hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult);
105             ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr);
106             ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n");
107
108             hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, &queryreader);
109             ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr);
110
111             hr = IWICBitmapDecoder_GetColorContexts(decoder, 1, &colorcontext, &count);
112             ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr);
113
114             hr = IWICBitmapDecoder_GetThumbnail(decoder, &thumbnail);
115             ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %x\n", hr);
116
117             hr = IWICBitmapDecoder_GetPreview(decoder, &thumbnail);
118             ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr);
119
120             hr = IWICBitmapDecoder_GetFrameCount(decoder, &count);
121             ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr);
122             ok(count == 1, "unexpected count %u\n", count);
123
124             hr = IWICBitmapDecoder_GetFrame(decoder, 1, &framedecode);
125             ok(hr == E_INVALIDARG || hr == WINCODEC_ERR_FRAMEMISSING, "GetFrame returned %x\n", hr);
126
127             hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode);
128             ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr);
129             if (SUCCEEDED(hr))
130             {
131                 IWICImagingFactory *factory;
132                 IWICPalette *palette;
133
134                 hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height);
135                 ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr);
136                 ok(width == 2, "expected width=2, got %u\n", width);
137                 ok(height == 3, "expected height=2, got %u\n", height);
138
139                 hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY);
140                 ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr);
141                 ok(dpiX == 96.0, "expected dpiX=96.0, got %f\n", dpiX);
142                 ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY);
143
144                 hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult);
145                 ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr);
146                 ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
147
148                 hr = IWICBitmapFrameDecode_GetMetadataQueryReader(framedecode, &queryreader);
149                 ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr);
150
151                 hr = IWICBitmapFrameDecode_GetColorContexts(framedecode, 1, &colorcontext, &count);
152                 ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr);
153
154                 hr = IWICBitmapFrameDecode_GetThumbnail(framedecode, &thumbnail);
155                 ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %x\n", hr);
156
157                 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
158                     &IID_IWICImagingFactory, (void**)&factory);
159                 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
160                 if (SUCCEEDED(hr))
161                 {
162                     hr = IWICImagingFactory_CreatePalette(factory, &palette);
163                     ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr);
164                     if (SUCCEEDED(hr))
165                     {
166                         hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
167                         ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr);
168
169                         hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette);
170                         ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr);
171
172                         IWICPalette_Release(palette);
173                     }
174
175                     IWICImagingFactory_Release(factory);
176                 }
177
178                 rc.X = 0;
179                 rc.Y = 0;
180                 rc.Width = 3;
181                 rc.Height = 3;
182                 hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata);
183                 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
184
185                 rc.X = -1;
186                 rc.Y = 0;
187                 rc.Width = 2;
188                 rc.Height = 3;
189                 hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata);
190                 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
191
192                 rc.X = 0;
193                 rc.Y = 0;
194                 rc.Width = 2;
195                 rc.Height = 3;
196                 hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 4, sizeof(imagedata), imagedata);
197                 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
198
199                 rc.X = 0;
200                 rc.Y = 0;
201                 rc.Width = 2;
202                 rc.Height = 3;
203                 hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 4, 5, imagedata);
204                 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
205
206                 rc.X = 0;
207                 rc.Y = 0;
208                 rc.Width = 2;
209                 rc.Height = 3;
210                 hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata);
211                 ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr);
212                 ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n");
213
214                 hr = IWICBitmapFrameDecode_CopyPixels(framedecode, NULL, 6, sizeof(imagedata), imagedata);
215                 ok(SUCCEEDED(hr), "CopyPixels(rect=NULL) failed, hr=%x\n", hr);
216                 ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n");
217
218                 IWICBitmapFrameDecode_Release(framedecode);
219             }
220
221             /* cannot initialize twice */
222             hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad);
223             ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr);
224
225             /* cannot querycapability after initialize */
226             hr = IWICBitmapDecoder_QueryCapability(decoder, bmpstream, &capability);
227             ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr);
228
229             hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
230                 &IID_IWICBitmapDecoder, (void**)&decoder2);
231             ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
232             if (SUCCEEDED(hr))
233             {
234                 hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability);
235                 ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr);
236                 ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages),
237                     "unexpected capabilities: %x\n", capability);
238
239                 /* cannot initialize after querycapability */
240                 hr = IWICBitmapDecoder_Initialize(decoder2, bmpstream, WICDecodeMetadataCacheOnLoad);
241                 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr);
242
243                 /* cannot querycapability twice */
244                 hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability);
245                 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr);
246
247                 IWICBitmapDecoder_Release(decoder2);
248             }
249
250             IStream_Release(bmpstream);
251         }
252
253         GlobalFree(hbmpdata);
254     }
255
256     IWICBitmapDecoder_Release(decoder);
257 }
258
259 static const char testbmp_1bpp[] = {
260     /* BITMAPFILEHEADER */
261     66,77, /* "BM" */
262     40,0,0,0, /* file size */
263     0,0,0,0, /* reserved */
264     32,0,0,0, /* offset to bits */
265     /* BITMAPCOREHEADER */
266     12,0,0,0, /* header size */
267     2,0, /* width */
268     2,0, /* height */
269     1,0, /* planes */
270     1,0, /* bit count */
271     /* color table */
272     255,0,0,
273     0,255,0,
274     /* bits */
275     0xc0,0,0,0,
276     0x80,0,0,0
277 };
278
279 static void test_decode_1bpp(void)
280 {
281     IWICBitmapDecoder *decoder, *decoder2;
282     IWICBitmapFrameDecode *framedecode;
283     HRESULT hr;
284     HGLOBAL hbmpdata;
285     char *bmpdata;
286     IStream *bmpstream;
287     DWORD capability=0;
288     GUID guidresult;
289     UINT count=0, width=0, height=0;
290     double dpiX, dpiY;
291     BYTE imagedata[2] = {1};
292     const BYTE expected_imagedata[2] = {0x80,0xc0};
293     WICColor palettedata[2] = {1};
294     const WICColor expected_palettedata[2] = {0xff0000ff,0xff00ff00};
295     WICRect rc;
296
297     hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
298         &IID_IWICBitmapDecoder, (void**)&decoder);
299     ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
300     if (FAILED(hr)) return;
301
302     hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_1bpp));
303     ok(hbmpdata != 0, "GlobalAlloc failed\n");
304     if (hbmpdata)
305     {
306         bmpdata = GlobalLock(hbmpdata);
307         memcpy(bmpdata, testbmp_1bpp, sizeof(testbmp_1bpp));
308         GlobalUnlock(hbmpdata);
309
310         hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream);
311         ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
312         if (SUCCEEDED(hr))
313         {
314             hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad);
315             ok(hr == S_OK, "Initialize failed, hr=%x\n", hr);
316
317             hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult);
318             ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr);
319             ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n");
320
321             hr = IWICBitmapDecoder_GetFrameCount(decoder, &count);
322             ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr);
323             ok(count == 1, "unexpected count %u\n", count);
324
325             hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode);
326             ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr);
327             if (SUCCEEDED(hr))
328             {
329                 IWICImagingFactory *factory;
330                 IWICPalette *palette;
331
332                 hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height);
333                 ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr);
334                 ok(width == 2, "expected width=2, got %u\n", width);
335                 ok(height == 2, "expected height=2, got %u\n", height);
336
337                 hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY);
338                 ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr);
339                 ok(dpiX == 96.0, "expected dpiX=96.0, got %f\n", dpiX);
340                 ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY);
341
342                 hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult);
343                 ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr);
344                 ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat1bppIndexed), "unexpected pixel format\n");
345
346                 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
347                     &IID_IWICImagingFactory, (void**)&factory);
348                 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
349                 if (SUCCEEDED(hr))
350                 {
351                     hr = IWICImagingFactory_CreatePalette(factory, &palette);
352                     ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr);
353                     if (SUCCEEDED(hr))
354                     {
355                         hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
356                         ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr);
357
358                         hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette);
359                         ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr);
360
361                         hr = IWICPalette_GetColorCount(palette, &count);
362                         ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
363                         ok(count == 2, "expected count=2, got %u\n", count);
364
365                         hr = IWICPalette_GetColors(palette, 2, palettedata, &count);
366                         ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
367                         ok(count == 2, "expected count=2, got %u\n", count);
368                         ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n");
369
370                         IWICPalette_Release(palette);
371                     }
372
373                     IWICImagingFactory_Release(factory);
374                 }
375
376                 rc.X = 0;
377                 rc.Y = 0;
378                 rc.Width = 2;
379                 rc.Height = 2;
380                 hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 1, sizeof(imagedata), imagedata);
381                 ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr);
382                 ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n");
383
384                 IWICBitmapFrameDecode_Release(framedecode);
385             }
386
387             hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
388                 &IID_IWICBitmapDecoder, (void**)&decoder2);
389             ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
390             if (SUCCEEDED(hr))
391             {
392                 hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability);
393                 ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr);
394                 ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages),
395                     "unexpected capabilities: %x\n", capability);
396                 IWICBitmapDecoder_Release(decoder2);
397             }
398
399             IStream_Release(bmpstream);
400         }
401
402         GlobalFree(hbmpdata);
403     }
404
405     IWICBitmapDecoder_Release(decoder);
406 }
407
408 static const char testbmp_4bpp[] = {
409     /* BITMAPFILEHEADER */
410     66,77, /* "BM" */
411     82,0,0,0, /* file size */
412     0,0,0,0, /* reserved */
413     74,0,0,0, /* offset to bits */
414     /* BITMAPINFOHEADER */
415     40,0,0,0, /* header size */
416     2,0,0,0, /* width */
417     254,255,255,255, /* height = -2 */
418     1,0, /* planes */
419     4,0, /* bit count */
420     0,0,0,0, /* compression = BI_RGB */
421     0,0,0,0, /* image size = 0 */
422     16,39,0,0, /* X pixels per meter = 10000 */
423     32,78,0,0, /* Y pixels per meter = 20000 */
424     5,0,0,0, /* colors used */
425     5,0,0,0, /* colors important */
426     /* color table */
427     255,0,0,0,
428     0,255,0,255,
429     0,0,255,23,
430     128,0,128,1,
431     255,255,255,0,
432     /* bits */
433     0x01,0,0,0,
434     0x23,0,0,0,
435 };
436
437 static void test_decode_4bpp(void)
438 {
439     IWICBitmapDecoder *decoder, *decoder2;
440     IWICBitmapFrameDecode *framedecode;
441     HRESULT hr;
442     HGLOBAL hbmpdata;
443     char *bmpdata;
444     IStream *bmpstream;
445     DWORD capability=0;
446     GUID guidresult;
447     UINT count=0, width=0, height=0;
448     double dpiX, dpiY;
449     BYTE imagedata[2] = {1};
450     const BYTE expected_imagedata[2] = {0x01,0x23};
451     WICColor palettedata[5] = {1};
452     const WICColor expected_palettedata[5] =
453         {0xff0000ff,0xff00ff00,0xffff0000,0xff800080,0xffffffff};
454     WICRect rc;
455
456     hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
457         &IID_IWICBitmapDecoder, (void**)&decoder);
458     ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
459     if (FAILED(hr)) return;
460
461     hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_4bpp));
462     ok(hbmpdata != 0, "GlobalAlloc failed\n");
463     if (hbmpdata)
464     {
465         bmpdata = GlobalLock(hbmpdata);
466         memcpy(bmpdata, testbmp_4bpp, sizeof(testbmp_4bpp));
467         GlobalUnlock(hbmpdata);
468
469         hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream);
470         ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
471         if (SUCCEEDED(hr))
472         {
473             hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad);
474             ok(hr == S_OK, "Initialize failed, hr=%x\n", hr);
475
476             hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult);
477             ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr);
478             ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n");
479
480             hr = IWICBitmapDecoder_GetFrameCount(decoder, &count);
481             ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr);
482             ok(count == 1, "unexpected count %u\n", count);
483
484             hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode);
485             ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr);
486             if (SUCCEEDED(hr))
487             {
488                 IWICImagingFactory *factory;
489                 IWICPalette *palette;
490
491                 hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height);
492                 ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr);
493                 ok(width == 2, "expected width=2, got %u\n", width);
494                 ok(height == 2, "expected height=2, got %u\n", height);
495
496                 hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY);
497                 ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr);
498                 ok(fabs(dpiX - 254.0) < 0.01, "expected dpiX=96.0, got %f\n", dpiX);
499                 ok(fabs(dpiY - 508.0) < 0.01, "expected dpiY=96.0, got %f\n", dpiY);
500
501                 hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult);
502                 ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr);
503                 ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat4bppIndexed), "unexpected pixel format\n");
504
505                 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
506                     &IID_IWICImagingFactory, (void**)&factory);
507                 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
508                 if (SUCCEEDED(hr))
509                 {
510                     hr = IWICImagingFactory_CreatePalette(factory, &palette);
511                     ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr);
512                     if (SUCCEEDED(hr))
513                     {
514                         hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
515                         ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr);
516
517                         hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette);
518                         ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr);
519
520                         hr = IWICPalette_GetColorCount(palette, &count);
521                         ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
522                         ok(count == 5, "expected count=5, got %u\n", count);
523
524                         hr = IWICPalette_GetColors(palette, 5, palettedata, &count);
525                         ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
526                         ok(count == 5, "expected count=5, got %u\n", count);
527                         ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n");
528
529                         IWICPalette_Release(palette);
530                     }
531
532                     IWICImagingFactory_Release(factory);
533                 }
534
535                 rc.X = 0;
536                 rc.Y = 0;
537                 rc.Width = 2;
538                 rc.Height = 2;
539                 hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 1, sizeof(imagedata), imagedata);
540                 ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr);
541                 ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n");
542
543                 IWICBitmapFrameDecode_Release(framedecode);
544             }
545
546             hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
547                 &IID_IWICBitmapDecoder, (void**)&decoder2);
548             ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
549             if (SUCCEEDED(hr))
550             {
551                 hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability);
552                 ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr);
553                 ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages),
554                     "unexpected capabilities: %x\n", capability);
555                 IWICBitmapDecoder_Release(decoder2);
556             }
557
558             IStream_Release(bmpstream);
559         }
560
561         GlobalFree(hbmpdata);
562     }
563
564     IWICBitmapDecoder_Release(decoder);
565 }
566
567 static const char testbmp_rle8[] = {
568     /* BITMAPFILEHEADER */
569     66,77, /* "BM" */
570     202,0,0,0, /* file size */
571     0,0,0,0, /* reserved */
572     122,0,0,0, /* offset to bits */
573     /* BITMAPINFOHEADER */
574     40,0,0,0, /* header size */
575     8,0,0,0, /* width */
576     8,0,0,0, /* height */
577     1,0, /* planes */
578     8,0, /* bit count */
579     1,0,0,0, /* compression = BI_RLE8 */
580     80,0,0,0, /* image size */
581     19,11,0,0, /* X pixels per meter */
582     19,11,0,0, /* Y pixels per meter */
583     17,0,0,0, /* colors used */
584     17,0,0,0, /* colors important */
585     /* color table */
586     0,0,0,0,
587     17,17,17,0,
588     255,0,0,0,
589     34,34,34,0,
590     0,0,204,0,
591     0,0,221,0,
592     0,0,238,0,
593     51,51,51,0,
594     0,0,255,0,
595     68,68,68,0,
596     255,0,255,0,
597     85,85,85,0,
598     0,204,0,0,
599     0,221,0,0,
600     0,238,0,0,
601     0,255,0,0,
602     255,255,255,0,
603     /* bits */
604     4,15,0,4,11,9,9,0,0,0,4,14,0,4,3,10,10,7,0,0,4,13,0,4,3,10,10,7,0,0,4,12,0,4,0,1,1,11,0,0,0,4,16,2,16,2,4,4,0,0,0,4,2,16,2,16,4,5,0,0,0,4,16,2,16,2,4,6,0,0,0,4,2,16,2,16,4,8,0,1
605 };
606
607 static void test_decode_rle8(void)
608 {
609     IWICBitmapDecoder *decoder, *decoder2;
610     IWICBitmapFrameDecode *framedecode;
611     HRESULT hr;
612     HGLOBAL hbmpdata;
613     char *bmpdata;
614     IStream *bmpstream;
615     DWORD capability=0;
616     GUID guidresult;
617     UINT count=0, width=0, height=0;
618     double dpiX, dpiY;
619     DWORD imagedata[64] = {1};
620     const DWORD expected_imagedata[64] = {
621         0x0000ff,0xffffff,0x0000ff,0xffffff,0xff0000,0xff0000,0xff0000,0xff0000,
622         0xffffff,0x0000ff,0xffffff,0x0000ff,0xee0000,0xee0000,0xee0000,0xee0000,
623         0x0000ff,0xffffff,0x0000ff,0xffffff,0xdd0000,0xdd0000,0xdd0000,0xdd0000,
624         0xffffff,0x0000ff,0xffffff,0x0000ff,0xcc0000,0xcc0000,0xcc0000,0xcc0000,
625         0x00cc00,0x00cc00,0x00cc00,0x00cc00,0x000000,0x111111,0x111111,0x555555,
626         0x00dd00,0x00dd00,0x00dd00,0x00dd00,0x222222,0xff00ff,0xff00ff,0x333333,
627         0x00ee00,0x00ee00,0x00ee00,0x00ee00,0x222222,0xff00ff,0xff00ff,0x333333,
628         0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x555555,0x444444,0x444444,0x000000};
629     WICColor palettedata[17] = {1};
630     const WICColor expected_palettedata[17] = {
631         0xff000000,0xff111111,0xff0000ff,0xff222222,0xffcc0000,0xffdd0000,
632         0xffee0000,0xff333333,0xffff0000,0xff444444,0xffff00ff,0xff555555,
633         0xff00cc00,0xff00dd00,0xff00ee00,0xff00ff00,0xffffffff};
634     WICRect rc;
635
636     hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
637         &IID_IWICBitmapDecoder, (void**)&decoder);
638     ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
639     if (FAILED(hr)) return;
640
641     hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_rle8));
642     ok(hbmpdata != 0, "GlobalAlloc failed\n");
643     if (hbmpdata)
644     {
645         bmpdata = GlobalLock(hbmpdata);
646         memcpy(bmpdata, testbmp_rle8, sizeof(testbmp_rle8));
647         GlobalUnlock(hbmpdata);
648
649         hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream);
650         ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
651         if (SUCCEEDED(hr))
652         {
653             hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad);
654             ok(hr == S_OK, "Initialize failed, hr=%x\n", hr);
655
656             hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult);
657             ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr);
658             ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n");
659
660             hr = IWICBitmapDecoder_GetFrameCount(decoder, &count);
661             ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr);
662             ok(count == 1, "unexpected count %u\n", count);
663
664             hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode);
665             ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr);
666             if (SUCCEEDED(hr))
667             {
668                 IWICImagingFactory *factory;
669                 IWICPalette *palette;
670
671                 hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height);
672                 ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr);
673                 ok(width == 8, "expected width=8, got %u\n", width);
674                 ok(height == 8, "expected height=8, got %u\n", height);
675
676                 hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY);
677                 ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr);
678                 ok(fabs(dpiX - 72.0) < 0.01, "expected dpiX=96.0, got %f\n", dpiX);
679                 ok(fabs(dpiY - 72.0) < 0.01, "expected dpiY=96.0, got %f\n", dpiY);
680
681                 hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult);
682                 ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr);
683                 ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format\n");
684
685                 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
686                     &IID_IWICImagingFactory, (void**)&factory);
687                 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
688                 if (SUCCEEDED(hr))
689                 {
690                     hr = IWICImagingFactory_CreatePalette(factory, &palette);
691                     ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr);
692                     if (SUCCEEDED(hr))
693                     {
694                         hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
695                         ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr);
696
697                         hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette);
698                         ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr);
699
700                         hr = IWICPalette_GetColorCount(palette, &count);
701                         ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
702                         ok(count == 17, "expected count=17, got %u\n", count);
703
704                         hr = IWICPalette_GetColors(palette, 17, palettedata, &count);
705                         ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
706                         ok(count == 17, "expected count=17, got %u\n", count);
707                         ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n");
708
709                         IWICPalette_Release(palette);
710                     }
711
712                     IWICImagingFactory_Release(factory);
713                 }
714
715                 rc.X = 0;
716                 rc.Y = 0;
717                 rc.Width = 8;
718                 rc.Height = 8;
719                 hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 32, sizeof(imagedata), (BYTE*)imagedata);
720                 ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr);
721                 ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n");
722
723                 IWICBitmapFrameDecode_Release(framedecode);
724             }
725
726             hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
727                 &IID_IWICBitmapDecoder, (void**)&decoder2);
728             ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
729             if (SUCCEEDED(hr))
730             {
731                 hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability);
732                 ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr);
733                 ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages),
734                     "unexpected capabilities: %x\n", capability);
735                 IWICBitmapDecoder_Release(decoder2);
736             }
737
738             IStream_Release(bmpstream);
739         }
740
741         GlobalFree(hbmpdata);
742     }
743
744     IWICBitmapDecoder_Release(decoder);
745 }
746
747 static const char testbmp_rle4[] = {
748     /* BITMAPFILEHEADER */
749     66,77, /* "BM" */
750     142,0,0,0, /* file size */
751     0,0,0,0, /* reserved */
752     78,0,0,0, /* offset to bits */
753     /* BITMAPINFOHEADER */
754     40,0,0,0, /* header size */
755     8,0,0,0, /* width */
756     8,0,0,0, /* height */
757     1,0, /* planes */
758     4,0, /* bit count */
759     2,0,0,0, /* compression = BI_RLE4 */
760     64,0,0,0, /* image size */
761     19,11,0,0, /* X pixels per meter */
762     19,11,0,0, /* Y pixels per meter */
763     6,0,0,0, /* colors used */
764     6,0,0,0, /* colors important */
765     /* color table */
766     0,0,0,0,
767     255,0,0,0,
768     0,0,255,0,
769     255,0,255,0,
770     0,255,0,0,
771     255,255,255,0,
772     /* bits */
773     0,8,68,68,0,0,0,0,0,8,68,68,3,48,0,0,0,8,68,68,3,48,0,0,0,8,68,68,0,0,0,0,0,8,81,81,34,34,0,0,0,8,21,21,34,34,0,0,0,8,81,81,34,34,0,0,0,8,21,21,34,34,0,1
774 };
775
776 static void test_decode_rle4(void)
777 {
778     IWICBitmapDecoder *decoder, *decoder2;
779     IWICBitmapFrameDecode *framedecode;
780     HRESULT hr;
781     HGLOBAL hbmpdata;
782     char *bmpdata;
783     IStream *bmpstream;
784     DWORD capability=0;
785     GUID guidresult;
786     UINT count=0, width=0, height=0;
787     double dpiX, dpiY;
788     DWORD imagedata[64] = {1};
789     const DWORD expected_imagedata[64] = {
790         0x0000ff,0xffffff,0x0000ff,0xffffff,0xff0000,0xff0000,0xff0000,0xff0000,
791         0xffffff,0x0000ff,0xffffff,0x0000ff,0xff0000,0xff0000,0xff0000,0xff0000,
792         0x0000ff,0xffffff,0x0000ff,0xffffff,0xff0000,0xff0000,0xff0000,0xff0000,
793         0xffffff,0x0000ff,0xffffff,0x0000ff,0xff0000,0xff0000,0xff0000,0xff0000,
794         0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x000000,0x000000,0x000000,
795         0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0xff00ff,0xff00ff,0x000000,
796         0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0xff00ff,0xff00ff,0x000000,
797         0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x000000,0x000000,0x000000};
798     WICColor palettedata[6] = {1};
799     const WICColor expected_palettedata[6] = {
800         0xff000000,0xff0000ff,0xffff0000,0xffff00ff,0xff00ff00,0xffffffff};
801     WICRect rc;
802
803     hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
804         &IID_IWICBitmapDecoder, (void**)&decoder);
805     ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
806     if (FAILED(hr)) return;
807
808     hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_rle4));
809     ok(hbmpdata != 0, "GlobalAlloc failed\n");
810     if (hbmpdata)
811     {
812         bmpdata = GlobalLock(hbmpdata);
813         memcpy(bmpdata, testbmp_rle4, sizeof(testbmp_rle4));
814         GlobalUnlock(hbmpdata);
815
816         hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream);
817         ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
818         if (SUCCEEDED(hr))
819         {
820             hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad);
821             ok(hr == S_OK, "Initialize failed, hr=%x\n", hr);
822
823             hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult);
824             ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr);
825             ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n");
826
827             hr = IWICBitmapDecoder_GetFrameCount(decoder, &count);
828             ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr);
829             ok(count == 1, "unexpected count %u\n", count);
830
831             hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode);
832             ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr);
833             if (SUCCEEDED(hr))
834             {
835                 IWICImagingFactory *factory;
836                 IWICPalette *palette;
837
838                 hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height);
839                 ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr);
840                 ok(width == 8, "expected width=8, got %u\n", width);
841                 ok(height == 8, "expected height=8, got %u\n", height);
842
843                 hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY);
844                 ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr);
845                 ok(fabs(dpiX - 72.0) < 0.01, "expected dpiX=96.0, got %f\n", dpiX);
846                 ok(fabs(dpiY - 72.0) < 0.01, "expected dpiY=96.0, got %f\n", dpiY);
847
848                 hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult);
849                 ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr);
850                 ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format\n");
851
852                 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
853                     &IID_IWICImagingFactory, (void**)&factory);
854                 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
855                 if (SUCCEEDED(hr))
856                 {
857                     hr = IWICImagingFactory_CreatePalette(factory, &palette);
858                     ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr);
859                     if (SUCCEEDED(hr))
860                     {
861                         hr = IWICBitmapDecoder_CopyPalette(decoder, palette);
862                         ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr);
863
864                         hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette);
865                         ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr);
866
867                         hr = IWICPalette_GetColorCount(palette, &count);
868                         ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
869                         ok(count == 6, "expected count=6, got %u\n", count);
870
871                         hr = IWICPalette_GetColors(palette, 6, palettedata, &count);
872                         ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
873                         ok(count == 6, "expected count=6, got %u\n", count);
874                         ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n");
875
876                         IWICPalette_Release(palette);
877                     }
878
879                     IWICImagingFactory_Release(factory);
880                 }
881
882                 rc.X = 0;
883                 rc.Y = 0;
884                 rc.Width = 8;
885                 rc.Height = 8;
886                 hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 32, sizeof(imagedata), (BYTE*)imagedata);
887                 ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr);
888                 ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n");
889
890                 IWICBitmapFrameDecode_Release(framedecode);
891             }
892
893             hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER,
894                 &IID_IWICBitmapDecoder, (void**)&decoder2);
895             ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
896             if (SUCCEEDED(hr))
897             {
898                 hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability);
899                 ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr);
900                 ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages),
901                     "unexpected capabilities: %x\n", capability);
902                 IWICBitmapDecoder_Release(decoder2);
903             }
904
905             IStream_Release(bmpstream);
906         }
907
908         GlobalFree(hbmpdata);
909     }
910
911     IWICBitmapDecoder_Release(decoder);
912 }
913
914 static void test_componentinfo(void)
915 {
916     IWICImagingFactory *factory;
917     IWICComponentInfo *info;
918     IWICBitmapDecoderInfo *decoderinfo;
919     IWICBitmapDecoder *decoder;
920     HRESULT hr;
921     WICBitmapPattern *patterns;
922     UINT pattern_count, pattern_size;
923     WICComponentType type;
924     GUID guidresult;
925     HGLOBAL hbmpdata;
926     char *bmpdata;
927     IStream *bmpstream;
928     BOOL boolresult;
929
930     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
931         &IID_IWICImagingFactory, (void**)&factory);
932     ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
933     if (SUCCEEDED(hr))
934     {
935         hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICBmpDecoder, &info);
936         ok(SUCCEEDED(hr), "CreateComponentInfo failed, hr=%x\n", hr);
937         if (SUCCEEDED(hr))
938         {
939             hr = IWICComponentInfo_GetComponentType(info, &type);
940             ok(SUCCEEDED(hr), "GetComponentType failed, hr=%x\n", hr);
941             ok(type == WICDecoder, "got %i, expected WICDecoder\n", type);
942
943             hr = IWICComponentInfo_QueryInterface(info, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo);
944             ok(SUCCEEDED(hr), "QueryInterface failed, hr=%x\n", hr);
945             if (SUCCEEDED(hr))
946             {
947                 pattern_count = 0;
948                 pattern_size = 0;
949                 hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, 0, NULL, &pattern_count, &pattern_size);
950                 ok(SUCCEEDED(hr), "GetPatterns failed, hr=%x\n", hr);
951                 ok(pattern_count != 0, "pattern count is 0\n");
952                 ok(pattern_size > pattern_count * sizeof(WICBitmapPattern), "size=%i, count=%i\n", pattern_size, pattern_count);
953
954                 patterns = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pattern_size);
955                 hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, pattern_size, patterns, &pattern_count, &pattern_size);
956                 ok(SUCCEEDED(hr), "GetPatterns failed, hr=%x\n", hr);
957                 ok(pattern_count != 0, "pattern count is 0\n");
958                 ok(pattern_size > pattern_count * sizeof(WICBitmapPattern), "size=%i, count=%i\n", pattern_size, pattern_count);
959                 ok(patterns[0].Length != 0, "pattern length is 0\n");
960                 ok(patterns[0].Pattern != NULL, "pattern is NULL\n");
961                 ok(patterns[0].Mask != NULL, "mask is NULL\n");
962
963                 pattern_size -= 1;
964                 hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, pattern_size, patterns, &pattern_count, &pattern_size);
965                 ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetPatterns returned %x, expected WINCODEC_ERR_INSUFFICIENTBUFFER\n", hr);
966
967                 HeapFree(GetProcessHeap(), 0, patterns);
968
969                 hr = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder);
970                 ok(SUCCEEDED(hr), "CreateInstance failed, hr=%x\n", hr);
971                 if (SUCCEEDED(hr))
972                 {
973                     hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult);
974                     ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr);
975                     ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n");
976
977                     IWICBitmapDecoder_Release(decoder);
978                 }
979
980                 hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_rle4));
981                 ok(hbmpdata != 0, "GlobalAlloc failed\n");
982                 if (hbmpdata)
983                 {
984                     bmpdata = GlobalLock(hbmpdata);
985                     memcpy(bmpdata, testbmp_rle4, sizeof(testbmp_rle4));
986                     GlobalUnlock(hbmpdata);
987
988                     hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream);
989                     ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
990                     if (SUCCEEDED(hr))
991                     {
992                         boolresult = 0;
993                         hr = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, bmpstream, &boolresult);
994                         ok(SUCCEEDED(hr), "MatchesPattern failed, hr=%x\n", hr);
995                         ok(boolresult, "pattern not matched\n");
996
997                         IStream_Release(bmpstream);
998                     }
999
1000                     GlobalFree(hbmpdata);
1001                 }
1002
1003                 IWICBitmapDecoderInfo_Release(decoderinfo);
1004             }
1005
1006             IWICComponentInfo_Release(info);
1007         }
1008
1009         IWICImagingFactory_Release(factory);
1010     }
1011 }
1012
1013 static void test_createfromstream(void)
1014 {
1015     IWICBitmapDecoder *decoder;
1016     IWICImagingFactory *factory;
1017     HRESULT hr;
1018     HGLOBAL hbmpdata;
1019     char *bmpdata;
1020     IStream *bmpstream;
1021     GUID guidresult;
1022
1023     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1024         &IID_IWICImagingFactory, (void**)&factory);
1025     ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
1026     if (FAILED(hr)) return;
1027
1028     hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_1bpp));
1029     ok(hbmpdata != 0, "GlobalAlloc failed\n");
1030     if (hbmpdata)
1031     {
1032         bmpdata = GlobalLock(hbmpdata);
1033         memcpy(bmpdata, testbmp_1bpp, sizeof(testbmp_1bpp));
1034         GlobalUnlock(hbmpdata);
1035
1036         hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream);
1037         ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
1038         if (SUCCEEDED(hr))
1039         {
1040             hr = IWICImagingFactory_CreateDecoderFromStream(factory, bmpstream,
1041                 NULL, WICDecodeMetadataCacheOnDemand, &decoder);
1042             ok(SUCCEEDED(hr), "CreateDecoderFromStream failed, hr=%x\n", hr);
1043             if (SUCCEEDED(hr))
1044             {
1045                 hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult);
1046                 ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr);
1047                 ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n");
1048
1049                 IWICBitmapDecoder_Release(decoder);
1050             }
1051
1052             IStream_Release(bmpstream);
1053         }
1054
1055         GlobalFree(hbmpdata);
1056     }
1057
1058     IWICImagingFactory_Release(factory);
1059 }
1060
1061 /* 1x1 pixel gif, missing trailer */
1062 static unsigned char gifimage_notrailer[] = {
1063 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x71,0xff,0xff,0xff,
1064 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1065 0x01,0x00
1066 };
1067
1068 static void test_gif_notrailer(void)
1069 {
1070     IWICBitmapDecoder *decoder;
1071     IWICImagingFactory *factory;
1072     HRESULT hr;
1073     IWICStream *gifstream;
1074     IWICBitmapFrameDecode *framedecode;
1075     double dpiX = 0.0, dpiY = 0.0;
1076     UINT framecount;
1077
1078     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1079         &IID_IWICImagingFactory, (void**)&factory);
1080     ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
1081     if (FAILED(hr)) return;
1082
1083     hr = IWICImagingFactory_CreateStream(factory, &gifstream);
1084     ok(hr == S_OK, "CreateStream failed, hr=%x\n", hr);
1085     if (SUCCEEDED(hr))
1086     {
1087         hr = IWICStream_InitializeFromMemory(gifstream, gifimage_notrailer,
1088             sizeof(gifimage_notrailer));
1089         ok(hr == S_OK, "InitializeFromMemory failed, hr=%x\n", hr);
1090
1091         if (SUCCEEDED(hr))
1092         {
1093             hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER,
1094                 &IID_IWICBitmapDecoder, (void**)&decoder);
1095             ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
1096         }
1097
1098         if (SUCCEEDED(hr))
1099         {
1100             hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)gifstream,
1101                 WICDecodeMetadataCacheOnDemand);
1102             ok(hr == S_OK, "Initialize failed, hr=%x\n", hr);
1103
1104             if (SUCCEEDED(hr))
1105             {
1106                 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode);
1107                 ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr);
1108                 if (SUCCEEDED(hr))
1109                 {
1110                     hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY);
1111                     ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr);
1112                     ok(dpiX == 48.0, "expected dpiX=48.0, got %f\n", dpiX);
1113                     ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY);
1114
1115                     IWICBitmapFrameDecode_Release(framedecode);
1116                 }
1117             }
1118
1119             if (SUCCEEDED(hr))
1120             {
1121                 hr = IWICBitmapDecoder_GetFrameCount(decoder, &framecount);
1122                 ok(hr == S_OK, "GetFrameCount failed, hr=%x\n", hr);
1123                 ok(framecount == 1, "framecount=%u\n", framecount);
1124             }
1125
1126             IWICBitmapDecoder_Release(decoder);
1127         }
1128
1129         IWICStream_Release(gifstream);
1130     }
1131
1132     IWICImagingFactory_Release(factory);
1133 }
1134
1135 static void test_create_decoder(void)
1136 {
1137     IWICBitmapDecoder *decoder;
1138     IWICImagingFactory *factory;
1139     HRESULT hr;
1140
1141     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1142         &IID_IWICImagingFactory, (void **)&factory);
1143     ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
1144
1145     hr = IWICImagingFactory_CreateDecoder(factory, NULL, NULL, NULL);
1146     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1147
1148     hr = IWICImagingFactory_CreateDecoder(factory, NULL, NULL, &decoder);
1149     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
1150
1151     hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatBmp, NULL, &decoder);
1152     ok(hr == S_OK, "CreateDecoder error %#x\n", hr);
1153     IWICBitmapDecoder_Release(decoder);
1154
1155     hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatBmp, &GUID_VendorMicrosoft, &decoder);
1156     ok(hr == S_OK, "CreateDecoder error %#x\n", hr);
1157     IWICBitmapDecoder_Release(decoder);
1158
1159     IWICImagingFactory_Release(factory);
1160 }
1161
1162 START_TEST(bmpformat)
1163 {
1164     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1165
1166     test_decode_24bpp();
1167     test_decode_1bpp();
1168     test_decode_4bpp();
1169     test_decode_rle8();
1170     test_decode_rle4();
1171     test_componentinfo();
1172     test_createfromstream();
1173     test_gif_notrailer();
1174     test_create_decoder();
1175
1176     CoUninitialize();
1177 }