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