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