[WINDOWSCODECS_WINETEST] Sync with Wine Staging 4.18. CORE-16441
[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 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};
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,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};
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 static const BYTE bits_64bppRGBA[] = {
495 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,
496 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,
497 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,
498 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,
499 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,
500 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,
501 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,
502 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255};
503 static const struct bitmap_data testdata_64bppRGBA = {
504 &GUID_WICPixelFormat64bppRGBA, 64, bits_64bppRGBA, 32, 2, 96.0, 96.0};
505
506 /* XP and 2003 use linear color conversion, later versions use sRGB gamma */
507 static const float bits_32bppGrayFloat_xp[] = {
508 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
509 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
510 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
511 0.114000f,0.587000f,0.299000f,0.000000f,0.114000f,0.587000f,0.299000f,0.000000f,
512 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f,
513 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f,
514 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f,
515 0.886000f,0.413000f,0.701000f,1.000000f,0.886000f,0.413000f,0.701000f,1.000000f};
516 static const struct bitmap_data testdata_32bppGrayFloat_xp = {
517 &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat_xp, 32, 2, 96.0, 96.0};
518
519 static const float bits_32bppGrayFloat[] = {
520 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
521 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
522 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
523 0.072200f,0.715200f,0.212600f,0.000000f,0.072200f,0.715200f,0.212600f,0.000000f,
524 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f,
525 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f,
526 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f,
527 0.927800f,0.284800f,0.787400f,1.000000f,0.927800f,0.284800f,0.787400f,1.000000f};
528 static const struct bitmap_data testdata_32bppGrayFloat = {
529 &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat, 32, 2, 96.0, 96.0, &testdata_32bppGrayFloat_xp};
530
531 static const BYTE bits_8bppGray_xp[] = {
532 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0,
533 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0,
534 226,105,179,255,226,105,179,255,226,105,179,255,226,105,179,255,
535 226,105,179,255,226,105,179,255,226,105,179,255,226,105,179,255};
536 static const struct bitmap_data testdata_8bppGray_xp = {
537 &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray_xp, 32, 2, 96.0, 96.0};
538
539 static const BYTE bits_8bppGray[] = {
540 76,220,127,0,76,220,127,0,76,220,127,0,76,220,127,0,
541 76,220,127,0,76,220,127,0,76,220,127,0,76,220,127,0,
542 247,145,230,255,247,145,230,255,247,145,230,255,247,145,230,255,
543 247,145,230,255,247,145,230,255,247,145,230,255,247,145,230,255};
544 static const struct bitmap_data testdata_8bppGray = {
545 &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray, 32, 2, 96.0, 96.0, &testdata_8bppGray_xp};
546
547 static const BYTE bits_24bppBGR_gray[] = {
548 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
549 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
550 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
551 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0,
552 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255,
553 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255,
554 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255,
555 247,247,247, 145,145,145, 230,230,230, 255,255,255, 247,247,247, 145,145,145, 230,230,230, 255,255,255};
556 static const struct bitmap_data testdata_24bppBGR_gray = {
557 &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR_gray, 32, 2, 96.0, 96.0};
558
559 static void test_conversion(const struct bitmap_data *src, const struct bitmap_data *dst, const char *name, BOOL todo)
560 {
561 BitmapTestSrc *src_obj;
562 IWICBitmapSource *dst_bitmap;
563 HRESULT hr;
564
565 CreateTestBitmap(src, &src_obj);
566
567 hr = WICConvertBitmapSource(dst->format, &src_obj->IWICBitmapSource_iface, &dst_bitmap);
568 todo_wine_if (todo)
569 ok(hr == S_OK ||
570 broken(hr == E_INVALIDARG || hr == WINCODEC_ERR_COMPONENTNOTFOUND) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr);
571
572 if (hr == S_OK)
573 {
574 compare_bitmap_data(src, dst, dst_bitmap, name);
575
576 IWICBitmapSource_Release(dst_bitmap);
577 }
578
579 DeleteTestBitmap(src_obj);
580 }
581
582 static void test_invalid_conversion(void)
583 {
584 BitmapTestSrc *src_obj;
585 IWICBitmapSource *dst_bitmap;
586 HRESULT hr;
587
588 CreateTestBitmap(&testdata_32bppBGRA, &src_obj);
589
590 /* convert to a non-pixel-format GUID */
591 hr = WICConvertBitmapSource(&GUID_VendorMicrosoft, &src_obj->IWICBitmapSource_iface, &dst_bitmap);
592 ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "WICConvertBitmapSource returned %x\n", hr);
593
594 DeleteTestBitmap(src_obj);
595 }
596
597 static void test_default_converter(void)
598 {
599 BitmapTestSrc *src_obj;
600 IWICFormatConverter *converter;
601 BOOL can_convert = TRUE;
602 HRESULT hr;
603
604 CreateTestBitmap(&testdata_32bppBGRA, &src_obj);
605
606 hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER,
607 &IID_IWICFormatConverter, (void**)&converter);
608 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
609 if (SUCCEEDED(hr))
610 {
611 hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA,
612 &GUID_WICPixelFormat32bppBGR, &can_convert);
613 ok(SUCCEEDED(hr), "CanConvert returned %x\n", hr);
614 ok(can_convert, "expected TRUE, got %i\n", can_convert);
615
616 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
617 &GUID_WICPixelFormat32bppBGR, WICBitmapDitherTypeNone, NULL, 0.0,
618 WICBitmapPaletteTypeCustom);
619 ok(SUCCEEDED(hr), "Initialize returned %x\n", hr);
620
621 if (SUCCEEDED(hr))
622 compare_bitmap_data(&testdata_32bppBGRA, &testdata_32bppBGR, (IWICBitmapSource*)converter, "default converter");
623
624 IWICFormatConverter_Release(converter);
625 }
626
627 DeleteTestBitmap(src_obj);
628 }
629
630 typedef struct property_opt_test_data
631 {
632 LPCOLESTR name;
633 VARTYPE var_type;
634 VARTYPE initial_var_type;
635 int i_init_val;
636 float f_init_val;
637 BOOL skippable;
638 } property_opt_test_data;
639
640 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};
641 static const WCHAR wszCompressionQuality[] = {'C','o','m','p','r','e','s','s','i','o','n','Q','u','a','l','i','t','y',0};
642 static const WCHAR wszInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0};
643 static const WCHAR wszFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0};
644 static const WCHAR wszImageQuality[] = {'I','m','a','g','e','Q','u','a','l','i','t','y',0};
645 static const WCHAR wszBitmapTransform[] = {'B','i','t','m','a','p','T','r','a','n','s','f','o','r','m',0};
646 static const WCHAR wszLuminance[] = {'L','u','m','i','n','a','n','c','e',0};
647 static const WCHAR wszChrominance[] = {'C','h','r','o','m','i','n','a','n','c','e',0};
648 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};
649 static const WCHAR wszSuppressApp0[] = {'S','u','p','p','r','e','s','s','A','p','p','0',0};
650 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};
651
652 static const struct property_opt_test_data testdata_tiff_props[] = {
653 { wszTiffCompressionMethod, VT_UI1, VT_UI1, WICTiffCompressionDontCare },
654 { wszCompressionQuality, VT_R4, VT_EMPTY },
655 { NULL }
656 };
657
658 static const struct property_opt_test_data testdata_png_props[] = {
659 { wszInterlaceOption, VT_BOOL, VT_BOOL, 0 },
660 { wszFilterOption, VT_UI1, VT_UI1, WICPngFilterUnspecified, 0.0f, TRUE /* not supported on XP/2k3 */},
661 { NULL }
662 };
663
664 static const struct property_opt_test_data testdata_jpeg_props[] = {
665 { wszImageQuality, VT_R4, VT_EMPTY },
666 { wszBitmapTransform, VT_UI1, VT_UI1, WICBitmapTransformRotate0 },
667 { wszLuminance, VT_I4|VT_ARRAY, VT_EMPTY },
668 { wszChrominance, VT_I4|VT_ARRAY, VT_EMPTY },
669 { wszJpegYCrCbSubsampling, VT_UI1, VT_UI1, WICJpegYCrCbSubsamplingDefault, 0.0f, TRUE }, /* not supported on XP/2k3 */
670 { wszSuppressApp0, VT_BOOL, VT_BOOL, FALSE },
671 { NULL }
672 };
673
674 static const struct property_opt_test_data testdata_bmp_props[] = {
675 { wszEnableV5Header32bppBGRA, VT_BOOL, VT_BOOL, VARIANT_FALSE, 0.0f, TRUE }, /* Supported since Win7 */
676 { NULL }
677 };
678
679 static int find_property_index(const WCHAR* name, PROPBAG2* all_props, int all_prop_cnt)
680 {
681 int i;
682 for (i=0; i < all_prop_cnt; i++)
683 {
684 if (lstrcmpW(name, all_props[i].pstrName) == 0)
685 return i;
686 }
687 return -1;
688 }
689
690 static void test_specific_encoder_properties(IPropertyBag2 *options, const property_opt_test_data* data, PROPBAG2* all_props, int all_prop_cnt)
691 {
692 HRESULT hr;
693 int i = 0;
694 VARIANT pvarValue;
695 HRESULT phrError = S_OK;
696
697 while (data[i].name)
698 {
699 int idx = find_property_index(data[i].name, all_props, all_prop_cnt);
700 PROPBAG2 pb = {0};
701 pb.pstrName = (LPOLESTR)data[i].name;
702
703 hr = IPropertyBag2_Read(options, 1, &pb, NULL, &pvarValue, &phrError);
704
705 if (data[i].skippable && idx == -1)
706 {
707 win_skip("Property %s is not supported on this machine.\n", wine_dbgstr_w(data[i].name));
708 i++;
709 continue;
710 }
711
712 ok(idx >= 0, "Property %s not in output of GetPropertyInfo\n",
713 wine_dbgstr_w(data[i].name));
714 if (idx >= 0)
715 {
716 ok(all_props[idx].vt == data[i].var_type, "Property %s has unexpected vt type, vt=%i\n",
717 wine_dbgstr_w(data[i].name), all_props[idx].vt);
718 ok(all_props[idx].dwType == PROPBAG2_TYPE_DATA, "Property %s has unexpected dw type, vt=%i\n",
719 wine_dbgstr_w(data[i].name), all_props[idx].dwType);
720 ok(all_props[idx].cfType == 0, "Property %s has unexpected cf type, vt=%i\n",
721 wine_dbgstr_w(data[i].name), all_props[idx].cfType);
722 }
723
724 ok(SUCCEEDED(hr), "Reading property %s from bag failed, hr=%x\n",
725 wine_dbgstr_w(data[i].name), hr);
726
727 if (SUCCEEDED(hr))
728 {
729 /* On XP the initial type is always VT_EMPTY */
730 ok(V_VT(&pvarValue) == data[i].initial_var_type || V_VT(&pvarValue) == VT_EMPTY,
731 "Property %s has unexpected initial type, V_VT=%i\n",
732 wine_dbgstr_w(data[i].name), V_VT(&pvarValue));
733
734 if(V_VT(&pvarValue) == data[i].initial_var_type)
735 {
736 switch (data[i].initial_var_type)
737 {
738 case VT_BOOL:
739 case VT_UI1:
740 ok(V_UNION(&pvarValue, bVal) == data[i].i_init_val, "Property %s has an unexpected initial value, pvarValue=%i\n",
741 wine_dbgstr_w(data[i].name), V_UNION(&pvarValue, bVal));
742 break;
743 case VT_R4:
744 ok(V_UNION(&pvarValue, fltVal) == data[i].f_init_val, "Property %s has an unexpected initial value, pvarValue=%f\n",
745 wine_dbgstr_w(data[i].name), V_UNION(&pvarValue, fltVal));
746 break;
747 default:
748 break;
749 }
750 }
751
752 VariantClear(&pvarValue);
753 }
754
755 i++;
756 }
757 }
758
759 static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *options)
760 {
761 HRESULT hr;
762 ULONG cProperties = 0;
763 ULONG cProperties2 = 0;
764 PROPBAG2 all_props[64] = {{0}}; /* Should be enough for every encoder out there */
765 int i;
766
767 /* CountProperties */
768 {
769 hr = IPropertyBag2_CountProperties(options, &cProperties);
770 ok(SUCCEEDED(hr), "Reading property count, hr=%x\n", hr);
771 }
772
773 /* GetPropertyInfo */
774 {
775 hr = IPropertyBag2_GetPropertyInfo(options, cProperties, 1, all_props, &cProperties2);
776 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - iProperty out of bounce handled wrong, hr=%x\n", hr);
777
778 hr = IPropertyBag2_GetPropertyInfo(options, 0, cProperties+1, all_props, &cProperties2);
779 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - cProperty out of bounce handled wrong, hr=%x\n", hr);
780
781 if (cProperties == 0) /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */
782 {
783 cProperties2 = cProperties;
784 hr = S_OK;
785 }
786 else
787 {
788 hr = IPropertyBag2_GetPropertyInfo(options, 0, min(64, cProperties), all_props, &cProperties2);
789 ok(SUCCEEDED(hr), "Reading infos from property bag failed, hr=%x\n", hr);
790 }
791
792 if (FAILED(hr))
793 return;
794
795 ok(cProperties == cProperties2, "Mismatch of property count (IPropertyBag2::CountProperties=%i, IPropertyBag2::GetPropertyInfo=%i)\n",
796 (int)cProperties, (int)cProperties2);
797 }
798
799 if (IsEqualCLSID(clsid_encoder, &CLSID_WICTiffEncoder))
800 test_specific_encoder_properties(options, testdata_tiff_props, all_props, cProperties2);
801 else if (IsEqualCLSID(clsid_encoder, &CLSID_WICPngEncoder))
802 test_specific_encoder_properties(options, testdata_png_props, all_props, cProperties2);
803 else if (IsEqualCLSID(clsid_encoder, &CLSID_WICJpegEncoder))
804 test_specific_encoder_properties(options, testdata_jpeg_props, all_props, cProperties2);
805 else if (IsEqualCLSID(clsid_encoder, &CLSID_WICBmpEncoder))
806 test_specific_encoder_properties(options, testdata_bmp_props, all_props, cProperties2);
807
808 for (i=0; i < cProperties2; i++)
809 {
810 ok(all_props[i].pstrName != NULL, "Unset property name in output of IPropertyBag2::GetPropertyInfo\n");
811 CoTaskMemFree(all_props[i].pstrName);
812 }
813 }
814
815 static void load_stream(IUnknown *reader, IStream *stream)
816 {
817 HRESULT hr;
818 IWICPersistStream *persist;
819 #ifdef WORDS_BIGENDIAN
820 DWORD persist_options = WICPersistOptionBigEndian;
821 #else
822 DWORD persist_options = WICPersistOptionLittleEndian;
823 #endif
824
825 hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist);
826 ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
827
828 hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options);
829 ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr);
830
831 IWICPersistStream_Release(persist);
832 }
833
834 static void check_tiff_format(IStream *stream, const WICPixelFormatGUID *format)
835 {
836 HRESULT hr;
837 IWICMetadataReader *reader;
838 PROPVARIANT id, value;
839 struct
840 {
841 USHORT byte_order;
842 USHORT version;
843 ULONG dir_offset;
844 } tiff;
845 LARGE_INTEGER pos;
846 UINT count, i;
847 int width, height, bps, photo, samples, colormap;
848 struct
849 {
850 int id, *value;
851 } tag[] =
852 {
853 { 0x100, &width }, { 0x101, &height }, { 0x102, &bps },
854 { 0x106, &photo }, { 0x115, &samples }, { 0x140, &colormap }
855 };
856
857 memset(&tiff, 0, sizeof(tiff));
858 hr = IStream_Read(stream, &tiff, sizeof(tiff), NULL);
859 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
860 ok(tiff.byte_order == MAKEWORD('I','I') || tiff.byte_order == MAKEWORD('M','M'),
861 "wrong TIFF byte order mark %02x\n", tiff.byte_order);
862 ok(tiff.version == 42, "wrong TIFF version %u\n", tiff.version);
863
864 pos.QuadPart = tiff.dir_offset;
865 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
866 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
867
868 hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER,
869 &IID_IWICMetadataReader, (void **)&reader);
870 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
871
872 load_stream((IUnknown *)reader, stream);
873
874 hr = IWICMetadataReader_GetCount(reader, &count);
875 ok(hr == S_OK, "GetCount error %#x\n", hr);
876 ok(count != 0, "wrong count %u\n", count);
877
878 for (i = 0; i < ARRAY_SIZE(tag); i++)
879 {
880 PropVariantInit(&id);
881 PropVariantInit(&value);
882
883 id.vt = VT_UI2;
884 U(id).uiVal = tag[i].id;
885 hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value);
886 ok(hr == S_OK || (tag[i].id == 0x140 && hr == WINCODEC_ERR_PROPERTYNOTFOUND),
887 "GetValue(%04x) error %#x\n", tag[i].id, hr);
888 if (hr == S_OK)
889 {
890 ok(value.vt == VT_UI2 || value.vt == VT_UI4 || value.vt == (VT_UI2 | VT_VECTOR), "wrong vt: %d\n", value.vt);
891 tag[i].value[0] = U(value).uiVal;
892 }
893 else
894 tag[i].value[0] = -1;
895
896 PropVariantClear(&value);
897 }
898
899 IWICMetadataReader_Release(reader);
900
901 if (IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite))
902 {
903 ok(width == 32, "wrong width %u\n", width);
904 ok(height == 2, "wrong height %u\n", height);
905
906 ok(bps == 1, "wrong bps %d\n", bps);
907 ok(photo == 1, "wrong photometric %d\n", photo);
908 ok(samples == 1, "wrong samples %d\n", samples);
909 ok(colormap == -1, "wrong colormap %d\n", colormap);
910 }
911 else if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed))
912 {
913 ok(width == 32, "wrong width %u\n", width);
914 ok(height == 2, "wrong height %u\n", height);
915
916 ok(bps == 1, "wrong bps %d\n", bps);
917 ok(photo == 3, "wrong photometric %d\n", photo);
918 ok(samples == 1, "wrong samples %d\n", samples);
919 ok(colormap == 6, "wrong colormap %d\n", colormap);
920 }
921 else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed))
922 {
923 ok(width == 32, "wrong width %u\n", width);
924 ok(height == 2, "wrong height %u\n", height);
925
926 ok(bps == 4, "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 == 48, "wrong colormap %d\n", colormap);
930 }
931 else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
932 {
933 ok(width == 32, "wrong width %u\n", width);
934 ok(height == 2, "wrong height %u\n", height);
935
936 ok(bps == 8, "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 == 768, "wrong colormap %d\n", colormap);
940 }
941 else if (IsEqualGUID(format, &GUID_WICPixelFormat24bppBGR))
942 {
943 ok(width == 32, "wrong width %u\n", width);
944 ok(height == 2, "wrong height %u\n", height);
945
946 ok(bps == 3, "wrong bps %d\n", bps);
947 ok(photo == 2, "wrong photometric %d\n", photo);
948 ok(samples == 3, "wrong samples %d\n", samples);
949 ok(colormap == -1, "wrong colormap %d\n", colormap);
950 }
951 else
952 ok(0, "unknown TIFF pixel format %s\n", wine_dbgstr_guid(format));
953 }
954
955 static void check_bmp_format(IStream *stream, const WICPixelFormatGUID *format)
956 {
957 HRESULT hr;
958 BITMAPFILEHEADER bfh;
959 BITMAPV5HEADER bih;
960
961 hr = IStream_Read(stream, &bfh, sizeof(bfh), NULL);
962 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
963
964 ok(bfh.bfType == 0x4d42, "wrong BMP signature %02x\n", bfh.bfType);
965 ok(bfh.bfReserved1 == 0, "wrong bfReserved1 %02x\n", bfh.bfReserved1);
966 ok(bfh.bfReserved2 == 0, "wrong bfReserved2 %02x\n", bfh.bfReserved2);
967
968 hr = IStream_Read(stream, &bih, sizeof(bih), NULL);
969 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
970
971 if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed))
972 {
973 ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits);
974
975 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
976 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
977
978 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
979 ok(bih.bV5BitCount == 1, "wrong BitCount %d\n", bih.bV5BitCount);
980 ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
981 ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
982 }
983 else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed))
984 {
985 ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits);
986
987 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
988 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
989
990 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
991 ok(bih.bV5BitCount == 4, "wrong BitCount %d\n", bih.bV5BitCount);
992 ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
993 ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
994 }
995 else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
996 {
997 ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits);
998
999 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
1000 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
1001
1002 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
1003 ok(bih.bV5BitCount == 8, "wrong BitCount %d\n", bih.bV5BitCount);
1004 ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
1005 ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
1006 }
1007 else if (IsEqualGUID(format, &GUID_WICPixelFormat32bppBGR))
1008 {
1009 ok(bfh.bfOffBits == 0x0036, "wrong bfOffBits %08x\n", bfh.bfOffBits);
1010
1011 ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width);
1012 ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height);
1013
1014 ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes);
1015 ok(bih.bV5BitCount == 32, "wrong BitCount %d\n", bih.bV5BitCount);
1016 ok(bih.bV5ClrUsed == 0, "wrong ClrUsed %d\n", bih.bV5ClrUsed);
1017 ok(bih.bV5ClrImportant == 0, "wrong ClrImportant %d\n", bih.bV5ClrImportant);
1018 }
1019 else
1020 ok(0, "unknown BMP pixel format %s\n", wine_dbgstr_guid(format));
1021 }
1022
1023 static unsigned be_uint(unsigned val)
1024 {
1025 union
1026 {
1027 unsigned val;
1028 char c[4];
1029 } u;
1030
1031 u.val = val;
1032 return (u.c[0] << 24) | (u.c[1] << 16) | (u.c[2] << 8) | u.c[3];
1033 }
1034
1035 static void check_png_format(IStream *stream, const WICPixelFormatGUID *format)
1036 {
1037 static const char png_sig[8] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a};
1038 static const char png_IHDR[8] = {0,0,0,0x0d,'I','H','D','R'};
1039 HRESULT hr;
1040 struct
1041 {
1042 char png_sig[8];
1043 char ihdr_sig[8];
1044 unsigned width, height;
1045 char bit_depth, color_type, compression, filter, interlace;
1046 } png;
1047
1048 memset(&png, 0, sizeof(png));
1049 hr = IStream_Read(stream, &png, sizeof(png), NULL);
1050 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
1051
1052 ok(!memcmp(png.png_sig, png_sig, sizeof(png_sig)), "expected PNG signature\n");
1053 ok(!memcmp(png.ihdr_sig, png_IHDR, sizeof(png_IHDR)), "expected PNG IHDR\n");
1054
1055 if (IsEqualGUID(format, &GUID_WICPixelFormatBlackWhite))
1056 {
1057 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1058 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1059
1060 ok(png.bit_depth == 1, "wrong bit_depth %d\n", png.bit_depth);
1061 ok(png.color_type == 0, "wrong color_type %d\n", png.color_type);
1062 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1063 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1064 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1065 }
1066 else if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed))
1067 {
1068 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1069 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1070
1071 ok(png.bit_depth == 1, "wrong bit_depth %d\n", png.bit_depth);
1072 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1073 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1074 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1075 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1076 }
1077 else if (IsEqualGUID(format, &GUID_WICPixelFormat2bppIndexed))
1078 {
1079 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1080 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1081
1082 ok(png.bit_depth == 2, "wrong bit_depth %d\n", png.bit_depth);
1083 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1084 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1085 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1086 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1087 }
1088 else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed))
1089 {
1090 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1091 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1092
1093 ok(png.bit_depth == 4, "wrong bit_depth %d\n", png.bit_depth);
1094 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1095 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1096 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1097 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1098 }
1099 else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed))
1100 {
1101 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1102 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1103
1104 ok(png.bit_depth == 8, "wrong bit_depth %d\n", png.bit_depth);
1105 ok(png.color_type == 3, "wrong color_type %d\n", png.color_type);
1106 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1107 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1108 ok(png.interlace == 0, "wrong interlace %d\n", png.interlace);
1109 }
1110 else if (IsEqualGUID(format, &GUID_WICPixelFormat24bppBGR))
1111 {
1112 ok(be_uint(png.width) == 32, "wrong width %u\n", be_uint(png.width));
1113 ok(be_uint(png.height) == 2, "wrong height %u\n", be_uint(png.height));
1114
1115 ok(png.bit_depth == 8, "wrong bit_depth %d\n", png.bit_depth);
1116 ok(png.color_type == 2, "wrong color_type %d\n", png.color_type);
1117 ok(png.compression == 0, "wrong compression %d\n", png.compression);
1118 ok(png.filter == 0, "wrong filter %d\n", png.filter);
1119 ok(png.interlace == 0 || png.interlace == 1, "wrong interlace %d\n", png.interlace);
1120 }
1121 else
1122 ok(0, "unknown PNG pixel format %s\n", wine_dbgstr_guid(format));
1123 }
1124
1125 static void check_gif_format(IStream *stream, const WICPixelFormatGUID *format)
1126 {
1127 #include "pshpack1.h"
1128 struct logical_screen_descriptor
1129 {
1130 char signature[6];
1131 USHORT width;
1132 USHORT height;
1133 BYTE packed;
1134 /* global_color_table_flag : 1;
1135 * color_resolution : 3;
1136 * sort_flag : 1;
1137 * global_color_table_size : 3;
1138 */
1139 BYTE background_color_index;
1140 BYTE pixel_aspect_ratio;
1141 } lsd;
1142 #include "poppack.h"
1143 UINT color_resolution;
1144 HRESULT hr;
1145
1146 memset(&lsd, 0, sizeof(lsd));
1147 hr = IStream_Read(stream, &lsd, sizeof(lsd), NULL);
1148 ok(hr == S_OK, "IStream_Read error %#x\n", hr);
1149
1150 ok(!memcmp(lsd.signature, "GIF89a", 6), "wrong GIF signature %.6s\n", lsd.signature);
1151
1152 ok(lsd.width == 32, "wrong width %u\n", lsd.width);
1153 ok(lsd.height == 2, "wrong height %u\n", lsd.height);
1154 color_resolution = 1 << (((lsd.packed >> 4) & 0x07) + 1);
1155 ok(color_resolution == 256, "wrong color resolution %u\n", color_resolution);
1156 ok(lsd.pixel_aspect_ratio == 0, "wrong pixel_aspect_ratio %u\n", lsd.pixel_aspect_ratio);
1157 }
1158
1159 static void check_bitmap_format(IStream *stream, const CLSID *encoder, const WICPixelFormatGUID *format)
1160 {
1161 HRESULT hr;
1162 LARGE_INTEGER pos;
1163
1164 pos.QuadPart = 0;
1165 hr = IStream_Seek(stream, pos, SEEK_SET, (ULARGE_INTEGER *)&pos);
1166 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
1167
1168 if (IsEqualGUID(encoder, &CLSID_WICPngEncoder))
1169 check_png_format(stream, format);
1170 else if (IsEqualGUID(encoder, &CLSID_WICBmpEncoder))
1171 check_bmp_format(stream, format);
1172 else if (IsEqualGUID(encoder, &CLSID_WICTiffEncoder))
1173 check_tiff_format(stream, format);
1174 else if (IsEqualGUID(encoder, &CLSID_WICGifEncoder))
1175 check_gif_format(stream, format);
1176 else
1177 ok(0, "unknown encoder %s\n", wine_dbgstr_guid(encoder));
1178
1179 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
1180 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
1181 }
1182
1183 struct setting {
1184 const WCHAR *name;
1185 PROPBAG2_TYPE type;
1186 VARTYPE vt;
1187 void *value;
1188 };
1189
1190 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
1191 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
1192 {
1193 ULONG rc;
1194 IUnknown_AddRef(obj);
1195 rc = IUnknown_Release(obj);
1196 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
1197 }
1198
1199 static void test_set_frame_palette(IWICBitmapFrameEncode *frameencode)
1200 {
1201 IWICComponentFactory *factory;
1202 IWICPalette *palette;
1203 HRESULT hr;
1204
1205 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1206 &IID_IWICComponentFactory, (void **)&factory);
1207 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
1208
1209 hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL);
1210 ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr);
1211
1212 hr = IWICComponentFactory_CreatePalette(factory, &palette);
1213 ok(hr == S_OK, "CreatePalette failed, hr=%x\n", hr);
1214
1215 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1216 todo_wine
1217 ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr=%x\n", hr);
1218
1219 hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedHalftone256, FALSE);
1220 ok(hr == S_OK, "InitializePredefined failed, hr=%x\n", hr);
1221
1222 EXPECT_REF(palette, 1);
1223 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1224 ok(hr == S_OK, "SetPalette failed, hr=%x\n", hr);
1225 EXPECT_REF(palette, 1);
1226
1227 hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL);
1228 ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr);
1229
1230 IWICPalette_Release(palette);
1231 IWICComponentFactory_Release(factory);
1232 }
1233
1234 static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* clsid_encoder,
1235 const struct bitmap_data **dsts, const CLSID *clsid_decoder, WICRect *rc,
1236 const struct setting *settings, const char *name, IWICPalette *palette)
1237 {
1238 const GUID *container_format = NULL;
1239 HRESULT hr;
1240 IWICBitmapEncoder *encoder;
1241 BitmapTestSrc *src_obj;
1242 HGLOBAL hglobal;
1243 IStream *stream;
1244 IWICBitmapFrameEncode *frameencode;
1245 IPropertyBag2 *options=NULL;
1246 IWICBitmapDecoder *decoder;
1247 IWICBitmapFrameDecode *framedecode;
1248 WICPixelFormatGUID pixelformat;
1249 GUID guid;
1250 int i;
1251
1252 hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER,
1253 &IID_IWICBitmapEncoder, (void **)&encoder);
1254 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
1255
1256 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1257 ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
1258
1259 hr = IWICBitmapEncoder_GetContainerFormat(encoder, NULL);
1260 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1261
1262 if (IsEqualGUID(clsid_encoder, &CLSID_WICPngEncoder))
1263 container_format = &GUID_ContainerFormatPng;
1264 else if (IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder))
1265 container_format = &GUID_ContainerFormatBmp;
1266 else if (IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder))
1267 container_format = &GUID_ContainerFormatTiff;
1268 else if (IsEqualGUID(clsid_encoder, &CLSID_WICJpegEncoder))
1269 container_format = &GUID_ContainerFormatJpeg;
1270 else
1271 ok(0, "Unknown encoder %s.\n", wine_dbgstr_guid(clsid_encoder));
1272
1273 if (container_format)
1274 {
1275 memset(&guid, 0, sizeof(guid));
1276 hr = IWICBitmapEncoder_GetContainerFormat(encoder, &guid);
1277 ok(SUCCEEDED(hr), "Failed to get container format, hr %#x.\n", hr);
1278 ok(IsEqualGUID(container_format, &guid), "Unexpected container format %s.\n", wine_dbgstr_guid(&guid));
1279 }
1280
1281 hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache);
1282 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1283
1284 /* Encoder options are optional. */
1285 hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, NULL);
1286 ok(SUCCEEDED(hr), "Failed to create encode frame, hr %#x.\n", hr);
1287
1288 IStream_Release(stream);
1289 IWICBitmapEncoder_Release(encoder);
1290 IWICBitmapFrameEncode_Release(frameencode);
1291
1292 hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER,
1293 &IID_IWICBitmapEncoder, (void**)&encoder);
1294 ok(SUCCEEDED(hr), "CoCreateInstance(%s) failed, hr=%x\n", wine_dbgstr_guid(clsid_encoder), hr);
1295 if (SUCCEEDED(hr))
1296 {
1297 hglobal = GlobalAlloc(GMEM_MOVEABLE, 0);
1298 ok(hglobal != NULL, "GlobalAlloc failed\n");
1299 if (hglobal)
1300 {
1301 hr = CreateStreamOnHGlobal(hglobal, TRUE, &stream);
1302 ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr);
1303 }
1304
1305 if (hglobal && SUCCEEDED(hr))
1306 {
1307 IWICBitmapEncoderInfo *info = NULL;
1308
1309 if (palette)
1310 {
1311 hr = IWICBitmapEncoder_SetPalette(encoder, palette);
1312 ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#x (%s)\n", hr, name);
1313 }
1314
1315 hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache);
1316 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1317
1318 if (palette)
1319 {
1320 hr = IWICBitmapEncoder_SetPalette(encoder, palette);
1321 if (IsEqualGUID(clsid_encoder, &CLSID_WICGifEncoder))
1322 ok(hr == S_OK, "SetPalette failed, hr=%#x\n", hr);
1323 else
1324 ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "wrong error %#x\n", hr);
1325 hr = S_OK;
1326 }
1327
1328 hr = IWICBitmapEncoder_GetEncoderInfo(encoder, &info);
1329 ok(hr == S_OK || hr == WINCODEC_ERR_COMPONENTNOTFOUND, "wrong error %#x\n", hr);
1330 if (SUCCEEDED(hr))
1331 {
1332 CLSID clsid;
1333
1334 hr = IWICBitmapEncoderInfo_GetCLSID(info, &clsid);
1335 ok(hr == S_OK, "wrong error %#x\n", hr);
1336 ok(!IsEqualGUID(clsid_encoder, &clsid), "wrong CLSID %s (%s)\n",
1337 wine_dbgstr_guid(clsid_encoder), wine_dbgstr_guid(&clsid));
1338
1339 IWICBitmapEncoderInfo_Release(info);
1340 }
1341
1342 i=0;
1343 while (SUCCEEDED(hr) && srcs[i])
1344 {
1345 CreateTestBitmap(srcs[i], &src_obj);
1346
1347 hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, &options);
1348 ok(SUCCEEDED(hr), "CreateFrame failed, hr=%x\n", hr);
1349 if (SUCCEEDED(hr))
1350 {
1351 ok(options != NULL, "Encoder initialization has not created an property bag\n");
1352 if(options)
1353 test_encoder_properties(clsid_encoder, options);
1354
1355 if (settings)
1356 {
1357 int j;
1358 for (j=0; settings[j].name; j++)
1359 {
1360 PROPBAG2 propbag;
1361 VARIANT var;
1362
1363 memset(&propbag, 0, sizeof(propbag));
1364 memset(&var, 0, sizeof(var));
1365 propbag.pstrName = (LPOLESTR)settings[j].name;
1366 propbag.dwType = settings[j].type;
1367 V_VT(&var) = settings[j].vt;
1368 V_UNKNOWN(&var) = settings[j].value;
1369
1370 hr = IPropertyBag2_Write(options, 1, &propbag, &var);
1371 ok(SUCCEEDED(hr), "Writing property %s failed, hr=%x\n", wine_dbgstr_w(settings[j].name), hr);
1372 }
1373 }
1374
1375 if (palette)
1376 {
1377 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1378 ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#x\n", hr);
1379 }
1380
1381 hr = IWICBitmapFrameEncode_Initialize(frameencode, options);
1382 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1383
1384 memcpy(&pixelformat, srcs[i]->format, sizeof(GUID));
1385 hr = IWICBitmapFrameEncode_SetPixelFormat(frameencode, &pixelformat);
1386 ok(SUCCEEDED(hr), "SetPixelFormat failed, hr=%x\n", hr);
1387 ok(IsEqualGUID(&pixelformat, dsts[i]->format) ||
1388 (IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)) ||
1389 (IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)),
1390 "SetPixelFormat changed the format to %s (%s)\n", wine_dbgstr_guid(&pixelformat), name);
1391
1392 hr = IWICBitmapFrameEncode_SetSize(frameencode, srcs[i]->width, srcs[i]->height);
1393 ok(SUCCEEDED(hr), "SetSize failed, hr=%x\n", hr);
1394
1395 if (IsEqualGUID(clsid_encoder, &CLSID_WICPngEncoder))
1396 test_set_frame_palette(frameencode);
1397
1398 if (palette)
1399 {
1400 WICColor colors[256];
1401
1402 hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette);
1403 ok(SUCCEEDED(hr), "SetPalette failed, hr=%x (%s)\n", hr, name);
1404
1405 /* trash the assigned palette */
1406 memset(colors, 0, sizeof(colors));
1407 hr = IWICPalette_InitializeCustom(palette, colors, 256);
1408 ok(hr == S_OK, "InitializeCustom error %#x\n", hr);
1409 }
1410
1411 hr = IWICBitmapFrameEncode_WriteSource(frameencode, &src_obj->IWICBitmapSource_iface, rc);
1412 if (rc && (rc->Width <= 0 || rc->Height <= 0))
1413 {
1414 /* WriteSource fails but WriteSource_Proxy succeeds. */
1415 ok(hr == E_INVALIDARG, "WriteSource should fail, hr=%x (%s)\n", hr, name);
1416 hr = IWICBitmapFrameEncode_WriteSource_Proxy(frameencode, &src_obj->IWICBitmapSource_iface, rc);
1417 ok(SUCCEEDED(hr), "WriteSource_Proxy failed, %dx%d, hr=%x (%s)\n", rc->Width, rc->Height, hr, name);
1418 }
1419 else
1420 {
1421 if (rc)
1422 ok(SUCCEEDED(hr), "WriteSource(%dx%d) failed, hr=%x (%s)\n", rc->Width, rc->Height, hr, name);
1423 else
1424 ok(hr == S_OK ||
1425 (FAILED(hr) && IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2) /* XP */ ||
1426 (FAILED(hr) && IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2) /* XP */ ||
1427 broken(hr == E_INVALIDARG && IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && IsEqualGUID(srcs[i]->format, &GUID_WICPixelFormatBlackWhite)) /* XP */,
1428 "WriteSource(NULL) failed, hr=%x (%s)\n", hr, name);
1429 }
1430
1431 if (SUCCEEDED(hr))
1432 {
1433 hr = IWICBitmapFrameEncode_Commit(frameencode);
1434 ok(SUCCEEDED(hr), "Commit failed, hr=%x (%s)\n", hr, name);
1435 }
1436
1437 IWICBitmapFrameEncode_Release(frameencode);
1438 IPropertyBag2_Release(options);
1439 }
1440
1441 DeleteTestBitmap(src_obj);
1442
1443 i++;
1444 }
1445
1446 if (clsid_decoder == NULL)
1447 {
1448 IStream_Release(stream);
1449 IWICBitmapEncoder_Release(encoder);
1450 return;
1451 }
1452
1453 if (SUCCEEDED(hr))
1454 {
1455 hr = IWICBitmapEncoder_Commit(encoder);
1456 ok(SUCCEEDED(hr), "Commit failed, hr=%x\n", hr);
1457
1458 if (IsEqualGUID(&pixelformat, dsts[0]->format))
1459 check_bitmap_format(stream, clsid_encoder, dsts[0]->format);
1460 }
1461
1462 if (SUCCEEDED(hr))
1463 {
1464 hr = CoCreateInstance(clsid_decoder, NULL, CLSCTX_INPROC_SERVER,
1465 &IID_IWICBitmapDecoder, (void**)&decoder);
1466 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
1467 }
1468
1469 if (SUCCEEDED(hr))
1470 {
1471 IWICPalette *frame_palette;
1472
1473 hr = IWICImagingFactory_CreatePalette(factory, &frame_palette);
1474 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
1475
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);
1481
1482 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
1483 ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr);
1484
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);
1490
1491 hr = S_OK;
1492 i=0;
1493 while (SUCCEEDED(hr) && dsts[i])
1494 {
1495 hr = IWICBitmapDecoder_GetFrame(decoder, i, &framedecode);
1496 ok(SUCCEEDED(hr), "GetFrame failed, hr=%x (%s)\n", hr, name);
1497
1498 if (SUCCEEDED(hr))
1499 {
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);
1504
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
1511 {
1512 UINT count, ret;
1513 WICColor colors[256];
1514
1515 ok(hr == S_OK, "CopyPalette error %#x (%s)\n", hr, name);
1516
1517 count = 0;
1518 hr = IWICPalette_GetColorCount(frame_palette, &count);
1519 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1520
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))
1527 {
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.
1530 */
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);
1534
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)
1538 {
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)
1542 {
1543 ok(colors[4] == 0x55555555, "got %08x (%s)\n", colors[4], name);
1544 ok(colors[5] == 0, "got %08x (%s)\n", colors[5], name);
1545 }
1546 }
1547 }
1548 else if (IsEqualGUID(clsid_decoder, &CLSID_WICBmpDecoder) ||
1549 IsEqualGUID(clsid_decoder, &CLSID_WICTiffDecoder) ||
1550 IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder))
1551 {
1552 if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormatBlackWhite) ||
1553 IsEqualGUID(&pixelformat, &GUID_WICPixelFormat8bppIndexed))
1554 {
1555 ok(count == 256, "expected 256, got %u (%s)\n", count, name);
1556
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);
1563 }
1564 else if (IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed))
1565 {
1566 ok(count == 16, "expected 16, got %u (%s)\n", count, name);
1567
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);
1574 }
1575 else
1576 {
1577 ok(count == 2, "expected 2, got %u (%s)\n", count, name);
1578
1579 ok(colors[0] == 0xff111111, "got %08x (%s)\n", colors[0], name);
1580 ok(colors[1] == 0xff222222, "got %08x (%s)\n", colors[1], name);
1581 }
1582 }
1583 else
1584 {
1585 ok(count == 2, "expected 2, got %u (%s)\n", count, name);
1586
1587 ok(colors[0] == 0xff111111, "got %08x\n", colors[0]);
1588 ok(colors[1] == 0xff222222, "got %08x\n", colors[1]);
1589 }
1590 }
1591
1592 IWICBitmapFrameDecode_Release(framedecode);
1593 }
1594
1595 i++;
1596 }
1597
1598 IWICPalette_Release(frame_palette);
1599 IWICBitmapDecoder_Release(decoder);
1600 }
1601
1602 IStream_Release(stream);
1603 }
1604
1605 IWICBitmapEncoder_Release(encoder);
1606 }
1607 }
1608
1609 static void test_encoder(const struct bitmap_data *src, const CLSID* clsid_encoder,
1610 const struct bitmap_data *dst, const CLSID *clsid_decoder, const char *name)
1611 {
1612 const struct bitmap_data *srcs[2];
1613 const struct bitmap_data *dsts[2];
1614 WICColor colors[256];
1615 IWICPalette *palette;
1616 HRESULT hr;
1617
1618 hr = IWICImagingFactory_CreatePalette(factory, &palette);
1619 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
1620
1621 memset(colors, 0, sizeof(colors));
1622 colors[0] = 0x11111111;
1623 colors[1] = 0x22222222;
1624 colors[2] = 0x33333333;
1625 colors[3] = 0x44444444;
1626 colors[4] = 0x55555555;
1627 /* TIFF decoder fails to decode a 8bpp frame if palette has less than 256 colors */
1628 hr = IWICPalette_InitializeCustom(palette, colors, 256);
1629 ok(hr == S_OK, "InitializeCustom error %#x\n", hr);
1630
1631 srcs[0] = src;
1632 srcs[1] = NULL;
1633 dsts[0] = dst;
1634 dsts[1] = NULL;
1635
1636 test_multi_encoder(srcs, clsid_encoder, dsts, clsid_decoder, NULL, NULL, name, palette);
1637
1638 IWICPalette_Release(palette);
1639 }
1640
1641 static void test_encoder_rects(void)
1642 {
1643 const struct bitmap_data *srcs[2];
1644 const struct bitmap_data *dsts[2];
1645 WICRect rc;
1646
1647 srcs[0] = &testdata_24bppBGR;
1648 srcs[1] = NULL;
1649 dsts[0] = &testdata_24bppBGR;
1650 dsts[1] = NULL;
1651
1652 rc.X = 0;
1653 rc.Y = 0;
1654 rc.Width = 32;
1655 rc.Height = 2;
1656
1657 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects full", NULL);
1658
1659 rc.Width = 0;
1660 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects width=0", NULL);
1661
1662 rc.Width = -1;
1663 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects width=-1", NULL);
1664
1665 rc.Width = 32;
1666 rc.Height = 0;
1667 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects height=0", NULL);
1668
1669 rc.Height = -1;
1670 test_multi_encoder(srcs, &CLSID_WICTiffEncoder, dsts, &CLSID_WICTiffDecoder, &rc, NULL, "test_encoder_rects height=-1", NULL);
1671 }
1672
1673 static const struct bitmap_data *multiple_frames[3] = {
1674 &testdata_24bppBGR,
1675 &testdata_24bppBGR,
1676 NULL};
1677
1678 static const struct bitmap_data *single_frame[2] = {
1679 &testdata_24bppBGR,
1680 NULL};
1681
1682 static const struct setting png_interlace_settings[] = {
1683 {wszInterlaceOption, PROPBAG2_TYPE_DATA, VT_BOOL, (void*)VARIANT_TRUE},
1684 {NULL}
1685 };
1686
1687 static void test_converter_8bppIndexed(void)
1688 {
1689 HRESULT hr;
1690 BitmapTestSrc *src_obj;
1691 IWICFormatConverter *converter;
1692 IWICPalette *palette;
1693 UINT count, i;
1694 BYTE buf[32 * 2 * 3]; /* enough to hold 32x2 24bppBGR data */
1695
1696 CreateTestBitmap(&testdata_24bppBGR, &src_obj);
1697
1698 hr = IWICImagingFactory_CreatePalette(factory, &palette);
1699 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
1700 count = 0xdeadbeef;
1701 hr = IWICPalette_GetColorCount(palette, &count);
1702 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1703 ok(count == 0, "expected 0, got %u\n", count);
1704
1705 /* NULL palette + Custom type */
1706 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1707 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1708 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1709 &GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone,
1710 NULL, 0.0, WICBitmapPaletteTypeCustom);
1711 ok(hr == S_OK, "Initialize error %#x\n", hr);
1712 hr = IWICFormatConverter_CopyPalette(converter, palette);
1713 ok(hr == 0xdeadbeef, "unexpected error %#x\n", hr);
1714 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32 * 3, sizeof(buf), buf);
1715 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1716 IWICFormatConverter_Release(converter);
1717
1718 /* NULL palette + Custom type */
1719 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1720 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1721 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1722 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1723 NULL, 0.0, WICBitmapPaletteTypeCustom);
1724 ok(hr == E_INVALIDARG, "unexpected error %#x\n", hr);
1725 hr = IWICFormatConverter_CopyPalette(converter, palette);
1726 ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr);
1727 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1728 ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr);
1729 IWICFormatConverter_Release(converter);
1730
1731 /* empty palette + Custom type */
1732 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1733 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1734 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1735 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1736 palette, 0.0, WICBitmapPaletteTypeCustom);
1737 ok(hr == S_OK, "Initialize error %#x\n", hr);
1738 hr = IWICFormatConverter_CopyPalette(converter, palette);
1739 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1740 count = 0xdeadbeef;
1741 hr = IWICPalette_GetColorCount(palette, &count);
1742 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1743 ok(count == 0, "expected 0, got %u\n", count);
1744 memset(buf, 0xaa, sizeof(buf));
1745 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1746 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1747 count = 0;
1748 for (i = 0; i < 32 * 2; i++)
1749 if (buf[i] != 0) count++;
1750 ok(count == 0, "expected 0\n");
1751 IWICFormatConverter_Release(converter);
1752
1753 /* NULL palette + Predefined type */
1754 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1755 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1756 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1757 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1758 NULL, 0.0, WICBitmapPaletteTypeFixedGray16);
1759 ok(hr == S_OK, "Initialize error %#x\n", hr);
1760 hr = IWICFormatConverter_CopyPalette(converter, palette);
1761 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1762 count = 0xdeadbeef;
1763 hr = IWICPalette_GetColorCount(palette, &count);
1764 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1765 ok(count == 16, "expected 16, got %u\n", count);
1766 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1767 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1768 count = 0;
1769 for (i = 0; i < 32 * 2; i++)
1770 if (buf[i] != 0) count++;
1771 ok(count != 0, "expected != 0\n");
1772 IWICFormatConverter_Release(converter);
1773
1774 /* not empty palette + Predefined type */
1775 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1776 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1777 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1778 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1779 palette, 0.0, WICBitmapPaletteTypeFixedHalftone64);
1780 ok(hr == S_OK, "Initialize error %#x\n", hr);
1781 hr = IWICFormatConverter_CopyPalette(converter, palette);
1782 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1783 count = 0xdeadbeef;
1784 hr = IWICPalette_GetColorCount(palette, &count);
1785 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1786 ok(count == 16, "expected 16, got %u\n", count);
1787 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1788 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1789 count = 0;
1790 for (i = 0; i < 32 * 2; i++)
1791 if (buf[i] != 0) count++;
1792 ok(count != 0, "expected != 0\n");
1793 IWICFormatConverter_Release(converter);
1794
1795 /* not empty palette + MedianCut type */
1796 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1797 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1798 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1799 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1800 palette, 0.0, WICBitmapPaletteTypeMedianCut);
1801 ok(hr == S_OK, "Initialize error %#x\n", hr);
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 == 16, "expected 16, 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 IWICFormatConverter_Release(converter);
1815
1816 /* NULL palette + MedianCut type */
1817 hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
1818 ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
1819 hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
1820 &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone,
1821 NULL, 0.0, WICBitmapPaletteTypeMedianCut);
1822 ok(hr == S_OK || broken(hr == E_INVALIDARG) /* XP */, "Initialize error %#x\n", hr);
1823 if (hr == S_OK)
1824 {
1825 hr = IWICFormatConverter_CopyPalette(converter, palette);
1826 ok(hr == S_OK, "CopyPalette error %#x\n", hr);
1827 count = 0xdeadbeef;
1828 hr = IWICPalette_GetColorCount(palette, &count);
1829 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
1830 ok(count == 8, "expected 8, got %u\n", count);
1831 hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf);
1832 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1833 count = 0;
1834 for (i = 0; i < 32 * 2; i++)
1835 if (buf[i] != 0) count++;
1836 ok(count != 0, "expected != 0\n");
1837 }
1838 IWICFormatConverter_Release(converter);
1839
1840 IWICPalette_Release(palette);
1841 DeleteTestBitmap(src_obj);
1842 }
1843
1844 START_TEST(converter)
1845 {
1846 HRESULT hr;
1847
1848 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1849
1850 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1851 &IID_IWICImagingFactory, (void **)&factory);
1852 ok(hr == S_OK, "failed to create factory: %#x\n", hr);
1853
1854 test_conversion(&testdata_24bppRGB, &testdata_1bppIndexed, "24bppRGB -> 1bppIndexed", TRUE);
1855 test_conversion(&testdata_24bppRGB, &testdata_2bppIndexed, "24bppRGB -> 2bppIndexed", TRUE);
1856 test_conversion(&testdata_24bppRGB, &testdata_4bppIndexed, "24bppRGB -> 4bppIndexed", TRUE);
1857 test_conversion(&testdata_24bppRGB, &testdata_8bppIndexed, "24bppRGB -> 8bppIndexed", FALSE);
1858
1859 test_conversion(&testdata_BlackWhite, &testdata_8bppIndexed_BW, "BlackWhite -> 8bppIndexed", TRUE);
1860 test_conversion(&testdata_1bppIndexed, &testdata_8bppIndexed_BW, "1bppIndexed -> 8bppIndexed", TRUE);
1861 test_conversion(&testdata_2bppIndexed, &testdata_8bppIndexed_4colors, "2bppIndexed -> 8bppIndexed", TRUE);
1862 test_conversion(&testdata_4bppIndexed, &testdata_8bppIndexed, "4bppIndexed -> 8bppIndexed", TRUE);
1863
1864 test_conversion(&testdata_32bppBGRA, &testdata_32bppBGR, "BGRA -> BGR", FALSE);
1865 test_conversion(&testdata_32bppBGR, &testdata_32bppBGRA, "BGR -> BGRA", FALSE);
1866 test_conversion(&testdata_32bppBGRA, &testdata_32bppBGRA, "BGRA -> BGRA", FALSE);
1867 test_conversion(&testdata_32bppBGRA80, &testdata_32bppPBGRA, "BGRA -> PBGRA", FALSE);
1868
1869 test_conversion(&testdata_32bppRGBA, &testdata_32bppRGB, "RGBA -> RGB", FALSE);
1870 test_conversion(&testdata_32bppRGB, &testdata_32bppRGBA, "RGB -> RGBA", FALSE);
1871 test_conversion(&testdata_32bppRGBA, &testdata_32bppRGBA, "RGBA -> RGBA", FALSE);
1872 test_conversion(&testdata_32bppRGBA80, &testdata_32bppPRGBA, "RGBA -> PRGBA", FALSE);
1873
1874 test_conversion(&testdata_24bppBGR, &testdata_24bppBGR, "24bppBGR -> 24bppBGR", FALSE);
1875 test_conversion(&testdata_24bppBGR, &testdata_24bppRGB, "24bppBGR -> 24bppRGB", FALSE);
1876
1877 test_conversion(&testdata_24bppRGB, &testdata_24bppRGB, "24bppRGB -> 24bppRGB", FALSE);
1878 test_conversion(&testdata_24bppRGB, &testdata_24bppBGR, "24bppRGB -> 24bppBGR", FALSE);
1879
1880 test_conversion(&testdata_32bppBGR, &testdata_24bppRGB, "32bppBGR -> 24bppRGB", FALSE);
1881 test_conversion(&testdata_24bppRGB, &testdata_32bppBGR, "24bppRGB -> 32bppBGR", FALSE);
1882 test_conversion(&testdata_32bppBGRA, &testdata_24bppRGB, "32bppBGRA -> 24bppRGB", FALSE);
1883
1884 test_conversion(&testdata_64bppRGBA, &testdata_32bppRGBA, "64bppRGBA -> 32bppRGBA", FALSE);
1885 test_conversion(&testdata_64bppRGBA, &testdata_32bppRGB, "64bppRGBA -> 32bppRGB", FALSE);
1886
1887 test_conversion(&testdata_24bppRGB, &testdata_32bppGrayFloat, "24bppRGB -> 32bppGrayFloat", FALSE);
1888 test_conversion(&testdata_32bppBGR, &testdata_32bppGrayFloat, "32bppBGR -> 32bppGrayFloat", FALSE);
1889
1890 test_conversion(&testdata_24bppBGR, &testdata_8bppGray, "24bppBGR -> 8bppGray", FALSE);
1891 test_conversion(&testdata_32bppBGR, &testdata_8bppGray, "32bppBGR -> 8bppGray", FALSE);
1892 test_conversion(&testdata_32bppGrayFloat, &testdata_24bppBGR_gray, "32bppGrayFloat -> 24bppBGR gray", FALSE);
1893 test_conversion(&testdata_32bppGrayFloat, &testdata_8bppGray, "32bppGrayFloat -> 8bppGray", FALSE);
1894
1895 test_invalid_conversion();
1896 test_default_converter();
1897 test_converter_8bppIndexed();
1898
1899 test_encoder(&testdata_8bppIndexed, &CLSID_WICGifEncoder,
1900 &testdata_8bppIndexed, &CLSID_WICGifDecoder, "GIF encoder 8bppIndexed");
1901
1902 test_encoder(&testdata_BlackWhite, &CLSID_WICPngEncoder,
1903 &testdata_BlackWhite, &CLSID_WICPngDecoder, "PNG encoder BlackWhite");
1904 test_encoder(&testdata_1bppIndexed, &CLSID_WICPngEncoder,
1905 &testdata_1bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 1bppIndexed");
1906 test_encoder(&testdata_2bppIndexed, &CLSID_WICPngEncoder,
1907 &testdata_2bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 2bppIndexed");
1908 test_encoder(&testdata_4bppIndexed, &CLSID_WICPngEncoder,
1909 &testdata_4bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 4bppIndexed");
1910 test_encoder(&testdata_8bppIndexed, &CLSID_WICPngEncoder,
1911 &testdata_8bppIndexed, &CLSID_WICPngDecoder, "PNG encoder 8bppIndexed");
1912 test_encoder(&testdata_24bppBGR, &CLSID_WICPngEncoder,
1913 &testdata_24bppBGR, &CLSID_WICPngDecoder, "PNG encoder 24bppBGR");
1914 if (!strcmp(winetest_platform, "windows")) /* FIXME: enable once implemented in Wine */
1915 {
1916 test_encoder(&testdata_32bppBGR, &CLSID_WICPngEncoder,
1917 &testdata_24bppBGR, &CLSID_WICPngDecoder, "PNG encoder 32bppBGR");
1918 }
1919
1920 test_encoder(&testdata_BlackWhite, &CLSID_WICBmpEncoder,
1921 &testdata_1bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder BlackWhite");
1922 test_encoder(&testdata_1bppIndexed, &CLSID_WICBmpEncoder,
1923 &testdata_1bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 1bppIndexed");
1924 test_encoder(&testdata_2bppIndexed, &CLSID_WICBmpEncoder,
1925 &testdata_4bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 2bppIndexed");
1926 test_encoder(&testdata_4bppIndexed, &CLSID_WICBmpEncoder,
1927 &testdata_4bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 4bppIndexed");
1928 test_encoder(&testdata_8bppIndexed, &CLSID_WICBmpEncoder,
1929 &testdata_8bppIndexed, &CLSID_WICBmpDecoder, "BMP encoder 8bppIndexed");
1930 test_encoder(&testdata_32bppBGR, &CLSID_WICBmpEncoder,
1931 &testdata_32bppBGR, &CLSID_WICBmpDecoder, "BMP encoder 32bppBGR");
1932
1933 test_encoder(&testdata_BlackWhite, &CLSID_WICTiffEncoder,
1934 &testdata_BlackWhite, &CLSID_WICTiffDecoder, "TIFF encoder BlackWhite");
1935 test_encoder(&testdata_1bppIndexed, &CLSID_WICTiffEncoder,
1936 &testdata_1bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 1bppIndexed");
1937 test_encoder(&testdata_2bppIndexed, &CLSID_WICTiffEncoder,
1938 &testdata_4bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 2bppIndexed");
1939 test_encoder(&testdata_4bppIndexed, &CLSID_WICTiffEncoder,
1940 &testdata_4bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 4bppIndexed");
1941 test_encoder(&testdata_8bppIndexed, &CLSID_WICTiffEncoder,
1942 &testdata_8bppIndexed, &CLSID_WICTiffDecoder, "TIFF encoder 8bppIndexed");
1943 test_encoder(&testdata_24bppBGR, &CLSID_WICTiffEncoder,
1944 &testdata_24bppBGR, &CLSID_WICTiffDecoder, "TIFF encoder 24bppBGR");
1945
1946 test_encoder(&testdata_24bppBGR, &CLSID_WICJpegEncoder,
1947 &testdata_24bppBGR, NULL, "JPEG encoder 24bppBGR");
1948
1949 test_multi_encoder(multiple_frames, &CLSID_WICTiffEncoder,
1950 multiple_frames, &CLSID_WICTiffDecoder, NULL, NULL, "TIFF encoder multi-frame", NULL);
1951
1952 test_encoder_rects();
1953
1954 test_multi_encoder(single_frame, &CLSID_WICPngEncoder,
1955 single_frame, &CLSID_WICPngDecoder, NULL, png_interlace_settings, "PNG encoder interlaced", NULL);
1956
1957 IWICImagingFactory_Release(factory);
1958
1959 CoUninitialize();
1960 }