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