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