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