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