ReactOS  0.4.14-dev-608-gd495a4f
tiffformat.c
Go to the documentation of this file.
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 {
64 };
65 
66 static const struct tiff_1bpp_data
67 {
72  struct IFD_entry entry[13];
74  struct IFD_rational res;
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 {
112  struct IFD_entry entry[15];
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 {
154  struct IFD_entry entry[14];
157  short palette_data[3][256];
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 {
198  /* if != 0: values for different behavior of some Windows versions */
199  double broken_dpi_x;
200  double broken_dpi_y;
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 
225 {
230  struct IFD_entry entry[13];
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 {
272  struct IFD_entry entry[13];
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 #include "poppack.h"
306 
308 
309 static IStream *create_stream(const void *data, int data_size)
310 {
311  HRESULT hr;
312  IStream *stream;
313  HGLOBAL hdata;
314  void *locked_data;
315 
316  hdata = GlobalAlloc(GMEM_MOVEABLE, data_size);
317  ok(hdata != 0, "GlobalAlloc failed\n");
318  if (!hdata) return NULL;
319 
320  locked_data = GlobalLock(hdata);
321  memcpy(locked_data, data, data_size);
322  GlobalUnlock(hdata);
323 
324  hr = CreateStreamOnHGlobal(hdata, TRUE, &stream);
325  ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr);
326 
327  return stream;
328 }
329 
330 static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitmapDecoder **decoder)
331 {
332  HGLOBAL hmem;
333  BYTE *data;
334  HRESULT hr;
335  IStream *stream;
336  GUID format;
337  LONG refcount;
338 
339  *decoder = NULL;
340 
341  hmem = GlobalAlloc(0, image_size);
342  data = GlobalLock(hmem);
343  memcpy(data, image_data, image_size);
344  GlobalUnlock(hmem);
345 
346  hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
347  ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
348 
349  hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, decoder);
350  if (hr == S_OK)
351  {
352  hr = IWICBitmapDecoder_GetContainerFormat(*decoder, &format);
353  ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
354  ok(IsEqualGUID(&format, &GUID_ContainerFormatTiff),
355  "wrong container format %s\n", wine_dbgstr_guid(&format));
356 
357  refcount = IStream_Release(stream);
358  ok(refcount > 0, "expected stream refcount > 0\n");
359  }
360 
361  return hr;
362 }
363 
364 static HRESULT get_pixelformat_info(const GUID *format, UINT *bpp, UINT *channels, BOOL *trasparency)
365 {
366  HRESULT hr;
368  IWICPixelFormatInfo2 *formatinfo;
369 
370  hr = IWICImagingFactory_CreateComponentInfo(factory, format, &info);
371  ok(hr == S_OK, "CreateComponentInfo(%s) error %#x\n", wine_dbgstr_guid(format), hr);
372  if (hr == S_OK)
373  {
374  hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void **)&formatinfo);
375  if (hr == S_OK)
376  {
377  hr = IWICPixelFormatInfo2_SupportsTransparency(formatinfo, trasparency);
378  ok(hr == S_OK, "SupportsTransparency error %#x\n", hr);
379  IWICPixelFormatInfo2_Release(formatinfo);
380  }
381  hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void **)&formatinfo);
382  if (hr == S_OK)
383  {
384  hr = IWICPixelFormatInfo2_GetBitsPerPixel(formatinfo, bpp);
385  ok(hr == S_OK, "GetBitsPerPixel error %#x\n", hr);
386  hr = IWICPixelFormatInfo2_GetChannelCount(formatinfo, channels);
387  ok(hr == S_OK, "GetChannelCount error %#x\n", hr);
388  IWICPixelFormatInfo2_Release(formatinfo);
389  }
390  IWICComponentInfo_Release(info);
391  }
392  return hr;
393 }
394 
395 static void dump_tiff(void *buf)
396 {
397  UINT count, i;
398  struct tiff_1bpp_data *tiff;
399  struct IFD_entry *tag;
400 
401  tiff = buf;
402  count = *(short *)((char *)tiff + tiff->dir_offset);
403  tag = (struct IFD_entry *)((char *)tiff + tiff->dir_offset + sizeof(short));
404 
405  for (i = 0; i < count; i++)
406  {
407  printf("tag %u: id %04x, type %04x, count %u, value %d",
408  i, tag[i].id, tag[i].type, tag[i].count, tag[i].value);
409  if (tag[i].id == 0x102 && tag[i].count > 2)
410  {
411  short *bps = (short *)((char *)tiff + tag[i].value);
412  printf(" (%d,%d,%d,%d)\n", bps[0], bps[1], bps[2], bps[3]);
413  }
414  else
415  printf("\n");
416  }
417 }
418 
419 static void test_tiff_1bpp_palette(void)
420 {
421  HRESULT hr;
422  IWICBitmapDecoder *decoder;
423  IWICBitmapFrameDecode *frame;
425  GUID format;
426 
427  hr = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data), &decoder);
428  ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
429  if (hr != S_OK) return;
430 
431  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
432  ok(hr == S_OK, "GetFrame error %#x\n", hr);
433 
434  hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
435  ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
436  ok(IsEqualGUID(&format, &GUID_WICPixelFormatBlackWhite),
437  "got wrong format %s\n", wine_dbgstr_guid(&format));
438 
439  hr = IWICImagingFactory_CreatePalette(factory, &palette);
440  ok(hr == S_OK, "CreatePalette error %#x\n", hr);
441  hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
443  "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr);
444 
445  IWICPalette_Release(palette);
446  IWICBitmapFrameDecode_Release(frame);
447  IWICBitmapDecoder_Release(decoder);
448 }
449 
450 static void test_QueryCapability(void)
451 {
452  HRESULT hr;
453  IStream *stream;
454  IWICBitmapDecoder *decoder;
455  IWICBitmapFrameDecode *frame;
456  static const DWORD exp_caps = WICBitmapDecoderCapabilityCanDecodeAllImages |
459  static const DWORD exp_caps_xp = WICBitmapDecoderCapabilityCanDecodeAllImages |
461  DWORD capability;
463  ULARGE_INTEGER cur_pos;
464  UINT frame_count;
465 
467  if (!stream) return;
468 
469  hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatTiff, NULL, &decoder);
470  ok(hr == S_OK, "CreateDecoder error %#x\n", hr);
471  if (FAILED(hr)) return;
472 
473  frame_count = 0xdeadbeef;
474  hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
475  ok(hr == S_OK || broken(hr == E_POINTER) /* XP */, "GetFrameCount error %#x\n", hr);
476  ok(frame_count == 0, "expected 0, got %u\n", frame_count);
477 
478  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
479  ok(hr == WINCODEC_ERR_FRAMEMISSING || broken(hr == E_POINTER) /* XP */, "expected WINCODEC_ERR_FRAMEMISSING, got %#x\n", hr);
480 
481  pos.QuadPart = 4;
482  hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
483  ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
484 
485  capability = 0xdeadbeef;
486  hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
487  ok(hr == S_OK, "QueryCapability error %#x\n", hr);
488  ok(capability == exp_caps || capability == exp_caps_xp,
489  "expected %#x, got %#x\n", exp_caps, capability);
490 
491  frame_count = 0xdeadbeef;
492  hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
493  ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
494  ok(frame_count == 1, "expected 1, got %u\n", frame_count);
495 
496  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
497  ok(hr == S_OK, "GetFrame error %#x\n", hr);
498  IWICBitmapFrameDecode_Release(frame);
499 
500  pos.QuadPart = 0;
501  hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos);
502  ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
503  ok(cur_pos.QuadPart > 4 && cur_pos.QuadPart < sizeof(tiff_1bpp_data),
504  "current stream pos is at %x/%x\n", cur_pos.u.LowPart, cur_pos.u.HighPart);
505 
506  hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
507  ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
508 
509  hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
510  ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
511 
512  IWICBitmapDecoder_Release(decoder);
513 
514  hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
515 todo_wine
516  ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "expected WINCODEC_ERR_COMPONENTNOTFOUND, got %#x\n", hr);
517 
518  if (SUCCEEDED(hr))
519  IWICBitmapDecoder_Release(decoder);
520 
521  pos.QuadPart = 0;
522  hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
523  ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
524 
525  hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
526  ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
527 
528  frame_count = 0xdeadbeef;
529  hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
530  ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
531  ok(frame_count == 1, "expected 1, got %u\n", frame_count);
532 
533  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
534  ok(hr == S_OK, "GetFrame error %#x\n", hr);
535  IWICBitmapFrameDecode_Release(frame);
536 
537  hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
538  ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
539 
540  hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
541  ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
542 
543  IWICBitmapDecoder_Release(decoder);
544  IStream_Release(stream);
545 }
546 
547 static void test_tiff_8bpp_alpha(void)
548 {
549  HRESULT hr;
550  IWICBitmapDecoder *decoder;
551  IWICBitmapFrameDecode *frame;
552  UINT frame_count, width, height, i;
553  double dpi_x, dpi_y;
555  GUID format;
556  WICRect rc;
557  BYTE data[16];
558  static const BYTE expected_data[16] = { 0x11,0x11,0x11,0x22,0x33,0x33,0x33,0x44,
559  0x55,0x55,0x55,0x66,0x77,0x77,0x77,0x88 };
560 
561  hr = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha), &decoder);
562  ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
563  if (hr != S_OK) return;
564 
565  hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
566  ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
567  ok(frame_count == 1, "expected 1, got %u\n", frame_count);
568 
569  EXPECT_REF(decoder, 1);
570  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
571  ok(hr == S_OK, "GetFrame error %#x\n", hr);
572  EXPECT_REF(decoder, 2);
573  IWICBitmapDecoder_Release(decoder);
574 
575  hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
576  ok(hr == S_OK, "GetSize error %#x\n", hr);
577  ok(width == 2, "expected 2, got %u\n", width);
578  ok(height == 2, "expected 2, got %u\n", height);
579 
580  hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y);
581  ok(hr == S_OK, "GetResolution error %#x\n", hr);
582  ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x);
583  ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y);
584 
585  hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
586  ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
587  ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppPBGRA),
588  "got wrong format %s\n", wine_dbgstr_guid(&format));
589 
590  hr = IWICImagingFactory_CreatePalette(factory, &palette);
591  ok(hr == S_OK, "CreatePalette error %#x\n", hr);
592  hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
594  "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr);
595  IWICPalette_Release(palette);
596 
597  rc.X = 0;
598  rc.Y = 0;
599  rc.Width = 2;
600  rc.Height = 2;
601  hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 8, sizeof(data), data);
602  ok(hr == S_OK, "CopyPixels error %#x\n", hr);
603 
604  for (i = 0; i < sizeof(data); i++)
605  ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]);
606 
607  IWICBitmapFrameDecode_Release(frame);
608 }
609 
610 static void generate_tiff_palette(void *buf, unsigned count)
611 {
612  unsigned short *r, *g, *b;
613  unsigned i;
614 
615  r = buf;
616  g = r + count;
617  b = g + count;
618 
619  r[0] = 0x11 * 257;
620  g[0] = 0x22 * 257;
621  b[0] = 0x33 * 257;
622  r[1] = 0x44 * 257;
623  g[1] = 0x55 * 257;
624  b[1] = 0x66 * 257;
625  r[2] = 0x77 * 257;
626  g[2] = 0x88 * 257;
627  b[2] = 0x99 * 257;
628  r[3] = 0xa1 * 257;
629  g[3] = 0xb5 * 257;
630  b[3] = 0xff * 257;
631 
632  for (i = 4; i < count; i++)
633  {
634  r[i] = i * 257;
635  g[i] = (i | 0x40) * 257;
636  b[i] = (i | 0x80) * 257;
637  }
638 }
639 
640 static void test_tiff_8bpp_palette(void)
641 {
642  char buf[sizeof(tiff_8bpp_data)];
643  HRESULT hr;
644  IWICBitmapDecoder *decoder;
645  IWICBitmapFrameDecode *frame;
647  GUID format;
648  UINT count, ret;
649  WICColor color[256];
650 
652  generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_8bpp_data, palette_data), 256);
653 
654  hr = create_decoder(buf, sizeof(buf), &decoder);
655  ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
656  if (hr != S_OK) return;
657 
658  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
659  ok(hr == S_OK, "GetFrame error %#x\n", hr);
660 
661  hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
662  ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
663  ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
664  "expected GUID_WICPixelFormat8bppIndexed, got %s\n", wine_dbgstr_guid(&format));
665 
666  hr = IWICImagingFactory_CreatePalette(factory, &palette);
667  ok(hr == S_OK, "CreatePalette error %#x\n", hr);
668  hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
669  ok(hr == S_OK, "CopyPalette error %#x\n", hr);
670 
671  hr = IWICPalette_GetColorCount(palette, &count);
672  ok(hr == S_OK, "GetColorCount error %#x\n", hr);
673  ok(count == 256, "expected 256, got %u\n", count);
674 
675  hr = IWICPalette_GetColors(palette, 256, color, &ret);
676  ok(hr == S_OK, "GetColors error %#x\n", hr);
677  ok(ret == count, "expected %u, got %u\n", count, ret);
678  ok(color[0] == 0xff112233, "got %#x\n", color[0]);
679  ok(color[1] == 0xff445566, "got %#x\n", color[1]);
680  ok(color[2] == 0xff778899, "got %#x\n", color[2]);
681  ok(color[3] == 0xffa1b5ff, "got %#x\n", color[3]);
682 
683  IWICPalette_Release(palette);
684  IWICBitmapFrameDecode_Release(frame);
685  IWICBitmapDecoder_Release(decoder);
686 }
687 
688 static void test_tiff_resolution(void)
689 {
690  HRESULT hr;
691  IWICBitmapDecoder *decoder;
692  IWICBitmapFrameDecode *frame;
693  double dpi_x, dpi_y;
694  int i;
695 
696  for (i = 0; i < ARRAY_SIZE(tiff_resolution_test_data); i++)
697  {
701  tiff_resolution_image_data.entry[12].value = test_data->resolution_unit;
702 
704  ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
705  if (hr != S_OK) return;
706 
707  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
708  ok(hr == S_OK, "%d: GetFrame error %#x\n", i, hr);
709 
710  hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y);
711  ok(hr == S_OK, "%d: GetResolution error %#x\n", i, hr);
712 
713  if (test_data->broken_dpi_x != 0)
714  {
715  ok(fabs(dpi_x - test_data->expected_dpi_x) < 0.01 || broken(fabs(dpi_x - test_data->broken_dpi_x) < 0.01),
716  "%d: x: expected %f or %f, got %f\n", i, test_data->expected_dpi_x, test_data->broken_dpi_x, dpi_x);
717  }
718  else
719  {
720  ok(fabs(dpi_x - test_data->expected_dpi_x) < 0.01,
721  "%d: x: expected %f, got %f\n", i, test_data->expected_dpi_x, dpi_x);
722  }
723 
724  if (test_data->broken_dpi_y != 0)
725  {
726  ok(fabs(dpi_y - test_data->expected_dpi_y) < 0.01 || broken(fabs(dpi_y - test_data->broken_dpi_y) < 0.01),
727  "%d: y: expected %f or %f, got %f\n", i, test_data->expected_dpi_y, test_data->broken_dpi_y, dpi_y);
728  }
729  else
730  {
731  ok(fabs(dpi_y - test_data->expected_dpi_y) < 0.01,
732  "%d: y: expected %f, got %f\n", i, test_data->expected_dpi_y, dpi_y);
733  }
734 
735  IWICBitmapFrameDecode_Release(frame);
736  IWICBitmapDecoder_Release(decoder);
737  }
738 }
739 
740 static void test_tiff_24bpp(void)
741 {
742  HRESULT hr;
743  IWICBitmapDecoder *decoder;
744  IWICBitmapFrameDecode *frame;
746  double dpi_x, dpi_y;
747  GUID format;
748  WICRect rc;
749  BYTE data[3];
750  static const BYTE expected_data[] = { 0x33,0x22,0x11 };
751 
752  hr = create_decoder(&tiff_24bpp_data, sizeof(tiff_24bpp_data), &decoder);
753  ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
754  if (hr != S_OK) return;
755  ok(decoder != NULL, "Failed to load TIFF image data\n");
756 
757  hr = IWICBitmapDecoder_GetFrameCount(decoder, &count);
758  ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
759  ok(count == 1, "got %u\n", count);
760 
761  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
762  ok(hr == S_OK, "GetFrame error %#x\n", hr);
763 
764  hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
765  ok(hr == S_OK, "GetSize error %#x\n", hr);
766  ok(width == 1, "got %u\n", width);
767  ok(height == 1, "got %u\n", height);
768 
769  hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y);
770  ok(hr == S_OK, "GetResolution error %#x\n", hr);
771  ok(dpi_x == 300.0, "got %f\n", dpi_x);
772  ok(dpi_y == 300.0, "got %f\n", dpi_y);
773 
774  hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
775  ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
776  ok(IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR),
777  "got wrong format %s\n", wine_dbgstr_guid(&format));
778 
779  for (stride = 0; stride <= 32; stride++)
780  {
781  memset(data, 0, sizeof(data));
782  rc.X = 0;
783  rc.Y = 0;
784  rc.Width = 1;
785  rc.Height = 1;
786  hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, stride, sizeof(data), data);
787  if (stride < 3)
788  ok(hr == E_INVALIDARG, "CopyPixels(%u) should fail: %#x\n", stride, hr);
789  else
790  {
791  ok(hr == S_OK, "CopyPixels(%u) error %#x\n", stride, hr);
792 
793  for (i = 0; i < sizeof(data); i++)
794  ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]);
795  }
796  }
797 
798  IWICBitmapFrameDecode_Release(frame);
799  IWICBitmapDecoder_Release(decoder);
800 }
801 
802 #include "pshpack2.h"
803 static const struct tiff_1x1_data
804 {
806  USHORT version;
809  struct IFD_entry entry[12];
810  ULONG next_IFD;
811  struct IFD_rational res;
812  short palette_data[3][256];
813  short bps_data[4];
814  BYTE pixel_data[32];
815 } tiff_1x1_data =
816 {
817 #ifdef WORDS_BIGENDIAN
818  'M' | 'M' << 8,
819 #else
820  'I' | 'I' << 8,
821 #endif
822  42,
823  FIELD_OFFSET(struct tiff_1x1_data, number_of_entries),
824  12,
825  {
826  { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
827  { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */
828  { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
829  { 0x102, IFD_SHORT, 3, FIELD_OFFSET(struct tiff_1x1_data, bps_data) }, /* BITSPERSAMPLE */
830  { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
831  { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */
832  { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1x1_data, pixel_data) }, /* STRIPOFFSETS */
833  { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */
834  { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) },
835  { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) },
836  { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
837  { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */
838  },
839  0,
840  { 96, 1 },
841  { { 0 } },
842  { 8,8,8,0 },
843  { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }
844 };
845 #include "poppack.h"
846 
848 {
849  return (width * bpp + 7) / 8;
850 }
851 
852 static void test_color_formats(void)
853 {
854  struct bitmap_data
855  {
856  UINT bpp;
857  UINT width;
858  UINT height;
859  const WICPixelFormatGUID *format;
860  const BYTE *bits;
861  };
862  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 };
863  static const struct bitmap_data data_1bpsBGR =
864  {
865  24, 10, 2, &GUID_WICPixelFormat24bppBGR, bits_1bpsBGR
866  };
867  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 };
868  static const struct bitmap_data data_4bpsBGR =
869  {
870  24, 5, 2, &GUID_WICPixelFormat24bppBGR, bits_4bpsBGR
871  };
872  static const BYTE bits_8bpsBGR[] = { 2,0,1,5,4,3,8,7,6 };
873  static const struct bitmap_data data_8bpsBGR =
874  {
875  24, 3, 1, &GUID_WICPixelFormat24bppBGR, bits_8bpsBGR
876  };
877  static const BYTE bits_48bppRGB[] = { 1,0,2,3,4,5,6,7,8,9,0,1 };
878  static const struct bitmap_data data_48bppRGB =
879  {
880  48, 2, 1, &GUID_WICPixelFormat48bppRGB, bits_48bppRGB
881  };
882  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 };
883  static const struct bitmap_data data_1bpsBGRA =
884  {
885  32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_1bpsBGRA
886  };
887  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 };
888  static const struct bitmap_data data_4bpsBGRA =
889  {
890  32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_4bpsBGRA
891  };
892  static const BYTE bits_8bpsBGRA[] = { 2,0,1,3,6,5,4,7,0,9,8,1,4,3,2,5 };
893  static const struct bitmap_data data_8bpsBGRA =
894  {
895  32, 4, 1, &GUID_WICPixelFormat32bppBGRA, bits_8bpsBGRA
896  };
897  static const BYTE bits_64bppRGBA[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 };
898  static const struct bitmap_data data_64bppRGBA =
899  {
900  64, 2, 1, &GUID_WICPixelFormat64bppRGBA, bits_64bppRGBA
901  };
902  static const BYTE bits_BlackWhite[] = { 85,195,184,85 };
903  static const struct bitmap_data data_BlackWhite =
904  {
905  1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite
906  };
907  static const BYTE bits_BlackWhite_xp[] = { 85,195,184,84 };
908  static const struct bitmap_data data_BlackWhite_xp =
909  {
910  1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite_xp
911  };
912  static const BYTE bits_4bppGray[] = { 85,195,184,85 };
913  static const struct bitmap_data data_4bppGray =
914  {
915  4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray
916  };
917  static const BYTE bits_4bppGray_xp[] = { 85,195,184,80 };
918  static const struct bitmap_data data_4bppGray_xp =
919  {
920  4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray_xp
921  };
922  static const BYTE bits_8bppGray[] = { 1,0,2,3,4,5,6,7,8,9 };
923  static const struct bitmap_data data_8bppGray =
924  {
925  8, 10, 1, &GUID_WICPixelFormat8bppGray, bits_8bppGray
926  };
927  static const BYTE bits_16bppGray[] = { 1,0,2,3,4,5 };
928  static const struct bitmap_data data_16bppGray =
929  {
930  16, 3, 1, &GUID_WICPixelFormat16bppGray, bits_16bppGray
931  };
932  static const BYTE bits_32bppGrayFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1 };
933  static const struct bitmap_data data_32bppGrayFloat =
934  {
935  32, 3, 1, &GUID_WICPixelFormat32bppGrayFloat, bits_32bppGrayFloat
936  };
937 #if 0 /* FIXME */
938  static const BYTE bits_96bpp3Channels[] = { 0 };
939  static const struct bitmap_data data_96bpp3Channels =
940  {
941  64, 1, 1, &GUID_WICPixelFormat96bpp3Channels, bits_96bpp3Channels
942  };
943 #endif
944  static const BYTE bits_128bppRGBAFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 };
945  static const struct bitmap_data data_128bppRGBAFloat =
946  {
947  128, 1, 1, &GUID_WICPixelFormat128bppRGBAFloat, bits_128bppRGBAFloat
948  };
949  static const BYTE bits_1bppIndexed[] = { 85,195,184,85 };
950  static const struct bitmap_data data_1bppIndexed =
951  {
952  1, 32, 1, &GUID_WICPixelFormat1bppIndexed, bits_1bppIndexed
953  };
954  static const BYTE bits_4bppIndexed[] = { 85,195,184,85 };
955  static const struct bitmap_data data_4bppIndexed =
956  {
957  4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed
958  };
959  static const BYTE bits_4bppIndexed_xp[] = { 85,195,184,80 };
960  static const struct bitmap_data data_4bppIndexed_xp =
961  {
962  4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed_xp
963  };
964  static const BYTE bits_8bppIndexed[] = { 1,0,2,3,4,5,6,7,8,9 };
965  static const struct bitmap_data data_8bppIndexed =
966  {
967  8, 3, 1, &GUID_WICPixelFormat8bppIndexed, bits_8bppIndexed
968  };
969  static const BYTE bits_32bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1 };
970  static const struct bitmap_data data_32bppCMYK =
971  {
972  32, 3, 1, &GUID_WICPixelFormat32bppCMYK, bits_32bppCMYK
973  };
974  static const BYTE bits_64bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 };
975  static const struct bitmap_data data_64bppCMYK =
976  {
977  64, 2, 1, &GUID_WICPixelFormat64bppCMYK, bits_64bppCMYK
978  };
979  static const struct
980  {
981  int photometric; /* PhotometricInterpretation */
982  int samples; /* SamplesPerPixel */
983  int bps; /* BitsPerSample */
984  const struct bitmap_data *data;
985  const struct bitmap_data *alt_data;
986  } td[] =
987  {
988  /* 2 - RGB */
989  { 2, 3, 1, &data_1bpsBGR },
990  { 2, 3, 4, &data_4bpsBGR },
991  { 2, 3, 8, &data_8bpsBGR },
992  { 2, 3, 16, &data_48bppRGB },
993  { 2, 3, 24, NULL },
994 #if 0 /* FIXME */
995  { 2, 3, 32, &data_96bpp3Channels },
996 #endif
997  { 2, 4, 1, &data_1bpsBGRA },
998  { 2, 4, 4, &data_4bpsBGRA },
999  { 2, 4, 8, &data_8bpsBGRA },
1000  { 2, 4, 16, &data_64bppRGBA },
1001  { 2, 4, 24, NULL },
1002  { 2, 4, 32, &data_128bppRGBAFloat },
1003  /* 1 - BlackIsZero (Bilevel) */
1004  { 1, 1, 1, &data_BlackWhite, &data_BlackWhite_xp },
1005  { 1, 1, 4, &data_4bppGray, &data_4bppGray_xp },
1006  { 1, 1, 8, &data_8bppGray },
1007  { 1, 1, 16, &data_16bppGray },
1008  { 1, 1, 24, NULL },
1009  { 1, 1, 32, &data_32bppGrayFloat },
1010  /* 3 - Palette Color */
1011  { 3, 1, 1, &data_1bppIndexed },
1012  { 3, 1, 4, &data_4bppIndexed, &data_4bppIndexed_xp },
1013  { 3, 1, 8, &data_8bppIndexed },
1014 #if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */
1015  { 3, 1, 16, &data_8bppIndexed },
1016  { 3, 1, 24, &data_8bppIndexed },
1017  { 3, 1, 32, &data_8bppIndexed },
1018 #endif
1019  /* 5 - Separated */
1020  { 5, 4, 1, NULL },
1021  { 5, 4, 4, NULL },
1022  { 5, 4, 8, &data_32bppCMYK },
1023  { 5, 4, 16, &data_64bppCMYK },
1024  { 5, 4, 24, NULL },
1025  { 5, 4, 32, NULL },
1026  };
1027  BYTE buf[sizeof(tiff_1x1_data)];
1028  BYTE pixels[256];
1029  HRESULT hr;
1030  IWICBitmapDecoder *decoder;
1031  IWICBitmapFrameDecode *frame;
1032  GUID format;
1033  UINT count, i, bpp, channels, ret;
1034  BOOL trasparency;
1035  struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL;
1036  struct IFD_entry *tag_width = NULL, *tag_height = NULL;
1037  short *bps;
1038 
1039  memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data));
1040  generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_1x1_data, palette_data), 256);
1041 
1042  count = *(short *)(buf + tiff_1x1_data.dir_offset);
1043  tag = (struct IFD_entry *)(buf + tiff_1x1_data.dir_offset + sizeof(short));
1044 
1045  /* verify the TIFF structure */
1046  for (i = 0; i < count; i++)
1047  {
1048  if (tag[i].id == 0x100) /* ImageWidth */
1049  tag_width = &tag[i];
1050  else if (tag[i].id == 0x101) /* ImageLength */
1051  tag_height = &tag[i];
1052  else if (tag[i].id == 0x102) /* BitsPerSample */
1053  tag_bps = &tag[i];
1054  else if (tag[i].id == 0x106) /* PhotometricInterpretation */
1055  tag_photo = &tag[i];
1056  else if (tag[i].id == 0x115) /* SamplesPerPixel */
1057  tag_samples = &tag[i];
1058  else if (tag[i].id == 0x140) /* ColorMap */
1059  tag_colormap = &tag[i];
1060  }
1061 
1062  ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n");
1063  if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return;
1064 
1065  ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n");
1066  bps = (short *)(buf + tag_bps->value);
1067  ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0,
1068  "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]);
1069 
1070  for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
1071  {
1072  if (td[i].data)
1073  {
1074  bpp = td[i].samples * td[i].bps;
1075  if (winetest_debug > 1)
1076  trace("samples %u, bps %u, bpp %u, width %u => width_bytes %u\n", td[i].samples, td[i].bps, bpp,
1077  td[i].data->width, width_bytes(td[i].data->width, bpp));
1078  tag_width->value = td[i].data->width;
1079  tag_height->value = td[i].data->height;
1080  }
1081  else
1082  {
1083  tag_width->value = 1;
1084  tag_height->value = 1;
1085  }
1086 
1087  tag_colormap->count = (1 << td[i].bps) * 3;
1088 
1089  if (td[i].bps < 8)
1090  {
1091  buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 0x55;
1092  buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0xc3;
1093  buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 0xb8;
1094  buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 0x55;
1095  }
1096  else
1097  {
1098  buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 1;
1099  buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0;
1100  buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 2;
1101  buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 3;
1102  }
1103 
1104  tag_photo->value = td[i].photometric;
1105  tag_bps->count = td[i].samples;
1106  tag_samples->value = td[i].samples;
1107 
1108  if (td[i].samples == 1)
1109  tag_bps->value = td[i].bps;
1110  else if (td[i].samples == 2)
1111  tag_bps->value = MAKELONG(td[i].bps, td[i].bps);
1112  else if (td[i].samples == 3)
1113  {
1114  tag_bps->value = (BYTE *)bps - buf;
1115  bps[0] = bps[1] = bps[2] = td[i].bps;
1116  }
1117  else if (td[i].samples == 4)
1118  {
1119  tag_bps->value = (BYTE *)bps - buf;
1120  bps[0] = bps[1] = bps[2] = bps[3] = td[i].bps;
1121  }
1122  else
1123  {
1124  ok(0, "%u: unsupported samples count %d\n", i, td[i].samples);
1125  continue;
1126  }
1127 
1128  hr = create_decoder(buf, sizeof(buf), &decoder);
1129  if (!td[i].data)
1130  {
1132  "%u: (%d,%d,%d) wrong error %#x\n", i, td[i].photometric, td[i].samples, td[i].bps, hr);
1133  if (hr == S_OK)
1134  {
1135  IWICBitmapDecoder_Release(decoder);
1136  dump_tiff(buf);
1137  }
1138  continue;
1139  }
1140  else
1142  "%u: failed to load TIFF image data (%d,%d,%d) %#x\n",
1143  i, td[i].photometric, td[i].samples, td[i].bps, hr);
1144  if (hr != S_OK) continue;
1145 
1146  hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
1147  ok(hr == S_OK, "%u: GetFrame error %#x\n", i, hr);
1148 
1149  hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
1150  ok(hr == S_OK, "%u: GetPixelFormat error %#x\n", i, hr);
1151  ok(IsEqualGUID(&format, td[i].data->format),
1152  "%u (%d,%d,%d): expected %s, got %s\n",
1153  i, td[i].photometric, td[i].samples, td[i].bps,
1154  wine_dbgstr_guid(td[i].data->format), wine_dbgstr_guid(&format));
1155 
1156  trasparency = (td[i].photometric == 2 && td[i].samples == 4); /* for XP */
1157  hr = get_pixelformat_info(&format, &bpp, &channels, &trasparency);
1158  ok(hr == S_OK, "%u: get_pixelformat_bpp error %#x\n", i, hr);
1159  ok(bpp == td[i].data->bpp, "%u: expected %u, got %u\n", i, td[i].data->bpp, bpp);
1160  ok(channels == td[i].samples, "%u: expected %u, got %u\n", i, td[i].samples, channels);
1161  ok(trasparency == (td[i].photometric == 2 && td[i].samples == 4), "%u: got %u\n", i, trasparency);
1162 
1163  memset(pixels, 0, sizeof(pixels));
1164  hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, width_bytes(td[i].data->width, bpp), sizeof(pixels), pixels);
1165  ok(hr == S_OK, "%u: CopyPixels error %#x\n", i, hr);
1166  ret = memcmp(pixels, td[i].data->bits, width_bytes(td[i].data->width, bpp));
1167  if (ret && td[i].alt_data)
1168  ret = memcmp(pixels, td[i].alt_data->bits, width_bytes(td[i].data->width, bpp));
1169  ok(ret == 0, "%u: (%d,%d,%d) wrong pixel data\n", i, td[i].photometric, td[i].samples, td[i].bps);
1170  if (ret)
1171  {
1172  UINT j, n = width_bytes(td[i].data->width, bpp);
1173  for (j = 0; j < n; j++)
1174  printf("%u%s", pixels[j], (j + 1) < n ? "," : "\n");
1175  }
1176 
1177  IWICBitmapFrameDecode_Release(frame);
1178  IWICBitmapDecoder_Release(decoder);
1179  }
1180 }
1181 
1182 START_TEST(tiffformat)
1183 {
1184  HRESULT hr;
1185 
1187 
1188  hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1189  &IID_IWICImagingFactory, (void **)&factory);
1190  ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
1191  if (FAILED(hr)) return;
1192 
1199  test_tiff_24bpp();
1200 
1201  IWICImagingFactory_Release(factory);
1202  CoUninitialize();
1203 }
USHORT number_of_entries
Definition: image.c:5508
struct IFD_entry entry[13]
Definition: tiffformat.c:230
struct IFD_entry entry[13]
Definition: tiffformat.c:72
GLsizei samples
Definition: glext.h:7006
#define SEEK_CUR
Definition: util.h:63
GLint GLint GLsizei width
Definition: gl.h:1546
ULONG count
UINT bpp
Definition: converter.c:37
USHORT number_of_entries
Definition: tiffformat.c:111
#define TRUE
Definition: types.h:120
USHORT version
Definition: image.c:5506
struct IFD_rational resy
Definition: tiffformat.c:233
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
short palette_data[3][256]
Definition: tiffformat.c:157
static IWICImagingFactory * factory
Definition: tiffformat.c:307
struct IFD_entry entry[13]
Definition: tiffformat.c:272
static void dump_tiff(void *buf)
Definition: tiffformat.c:395
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
USHORT byte_order
Definition: tiffformat.c:150
HRESULT hr
Definition: shlfolder.c:183
struct IFD_rational resx
Definition: tiffformat.c:232
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static const struct tiff_8bpp_data tiff_8bpp_data
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
struct IFD_rational resy
Definition: tiffformat.c:194
GLuint GLuint GLsizei count
Definition: gl.h:1545
BYTE pixel_data[4]
Definition: tiffformat.c:75
static void test_tiff_resolution(void)
Definition: tiffformat.c:688
USHORT number_of_entries
Definition: tiffformat.c:153
GLdouble n
Definition: glext.h:7729
static const struct tiff_1x1_data tiff_1x1_data
USHORT byte_order
Definition: tiffformat.c:268
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
const char * wine_dbgstr_guid(const GUID *guid)
Definition: ecma_167.h:138
int This channels
Definition: rdpsnd_libao.c:37
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
struct IFD_entry entry[12]
Definition: image.c:5509
ULONG dir_offset
Definition: image.c:5507
USHORT version
Definition: tiffformat.c:151
#define IFD_LONG
Definition: tiffformat.c:41
static const float bits_32bppGrayFloat[]
Definition: converter.c:519
int winetest_debug
Definition: send.c:47
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
Definition: tiffiop.h:115
struct _test_info info[]
Definition: SetCursorPos.c:19
#define EXPECT_REF(obj, ref)
Definition: tiffformat.c:29
BYTE pixel_data[32]
Definition: image.c:5514
LONG denominator
Definition: image.c:3499
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
BYTE pixel_data[8]
Definition: tiffformat.c:115
unsigned int BOOL
Definition: ntddk_ex.h:94
static HRESULT get_pixelformat_info(const GUID *format, UINT *bpp, UINT *channels, BOOL *trasparency)
Definition: tiffformat.c:364
long LONG
Definition: pedump.c:60
Definition: main.c:438
GLuint color
Definition: glext.h:6243
short SHORT
Definition: pedump.c:59
SHORT id
static void test_QueryCapability(void)
Definition: tiffformat.c:450
GLenum GLint ref
Definition: glext.h:6028
ULONG dir_offset
Definition: tiffformat.c:70
#define E_INVALIDARG
Definition: ddrawi.h:101
#define MAKELONG(a, b)
Definition: typedefs.h:248
#define WINCODEC_ERR_PALETTEUNAVAILABLE
Definition: winerror.h:3284
smooth NULL
Definition: ftsmooth.c:416
short bps_data[4]
Definition: image.c:5513
#define IFD_SHORT
Definition: tiffformat.c:40
static const WCHAR tiff[]
USHORT number_of_entries
Definition: tiffformat.c:71
static void test_tiff_8bpp_alpha(void)
Definition: tiffformat.c:547
Definition: parser.c:48
INT Height
Definition: wincodec.idl:239
BYTE pixel_data[4]
Definition: tiffformat.c:158
static const BYTE bits_8bppGray[]
Definition: converter.c:539
static void _expect_ref(IUnknown *obj, ULONG ref, int line)
Definition: tiffformat.c:30
LONG value
#define b
Definition: ke_i.h:79
static void generate_tiff_palette(void *buf, unsigned count)
Definition: tiffformat.c:610
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
UINT height
Definition: converter.c:40
static void test_tiff_1bpp_palette(void)
Definition: tiffformat.c:419
#define SEEK_SET
Definition: jmemansi.c:26
GLboolean GLboolean g
Definition: glext.h:6204
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLsizei stride
Definition: glext.h:5848
struct IFD_entry entry[15]
Definition: tiffformat.c:112
#define trace
Definition: atltest.h:70
LONG HRESULT
Definition: typedefs.h:77
short palette_data[3][256]
Definition: image.c:5512
unsigned long DWORD
Definition: ntddk_ex.h:95
USHORT byte_order
Definition: tiffformat.c:68
static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitmapDecoder **decoder)
Definition: tiffformat.c:330
static const BYTE bits_64bppRGBA[]
Definition: converter.c:494
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
UINT width
Definition: converter.c:39
int ret
#define WINCODEC_ERR_FRAMEMISSING
Definition: winerror.h:3293
static UINT width_bytes(UINT width, UINT bpp)
Definition: tiffformat.c:847
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define todo_wine
Definition: test.h:163
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
START_TEST(tiffformat)
Definition: tiffformat.c:1182
USHORT version
Definition: tiffformat.c:69
static HPALETTE palette
Definition: clipboard.c:1345
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
#define broken(x)
Definition: _sntprintf.h:21
USHORT byte_order
Definition: image.c:5505
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
USHORT byte_order
Definition: tiffformat.c:108
#define WINCODEC_ERR_WRONGSTATE
Definition: winerror.h:3273
#define S_OK
Definition: intsafe.h:59
static void test_tiff_8bpp_palette(void)
Definition: tiffformat.c:640
unsigned short USHORT
Definition: pedump.c:61
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define ARRAY_SIZE(a)
Definition: main.h:24
#define IFD_RATIONAL
Definition: tiffformat.c:42
#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT
Definition: winerror.h:3299
#define ok(value,...)
Definition: atltest.h:57
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl.h:1546
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
const BYTE * bits
Definition: converter.c:38
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
BYTE pixel_data[3]
Definition: tiffformat.c:275
LONG numerator
Definition: image.c:3498
INT Width
Definition: wincodec.idl:238
#define WINCODEC_ERR_COMPONENTNOTFOUND
Definition: winerror.h:3288
USHORT number_of_entries
Definition: tiffformat.c:271
GLuint res
Definition: glext.h:9613
#define WINCODEC_ERR_BADIMAGE
Definition: winerror.h:3291
unsigned int ULONG
Definition: retypes.h:1
struct IFD_rational resx
Definition: tiffformat.c:193
const WICPixelFormatGUID * format
Definition: converter.c:36
DWORD bpp
Definition: surface.c:181
ULONG dir_offset
Definition: tiffformat.c:152
#define E_POINTER
Definition: winerror.h:2365
struct IFD_entry entry[14]
Definition: tiffformat.c:154
static IStream * create_stream(const void *data, int data_size)
Definition: tiffformat.c:309
#define memset(x, y, z)
Definition: compat.h:39
UINT32 WICColor
Definition: wincodec.idl:250
static void test_tiff_24bpp(void)
Definition: tiffformat.c:740
struct _ULARGE_INTEGER::@3769 u
const struct bitmap_data * alt_data
Definition: converter.c:43
static void test_color_formats(void)
Definition: tiffformat.c:852
#define GMEM_MOVEABLE
Definition: winbase.h:291
ULONG next_IFD
Definition: image.c:5510
ULONG next_IFD
Definition: tiffformat.c:73
#define SUCCEEDED(hr)
Definition: intsafe.h:57
SHORT type
#define ok_(x1, x2)
Definition: atltest.h:61
#define printf
Definition: config.h:203
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
Definition: mipmap.c:4856
char * tag
Definition: main.c:59