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