1 /* 2 * Copyright 2012,2016 Dmitry Timoshkov 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #include <math.h> 20 #include <stdarg.h> 21 #include <stdio.h> 22 23 #define COBJMACROS 24 25 #include "windef.h" 26 #include "wincodec.h" 27 #include "wine/test.h" 28 29 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__) 30 static void _expect_ref(IUnknown* obj, ULONG ref, int line) 31 { 32 ULONG rc; 33 IUnknown_AddRef(obj); 34 rc = IUnknown_Release(obj); 35 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); 36 } 37 38 #define IFD_BYTE 1 39 #define IFD_ASCII 2 40 #define IFD_SHORT 3 41 #define IFD_LONG 4 42 #define IFD_RATIONAL 5 43 #define IFD_SBYTE 6 44 #define IFD_UNDEFINED 7 45 #define IFD_SSHORT 8 46 #define IFD_SLONG 9 47 #define IFD_SRATIONAL 10 48 #define IFD_FLOAT 11 49 #define IFD_DOUBLE 12 50 51 #include "pshpack2.h" 52 struct IFD_entry 53 { 54 SHORT id; 55 SHORT type; 56 ULONG count; 57 LONG value; 58 }; 59 60 struct IFD_rational 61 { 62 LONG numerator; 63 LONG denominator; 64 }; 65 66 static const struct tiff_1bpp_data 67 { 68 USHORT byte_order; 69 USHORT version; 70 ULONG dir_offset; 71 USHORT number_of_entries; 72 struct IFD_entry entry[13]; 73 ULONG next_IFD; 74 struct IFD_rational res; 75 BYTE pixel_data[4]; 76 } tiff_1bpp_data = 77 { 78 #ifdef WORDS_BIGENDIAN 79 'M' | 'M' << 8, 80 #else 81 'I' | 'I' << 8, 82 #endif 83 42, 84 FIELD_OFFSET(struct tiff_1bpp_data, number_of_entries), 85 13, 86 { 87 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ 88 { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ 89 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ 90 { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */ 91 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ 92 { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */ 93 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1bpp_data, pixel_data) }, /* STRIPOFFSETS */ 94 { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */ 95 { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */ 96 { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */ 97 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1bpp_data, res) }, /* XRESOLUTION */ 98 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1bpp_data, res) }, /* YRESOLUTION */ 99 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ 100 }, 101 0, 102 { 900, 3 }, 103 { 0x11, 0x22, 0x33, 0 } 104 }; 105 106 static const struct tiff_8bpp_alpha 107 { 108 USHORT byte_order; 109 USHORT version; 110 ULONG dir_offset; 111 USHORT number_of_entries; 112 struct IFD_entry entry[15]; 113 ULONG next_IFD; 114 struct IFD_rational res; 115 BYTE pixel_data[8]; 116 } tiff_8bpp_alpha = 117 { 118 #ifdef WORDS_BIGENDIAN 119 'M' | 'M' << 8, 120 #else 121 'I' | 'I' << 8, 122 #endif 123 42, 124 FIELD_OFFSET(struct tiff_8bpp_alpha, number_of_entries), 125 15, 126 { 127 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ 128 { 0x100, IFD_LONG, 1, 2 }, /* IMAGEWIDTH */ 129 { 0x101, IFD_LONG, 1, 2 }, /* IMAGELENGTH */ 130 { 0x102, IFD_SHORT, 2, MAKELONG(8, 8) }, /* BITSPERSAMPLE */ 131 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ 132 { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */ 133 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, pixel_data) }, /* STRIPOFFSETS */ 134 { 0x115, IFD_SHORT, 1, 2 }, /* SAMPLESPERPIXEL */ 135 { 0x116, IFD_LONG, 1, 2 }, /* ROWSPERSTRIP */ 136 { 0x117, IFD_LONG, 1, 8 }, /* STRIPBYTECOUNT */ 137 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, res) }, /* XRESOLUTION */ 138 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, res) }, /* YRESOLUTION */ 139 { 0x11c, IFD_SHORT, 1, 1 }, /* PLANARCONFIGURATION */ 140 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ 141 { 0x152, IFD_SHORT, 1, 1 } /* EXTRASAMPLES: 1 - Associated alpha with pre-multiplied color */ 142 }, 143 0, 144 { 96, 1 }, 145 { 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88 } 146 }; 147 148 static const struct tiff_8bpp_data 149 { 150 USHORT byte_order; 151 USHORT version; 152 ULONG dir_offset; 153 USHORT number_of_entries; 154 struct IFD_entry entry[14]; 155 ULONG next_IFD; 156 struct IFD_rational res; 157 short palette_data[3][256]; 158 BYTE pixel_data[4]; 159 } tiff_8bpp_data = 160 { 161 #ifdef WORDS_BIGENDIAN 162 'M' | 'M' << 8, 163 #else 164 'I' | 'I' << 8, 165 #endif 166 42, 167 FIELD_OFFSET(struct tiff_8bpp_data, number_of_entries), 168 14, 169 { 170 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ 171 { 0x100, IFD_LONG, 1, 4 }, /* IMAGEWIDTH */ 172 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ 173 { 0x102, IFD_SHORT, 1, 8 }, /* BITSPERSAMPLE: XP doesn't accept IFD_LONG here */ 174 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ 175 { 0x106, IFD_SHORT, 1, 3 }, /* PHOTOMETRIC */ 176 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_8bpp_data, pixel_data) }, /* STRIPOFFSETS */ 177 { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */ 178 { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */ 179 { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */ 180 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_data, res) }, 181 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_data, res) }, 182 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ 183 { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_8bpp_data, palette_data) } /* COLORMAP */ 184 }, 185 0, 186 { 96, 1 }, 187 { { 0 } }, 188 { 0,1,2,3 } 189 }; 190 191 static const struct tiff_resolution_test_data 192 { 193 struct IFD_rational resx; 194 struct IFD_rational resy; 195 LONG resolution_unit; 196 double expected_dpi_x; 197 double expected_dpi_y; 198 /* if != 0: values for different behavior of some Windows versions */ 199 double broken_dpi_x; 200 double broken_dpi_y; 201 } tiff_resolution_test_data[] = 202 { 203 { { 100, 1 }, { 50, 1 }, 0, 100.0, 50.0, 0, 0 }, /* invalid resolution unit */ 204 { { 50, 1 }, { 100, 1 }, 0, 50.0, 100.0, 0, 0 }, 205 206 { { 100, 1 }, { 50, 1 }, 1, 100.0, 50.0, 0, 0 }, /* RESUNIT_NONE */ 207 { { 50, 1 }, { 100, 1 }, 1, 50.0, 100.0, 0, 0 }, 208 209 { { 49, 1 }, { 49, 1 }, 2, 49.0, 49.0, 0, 0 }, /* same resolution for both X and Y */ 210 { { 33, 1 }, { 55, 1 }, 2, 33.0, 55.0, 0, 0 }, /* different resolutions for X and Y */ 211 { { 50, 2 }, { 66, 3 }, 2, 25.0, 22.0, 0, 0 }, /* denominator != 1 */ 212 213 { { 100, 1 }, { 200, 1 }, 3, 254.0, 508.0, 0, 0 }, /* unit = centimeters */ 214 215 /* XP and Server 2003 do not discard both resolution values if only one of them is invalid */ 216 { { 0, 1 }, { 29, 1 }, 2, 96.0, 96.0, 0, 29.0 }, /* resolution 0 */ 217 { { 58, 1 }, { 29, 0 }, 2, 96.0, 96.0, 58.0, 0 }, /* denominator 0 (division by zero) */ 218 219 /* XP and Server 2003 return 96 dots per centimeter (= 243.84 dpi) as fallback value */ 220 { { 0, 1 }, { 100, 1 }, 3, 96.0, 96.0, 243.84, 254.0 }, /* resolution 0 and unit = centimeters */ 221 { { 50, 1 }, { 72, 0 }, 3, 96.0, 96.0, 127.0, 243.84 } /* denominator 0 and unit = centimeters */ 222 }; 223 224 static struct tiff_resolution_image_data 225 { 226 USHORT byte_order; 227 USHORT version; 228 ULONG dir_offset; 229 USHORT number_of_entries; 230 struct IFD_entry entry[13]; 231 ULONG next_IFD; 232 struct IFD_rational resx; 233 struct IFD_rational resy; 234 BYTE pixel_data[4]; 235 } tiff_resolution_image_data = 236 { 237 #ifdef WORDS_BIGENDIAN 238 'M' | 'M' << 8, 239 #else 240 'I' | 'I' << 8, 241 #endif 242 42, 243 FIELD_OFFSET(struct tiff_resolution_image_data, number_of_entries), 244 13, 245 { 246 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ 247 { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ 248 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ 249 { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */ 250 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ 251 { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */ 252 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_resolution_image_data, pixel_data) }, /* STRIPOFFSETS */ 253 { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */ 254 { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */ 255 { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */ 256 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_resolution_image_data, resx) }, /* XRESOLUTION */ 257 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_resolution_image_data, resy) }, /* YRESOLUTION */ 258 { 0x128, IFD_SHORT, 1, 1 }, /* RESOLUTIONUNIT -- value will be filled with test data */ 259 }, 260 0, 261 { 72, 1 }, /* value will be filled with test data */ 262 { 72, 1 }, /* value will be filled with test data */ 263 { 0x11, 0x22, 0x33, 0 } 264 }; 265 266 static const struct tiff_24bpp_data 267 { 268 USHORT byte_order; 269 USHORT version; 270 ULONG dir_offset; 271 USHORT number_of_entries; 272 struct IFD_entry entry[13]; 273 ULONG next_IFD; 274 struct IFD_rational res; 275 BYTE pixel_data[3]; 276 } tiff_24bpp_data = 277 { 278 #ifdef WORDS_BIGENDIAN 279 'M' | 'M' << 8, 280 #else 281 'I' | 'I' << 8, 282 #endif 283 42, 284 FIELD_OFFSET(struct tiff_1bpp_data, number_of_entries), 285 13, 286 { 287 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ 288 { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ 289 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ 290 { 0x102, IFD_SHORT, 1, 8 }, /* BITSPERSAMPLE */ 291 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ 292 { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */ 293 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_24bpp_data, pixel_data) }, /* STRIPOFFSETS */ 294 { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */ 295 { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */ 296 { 0x117, IFD_LONG, 1, 3 }, /* STRIPBYTECOUNT */ 297 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_24bpp_data, res) }, /* XRESOLUTION */ 298 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_24bpp_data, res) }, /* YRESOLUTION */ 299 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ 300 }, 301 0, 302 { 900, 3 }, 303 { 0x11, 0x22, 0x33 } 304 }; 305 306 static const struct tiff_4bps_bgra 307 { 308 USHORT byte_order; 309 USHORT version; 310 ULONG dir_offset; 311 USHORT number_of_entries; 312 struct IFD_entry entry[14]; 313 ULONG next_IFD; 314 struct IFD_rational res; 315 BYTE pixel_data[4]; 316 } tiff_4bps_bgra = 317 { 318 #ifdef WORDS_BIGENDIAN 319 'M' | 'M' << 8, 320 #else 321 'I' | 'I' << 8, 322 #endif 323 42, 324 FIELD_OFFSET(struct tiff_4bps_bgra, number_of_entries), 325 14, 326 { 327 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ 328 { 0x100, IFD_LONG, 1, 3 }, /* IMAGEWIDTH */ 329 { 0x101, IFD_LONG, 1, 2 }, /* IMAGELENGTH */ 330 { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */ 331 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION */ 332 { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */ 333 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_4bps_bgra, pixel_data) }, /* STRIPOFFSETS */ 334 { 0x115, IFD_SHORT, 1, 4 }, /* SAMPLESPERPIXEL */ 335 { 0x116, IFD_LONG, 1, 2 }, /* ROWSPERSTRIP */ 336 { 0x117, IFD_LONG, 1, 4 }, /* STRIPBYTECOUNT */ 337 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_4bps_bgra, res) }, /* XRESOLUTION */ 338 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_4bps_bgra, res) }, /* YRESOLUTION */ 339 { 0x11c, IFD_SHORT, 1, 1 }, /* PLANARCONFIGURATION */ 340 { 0x128, IFD_SHORT, 1, 2 } /* RESOLUTIONUNIT */ 341 }, 342 0, 343 { 96, 1 }, 344 { 0x12,0x30, 0x47,0xe0 } 345 }; 346 #include "poppack.h" 347 348 static IWICImagingFactory *factory; 349 350 static IStream *create_stream(const void *data, int data_size) 351 { 352 HRESULT hr; 353 IStream *stream; 354 HGLOBAL hdata; 355 void *locked_data; 356 357 hdata = GlobalAlloc(GMEM_MOVEABLE, data_size); 358 ok(hdata != 0, "GlobalAlloc failed\n"); 359 if (!hdata) return NULL; 360 361 locked_data = GlobalLock(hdata); 362 memcpy(locked_data, data, data_size); 363 GlobalUnlock(hdata); 364 365 hr = CreateStreamOnHGlobal(hdata, TRUE, &stream); 366 ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr); 367 368 return stream; 369 } 370 371 static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitmapDecoder **decoder) 372 { 373 HGLOBAL hmem; 374 BYTE *data; 375 HRESULT hr; 376 IStream *stream; 377 GUID format; 378 LONG refcount; 379 380 *decoder = NULL; 381 382 hmem = GlobalAlloc(0, image_size); 383 data = GlobalLock(hmem); 384 memcpy(data, image_data, image_size); 385 GlobalUnlock(hmem); 386 387 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); 388 ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); 389 390 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, decoder); 391 if (hr == S_OK) 392 { 393 hr = IWICBitmapDecoder_GetContainerFormat(*decoder, &format); 394 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); 395 ok(IsEqualGUID(&format, &GUID_ContainerFormatTiff), 396 "wrong container format %s\n", wine_dbgstr_guid(&format)); 397 398 refcount = IStream_Release(stream); 399 ok(refcount > 0, "expected stream refcount > 0\n"); 400 } 401 402 return hr; 403 } 404 405 static HRESULT get_pixelformat_info(const GUID *format, UINT *bpp, UINT *channels, BOOL *trasparency) 406 { 407 HRESULT hr; 408 IWICComponentInfo *info; 409 IWICPixelFormatInfo2 *formatinfo; 410 411 hr = IWICImagingFactory_CreateComponentInfo(factory, format, &info); 412 ok(hr == S_OK, "CreateComponentInfo(%s) error %#x\n", wine_dbgstr_guid(format), hr); 413 if (hr == S_OK) 414 { 415 hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void **)&formatinfo); 416 if (hr == S_OK) 417 { 418 hr = IWICPixelFormatInfo2_SupportsTransparency(formatinfo, trasparency); 419 ok(hr == S_OK, "SupportsTransparency error %#x\n", hr); 420 IWICPixelFormatInfo2_Release(formatinfo); 421 } 422 hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void **)&formatinfo); 423 if (hr == S_OK) 424 { 425 hr = IWICPixelFormatInfo2_GetBitsPerPixel(formatinfo, bpp); 426 ok(hr == S_OK, "GetBitsPerPixel error %#x\n", hr); 427 hr = IWICPixelFormatInfo2_GetChannelCount(formatinfo, channels); 428 ok(hr == S_OK, "GetChannelCount error %#x\n", hr); 429 IWICPixelFormatInfo2_Release(formatinfo); 430 } 431 IWICComponentInfo_Release(info); 432 } 433 return hr; 434 } 435 436 static void dump_tiff(void *buf) 437 { 438 UINT count, i; 439 struct tiff_1bpp_data *tiff; 440 struct IFD_entry *tag; 441 442 tiff = buf; 443 count = *(short *)((char *)tiff + tiff->dir_offset); 444 tag = (struct IFD_entry *)((char *)tiff + tiff->dir_offset + sizeof(short)); 445 446 for (i = 0; i < count; i++) 447 { 448 printf("tag %u: id %04x, type %04x, count %u, value %d", 449 i, tag[i].id, tag[i].type, tag[i].count, tag[i].value); 450 if (tag[i].id == 0x102 && tag[i].count > 2) 451 { 452 short *bps = (short *)((char *)tiff + tag[i].value); 453 printf(" (%d,%d,%d,%d)\n", bps[0], bps[1], bps[2], bps[3]); 454 } 455 else 456 printf("\n"); 457 } 458 } 459 460 static void test_tiff_1bpp_palette(void) 461 { 462 HRESULT hr; 463 IWICBitmapDecoder *decoder; 464 IWICBitmapFrameDecode *frame; 465 IWICPalette *palette; 466 GUID format; 467 468 hr = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data), &decoder); 469 ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); 470 if (hr != S_OK) return; 471 472 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); 473 ok(hr == S_OK, "GetFrame error %#x\n", hr); 474 475 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); 476 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); 477 ok(IsEqualGUID(&format, &GUID_WICPixelFormatBlackWhite), 478 "got wrong format %s\n", wine_dbgstr_guid(&format)); 479 480 hr = IWICImagingFactory_CreatePalette(factory, &palette); 481 ok(hr == S_OK, "CreatePalette error %#x\n", hr); 482 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); 483 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, 484 "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr); 485 486 IWICPalette_Release(palette); 487 IWICBitmapFrameDecode_Release(frame); 488 IWICBitmapDecoder_Release(decoder); 489 } 490 491 static void test_QueryCapability(void) 492 { 493 HRESULT hr; 494 IStream *stream; 495 IWICBitmapDecoder *decoder; 496 IWICBitmapFrameDecode *frame; 497 static const DWORD exp_caps = WICBitmapDecoderCapabilityCanDecodeAllImages | 498 WICBitmapDecoderCapabilityCanDecodeSomeImages | 499 WICBitmapDecoderCapabilityCanEnumerateMetadata; 500 static const DWORD exp_caps_xp = WICBitmapDecoderCapabilityCanDecodeAllImages | 501 WICBitmapDecoderCapabilityCanDecodeSomeImages; 502 DWORD capability; 503 LARGE_INTEGER pos; 504 ULARGE_INTEGER cur_pos; 505 UINT frame_count; 506 507 stream = create_stream(&tiff_1bpp_data, sizeof(tiff_1bpp_data)); 508 if (!stream) return; 509 510 hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatTiff, NULL, &decoder); 511 ok(hr == S_OK, "CreateDecoder error %#x\n", hr); 512 if (FAILED(hr)) return; 513 514 frame_count = 0xdeadbeef; 515 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); 516 ok(hr == S_OK || broken(hr == E_POINTER) /* XP */, "GetFrameCount error %#x\n", hr); 517 ok(frame_count == 0, "expected 0, got %u\n", frame_count); 518 519 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); 520 ok(hr == WINCODEC_ERR_FRAMEMISSING || broken(hr == E_POINTER) /* XP */, "expected WINCODEC_ERR_FRAMEMISSING, got %#x\n", hr); 521 522 pos.QuadPart = 4; 523 hr = IStream_Seek(stream, pos, SEEK_SET, NULL); 524 ok(hr == S_OK, "IStream_Seek error %#x\n", hr); 525 526 capability = 0xdeadbeef; 527 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability); 528 ok(hr == S_OK, "QueryCapability error %#x\n", hr); 529 ok(capability == exp_caps || capability == exp_caps_xp, 530 "expected %#x, got %#x\n", exp_caps, capability); 531 532 frame_count = 0xdeadbeef; 533 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); 534 ok(hr == S_OK, "GetFrameCount error %#x\n", hr); 535 ok(frame_count == 1, "expected 1, got %u\n", frame_count); 536 537 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); 538 ok(hr == S_OK, "GetFrame error %#x\n", hr); 539 IWICBitmapFrameDecode_Release(frame); 540 541 pos.QuadPart = 0; 542 hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos); 543 ok(hr == S_OK, "IStream_Seek error %#x\n", hr); 544 ok(cur_pos.QuadPart > 4 && cur_pos.QuadPart < sizeof(tiff_1bpp_data), 545 "current stream pos is at %x/%x\n", cur_pos.u.LowPart, cur_pos.u.HighPart); 546 547 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability); 548 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); 549 550 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand); 551 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); 552 553 IWICBitmapDecoder_Release(decoder); 554 555 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); 556 todo_wine 557 ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "expected WINCODEC_ERR_COMPONENTNOTFOUND, got %#x\n", hr); 558 559 if (SUCCEEDED(hr)) 560 IWICBitmapDecoder_Release(decoder); 561 562 pos.QuadPart = 0; 563 hr = IStream_Seek(stream, pos, SEEK_SET, NULL); 564 ok(hr == S_OK, "IStream_Seek error %#x\n", hr); 565 566 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); 567 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); 568 569 frame_count = 0xdeadbeef; 570 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); 571 ok(hr == S_OK, "GetFrameCount error %#x\n", hr); 572 ok(frame_count == 1, "expected 1, got %u\n", frame_count); 573 574 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); 575 ok(hr == S_OK, "GetFrame error %#x\n", hr); 576 IWICBitmapFrameDecode_Release(frame); 577 578 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand); 579 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); 580 581 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability); 582 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); 583 584 IWICBitmapDecoder_Release(decoder); 585 IStream_Release(stream); 586 } 587 588 static void test_tiff_8bpp_alpha(void) 589 { 590 HRESULT hr; 591 IWICBitmapDecoder *decoder; 592 IWICBitmapFrameDecode *frame; 593 UINT frame_count, width, height, i; 594 double dpi_x, dpi_y; 595 IWICPalette *palette; 596 GUID format; 597 WICRect rc; 598 BYTE data[16]; 599 static const BYTE expected_data[16] = { 0x11,0x11,0x11,0x22,0x33,0x33,0x33,0x44, 600 0x55,0x55,0x55,0x66,0x77,0x77,0x77,0x88 }; 601 602 hr = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha), &decoder); 603 ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); 604 if (hr != S_OK) return; 605 606 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); 607 ok(hr == S_OK, "GetFrameCount error %#x\n", hr); 608 ok(frame_count == 1, "expected 1, got %u\n", frame_count); 609 610 EXPECT_REF(decoder, 1); 611 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); 612 ok(hr == S_OK, "GetFrame error %#x\n", hr); 613 EXPECT_REF(decoder, 2); 614 IWICBitmapDecoder_Release(decoder); 615 616 hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); 617 ok(hr == S_OK, "GetSize error %#x\n", hr); 618 ok(width == 2, "expected 2, got %u\n", width); 619 ok(height == 2, "expected 2, got %u\n", height); 620 621 hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); 622 ok(hr == S_OK, "GetResolution error %#x\n", hr); 623 ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x); 624 ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y); 625 626 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); 627 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); 628 ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppPBGRA), 629 "got wrong format %s\n", wine_dbgstr_guid(&format)); 630 631 hr = IWICImagingFactory_CreatePalette(factory, &palette); 632 ok(hr == S_OK, "CreatePalette error %#x\n", hr); 633 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); 634 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, 635 "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr); 636 IWICPalette_Release(palette); 637 638 rc.X = 0; 639 rc.Y = 0; 640 rc.Width = 2; 641 rc.Height = 2; 642 hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 8, sizeof(data), data); 643 ok(hr == S_OK, "CopyPixels error %#x\n", hr); 644 645 for (i = 0; i < sizeof(data); i++) 646 ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]); 647 648 IWICBitmapFrameDecode_Release(frame); 649 } 650 651 static void generate_tiff_palette(void *buf, unsigned count) 652 { 653 unsigned short *r, *g, *b; 654 unsigned i; 655 656 r = buf; 657 g = r + count; 658 b = g + count; 659 660 r[0] = 0x11 * 257; 661 g[0] = 0x22 * 257; 662 b[0] = 0x33 * 257; 663 r[1] = 0x44 * 257; 664 g[1] = 0x55 * 257; 665 b[1] = 0x66 * 257; 666 r[2] = 0x77 * 257; 667 g[2] = 0x88 * 257; 668 b[2] = 0x99 * 257; 669 r[3] = 0xa1 * 257; 670 g[3] = 0xb5 * 257; 671 b[3] = 0xff * 257; 672 673 for (i = 4; i < count; i++) 674 { 675 r[i] = i * 257; 676 g[i] = (i | 0x40) * 257; 677 b[i] = (i | 0x80) * 257; 678 } 679 } 680 681 static void test_tiff_8bpp_palette(void) 682 { 683 char buf[sizeof(tiff_8bpp_data)]; 684 HRESULT hr; 685 IWICBitmapDecoder *decoder; 686 IWICBitmapFrameDecode *frame; 687 IWICPalette *palette; 688 GUID format; 689 UINT count, ret; 690 WICColor color[256]; 691 692 memcpy(buf, &tiff_8bpp_data, sizeof(tiff_8bpp_data)); 693 generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_8bpp_data, palette_data), 256); 694 695 hr = create_decoder(buf, sizeof(buf), &decoder); 696 ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); 697 if (hr != S_OK) return; 698 699 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); 700 ok(hr == S_OK, "GetFrame error %#x\n", hr); 701 702 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); 703 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); 704 ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), 705 "expected GUID_WICPixelFormat8bppIndexed, got %s\n", wine_dbgstr_guid(&format)); 706 707 hr = IWICImagingFactory_CreatePalette(factory, &palette); 708 ok(hr == S_OK, "CreatePalette error %#x\n", hr); 709 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); 710 ok(hr == S_OK, "CopyPalette error %#x\n", hr); 711 712 hr = IWICPalette_GetColorCount(palette, &count); 713 ok(hr == S_OK, "GetColorCount error %#x\n", hr); 714 ok(count == 256, "expected 256, got %u\n", count); 715 716 hr = IWICPalette_GetColors(palette, 256, color, &ret); 717 ok(hr == S_OK, "GetColors error %#x\n", hr); 718 ok(ret == count, "expected %u, got %u\n", count, ret); 719 ok(color[0] == 0xff112233, "got %#x\n", color[0]); 720 ok(color[1] == 0xff445566, "got %#x\n", color[1]); 721 ok(color[2] == 0xff778899, "got %#x\n", color[2]); 722 ok(color[3] == 0xffa1b5ff, "got %#x\n", color[3]); 723 724 IWICPalette_Release(palette); 725 IWICBitmapFrameDecode_Release(frame); 726 IWICBitmapDecoder_Release(decoder); 727 } 728 729 static void test_tiff_resolution(void) 730 { 731 HRESULT hr; 732 IWICBitmapDecoder *decoder; 733 IWICBitmapFrameDecode *frame; 734 double dpi_x, dpi_y; 735 int i; 736 737 for (i = 0; i < ARRAY_SIZE(tiff_resolution_test_data); i++) 738 { 739 const struct tiff_resolution_test_data *test_data = &tiff_resolution_test_data[i]; 740 tiff_resolution_image_data.resx = test_data->resx; 741 tiff_resolution_image_data.resy = test_data->resy; 742 tiff_resolution_image_data.entry[12].value = test_data->resolution_unit; 743 744 hr = create_decoder(&tiff_resolution_image_data, sizeof(tiff_resolution_image_data), &decoder); 745 ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); 746 if (hr != S_OK) return; 747 748 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); 749 ok(hr == S_OK, "%d: GetFrame error %#x\n", i, hr); 750 751 hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); 752 ok(hr == S_OK, "%d: GetResolution error %#x\n", i, hr); 753 754 if (test_data->broken_dpi_x != 0) 755 { 756 ok(fabs(dpi_x - test_data->expected_dpi_x) < 0.01 || broken(fabs(dpi_x - test_data->broken_dpi_x) < 0.01), 757 "%d: x: expected %f or %f, got %f\n", i, test_data->expected_dpi_x, test_data->broken_dpi_x, dpi_x); 758 } 759 else 760 { 761 ok(fabs(dpi_x - test_data->expected_dpi_x) < 0.01, 762 "%d: x: expected %f, got %f\n", i, test_data->expected_dpi_x, dpi_x); 763 } 764 765 if (test_data->broken_dpi_y != 0) 766 { 767 ok(fabs(dpi_y - test_data->expected_dpi_y) < 0.01 || broken(fabs(dpi_y - test_data->broken_dpi_y) < 0.01), 768 "%d: y: expected %f or %f, got %f\n", i, test_data->expected_dpi_y, test_data->broken_dpi_y, dpi_y); 769 } 770 else 771 { 772 ok(fabs(dpi_y - test_data->expected_dpi_y) < 0.01, 773 "%d: y: expected %f, got %f\n", i, test_data->expected_dpi_y, dpi_y); 774 } 775 776 IWICBitmapFrameDecode_Release(frame); 777 IWICBitmapDecoder_Release(decoder); 778 } 779 } 780 781 static void test_tiff_24bpp(void) 782 { 783 HRESULT hr; 784 IWICBitmapDecoder *decoder; 785 IWICBitmapFrameDecode *frame; 786 UINT count, width, height, i, stride; 787 double dpi_x, dpi_y; 788 GUID format; 789 WICRect rc; 790 BYTE data[3]; 791 static const BYTE expected_data[] = { 0x33,0x22,0x11 }; 792 793 hr = create_decoder(&tiff_24bpp_data, sizeof(tiff_24bpp_data), &decoder); 794 ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); 795 if (hr != S_OK) return; 796 ok(decoder != NULL, "Failed to load TIFF image data\n"); 797 798 hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); 799 ok(hr == S_OK, "GetFrameCount error %#x\n", hr); 800 ok(count == 1, "got %u\n", count); 801 802 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); 803 ok(hr == S_OK, "GetFrame error %#x\n", hr); 804 805 hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); 806 ok(hr == S_OK, "GetSize error %#x\n", hr); 807 ok(width == 1, "got %u\n", width); 808 ok(height == 1, "got %u\n", height); 809 810 hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); 811 ok(hr == S_OK, "GetResolution error %#x\n", hr); 812 ok(dpi_x == 300.0, "got %f\n", dpi_x); 813 ok(dpi_y == 300.0, "got %f\n", dpi_y); 814 815 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); 816 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); 817 ok(IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR), 818 "got wrong format %s\n", wine_dbgstr_guid(&format)); 819 820 for (stride = 0; stride <= 32; stride++) 821 { 822 memset(data, 0, sizeof(data)); 823 rc.X = 0; 824 rc.Y = 0; 825 rc.Width = 1; 826 rc.Height = 1; 827 hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, stride, sizeof(data), data); 828 if (stride < 3) 829 ok(hr == E_INVALIDARG, "CopyPixels(%u) should fail: %#x\n", stride, hr); 830 else 831 { 832 ok(hr == S_OK, "CopyPixels(%u) error %#x\n", stride, hr); 833 834 for (i = 0; i < sizeof(data); i++) 835 ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]); 836 } 837 } 838 839 IWICBitmapFrameDecode_Release(frame); 840 IWICBitmapDecoder_Release(decoder); 841 } 842 843 #include "pshpack2.h" 844 static const struct tiff_1x1_data 845 { 846 USHORT byte_order; 847 USHORT version; 848 ULONG dir_offset; 849 USHORT number_of_entries; 850 struct IFD_entry entry[12]; 851 ULONG next_IFD; 852 struct IFD_rational res; 853 short palette_data[3][256]; 854 short bps_data[4]; 855 BYTE pixel_data[32]; 856 } tiff_1x1_data = 857 { 858 #ifdef WORDS_BIGENDIAN 859 'M' | 'M' << 8, 860 #else 861 'I' | 'I' << 8, 862 #endif 863 42, 864 FIELD_OFFSET(struct tiff_1x1_data, number_of_entries), 865 12, 866 { 867 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ 868 { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ 869 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ 870 { 0x102, IFD_SHORT, 3, FIELD_OFFSET(struct tiff_1x1_data, bps_data) }, /* BITSPERSAMPLE */ 871 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ 872 { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */ 873 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1x1_data, pixel_data) }, /* STRIPOFFSETS */ 874 { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */ 875 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, 876 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, 877 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ 878 { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */ 879 }, 880 0, 881 { 96, 1 }, 882 { { 0 } }, 883 { 8,8,8,0 }, 884 { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 } 885 }; 886 #include "poppack.h" 887 888 static UINT width_bytes(UINT width, UINT bpp) 889 { 890 return (width * bpp + 7) / 8; 891 } 892 893 static void test_color_formats(void) 894 { 895 struct bitmap_data 896 { 897 UINT bpp; 898 UINT width; 899 UINT height; 900 const WICPixelFormatGUID *format; 901 const BYTE *bits; 902 }; 903 static const BYTE bits_1bpsBGR[] = { 0,255,0,255,0,255,255,255,0,0,0,255,255,0,0,0,255,255,255,255,255,0,0,0,0,255,0,255,0,255 }; 904 static const struct bitmap_data data_1bpsBGR = 905 { 906 24, 10, 2, &GUID_WICPixelFormat24bppBGR, bits_1bpsBGR 907 }; 908 static const BYTE bits_4bpsBGR[] = { 204,85,85,136,187,51,0,85,85,85,0,68,0,102,0,136,0,119,0,153,0 }; 909 static const struct bitmap_data data_4bpsBGR = 910 { 911 24, 5, 2, &GUID_WICPixelFormat24bppBGR, bits_4bpsBGR 912 }; 913 static const BYTE bits_8bpsBGR[] = { 2,0,1,5,4,3,8,7,6 }; 914 static const struct bitmap_data data_8bpsBGR = 915 { 916 24, 3, 1, &GUID_WICPixelFormat24bppBGR, bits_8bpsBGR 917 }; 918 static const BYTE bits_48bppRGB[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; 919 static const struct bitmap_data data_48bppRGB = 920 { 921 48, 2, 1, &GUID_WICPixelFormat48bppRGB, bits_48bppRGB 922 }; 923 static const BYTE bits_1bpsBGRA[] = { 0,255,0,255,0,255,0,255,0,255,255,0,255,0,0,255,255,0,255,255,0,0,255,0,0,255,0,255,0,255,0,255,0,0,0,0,0,255,0,0 }; 924 static const struct bitmap_data data_1bpsBGRA = 925 { 926 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_1bpsBGRA 927 }; 928 static const BYTE bits_4bpsBGRA[] = { 204,85,85,51,85,136,187,85,0,68,0,85,0,102,0,119,0,136,0,153,0,0,0,17,0,34,0,51 }; 929 static const struct bitmap_data data_4bpsBGRA = 930 { 931 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_4bpsBGRA 932 }; 933 static const BYTE bits_8bpsBGRA[] = { 2,0,1,3,6,5,4,7,0,9,8,1,4,3,2,5 }; 934 static const struct bitmap_data data_8bpsBGRA = 935 { 936 32, 4, 1, &GUID_WICPixelFormat32bppBGRA, bits_8bpsBGRA 937 }; 938 static const BYTE bits_64bppRGBA[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; 939 static const struct bitmap_data data_64bppRGBA = 940 { 941 64, 2, 1, &GUID_WICPixelFormat64bppRGBA, bits_64bppRGBA 942 }; 943 static const BYTE bits_BlackWhite[] = { 85,195,184,85 }; 944 static const struct bitmap_data data_BlackWhite = 945 { 946 1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite 947 }; 948 static const BYTE bits_BlackWhite_xp[] = { 85,195,184,84 }; 949 static const struct bitmap_data data_BlackWhite_xp = 950 { 951 1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite_xp 952 }; 953 static const BYTE bits_4bppGray[] = { 85,195,184,85 }; 954 static const struct bitmap_data data_4bppGray = 955 { 956 4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray 957 }; 958 static const BYTE bits_4bppGray_xp[] = { 85,195,184,80 }; 959 static const struct bitmap_data data_4bppGray_xp = 960 { 961 4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray_xp 962 }; 963 static const BYTE bits_8bppGray[] = { 1,0,2,3,4,5,6,7,8,9 }; 964 static const struct bitmap_data data_8bppGray = 965 { 966 8, 10, 1, &GUID_WICPixelFormat8bppGray, bits_8bppGray 967 }; 968 static const BYTE bits_16bppGray[] = { 1,0,2,3,4,5 }; 969 static const struct bitmap_data data_16bppGray = 970 { 971 16, 3, 1, &GUID_WICPixelFormat16bppGray, bits_16bppGray 972 }; 973 static const BYTE bits_32bppGrayFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; 974 static const struct bitmap_data data_32bppGrayFloat = 975 { 976 32, 3, 1, &GUID_WICPixelFormat32bppGrayFloat, bits_32bppGrayFloat 977 }; 978 #if 0 /* FIXME */ 979 static const BYTE bits_96bpp3Channels[] = { 0 }; 980 static const struct bitmap_data data_96bpp3Channels = 981 { 982 64, 1, 1, &GUID_WICPixelFormat96bpp3Channels, bits_96bpp3Channels 983 }; 984 #endif 985 static const BYTE bits_128bppRGBAFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; 986 static const struct bitmap_data data_128bppRGBAFloat = 987 { 988 128, 1, 1, &GUID_WICPixelFormat128bppRGBAFloat, bits_128bppRGBAFloat 989 }; 990 static const BYTE bits_1bppIndexed[] = { 85,195,184,85 }; 991 static const struct bitmap_data data_1bppIndexed = 992 { 993 1, 32, 1, &GUID_WICPixelFormat1bppIndexed, bits_1bppIndexed 994 }; 995 static const BYTE bits_4bppIndexed[] = { 85,195,184,85 }; 996 static const struct bitmap_data data_4bppIndexed = 997 { 998 4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed 999 }; 1000 static const BYTE bits_4bppIndexed_xp[] = { 85,195,184,80 }; 1001 static const struct bitmap_data data_4bppIndexed_xp = 1002 { 1003 4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed_xp 1004 }; 1005 static const BYTE bits_8bppIndexed[] = { 1,0,2,3,4,5,6,7,8,9 }; 1006 static const struct bitmap_data data_8bppIndexed = 1007 { 1008 8, 3, 1, &GUID_WICPixelFormat8bppIndexed, bits_8bppIndexed 1009 }; 1010 static const BYTE bits_32bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; 1011 static const struct bitmap_data data_32bppCMYK = 1012 { 1013 32, 3, 1, &GUID_WICPixelFormat32bppCMYK, bits_32bppCMYK 1014 }; 1015 static const BYTE bits_64bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; 1016 static const struct bitmap_data data_64bppCMYK = 1017 { 1018 64, 2, 1, &GUID_WICPixelFormat64bppCMYK, bits_64bppCMYK 1019 }; 1020 static const struct 1021 { 1022 int photometric; /* PhotometricInterpretation */ 1023 int samples; /* SamplesPerPixel */ 1024 int bps; /* BitsPerSample */ 1025 const struct bitmap_data *data; 1026 const struct bitmap_data *alt_data; 1027 } td[] = 1028 { 1029 /* 2 - RGB */ 1030 { 2, 3, 1, &data_1bpsBGR }, 1031 { 2, 3, 4, &data_4bpsBGR }, 1032 { 2, 3, 8, &data_8bpsBGR }, 1033 { 2, 3, 16, &data_48bppRGB }, 1034 { 2, 3, 24, NULL }, 1035 #if 0 /* FIXME */ 1036 { 2, 3, 32, &data_96bpp3Channels }, 1037 #endif 1038 { 2, 4, 1, &data_1bpsBGRA }, 1039 { 2, 4, 4, &data_4bpsBGRA }, 1040 { 2, 4, 8, &data_8bpsBGRA }, 1041 { 2, 4, 16, &data_64bppRGBA }, 1042 { 2, 4, 24, NULL }, 1043 { 2, 4, 32, &data_128bppRGBAFloat }, 1044 /* 1 - BlackIsZero (Bilevel) */ 1045 { 1, 1, 1, &data_BlackWhite, &data_BlackWhite_xp }, 1046 { 1, 1, 4, &data_4bppGray, &data_4bppGray_xp }, 1047 { 1, 1, 8, &data_8bppGray }, 1048 { 1, 1, 16, &data_16bppGray }, 1049 { 1, 1, 24, NULL }, 1050 { 1, 1, 32, &data_32bppGrayFloat }, 1051 /* 3 - Palette Color */ 1052 { 3, 1, 1, &data_1bppIndexed }, 1053 { 3, 1, 4, &data_4bppIndexed, &data_4bppIndexed_xp }, 1054 { 3, 1, 8, &data_8bppIndexed }, 1055 #if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */ 1056 { 3, 1, 16, &data_8bppIndexed }, 1057 { 3, 1, 24, &data_8bppIndexed }, 1058 { 3, 1, 32, &data_8bppIndexed }, 1059 #endif 1060 /* 5 - Separated */ 1061 { 5, 4, 1, NULL }, 1062 { 5, 4, 4, NULL }, 1063 { 5, 4, 8, &data_32bppCMYK }, 1064 { 5, 4, 16, &data_64bppCMYK }, 1065 { 5, 4, 24, NULL }, 1066 { 5, 4, 32, NULL }, 1067 }; 1068 BYTE buf[sizeof(tiff_1x1_data)]; 1069 BYTE pixels[256]; 1070 HRESULT hr; 1071 IWICBitmapDecoder *decoder; 1072 IWICBitmapFrameDecode *frame; 1073 GUID format; 1074 UINT count, i, bpp, channels, ret; 1075 BOOL trasparency; 1076 struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL; 1077 struct IFD_entry *tag_width = NULL, *tag_height = NULL; 1078 short *bps; 1079 1080 memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data)); 1081 generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_1x1_data, palette_data), 256); 1082 1083 count = *(short *)(buf + tiff_1x1_data.dir_offset); 1084 tag = (struct IFD_entry *)(buf + tiff_1x1_data.dir_offset + sizeof(short)); 1085 1086 /* verify the TIFF structure */ 1087 for (i = 0; i < count; i++) 1088 { 1089 if (tag[i].id == 0x100) /* ImageWidth */ 1090 tag_width = &tag[i]; 1091 else if (tag[i].id == 0x101) /* ImageLength */ 1092 tag_height = &tag[i]; 1093 else if (tag[i].id == 0x102) /* BitsPerSample */ 1094 tag_bps = &tag[i]; 1095 else if (tag[i].id == 0x106) /* PhotometricInterpretation */ 1096 tag_photo = &tag[i]; 1097 else if (tag[i].id == 0x115) /* SamplesPerPixel */ 1098 tag_samples = &tag[i]; 1099 else if (tag[i].id == 0x140) /* ColorMap */ 1100 tag_colormap = &tag[i]; 1101 } 1102 1103 ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n"); 1104 if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return; 1105 1106 ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n"); 1107 bps = (short *)(buf + tag_bps->value); 1108 ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0, 1109 "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]); 1110 1111 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) 1112 { 1113 if (td[i].data) 1114 { 1115 bpp = td[i].samples * td[i].bps; 1116 if (winetest_debug > 1) 1117 trace("samples %u, bps %u, bpp %u, width %u => width_bytes %u\n", td[i].samples, td[i].bps, bpp, 1118 td[i].data->width, width_bytes(td[i].data->width, bpp)); 1119 tag_width->value = td[i].data->width; 1120 tag_height->value = td[i].data->height; 1121 } 1122 else 1123 { 1124 tag_width->value = 1; 1125 tag_height->value = 1; 1126 } 1127 1128 tag_colormap->count = (1 << td[i].bps) * 3; 1129 1130 if (td[i].bps < 8) 1131 { 1132 buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 0x55; 1133 buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0xc3; 1134 buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 0xb8; 1135 buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 0x55; 1136 } 1137 else 1138 { 1139 buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 1; 1140 buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0; 1141 buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 2; 1142 buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 3; 1143 } 1144 1145 tag_photo->value = td[i].photometric; 1146 tag_bps->count = td[i].samples; 1147 tag_samples->value = td[i].samples; 1148 1149 if (td[i].samples == 1) 1150 tag_bps->value = td[i].bps; 1151 else if (td[i].samples == 2) 1152 tag_bps->value = MAKELONG(td[i].bps, td[i].bps); 1153 else if (td[i].samples == 3) 1154 { 1155 tag_bps->value = (BYTE *)bps - buf; 1156 bps[0] = bps[1] = bps[2] = td[i].bps; 1157 } 1158 else if (td[i].samples == 4) 1159 { 1160 tag_bps->value = (BYTE *)bps - buf; 1161 bps[0] = bps[1] = bps[2] = bps[3] = td[i].bps; 1162 } 1163 else 1164 { 1165 ok(0, "%u: unsupported samples count %d\n", i, td[i].samples); 1166 continue; 1167 } 1168 1169 hr = create_decoder(buf, sizeof(buf), &decoder); 1170 if (!td[i].data) 1171 { 1172 ok(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_COMPONENTNOTFOUND /* win8+ */ || WINCODEC_ERR_BADIMAGE /* XP */, 1173 "%u: (%d,%d,%d) wrong error %#x\n", i, td[i].photometric, td[i].samples, td[i].bps, hr); 1174 if (hr == S_OK) 1175 { 1176 IWICBitmapDecoder_Release(decoder); 1177 dump_tiff(buf); 1178 } 1179 continue; 1180 } 1181 else 1182 ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_BADIMAGE) /* XP */, 1183 "%u: failed to load TIFF image data (%d,%d,%d) %#x\n", 1184 i, td[i].photometric, td[i].samples, td[i].bps, hr); 1185 if (hr != S_OK) continue; 1186 1187 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); 1188 ok(hr == S_OK, "%u: GetFrame error %#x\n", i, hr); 1189 1190 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); 1191 ok(hr == S_OK, "%u: GetPixelFormat error %#x\n", i, hr); 1192 ok(IsEqualGUID(&format, td[i].data->format), 1193 "%u (%d,%d,%d): expected %s, got %s\n", 1194 i, td[i].photometric, td[i].samples, td[i].bps, 1195 wine_dbgstr_guid(td[i].data->format), wine_dbgstr_guid(&format)); 1196 1197 trasparency = (td[i].photometric == 2 && td[i].samples == 4); /* for XP */ 1198 hr = get_pixelformat_info(&format, &bpp, &channels, &trasparency); 1199 ok(hr == S_OK, "%u: get_pixelformat_bpp error %#x\n", i, hr); 1200 ok(bpp == td[i].data->bpp, "%u: expected %u, got %u\n", i, td[i].data->bpp, bpp); 1201 ok(channels == td[i].samples, "%u: expected %u, got %u\n", i, td[i].samples, channels); 1202 ok(trasparency == (td[i].photometric == 2 && td[i].samples == 4), "%u: got %u\n", i, trasparency); 1203 1204 memset(pixels, 0, sizeof(pixels)); 1205 hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, width_bytes(td[i].data->width, bpp), sizeof(pixels), pixels); 1206 ok(hr == S_OK, "%u: CopyPixels error %#x\n", i, hr); 1207 ret = memcmp(pixels, td[i].data->bits, width_bytes(td[i].data->width, bpp)); 1208 if (ret && td[i].alt_data) 1209 ret = memcmp(pixels, td[i].alt_data->bits, width_bytes(td[i].data->width, bpp)); 1210 ok(ret == 0, "%u: (%d,%d,%d) wrong pixel data\n", i, td[i].photometric, td[i].samples, td[i].bps); 1211 if (ret) 1212 { 1213 UINT j, n = width_bytes(td[i].data->width, bpp); 1214 for (j = 0; j < n; j++) 1215 printf("%u%s", pixels[j], (j + 1) < n ? "," : "\n"); 1216 } 1217 1218 IWICBitmapFrameDecode_Release(frame); 1219 IWICBitmapDecoder_Release(decoder); 1220 } 1221 } 1222 1223 static void test_tiff_4bps_bgra(void) 1224 { 1225 HRESULT hr; 1226 IWICBitmapDecoder *decoder; 1227 IWICBitmapFrameDecode *frame; 1228 UINT frame_count, width, height, i; 1229 double dpi_x, dpi_y; 1230 IWICPalette *palette; 1231 GUID format; 1232 WICRect rc; 1233 BYTE data[24]; 1234 static const BYTE expected_data[24] = { 0,0,0,0xff, 0xff,0,0,0, 0xff,0,0,0xff, 1235 0,0xff,0,0, 0xff,0xff,0,0xff, 0xff,0xff,0xff,0 }; 1236 1237 hr = create_decoder(&tiff_4bps_bgra, sizeof(tiff_4bps_bgra), &decoder); 1238 ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); 1239 if (hr != S_OK) return; 1240 1241 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); 1242 ok(hr == S_OK, "GetFrameCount error %#x\n", hr); 1243 ok(frame_count == 1, "expected 1, got %u\n", frame_count); 1244 1245 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); 1246 ok(hr == S_OK, "GetFrame error %#x\n", hr); 1247 1248 hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); 1249 ok(hr == S_OK, "GetSize error %#x\n", hr); 1250 ok(width == 3, "got %u\n", width); 1251 ok(height == 2, "got %u\n", height); 1252 1253 hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); 1254 ok(hr == S_OK, "GetResolution error %#x\n", hr); 1255 ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x); 1256 ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y); 1257 1258 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); 1259 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); 1260 ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA), 1261 "got wrong format %s\n", wine_dbgstr_guid(&format)); 1262 1263 hr = IWICImagingFactory_CreatePalette(factory, &palette); 1264 ok(hr == S_OK, "CreatePalette error %#x\n", hr); 1265 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); 1266 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, 1267 "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr); 1268 IWICPalette_Release(palette); 1269 1270 memset(data, 0xaa, sizeof(data)); 1271 rc.X = 0; 1272 rc.Y = 0; 1273 rc.Width = 3; 1274 rc.Height = 2; 1275 hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 12, sizeof(data), data); 1276 ok(hr == S_OK, "CopyPixels error %#x\n", hr); 1277 1278 for (i = 0; i < sizeof(data); i++) 1279 ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]); 1280 1281 IWICBitmapFrameDecode_Release(frame); 1282 IWICBitmapDecoder_Release(decoder); 1283 } 1284 1285 START_TEST(tiffformat) 1286 { 1287 HRESULT hr; 1288 1289 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 1290 1291 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, 1292 &IID_IWICImagingFactory, (void **)&factory); 1293 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); 1294 if (FAILED(hr)) return; 1295 1296 test_tiff_4bps_bgra(); 1297 test_color_formats(); 1298 test_tiff_1bpp_palette(); 1299 test_tiff_8bpp_palette(); 1300 test_QueryCapability(); 1301 test_tiff_8bpp_alpha(); 1302 test_tiff_resolution(); 1303 test_tiff_24bpp(); 1304 1305 IWICImagingFactory_Release(factory); 1306 CoUninitialize(); 1307 } 1308