[WINDOWSCODECS_WINETEST] Sync with Wine Staging 3.3. CORE-14434
[reactos.git] / modules / rostests / winetests / windowscodecs / converter.c
1 /*
2 * Copyright 2009 Vincent Povirk
3 * Copyright 2016 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 <math.h>
23
24 #define COBJMACROS
25 #define CONST_VTABLE
26
27 #include "windef.h"
28 #include "objbase.h"
29 #include "wincodec.h"
30 #include "wincodecsdk.h"
31 #include "wine/test.h"
32
33 static IWICImagingFactory *factory;
34
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;
45
46 typedef struct BitmapTestSrc {
47 IWICBitmapSource IWICBitmapSource_iface;
48 LONG ref;
49 const bitmap_data *data;
50 } BitmapTestSrc;
51
52 extern HRESULT STDMETHODCALLTYPE IWICBitmapFrameEncode_WriteSource_Proxy(IWICBitmapFrameEncode* This,
53 IWICBitmapSource *pIBitmapSource, WICRect *prc);
54
55 static BOOL near_equal(float a, float b)
56 {
57 return fabsf(a - b) < 0.001;
58 }
59
60 static inline BitmapTestSrc *impl_from_IWICBitmapSource(IWICBitmapSource *iface)
61 {
62 return CONTAINING_RECORD(iface, BitmapTestSrc, IWICBitmapSource_iface);
63 }
64
65 static HRESULT WINAPI BitmapTestSrc_QueryInterface(IWICBitmapSource *iface, REFIID iid,
66 void **ppv)
67 {
68 if (!ppv) return E_INVALIDARG;
69
70 if (IsEqualIID(&IID_IUnknown, iid) ||
71 IsEqualIID(&IID_IWICBitmapSource, iid))
72 *ppv = iface;
73 else
74 return E_NOINTERFACE;
75
76 IUnknown_AddRef((IUnknown*)*ppv);
77 return S_OK;
78 }
79
80 static ULONG WINAPI BitmapTestSrc_AddRef(IWICBitmapSource *iface)
81 {
82 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
83 ULONG ref = InterlockedIncrement(&This->ref);
84 return ref;
85 }
86
87 static ULONG WINAPI BitmapTestSrc_Release(IWICBitmapSource *iface)
88 {
89 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
90 ULONG ref = InterlockedDecrement(&This->ref);
91 return ref;
92 }
93
94 static HRESULT WINAPI BitmapTestSrc_GetSize(IWICBitmapSource *iface,
95 UINT *puiWidth, UINT *puiHeight)
96 {
97 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
98 *puiWidth = This->data->width;
99 *puiHeight = This->data->height;
100 return S_OK;
101 }
102
103 static HRESULT WINAPI BitmapTestSrc_GetPixelFormat(IWICBitmapSource *iface,
104 WICPixelFormatGUID *pPixelFormat)
105 {
106 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
107 memcpy(pPixelFormat, This->data->format, sizeof(GUID));
108 return S_OK;
109 }
110
111 static HRESULT WINAPI BitmapTestSrc_GetResolution(IWICBitmapSource *iface,
112 double *pDpiX, double *pDpiY)
113 {
114 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
115 *pDpiX = This->data->xres;
116 *pDpiY = This->data->yres;
117 return S_OK;
118 }
119
120 static HRESULT WINAPI BitmapTestSrc_CopyPalette(IWICBitmapSource *iface,
121 IWICPalette *palette)
122 {
123 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
124
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))
129 {
130 WICColor colors[8];
131
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);
141 }
142
143 /* unique error marker */
144 return 0xdeadbeef;
145 }
146
147 static HRESULT WINAPI BitmapTestSrc_CopyPixels(IWICBitmapSource *iface,
148 const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
149 {
150 BitmapTestSrc *This = impl_from_IWICBitmapSource(iface);
151 UINT bytesperrow;
152 UINT srcstride;
153 UINT row_offset;
154 WICRect rc;
155
156 if (!prc)
157 {
158 rc.X = 0;
159 rc.Y = 0;
160 rc.Width = This->data->width;
161 rc.Height = This->data->height;
162 prc = &rc;
163 }
164 else
165 {
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;
168 }
169
170 bytesperrow = ((This->data->bpp * prc->Width)+7)/8;
171 srcstride = ((This->data->bpp * This->data->width)+7)/8;
172
173 if (cbStride < bytesperrow)
174 return E_INVALIDARG;
175
176 if ((cbStride * prc->Height) > cbBufferSize)
177 return E_INVALIDARG;
178
179 row_offset = prc->X * This->data->bpp;
180
181 if (row_offset % 8 == 0)
182 {
183 UINT row;
184 const BYTE *src;
185 BYTE *dst;
186
187 src = This->data->bits + (row_offset / 8) + prc->Y * srcstride;
188 dst = pbBuffer;
189 for (row=0; row < prc->Height; row++)
190 {
191 memcpy(dst, src, bytesperrow);
192 src += srcstride;
193 dst += cbStride;
194 }
195 return S_OK;
196 }
197 else
198 {
199 ok(0, "bitmap %p was asked to copy pixels not aligned on a byte boundary\n", iface);
200 return E_FAIL;
201 }
202 }
203
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
213 };
214
215 static void CreateTestBitmap(const bitmap_data *data, BitmapTestSrc **This)
216 {
217 *This = HeapAlloc(GetProcessHeap(), 0, sizeof(**This));
218
219 if (*This)
220 {
221 (*This)->IWICBitmapSource_iface.lpVtbl = &BitmapTestSrc_Vtbl;
222 (*This)->ref = 1;
223 (*This)->data = data;
224 }
225 }
226
227 static void DeleteTestBitmap(BitmapTestSrc *This)
228 {
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);
232 }
233
234 static BOOL compare_bits(const struct bitmap_data *expect, UINT buffersize, const BYTE *converted_bits)
235 {
236 BOOL equal;
237
238 if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppBGR))
239 {
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))
246 {
247 equal = FALSE;
248 break;
249 }
250 }
251 else if (IsEqualGUID(expect->format, &GUID_WICPixelFormat32bppGrayFloat))
252 {
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]))
258 {
259 equal = FALSE;
260 break;
261 }
262 }
263 else if (IsEqualGUID(expect->format, &GUID_WICPixelFormatBlackWhite) ||
264 IsEqualGUID(expect->format, &GUID_WICPixelFormat1bppIndexed))
265 {
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 */)
271 {
272 equal = FALSE;
273 break;
274 }
275 }
276 else if (IsEqualGUID(expect->format, &GUID_WICPixelFormat2bppIndexed) ||
277 IsEqualGUID(expect->format, &GUID_WICPixelFormat4bppIndexed) ||
278 IsEqualGUID(expect->format, &GUID_WICPixelFormat8bppIndexed))
279 {
280 UINT i;
281 const BYTE *a=(const BYTE*)expect->bits, *b=(const BYTE*)converted_bits;
282 equal=TRUE;
283
284 for (i=0; i<buffersize; i++)
285 if (a[i] != b[i])
286 {
287 equal = FALSE;
288 break;
289 }
290 }
291 else
292 equal = (memcmp(expect->bits, converted_bits, buffersize) == 0);
293
294 if (!equal && expect->alt_data)
295 equal = compare_bits(expect->alt_data, buffersize, converted_bits);
296
297 if (!equal && winetest_debug > 1)
298 {
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++)
304 {
305 printf("%u,", converted_bits[i]);
306 if (!((i + 1) % 32)) printf("\n ");
307 else if (!((i+1) % bps)) printf(" ");
308 }
309 printf("\n");
310 }
311
312 return equal;
313 }
314
315 static BOOL is_indexed_format(const GUID *format)
316 {
317 if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed) ||
318 IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed) ||
319 IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed) ||
320 IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
321 return TRUE;
322
323 return FALSE;
324 }
325
326 static void compare_bitmap_data(const struct bitmap_data *src, const struct bitmap_data *expect,
327 IWICBitmapSource *source, const char *name)
328 {
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;
336
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);
341
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);
346
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);
350
351 prc.X = 0;
352 prc.Y = 0;
353 prc.Width = expect->width;
354 prc.Height = expect->height;
355
356 stride = (expect->bpp * expect->width + 7) / 8;
357 buffersize = stride * expect->height;
358
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);
363
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.
367 */
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);
370
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);
378
379 HeapFree(GetProcessHeap(), 0, converted_bits);
380 }
381
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};
390
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};
397
398 /* some encoders (like BMP) require data to be 4-bytes aligned */
399 static const BYTE bits_4bpp[] = {
400 0x01,0x23,0x01,0x23,0x01,0x23,0x01,0x23,0x01,0x23,0x01,0x23,0x01,0x23,0x01,0x23,
401 0x45,0x67,0x45,0x67,0x45,0x67,0x45,0x67,0x45,0x67,0x45,0x67,0x45,0x67,0x45,0x67};
402
403 static const struct bitmap_data testdata_4bppIndexed = {
404 &GUID_WICPixelFormat4bppIndexed, 4, bits_4bpp, 32, 2, 96.0, 96.0};
405
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};
411
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};
417
418 static const BYTE bits_8bpp[] = {
419 0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,
420 4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7};
421 static const struct bitmap_data testdata_8bppIndexed = {
422 &GUID_WICPixelFormat8bppIndexed, 8, bits_8bpp, 32, 2, 96.0, 96.0};
423
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};
435
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};
447
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};
463
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 struct bitmap_data testdata_32bppBGRA = {
474 &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0};
475 static const struct bitmap_data testdata_32bppRGBA = {
476 &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0};
477 static const struct bitmap_data testdata_32bppRGB = {
478 &GUID_WICPixelFormat32bppRGB, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0};
479
480 static const BYTE bits_32bppPBGRA[] = {
481 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,
482 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,
483 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,
484 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,
485 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,
486 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,
487 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,
488 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};
489 static const struct bitmap_data testdata_32bppPBGRA = {
490 &GUID_WICPixelFormat32bppPBGRA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0};
491 static const struct bitmap_data testdata_32bppPRGBA = {
492 &GUID_WICPixelFormat32bppPRGBA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0};
493
494 /* XP and 2003 use linear color conversion, later versions use sRGB gamma */
495 static const float bits_32bppGrayFloat_xp[] = {
496 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
497 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
498 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
499 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
500 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f,
501 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f,
502 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f,
503 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f};
504 static const struct bitmap_data testdata_32bppGrayFloat_xp = {
505 &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat_xp, 32, 2, 96.0, 96.0};
506
507 static const float bits_32bppGrayFloat[] = {
508 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
509 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
510 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
511 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
512 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f,
513 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f,
514 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f,
515 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f};
516 static const struct bitmap_data testdata_32bppGrayFloat = {
517 &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat, 32, 2, 96.0, 96.0, &testdata_32bppGrayFloat_xp};
518
519 static const BYTE bits_8bppGray_xp[] = {
520 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0,
521 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0,
522 226,105,179,255,226,105,179,255,226,105,179,255,226,105,179,255,
523 226,105,179,255,226,105,179,255,226,105,179,255,226,105,179,255};
524 static const struct bitmap_data testdata_8bppGray_xp = {
525 &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray_xp, 32, 2, 96.0, 96.0};
526
527 static const BYTE bits_8bppGray[] = {
528 76,220,127,0,76,220,127,0,76,220,127,0,76,220,127,0,
529 76,220,127,0,76,220,127,0,76,220,127,0,76,220,127,0,
530 247,145,230,255,247,145,230,255,247,145,230,255,247,145,230,255,
531 247,145,230,255,247,145,230,255,247,145,230,255,247,145,230,255};
532 static const struct bitmap_data testdata_8bppGray = {
533 &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray, 32, 2, 96.0, 96.0, &testdata_8bppGray_xp};
534
535 static const BYTE bits_24bppBGR_gray[] = {
536 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
537 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
538 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
539 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
540 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255,
541 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255,
542 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255,
543 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255};
544 static const struct bitmap_data testdata_24bppBGR_gray = {
545 &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR_gray, 32, 2, 96.0, 96.0};
546
547 static void test_conversion(const struct bitmap_data *src, const struct bitmap_data *dst, const char *name, BOOL todo)
548 {
549 BitmapTestSrc *src_obj;
550 IWICBitmapSource *dst_bitmap;
551 HRESULT hr;
552
553 CreateTestBitmap(src, &src_obj);
554
555 hr = WICConvertBitmapSource(dst->format, &src_obj->IWICBitmapSource_iface, &dst_bitmap);
556 todo_wine_if (todo)
557 ok(hr == S_OK ||
558 broken(hr == E_INVALIDARG || hr == WINCODEC_ERR_COMPONENTNOTFOUND) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr);
559
560 if (hr == S_OK)
561 {
562 compare_bitmap_data(src, dst, dst_bitmap, name);
563
564 IWICBitmapSource_Release(dst_bitmap);
565 }
566
567 DeleteTestBitmap(src_obj);
568 }
569
570 static void test_invalid_conversion(void)
571 {
572 BitmapTestSrc *src_obj;
573 IWICBitmapSource *dst_bitmap;
574 HRESULT hr;
575
576 CreateTestBitmap(&testdata_32bppBGRA, &src_obj);
577
578 /* convert to a non-pixel-format GUID */
579 hr = WICConvertBitmapSource(&GUID_VendorMicrosoft, &src_obj->IWICBitmapSource_iface, &dst_bitmap);
580 ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "WICConvertBitmapSource returned %x\n", hr);
581
582 DeleteTestBitmap(src_obj);
583 }
584
585 static void test_default_converter(void)
586 {
587 BitmapTestSrc *src_obj;
588 IWICFormatConverter *converter;
589 BOOL can_convert = TRUE;
590 HRESULT hr;
591
592 CreateTestBitmap(&testdata_32bppBGRA, &src_obj);
593
594 hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER,
595 &IID_IWICFormatConverter, (void**)&converter);
596 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
597 if (SUCCEEDED(hr))
598 {
599 hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA,
600 &GUID_WICPixelFormat32bppBGR, &can_convert);
601 ok(SUCCEEDED(hr), "CanConvert returned %x\n", hr);
602 ok(can_convert, "expected TRUE, got %i\n", can_convert);
603
604 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
605 &GUID_WICPixelFormat32bppBGR, WICBitmapDitherTypeNone, NULL, 0.0,
606 WICBitmapPaletteTypeCustom);
607 ok(SUCCEEDED(hr), "Initialize returned %x\n", hr);
608
609 if (SUCCEEDED(hr))
610 compare_bitmap_data(&testdata_32bppBGRA, &testdata_32bppBGR, (IWICBitmapSource*)converter, "default converter");
611
612 IWICFormatConverter_Release(converter);
613 }
614
615 DeleteTestBitmap(src_obj);
616 }
617
618 typedef struct property_opt_test_data
619 {
620 LPCOLESTR name;
621 VARTYPE var_type;
622 VARTYPE initial_var_type;
623 int i_init_val;
624 float f_init_val;
625 BOOL skippable;
626 } property_opt_test_data;
627
628 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};
629 static const WCHAR wszCompressionQuality[] = {'C','o','m','p','r','e','s','s','i','o','n','Q','u','a','l','i','t','y',0};
630 static const WCHAR wszInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0};
631 static const WCHAR wszFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0};
632 static const WCHAR wszImageQuality[] = {'I','m','a','g','e','Q','u','a','l','i','t','y',0};
633 static const WCHAR wszBitmapTransform[] = {'B','i','t','m','a','p','T','r','a','n','s','f','o','r','m',0};
634 static const WCHAR wszLuminance[] = {'L','u','m','i','n','a','n','c','e',0};
635 static const WCHAR wszChrominance[] = {'C','h','r','o','m','i','n','a','n','c','e',0};
636 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};
637 static const WCHAR wszSuppressApp0[] = {'S','u','p','p','r','e','s','s','A','p','p','0',0};
638 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};
639
640 static const struct property_opt_test_data testdata_tiff_props[] = {
641 { wszTiffCompressionMethod, VT_UI1, VT_UI1, WICTiffCompressionDontCare },
642 { wszCompressionQuality, VT_R4, VT_EMPTY },
643 { NULL }
644 };
645
646 static const struct property_opt_test_data testdata_png_props[] = {
647 { wszInterlaceOption, VT_BOOL, VT_BOOL, 0 },
648 { wszFilterOption, VT_UI1, VT_UI1, WICPngFilterUnspecified, 0.0f, TRUE /* not supported on XP/2k3 */},
649 { NULL }
650 };
651
652 static const struct property_opt_test_data testdata_jpeg_props[] = {
653 { wszImageQuality, VT_R4, VT_EMPTY },
654 { wszBitmapTransform, VT_UI1, VT_UI1, WICBitmapTransformRotate0 },
655 { wszLuminance, VT_I4|VT_ARRAY, VT_EMPTY },
656 { wszChrominance, VT_I4|VT_ARRAY, VT_EMPTY },
657 { wszJpegYCrCbSubsampling, VT_UI1, VT_UI1, WICJpegYCrCbSubsamplingDefault, 0.0f, TRUE }, /* not supported on XP/2k3 */
658 { wszSuppressApp0, VT_BOOL, VT_BOOL, FALSE },
659 { NULL }
660 };
661
662 static const struct property_opt_test_data testdata_bmp_props[] = {
663 { wszEnableV5Header32bppBGRA, VT_BOOL, VT_BOOL, VARIANT_FALSE, 0.0f, TRUE }, /* Supported since Win7 */
664 { NULL }
665 };
666
667 static int find_property_index(const WCHAR* name, PROPBAG2* all_props, int all_prop_cnt)
668 {
669 int i;
670 for (i=0; i < all_prop_cnt; i++)
671 {
672 if (lstrcmpW(name, all_props[i].pstrName) == 0)
673 return i;
674 }
675 return -1;
676 }
677
678 static void test_specific_encoder_properties(IPropertyBag2 *options, const property_opt_test_data* data, PROPBAG2* all_props, int all_prop_cnt)
679 {
680 HRESULT hr;
681 int i = 0;
682 VARIANT pvarValue;
683 HRESULT phrError = S_OK;
684
685 while (data[i].name)
686 {
687 int idx = find_property_index(data[i].name, all_props, all_prop_cnt);
688 PROPBAG2 pb = {0};
689 pb.pstrName = (LPOLESTR)data[i].name;
690
691 hr = IPropertyBag2_Read(options, 1, &pb, NULL, &pvarValue, &phrError);
692
693 if (data[i].skippable && idx == -1)
694 {
695 win_skip("Property %s is not supported on this machine.\n", wine_dbgstr_w(data[i].name));
696 i++;
697 continue;
698 }
699
700 ok(idx >= 0, "Property %s not in output of GetPropertyInfo\n",
701 wine_dbgstr_w(data[i].name));
702 if (idx >= 0)
703 {
704 ok(all_props[idx].vt == data[i].var_type, "Property %s has unexpected vt type, vt=%i\n",
705 wine_dbgstr_w(data[i].name), all_props[idx].vt);
706 ok(all_props[idx].dwType == PROPBAG2_TYPE_DATA, "Property %s has unexpected dw type, vt=%i\n",
707 wine_dbgstr_w(data[i].name), all_props[idx].dwType);
708 ok(all_props[idx].cfType == 0, "Property %s has unexpected cf type, vt=%i\n",
709 wine_dbgstr_w(data[i].name), all_props[idx].cfType);
710 }
711
712 ok(SUCCEEDED(hr), "Reading property %s from bag failed, hr=%x\n",
713 wine_dbgstr_w(data[i].name), hr);
714
715 if (SUCCEEDED(hr))
716 {
717 /* On XP the initial type is always VT_EMPTY */
718 ok(V_VT(&pvarValue) == data[i].initial_var_type || V_VT(&pvarValue) == VT_EMPTY,
719 "Property %s has unexpected initial type, V_VT=%i\n",
720 wine_dbgstr_w(data[i].name), V_VT(&pvarValue));
721
722 if(V_VT(&pvarValue) == data[i].initial_var_type)
723 {
724 switch (data[i].initial_var_type)
725 {
726 case VT_BOOL:
727 case VT_UI1:
728 ok(V_UNION(&pvarValue, bVal) == data[i].i_init_val, "Property %s has an unexpected initial value, pvarValue=%i\n",
729 wine_dbgstr_w(data[i].name), V_UNION(&pvarValue, bVal));
730 break;
731 case VT_R4:
732 ok(V_UNION(&pvarValue, fltVal) == data[i].f_init_val, "Property %s has an unexpected initial value, pvarValue=%f\n",
733 wine_dbgstr_w(data[i].name), V_UNION(&pvarValue, fltVal));
734 break;
735 default:
736 break;
737 }
738 }
739
740 VariantClear(&pvarValue);
741 }
742
743 i++;
744 }
745 }
746
747 static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *options)
748 {
749 HRESULT hr;
750 ULONG cProperties = 0;
751 ULONG cProperties2 = 0;
752 PROPBAG2 all_props[64] = {{0}}; /* Should be enough for every encoder out there */
753 int i;
754
755 /* CountProperties */
756 {
757 hr = IPropertyBag2_CountProperties(options, &cProperties);
758 ok(SUCCEEDED(hr), "Reading property count, hr=%x\n", hr);
759 }
760
761 /* GetPropertyInfo */
762 {
763 hr = IPropertyBag2_GetPropertyInfo(options, cProperties, 1, all_props, &cProperties2);
764 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - iProperty out of bounce handled wrong, hr=%x\n", hr);
765
766 hr = IPropertyBag2_GetPropertyInfo(options, 0, cProperties+1, all_props, &cProperties2);
767 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - cProperty out of bounce handled wrong, hr=%x\n", hr);
768
769 if (cProperties == 0) /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */
770 {
771 cProperties2 = cProperties;
772 hr = S_OK;
773 }
774 else
775 {
776 hr = IPropertyBag2_GetPropertyInfo(options, 0, min(64, cProperties), all_props, &cProperties2);
777 ok(SUCCEEDED(hr), "Reading infos from property bag failed, hr=%x\n", hr);
778 }
779
780 if (FAILED(hr))
781 return;
782
783 ok(cProperties == cProperties2, "Mismatch of property count (IPropertyBag2::CountProperties=%i, IPropertyBag2::GetPropertyInfo=%i)\n",
784 (int)cProperties, (int)cProperties2);
785 }
786
787 if (IsEqualCLSID(clsid_encoder, &CLSID_WICTiffEncoder))
788 test_specific_encoder_properties(options, testdata_tiff_props, all_props, cProperties2);
789 else if (IsEqualCLSID(clsid_encoder, &CLSID_WICPngEncoder))
790 test_specific_encoder_properties(options, testdata_png_props, all_props, cProperties2);
791 else if (IsEqualCLSID(clsid_encoder, &CLSID_WICJpegEncoder))
792 test_specific_encoder_properties(options, testdata_jpeg_props, all_props, cProperties2);
793 else if (IsEqualCLSID(clsid_encoder, &CLSID_WICBmpEncoder))
794 test_specific_encoder_properties(options, testdata_bmp_props, all_props, cProperties2);
795
796 for (i=0; i < cProperties2; i++)
797 {
798 ok(all_props[i].pstrName != NULL, "Unset property name in output of IPropertyBag2::GetPropertyInfo\n");
799 CoTaskMemFree(all_props[i].pstrName);
800 }
801 }
802
803 static void load_stream(IUnknown *reader, IStream *stream)
804 {
805 HRESULT hr;
806 IWICPersistStream *persist;
807 #ifdef WORDS_BIGENDIAN
808 DWORD persist_options = WICPersistOptionBigEndian;
809 #else
810 DWORD persist_options = WICPersistOptionLittleEndian;
811 #endif
812
813 hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist);
814 ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
815
816 hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options);
817 ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr);
818
819 IWICPersistStream_Release(persist);
820 }
821
822 static void check_tiff_format(IStream *stream, const WICPixelFormatGUID *format)
823 {
824 HRESULT hr;
825 IWICMetadataReader *reader;
826 PROPVARIANT id, value;
827 struct
828 {
829 USHORT byte_order;
830 USHORT version;
831 ULONG dir_offset;
832 } tiff;
833 LARGE_INTEGER pos;
834 UINT count, i;
835 int width, height, bps, photo, samples, colormap;
836 struct
837 {
838 int id, *value;
839 } tag[] =
840 {
841 { 0x100, &width }, { 0x101, &height }, { 0x102, &bps },
842 { 0x106, &photo }, { 0x115, &samples }, { 0x140, &colormap }
843 };
844
845 memset(&tiff, 0, sizeof(tiff));
846 hr = IStream_Read(stream, &tiff, sizeof(tiff), NULL);
847 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
848 ok(tiff.byte_order == MAKEWORD('I','I') || tiff.byte_order == MAKEWORD('M','M'),
849 "wrong TIFF byte order mark %02x\n", tiff.byte_order);
850 ok(tiff.version == 42, "wrong TIFF version %u\n", tiff.version);
851
852 pos.QuadPart = tiff.dir_offset;
853 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
854 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
855
856 hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER,
857 &IID_IWICMetadataReader, (void **)&reader);
858 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
859
860 load_stream((IUnknown *)reader, stream);
861
862 hr = IWICMetadataReader_GetCount(reader, &count);
863 ok(hr == S_OK, "GetCount error %#x\n", hr);
864 ok(count != 0, "wrong count %u\n", count);
865
866 for (i = 0; i < sizeof(tag)/sizeof(tag[0]); i++)
867 {
868 PropVariantInit(&id);
869 PropVariantInit(&value);
870
871 id.vt = VT_UI2;
872 U(id).uiVal = tag[i].id;
873 hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value);
874 ok(hr == S_OK || (tag[i].id == 0x140 && hr == WINCODEC_ERR_PROPERTYNOTFOUND),
875 "GetValue(%04x) error %#x\n", tag[i].id, hr);
876 if (hr == S_OK)
877 {
878 ok(value.vt == VT_UI2 || value.vt == VT_UI4 || value.vt == (VT_UI2 | VT_VECTOR), "wrong vt: %d\n", value.vt);
879 tag[i].value[0] = U(value).uiVal;
880 }
881 else
882 tag[i].value[0] = -1;
883 }
884
885 IWICMetadataReader_Release(reader);
886
887 if (IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite))
888 {
889 ok(width == 32, "wrong width %u\n", width);
890 ok(height == 2, "wrong height %u\n", height);
891
892 ok(bps == 1, "wrong bps %d\n", bps);
893 ok(photo == 1, "wrong photometric %d\n", photo);
894 ok(samples == 1, "wrong samples %d\n", samples);
895 ok(colormap == -1, "wrong colormap %d\n", colormap);
896 }
897 else if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed))
898 {
899 ok(width == 32, "wrong width %u\n", width);
900 ok(height == 2, "wrong height %u\n", height);
901
902 ok(bps == 1, "wrong bps %d\n", bps);
903 ok(photo == 3, "wrong photometric %d\n", photo);
904 ok(samples == 1, "wrong samples %d\n", samples);
905 ok(colormap == 6, "wrong colormap %d\n", colormap);
906 }
907 else if (IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed))
908 {
909 ok(width == 32, "wrong width %u\n", width);
910 ok(height == 2, "wrong height %u\n", height);
911
912 ok(bps == 2, "wrong bps %d\n", bps);
913 ok(photo == 3, "wrong photometric %d\n", photo);
914 ok(samples == 1, "wrong samples %d\n", samples);
915 ok(colormap == 12, "wrong colormap %d\n", colormap);
916 }
917 else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed))
918 {
919 ok(width == 32, "wrong width %u\n", width);
920 ok(height == 2, "wrong height %u\n", height);
921
922 ok(bps == 4, "wrong bps %d\n", bps);
923 ok(photo == 3, "wrong photometric %d\n", photo);
924 ok(samples == 1, "wrong samples %d\n", samples);
925 ok(colormap == 48, "wrong colormap %d\n", colormap);
926 }
927 else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
928 {
929 ok(width == 32, "wrong width %u\n", width);
930 ok(height == 2, "wrong height %u\n", height);
931
932 ok(bps == 8, "wrong bps %d\n", bps);
933 ok(photo == 3, "wrong photometric %d\n", photo);
934 ok(samples == 1, "wrong samples %d\n", samples);
935 ok(colormap == 768, "wrong colormap %d\n", colormap);
936 }
937 else if (IsEqualGUID(format, &GUID_WICPixelFormat24bppBGR))
938 {
939 ok(width == 32, "wrong width %u\n", width);
940 ok(height == 2, "wrong height %u\n", height);
941
942 ok(bps == 3, "wrong bps %d\n", bps);
943 ok(photo == 2, "wrong photometric %d\n", photo);
944 ok(samples == 3, "wrong samples %d\n", samples);
945 ok(colormap == -1, "wrong colormap %d\n", colormap);
946 }
947 else
948 ok(0, "unknown TIFF pixel format %s\n", wine_dbgstr_guid(format));
949 }
950
951 static void check_bmp_format(IStream *stream, const WICPixelFormatGUID *format)
952 {
953 HRESULT hr;
954 BITMAPFILEHEADER bfh;
955 BITMAPV5HEADER bih;
956
957 hr = IStream_Read(stream, &bfh, sizeof(bfh), NULL);
958 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
959
960 ok(bfh.bfType == 0x4d42, "wrong BMP signature %02x\n", bfh.bfType);
961 ok(bfh.bfReserved1 == 0, "wrong bfReserved1 %02x\n", bfh.bfReserved1);
962 ok(bfh.bfReserved2 == 0, "wrong bfReserved2 %02x\n", bfh.bfReserved2);
963
964 hr = IStream_Read(stream, &bih, sizeof(bih), NULL);
965 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
966
967 if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed))
968 {
969 ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits);
970
971 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
972 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
973
974 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
975 ok(bih.bV5BitCount == 1, "wrong BitCount %d\n", bih.bV5BitCount);
976 ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
977 ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
978 }
979 else if (IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed))
980 {
981 ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits);
982
983 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
984 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
985
986 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
987 ok(bih.bV5BitCount == 2, "wrong BitCount %d\n", bih.bV5BitCount);
988 ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
989 ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
990 }
991 else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed))
992 {
993 ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits);
994
995 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
996 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
997
998 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
999 ok(bih.bV5BitCount == 4, "wrong BitCount %d\n", bih.bV5BitCount);
1000 ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
1001 ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
1002 }
1003 else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
1004 {
1005 ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits);
1006
1007 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
1008 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
1009
1010 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
1011 ok(bih.bV5BitCount == 8, "wrong BitCount %d\n", bih.bV5BitCount);
1012 ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
1013 ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
1014 }
1015 else if (IsEqualGUID(format, &GUID_WICPixelFormat32bppBGR))
1016 {
1017 ok(bfh.bfOffBits == 0x0036, "wrong bfOffBits %08x\n", bfh.bfOffBits);
1018
1019 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
1020 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
1021
1022 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
1023 ok(bih.bV5BitCount == 32, "wrong BitCount %d\n", bih.bV5BitCount);
1024 ok(bih.bV5ClrUsed == 0, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
1025 ok(bih.bV5ClrImportant == 0, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
1026 }
1027 else
1028 ok(0, "unknown BMP pixel format %s\n", wine_dbgstr_guid(format));
1029 }
1030
1031 static unsigned be_uint(unsigned val)
1032 {
1033 union
1034 {
1035 unsigned val;
1036 char c[4];
1037 } u;
1038
1039 u.val = val;
1040 return (u.c[0] << 24) | (u.c[1] << 16) | (u.c[2] << 8) | u.c[3];
1041 }
1042
1043 static void check_png_format(IStream *stream, const WICPixelFormatGUID *format)
1044 {
1045 static const char png_sig[8] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a};
1046 static const char png_IHDR[8] = {0,0,0,0x0d,'I','H','D','R'};
1047 HRESULT hr;
1048 struct
1049 {
1050 char png_sig[8];
1051 char ihdr_sig[8];
1052 unsigned width, height;
1053 char bit_depth, color_type, compression, filter, interlace;
1054 } png;
1055
1056 memset(&png, 0, sizeof(png));
1057 hr = IStream_Read(stream, &png, sizeof(png), NULL);
1058 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
1059
1060 ok(!memcmp(png.png_sig, png_sig, sizeof(png_sig)), "expected PNG signature\n");
1061 ok(!memcmp(png.ihdr_sig, png_IHDR, sizeof(png_IHDR)), "expected PNG IHDR\n");
1062
1063 if (IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite))
1064 {
1065 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1066 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1067
1068 ok(png.bit_depth == 1, "wrong bit_depth %d\n", png.bit_depth);
1069 ok(png.color_type == 0, "wrong color_type %d\n", png.color_type);
1070 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1071 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1072 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1073 }
1074 else if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed))
1075 {
1076 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1077 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1078
1079 ok(png.bit_depth == 1, "wrong bit_depth %d\n", png.bit_depth);
1080 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1081 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1082 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1083 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1084 }
1085 else if (IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed))
1086 {
1087 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1088 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1089
1090 ok(png.bit_depth == 2, "wrong bit_depth %d\n", png.bit_depth);
1091 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1092 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1093 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1094 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1095 }
1096 else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed))
1097 {
1098 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1099 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1100
1101 ok(png.bit_depth == 4, "wrong bit_depth %d\n", png.bit_depth);
1102 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1103 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1104 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1105 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1106 }
1107 else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
1108 {
1109 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1110 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1111
1112 ok(png.bit_depth == 8, "wrong bit_depth %d\n", png.bit_depth);
1113 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1114 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1115 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1116 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1117 }
1118 else if (IsEqualGUID(format, &GUID_WICPixelFormat24bppBGR))
1119 {
1120 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1121 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1122
1123 ok(png.bit_depth == 8, "wrong bit_depth %d\n", png.bit_depth);
1124 ok(png.color_type == 2, "wrong color_type %d\n", png.color_type);
1125 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1126 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1127 ok(png.interlace == 0 || png.interlace == 1, "wrong interlace %d\n", png.interlace);
1128 }
1129 else
1130 ok(0, "unknown PNG pixel format %s\n", wine_dbgstr_guid(format));
1131 }
1132
1133 static void check_gif_format(IStream *stream, const WICPixelFormatGUID *format)
1134 {
1135 #include "pshpack1.h"
1136 struct logical_screen_descriptor
1137 {
1138 char signature[6];
1139 USHORT width;
1140 USHORT height;
1141 BYTE packed;
1142 /* global_color_table_flag : 1;
1143 * color_resolution : 3;
1144 * sort_flag : 1;
1145 * global_color_table_size : 3;
1146 */
1147 BYTE background_color_index;
1148 BYTE pixel_aspect_ratio;
1149 } lsd;
1150 #include "poppack.h"
1151 UINT color_resolution;
1152 HRESULT hr;
1153
1154 memset(&lsd, 0, sizeof(lsd));
1155 hr = IStream_Read(stream, &lsd, sizeof(lsd), NULL);
1156 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
1157
1158 ok(!memcmp(lsd.signature, "GIF89a", 6), "wrong GIF signature %.6s\n", lsd.signature);
1159
1160 ok(lsd.width == 32, "wrong width %u\n", lsd.width);
1161 ok(lsd.height == 2, "wrong height %u\n", lsd.height);
1162 color_resolution = 1 << (((lsd.packed >> 4) & 0x07) + 1);
1163 ok(color_resolution == 256, "wrong color resolution %u\n", color_resolution);
1164 ok(lsd.pixel_aspect_ratio == 0, "wrong pixel_aspect_ratio %u\n", lsd.pixel_aspect_ratio);
1165 }
1166
1167 static void check_bitmap_format(IStream *stream, const CLSID *encoder, const WICPixelFormatGUID *format)
1168 {
1169 HRESULT hr;
1170 LARGE_INTEGER pos;
1171
1172 pos.QuadPart = 0;
1173 hr = IStream_Seek(stream, pos, SEEK_SET, (ULARGE_INTEGER *)&pos);
1174 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
1175
1176 if (IsEqualGUID(encoder, &CLSID_WICPngEncoder))
1177 check_png_format(stream, format);
1178 else if (IsEqualGUID(encoder, &CLSID_WICBmpEncoder))
1179 check_bmp_format(stream, format);
1180 else if (IsEqualGUID(encoder, &CLSID_WICTiffEncoder))
1181 check_tiff_format(stream, format);
1182 else if (IsEqualGUID(encoder, &CLSID_WICGifEncoder))
1183 check_gif_format(stream, format);
1184 else
1185 ok(0, "unknown encoder %s\n", wine_dbgstr_guid(encoder));
1186
1187 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
1188 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
1189 }
1190
1191 struct setting {
1192 const WCHAR *name;
1193 PROPBAG2_TYPE type;
1194 VARTYPE vt;
1195 void *value;
1196 };
1197
1198 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
1199 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
1200 {
1201 ULONG rc;
1202 IUnknown_AddRef(obj);
1203 rc = IUnknown_Release(obj);
1204 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
1205 }
1206
1207 static void test_set_frame_palette(IWICBitmapFrameEncode *frameencode)
1208 {
1209 IWICComponentFactory *factory;
1210 IWICPalette *palette;
1211 HRESULT hr;
1212
1213 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1214 &IID_IWICComponentFactory, (void **)&factory);
1215 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
1216
1217 hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL);
1218 ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr);
1219
1220 hr = IWICComponentFactory_CreatePalette(factory, &palette);
1221 ok(hr == S_OK, "CreatePalette failed, hr=%x\n", hr);
1222
1223 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1224 todo_wine
1225 ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr=%x\n", hr);
1226
1227 hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedHalftone256, FALSE);
1228 ok(hr == S_OK, "InitializePredefined failed, hr=%x\n", hr);
1229
1230 EXPECT_REF(palette, 1);
1231 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1232 ok(hr == S_OK, "SetPalette failed, hr=%x\n", hr);
1233 EXPECT_REF(palette, 1);
1234
1235 hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL);
1236 ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr);
1237
1238 IWICPalette_Release(palette);
1239 IWICComponentFactory_Release(factory);
1240 }
1241
1242 static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* clsid_encoder,
1243 const struct bitmap_data **dsts, const CLSID *clsid_decoder, WICRect *rc,
1244 const struct setting *settings, const char *name, IWICPalette *palette)
1245 {
1246 HRESULT hr;
1247 IWICBitmapEncoder *encoder;
1248 BitmapTestSrc *src_obj;
1249 HGLOBAL hglobal;
1250 IStream *stream;
1251 IWICBitmapFrameEncode *frameencode;
1252 IPropertyBag2 *options=NULL;
1253 IWICBitmapDecoder *decoder;
1254 IWICBitmapFrameDecode *framedecode;
1255 WICPixelFormatGUID pixelformat;
1256 int i;
1257
1258 hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER,
1259 &IID_IWICBitmapEncoder, (void **)&encoder);
1260 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
1261
1262 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1263 ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
1264
1265 hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache);
1266 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1267
1268 /* Encoder options are optional. */
1269 hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, NULL);
1270 ok(SUCCEEDED(hr), "Failed to create encode frame, hr %#x.\n", hr);
1271
1272 IStream_Release(stream);
1273 IWICBitmapEncoder_Release(encoder);
1274 IWICBitmapFrameEncode_Release(frameencode);
1275
1276 hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER,
1277 &IID_IWICBitmapEncoder, (void**)&encoder);
1278 ok(SUCCEEDED(hr), "CoCreateInstance(%s) failed, hr=%x\n", wine_dbgstr_guid(clsid_encoder), hr);
1279 if (SUCCEEDED(hr))
1280 {
1281 hglobal = GlobalAlloc(GMEM_MOVEABLE, 0);
1282 ok(hglobal != NULL, "GlobalAlloc failed\n");
1283 if (hglobal)
1284 {
1285 hr = CreateStreamOnHGlobal(hglobal, TRUE, &stream);
1286 ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
1287 }
1288
1289 if (hglobal && SUCCEEDED(hr))
1290 {
1291 if (palette)
1292 {
1293 hr = IWICBitmapEncoder_SetPalette(encoder, palette);
1294 ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#x (%s)\n", hr, name);
1295 }
1296
1297 hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache);
1298 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1299
1300 if (palette)
1301 {
1302 hr = IWICBitmapEncoder_SetPalette(encoder, palette);
1303 if (IsEqualGUID(clsid_encoder, &CLSID_WICGifEncoder))
1304 ok(hr == S_OK, "SetPalette failed, hr=%#x\n", hr);
1305 else
1306 ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "wrong error %#x\n", hr);
1307 hr = S_OK;
1308 }
1309
1310 i=0;
1311 while (SUCCEEDED(hr) && srcs[i])
1312 {
1313 CreateTestBitmap(srcs[i], &src_obj);
1314
1315 hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, &options);
1316 ok(SUCCEEDED(hr), "CreateFrame failed, hr=%x\n", hr);
1317 if (SUCCEEDED(hr))
1318 {
1319 ok(options != NULL, "Encoder initialization has not created an property bag\n");
1320 if(options)
1321 test_encoder_properties(clsid_encoder, options);
1322
1323 if (settings)
1324 {
1325 int j;
1326 for (j=0; settings[j].name; j++)
1327 {
1328 PROPBAG2 propbag;
1329 VARIANT var;
1330
1331 memset(&propbag, 0, sizeof(propbag));
1332 memset(&var, 0, sizeof(var));
1333 propbag.pstrName = (LPOLESTR)settings[j].name;
1334 propbag.dwType = settings[j].type;
1335 V_VT(&var) = settings[j].vt;
1336 V_UNKNOWN(&var) = settings[j].value;
1337
1338 hr = IPropertyBag2_Write(options, 1, &propbag, &var);
1339 ok(SUCCEEDED(hr), "Writing property %s failed, hr=%x\n", wine_dbgstr_w(settings[j].name), hr);
1340 }
1341 }
1342
1343 if (palette)
1344 {
1345 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1346 ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#x\n", hr);
1347 }
1348
1349 hr = IWICBitmapFrameEncode_Initialize(frameencode, options);
1350 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1351
1352 memcpy(&pixelformat, srcs[i]->format, sizeof(GUID));
1353 hr = IWICBitmapFrameEncode_SetPixelFormat(frameencode, &pixelformat);
1354 ok(SUCCEEDED(hr), "SetPixelFormat failed, hr=%x\n", hr);
1355 ok(IsEqualGUID(&pixelformat, dsts[i]->format) ||
1356 broken(IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)) ||
1357 broken(IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)),
1358 "SetPixelFormat changed the format to %s (%s)\n", wine_dbgstr_guid(&pixelformat), name);
1359
1360 hr = IWICBitmapFrameEncode_SetSize(frameencode, srcs[i]->width, srcs[i]->height);
1361 ok(SUCCEEDED(hr), "SetSize failed, hr=%x\n", hr);
1362
1363 if (IsEqualGUID(clsid_encoder, &CLSID_WICPngEncoder))
1364 test_set_frame_palette(frameencode);
1365
1366 if (palette)
1367 {
1368 WICColor colors[256];
1369
1370 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1371 ok(SUCCEEDED(hr), "SetPalette failed, hr=%x (%s)\n", hr, name);
1372
1373 /* trash the assigned palette */
1374 memset(colors, 0, sizeof(colors));
1375 hr = IWICPalette_InitializeCustom(palette, colors, 256);
1376 ok(hr == S_OK, "InitializeCustom error %#x\n", hr);
1377 }
1378
1379 hr = IWICBitmapFrameEncode_WriteSource(frameencode, &src_obj->IWICBitmapSource_iface, rc);
1380 if (rc && (rc->Width <= 0 || rc->Height <= 0))
1381 {
1382 /* WriteSource fails but WriteSource_Proxy succeeds. */
1383 ok(hr == E_INVALIDARG, "WriteSource should fail, hr=%x (%s)\n", hr, name);
1384 hr = IWICBitmapFrameEncode_WriteSource_Proxy(frameencode, &src_obj->IWICBitmapSource_iface, rc);
1385 ok(SUCCEEDED(hr), "WriteSource_Proxy failed, %dx%d, hr=%x (%s)\n", rc->Width, rc->Height, hr, name);
1386 }
1387 else
1388 {
1389 if (rc)
1390 ok(SUCCEEDED(hr), "WriteSource(%dx%d) failed, hr=%x (%s)\n", rc->Width, rc->Height, hr, name);
1391 else
1392 ok(hr == S_OK ||
1393 broken(hr == E_INVALIDARG && IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2) /* XP */ ||
1394 broken(hr == E_INVALIDARG && IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2) /* XP */ ||
1395 broken(hr == E_INVALIDARG && IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && IsEqualGUID(srcs[i]->format, &GUID_WICPixelFormatBlackWhite)) /* XP */,
1396 "WriteSource(NULL) failed, hr=%x (%s)\n", hr, name);
1397 }
1398
1399 if (SUCCEEDED(hr))
1400 {
1401 hr = IWICBitmapFrameEncode_Commit(frameencode);
1402 ok(SUCCEEDED(hr), "Commit failed, hr=%x (%s)\n", hr, name);
1403 }
1404
1405 IWICBitmapFrameEncode_Release(frameencode);
1406 IPropertyBag2_Release(options);
1407 }
1408
1409 DeleteTestBitmap(src_obj);
1410
1411 i++;
1412 }
1413
1414 if (clsid_decoder == NULL)
1415 {
1416 IStream_Release(stream);
1417 IWICBitmapEncoder_Release(encoder);
1418 return;
1419 }
1420
1421 if (SUCCEEDED(hr))
1422 {
1423 hr = IWICBitmapEncoder_Commit(encoder);
1424 ok(SUCCEEDED(hr), "Commit failed, hr=%x\n", hr);
1425
1426 if (IsEqualGUID(&pixelformat, dsts[0]->format))
1427 check_bitmap_format(stream, clsid_encoder, dsts[0]->format);
1428 }
1429
1430 if (SUCCEEDED(hr))
1431 {
1432 hr = CoCreateInstance(clsid_decoder, NULL, CLSCTX_INPROC_SERVER,
1433 &IID_IWICBitmapDecoder, (void**)&decoder);
1434 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
1435 }
1436
1437 if (SUCCEEDED(hr))
1438 {
1439 IWICPalette *frame_palette;
1440
1441 hr = IWICImagingFactory_CreatePalette(factory, &frame_palette);
1442 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
1443
1444 hr = IWICBitmapDecoder_CopyPalette(decoder, frame_palette);
1445 if (IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder))
1446 ok(hr == WINCODEC_ERR_WRONGSTATE, "wrong error %#x\n", hr);
1447 else
1448 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr);
1449
1450 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
1451 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1452
1453 hr = IWICBitmapDecoder_CopyPalette(decoder, frame_palette);
1454 if (IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder))
1455 ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING) /* XP */, "CopyPalette failed, hr=%#x\n", hr);
1456 else
1457 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr);
1458
1459 hr = S_OK;
1460 i=0;
1461 while (SUCCEEDED(hr) && dsts[i])
1462 {
1463 hr = IWICBitmapDecoder_GetFrame(decoder, i, &framedecode);
1464 ok(SUCCEEDED(hr), "GetFrame failed, hr=%x (%s)\n", hr, name);
1465
1466 if (SUCCEEDED(hr))
1467 {
1468 hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &pixelformat);
1469 ok(hr == S_OK, "GetPixelFormat) failed, hr=%x (%s)\n", hr, name);
1470 if (IsEqualGUID(&pixelformat, dsts[i]->format))
1471 compare_bitmap_data(srcs[i], dsts[i], (IWICBitmapSource*)framedecode, name);
1472
1473 hr = IWICBitmapFrameDecode_CopyPalette(framedecode, frame_palette);
1474 if (winetest_debug > 1)
1475 trace("%s, bpp %d, %s, hr %#x\n", name, dsts[i]->bpp, wine_dbgstr_guid(dsts[i]->format), hr);
1476 if (dsts[i]->bpp > 8 || IsEqualGUID(dsts[i]->format, &GUID_WICPixelFormatBlackWhite))
1477 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr);
1478 else
1479 {
1480 UINT count, ret;
1481 WICColor colors[256];
1482
1483 ok(hr == S_OK, "CopyPalette error %#x (%s)\n", hr, name);
1484
1485 count = 0;
1486 hr = IWICPalette_GetColorCount(frame_palette, &count);
1487 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1488
1489 memset(colors, 0, sizeof(colors));
1490 ret = 0;
1491 hr = IWICPalette_GetColors(frame_palette, count, colors, &ret);
1492 ok(hr == S_OK, "GetColors error %#x\n", hr);
1493 ok(ret == count, "expected %u, got %u\n", count, ret);
1494 if (IsEqualGUID(clsid_decoder, &CLSID_WICPngDecoder))
1495 {
1496 /* Newer libpng versions don't accept larger palettes than the declared
1497 * bit depth, so we need to generate the palette of the correct length.
1498 */
1499 ok(count == 256 || (dsts[i]->bpp == 1 && count == 2) ||
1500 (dsts[i]->bpp == 2 && count == 4) || (dsts[i]->bpp == 4 && count == 16),
1501 "expected 256, got %u (%s)\n", count, name);
1502
1503 ok(colors[0] == 0x11111111, "got %08x (%s)\n", colors[0], name);
1504 ok(colors[1] == 0x22222222, "got %08x (%s)\n", colors[1], name);
1505 if (count > 2)
1506 {
1507 ok(colors[2] == 0x33333333, "got %08x (%s)\n", colors[2], name);
1508 ok(colors[3] == 0x44444444, "got %08x (%s)\n", colors[3], name);
1509 if (count > 4)
1510 {
1511 ok(colors[4] == 0x55555555, "got %08x (%s)\n", colors[4], name);
1512 ok(colors[5] == 0, "got %08x (%s)\n", colors[5], name);
1513 }
1514 }
1515 }
1516 else if (IsEqualGUID(clsid_decoder, &CLSID_WICBmpDecoder) ||
1517 IsEqualGUID(clsid_decoder, &CLSID_WICTiffDecoder) ||
1518 IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder))
1519 {
1520 if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormatBlackWhite) ||
1521 IsEqualGUID(&pixelformat, &GUID_WICPixelFormat8bppIndexed))
1522 {
1523 ok(count == 256, "expected 256, got %u (%s)\n", count, name);
1524
1525 ok(colors[0] == 0xff111111, "got %08x (%s)\n", colors[0], name);
1526 ok(colors[1] == 0xff222222, "got %08x (%s)\n", colors[1], name);
1527 ok(colors[2] == 0xff333333, "got %08x (%s)\n", colors[2], name);
1528 ok(colors[3] == 0xff444444, "got %08x (%s)\n", colors[3], name);
1529 ok(colors[4] == 0xff555555, "got %08x (%s)\n", colors[4], name);
1530 ok(colors[5] == 0xff000000, "got %08x (%s)\n", colors[5], name);
1531 }
1532 else if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormat2bppIndexed))
1533 {
1534 ok(count == 4, "expected 4, got %u (%s)\n", count, name);
1535
1536 ok(colors[0] == 0xff111111, "got %08x (%s)\n", colors[0], name);
1537 ok(colors[1] == 0xff222222, "got %08x (%s)\n", colors[1], name);
1538 ok(colors[2] == 0xff333333, "got %08x (%s)\n", colors[2], name);
1539 ok(colors[3] == 0xff444444, "got %08x (%s)\n", colors[3], name);
1540 }
1541 else if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed))
1542 {
1543 ok(count == 16, "expected 16, got %u (%s)\n", count, name);
1544
1545 ok(colors[0] == 0xff111111, "got %08x (%s)\n", colors[0], name);
1546 ok(colors[1] == 0xff222222, "got %08x (%s)\n", colors[1], name);
1547 ok(colors[2] == 0xff333333, "got %08x (%s)\n", colors[2], name);
1548 ok(colors[3] == 0xff444444, "got %08x (%s)\n", colors[3], name);
1549 ok(colors[4] == 0xff555555, "got %08x (%s)\n", colors[4], name);
1550 ok(colors[5] == 0xff000000, "got %08x (%s)\n", colors[5], name);
1551 }
1552 else
1553 {
1554 ok(count == 2, "expected 2, got %u (%s)\n", count, name);
1555
1556 ok(colors[0] == 0xff111111, "got %08x (%s)\n", colors[0], name);
1557 ok(colors[1] == 0xff222222, "got %08x (%s)\n", colors[1], name);
1558 }
1559 }
1560 else
1561 {
1562 ok(count == 2, "expected 2, got %u (%s)\n", count, name);
1563
1564 ok(colors[0] == 0xff111111, "got %08x\n", colors[0]);
1565 ok(colors[1] == 0xff222222, "got %08x\n", colors[1]);
1566 }
1567 }
1568
1569 IWICBitmapFrameDecode_Release(framedecode);
1570 }
1571
1572 i++;
1573 }
1574
1575 IWICPalette_Release(frame_palette);
1576 IWICBitmapDecoder_Release(decoder);
1577 }
1578
1579 IStream_Release(stream);
1580 }
1581
1582 IWICBitmapEncoder_Release(encoder);
1583 }
1584 }
1585
1586 static void test_encoder(const struct bitmap_data *src, const CLSID* clsid_encoder,
1587 const struct bitmap_data *dst, const CLSID *clsid_decoder, const char *name)
1588 {
1589 const struct bitmap_data *srcs[2];
1590 const struct bitmap_data *dsts[2];
1591 WICColor colors[256];
1592 IWICPalette *palette;
1593 HRESULT hr;
1594
1595 hr = IWICImagingFactory_CreatePalette(factory, &palette);
1596 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
1597
1598 memset(colors, 0, sizeof(colors));
1599 colors[0] = 0x11111111;
1600 colors[1] = 0x22222222;
1601 colors[2] = 0x33333333;
1602 colors[3] = 0x44444444;
1603 colors[4] = 0x55555555;
1604 /* TIFF decoder fails to decode a 8bpp frame if palette has less than 256 colors */
1605 hr = IWICPalette_InitializeCustom(palette, colors, 256);
1606 ok(hr == S_OK, "InitializeCustom error %#x\n", hr);
1607
1608 srcs[0] = src;
1609 srcs[1] = NULL;
1610 dsts[0] = dst;
1611 dsts[1] = NULL;
1612
1613 test_multi_encoder(srcs, clsid_encoder, dsts, clsid_decoder, NULL, NULL, name, palette);
1614
1615 IWICPalette_Release(palette);
1616 }
1617
1618 static void test_encoder_rects(void)
1619 {
1620 const struct bitmap_data *srcs[2];
1621 const struct bitmap_data *dsts[2];
1622 WICRect rc;
1623
1624 srcs[0] = &testdata_24bppBGR;
1625 srcs[1] = NULL;
1626 dsts[0] = &testdata_24bppBGR;
1627 dsts[1] = NULL;
1628
1629 rc.X = 0;
1630 rc.Y = 0;
1631 rc.Width = 32;
1632 rc.Height = 2;
1633
1634 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects full", NULL);
1635
1636 rc.Width = 0;
1637 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects width=0", NULL);
1638
1639 rc.Width = -1;
1640 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects width=-1", NULL);
1641
1642 rc.Width = 32;
1643 rc.Height = 0;
1644 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects height=0", NULL);
1645
1646 rc.Height = -1;
1647 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects height=-1", NULL);
1648 }
1649
1650 static const struct bitmap_data *multiple_frames[3] = {
1651 &testdata_24bppBGR,
1652 &testdata_24bppBGR,
1653 NULL};
1654
1655 static const struct bitmap_data *single_frame[2] = {
1656 &testdata_24bppBGR,
1657 NULL};
1658
1659 static const struct setting png_interlace_settings[] = {
1660 {wszInterlaceOption, PROPBAG2_TYPE_DATA, VT_BOOL, (void*)VARIANT_TRUE},
1661 {NULL}
1662 };
1663
1664 static void test_converter_8bppIndexed(void)
1665 {
1666 HRESULT hr;
1667 BitmapTestSrc *src_obj;
1668 IWICFormatConverter *converter;
1669 IWICPalette *palette;
1670 UINT count, i;
1671 BYTE buf[32 * 2 * 3]; /* enough to hold 32x2 24bppBGR data */
1672
1673 CreateTestBitmap(&testdata_24bppBGR, &src_obj);
1674
1675 hr = IWICImagingFactory_CreatePalette(factory, &palette);
1676 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
1677 count = 0xdeadbeef;
1678 hr = IWICPalette_GetColorCount(palette, &count);
1679 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1680 ok(count == 0, "expected 0, got %u\n", count);
1681
1682 /* NULL palette + Custom type*/
1683 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1684 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1685 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1686 &GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone,
1687 NULL, 0.0, WICBitmapPaletteTypeCustom);
1688 ok(hr == S_OK, "Initialize error %#x\n", hr);
1689 hr = IWICFormatConverter_CopyPalette(converter, palette);
1690 ok(hr == 0xdeadbeef, "unexpected error %#x\n", hr);
1691 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32 * 3, sizeof(buf), buf);
1692 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1693 IWICFormatConverter_Release(converter);
1694
1695 /* NULL palette + Custom type*/
1696 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1697 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1698 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1699 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1700 NULL, 0.0, WICBitmapPaletteTypeCustom);
1701 ok(hr == E_INVALIDARG, "unexpected error %#x\n", hr);
1702 hr = IWICFormatConverter_CopyPalette(converter, palette);
1703 ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr);
1704 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1705 ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr);
1706 IWICFormatConverter_Release(converter);
1707
1708 /* empty palette + Custom type*/
1709 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1710 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1711 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1712 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1713 palette, 0.0, WICBitmapPaletteTypeCustom);
1714 ok(hr == S_OK, "Initialize error %#x\n", hr);
1715 hr = IWICFormatConverter_CopyPalette(converter, palette);
1716 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1717 count = 0xdeadbeef;
1718 hr = IWICPalette_GetColorCount(palette, &count);
1719 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1720 ok(count == 0, "expected 0, got %u\n", count);
1721 memset(buf, 0xaa, sizeof(buf));
1722 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1723 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1724 count = 0;
1725 for (i = 0; i < 32 * 2; i++)
1726 if (buf[i] != 0) count++;
1727 ok(count == 0, "expected 0\n");
1728 IWICFormatConverter_Release(converter);
1729
1730 /* NULL palette + Predefined type*/
1731 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1732 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1733 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1734 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1735 NULL, 0.0, WICBitmapPaletteTypeFixedGray16);
1736 ok(hr == S_OK, "Initialize error %#x\n", hr);
1737 hr = IWICFormatConverter_CopyPalette(converter, palette);
1738 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1739 count = 0xdeadbeef;
1740 hr = IWICPalette_GetColorCount(palette, &count);
1741 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1742 ok(count == 16, "expected 16, got %u\n", count);
1743 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1744 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1745 count = 0;
1746 for (i = 0; i < 32 * 2; i++)
1747 if (buf[i] != 0) count++;
1748 ok(count != 0, "expected != 0\n");
1749 IWICFormatConverter_Release(converter);
1750
1751 /* not empty palette + Predefined type*/
1752 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1753 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1754 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1755 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1756 palette, 0.0, WICBitmapPaletteTypeFixedHalftone64);
1757 ok(hr == S_OK, "Initialize error %#x\n", hr);
1758 hr = IWICFormatConverter_CopyPalette(converter, palette);
1759 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1760 count = 0xdeadbeef;
1761 hr = IWICPalette_GetColorCount(palette, &count);
1762 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1763 ok(count == 16, "expected 16, got %u\n", count);
1764 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1765 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1766 count = 0;
1767 for (i = 0; i < 32 * 2; i++)
1768 if (buf[i] != 0) count++;
1769 ok(count != 0, "expected != 0\n");
1770 IWICFormatConverter_Release(converter);
1771
1772 /* not empty palette + MedianCut type*/
1773 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1774 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1775 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1776 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1777 palette, 0.0, WICBitmapPaletteTypeMedianCut);
1778 ok(hr == S_OK, "Initialize error %#x\n", hr);
1779 hr = IWICFormatConverter_CopyPalette(converter, palette);
1780 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1781 count = 0xdeadbeef;
1782 hr = IWICPalette_GetColorCount(palette, &count);
1783 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1784 ok(count == 16, "expected 16, got %u\n", count);
1785 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1786 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1787 count = 0;
1788 for (i = 0; i < 32 * 2; i++)
1789 if (buf[i] != 0) count++;
1790 ok(count != 0, "expected != 0\n");
1791 IWICFormatConverter_Release(converter);
1792
1793 /* NULL palette + MedianCut type*/
1794 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1795 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1796 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1797 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1798 NULL, 0.0, WICBitmapPaletteTypeMedianCut);
1799 ok(hr == S_OK || broken(hr == E_INVALIDARG) /* XP */, "Initialize error %#x\n", hr);
1800 if (hr == S_OK)
1801 {
1802 hr = IWICFormatConverter_CopyPalette(converter, palette);
1803 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1804 count = 0xdeadbeef;
1805 hr = IWICPalette_GetColorCount(palette, &count);
1806 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1807 ok(count == 8, "expected 8, got %u\n", count);
1808 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1809 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1810 count = 0;
1811 for (i = 0; i < 32 * 2; i++)
1812 if (buf[i] != 0) count++;
1813 ok(count != 0, "expected != 0\n");
1814 }
1815 IWICFormatConverter_Release(converter);
1816
1817 IWICPalette_Release(palette);
1818 DeleteTestBitmap(src_obj);
1819 }
1820
1821 START_TEST(converter)
1822 {
1823 HRESULT hr;
1824
1825 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1826
1827 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1828 &IID_IWICImagingFactory, (void **)&factory);
1829 ok(hr == S_OK, "failed to create factory: %#x\n", hr);
1830
1831 test_converter_8bppIndexed();
1832
1833 test_conversion(&testdata_24bppRGB, &testdata_1bppIndexed, "24bppRGB -> 1bppIndexed", TRUE);
1834 test_conversion(&testdata_24bppRGB, &testdata_2bppIndexed, "24bppRGB -> 2bppIndexed", TRUE);
1835 test_conversion(&testdata_24bppRGB, &testdata_4bppIndexed, "24bppRGB -> 4bppIndexed", TRUE);
1836 test_conversion(&testdata_24bppRGB, &testdata_8bppIndexed, "24bppRGB -> 8bppIndexed", FALSE);
1837
1838 test_conversion(&testdata_BlackWhite, &testdata_8bppIndexed_BW, "BlackWhite -> 8bppIndexed", TRUE);
1839 test_conversion(&testdata_1bppIndexed, &testdata_8bppIndexed_BW, "1bppIndexed -> 8bppIndexed", TRUE);
1840 test_conversion(&testdata_2bppIndexed, &testdata_8bppIndexed_4colors, "2bppIndexed -> 8bppIndexed", TRUE);
1841 test_conversion(&testdata_4bppIndexed, &testdata_8bppIndexed, "4bppIndexed -> 8bppIndexed", TRUE);
1842
1843 test_conversion(&testdata_32bppBGRA, &testdata_32bppBGR, "BGRA -> BGR", FALSE);
1844 test_conversion(&testdata_32bppBGR, &testdata_32bppBGRA, "BGR -> BGRA", FALSE);
1845 test_conversion(&testdata_32bppBGRA, &testdata_32bppBGRA, "BGRA -> BGRA", FALSE);
1846 test_conversion(&testdata_32bppBGRA80, &testdata_32bppPBGRA, "BGRA -> PBGRA", FALSE);
1847
1848 test_conversion(&testdata_32bppRGBA, &testdata_32bppRGB, "RGBA -> RGB", FALSE);
1849 test_conversion(&testdata_32bppRGB, &testdata_32bppRGBA, "RGB -> RGBA", FALSE);
1850 test_conversion(&testdata_32bppRGBA, &testdata_32bppRGBA, "RGBA -> RGBA", FALSE);
1851 test_conversion(&testdata_32bppRGBA80, &testdata_32bppPRGBA, "RGBA -> PRGBA", FALSE);
1852
1853 test_conversion(&testdata_24bppBGR, &testdata_24bppBGR, "24bppBGR -> 24bppBGR", FALSE);
1854 test_conversion(&testdata_24bppBGR, &testdata_24bppRGB, "24bppBGR -> 24bppRGB", FALSE);
1855
1856 test_conversion(&testdata_24bppRGB, &testdata_24bppRGB, "24bppRGB -> 24bppRGB", FALSE);
1857 test_conversion(&testdata_24bppRGB, &testdata_24bppBGR, "24bppRGB -> 24bppBGR", FALSE);
1858
1859 test_conversion(&testdata_32bppBGR, &testdata_24bppRGB, "32bppBGR -> 24bppRGB", FALSE);
1860 test_conversion(&testdata_24bppRGB, &testdata_32bppBGR, "24bppRGB -> 32bppBGR", FALSE);
1861 test_conversion(&testdata_32bppBGRA, &testdata_24bppRGB, "32bppBGRA -> 24bppRGB", FALSE);
1862
1863 test_conversion(&testdata_24bppRGB, &testdata_32bppGrayFloat, "24bppRGB -> 32bppGrayFloat", FALSE);
1864 test_conversion(&testdata_32bppBGR, &testdata_32bppGrayFloat, "32bppBGR -> 32bppGrayFloat", FALSE);
1865
1866 test_conversion(&testdata_24bppBGR, &testdata_8bppGray, "24bppBGR -> 8bppGray", FALSE);
1867 test_conversion(&testdata_32bppBGR, &testdata_8bppGray, "32bppBGR -> 8bppGray", FALSE);
1868 test_conversion(&testdata_32bppGrayFloat, &testdata_24bppBGR_gray, "32bppGrayFloat -> 24bppBGR gray", FALSE);
1869 test_conversion(&testdata_32bppGrayFloat, &testdata_8bppGray, "32bppGrayFloat -> 8bppGray", FALSE);
1870
1871 test_invalid_conversion();
1872 test_default_converter();
1873
1874 test_encoder(&testdata_8bppIndexed, &CLSID_WICGifEncoder,
1875 &testdata_8bppIndexed, &CLSID_WICGifDecoder, "GIF encoder 8bppIndexed");
1876
1877 test_encoder(&testdata_BlackWhite, &CLSID_WICPngEncoder,
1878 &testdata_BlackWhite, &CLSID_WICPngDecoder, "PNG encoder BlackWhite");
1879 test_encoder(&testdata_1bppIndexed, &CLSID_WICPngEncoder,
1880 &testdata_1bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 1bppIndexed");
1881 test_encoder(&testdata_2bppIndexed, &CLSID_WICPngEncoder,
1882 &testdata_2bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 2bppIndexed");
1883 test_encoder(&testdata_4bppIndexed, &CLSID_WICPngEncoder,
1884 &testdata_4bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 4bppIndexed");
1885 test_encoder(&testdata_8bppIndexed, &CLSID_WICPngEncoder,
1886 &testdata_8bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 8bppIndexed");
1887 test_encoder(&testdata_24bppBGR, &CLSID_WICPngEncoder,
1888 &testdata_24bppBGR, &CLSID_WICPngDecoder, "PNG encoder 24bppBGR");
1889 if (!strcmp(winetest_platform, "windows")) /* FIXME: enable once implemented in Wine */
1890 {
1891 test_encoder(&testdata_32bppBGR, &CLSID_WICPngEncoder,
1892 &testdata_24bppBGR, &CLSID_WICPngDecoder, "PNG encoder 32bppBGR");
1893 }
1894
1895 test_encoder(&testdata_BlackWhite, &CLSID_WICBmpEncoder,
1896 &testdata_1bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder BlackWhite");
1897 test_encoder(&testdata_1bppIndexed, &CLSID_WICBmpEncoder,
1898 &testdata_1bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 1bppIndexed");
1899 test_encoder(&testdata_2bppIndexed, &CLSID_WICBmpEncoder,
1900 &testdata_2bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 2bppIndexed");
1901 test_encoder(&testdata_4bppIndexed, &CLSID_WICBmpEncoder,
1902 &testdata_4bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 4bppIndexed");
1903 test_encoder(&testdata_8bppIndexed, &CLSID_WICBmpEncoder,
1904 &testdata_8bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 8bppIndexed");
1905 test_encoder(&testdata_32bppBGR, &CLSID_WICBmpEncoder,
1906 &testdata_32bppBGR, &CLSID_WICBmpDecoder, "BMP encoder 32bppBGR");
1907
1908 test_encoder(&testdata_BlackWhite, &CLSID_WICTiffEncoder,
1909 &testdata_BlackWhite, &CLSID_WICTiffDecoder, "TIFF encoder BlackWhite");
1910 test_encoder(&testdata_1bppIndexed, &CLSID_WICTiffEncoder,
1911 &testdata_1bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 1bppIndexed");
1912 test_encoder(&testdata_2bppIndexed, &CLSID_WICTiffEncoder,
1913 &testdata_2bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 2bppIndexed");
1914 test_encoder(&testdata_4bppIndexed, &CLSID_WICTiffEncoder,
1915 &testdata_4bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 4bppIndexed");
1916 test_encoder(&testdata_8bppIndexed, &CLSID_WICTiffEncoder,
1917 &testdata_8bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 8bppIndexed");
1918 test_encoder(&testdata_24bppBGR, &CLSID_WICTiffEncoder,
1919 &testdata_24bppBGR, &CLSID_WICTiffDecoder, "TIFF encoder 24bppBGR");
1920
1921 test_encoder(&testdata_24bppBGR, &CLSID_WICJpegEncoder,
1922 &testdata_24bppBGR, NULL, "JPEG encoder 24bppBGR");
1923
1924 test_multi_encoder(multiple_frames, &CLSID_WICTiffEncoder,
1925 multiple_frames, &CLSID_WICTiffDecoder, NULL, NULL, "TIFF encoder multi-frame", NULL);
1926
1927 test_encoder_rects();
1928
1929 test_multi_encoder(single_frame, &CLSID_WICPngEncoder,
1930 single_frame, &CLSID_WICPngDecoder, NULL, png_interlace_settings, "PNG encoder interlaced", NULL);
1931
1932 IWICImagingFactory_Release(factory);
1933
1934 CoUninitialize();
1935 }