Release 1.5.29.
[wine] / dlls / windowscodecs / tests / bitmap.c
1 /*
2  * Copyright 2012 Vincent Povirk for CodeWeavers
3  * Copyright 2012 Dmitry Timoshkov
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <assert.h>
23 #include <math.h>
24
25 #define COBJMACROS
26
27 #include "windef.h"
28 #include "objbase.h"
29 #include "wincodec.h"
30 #include "wine/test.h"
31
32 static IWICImagingFactory *factory;
33
34 static const char *debugstr_guid(const GUID *guid)
35 {
36     static char buf[50];
37
38     if (!guid) return "(null)";
39     sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
40             guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
41             guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
42             guid->Data4[5], guid->Data4[6], guid->Data4[7]);
43     return buf;
44 }
45
46 static HBITMAP create_dib(int width, int height, int bpp, LOGPALETTE *pal, const void *data)
47 {
48     char bmibuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255];
49     BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
50     void *bits;
51     HBITMAP hdib;
52     BITMAP bm;
53
54     memset(bmibuf, 0, sizeof(bmibuf));
55     bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
56     bmi->bmiHeader.biWidth = width;
57     bmi->bmiHeader.biHeight = -height;
58     bmi->bmiHeader.biBitCount = bpp;
59     bmi->bmiHeader.biPlanes = 1;
60     bmi->bmiHeader.biCompression = BI_RGB;
61     if (pal)
62     {
63         WORD i;
64
65         assert(pal->palNumEntries <= 256);
66         for (i = 0; i < pal->palNumEntries; i++)
67         {
68             bmi->bmiColors[i].rgbRed = pal->palPalEntry[i].peRed;
69             bmi->bmiColors[i].rgbGreen = pal->palPalEntry[i].peGreen;
70             bmi->bmiColors[i].rgbBlue = pal->palPalEntry[i].peBlue;
71             bmi->bmiColors[i].rgbReserved = 0;
72         }
73
74         bmi->bmiHeader.biClrUsed = pal->palNumEntries;
75         bmi->bmiHeader.biClrImportant = pal->palNumEntries;
76     }
77     hdib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
78     ok(hdib != 0, "CreateDIBSection(%dx%d,%d bpp) failed\n", width, height, bpp);
79
80     GetObject(hdib, sizeof(bm), &bm);
81     ok(bm.bmWidth == width, "expected %d, got %d\n", width, bm.bmWidth);
82     ok(bm.bmHeight == height, "expected %d, got %d\n", height, bm.bmHeight);
83     ok(bm.bmPlanes == 1, "expected 1, got %d\n", bm.bmPlanes);
84     ok(bm.bmBitsPixel == bpp, "expected %d, got %d\n", bpp, bm.bmBitsPixel);
85
86     if (data) memcpy(bits, data, bm.bmWidthBytes * bm.bmHeight);
87
88     return hdib;
89 }
90
91 static void test_createbitmap(void)
92 {
93     HRESULT hr;
94     IWICBitmap *bitmap;
95     IWICPalette *palette;
96     IWICBitmapLock *lock, *lock2;
97     WICBitmapPaletteType palettetype;
98     int i;
99     WICRect rc;
100     const BYTE bitmap_data[27] = {
101         128,128,255, 128,128,128, 128,255,128,
102         128,128,128, 128,128,128, 255,255,255,
103         255,128,128, 255,255,255, 255,255,255};
104     BYTE returned_data[27] = {0};
105     BYTE *lock_buffer=NULL, *base_lock_buffer=NULL;
106     UINT lock_buffer_size=0;
107     UINT lock_buffer_stride=0;
108     WICPixelFormatGUID pixelformat = {0};
109     UINT width=0, height=0;
110     double dpix=10.0, dpiy=10.0;
111     int can_lock_null = 1;
112
113     hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
114         WICBitmapCacheOnLoad, &bitmap);
115     ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr);
116
117     if (FAILED(hr))
118         return;
119
120     hr = IWICImagingFactory_CreatePalette(factory, &palette);
121     ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
122
123     /* Palette is unavailable until explicitly set */
124     hr = IWICBitmap_CopyPalette(bitmap, palette);
125     ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
126
127     hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE);
128     ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
129
130     hr = IWICBitmap_SetPalette(bitmap, palette);
131     ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr);
132
133     hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray4, FALSE);
134     ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
135
136     hr = IWICBitmap_CopyPalette(bitmap, palette);
137     ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
138
139     hr = IWICPalette_GetType(palette, &palettetype);
140     ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr);
141     ok(palettetype == WICBitmapPaletteTypeFixedGray256,
142         "expected WICBitmapPaletteTypeFixedGray256, got %x\n", palettetype);
143
144     IWICPalette_Release(palette);
145
146     /* pixel data is initially zeroed */
147     hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, 27, returned_data);
148     ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr);
149
150     for (i=0; i<27; i++)
151         ok(returned_data[i] == 0, "returned_data[%i] == %i\n", i, returned_data[i]);
152
153     /* Invalid lock rects */
154     rc.X = rc.Y = 0;
155     rc.Width = 4;
156     rc.Height = 3;
157     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
158     ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
159     if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
160
161     rc.Width = 3;
162     rc.Height = 4;
163     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
164     ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
165     if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
166
167     rc.Height = 3;
168     rc.X = 4;
169     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
170     ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
171     if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
172
173     rc.X = 0;
174     rc.Y = 4;
175     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
176     ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
177     if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
178
179     /* NULL lock rect */
180     hr = IWICBitmap_Lock(bitmap, NULL, WICBitmapLockRead, &lock);
181     ok(hr == S_OK || broken(hr == E_INVALIDARG) /* winxp */, "IWICBitmap_Lock failed hr=%x\n", hr);
182
183     if (SUCCEEDED(hr))
184     {
185         /* entire bitmap is locked */
186         hr = IWICBitmapLock_GetSize(lock, &width, &height);
187         ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr);
188         ok(width == 3, "got %d, expected 3\n", width);
189         ok(height == 3, "got %d, expected 3\n", height);
190
191         IWICBitmapLock_Release(lock);
192     }
193     else
194         can_lock_null = 0;
195
196     /* lock with a valid rect */
197     rc.Y = 0;
198     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
199     ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
200     if (SUCCEEDED(hr))
201     {
202         hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride);
203         ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr);
204         /* stride is divisible by 4 */
205         ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride);
206
207         hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer);
208         ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
209         /* buffer size does not include padding from the last row */
210         ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size);
211         ok(lock_buffer != NULL, "got NULL data pointer\n");
212         base_lock_buffer = lock_buffer;
213
214         hr = IWICBitmapLock_GetPixelFormat(lock, &pixelformat);
215         ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%x\n", hr);
216         ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
217
218         hr = IWICBitmapLock_GetSize(lock, &width, &height);
219         ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr);
220         ok(width == 3, "got %d, expected 3\n", width);
221         ok(height == 3, "got %d, expected 3\n", height);
222
223         /* We can have multiple simultaneous read locks */
224         hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2);
225         ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
226
227         if (SUCCEEDED(hr))
228         {
229             hr = IWICBitmapLock_GetDataPointer(lock2, &lock_buffer_size, &lock_buffer);
230             ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
231             ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size);
232             ok(lock_buffer == base_lock_buffer, "got %p, expected %p\n", lock_buffer, base_lock_buffer);
233
234             IWICBitmapLock_Release(lock2);
235         }
236
237         if (can_lock_null) /* this hangs on xp/vista */
238         {
239             /* But not a read and a write lock */
240             hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock2);
241             ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr);
242         }
243
244         /* But we don't need a write lock to write */
245         if (base_lock_buffer)
246         {
247             for (i=0; i<3; i++)
248                 memcpy(base_lock_buffer + lock_buffer_stride*i, bitmap_data + i*9, 9);
249         }
250
251         IWICBitmapLock_Release(lock);
252     }
253
254     /* test that the data we wrote is returned by CopyPixels */
255     hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, 27, returned_data);
256     ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr);
257
258     for (i=0; i<27; i++)
259         ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]);
260
261     /* try a valid partial rect, and write mode */
262     rc.X = 2;
263     rc.Y = 0;
264     rc.Width = 1;
265     rc.Height = 2;
266     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock);
267     ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
268
269     if (SUCCEEDED(hr))
270     {
271         if (can_lock_null) /* this hangs on xp/vista */
272         {
273             /* Can't lock again while locked for writing */
274             hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock2);
275             ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr);
276
277             hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2);
278             ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr);
279         }
280
281         hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride);
282         ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr);
283         ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride);
284
285         hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer);
286         ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
287         ok(lock_buffer_size == 15, "got %i, expected 15\n", lock_buffer_size);
288         ok(lock_buffer == base_lock_buffer+6, "got %p, expected %p+6\n", lock_buffer, base_lock_buffer);
289
290         hr = IWICBitmapLock_GetPixelFormat(lock, &pixelformat);
291         ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%x\n", hr);
292         ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
293
294         hr = IWICBitmapLock_GetSize(lock, &width, &height);
295         ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr);
296         ok(width == 1, "got %d, expected 1\n", width);
297         ok(height == 2, "got %d, expected 2\n", height);
298
299         IWICBitmapLock_Release(lock);
300     }
301
302     hr = IWICBitmap_GetPixelFormat(bitmap, &pixelformat);
303     ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr);
304     ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
305
306     hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy);
307     ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr);
308     ok(dpix == 0.0, "got %f, expected 0.0\n", dpix);
309     ok(dpiy == 0.0, "got %f, expected 0.0\n", dpiy);
310
311     hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0);
312     ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%x\n", hr);
313
314     hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy);
315     ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr);
316     ok(dpix == 12.0, "got %f, expected 12.0\n", dpix);
317     ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy);
318
319     hr = IWICBitmap_GetSize(bitmap, &width, &height);
320     ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr);
321     ok(width == 3, "got %d, expected 3\n", width);
322     ok(height == 3, "got %d, expected 3\n", height);
323
324     IWICBitmap_Release(bitmap);
325 }
326
327 static void test_createbitmapfromsource(void)
328 {
329     HRESULT hr;
330     IWICBitmap *bitmap, *bitmap2;
331     IWICPalette *palette;
332     IWICBitmapLock *lock;
333     int i;
334     WICRect rc;
335     const BYTE bitmap_data[27] = {
336         128,128,255, 128,128,128, 128,255,128,
337         128,128,128, 128,128,128, 255,255,255,
338         255,128,128, 255,255,255, 255,255,255};
339     BYTE returned_data[27] = {0};
340     BYTE *lock_buffer=NULL;
341     UINT lock_buffer_stride=0;
342     UINT lock_buffer_size=0;
343     WICPixelFormatGUID pixelformat = {0};
344     UINT width=0, height=0;
345     double dpix=10.0, dpiy=10.0;
346     UINT count;
347     WICBitmapPaletteType palette_type;
348
349     hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
350         WICBitmapCacheOnLoad, &bitmap);
351     ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr);
352
353     if (FAILED(hr))
354         return;
355
356     hr = IWICImagingFactory_CreatePalette(factory, &palette);
357     ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
358
359     hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE);
360     ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
361
362     hr = IWICBitmap_SetPalette(bitmap, palette);
363     ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr);
364
365     IWICPalette_Release(palette);
366
367     rc.X = rc.Y = 0;
368     rc.Width = 3;
369     rc.Height = 3;
370     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock);
371     ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
372     if (SUCCEEDED(hr))
373     {
374         hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride);
375         ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr);
376         ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride);
377
378         hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer);
379         ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
380         ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size);
381         ok(lock_buffer != NULL, "got NULL data pointer\n");
382
383         for (i=0; i<3; i++)
384             memcpy(lock_buffer + lock_buffer_stride*i, bitmap_data + i*9, 9);
385
386         IWICBitmapLock_Release(lock);
387     }
388
389     hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0);
390     ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%x\n", hr);
391
392     hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource*)bitmap,
393         WICBitmapCacheOnLoad, &bitmap2);
394     ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr);
395
396     IWICBitmap_Release(bitmap);
397
398     if (FAILED(hr)) return;
399
400     hr = IWICImagingFactory_CreatePalette(factory, &palette);
401     ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
402
403     /* palette isn't copied for non-indexed formats? */
404     hr = IWICBitmap_CopyPalette(bitmap2, palette);
405     ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
406
407     IWICPalette_Release(palette);
408
409     hr = IWICBitmap_CopyPixels(bitmap2, NULL, 9, 27, returned_data);
410     ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr);
411
412     for (i=0; i<27; i++)
413         ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]);
414
415     hr = IWICBitmap_GetPixelFormat(bitmap2, &pixelformat);
416     ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr);
417     ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
418
419     hr = IWICBitmap_GetResolution(bitmap2, &dpix, &dpiy);
420     ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr);
421     ok(dpix == 12.0, "got %f, expected 12.0\n", dpix);
422     ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy);
423
424     hr = IWICBitmap_GetSize(bitmap2, &width, &height);
425     ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr);
426     ok(width == 3, "got %d, expected 3\n", width);
427     ok(height == 3, "got %d, expected 3\n", height);
428
429     IWICBitmap_Release(bitmap2);
430
431     /* Ensure palette is copied for indexed formats */
432     hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat4bppIndexed,
433         WICBitmapCacheOnLoad, &bitmap);
434     ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr);
435
436     hr = IWICImagingFactory_CreatePalette(factory, &palette);
437     ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
438
439     hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE);
440     ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
441
442     hr = IWICBitmap_SetPalette(bitmap, palette);
443     ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr);
444
445     IWICPalette_Release(palette);
446
447     hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource*)bitmap,
448         WICBitmapCacheOnLoad, &bitmap2);
449     ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr);
450
451     IWICBitmap_Release(bitmap);
452
453     hr = IWICImagingFactory_CreatePalette(factory, &palette);
454     ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
455
456     hr = IWICBitmap_CopyPalette(bitmap2, palette);
457     ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
458
459     hr = IWICPalette_GetColorCount(palette, &count);
460     ok(hr == S_OK, "IWICPalette_GetColorCount failed hr=%x\n", hr);
461     ok(count == 256, "unexpected count %d\n", count);
462
463     hr = IWICPalette_GetType(palette, &palette_type);
464     ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr);
465     ok(palette_type == WICBitmapPaletteTypeFixedGray256, "unexpected palette type %d\n", palette_type);
466
467     IWICPalette_Release(palette);
468
469     hr = IWICBitmap_GetPixelFormat(bitmap2, &pixelformat);
470     ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr);
471     ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed), "unexpected pixel format\n");
472
473     hr = IWICBitmap_GetSize(bitmap2, &width, &height);
474     ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr);
475     ok(width == 3, "got %d, expected 3\n", width);
476     ok(height == 3, "got %d, expected 3\n", height);
477
478     IWICBitmap_Release(bitmap2);
479 }
480
481 static void test_CreateBitmapFromMemory(void)
482 {
483     BYTE orig_data3x3[27] = {
484         128,128,255, 128,128,128, 128,255,128,
485         128,128,128, 128,128,128, 255,255,255,
486         255,128,128, 255,255,255, 255,255,255 };
487     BYTE data3x3[27];
488     BYTE data3x2[27] = {
489         128,128,255, 128,128,128, 128,255,128,
490         0,0,0, 0,128,128, 255,255,255,
491         255,128,128, 255,0,0, 0,0,0 };
492     BYTE data[27];
493     HRESULT hr;
494     IWICBitmap *bitmap;
495     UINT width, height, i;
496
497     memcpy(data3x3, orig_data3x3, sizeof(data3x3));
498
499     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
500                                                    0, 0, NULL, &bitmap);
501     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
502
503     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
504                                                    0, sizeof(data3x3), data3x3, &bitmap);
505     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
506
507     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
508                                                    6, sizeof(data3x3), data3x3, &bitmap);
509     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
510
511     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
512                                                    12, sizeof(data3x3), data3x3, &bitmap);
513     ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#x\n", hr);
514
515     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
516                                                    9, sizeof(data3x3) - 1, data3x3, &bitmap);
517     ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#x\n", hr);
518
519     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
520                                                    9, sizeof(data3x3), data3x3, &bitmap);
521     ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#x\n", hr);
522
523     hr = IWICBitmap_GetSize(bitmap, &width, &height);
524     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
525     ok(width == 3, "expected 3, got %u\n", width);
526     ok(height == 3, "expected 3, got %u\n", height);
527
528     data3x3[2] = 192;
529
530     memset(data, 0, sizeof(data));
531     hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, sizeof(data), data);
532     ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr);
533     for (i = 0; i < sizeof(data); i++)
534         ok(data[i] == orig_data3x3[i], "%u: expected %u, got %u\n", i, data[i], data3x3[i]);
535
536     IWICBitmap_Release(bitmap);
537
538     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 2, &GUID_WICPixelFormat24bppBGR,
539                                                    13, sizeof(orig_data3x3), orig_data3x3, &bitmap);
540     ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#x\n", hr);
541
542     hr = IWICBitmap_GetSize(bitmap, &width, &height);
543     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
544     ok(width == 3, "expected 3, got %u\n", width);
545     ok(height == 2, "expected 2, got %u\n", height);
546
547     memset(data, 0, sizeof(data));
548     hr = IWICBitmap_CopyPixels(bitmap, NULL, 13, sizeof(data), data);
549     ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr);
550     for (i = 0; i < sizeof(data); i++)
551         ok(data[i] == data3x2[i], "%u: expected %u, got %u\n", i, data3x2[i], data[i]);
552
553     IWICBitmap_Release(bitmap);
554 }
555
556 static void test_CreateBitmapFromHICON(void)
557 {
558     static const char bits[4096];
559     HICON icon;
560     ICONINFO info;
561     HRESULT hr;
562     IWICBitmap *bitmap;
563     UINT width, height;
564     WICPixelFormatGUID format;
565
566     /* 1 bpp mask */
567     info.fIcon = 1;
568     info.xHotspot = 0;
569     info.yHotspot = 0;
570     info.hbmColor = 0;
571     info.hbmMask = CreateBitmap(16, 32, 1, 1, bits);
572     ok(info.hbmMask != 0, "CreateBitmap failed\n");
573     icon = CreateIconIndirect(&info);
574     ok(icon != 0, "CreateIconIndirect failed\n");
575     DeleteObject(info.hbmMask);
576
577     hr = IWICImagingFactory_CreateBitmapFromHICON(factory, 0, NULL);
578     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
579
580     hr = IWICImagingFactory_CreateBitmapFromHICON(factory, 0, &bitmap);
581     ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_CURSOR_HANDLE), "expected ERROR_INVALID_CURSOR_HANDLE, got %#x\n", hr);
582
583     hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, NULL);
584     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
585
586     hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, &bitmap);
587     ok(hr == S_OK, "CreateBitmapFromHICON error %#x\n", hr);
588     DestroyIcon(icon);
589     if (hr != S_OK) return;
590
591     IWICBitmap_GetPixelFormat(bitmap, &format);
592     ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA),
593        "unexpected pixel format %s\n", debugstr_guid(&format));
594
595     IWICBitmap_GetSize(bitmap, &width, &height);
596     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
597     ok(width == 16, "expected 16, got %u\n", width);
598     ok(height == 16, "expected 16, got %u\n", height);
599
600     IWICBitmap_Release(bitmap);
601
602     /* 24 bpp color, 1 bpp mask */
603     info.fIcon = 1;
604     info.xHotspot = 0;
605     info.yHotspot = 0;
606     info.hbmColor = CreateBitmap(16, 16, 1, 24, bits);
607     ok(info.hbmColor != 0, "CreateBitmap failed\n");
608     info.hbmMask = CreateBitmap(16, 16, 1, 1, bits);
609     ok(info.hbmMask != 0, "CreateBitmap failed\n");
610     icon = CreateIconIndirect(&info);
611     ok(icon != 0, "CreateIconIndirect failed\n");
612     DeleteObject(info.hbmColor);
613     DeleteObject(info.hbmMask);
614
615     hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, &bitmap);
616     ok(hr == S_OK, "CreateBitmapFromHICON error %#x\n", hr);
617     DestroyIcon(icon);
618
619     IWICBitmap_GetPixelFormat(bitmap, &format);
620     ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA),
621        "unexpected pixel format %s\n", debugstr_guid(&format));
622
623     IWICBitmap_GetSize(bitmap, &width, &height);
624     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
625     ok(width == 16, "expected 16, got %u\n", width);
626     ok(height == 16, "expected 16, got %u\n", height);
627
628     IWICBitmap_Release(bitmap);
629 }
630
631 static void test_CreateBitmapFromHBITMAP(void)
632 {
633     /* 8 bpp data must be aligned to a DWORD boundary for a DIB */
634     static const BYTE data_8bpp_pal_dib[12] = { 0,1,2,0, 1,2,0,0, 2,1,0,0 };
635     static const BYTE data_8bpp_rgb_dib[12] = { 0xf0,0x0f,0xff,0, 0x0f,0xff,0xf0,0, 0xf0,0x0f,0xff,0 };
636     static const BYTE data_8bpp_pal_wic[12] = { 0xd,0xe,0x10,0, 0xe,0x10,0xd,0, 0x10,0xe,0xd,0 };
637     static const PALETTEENTRY pal_data[3] = { {0xff,0,0,0}, {0,0xff,0,0}, {0,0,0xff,0} };
638     char pal_buf[sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 255];
639     LOGPALETTE *pal = (LOGPALETTE *)pal_buf;
640     HBITMAP hbmp;
641     HPALETTE hpal;
642     BYTE data[12];
643     HRESULT hr;
644     IWICBitmap *bitmap;
645     UINT width, height, i, count;
646     WICPixelFormatGUID format;
647     IWICPalette *palette;
648     WICBitmapPaletteType type;
649
650     /* 8 bpp without palette */
651     hbmp = create_dib(3, 3, 8, NULL, data_8bpp_rgb_dib);
652     ok(hbmp != 0, "failed to create bitmap\n");
653
654     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, 0, 0, WICBitmapCacheOnLoad, &bitmap);
655 todo_wine
656     ok(hr == WINCODEC_ERR_WIN32ERROR || hr == 0x88980003 /*XP*/, "expected WINCODEC_ERR_WIN32ERROR, got %#x\n", hr);
657
658     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapCacheOnLoad, NULL);
659 todo_wine
660     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
661
662     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapCacheOnLoad, &bitmap);
663 todo_wine
664     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
665     if (hr != S_OK) return;
666
667     IWICBitmap_GetPixelFormat(bitmap, &format);
668     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
669        "unexpected pixel format %s\n", debugstr_guid(&format));
670
671     hr = IWICBitmap_GetSize(bitmap, &width, &height);
672     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
673     ok(width == 3, "expected 3, got %u\n", width);
674     ok(height == 3, "expected 3, got %u\n", height);
675
676     memset(data, 0, sizeof(data));
677     hr = IWICBitmap_CopyPixels(bitmap, NULL, 4, sizeof(data), data);
678     ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr);
679     for (i = 0; i < sizeof(data); i++)
680         ok(data[i] == data_8bpp_rgb_dib[i], "%u: expected %#x, got %#x\n", i, data_8bpp_rgb_dib[i], data[i]);
681
682     IWICBitmap_Release(bitmap);
683     DeleteObject(hbmp);
684
685     /* 8 bpp with a 3 entries palette */
686     memset(pal_buf, 0, sizeof(pal_buf));
687     pal->palVersion = 0x300;
688     pal->palNumEntries = 3;
689     memcpy(pal->palPalEntry, pal_data, sizeof(pal_data));
690     hpal = CreatePalette(pal);
691     ok(hpal != 0, "CreatePalette failed\n");
692
693     hbmp = create_dib(3, 3, 8, pal, data_8bpp_pal_dib);
694     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapCacheOnLoad, &bitmap);
695     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
696
697     IWICBitmap_GetPixelFormat(bitmap, &format);
698     ok(IsEqualGUID(&format, &GUID_WICPixelFormat4bppIndexed),
699        "unexpected pixel format %s\n", debugstr_guid(&format));
700
701     hr = IWICBitmap_GetSize(bitmap, &width, &height);
702     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
703     ok(width == 3, "expected 3, got %u\n", width);
704     ok(height == 3, "expected 3, got %u\n", height);
705
706     hr = IWICImagingFactory_CreatePalette(factory, &palette);
707     ok(hr == S_OK, "CreatePalette error %#x\n", hr);
708     hr = IWICBitmap_CopyPalette(bitmap, palette);
709     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
710
711     hr = IWICPalette_GetType(palette, &type);
712     ok(hr == S_OK, "%u: GetType error %#x\n", i, hr);
713     ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
714
715     hr = IWICPalette_GetColorCount(palette, &count);
716     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
717     ok(count == 16, "expected 16, got %u\n", count);
718
719     IWICPalette_Release(palette);
720
721     IWICBitmap_Release(bitmap);
722     DeleteObject(hbmp);
723     DeleteObject(hpal);
724
725     /* 8 bpp with a 256 entries palette */
726     memset(pal_buf, 0, sizeof(pal_buf));
727     pal->palVersion = 0x300;
728     pal->palNumEntries = 256;
729     memcpy(pal->palPalEntry, pal_data, sizeof(pal_data));
730     hpal = CreatePalette(pal);
731     ok(hpal != 0, "CreatePalette failed\n");
732
733     hbmp = create_dib(3, 3, 8, pal, data_8bpp_pal_dib);
734     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapCacheOnLoad, &bitmap);
735     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
736
737     IWICBitmap_GetPixelFormat(bitmap, &format);
738     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
739        "unexpected pixel format %s\n", debugstr_guid(&format));
740
741     hr = IWICBitmap_GetSize(bitmap, &width, &height);
742     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
743     ok(width == 3, "expected 3, got %u\n", width);
744     ok(height == 3, "expected 3, got %u\n", height);
745
746     hr = IWICImagingFactory_CreatePalette(factory, &palette);
747     ok(hr == S_OK, "CreatePalette error %#x\n", hr);
748     hr = IWICBitmap_CopyPalette(bitmap, palette);
749     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
750
751     hr = IWICPalette_GetType(palette, &type);
752     ok(hr == S_OK, "%u: GetType error %#x\n", i, hr);
753     ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
754
755     hr = IWICPalette_GetColorCount(palette, &count);
756     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
757     ok(count == 256, "expected 256, got %u\n", count);
758
759     IWICPalette_Release(palette);
760
761     memset(data, 0, sizeof(data));
762     hr = IWICBitmap_CopyPixels(bitmap, NULL, 4, sizeof(data), data);
763     ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr);
764     for (i = 0; i < sizeof(data); i++)
765         ok(data[i] == data_8bpp_pal_wic[i], "%u: expected %#x, got %#x\n", i, data_8bpp_pal_wic[i], data[i]);
766
767     IWICBitmap_Release(bitmap);
768     DeleteObject(hbmp);
769     DeleteObject(hpal);
770 }
771
772 START_TEST(bitmap)
773 {
774     HRESULT hr;
775
776     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
777
778     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
779         &IID_IWICImagingFactory, (void**)&factory);
780     ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
781
782     test_createbitmap();
783     test_createbitmapfromsource();
784     test_CreateBitmapFromMemory();
785     test_CreateBitmapFromHICON();
786     test_CreateBitmapFromHBITMAP();
787
788     IWICImagingFactory_Release(factory);
789
790     CoUninitialize();
791 }