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 }
1178