wined3d: Pass a wined3d_device_context to wined3d_cs_emit_blt_sub_resource().
[wine/zf.git] / dlls / windowscodecs / tests / converter.c
blob0429b7a3af6e48cfe45045a3dc50053bb014272e
1 /*
2 * Copyright 2009 Vincent Povirk
3 * Copyright 2016 Dmitry Timoshkov
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.
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.
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
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <math.h>
24 #define COBJMACROS
25 #define CONST_VTABLE
27 #include "windef.h"
28 #include "objbase.h"
29 #include "wincodec.h"
30 #include "wincodecsdk.h"
31 #include "wine/test.h"
33 static IWICImagingFactory *factory;
35 typedef struct bitmap_data {
36 const WICPixelFormatGUID *format;
37 UINT bpp;
38 const BYTE *bits;
39 UINT width;
40 UINT height;
41 double xres;
42 double yres;
43 const struct bitmap_data *alt_data;
44 } bitmap_data;
46 typedef struct BitmapTestSrc {
47 IWICBitmapSource IWICBitmapSource_iface;
48 LONG ref;
49 const bitmap_data *data;
50 } BitmapTestSrc;
52 extern HRESULT STDMETHODCALLTYPE IWICBitmapFrameEncode_WriteSource_Proxy(IWICBitmapFrameEncode* This,
53 IWICBitmapSource *pIBitmapSource, WICRect *prc);
55 static BOOL near_equal(float a, float b)
57 return fabsf(a - b) < 0.001;
60 static inline BitmapTestSrc *impl_from_IWICBitmapSource(IWICBitmapSource *iface)
62 return CONTAINING_RECORD(iface, BitmapTestSrc, IWICBitmapSource_iface);
65 static HRESULT WINAPI BitmapTestSrc_QueryInterface(IWICBitmapSource *iface, REFIID iid,
66 void **ppv)
68 if (!ppv) return E_INVALIDARG;
70 if (IsEqualIID(&IID_IUnknown, iid) ||
71 IsEqualIID(&IID_IWICBitmapSource, iid))
72 *ppv = iface;
73 else
74 return E_NOINTERFACE;
76 IUnknown_AddRef((IUnknown*)*ppv);
77 return S_OK;
80 static ULONG WINAPI BitmapTestSrc_AddRef(IWICBitmapSource *iface)
82 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
83 ULONG ref = InterlockedIncrement(&This->ref);
84 return ref;
87 static ULONG WINAPI BitmapTestSrc_Release(IWICBitmapSource *iface)
89 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
90 ULONG ref = InterlockedDecrement(&This->ref);
91 return ref;
94 static HRESULT WINAPI BitmapTestSrc_GetSize(IWICBitmapSource *iface,
95 UINT *puiWidth, UINT *puiHeight)
97 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
98 *puiWidth = This->data->width;
99 *puiHeight = This->data->height;
100 return S_OK;
103 static HRESULT WINAPI BitmapTestSrc_GetPixelFormat(IWICBitmapSource *iface,
104 WICPixelFormatGUID *pPixelFormat)
106 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
107 memcpy(pPixelFormat, This->data->format, sizeof(GUID));
108 return S_OK;
111 static HRESULT WINAPI BitmapTestSrc_GetResolution(IWICBitmapSource *iface,
112 double *pDpiX, double *pDpiY)
114 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
115 *pDpiX = This->data->xres;
116 *pDpiY = This->data->yres;
117 return S_OK;
120 static HRESULT WINAPI BitmapTestSrc_CopyPalette(IWICBitmapSource *iface,
121 IWICPalette *palette)
123 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
125 if (IsEqualGUID(This->data->format, &GUID_WICPixelFormat1bppIndexed) ||
126 IsEqualGUID(This->data->format, &GUID_WICPixelFormat2bppIndexed) ||
127 IsEqualGUID(This->data->format, &GUID_WICPixelFormat4bppIndexed) ||
128 IsEqualGUID(This->data->format, &GUID_WICPixelFormat8bppIndexed))
130 WICColor colors[8];
132 colors[0] = 0xff0000ff;
133 colors[1] = 0xff00ff00;
134 colors[2] = 0xffff0000;
135 colors[3] = 0xff000000;
136 colors[4] = 0xffffff00;
137 colors[5] = 0xffff00ff;
138 colors[6] = 0xff00ffff;
139 colors[7] = 0xffffffff;
140 return IWICPalette_InitializeCustom(palette, colors, 8);
143 /* unique error marker */
144 return 0xdeadbeef;
147 static HRESULT WINAPI BitmapTestSrc_CopyPixels(IWICBitmapSource *iface,
148 const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
150 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
151 UINT bytesperrow;
152 UINT srcstride;
153 UINT row_offset;
154 WICRect rc;
156 if (!prc)
158 rc.X = 0;
159 rc.Y = 0;
160 rc.Width = This->data->width;
161 rc.Height = This->data->height;
162 prc = &rc;
164 else
166 if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->data->width || prc->Y+prc->Height > This->data->height)
167 return E_INVALIDARG;
170 bytesperrow = ((This->data->bpp * prc->Width)+7)/8;
171 srcstride = ((This->data->bpp * This->data->width)+7)/8;
173 if (cbStride < bytesperrow)
174 return E_INVALIDARG;
176 if ((cbStride * prc->Height) > cbBufferSize)
177 return E_INVALIDARG;
179 row_offset = prc->X * This->data->bpp;
181 if (row_offset % 8 == 0)
183 UINT row;
184 const BYTE *src;
185 BYTE *dst;
187 src = This->data->bits + (row_offset / 8) + prc->Y * srcstride;
188 dst = pbBuffer;
189 for (row=0; row < prc->Height; row++)
191 memcpy(dst, src, bytesperrow);
192 src += srcstride;
193 dst += cbStride;
195 return S_OK;
197 else
199 ok(0, "bitmap %p was asked to copy pixels not aligned on a byte boundary\n", iface);
200 return E_FAIL;
204 static const IWICBitmapSourceVtbl BitmapTestSrc_Vtbl = {
205 BitmapTestSrc_QueryInterface,
206 BitmapTestSrc_AddRef,
207 BitmapTestSrc_Release,
208 BitmapTestSrc_GetSize,
209 BitmapTestSrc_GetPixelFormat,
210 BitmapTestSrc_GetResolution,
211 BitmapTestSrc_CopyPalette,
212 BitmapTestSrc_CopyPixels
215 static void CreateTestBitmap(const bitmap_data *data, BitmapTestSrc **This)
217 *This = HeapAlloc(GetProcessHeap(), 0, sizeof(**This));
219 if (*This)
221 (*This)->IWICBitmapSource_iface.lpVtbl = &BitmapTestSrc_Vtbl;
222 (*This)->ref = 1;
223 (*This)->data = data;
227 static void DeleteTestBitmap(BitmapTestSrc *This)
229 ok(This->IWICBitmapSource_iface.lpVtbl == &BitmapTestSrc_Vtbl, "test bitmap %p deleted with incorrect vtable\n", This);
230 ok(This->ref == 1, "test bitmap %p deleted with %i references instead of 1\n", This, This->ref);
231 HeapFree(GetProcessHeap(), 0, This);
234 static BOOL compare_bits(const struct bitmap_data *expect, UINT buffersize, const BYTE *converted_bits)
236 BOOL equal;
238 if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppBGR))
240 /* ignore the padding byte when comparing data */
241 UINT i;
242 const DWORD *a=(const DWORD*)expect->bits, *b=(const DWORD*)converted_bits;
243 equal=TRUE;
244 for (i=0; i<(buffersize/4); i++)
245 if ((a[i]&0xffffff) != (b[i]&0xffffff))
247 equal = FALSE;
248 break;
251 else if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppGrayFloat))
253 UINT i;
254 const float *a=(const float*)expect->bits, *b=(const float*)converted_bits;
255 equal=TRUE;
256 for (i=0; i<(buffersize/4); i++)
257 if (!near_equal(a[i], b[i]))
259 equal = FALSE;
260 break;
263 else if (IsEqualGUID(expect->format, &GUID_WICPixelFormatBlackWhite) ||
264 IsEqualGUID(expect->format, &GUID_WICPixelFormat1bppIndexed))
266 UINT i;
267 const BYTE *a=(const BYTE*)expect->bits, *b=(const BYTE*)converted_bits;
268 equal=TRUE;
269 for (i=0; i<buffersize; i++)
270 if (a[i] != b[i] && b[i] != 0xff /* BMP encoder B&W */)
272 equal = FALSE;
273 break;
276 else if (IsEqualGUID(expect->format, &GUID_WICPixelFormat2bppIndexed) ||
277 IsEqualGUID(expect->format, &GUID_WICPixelFormat4bppIndexed) ||
278 IsEqualGUID(expect->format, &GUID_WICPixelFormat8bppIndexed))
280 UINT i;
281 const BYTE *a=(const BYTE*)expect->bits, *b=(const BYTE*)converted_bits;
282 equal=TRUE;
284 for (i=0; i<buffersize; i++)
285 if (a[i] != b[i])
287 equal = FALSE;
288 break;
291 else
292 equal = (memcmp(expect->bits, converted_bits, buffersize) == 0);
294 if (!equal && expect->alt_data)
295 equal = compare_bits(expect->alt_data, buffersize, converted_bits);
297 if (!equal && winetest_debug > 1)
299 UINT i, bps;
300 bps = expect->bpp / 8;
301 if (!bps) bps = buffersize;
302 printf("converted_bits (%u bytes):\n ", buffersize);
303 for (i = 0; i < buffersize; i++)
305 printf("%u,", converted_bits[i]);
306 if (!((i + 1) % 32)) printf("\n ");
307 else if (!((i+1) % bps)) printf(" ");
309 printf("\n");
312 return equal;
315 static BOOL is_indexed_format(const GUID *format)
317 if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed) ||
318 IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed) ||
319 IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed) ||
320 IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
321 return TRUE;
323 return FALSE;
326 static void compare_bitmap_data(const struct bitmap_data *src, const struct bitmap_data *expect,
327 IWICBitmapSource *source, const char *name)
329 BYTE *converted_bits;
330 UINT width, height;
331 double xres, yres;
332 WICRect prc;
333 UINT stride, buffersize;
334 GUID dst_pixelformat;
335 HRESULT hr;
337 hr = IWICBitmapSource_GetSize(source, &width, &height);
338 ok(SUCCEEDED(hr), "GetSize(%s) failed, hr=%x\n", name, hr);
339 ok(width == expect->width, "expecting %u, got %u (%s)\n", expect->width, width, name);
340 ok(height == expect->height, "expecting %u, got %u (%s)\n", expect->height, height, name);
342 hr = IWICBitmapSource_GetResolution(source, &xres, &yres);
343 ok(SUCCEEDED(hr), "GetResolution(%s) failed, hr=%x\n", name, hr);
344 ok(fabs(xres - expect->xres) < 0.02, "expecting %0.2f, got %0.2f (%s)\n", expect->xres, xres, name);
345 ok(fabs(yres - expect->yres) < 0.02, "expecting %0.2f, got %0.2f (%s)\n", expect->yres, yres, name);
347 hr = IWICBitmapSource_GetPixelFormat(source, &dst_pixelformat);
348 ok(SUCCEEDED(hr), "GetPixelFormat(%s) failed, hr=%x\n", name, hr);
349 ok(IsEqualGUID(&dst_pixelformat, expect->format), "got unexpected pixel format %s (%s)\n", wine_dbgstr_guid(&dst_pixelformat), name);
351 prc.X = 0;
352 prc.Y = 0;
353 prc.Width = expect->width;
354 prc.Height = expect->height;
356 stride = (expect->bpp * expect->width + 7) / 8;
357 buffersize = stride * expect->height;
359 converted_bits = HeapAlloc(GetProcessHeap(), 0, buffersize);
360 memset(converted_bits, 0xaa, buffersize);
361 hr = IWICBitmapSource_CopyPixels(source, &prc, stride, buffersize, converted_bits);
362 ok(SUCCEEDED(hr), "CopyPixels(%s) failed, hr=%x\n", name, hr);
364 /* The result of conversion of color to indexed formats depends on
365 * optimized palette generation implementation. We either need to
366 * assign our own palette, or just skip the comparison.
368 if (!(!is_indexed_format(src->format) && is_indexed_format(expect->format)))
369 ok(compare_bits(expect, buffersize, converted_bits), "unexpected pixel data (%s)\n", name);
371 /* Test with NULL rectangle - should copy the whole bitmap */
372 memset(converted_bits, 0xaa, buffersize);
373 hr = IWICBitmapSource_CopyPixels(source, NULL, stride, buffersize, converted_bits);
374 ok(SUCCEEDED(hr), "CopyPixels(%s,rc=NULL) failed, hr=%x\n", name, hr);
375 /* see comment above */
376 if (!(!is_indexed_format(src->format) && is_indexed_format(expect->format)))
377 ok(compare_bits(expect, buffersize, converted_bits), "unexpected pixel data (%s)\n", name);
379 HeapFree(GetProcessHeap(), 0, converted_bits);
382 /* some encoders (like BMP) require data to be 4-bytes aligned */
383 static const BYTE bits_1bpp[] = {
384 0x55,0x55,0x55,0x55, /*01010101*/
385 0xaa,0xaa,0xaa,0xaa}; /*10101010*/
386 static const struct bitmap_data testdata_BlackWhite = {
387 &GUID_WICPixelFormatBlackWhite, 1, bits_1bpp, 32, 2, 96.0, 96.0};
388 static const struct bitmap_data testdata_1bppIndexed = {
389 &GUID_WICPixelFormat1bppIndexed, 1, bits_1bpp, 32, 2, 96.0, 96.0};
391 /* some encoders (like BMP) require data to be 4-bytes aligned */
392 static const BYTE bits_2bpp[] = {
393 0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,
394 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24};
395 static const struct bitmap_data testdata_2bppIndexed = {
396 &GUID_WICPixelFormat2bppIndexed, 2, bits_2bpp, 32, 2, 96.0, 96.0};
398 /* some encoders (like BMP) require data to be 4-bytes aligned */
399 static const BYTE bits_4bpp[] = {
400 0x34,0x43,0x34,0x43,0x34,0x43,0x34,0x43,0x34,0x43,0x34,0x43,0x34,0x43,0x34,0x43,
401 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44};
403 static const struct bitmap_data testdata_4bppIndexed = {
404 &GUID_WICPixelFormat4bppIndexed, 4, bits_4bpp, 32, 2, 96.0, 96.0};
406 static const BYTE bits_8bpp_BW[] = {
407 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
408 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0};
409 static const struct bitmap_data testdata_8bppIndexed_BW = {
410 &GUID_WICPixelFormat8bppIndexed, 8, bits_8bpp_BW, 32, 2, 96.0, 96.0};
412 static const BYTE bits_8bpp_4colors[] = {
413 0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,
414 3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,3};
415 static const struct bitmap_data testdata_8bppIndexed_4colors = {
416 &GUID_WICPixelFormat8bppIndexed, 8, bits_8bpp_4colors, 32, 2, 96.0, 96.0};
418 static const BYTE bits_8bpp[] = {
419 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,
420 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
421 static const struct bitmap_data testdata_8bppIndexed = {
422 &GUID_WICPixelFormat8bppIndexed, 8, bits_8bpp, 32, 2, 96.0, 96.0};
424 static const BYTE bits_24bppBGR[] = {
425 255,0,0, 0,255,0, 0,0,255, 0,0,0, 255,0,0, 0,255,0, 0,0,255, 0,0,0,
426 255,0,0, 0,255,0, 0,0,255, 0,0,0, 255,0,0, 0,255,0, 0,0,255, 0,0,0,
427 255,0,0, 0,255,0, 0,0,255, 0,0,0, 255,0,0, 0,255,0, 0,0,255, 0,0,0,
428 255,0,0, 0,255,0, 0,0,255, 0,0,0, 255,0,0, 0,255,0, 0,0,255, 0,0,0,
429 0,255,255, 255,0,255, 255,255,0, 255,255,255, 0,255,255, 255,0,255, 255,255,0, 255,255,255,
430 0,255,255, 255,0,255, 255,255,0, 255,255,255, 0,255,255, 255,0,255, 255,255,0, 255,255,255,
431 0,255,255, 255,0,255, 255,255,0, 255,255,255, 0,255,255, 255,0,255, 255,255,0, 255,255,255,
432 0,255,255, 255,0,255, 255,255,0, 255,255,255, 0,255,255, 255,0,255, 255,255,0, 255,255,255};
433 static const struct bitmap_data testdata_24bppBGR = {
434 &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR, 32, 2, 96.0, 96.0};
436 static const BYTE bits_24bppRGB[] = {
437 0,0,255, 0,255,0, 255,0,0, 0,0,0, 0,0,255, 0,255,0, 255,0,0, 0,0,0,
438 0,0,255, 0,255,0, 255,0,0, 0,0,0, 0,0,255, 0,255,0, 255,0,0, 0,0,0,
439 0,0,255, 0,255,0, 255,0,0, 0,0,0, 0,0,255, 0,255,0, 255,0,0, 0,0,0,
440 0,0,255, 0,255,0, 255,0,0, 0,0,0, 0,0,255, 0,255,0, 255,0,0, 0,0,0,
441 255,255,0, 255,0,255, 0,255,255, 255,255,255, 255,255,0, 255,0,255, 0,255,255, 255,255,255,
442 255,255,0, 255,0,255, 0,255,255, 255,255,255, 255,255,0, 255,0,255, 0,255,255, 255,255,255,
443 255,255,0, 255,0,255, 0,255,255, 255,255,255, 255,255,0, 255,0,255, 0,255,255, 255,255,255,
444 255,255,0, 255,0,255, 0,255,255, 255,255,255, 255,255,0, 255,0,255, 0,255,255, 255,255,255 };
445 static const struct bitmap_data testdata_24bppRGB = {
446 &GUID_WICPixelFormat24bppRGB, 24, bits_24bppRGB, 32, 2, 96.0, 96.0};
448 static const BYTE bits_32bppBGR[] = {
449 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80,
450 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80,
451 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80,
452 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80, 255,0,0,80, 0,255,0,80, 0,0,255,80, 0,0,0,80,
453 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80,
454 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80,
455 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80,
456 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80};
457 static const struct bitmap_data testdata_32bppBGR = {
458 &GUID_WICPixelFormat32bppBGR, 32, bits_32bppBGR, 32, 2, 96.0, 96.0};
459 static const struct bitmap_data testdata_32bppBGRA80 = {
460 &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGR, 32, 2, 96.0, 96.0};
461 static const struct bitmap_data testdata_32bppRGBA80 = {
462 &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGR, 32, 2, 96.0, 96.0};
464 static const BYTE bits_32bppBGRA[] = {
465 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255,
466 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255,
467 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255,
468 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255,
469 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255,
470 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255,
471 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255,
472 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255};
473 static const BYTE bits_32bppRGBA[] = {
474 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255,
475 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255,
476 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255,
477 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255,
478 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255,
479 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255,
480 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255,
481 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255};
483 static const struct bitmap_data testdata_32bppBGRA = {
484 &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0};
485 static const struct bitmap_data testdata_32bppRGBA = {
486 &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppRGBA, 32, 2, 96.0, 96.0};
487 static const struct bitmap_data testdata_32bppRGB = {
488 &GUID_WICPixelFormat32bppRGB, 32, bits_32bppRGBA, 32, 2, 96.0, 96.0};
490 static const BYTE bits_32bppPBGRA[] = {
491 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80,
492 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80,
493 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80,
494 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80,
495 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80,
496 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80,
497 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80,
498 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80};
499 static const struct bitmap_data testdata_32bppPBGRA = {
500 &GUID_WICPixelFormat32bppPBGRA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0};
501 static const struct bitmap_data testdata_32bppPRGBA = {
502 &GUID_WICPixelFormat32bppPRGBA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0};
504 static const BYTE bits_64bppRGBA[] = {
505 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255,
506 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255,
507 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255,
508 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255,
509 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255,
510 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255,
511 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255,
512 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255};
513 static const struct bitmap_data testdata_64bppRGBA = {
514 &GUID_WICPixelFormat64bppRGBA, 64, bits_64bppRGBA, 32, 2, 96.0, 96.0};
516 /* XP and 2003 use linear color conversion, later versions use sRGB gamma */
517 static const float bits_32bppGrayFloat_xp[] = {
518 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
519 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
520 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
521 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
522 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f,
523 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f,
524 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f,
525 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f};
526 static const struct bitmap_data testdata_32bppGrayFloat_xp = {
527 &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat_xp, 32, 2, 96.0, 96.0};
529 static const float bits_32bppGrayFloat[] = {
530 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
531 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
532 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
533 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
534 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f,
535 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f,
536 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f,
537 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f};
538 static const struct bitmap_data testdata_32bppGrayFloat = {
539 &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat, 32, 2, 96.0, 96.0, &testdata_32bppGrayFloat_xp};
541 static const BYTE bits_8bppGray_xp[] = {
542 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0,
543 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0,
544 226,105,179,255,226,105,179,255,226,105,179,255,226,105,179,255,
545 226,105,179,255,226,105,179,255,226,105,179,255,226,105,179,255};
546 static const struct bitmap_data testdata_8bppGray_xp = {
547 &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray_xp, 32, 2, 96.0, 96.0};
549 static const BYTE bits_8bppGray[] = {
550 76,220,127,0,76,220,127,0,76,220,127,0,76,220,127,0,
551 76,220,127,0,76,220,127,0,76,220,127,0,76,220,127,0,
552 247,145,230,255,247,145,230,255,247,145,230,255,247,145,230,255,
553 247,145,230,255,247,145,230,255,247,145,230,255,247,145,230,255};
554 static const struct bitmap_data testdata_8bppGray = {
555 &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray, 32, 2, 96.0, 96.0, &testdata_8bppGray_xp};
557 static const BYTE bits_24bppBGR_gray[] = {
558 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
559 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
560 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
561 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
562 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255,
563 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255,
564 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255,
565 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255};
566 static const struct bitmap_data testdata_24bppBGR_gray = {
567 &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR_gray, 32, 2, 96.0, 96.0};
569 static void test_conversion(const struct bitmap_data *src, const struct bitmap_data *dst, const char *name, BOOL todo)
571 BitmapTestSrc *src_obj;
572 IWICBitmapSource *dst_bitmap;
573 HRESULT hr;
575 CreateTestBitmap(src, &src_obj);
577 hr = WICConvertBitmapSource(dst->format, &src_obj->IWICBitmapSource_iface, &dst_bitmap);
578 todo_wine_if (todo)
579 ok(hr == S_OK ||
580 broken(hr == E_INVALIDARG || hr == WINCODEC_ERR_COMPONENTNOTFOUND) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr);
582 if (hr == S_OK)
584 compare_bitmap_data(src, dst, dst_bitmap, name);
586 IWICBitmapSource_Release(dst_bitmap);
589 DeleteTestBitmap(src_obj);
592 static void test_invalid_conversion(void)
594 BitmapTestSrc *src_obj;
595 IWICBitmapSource *dst_bitmap;
596 HRESULT hr;
598 CreateTestBitmap(&testdata_32bppBGRA, &src_obj);
600 /* convert to a non-pixel-format GUID */
601 hr = WICConvertBitmapSource(&GUID_VendorMicrosoft, &src_obj->IWICBitmapSource_iface, &dst_bitmap);
602 ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "WICConvertBitmapSource returned %x\n", hr);
604 DeleteTestBitmap(src_obj);
607 static void test_default_converter(void)
609 BitmapTestSrc *src_obj;
610 IWICFormatConverter *converter;
611 BOOL can_convert = TRUE;
612 HRESULT hr;
614 CreateTestBitmap(&testdata_32bppBGRA, &src_obj);
616 hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER,
617 &IID_IWICFormatConverter, (void**)&converter);
618 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
619 if (SUCCEEDED(hr))
621 hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA,
622 &GUID_WICPixelFormat32bppBGR, &can_convert);
623 ok(SUCCEEDED(hr), "CanConvert returned %x\n", hr);
624 ok(can_convert, "expected TRUE, got %i\n", can_convert);
626 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
627 &GUID_WICPixelFormat32bppBGR, WICBitmapDitherTypeNone, NULL, 0.0,
628 WICBitmapPaletteTypeCustom);
629 ok(SUCCEEDED(hr), "Initialize returned %x\n", hr);
631 if (SUCCEEDED(hr))
632 compare_bitmap_data(&testdata_32bppBGRA, &testdata_32bppBGR, (IWICBitmapSource*)converter, "default converter");
634 IWICFormatConverter_Release(converter);
637 DeleteTestBitmap(src_obj);
640 typedef struct property_opt_test_data
642 LPCOLESTR name;
643 VARTYPE var_type;
644 VARTYPE initial_var_type;
645 int i_init_val;
646 float f_init_val;
647 BOOL skippable;
648 } property_opt_test_data;
650 static const WCHAR wszTiffCompressionMethod[] = {'T','i','f','f','C','o','m','p','r','e','s','s','i','o','n','M','e','t','h','o','d',0};
651 static const WCHAR wszCompressionQuality[] = {'C','o','m','p','r','e','s','s','i','o','n','Q','u','a','l','i','t','y',0};
652 static const WCHAR wszInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0};
653 static const WCHAR wszFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0};
654 static const WCHAR wszImageQuality[] = {'I','m','a','g','e','Q','u','a','l','i','t','y',0};
655 static const WCHAR wszBitmapTransform[] = {'B','i','t','m','a','p','T','r','a','n','s','f','o','r','m',0};
656 static const WCHAR wszLuminance[] = {'L','u','m','i','n','a','n','c','e',0};
657 static const WCHAR wszChrominance[] = {'C','h','r','o','m','i','n','a','n','c','e',0};
658 static const WCHAR wszJpegYCrCbSubsampling[] = {'J','p','e','g','Y','C','r','C','b','S','u','b','s','a','m','p','l','i','n','g',0};
659 static const WCHAR wszSuppressApp0[] = {'S','u','p','p','r','e','s','s','A','p','p','0',0};
660 static const WCHAR wszEnableV5Header32bppBGRA[] = {'E','n','a','b','l','e','V','5','H','e','a','d','e','r','3','2','b','p','p','B','G','R','A',0};
662 static const struct property_opt_test_data testdata_tiff_props[] = {
663 { wszTiffCompressionMethod, VT_UI1, VT_UI1, WICTiffCompressionDontCare },
664 { wszCompressionQuality, VT_R4, VT_EMPTY },
665 { NULL }
668 static const struct property_opt_test_data testdata_png_props[] = {
669 { wszInterlaceOption, VT_BOOL, VT_BOOL, 0 },
670 { wszFilterOption, VT_UI1, VT_UI1, WICPngFilterUnspecified, 0.0f, TRUE /* not supported on XP/2k3 */},
671 { NULL }
674 static const struct property_opt_test_data testdata_jpeg_props[] = {
675 { wszImageQuality, VT_R4, VT_EMPTY },
676 { wszBitmapTransform, VT_UI1, VT_UI1, WICBitmapTransformRotate0 },
677 { wszLuminance, VT_I4|VT_ARRAY, VT_EMPTY },
678 { wszChrominance, VT_I4|VT_ARRAY, VT_EMPTY },
679 { wszJpegYCrCbSubsampling, VT_UI1, VT_UI1, WICJpegYCrCbSubsamplingDefault, 0.0f, TRUE }, /* not supported on XP/2k3 */
680 { wszSuppressApp0, VT_BOOL, VT_BOOL, FALSE },
681 { NULL }
684 static const struct property_opt_test_data testdata_bmp_props[] = {
685 { wszEnableV5Header32bppBGRA, VT_BOOL, VT_BOOL, VARIANT_FALSE, 0.0f, TRUE }, /* Supported since Win7 */
686 { NULL }
689 static int find_property_index(const WCHAR* name, PROPBAG2* all_props, int all_prop_cnt)
691 int i;
692 for (i=0; i < all_prop_cnt; i++)
694 if (lstrcmpW(name, all_props[i].pstrName) == 0)
695 return i;
697 return -1;
700 static void test_specific_encoder_properties(IPropertyBag2 *options, const property_opt_test_data* data, PROPBAG2* all_props, int all_prop_cnt)
702 HRESULT hr;
703 int i = 0;
704 VARIANT pvarValue;
705 HRESULT phrError = S_OK;
707 while (data[i].name)
709 int idx = find_property_index(data[i].name, all_props, all_prop_cnt);
710 PROPBAG2 pb = {0};
711 pb.pstrName = (LPOLESTR)data[i].name;
713 hr = IPropertyBag2_Read(options, 1, &pb, NULL, &pvarValue, &phrError);
715 if (data[i].skippable && idx == -1)
717 win_skip("Property %s is not supported on this machine.\n", wine_dbgstr_w(data[i].name));
718 i++;
719 continue;
722 ok(idx >= 0, "Property %s not in output of GetPropertyInfo\n",
723 wine_dbgstr_w(data[i].name));
724 if (idx >= 0)
726 ok(all_props[idx].vt == data[i].var_type, "Property %s has unexpected vt type, vt=%i\n",
727 wine_dbgstr_w(data[i].name), all_props[idx].vt);
728 ok(all_props[idx].dwType == PROPBAG2_TYPE_DATA, "Property %s has unexpected dw type, vt=%i\n",
729 wine_dbgstr_w(data[i].name), all_props[idx].dwType);
730 ok(all_props[idx].cfType == 0, "Property %s has unexpected cf type, vt=%i\n",
731 wine_dbgstr_w(data[i].name), all_props[idx].cfType);
734 ok(SUCCEEDED(hr), "Reading property %s from bag failed, hr=%x\n",
735 wine_dbgstr_w(data[i].name), hr);
737 if (SUCCEEDED(hr))
739 /* On XP the initial type is always VT_EMPTY */
740 ok(V_VT(&pvarValue) == data[i].initial_var_type || V_VT(&pvarValue) == VT_EMPTY,
741 "Property %s has unexpected initial type, V_VT=%i\n",
742 wine_dbgstr_w(data[i].name), V_VT(&pvarValue));
744 if(V_VT(&pvarValue) == data[i].initial_var_type)
746 switch (data[i].initial_var_type)
748 case VT_BOOL:
749 case VT_UI1:
750 ok(V_UNION(&pvarValue, bVal) == data[i].i_init_val, "Property %s has an unexpected initial value, pvarValue=%i\n",
751 wine_dbgstr_w(data[i].name), V_UNION(&pvarValue, bVal));
752 break;
753 case VT_R4:
754 ok(V_UNION(&pvarValue, fltVal) == data[i].f_init_val, "Property %s has an unexpected initial value, pvarValue=%f\n",
755 wine_dbgstr_w(data[i].name), V_UNION(&pvarValue, fltVal));
756 break;
757 default:
758 break;
762 VariantClear(&pvarValue);
765 i++;
769 static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *options)
771 HRESULT hr;
772 ULONG cProperties = 0;
773 ULONG cProperties2 = 0;
774 PROPBAG2 all_props[64] = {{0}}; /* Should be enough for every encoder out there */
775 int i;
777 /* CountProperties */
779 hr = IPropertyBag2_CountProperties(options, &cProperties);
780 ok(SUCCEEDED(hr), "Reading property count, hr=%x\n", hr);
783 /* GetPropertyInfo */
785 hr = IPropertyBag2_GetPropertyInfo(options, cProperties, 1, all_props, &cProperties2);
786 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - iProperty out of bounce handled wrong, hr=%x\n", hr);
788 hr = IPropertyBag2_GetPropertyInfo(options, 0, cProperties+1, all_props, &cProperties2);
789 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - cProperty out of bounce handled wrong, hr=%x\n", hr);
791 if (cProperties == 0) /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */
793 cProperties2 = cProperties;
794 hr = S_OK;
796 else
798 hr = IPropertyBag2_GetPropertyInfo(options, 0, min(64, cProperties), all_props, &cProperties2);
799 ok(SUCCEEDED(hr), "Reading infos from property bag failed, hr=%x\n", hr);
802 if (FAILED(hr))
803 return;
805 ok(cProperties == cProperties2, "Mismatch of property count (IPropertyBag2::CountProperties=%i, IPropertyBag2::GetPropertyInfo=%i)\n",
806 (int)cProperties, (int)cProperties2);
809 if (IsEqualCLSID(clsid_encoder, &CLSID_WICTiffEncoder))
810 test_specific_encoder_properties(options, testdata_tiff_props, all_props, cProperties2);
811 else if (IsEqualCLSID(clsid_encoder, &CLSID_WICPngEncoder))
812 test_specific_encoder_properties(options, testdata_png_props, all_props, cProperties2);
813 else if (IsEqualCLSID(clsid_encoder, &CLSID_WICJpegEncoder))
814 test_specific_encoder_properties(options, testdata_jpeg_props, all_props, cProperties2);
815 else if (IsEqualCLSID(clsid_encoder, &CLSID_WICBmpEncoder))
816 test_specific_encoder_properties(options, testdata_bmp_props, all_props, cProperties2);
818 for (i=0; i < cProperties2; i++)
820 ok(all_props[i].pstrName != NULL, "Unset property name in output of IPropertyBag2::GetPropertyInfo\n");
821 CoTaskMemFree(all_props[i].pstrName);
825 static void load_stream(IUnknown *reader, IStream *stream)
827 HRESULT hr;
828 IWICPersistStream *persist;
829 #ifdef WORDS_BIGENDIAN
830 DWORD persist_options = WICPersistOptionBigEndian;
831 #else
832 DWORD persist_options = WICPersistOptionLittleEndian;
833 #endif
835 hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist);
836 ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
838 hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options);
839 ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr);
841 IWICPersistStream_Release(persist);
844 static void check_tiff_format(IStream *stream, const WICPixelFormatGUID *format)
846 HRESULT hr;
847 IWICMetadataReader *reader;
848 PROPVARIANT id, value;
849 struct
851 USHORT byte_order;
852 USHORT version;
853 ULONG dir_offset;
854 } tiff;
855 LARGE_INTEGER pos;
856 UINT count, i;
857 int width, height, bps, photo, samples, colormap;
858 struct
860 int id, *value;
861 } tag[] =
863 { 0x100, &width }, { 0x101, &height }, { 0x102, &bps },
864 { 0x106, &photo }, { 0x115, &samples }, { 0x140, &colormap }
867 memset(&tiff, 0, sizeof(tiff));
868 hr = IStream_Read(stream, &tiff, sizeof(tiff), NULL);
869 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
870 ok(tiff.byte_order == MAKEWORD('I','I') || tiff.byte_order == MAKEWORD('M','M'),
871 "wrong TIFF byte order mark %02x\n", tiff.byte_order);
872 ok(tiff.version == 42, "wrong TIFF version %u\n", tiff.version);
874 pos.QuadPart = tiff.dir_offset;
875 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
876 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
878 hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER,
879 &IID_IWICMetadataReader, (void **)&reader);
880 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
882 load_stream((IUnknown *)reader, stream);
884 hr = IWICMetadataReader_GetCount(reader, &count);
885 ok(hr == S_OK, "GetCount error %#x\n", hr);
886 ok(count != 0, "wrong count %u\n", count);
888 for (i = 0; i < ARRAY_SIZE(tag); i++)
890 PropVariantInit(&id);
891 PropVariantInit(&value);
893 id.vt = VT_UI2;
894 U(id).uiVal = tag[i].id;
895 hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value);
896 ok(hr == S_OK || (tag[i].id == 0x140 && hr == WINCODEC_ERR_PROPERTYNOTFOUND),
897 "GetValue(%04x) error %#x\n", tag[i].id, hr);
898 if (hr == S_OK)
900 ok(value.vt == VT_UI2 || value.vt == VT_UI4 || value.vt == (VT_UI2 | VT_VECTOR), "wrong vt: %d\n", value.vt);
901 tag[i].value[0] = U(value).uiVal;
903 else
904 tag[i].value[0] = -1;
906 PropVariantClear(&value);
909 IWICMetadataReader_Release(reader);
911 if (IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite))
913 ok(width == 32, "wrong width %u\n", width);
914 ok(height == 2, "wrong height %u\n", height);
916 ok(bps == 1, "wrong bps %d\n", bps);
917 ok(photo == 1, "wrong photometric %d\n", photo);
918 ok(samples == 1, "wrong samples %d\n", samples);
919 ok(colormap == -1, "wrong colormap %d\n", colormap);
921 else if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed))
923 ok(width == 32, "wrong width %u\n", width);
924 ok(height == 2, "wrong height %u\n", height);
926 ok(bps == 1, "wrong bps %d\n", bps);
927 ok(photo == 3, "wrong photometric %d\n", photo);
928 ok(samples == 1, "wrong samples %d\n", samples);
929 ok(colormap == 6, "wrong colormap %d\n", colormap);
931 else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed))
933 ok(width == 32, "wrong width %u\n", width);
934 ok(height == 2, "wrong height %u\n", height);
936 ok(bps == 4, "wrong bps %d\n", bps);
937 ok(photo == 3, "wrong photometric %d\n", photo);
938 ok(samples == 1, "wrong samples %d\n", samples);
939 ok(colormap == 48, "wrong colormap %d\n", colormap);
941 else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
943 ok(width == 32, "wrong width %u\n", width);
944 ok(height == 2, "wrong height %u\n", height);
946 ok(bps == 8, "wrong bps %d\n", bps);
947 ok(photo == 3, "wrong photometric %d\n", photo);
948 ok(samples == 1, "wrong samples %d\n", samples);
949 ok(colormap == 768, "wrong colormap %d\n", colormap);
951 else if (IsEqualGUID(format, &GUID_WICPixelFormat24bppBGR))
953 ok(width == 32, "wrong width %u\n", width);
954 ok(height == 2, "wrong height %u\n", height);
956 ok(bps == 3, "wrong bps %d\n", bps);
957 ok(photo == 2, "wrong photometric %d\n", photo);
958 ok(samples == 3, "wrong samples %d\n", samples);
959 ok(colormap == -1, "wrong colormap %d\n", colormap);
961 else
962 ok(0, "unknown TIFF pixel format %s\n", wine_dbgstr_guid(format));
965 static void check_bmp_format(IStream *stream, const WICPixelFormatGUID *format)
967 HRESULT hr;
968 BITMAPFILEHEADER bfh;
969 BITMAPV5HEADER bih;
971 hr = IStream_Read(stream, &bfh, sizeof(bfh), NULL);
972 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
974 ok(bfh.bfType == 0x4d42, "wrong BMP signature %02x\n", bfh.bfType);
975 ok(bfh.bfReserved1 == 0, "wrong bfReserved1 %02x\n", bfh.bfReserved1);
976 ok(bfh.bfReserved2 == 0, "wrong bfReserved2 %02x\n", bfh.bfReserved2);
978 hr = IStream_Read(stream, &bih, sizeof(bih), NULL);
979 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
981 if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed))
983 ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits);
985 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
986 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
988 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
989 ok(bih.bV5BitCount == 1, "wrong BitCount %d\n", bih.bV5BitCount);
990 ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
991 ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
993 else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed))
995 ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits);
997 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
998 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
1000 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
1001 ok(bih.bV5BitCount == 4, "wrong BitCount %d\n", bih.bV5BitCount);
1002 ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
1003 ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
1005 else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
1007 ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits);
1009 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
1010 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
1012 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
1013 ok(bih.bV5BitCount == 8, "wrong BitCount %d\n", bih.bV5BitCount);
1014 ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
1015 ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
1017 else if (IsEqualGUID(format, &GUID_WICPixelFormat32bppBGR))
1019 ok(bfh.bfOffBits == 0x0036, "wrong bfOffBits %08x\n", bfh.bfOffBits);
1021 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
1022 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
1024 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
1025 ok(bih.bV5BitCount == 32, "wrong BitCount %d\n", bih.bV5BitCount);
1026 ok(bih.bV5ClrUsed == 0, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
1027 ok(bih.bV5ClrImportant == 0, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
1029 else
1030 ok(0, "unknown BMP pixel format %s\n", wine_dbgstr_guid(format));
1033 static unsigned be_uint(unsigned val)
1035 union
1037 unsigned val;
1038 char c[4];
1039 } u;
1041 u.val = val;
1042 return (u.c[0] << 24) | (u.c[1] << 16) | (u.c[2] << 8) | u.c[3];
1045 static void check_png_format(IStream *stream, const WICPixelFormatGUID *format)
1047 static const char png_sig[8] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a};
1048 static const char png_IHDR[8] = {0,0,0,0x0d,'I','H','D','R'};
1049 HRESULT hr;
1050 struct
1052 char png_sig[8];
1053 char ihdr_sig[8];
1054 unsigned width, height;
1055 char bit_depth, color_type, compression, filter, interlace;
1056 } png;
1058 memset(&png, 0, sizeof(png));
1059 hr = IStream_Read(stream, &png, sizeof(png), NULL);
1060 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
1062 ok(!memcmp(png.png_sig, png_sig, sizeof(png_sig)), "expected PNG signature\n");
1063 ok(!memcmp(png.ihdr_sig, png_IHDR, sizeof(png_IHDR)), "expected PNG IHDR\n");
1065 if (IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite))
1067 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1068 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1070 ok(png.bit_depth == 1, "wrong bit_depth %d\n", png.bit_depth);
1071 ok(png.color_type == 0, "wrong color_type %d\n", png.color_type);
1072 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1073 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1074 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1076 else if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed))
1078 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1079 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1081 ok(png.bit_depth == 1, "wrong bit_depth %d\n", png.bit_depth);
1082 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1083 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1084 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1085 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1087 else if (IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed))
1089 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1090 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1092 ok(png.bit_depth == 2, "wrong bit_depth %d\n", png.bit_depth);
1093 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1094 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1095 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1096 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1098 else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed))
1100 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1101 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1103 ok(png.bit_depth == 4, "wrong bit_depth %d\n", png.bit_depth);
1104 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1105 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1106 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1107 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1109 else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
1111 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1112 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1114 ok(png.bit_depth == 8, "wrong bit_depth %d\n", png.bit_depth);
1115 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1116 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1117 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1118 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1120 else if (IsEqualGUID(format, &GUID_WICPixelFormat24bppBGR))
1122 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1123 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1125 ok(png.bit_depth == 8, "wrong bit_depth %d\n", png.bit_depth);
1126 ok(png.color_type == 2, "wrong color_type %d\n", png.color_type);
1127 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1128 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1129 ok(png.interlace == 0 || png.interlace == 1, "wrong interlace %d\n", png.interlace);
1131 else
1132 ok(0, "unknown PNG pixel format %s\n", wine_dbgstr_guid(format));
1135 static void check_gif_format(IStream *stream, const WICPixelFormatGUID *format)
1137 #include "pshpack1.h"
1138 struct logical_screen_descriptor
1140 char signature[6];
1141 USHORT width;
1142 USHORT height;
1143 BYTE packed;
1144 /* global_color_table_flag : 1;
1145 * color_resolution : 3;
1146 * sort_flag : 1;
1147 * global_color_table_size : 3;
1149 BYTE background_color_index;
1150 BYTE pixel_aspect_ratio;
1151 } lsd;
1152 #include "poppack.h"
1153 UINT color_resolution;
1154 HRESULT hr;
1156 memset(&lsd, 0, sizeof(lsd));
1157 hr = IStream_Read(stream, &lsd, sizeof(lsd), NULL);
1158 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
1160 ok(!memcmp(lsd.signature, "GIF89a", 6), "wrong GIF signature %.6s\n", lsd.signature);
1162 ok(lsd.width == 32, "wrong width %u\n", lsd.width);
1163 ok(lsd.height == 2, "wrong height %u\n", lsd.height);
1164 color_resolution = 1 << (((lsd.packed >> 4) & 0x07) + 1);
1165 ok(color_resolution == 256, "wrong color resolution %u\n", color_resolution);
1166 ok(lsd.pixel_aspect_ratio == 0, "wrong pixel_aspect_ratio %u\n", lsd.pixel_aspect_ratio);
1169 static void check_bitmap_format(IStream *stream, const CLSID *encoder, const WICPixelFormatGUID *format)
1171 HRESULT hr;
1172 LARGE_INTEGER pos;
1174 pos.QuadPart = 0;
1175 hr = IStream_Seek(stream, pos, SEEK_SET, (ULARGE_INTEGER *)&pos);
1176 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
1178 if (IsEqualGUID(encoder, &CLSID_WICPngEncoder))
1179 check_png_format(stream, format);
1180 else if (IsEqualGUID(encoder, &CLSID_WICBmpEncoder))
1181 check_bmp_format(stream, format);
1182 else if (IsEqualGUID(encoder, &CLSID_WICTiffEncoder))
1183 check_tiff_format(stream, format);
1184 else if (IsEqualGUID(encoder, &CLSID_WICGifEncoder))
1185 check_gif_format(stream, format);
1186 else
1187 ok(0, "unknown encoder %s\n", wine_dbgstr_guid(encoder));
1189 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
1190 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
1193 struct setting {
1194 const WCHAR *name;
1195 PROPBAG2_TYPE type;
1196 VARTYPE vt;
1197 void *value;
1200 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
1201 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
1203 ULONG rc;
1204 IUnknown_AddRef(obj);
1205 rc = IUnknown_Release(obj);
1206 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
1209 static void test_set_frame_palette(IWICBitmapFrameEncode *frameencode)
1211 IWICComponentFactory *factory;
1212 IWICPalette *palette;
1213 HRESULT hr;
1215 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1216 &IID_IWICComponentFactory, (void **)&factory);
1217 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
1219 hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL);
1220 ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr);
1222 hr = IWICComponentFactory_CreatePalette(factory, &palette);
1223 ok(hr == S_OK, "CreatePalette failed, hr=%x\n", hr);
1225 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1226 todo_wine
1227 ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr=%x\n", hr);
1229 hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedHalftone256, FALSE);
1230 ok(hr == S_OK, "InitializePredefined failed, hr=%x\n", hr);
1232 EXPECT_REF(palette, 1);
1233 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1234 ok(hr == S_OK, "SetPalette failed, hr=%x\n", hr);
1235 EXPECT_REF(palette, 1);
1237 hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL);
1238 ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr);
1240 IWICPalette_Release(palette);
1241 IWICComponentFactory_Release(factory);
1244 static void test_multi_encoder_impl(const struct bitmap_data **srcs, const CLSID* clsid_encoder,
1245 const struct bitmap_data **dsts, const CLSID *clsid_decoder, WICRect *rc,
1246 const struct setting *settings, const char *name, IWICPalette *palette, BOOL set_size)
1248 const GUID *container_format = NULL;
1249 HRESULT hr;
1250 IWICBitmapEncoder *encoder;
1251 BitmapTestSrc *src_obj;
1252 HGLOBAL hglobal;
1253 IStream *stream;
1254 IWICBitmapFrameEncode *frameencode;
1255 IPropertyBag2 *options=NULL;
1256 IWICBitmapDecoder *decoder;
1257 IWICBitmapFrameDecode *framedecode;
1258 WICPixelFormatGUID pixelformat;
1259 GUID guid;
1260 int i;
1262 hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER,
1263 &IID_IWICBitmapEncoder, (void **)&encoder);
1264 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
1266 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1267 ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
1269 hr = IWICBitmapEncoder_GetContainerFormat(encoder, NULL);
1270 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1272 if (IsEqualGUID(clsid_encoder, &CLSID_WICPngEncoder))
1273 container_format = &GUID_ContainerFormatPng;
1274 else if (IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder))
1275 container_format = &GUID_ContainerFormatBmp;
1276 else if (IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder))
1277 container_format = &GUID_ContainerFormatTiff;
1278 else if (IsEqualGUID(clsid_encoder, &CLSID_WICJpegEncoder))
1279 container_format = &GUID_ContainerFormatJpeg;
1280 else if (IsEqualGUID(clsid_encoder, &CLSID_WICGifEncoder))
1281 container_format = &GUID_ContainerFormatGif;
1282 else
1283 ok(0, "Unknown encoder %s.\n", wine_dbgstr_guid(clsid_encoder));
1285 if (container_format)
1287 memset(&guid, 0, sizeof(guid));
1288 hr = IWICBitmapEncoder_GetContainerFormat(encoder, &guid);
1289 ok(SUCCEEDED(hr), "Failed to get container format, hr %#x.\n", hr);
1290 ok(IsEqualGUID(container_format, &guid), "Unexpected container format %s.\n", wine_dbgstr_guid(&guid));
1293 hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache);
1294 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1296 /* Encoder options are optional. */
1297 hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, NULL);
1298 ok(SUCCEEDED(hr), "Failed to create encode frame, hr %#x.\n", hr);
1300 IStream_Release(stream);
1301 IWICBitmapEncoder_Release(encoder);
1302 IWICBitmapFrameEncode_Release(frameencode);
1304 hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER,
1305 &IID_IWICBitmapEncoder, (void**)&encoder);
1306 ok(SUCCEEDED(hr), "CoCreateInstance(%s) failed, hr=%x\n", wine_dbgstr_guid(clsid_encoder), hr);
1307 if (SUCCEEDED(hr))
1309 hglobal = GlobalAlloc(GMEM_MOVEABLE, 0);
1310 ok(hglobal != NULL, "GlobalAlloc failed\n");
1311 if (hglobal)
1313 hr = CreateStreamOnHGlobal(hglobal, TRUE, &stream);
1314 ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
1317 if (hglobal && SUCCEEDED(hr))
1319 if (palette)
1321 hr = IWICBitmapEncoder_SetPalette(encoder, palette);
1322 ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#x (%s)\n", hr, name);
1325 hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache);
1326 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1328 if (palette)
1330 hr = IWICBitmapEncoder_SetPalette(encoder, palette);
1331 if (IsEqualGUID(clsid_encoder, &CLSID_WICGifEncoder))
1332 ok(hr == S_OK, "SetPalette failed, hr=%#x\n", hr);
1333 else
1334 ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "wrong error %#x\n", hr);
1335 hr = S_OK;
1338 i=0;
1339 while (SUCCEEDED(hr) && srcs[i])
1341 CreateTestBitmap(srcs[i], &src_obj);
1343 hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, &options);
1344 ok(SUCCEEDED(hr), "CreateFrame failed, hr=%x\n", hr);
1345 if (SUCCEEDED(hr))
1347 ok(options != NULL, "Encoder initialization has not created an property bag\n");
1348 if(options)
1349 test_encoder_properties(clsid_encoder, options);
1351 if (settings)
1353 int j;
1354 for (j=0; settings[j].name; j++)
1356 PROPBAG2 propbag;
1357 VARIANT var;
1359 memset(&propbag, 0, sizeof(propbag));
1360 memset(&var, 0, sizeof(var));
1361 propbag.pstrName = (LPOLESTR)settings[j].name;
1362 propbag.dwType = settings[j].type;
1363 V_VT(&var) = settings[j].vt;
1364 V_UNKNOWN(&var) = settings[j].value;
1366 hr = IPropertyBag2_Write(options, 1, &propbag, &var);
1367 ok(SUCCEEDED(hr), "Writing property %s failed, hr=%x\n", wine_dbgstr_w(settings[j].name), hr);
1371 if (palette)
1373 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1374 ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#x\n", hr);
1377 hr = IWICBitmapFrameEncode_Initialize(frameencode, options);
1378 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1380 memcpy(&pixelformat, srcs[i]->format, sizeof(GUID));
1381 hr = IWICBitmapFrameEncode_SetPixelFormat(frameencode, &pixelformat);
1382 ok(SUCCEEDED(hr), "SetPixelFormat failed, hr=%x\n", hr);
1383 ok(IsEqualGUID(&pixelformat, dsts[i]->format) ||
1384 (IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)) ||
1385 (IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)),
1386 "SetPixelFormat changed the format to %s (%s)\n", wine_dbgstr_guid(&pixelformat), name);
1388 if (set_size)
1390 hr = IWICBitmapFrameEncode_SetSize(frameencode, srcs[i]->width, srcs[i]->height);
1391 ok(hr == S_OK, "SetSize failed, hr=%x\n", hr);
1394 if (IsEqualGUID(clsid_encoder, &CLSID_WICPngEncoder))
1395 test_set_frame_palette(frameencode);
1397 if (palette)
1399 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1400 ok(SUCCEEDED(hr), "SetPalette failed, hr=%x (%s)\n", hr, name);
1403 hr = IWICBitmapFrameEncode_WriteSource(frameencode, &src_obj->IWICBitmapSource_iface, rc);
1404 if (rc && (rc->Width <= 0 || rc->Height <= 0))
1406 /* WriteSource fails but WriteSource_Proxy succeeds. */
1407 ok(hr == E_INVALIDARG, "WriteSource should fail, hr=%x (%s)\n", hr, name);
1408 hr = IWICBitmapFrameEncode_WriteSource_Proxy(frameencode, &src_obj->IWICBitmapSource_iface, rc);
1409 if (!set_size && rc->Width < 0)
1410 todo_wine
1411 ok(hr == WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS,
1412 "WriteSource_Proxy(%dx%d) got unexpected hr %x (%s)\n", rc->Width, rc->Height, hr, name);
1413 else
1414 ok(hr == S_OK, "WriteSource_Proxy failed, %dx%d, hr=%x (%s)\n", rc->Width, rc->Height, hr, name);
1416 else
1418 if (rc)
1419 ok(SUCCEEDED(hr), "WriteSource(%dx%d) failed, hr=%x (%s)\n", rc->Width, rc->Height, hr, name);
1420 else
1421 todo_wine_if((IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2) ||
1422 (IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2))
1423 ok(hr == S_OK, "WriteSource(NULL) failed, hr=%x (%s)\n", hr, name);
1427 if (SUCCEEDED(hr))
1429 hr = IWICBitmapFrameEncode_Commit(frameencode);
1430 if (!set_size && rc && rc->Height < 0)
1431 todo_wine
1432 ok(hr == WINCODEC_ERR_UNEXPECTEDSIZE, "Commit got unexpected hr %x (%s)\n", hr, name);
1433 else
1434 ok(hr == S_OK, "Commit failed, hr=%x (%s)\n", hr, name);
1437 IWICBitmapFrameEncode_Release(frameencode);
1438 IPropertyBag2_Release(options);
1441 DeleteTestBitmap(src_obj);
1443 i++;
1446 if (clsid_decoder == NULL)
1448 IStream_Release(stream);
1449 IWICBitmapEncoder_Release(encoder);
1450 return;
1453 if (SUCCEEDED(hr))
1455 hr = IWICBitmapEncoder_Commit(encoder);
1456 ok(SUCCEEDED(hr), "Commit failed, hr=%x\n", hr);
1458 if (IsEqualGUID(&pixelformat, dsts[0]->format))
1459 check_bitmap_format(stream, clsid_encoder, dsts[0]->format);
1462 if (SUCCEEDED(hr))
1464 hr = CoCreateInstance(clsid_decoder, NULL, CLSCTX_INPROC_SERVER,
1465 &IID_IWICBitmapDecoder, (void**)&decoder);
1466 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
1469 if (SUCCEEDED(hr))
1471 IWICPalette *frame_palette;
1473 hr = IWICImagingFactory_CreatePalette(factory, &frame_palette);
1474 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
1476 hr = IWICBitmapDecoder_CopyPalette(decoder, frame_palette);
1477 if (IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder))
1478 ok(hr == WINCODEC_ERR_WRONGSTATE, "wrong error %#x\n", hr);
1479 else
1480 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr);
1482 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
1483 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1485 hr = IWICBitmapDecoder_CopyPalette(decoder, frame_palette);
1486 if (IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder))
1487 ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING) /* XP */, "CopyPalette failed, hr=%#x\n", hr);
1488 else
1489 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr);
1491 hr = S_OK;
1492 i=0;
1493 while (SUCCEEDED(hr) && dsts[i])
1495 hr = IWICBitmapDecoder_GetFrame(decoder, i, &framedecode);
1496 ok(SUCCEEDED(hr), "GetFrame failed, hr=%x (%s)\n", hr, name);
1498 if (SUCCEEDED(hr))
1500 hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &pixelformat);
1501 ok(hr == S_OK, "GetPixelFormat) failed, hr=%x (%s)\n", hr, name);
1502 if (IsEqualGUID(&pixelformat, dsts[i]->format))
1503 compare_bitmap_data(srcs[i], dsts[i], (IWICBitmapSource*)framedecode, name);
1505 hr = IWICBitmapFrameDecode_CopyPalette(framedecode, frame_palette);
1506 if (winetest_debug > 1)
1507 trace("%s, bpp %d, %s, hr %#x\n", name, dsts[i]->bpp, wine_dbgstr_guid(dsts[i]->format), hr);
1508 if (dsts[i]->bpp > 8 || IsEqualGUID(dsts[i]->format, &GUID_WICPixelFormatBlackWhite))
1509 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr);
1510 else
1512 UINT count, ret;
1513 WICColor colors[256];
1515 ok(hr == S_OK, "CopyPalette error %#x (%s)\n", hr, name);
1517 count = 0;
1518 hr = IWICPalette_GetColorCount(frame_palette, &count);
1519 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1521 memset(colors, 0, sizeof(colors));
1522 ret = 0;
1523 hr = IWICPalette_GetColors(frame_palette, count, colors, &ret);
1524 ok(hr == S_OK, "GetColors error %#x\n", hr);
1525 ok(ret == count, "expected %u, got %u\n", count, ret);
1526 if (IsEqualGUID(clsid_decoder, &CLSID_WICPngDecoder))
1528 /* Newer libpng versions don't accept larger palettes than the declared
1529 * bit depth, so we need to generate the palette of the correct length.
1531 ok(count == 256 || (dsts[i]->bpp == 1 && count == 2) ||
1532 (dsts[i]->bpp == 2 && count == 4) || (dsts[i]->bpp == 4 && count == 16),
1533 "expected 256, got %u (%s)\n", count, name);
1535 ok(colors[0] == 0x11111111, "got %08x (%s)\n", colors[0], name);
1536 ok(colors[1] == 0x22222222, "got %08x (%s)\n", colors[1], name);
1537 if (count > 2)
1539 ok(colors[2] == 0x33333333, "got %08x (%s)\n", colors[2], name);
1540 ok(colors[3] == 0x44444444, "got %08x (%s)\n", colors[3], name);
1541 if (count > 4)
1543 ok(colors[4] == 0x55555555, "got %08x (%s)\n", colors[4], name);
1544 ok(colors[5] == 0, "got %08x (%s)\n", colors[5], name);
1548 else if (IsEqualGUID(clsid_decoder, &CLSID_WICBmpDecoder) ||
1549 IsEqualGUID(clsid_decoder, &CLSID_WICTiffDecoder) ||
1550 IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder))
1552 if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormatBlackWhite) ||
1553 IsEqualGUID(&pixelformat, &GUID_WICPixelFormat8bppIndexed))
1555 ok(count == 256, "expected 256, got %u (%s)\n", count, name);
1557 ok(colors[0] == 0xff111111, "got %08x (%s)\n", colors[0], name);
1558 ok(colors[1] == 0xff222222, "got %08x (%s)\n", colors[1], name);
1559 ok(colors[2] == 0xff333333, "got %08x (%s)\n", colors[2], name);
1560 ok(colors[3] == 0xff444444, "got %08x (%s)\n", colors[3], name);
1561 ok(colors[4] == 0xff555555, "got %08x (%s)\n", colors[4], name);
1562 ok(colors[5] == 0xff000000, "got %08x (%s)\n", colors[5], name);
1564 else if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed))
1566 ok(count == 16, "expected 16, got %u (%s)\n", count, name);
1568 ok(colors[0] == 0xff111111, "got %08x (%s)\n", colors[0], name);
1569 ok(colors[1] == 0xff222222, "got %08x (%s)\n", colors[1], name);
1570 ok(colors[2] == 0xff333333, "got %08x (%s)\n", colors[2], name);
1571 ok(colors[3] == 0xff444444, "got %08x (%s)\n", colors[3], name);
1572 ok(colors[4] == 0xff555555, "got %08x (%s)\n", colors[4], name);
1573 ok(colors[5] == 0xff000000, "got %08x (%s)\n", colors[5], name);
1575 else
1577 ok(count == 2, "expected 2, got %u (%s)\n", count, name);
1579 ok(colors[0] == 0xff111111, "got %08x (%s)\n", colors[0], name);
1580 ok(colors[1] == 0xff222222, "got %08x (%s)\n", colors[1], name);
1583 else
1585 ok(count == 2, "expected 2, got %u (%s)\n", count, name);
1587 ok(colors[0] == 0xff111111, "got %08x\n", colors[0]);
1588 ok(colors[1] == 0xff222222, "got %08x\n", colors[1]);
1592 IWICBitmapFrameDecode_Release(framedecode);
1595 i++;
1598 IWICPalette_Release(frame_palette);
1599 IWICBitmapDecoder_Release(decoder);
1602 IStream_Release(stream);
1605 IWICBitmapEncoder_Release(encoder);
1609 static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* clsid_encoder,
1610 const struct bitmap_data **dsts, const CLSID *clsid_decoder, WICRect *rc,
1611 const struct setting *settings, const char *name, IWICPalette *palette)
1613 test_multi_encoder_impl(srcs, clsid_encoder, dsts, clsid_decoder, rc, settings, name, palette, TRUE);
1614 test_multi_encoder_impl(srcs, clsid_encoder, dsts, clsid_decoder, rc, settings, name, palette, FALSE);
1617 static void test_encoder(const struct bitmap_data *src, const CLSID* clsid_encoder,
1618 const struct bitmap_data *dst, const CLSID *clsid_decoder, const char *name)
1620 const struct bitmap_data *srcs[2];
1621 const struct bitmap_data *dsts[2];
1622 WICColor colors[256];
1623 IWICPalette *palette;
1624 HRESULT hr;
1626 hr = IWICImagingFactory_CreatePalette(factory, &palette);
1627 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
1629 memset(colors, 0, sizeof(colors));
1630 colors[0] = 0x11111111;
1631 colors[1] = 0x22222222;
1632 colors[2] = 0x33333333;
1633 colors[3] = 0x44444444;
1634 colors[4] = 0x55555555;
1635 /* TIFF decoder fails to decode a 8bpp frame if palette has less than 256 colors */
1636 hr = IWICPalette_InitializeCustom(palette, colors, 256);
1637 ok(hr == S_OK, "InitializeCustom error %#x\n", hr);
1639 srcs[0] = src;
1640 srcs[1] = NULL;
1641 dsts[0] = dst;
1642 dsts[1] = NULL;
1644 test_multi_encoder(srcs, clsid_encoder, dsts, clsid_decoder, NULL, NULL, name, palette);
1646 IWICPalette_Release(palette);
1649 static void test_encoder_rects(void)
1651 const struct bitmap_data *srcs[2];
1652 const struct bitmap_data *dsts[2];
1653 WICRect rc;
1655 srcs[0] = &testdata_24bppBGR;
1656 srcs[1] = NULL;
1657 dsts[0] = &testdata_24bppBGR;
1658 dsts[1] = NULL;
1660 rc.X = 0;
1661 rc.Y = 0;
1662 rc.Width = 32;
1663 rc.Height = 2;
1665 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects full", NULL);
1667 rc.Width = 0;
1668 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects width=0", NULL);
1670 rc.Width = -1;
1671 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects width=-1", NULL);
1673 rc.Width = 32;
1674 rc.Height = 0;
1675 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects height=0", NULL);
1677 rc.Height = -1;
1678 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects height=-1", NULL);
1681 static const struct bitmap_data *multiple_frames[3] = {
1682 &testdata_24bppBGR,
1683 &testdata_24bppBGR,
1684 NULL};
1686 static const struct bitmap_data *single_frame[2] = {
1687 &testdata_24bppBGR,
1688 NULL};
1690 static const struct setting png_interlace_settings[] = {
1691 {wszInterlaceOption, PROPBAG2_TYPE_DATA, VT_BOOL, (void*)VARIANT_TRUE},
1692 {NULL}
1695 static void test_converter_8bppIndexed(void)
1697 HRESULT hr;
1698 BitmapTestSrc *src_obj;
1699 IWICFormatConverter *converter;
1700 IWICPalette *palette;
1701 UINT count, i;
1702 BYTE buf[32 * 2 * 3]; /* enough to hold 32x2 24bppBGR data */
1704 CreateTestBitmap(&testdata_24bppBGR, &src_obj);
1706 hr = IWICImagingFactory_CreatePalette(factory, &palette);
1707 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
1708 count = 0xdeadbeef;
1709 hr = IWICPalette_GetColorCount(palette, &count);
1710 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1711 ok(count == 0, "expected 0, got %u\n", count);
1713 /* NULL palette + Custom type */
1714 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1715 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1716 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1717 &GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone,
1718 NULL, 0.0, WICBitmapPaletteTypeCustom);
1719 ok(hr == S_OK, "Initialize error %#x\n", hr);
1720 hr = IWICFormatConverter_CopyPalette(converter, palette);
1721 ok(hr == 0xdeadbeef, "unexpected error %#x\n", hr);
1722 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32 * 3, sizeof(buf), buf);
1723 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1724 IWICFormatConverter_Release(converter);
1726 /* NULL palette + Custom type */
1727 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1728 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1729 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1730 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1731 NULL, 0.0, WICBitmapPaletteTypeCustom);
1732 ok(hr == E_INVALIDARG, "unexpected error %#x\n", hr);
1733 hr = IWICFormatConverter_CopyPalette(converter, palette);
1734 ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr);
1735 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1736 ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr);
1737 IWICFormatConverter_Release(converter);
1739 /* empty palette + Custom type */
1740 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1741 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1742 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1743 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1744 palette, 0.0, WICBitmapPaletteTypeCustom);
1745 ok(hr == S_OK, "Initialize error %#x\n", hr);
1746 hr = IWICFormatConverter_CopyPalette(converter, palette);
1747 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1748 count = 0xdeadbeef;
1749 hr = IWICPalette_GetColorCount(palette, &count);
1750 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1751 ok(count == 0, "expected 0, got %u\n", count);
1752 memset(buf, 0xaa, sizeof(buf));
1753 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1754 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1755 count = 0;
1756 for (i = 0; i < 32 * 2; i++)
1757 if (buf[i] != 0) count++;
1758 ok(count == 0, "expected 0\n");
1759 IWICFormatConverter_Release(converter);
1761 /* NULL palette + Predefined type */
1762 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1763 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1764 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1765 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1766 NULL, 0.0, WICBitmapPaletteTypeFixedGray16);
1767 ok(hr == S_OK, "Initialize error %#x\n", hr);
1768 hr = IWICFormatConverter_CopyPalette(converter, palette);
1769 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1770 count = 0xdeadbeef;
1771 hr = IWICPalette_GetColorCount(palette, &count);
1772 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1773 ok(count == 16, "expected 16, got %u\n", count);
1774 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1775 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1776 count = 0;
1777 for (i = 0; i < 32 * 2; i++)
1778 if (buf[i] != 0) count++;
1779 ok(count != 0, "expected != 0\n");
1780 IWICFormatConverter_Release(converter);
1782 /* not empty palette + Predefined type */
1783 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1784 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1785 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1786 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1787 palette, 0.0, WICBitmapPaletteTypeFixedHalftone64);
1788 ok(hr == S_OK, "Initialize error %#x\n", hr);
1789 hr = IWICFormatConverter_CopyPalette(converter, palette);
1790 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1791 count = 0xdeadbeef;
1792 hr = IWICPalette_GetColorCount(palette, &count);
1793 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1794 ok(count == 16, "expected 16, got %u\n", count);
1795 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1796 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1797 count = 0;
1798 for (i = 0; i < 32 * 2; i++)
1799 if (buf[i] != 0) count++;
1800 ok(count != 0, "expected != 0\n");
1801 IWICFormatConverter_Release(converter);
1803 /* not empty palette + MedianCut type */
1804 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1805 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1806 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1807 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1808 palette, 0.0, WICBitmapPaletteTypeMedianCut);
1809 ok(hr == S_OK, "Initialize error %#x\n", hr);
1810 hr = IWICFormatConverter_CopyPalette(converter, palette);
1811 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1812 count = 0xdeadbeef;
1813 hr = IWICPalette_GetColorCount(palette, &count);
1814 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1815 ok(count == 16, "expected 16, got %u\n", count);
1816 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1817 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1818 count = 0;
1819 for (i = 0; i < 32 * 2; i++)
1820 if (buf[i] != 0) count++;
1821 ok(count != 0, "expected != 0\n");
1822 IWICFormatConverter_Release(converter);
1824 /* NULL palette + MedianCut type */
1825 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1826 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1827 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1828 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1829 NULL, 0.0, WICBitmapPaletteTypeMedianCut);
1830 ok(hr == S_OK || broken(hr == E_INVALIDARG) /* XP */, "Initialize error %#x\n", hr);
1831 if (hr == S_OK)
1833 hr = IWICFormatConverter_CopyPalette(converter, palette);
1834 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1835 count = 0xdeadbeef;
1836 hr = IWICPalette_GetColorCount(palette, &count);
1837 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1838 ok(count == 8, "expected 8, got %u\n", count);
1839 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1840 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1841 count = 0;
1842 for (i = 0; i < 32 * 2; i++)
1843 if (buf[i] != 0) count++;
1844 ok(count != 0, "expected != 0\n");
1846 IWICFormatConverter_Release(converter);
1848 IWICPalette_Release(palette);
1849 DeleteTestBitmap(src_obj);
1852 START_TEST(converter)
1854 HRESULT hr;
1856 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1858 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1859 &IID_IWICImagingFactory, (void **)&factory);
1860 ok(hr == S_OK, "failed to create factory: %#x\n", hr);
1862 test_conversion(&testdata_24bppRGB, &testdata_1bppIndexed, "24bppRGB -> 1bppIndexed", TRUE);
1863 test_conversion(&testdata_24bppRGB, &testdata_2bppIndexed, "24bppRGB -> 2bppIndexed", TRUE);
1864 test_conversion(&testdata_24bppRGB, &testdata_4bppIndexed, "24bppRGB -> 4bppIndexed", TRUE);
1865 test_conversion(&testdata_24bppRGB, &testdata_8bppIndexed, "24bppRGB -> 8bppIndexed", FALSE);
1867 test_conversion(&testdata_BlackWhite, &testdata_8bppIndexed_BW, "BlackWhite -> 8bppIndexed", TRUE);
1868 test_conversion(&testdata_1bppIndexed, &testdata_8bppIndexed_BW, "1bppIndexed -> 8bppIndexed", TRUE);
1869 test_conversion(&testdata_2bppIndexed, &testdata_8bppIndexed_4colors, "2bppIndexed -> 8bppIndexed", TRUE);
1870 test_conversion(&testdata_4bppIndexed, &testdata_8bppIndexed, "4bppIndexed -> 8bppIndexed", TRUE);
1872 test_conversion(&testdata_32bppBGRA, &testdata_32bppBGR, "BGRA -> BGR", FALSE);
1873 test_conversion(&testdata_32bppBGR, &testdata_32bppBGRA, "BGR -> BGRA", FALSE);
1874 test_conversion(&testdata_32bppBGRA, &testdata_32bppBGRA, "BGRA -> BGRA", FALSE);
1875 test_conversion(&testdata_32bppBGRA80, &testdata_32bppPBGRA, "BGRA -> PBGRA", FALSE);
1877 test_conversion(&testdata_32bppRGBA, &testdata_32bppRGB, "RGBA -> RGB", FALSE);
1878 test_conversion(&testdata_32bppRGB, &testdata_32bppRGBA, "RGB -> RGBA", FALSE);
1879 test_conversion(&testdata_32bppRGBA, &testdata_32bppRGBA, "RGBA -> RGBA", FALSE);
1880 test_conversion(&testdata_32bppRGBA80, &testdata_32bppPRGBA, "RGBA -> PRGBA", FALSE);
1882 test_conversion(&testdata_24bppBGR, &testdata_24bppBGR, "24bppBGR -> 24bppBGR", FALSE);
1883 test_conversion(&testdata_24bppBGR, &testdata_24bppRGB, "24bppBGR -> 24bppRGB", FALSE);
1885 test_conversion(&testdata_24bppRGB, &testdata_24bppRGB, "24bppRGB -> 24bppRGB", FALSE);
1886 test_conversion(&testdata_24bppRGB, &testdata_24bppBGR, "24bppRGB -> 24bppBGR", FALSE);
1888 test_conversion(&testdata_32bppBGR, &testdata_24bppRGB, "32bppBGR -> 24bppRGB", FALSE);
1889 test_conversion(&testdata_24bppRGB, &testdata_32bppBGR, "24bppRGB -> 32bppBGR", FALSE);
1890 test_conversion(&testdata_32bppBGRA, &testdata_24bppRGB, "32bppBGRA -> 24bppRGB", FALSE);
1891 test_conversion(&testdata_32bppRGBA, &testdata_24bppBGR, "32bppRGBA -> 24bppBGR", FALSE);
1893 test_conversion(&testdata_32bppRGBA, &testdata_32bppBGRA, "32bppRGBA -> 32bppBGRA", FALSE);
1894 test_conversion(&testdata_32bppBGRA, &testdata_32bppRGBA, "32bppBGRA -> 32bppRGBA", FALSE);
1896 test_conversion(&testdata_64bppRGBA, &testdata_32bppRGBA, "64bppRGBA -> 32bppRGBA", FALSE);
1897 test_conversion(&testdata_64bppRGBA, &testdata_32bppRGB, "64bppRGBA -> 32bppRGB", FALSE);
1899 test_conversion(&testdata_24bppRGB, &testdata_32bppGrayFloat, "24bppRGB -> 32bppGrayFloat", FALSE);
1900 test_conversion(&testdata_32bppBGR, &testdata_32bppGrayFloat, "32bppBGR -> 32bppGrayFloat", FALSE);
1902 test_conversion(&testdata_24bppBGR, &testdata_8bppGray, "24bppBGR -> 8bppGray", FALSE);
1903 test_conversion(&testdata_32bppBGR, &testdata_8bppGray, "32bppBGR -> 8bppGray", FALSE);
1904 test_conversion(&testdata_32bppGrayFloat, &testdata_24bppBGR_gray, "32bppGrayFloat -> 24bppBGR gray", FALSE);
1905 test_conversion(&testdata_32bppGrayFloat, &testdata_8bppGray, "32bppGrayFloat -> 8bppGray", FALSE);
1907 test_invalid_conversion();
1908 test_default_converter();
1909 test_converter_8bppIndexed();
1911 test_encoder(&testdata_8bppIndexed, &CLSID_WICGifEncoder,
1912 &testdata_8bppIndexed, &CLSID_WICGifDecoder, "GIF encoder 8bppIndexed");
1914 test_encoder(&testdata_BlackWhite, &CLSID_WICPngEncoder,
1915 &testdata_BlackWhite, &CLSID_WICPngDecoder, "PNG encoder BlackWhite");
1916 test_encoder(&testdata_1bppIndexed, &CLSID_WICPngEncoder,
1917 &testdata_1bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 1bppIndexed");
1918 test_encoder(&testdata_2bppIndexed, &CLSID_WICPngEncoder,
1919 &testdata_2bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 2bppIndexed");
1920 test_encoder(&testdata_4bppIndexed, &CLSID_WICPngEncoder,
1921 &testdata_4bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 4bppIndexed");
1922 test_encoder(&testdata_8bppIndexed, &CLSID_WICPngEncoder,
1923 &testdata_8bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 8bppIndexed");
1924 test_encoder(&testdata_24bppBGR, &CLSID_WICPngEncoder,
1925 &testdata_24bppBGR, &CLSID_WICPngDecoder, "PNG encoder 24bppBGR");
1926 if (!strcmp(winetest_platform, "windows")) /* FIXME: enable once implemented in Wine */
1928 test_encoder(&testdata_32bppBGR, &CLSID_WICPngEncoder,
1929 &testdata_24bppBGR, &CLSID_WICPngDecoder, "PNG encoder 32bppBGR");
1932 test_encoder(&testdata_BlackWhite, &CLSID_WICBmpEncoder,
1933 &testdata_1bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder BlackWhite");
1934 test_encoder(&testdata_1bppIndexed, &CLSID_WICBmpEncoder,
1935 &testdata_1bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 1bppIndexed");
1936 test_encoder(&testdata_2bppIndexed, &CLSID_WICBmpEncoder,
1937 &testdata_4bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 2bppIndexed");
1938 test_encoder(&testdata_4bppIndexed, &CLSID_WICBmpEncoder,
1939 &testdata_4bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 4bppIndexed");
1940 test_encoder(&testdata_8bppIndexed, &CLSID_WICBmpEncoder,
1941 &testdata_8bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 8bppIndexed");
1942 test_encoder(&testdata_32bppBGR, &CLSID_WICBmpEncoder,
1943 &testdata_32bppBGR, &CLSID_WICBmpDecoder, "BMP encoder 32bppBGR");
1945 test_encoder(&testdata_BlackWhite, &CLSID_WICTiffEncoder,
1946 &testdata_BlackWhite, &CLSID_WICTiffDecoder, "TIFF encoder BlackWhite");
1947 test_encoder(&testdata_1bppIndexed, &CLSID_WICTiffEncoder,
1948 &testdata_1bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 1bppIndexed");
1949 test_encoder(&testdata_2bppIndexed, &CLSID_WICTiffEncoder,
1950 &testdata_4bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 2bppIndexed");
1951 test_encoder(&testdata_4bppIndexed, &CLSID_WICTiffEncoder,
1952 &testdata_4bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 4bppIndexed");
1953 test_encoder(&testdata_8bppIndexed, &CLSID_WICTiffEncoder,
1954 &testdata_8bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 8bppIndexed");
1955 test_encoder(&testdata_24bppBGR, &CLSID_WICTiffEncoder,
1956 &testdata_24bppBGR, &CLSID_WICTiffDecoder, "TIFF encoder 24bppBGR");
1958 test_encoder(&testdata_24bppBGR, &CLSID_WICJpegEncoder,
1959 &testdata_24bppBGR, NULL, "JPEG encoder 24bppBGR");
1961 test_multi_encoder(multiple_frames, &CLSID_WICTiffEncoder,
1962 multiple_frames, &CLSID_WICTiffDecoder, NULL, NULL, "TIFF encoder multi-frame", NULL);
1964 test_encoder_rects();
1966 test_multi_encoder(single_frame, &CLSID_WICPngEncoder,
1967 single_frame, &CLSID_WICPngDecoder, NULL, png_interlace_settings, "PNG encoder interlaced", NULL);
1969 IWICImagingFactory_Release(factory);
1971 CoUninitialize();