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 #define CONST_VTABLE
27 
28 #include "windef.h"
29 #include "objbase.h"
30 #include "wincodec.h"
31 #include "wine/test.h"
32 
33 static IWICImagingFactory *factory;
34 
35 static HRESULT WINAPI bitmapsource_QueryInterface(IWICBitmapSource *iface, REFIID iid, void **ppv)
36 {
37     if (IsEqualIID(&IID_IUnknown, iid) ||
38         IsEqualIID(&IID_IWICBitmapSource, iid))
39     {
40         *ppv = iface;
41     }
42     else
43     {
44         *ppv = NULL;
45         return E_NOINTERFACE;
46     }
47 
48     return S_OK;
49 }
50 
51 static ULONG WINAPI bitmapsource_AddRef(IWICBitmapSource *iface)
52 {
53     return 2;
54 }
55 
56 static ULONG WINAPI bitmapsource_Release(IWICBitmapSource *iface)
57 {
58     return 1;
59 }
60 
61 static HRESULT WINAPI bitmapsource_GetSize(IWICBitmapSource *iface, UINT *width, UINT *height)
62 {
63     *width = *height = 10;
64     return S_OK;
65 }
66 
67 static HRESULT WINAPI bitmapsource_GetPixelFormat(IWICBitmapSource *iface,
68     WICPixelFormatGUID *format)
69 {
70     return E_NOTIMPL;
71 }
72 
73 static HRESULT WINAPI bitmapsource_GetResolution(IWICBitmapSource *iface,
74     double *dpiX, double *dpiY)
75 {
76     return E_NOTIMPL;
77 }
78 
79 static HRESULT WINAPI bitmapsource_CopyPalette(IWICBitmapSource *iface,
80     IWICPalette *palette)
81 {
82     return E_NOTIMPL;
83 }
84 
85 static WICRect g_rect;
86 static BOOL called_CopyPixels;
87 
88 static HRESULT WINAPI bitmapsource_CopyPixels(IWICBitmapSource *iface,
89     const WICRect *rc, UINT stride, UINT buffer_size, BYTE *buffer)
90 {
91     if (rc) g_rect = *rc;
92     called_CopyPixels = TRUE;
93     return S_OK;
94 }
95 
96 static const IWICBitmapSourceVtbl sourcevtbl = {
97     bitmapsource_QueryInterface,
98     bitmapsource_AddRef,
99     bitmapsource_Release,
100     bitmapsource_GetSize,
101     bitmapsource_GetPixelFormat,
102     bitmapsource_GetResolution,
103     bitmapsource_CopyPalette,
104     bitmapsource_CopyPixels
105 };
106 
107 static IWICBitmapSource bitmapsource = { &sourcevtbl };
108 
109 static HBITMAP create_dib(int width, int height, int bpp, LOGPALETTE *pal, const void *data)
110 {
111     char bmibuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255];
112     BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
113     void *bits;
114     HBITMAP hdib;
115     BITMAP bm;
116 
117     memset(bmibuf, 0, sizeof(bmibuf));
118     bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
119     bmi->bmiHeader.biWidth = width;
120     bmi->bmiHeader.biHeight = -height;
121     bmi->bmiHeader.biBitCount = bpp;
122     bmi->bmiHeader.biPlanes = 1;
123     bmi->bmiHeader.biCompression = BI_RGB;
124     if (pal)
125     {
126         WORD i;
127 
128         assert(pal->palNumEntries <= 256);
129         for (i = 0; i < pal->palNumEntries; i++)
130         {
131             bmi->bmiColors[i].rgbRed = pal->palPalEntry[i].peRed;
132             bmi->bmiColors[i].rgbGreen = pal->palPalEntry[i].peGreen;
133             bmi->bmiColors[i].rgbBlue = pal->palPalEntry[i].peBlue;
134             bmi->bmiColors[i].rgbReserved = 0;
135         }
136 
137         bmi->bmiHeader.biClrUsed = pal->palNumEntries;
138         bmi->bmiHeader.biClrImportant = pal->palNumEntries;
139     }
140     hdib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
141     ok(hdib != 0, "CreateDIBSection(%dx%d,%d bpp) failed\n", width, height, bpp);
142 
143     GetObjectW(hdib, sizeof(bm), &bm);
144     ok(bm.bmWidth == width, "expected %d, got %d\n", width, bm.bmWidth);
145     ok(bm.bmHeight == height, "expected %d, got %d\n", height, bm.bmHeight);
146     ok(bm.bmPlanes == 1, "expected 1, got %d\n", bm.bmPlanes);
147     ok(bm.bmBitsPixel == bpp, "expected %d, got %d\n", bpp, bm.bmBitsPixel);
148 
149     if (data) memcpy(bits, data, bm.bmWidthBytes * bm.bmHeight);
150 
151     return hdib;
152 }
153 
154 static void test_createbitmap(void)
155 {
156     HRESULT hr;
157     IWICBitmap *bitmap;
158     IWICPalette *palette;
159     IWICBitmapLock *lock, *lock2;
160     WICBitmapPaletteType palettetype;
161     int i;
162     WICRect rc;
163     const BYTE bitmap_data[27] = {
164         128,128,255, 128,128,128, 128,255,128,
165         128,128,128, 128,128,128, 255,255,255,
166         255,128,128, 255,255,255, 255,255,255};
167     BYTE returned_data[27] = {0};
168     BYTE *lock_buffer=NULL, *base_lock_buffer=NULL;
169     UINT lock_buffer_size=0;
170     UINT lock_buffer_stride=0;
171     WICPixelFormatGUID pixelformat = {0};
172     UINT width=0, height=0;
173     double dpix=10.0, dpiy=10.0;
174     int can_lock_null = 1;
175 
176     hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
177         WICBitmapCacheOnLoad, &bitmap);
178     ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr);
179 
180     if (FAILED(hr))
181         return;
182 
183     hr = IWICImagingFactory_CreatePalette(factory, &palette);
184     ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
185 
186     /* Palette is unavailable until explicitly set */
187     hr = IWICBitmap_CopyPalette(bitmap, palette);
188     ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
189 
190     hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE);
191     ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
192 
193     hr = IWICBitmap_SetPalette(bitmap, palette);
194     ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr);
195 
196     hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray4, FALSE);
197     ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
198 
199     hr = IWICBitmap_CopyPalette(bitmap, palette);
200     ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
201 
202     hr = IWICPalette_GetType(palette, &palettetype);
203     ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr);
204     ok(palettetype == WICBitmapPaletteTypeFixedGray256,
205         "expected WICBitmapPaletteTypeFixedGray256, got %x\n", palettetype);
206 
207     IWICPalette_Release(palette);
208 
209     /* pixel data is initially zeroed */
210     hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, 27, returned_data);
211     ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr);
212 
213     for (i=0; i<27; i++)
214         ok(returned_data[i] == 0, "returned_data[%i] == %i\n", i, returned_data[i]);
215 
216     /* Invalid lock rects */
217     rc.X = rc.Y = 0;
218     rc.Width = 4;
219     rc.Height = 3;
220     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
221     ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
222     if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
223 
224     rc.Width = 3;
225     rc.Height = 4;
226     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
227     ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
228     if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
229 
230     rc.Height = 3;
231     rc.X = 4;
232     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
233     ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
234     if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
235 
236     rc.X = 0;
237     rc.Y = 4;
238     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
239     ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
240     if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
241 
242     /* NULL lock rect */
243     hr = IWICBitmap_Lock(bitmap, NULL, WICBitmapLockRead, &lock);
244     ok(hr == S_OK || broken(hr == E_INVALIDARG) /* winxp */, "IWICBitmap_Lock failed hr=%x\n", hr);
245 
246     if (SUCCEEDED(hr))
247     {
248         /* entire bitmap is locked */
249         hr = IWICBitmapLock_GetSize(lock, &width, &height);
250         ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr);
251         ok(width == 3, "got %d, expected 3\n", width);
252         ok(height == 3, "got %d, expected 3\n", height);
253 
254         IWICBitmapLock_Release(lock);
255     }
256     else
257         can_lock_null = 0;
258 
259     /* lock with a valid rect */
260     rc.Y = 0;
261     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
262     ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
263     if (SUCCEEDED(hr))
264     {
265         hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride);
266         ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr);
267         /* stride is divisible by 4 */
268         ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride);
269 
270         hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer);
271         ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
272         /* buffer size does not include padding from the last row */
273         ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size);
274         ok(lock_buffer != NULL, "got NULL data pointer\n");
275         base_lock_buffer = lock_buffer;
276 
277         hr = IWICBitmapLock_GetPixelFormat(lock, &pixelformat);
278         ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%x\n", hr);
279         ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
280 
281         hr = IWICBitmapLock_GetSize(lock, &width, &height);
282         ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr);
283         ok(width == 3, "got %d, expected 3\n", width);
284         ok(height == 3, "got %d, expected 3\n", height);
285 
286         /* We can have multiple simultaneous read locks */
287         hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2);
288         ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
289 
290         if (SUCCEEDED(hr))
291         {
292             hr = IWICBitmapLock_GetDataPointer(lock2, &lock_buffer_size, &lock_buffer);
293             ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
294             ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size);
295             ok(lock_buffer == base_lock_buffer, "got %p, expected %p\n", lock_buffer, base_lock_buffer);
296 
297             IWICBitmapLock_Release(lock2);
298         }
299 
300         if (can_lock_null) /* this hangs on xp/vista */
301         {
302             /* But not a read and a write lock */
303             hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock2);
304             ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr);
305         }
306 
307         /* But we don't need a write lock to write */
308         if (base_lock_buffer)
309         {
310             for (i=0; i<3; i++)
311                 memcpy(base_lock_buffer + lock_buffer_stride*i, bitmap_data + i*9, 9);
312         }
313 
314         IWICBitmapLock_Release(lock);
315     }
316 
317     /* test that the data we wrote is returned by CopyPixels */
318     hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, 27, returned_data);
319     ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr);
320 
321     for (i=0; i<27; i++)
322         ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]);
323 
324     /* try a valid partial rect, and write mode */
325     rc.X = 2;
326     rc.Y = 0;
327     rc.Width = 1;
328     rc.Height = 2;
329     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock);
330     ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
331 
332     if (SUCCEEDED(hr))
333     {
334         if (can_lock_null) /* this hangs on xp/vista */
335         {
336             /* Can't lock again while locked for writing */
337             hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock2);
338             ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr);
339 
340             hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2);
341             ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr);
342         }
343 
344         hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride);
345         ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr);
346         ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride);
347 
348         hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer);
349         ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
350         ok(lock_buffer_size == 15, "got %i, expected 15\n", lock_buffer_size);
351         ok(lock_buffer == base_lock_buffer+6, "got %p, expected %p+6\n", lock_buffer, base_lock_buffer);
352 
353         hr = IWICBitmapLock_GetPixelFormat(lock, &pixelformat);
354         ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%x\n", hr);
355         ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
356 
357         hr = IWICBitmapLock_GetSize(lock, &width, &height);
358         ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr);
359         ok(width == 1, "got %d, expected 1\n", width);
360         ok(height == 2, "got %d, expected 2\n", height);
361 
362         IWICBitmapLock_Release(lock);
363     }
364 
365     hr = IWICBitmap_GetPixelFormat(bitmap, &pixelformat);
366     ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr);
367     ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
368 
369     hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy);
370     ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr);
371     ok(dpix == 0.0, "got %f, expected 0.0\n", dpix);
372     ok(dpiy == 0.0, "got %f, expected 0.0\n", dpiy);
373 
374     hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0);
375     ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%x\n", hr);
376 
377     hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy);
378     ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr);
379     ok(dpix == 12.0, "got %f, expected 12.0\n", dpix);
380     ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy);
381 
382     hr = IWICBitmap_GetSize(bitmap, &width, &height);
383     ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr);
384     ok(width == 3, "got %d, expected 3\n", width);
385     ok(height == 3, "got %d, expected 3\n", height);
386 
387     IWICBitmap_Release(bitmap);
388 }
389 
390 static void test_createbitmapfromsource(void)
391 {
392     HRESULT hr;
393     IWICBitmap *bitmap, *bitmap2;
394     IWICPalette *palette;
395     IWICBitmapLock *lock;
396     int i;
397     WICRect rc;
398     const BYTE bitmap_data[27] = {
399         128,128,255, 128,128,128, 128,255,128,
400         128,128,128, 128,128,128, 255,255,255,
401         255,128,128, 255,255,255, 255,255,255};
402     BYTE returned_data[27] = {0};
403     BYTE *lock_buffer=NULL;
404     UINT lock_buffer_stride=0;
405     UINT lock_buffer_size=0;
406     WICPixelFormatGUID pixelformat = {0};
407     UINT width=0, height=0;
408     double dpix=10.0, dpiy=10.0;
409     UINT count;
410     WICBitmapPaletteType palette_type;
411 
412     hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
413         WICBitmapCacheOnLoad, &bitmap);
414     ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr);
415 
416     if (FAILED(hr))
417         return;
418 
419     hr = IWICImagingFactory_CreatePalette(factory, &palette);
420     ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
421 
422     hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE);
423     ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
424 
425     hr = IWICBitmap_SetPalette(bitmap, palette);
426     ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr);
427 
428     IWICPalette_Release(palette);
429 
430     rc.X = rc.Y = 0;
431     rc.Width = 3;
432     rc.Height = 3;
433     hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock);
434     ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
435     if (SUCCEEDED(hr))
436     {
437         hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride);
438         ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr);
439         ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride);
440 
441         hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer);
442         ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
443         ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size);
444         ok(lock_buffer != NULL, "got NULL data pointer\n");
445 
446         for (i=0; i<3; i++)
447             memcpy(lock_buffer + lock_buffer_stride*i, bitmap_data + i*9, 9);
448 
449         IWICBitmapLock_Release(lock);
450     }
451 
452     hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0);
453     ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%x\n", hr);
454 
455     /* WICBitmapNoCache */
456     hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource *)bitmap,
457         WICBitmapNoCache, &bitmap2);
458     ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr);
459     ok(bitmap2 == bitmap, "Unexpected bitmap instance.\n");
460 
461     IWICBitmap_Release(bitmap2);
462 
463     bitmap2 = (void *)0xdeadbeef;
464     hr = IWICImagingFactory_CreateBitmapFromSource(factory, &bitmapsource, WICBitmapNoCache, &bitmap2);
465     ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
466     ok(bitmap2 == (void *)0xdeadbeef, "Unexpected pointer %p.\n", bitmap2);
467 
468     hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource*)bitmap,
469         WICBitmapCacheOnLoad, &bitmap2);
470     ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr);
471 
472     IWICBitmap_Release(bitmap);
473 
474     if (FAILED(hr)) return;
475 
476     hr = IWICImagingFactory_CreatePalette(factory, &palette);
477     ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
478 
479     /* palette isn't copied for non-indexed formats? */
480     hr = IWICBitmap_CopyPalette(bitmap2, palette);
481     ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
482 
483     IWICPalette_Release(palette);
484 
485     hr = IWICBitmap_CopyPixels(bitmap2, NULL, 9, 27, returned_data);
486     ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr);
487 
488     for (i=0; i<27; i++)
489         ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]);
490 
491     hr = IWICBitmap_GetPixelFormat(bitmap2, &pixelformat);
492     ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr);
493     ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
494 
495     hr = IWICBitmap_GetResolution(bitmap2, &dpix, &dpiy);
496     ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr);
497     ok(dpix == 12.0, "got %f, expected 12.0\n", dpix);
498     ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy);
499 
500     hr = IWICBitmap_GetSize(bitmap2, &width, &height);
501     ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr);
502     ok(width == 3, "got %d, expected 3\n", width);
503     ok(height == 3, "got %d, expected 3\n", height);
504 
505     IWICBitmap_Release(bitmap2);
506 
507     /* Ensure palette is copied for indexed formats */
508     hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat4bppIndexed,
509         WICBitmapCacheOnLoad, &bitmap);
510     ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr);
511 
512     hr = IWICImagingFactory_CreatePalette(factory, &palette);
513     ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
514 
515     hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE);
516     ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
517 
518     hr = IWICBitmap_SetPalette(bitmap, palette);
519     ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr);
520 
521     IWICPalette_Release(palette);
522 
523     hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource*)bitmap,
524         WICBitmapCacheOnLoad, &bitmap2);
525     ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr);
526 
527     IWICBitmap_Release(bitmap);
528 
529     hr = IWICImagingFactory_CreatePalette(factory, &palette);
530     ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
531 
532     hr = IWICBitmap_CopyPalette(bitmap2, palette);
533     ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
534 
535     hr = IWICPalette_GetColorCount(palette, &count);
536     ok(hr == S_OK, "IWICPalette_GetColorCount failed hr=%x\n", hr);
537     ok(count == 256, "unexpected count %d\n", count);
538 
539     hr = IWICPalette_GetType(palette, &palette_type);
540     ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr);
541     ok(palette_type == WICBitmapPaletteTypeFixedGray256, "unexpected palette type %d\n", palette_type);
542 
543     IWICPalette_Release(palette);
544 
545     hr = IWICBitmap_GetPixelFormat(bitmap2, &pixelformat);
546     ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr);
547     ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed), "unexpected pixel format\n");
548 
549     hr = IWICBitmap_GetSize(bitmap2, &width, &height);
550     ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr);
551     ok(width == 3, "got %d, expected 3\n", width);
552     ok(height == 3, "got %d, expected 3\n", height);
553 
554     /* CreateBitmapFromSourceRect */
555     hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 16, 32, &bitmap);
556     ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr);
557     hr = IWICBitmap_GetSize(bitmap, &width, &height);
558     ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr);
559     ok(width == 3, "Unexpected width %u.\n", width);
560     ok(height == 3, "Unexpected height %u.\n", height);
561     IWICBitmap_Release(bitmap);
562 
563     hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 1, 1, &bitmap);
564     ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr);
565     hr = IWICBitmap_GetSize(bitmap, &width, &height);
566     ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr);
567     ok(width == 1, "Unexpected width %u.\n", width);
568     ok(height == 1, "Unexpected height %u.\n", height);
569     IWICBitmap_Release(bitmap);
570 
571     hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 2, 1, 16, 32, &bitmap);
572     ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr);
573     hr = IWICBitmap_GetSize(bitmap, &width, &height);
574     ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr);
575     ok(width == 1, "Unexpected width %u.\n", width);
576     ok(height == 2, "Unexpected height %u.\n", height);
577     IWICBitmap_Release(bitmap);
578 
579     hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 0, 2, &bitmap);
580     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
581 
582     hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 2, 0, &bitmap);
583     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
584 
585     hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 1, 3, 16, 32, &bitmap);
586     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
587 
588     hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 3, 1, 16, 32, &bitmap);
589     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
590 
591     IWICBitmap_Release(bitmap2);
592 }
593 
594 static void test_CreateBitmapFromMemory(void)
595 {
596     BYTE orig_data3x3[27] = {
597         128,128,255, 128,128,128, 128,255,128,
598         128,128,128, 128,128,128, 255,255,255,
599         255,128,128, 255,255,255, 255,255,255 };
600     BYTE data3x3[27];
601     BYTE data3x2[27] = {
602         128,128,255, 128,128,128, 128,255,128,
603         0,0,0, 0,128,128, 255,255,255,
604         255,128,128, 255,0,0, 0,0,0 };
605     BYTE data[27];
606     HRESULT hr;
607     IWICBitmap *bitmap;
608     UINT width, height, i;
609 
610     memcpy(data3x3, orig_data3x3, sizeof(data3x3));
611 
612     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
613                                                    0, 0, NULL, &bitmap);
614     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
615 
616     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
617                                                    0, sizeof(data3x3), data3x3, &bitmap);
618     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
619 
620     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
621                                                    6, sizeof(data3x3), data3x3, &bitmap);
622     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
623 
624     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
625                                                    12, sizeof(data3x3), data3x3, &bitmap);
626     ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#x\n", hr);
627 
628     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
629                                                    9, sizeof(data3x3) - 1, data3x3, &bitmap);
630     ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#x\n", hr);
631 
632     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
633                                                    9, sizeof(data3x3), data3x3, &bitmap);
634     ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#x\n", hr);
635 
636     hr = IWICBitmap_GetSize(bitmap, &width, &height);
637     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
638     ok(width == 3, "expected 3, got %u\n", width);
639     ok(height == 3, "expected 3, got %u\n", height);
640 
641     data3x3[2] = 192;
642 
643     memset(data, 0, sizeof(data));
644     hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, sizeof(data), data);
645     ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr);
646     for (i = 0; i < sizeof(data); i++)
647         ok(data[i] == orig_data3x3[i], "%u: expected %u, got %u\n", i, data[i], data3x3[i]);
648 
649     IWICBitmap_Release(bitmap);
650 
651     hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 2, &GUID_WICPixelFormat24bppBGR,
652                                                    13, sizeof(orig_data3x3), orig_data3x3, &bitmap);
653     ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#x\n", hr);
654 
655     hr = IWICBitmap_GetSize(bitmap, &width, &height);
656     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
657     ok(width == 3, "expected 3, got %u\n", width);
658     ok(height == 2, "expected 2, got %u\n", height);
659 
660     memset(data, 0, sizeof(data));
661     hr = IWICBitmap_CopyPixels(bitmap, NULL, 13, sizeof(data), data);
662     ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr);
663     for (i = 0; i < sizeof(data); i++)
664         ok(data[i] == data3x2[i], "%u: expected %u, got %u\n", i, data3x2[i], data[i]);
665 
666     IWICBitmap_Release(bitmap);
667 }
668 
669 static void test_CreateBitmapFromHICON(void)
670 {
671     static const char bits[4096];
672     HICON icon;
673     ICONINFO info;
674     HRESULT hr;
675     IWICBitmap *bitmap;
676     UINT width, height;
677     WICPixelFormatGUID format;
678 
679     /* 1 bpp mask */
680     info.fIcon = 1;
681     info.xHotspot = 0;
682     info.yHotspot = 0;
683     info.hbmColor = 0;
684     info.hbmMask = CreateBitmap(16, 32, 1, 1, bits);
685     ok(info.hbmMask != 0, "CreateBitmap failed\n");
686     icon = CreateIconIndirect(&info);
687     ok(icon != 0, "CreateIconIndirect failed\n");
688     DeleteObject(info.hbmMask);
689 
690     hr = IWICImagingFactory_CreateBitmapFromHICON(factory, 0, NULL);
691     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
692 
693     hr = IWICImagingFactory_CreateBitmapFromHICON(factory, 0, &bitmap);
694     ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_CURSOR_HANDLE), "expected ERROR_INVALID_CURSOR_HANDLE, got %#x\n", hr);
695 
696     hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, NULL);
697     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
698 
699     hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, &bitmap);
700     ok(hr == S_OK, "CreateBitmapFromHICON error %#x\n", hr);
701     DestroyIcon(icon);
702     if (hr != S_OK) return;
703 
704     IWICBitmap_GetPixelFormat(bitmap, &format);
705     ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA),
706        "unexpected pixel format %s\n", wine_dbgstr_guid(&format));
707 
708     hr = IWICBitmap_GetSize(bitmap, &width, &height);
709     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
710     ok(width == 16, "expected 16, got %u\n", width);
711     ok(height == 16, "expected 16, got %u\n", height);
712 
713     IWICBitmap_Release(bitmap);
714 
715     /* 24 bpp color, 1 bpp mask */
716     info.fIcon = 1;
717     info.xHotspot = 0;
718     info.yHotspot = 0;
719     info.hbmColor = CreateBitmap(16, 16, 1, 24, bits);
720     ok(info.hbmColor != 0, "CreateBitmap failed\n");
721     info.hbmMask = CreateBitmap(16, 16, 1, 1, bits);
722     ok(info.hbmMask != 0, "CreateBitmap failed\n");
723     icon = CreateIconIndirect(&info);
724     ok(icon != 0, "CreateIconIndirect failed\n");
725     DeleteObject(info.hbmColor);
726     DeleteObject(info.hbmMask);
727 
728     hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, &bitmap);
729     ok(hr == S_OK, "CreateBitmapFromHICON error %#x\n", hr);
730     DestroyIcon(icon);
731 
732     IWICBitmap_GetPixelFormat(bitmap, &format);
733     ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA),
734        "unexpected pixel format %s\n", wine_dbgstr_guid(&format));
735 
736     hr = IWICBitmap_GetSize(bitmap, &width, &height);
737     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
738     ok(width == 16, "expected 16, got %u\n", width);
739     ok(height == 16, "expected 16, got %u\n", height);
740 
741     IWICBitmap_Release(bitmap);
742 }
743 
744 static void test_CreateBitmapFromHBITMAP(void)
745 {
746     /* 8 bpp data must be aligned to a DWORD boundary for a DIB */
747     static const BYTE data_8bpp_pal_dib[12] = { 0,1,2,0, 1,2,0,0, 2,1,0,0 };
748     static const BYTE data_8bpp_rgb_dib[12] = { 0xf0,0x0f,0xff,0, 0x0f,0xff,0xf0,0, 0xf0,0x0f,0xff,0 };
749     static const BYTE data_8bpp_pal_wic[12] = { 0xd,0xe,0x10,0, 0xe,0x10,0xd,0, 0x10,0xe,0xd,0 };
750     static const PALETTEENTRY pal_data[3] = { {0xff,0,0,0}, {0,0xff,0,0}, {0,0,0xff,0} };
751     char pal_buf[sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 255];
752     LOGPALETTE *pal = (LOGPALETTE *)pal_buf;
753     HBITMAP hbmp;
754     HPALETTE hpal;
755     BYTE data[12];
756     HRESULT hr;
757     IWICBitmap *bitmap;
758     UINT width, height, i, count;
759     WICPixelFormatGUID format;
760     IWICPalette *palette;
761     WICBitmapPaletteType type;
762 
763     /* 8 bpp without palette */
764     hbmp = create_dib(3, 3, 8, NULL, data_8bpp_rgb_dib);
765     ok(hbmp != 0, "failed to create bitmap\n");
766 
767     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, 0, 0, WICBitmapIgnoreAlpha, &bitmap);
768     ok(hr == WINCODEC_ERR_WIN32ERROR || hr == 0x88980003 /*XP*/, "expected WINCODEC_ERR_WIN32ERROR, got %#x\n", hr);
769 
770     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapIgnoreAlpha, NULL);
771     ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
772 
773     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapIgnoreAlpha, &bitmap);
774     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
775 
776     IWICBitmap_GetPixelFormat(bitmap, &format);
777     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
778        "unexpected pixel format %s\n", wine_dbgstr_guid(&format));
779 
780     hr = IWICBitmap_GetSize(bitmap, &width, &height);
781     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
782     ok(width == 3, "expected 3, got %u\n", width);
783     ok(height == 3, "expected 3, got %u\n", height);
784 
785     memset(data, 0, sizeof(data));
786     hr = IWICBitmap_CopyPixels(bitmap, NULL, 4, sizeof(data), data);
787     ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr);
788     for (i = 0; i < sizeof(data); i++)
789         ok(data[i] == data_8bpp_rgb_dib[i], "%u: expected %#x, got %#x\n", i, data_8bpp_rgb_dib[i], data[i]);
790 
791     IWICBitmap_Release(bitmap);
792     DeleteObject(hbmp);
793 
794     /* 8 bpp with a 3 entries palette */
795     memset(pal_buf, 0, sizeof(pal_buf));
796     pal->palVersion = 0x300;
797     pal->palNumEntries = 3;
798     memcpy(pal->palPalEntry, pal_data, sizeof(pal_data));
799     hpal = CreatePalette(pal);
800     ok(hpal != 0, "CreatePalette failed\n");
801 
802     hbmp = create_dib(3, 3, 8, pal, data_8bpp_pal_dib);
803     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapIgnoreAlpha, &bitmap);
804     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
805 
806     IWICBitmap_GetPixelFormat(bitmap, &format);
807 todo_wine
808     ok(IsEqualGUID(&format, &GUID_WICPixelFormat4bppIndexed),
809        "unexpected pixel format %s\n", wine_dbgstr_guid(&format));
810 
811     hr = IWICBitmap_GetSize(bitmap, &width, &height);
812     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
813     ok(width == 3, "expected 3, got %u\n", width);
814     ok(height == 3, "expected 3, got %u\n", height);
815 
816     hr = IWICImagingFactory_CreatePalette(factory, &palette);
817     ok(hr == S_OK, "CreatePalette error %#x\n", hr);
818     hr = IWICBitmap_CopyPalette(bitmap, palette);
819     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
820 
821     hr = IWICPalette_GetType(palette, &type);
822     ok(hr == S_OK, "%u: GetType error %#x\n", i, hr);
823     ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
824 
825     hr = IWICPalette_GetColorCount(palette, &count);
826     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
827 todo_wine
828     ok(count == 16, "expected 16, got %u\n", count);
829 
830     IWICPalette_Release(palette);
831 
832     IWICBitmap_Release(bitmap);
833     DeleteObject(hbmp);
834     DeleteObject(hpal);
835 
836     /* 8 bpp with a 256 entries palette */
837     memset(pal_buf, 0, sizeof(pal_buf));
838     pal->palVersion = 0x300;
839     pal->palNumEntries = 256;
840     memcpy(pal->palPalEntry, pal_data, sizeof(pal_data));
841     hpal = CreatePalette(pal);
842     ok(hpal != 0, "CreatePalette failed\n");
843 
844     hbmp = create_dib(3, 3, 8, pal, data_8bpp_pal_dib);
845     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapIgnoreAlpha, &bitmap);
846     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
847 
848     IWICBitmap_GetPixelFormat(bitmap, &format);
849     ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
850             "unexpected pixel format %s\n", wine_dbgstr_guid(&format));
851 
852     hr = IWICBitmap_GetSize(bitmap, &width, &height);
853     ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr);
854     ok(width == 3, "expected 3, got %u\n", width);
855     ok(height == 3, "expected 3, got %u\n", height);
856 
857     hr = IWICImagingFactory_CreatePalette(factory, &palette);
858     ok(hr == S_OK, "CreatePalette error %#x\n", hr);
859     hr = IWICBitmap_CopyPalette(bitmap, palette);
860     ok(hr == S_OK, "CopyPalette error %#x\n", hr);
861 
862     hr = IWICPalette_GetType(palette, &type);
863     ok(hr == S_OK, "%u: GetType error %#x\n", i, hr);
864     ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
865 
866     hr = IWICPalette_GetColorCount(palette, &count);
867     ok(hr == S_OK, "GetColorCount error %#x\n", hr);
868     ok(count == 256, "expected 256, got %u\n", count);
869 
870     IWICPalette_Release(palette);
871 
872     memset(data, 0, sizeof(data));
873     hr = IWICBitmap_CopyPixels(bitmap, NULL, 4, sizeof(data), data);
874     ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr);
875     for (i = 0; i < sizeof(data); i++)
876         todo_wine_if (data[i] != data_8bpp_pal_wic[i])
877             ok(data[i] == data_8bpp_pal_wic[i], "%u: expected %#x, got %#x\n", i, data_8bpp_pal_wic[i], data[i]);
878 
879     IWICBitmap_Release(bitmap);
880     DeleteObject(hbmp);
881     DeleteObject(hpal);
882 
883     /* 32bpp alpha */
884     hbmp = create_dib(2, 2, 32, NULL, NULL);
885     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, NULL, WICBitmapUseAlpha, &bitmap);
886     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
887 
888     hr = IWICBitmap_GetPixelFormat(bitmap, &format);
889     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
890     ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA),
891        "unexpected pixel format %s\n", wine_dbgstr_guid(&format));
892 
893     IWICBitmap_Release(bitmap);
894 
895     /* 32bpp pre-multiplied alpha */
896     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, NULL, WICBitmapUsePremultipliedAlpha, &bitmap);
897     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
898 
899     hr = IWICBitmap_GetPixelFormat(bitmap, &format);
900     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
901     ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppPBGRA),
902        "unexpected pixel format %s\n", wine_dbgstr_guid(&format));
903 
904     IWICBitmap_Release(bitmap);
905 
906     /* 32bpp no alpha */
907     hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, NULL, WICBitmapIgnoreAlpha, &bitmap);
908     ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr);
909 
910     hr = IWICBitmap_GetPixelFormat(bitmap, &format);
911     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
912     ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGR),
913        "unexpected pixel format %s\n", wine_dbgstr_guid(&format));
914 
915     IWICBitmap_Release(bitmap);
916     DeleteObject(hbmp);
917 }
918 
919 static void test_clipper(void)
920 {
921     IWICBitmapClipper *clipper;
922     UINT height, width;
923     IWICBitmap *bitmap;
924     BYTE buffer[500];
925     WICRect rect;
926     HRESULT hr;
927 
928     hr = IWICImagingFactory_CreateBitmap(factory, 10, 10, &GUID_WICPixelFormat24bppBGR,
929         WICBitmapCacheOnLoad, &bitmap);
930     ok(hr == S_OK, "got 0x%08x\n", hr);
931 
932     hr = IWICImagingFactory_CreateBitmapClipper(factory, &clipper);
933     ok(hr == S_OK, "got 0x%08x\n", hr);
934 
935     rect.X = rect.Y = 0;
936     rect.Width = rect.Height = 11;
937     hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect);
938     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
939 
940     rect.X = rect.Y = 5;
941     rect.Width = rect.Height = 6;
942     hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect);
943     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
944 
945     rect.X = rect.Y = 5;
946     rect.Width = rect.Height = 5;
947     hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect);
948     ok(hr == S_OK, "got 0x%08x\n", hr);
949 
950     width = height = 0;
951     hr = IWICBitmapClipper_GetSize(clipper, &width, &height);
952     ok(hr == S_OK, "got 0x%08x\n", hr);
953     ok(width == 5, "got %d\n", width);
954     ok(height == 5, "got %d\n", height);
955 
956     IWICBitmapClipper_Release(clipper);
957     IWICBitmap_Release(bitmap);
958 
959     /* CopyPixels */
960     hr = IWICImagingFactory_CreateBitmapClipper(factory, &clipper);
961     ok(hr == S_OK, "got 0x%08x\n", hr);
962 
963     rect.X = rect.Y = 5;
964     rect.Width = rect.Height = 5;
965     hr = IWICBitmapClipper_Initialize(clipper, &bitmapsource, &rect);
966     ok(hr == S_OK, "got 0x%08x\n", hr);
967 
968     rect.X = rect.Y = 0;
969     rect.Width = rect.Height = 2;
970 
971     /* passed rectangle is relative to clipper rectangle, underlying source gets intersected
972        rectangle */
973     memset(&g_rect, 0, sizeof(g_rect));
974     called_CopyPixels = FALSE;
975     hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer);
976     ok(hr == S_OK, "got 0x%08x\n", hr);
977     ok(called_CopyPixels, "CopyPixels not called\n");
978     ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 2 && g_rect.Height == 2,
979         "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height);
980 
981     /* whole clipping rectangle */
982     memset(&g_rect, 0, sizeof(g_rect));
983     called_CopyPixels = FALSE;
984 
985     rect.X = rect.Y = 0;
986     rect.Width = rect.Height = 5;
987 
988     hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer);
989     ok(hr == S_OK, "got 0x%08x\n", hr);
990     ok(called_CopyPixels, "CopyPixels not called\n");
991     ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 5 && g_rect.Height == 5,
992         "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height);
993 
994     /* larger than clipping rectangle */
995     memset(&g_rect, 0, sizeof(g_rect));
996     called_CopyPixels = FALSE;
997 
998     rect.X = rect.Y = 0;
999     rect.Width = rect.Height = 20;
1000 
1001     hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer);
1002     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1003     ok(!called_CopyPixels, "CopyPixels called\n");
1004 
1005     rect.X = rect.Y = 5;
1006     rect.Width = rect.Height = 5;
1007 
1008     hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer);
1009     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1010     ok(!called_CopyPixels, "CopyPixels called\n");
1011 
1012     /* null rectangle */
1013     memset(&g_rect, 0, sizeof(g_rect));
1014     called_CopyPixels = FALSE;
1015 
1016     hr = IWICBitmapClipper_CopyPixels(clipper, NULL, 0, sizeof(buffer), buffer);
1017     ok(hr == S_OK, "got 0x%08x\n", hr);
1018     ok(called_CopyPixels, "CopyPixels not called\n");
1019     ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 5 && g_rect.Height == 5,
1020         "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height);
1021 
1022     IWICBitmapClipper_Release(clipper);
1023 }
1024 
1025 static HRESULT (WINAPI *pWICCreateBitmapFromSectionEx)
1026     (UINT, UINT, REFWICPixelFormatGUID, HANDLE, UINT, UINT, WICSectionAccessLevel, IWICBitmap **);
1027 
1028 static void test_WICCreateBitmapFromSectionEx(void)
1029 {
1030     SYSTEM_INFO sysinfo;
1031     HANDLE hsection;
1032     BITMAPINFO info;
1033     void *bits;
1034     HBITMAP hdib;
1035     IWICBitmap *bitmap;
1036     HRESULT hr;
1037     pWICCreateBitmapFromSectionEx =
1038         (void *)GetProcAddress(LoadLibraryA("windowscodecs"), "WICCreateBitmapFromSectionEx");
1039 
1040     if (!pWICCreateBitmapFromSectionEx)
1041     {
1042         win_skip("WICCreateBitmapFromSectionEx not available\n");
1043         return;
1044     }
1045 
1046     GetSystemInfo(&sysinfo);
1047     hsection = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
1048                                   sysinfo.dwAllocationGranularity * 2, NULL);
1049     ok(hsection != NULL, "CreateFileMapping failed %u\n", GetLastError());
1050 
1051     memset(&info, 0, sizeof(info));
1052     info.bmiHeader.biSize        = sizeof(info.bmiHeader);
1053     info.bmiHeader.biWidth       = 3;
1054     info.bmiHeader.biHeight      = -3;
1055     info.bmiHeader.biBitCount    = 24;
1056     info.bmiHeader.biPlanes      = 1;
1057     info.bmiHeader.biCompression = BI_RGB;
1058 
1059     hdib = CreateDIBSection(0, &info, DIB_RGB_COLORS, &bits, hsection, 0);
1060     ok(hdib != NULL, "CreateDIBSection failed\n");
1061 
1062     hr = pWICCreateBitmapFromSectionEx(3, 3, &GUID_WICPixelFormat24bppBGR, hsection, 0, 0,
1063                                        WICSectionAccessLevelReadWrite, &bitmap);
1064     ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#x\n", hr);
1065     IWICBitmap_Release(bitmap);
1066 
1067     /* non-zero offset, smaller than allocation granularity */
1068     hr = pWICCreateBitmapFromSectionEx(3, 3, &GUID_WICPixelFormat24bppBGR, hsection, 0, 0x100,
1069                                        WICSectionAccessLevelReadWrite, &bitmap);
1070     ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#x\n", hr);
1071     IWICBitmap_Release(bitmap);
1072 
1073     /* offset larger than allocation granularity */
1074     hr = pWICCreateBitmapFromSectionEx(3, 3, &GUID_WICPixelFormat24bppBGR, hsection, 0,
1075                                        sysinfo.dwAllocationGranularity + 1,
1076                                        WICSectionAccessLevelReadWrite, &bitmap);
1077     ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#x\n", hr);
1078     IWICBitmap_Release(bitmap);
1079     DeleteObject(hdib);
1080     CloseHandle(hsection);
1081 }
1082 
1083 static void test_bitmap_scaler(void)
1084 {
1085     WICPixelFormatGUID pixel_format;
1086     IWICBitmapScaler *scaler;
1087     IWICPalette *palette;
1088     double res_x, res_y;
1089     IWICBitmap *bitmap;
1090     UINT width, height;
1091     HRESULT hr;
1092 
1093     hr = IWICImagingFactory_CreateBitmap(factory, 4, 2, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnLoad, &bitmap);
1094     ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr);
1095 
1096     hr = IWICBitmap_GetSize(bitmap, &width, &height);
1097     ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr);
1098     ok(width == 4, "Unexpected width %u.\n", width);
1099     ok(height == 2, "Unexpected height %u.\n", height);
1100 
1101     hr = IWICBitmap_GetResolution(bitmap, &res_x, &res_y);
1102     ok(hr == S_OK, "Failed to get bitmap resolution, hr %#x.\n", hr);
1103     ok(res_x == 0.0 && res_y == 0.0, "Unexpected resolution %f x %f.\n", res_x, res_y);
1104 
1105     hr = IWICImagingFactory_CreateBitmapScaler(factory, &scaler);
1106     ok(hr == S_OK, "Failed to create bitmap scaler, hr %#x.\n", hr);
1107 
1108     hr = IWICBitmapScaler_Initialize(scaler, NULL, 0, 0,
1109         WICBitmapInterpolationModeNearestNeighbor);
1110     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1111 
1112     hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 0, 0,
1113         WICBitmapInterpolationModeNearestNeighbor);
1114     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1115 
1116     hr = IWICBitmapScaler_GetSize(scaler, NULL, &height);
1117     ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
1118 
1119     hr = IWICBitmapScaler_GetSize(scaler, &width, NULL);
1120     ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
1121 
1122     hr = IWICBitmapScaler_GetResolution(scaler, NULL, NULL);
1123     ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
1124 
1125     res_x = 0.1;
1126     hr = IWICBitmapScaler_GetResolution(scaler, &res_x, NULL);
1127     ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
1128     ok(res_x == 0.1, "Unexpected resolution %f.\n", res_x);
1129 
1130     hr = IWICBitmapScaler_GetResolution(scaler, NULL, &res_y);
1131     ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
1132 
1133     hr = IWICBitmapScaler_GetResolution(scaler, &res_x, &res_y);
1134     ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
1135 
1136     hr = IWICBitmapScaler_GetPixelFormat(scaler, NULL);
1137     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1138 
1139     memset(&pixel_format, 0, sizeof(pixel_format));
1140     hr = IWICBitmapScaler_GetPixelFormat(scaler, &pixel_format);
1141     ok(hr == S_OK, "Failed to get pixel format, hr %#x.\n", hr);
1142     ok(IsEqualGUID(&pixel_format, &GUID_WICPixelFormatDontCare), "Unexpected pixel format %s.\n",
1143         wine_dbgstr_guid(&pixel_format));
1144 
1145     width = 123;
1146     height = 321;
1147     hr = IWICBitmapScaler_GetSize(scaler, &width, &height);
1148     ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
1149     ok(width == 123, "Unexpected width %u.\n", width);
1150     ok(height == 321, "Unexpected height %u.\n", height);
1151 
1152     hr = IWICBitmapScaler_CopyPalette(scaler, NULL);
1153     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1154 
1155     hr = IWICImagingFactory_CreatePalette(factory, &palette);
1156     ok(hr == S_OK, "Failed to create a palette, hr %#x.\n", hr);
1157     hr = IWICBitmapScaler_CopyPalette(scaler, palette);
1158     ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#x.\n", hr);
1159     IWICPalette_Release(palette);
1160 
1161     hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 4, 0,
1162         WICBitmapInterpolationModeNearestNeighbor);
1163     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1164 
1165     hr = IWICBitmapScaler_GetSize(scaler, &width, &height);
1166     ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
1167 
1168     hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 0, 2,
1169         WICBitmapInterpolationModeNearestNeighbor);
1170     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1171 
1172     hr = IWICBitmapScaler_GetSize(scaler, &width, &height);
1173     ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
1174 
1175     hr = IWICBitmapScaler_Initialize(scaler, NULL, 8, 4,
1176         WICBitmapInterpolationModeNearestNeighbor);
1177     ok(hr == E_INVALIDARG, "Failed to initialize bitmap scaler, hr %#x.\n", hr);
1178 
1179     hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 8, 4,
1180         WICBitmapInterpolationModeNearestNeighbor);
1181     ok(hr == S_OK, "Failed to initialize bitmap scaler, hr %#x.\n", hr);
1182 
1183     hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 0, 4,
1184         WICBitmapInterpolationModeNearestNeighbor);
1185     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1186 
1187     hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 8, 0,
1188         WICBitmapInterpolationModeNearestNeighbor);
1189     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1190 
1191     hr = IWICBitmapScaler_Initialize(scaler, NULL, 8, 4, WICBitmapInterpolationModeNearestNeighbor);
1192     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1193 
1194     hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 8, 4,
1195         WICBitmapInterpolationModeNearestNeighbor);
1196     ok(hr == WINCODEC_ERR_WRONGSTATE, "Unexpected hr %#x.\n", hr);
1197 
1198     hr = IWICBitmapScaler_GetSize(scaler, &width, &height);
1199     ok(hr == S_OK, "Failed to get scaler size, hr %#x.\n", hr);
1200     ok(width == 8, "Unexpected width %u.\n", width);
1201     ok(height == 4, "Unexpected height %u.\n", height);
1202 
1203     hr = IWICBitmapScaler_GetSize(scaler, NULL, &height);
1204     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1205 
1206     hr = IWICBitmapScaler_GetSize(scaler, &width, NULL);
1207     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1208 
1209     hr = IWICBitmapScaler_GetSize(scaler, NULL, NULL);
1210     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1211 
1212     hr = IWICBitmapScaler_GetPixelFormat(scaler, NULL);
1213     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1214 
1215     memset(&pixel_format, 0, sizeof(pixel_format));
1216     hr = IWICBitmapScaler_GetPixelFormat(scaler, &pixel_format);
1217     ok(hr == S_OK, "Failed to get pixel format, hr %#x.\n", hr);
1218     ok(IsEqualGUID(&pixel_format, &GUID_WICPixelFormat24bppBGR), "Unexpected pixel format %s.\n",
1219         wine_dbgstr_guid(&pixel_format));
1220 
1221     hr = IWICBitmapScaler_GetResolution(scaler, NULL, NULL);
1222     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1223 
1224     res_x = 0.1;
1225     hr = IWICBitmapScaler_GetResolution(scaler, &res_x, NULL);
1226     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1227     ok(res_x == 0.1, "Unexpected resolution %f.\n", res_x);
1228 
1229     hr = IWICBitmapScaler_GetResolution(scaler, NULL, &res_y);
1230     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1231 
1232     res_x = res_y = 1.0;
1233     hr = IWICBitmapScaler_GetResolution(scaler, &res_x, &res_y);
1234     ok(hr == S_OK, "Failed to get scaler resolution, hr %#x.\n", hr);
1235     ok(res_x == 0.0 && res_y == 0.0, "Unexpected resolution %f x %f.\n", res_x, res_y);
1236 
1237     hr = IWICImagingFactory_CreatePalette(factory, &palette);
1238     ok(hr == S_OK, "Failed to create a palette, hr %#x.\n", hr);
1239     hr = IWICBitmapScaler_CopyPalette(scaler, palette);
1240     ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#x.\n", hr);
1241     IWICPalette_Release(palette);
1242 
1243     IWICBitmapScaler_Release(scaler);
1244 
1245     IWICBitmap_Release(bitmap);
1246 }
1247 
1248 START_TEST(bitmap)
1249 {
1250     HRESULT hr;
1251 
1252     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1253 
1254     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1255         &IID_IWICImagingFactory, (void**)&factory);
1256     ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
1257 
1258     test_createbitmap();
1259     test_createbitmapfromsource();
1260     test_CreateBitmapFromMemory();
1261     test_CreateBitmapFromHICON();
1262     test_CreateBitmapFromHBITMAP();
1263     test_clipper();
1264     test_bitmap_scaler();
1265 
1266     IWICImagingFactory_Release(factory);
1267 
1268     CoUninitialize();
1269 
1270     test_WICCreateBitmapFromSectionEx();
1271 }
1272