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 #include "poppack.h"
306 
307 static IWICImagingFactory *factory;
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;
367     IWICComponentInfo *info;
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;
424     IWICPalette *palette;
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);
442     ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE,
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 |
457                                   WICBitmapDecoderCapabilityCanDecodeSomeImages |
458                                   WICBitmapDecoderCapabilityCanEnumerateMetadata;
459     static const DWORD exp_caps_xp = WICBitmapDecoderCapabilityCanDecodeAllImages |
460                                      WICBitmapDecoderCapabilityCanDecodeSomeImages;
461     DWORD capability;
462     LARGE_INTEGER pos;
463     ULARGE_INTEGER cur_pos;
464     UINT frame_count;
465 
466     stream = create_stream(&tiff_1bpp_data, sizeof(tiff_1bpp_data));
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;
554     IWICPalette *palette;
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);
593     ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE,
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;
646     IWICPalette *palette;
647     GUID format;
648     UINT count, ret;
649     WICColor color[256];
650 
651     memcpy(buf, &tiff_8bpp_data, sizeof(tiff_8bpp_data));
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     {
698         const struct tiff_resolution_test_data *test_data = &tiff_resolution_test_data[i];
699         tiff_resolution_image_data.resx = test_data->resx;
700         tiff_resolution_image_data.resy = test_data->resy;
701         tiff_resolution_image_data.entry[12].value = test_data->resolution_unit;
702 
703         hr = create_decoder(&tiff_resolution_image_data, sizeof(tiff_resolution_image_data), &decoder);
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;
745     UINT count, width, height, i, stride;
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, "got %#x\n", hr);
754     ok(decoder != NULL, "Failed to load TIFF image data\n");
755 
756     hr = IWICBitmapDecoder_GetFrameCount(decoder, &count);
757     ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
758     ok(count == 1, "got %u\n", count);
759 
760     hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
761     ok(hr == S_OK, "GetFrame error %#x\n", hr);
762 
763     hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
764     ok(hr == S_OK, "GetSize error %#x\n", hr);
765     ok(width == 1, "got %u\n", width);
766     ok(height == 1, "got %u\n", height);
767 
768     hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y);
769     ok(hr == S_OK, "GetResolution error %#x\n", hr);
770     ok(dpi_x == 300.0, "got %f\n", dpi_x);
771     ok(dpi_y == 300.0, "got %f\n", dpi_y);
772 
773     hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
774     ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
775     ok(IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR),
776        "got wrong format %s\n", wine_dbgstr_guid(&format));
777 
778     for (stride = 0; stride <= 32; stride++)
779     {
780         memset(data, 0, sizeof(data));
781         rc.X = 0;
782         rc.Y = 0;
783         rc.Width = 1;
784         rc.Height = 1;
785         hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, stride, sizeof(data), data);
786         if (stride < 3)
787             ok(hr == E_INVALIDARG, "CopyPixels(%u) should fail: %#x\n", stride, hr);
788         else
789         {
790             ok(hr == S_OK, "CopyPixels(%u) error %#x\n", stride, hr);
791 
792             for (i = 0; i < sizeof(data); i++)
793                 ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]);
794         }
795     }
796 
797     IWICBitmapFrameDecode_Release(frame);
798     IWICBitmapDecoder_Release(decoder);
799 }
800 
801 #include "pshpack2.h"
802 static const struct tiff_1x1_data
803 {
804     USHORT byte_order;
805     USHORT version;
806     ULONG  dir_offset;
807     USHORT number_of_entries;
808     struct IFD_entry entry[12];
809     ULONG next_IFD;
810     struct IFD_rational res;
811     short palette_data[3][256];
812     short bps_data[4];
813     BYTE pixel_data[32];
814 } tiff_1x1_data =
815 {
816 #ifdef WORDS_BIGENDIAN
817     'M' | 'M' << 8,
818 #else
819     'I' | 'I' << 8,
820 #endif
821     42,
822     FIELD_OFFSET(struct tiff_1x1_data, number_of_entries),
823     12,
824     {
825         { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
826         { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */
827         { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
828         { 0x102, IFD_SHORT, 3, FIELD_OFFSET(struct tiff_1x1_data, bps_data) }, /* BITSPERSAMPLE */
829         { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
830         { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */
831         { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1x1_data, pixel_data) }, /* STRIPOFFSETS */
832         { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */
833         { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) },
834         { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) },
835         { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
836         { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */
837     },
838     0,
839     { 96, 1 },
840     { { 0 } },
841     { 8,8,8,0 },
842     { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }
843 };
844 #include "poppack.h"
845 
846 static UINT width_bytes(UINT width, UINT bpp)
847 {
848     return (width * bpp + 7) / 8;
849 }
850 
851 static void test_color_formats(void)
852 {
853     struct bitmap_data
854     {
855         UINT bpp;
856         UINT width;
857         UINT height;
858         const WICPixelFormatGUID *format;
859         const BYTE *bits;
860     };
861     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 };
862     static const struct bitmap_data data_1bpsBGR =
863     {
864         24, 10, 2, &GUID_WICPixelFormat24bppBGR, bits_1bpsBGR
865     };
866     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 };
867     static const struct bitmap_data data_4bpsBGR =
868     {
869         24, 5, 2, &GUID_WICPixelFormat24bppBGR, bits_4bpsBGR
870     };
871     static const BYTE bits_8bpsBGR[] = { 2,0,1,5,4,3,8,7,6 };
872     static const struct bitmap_data data_8bpsBGR =
873     {
874         24, 3, 1, &GUID_WICPixelFormat24bppBGR, bits_8bpsBGR
875     };
876     static const BYTE bits_48bppRGB[] = { 1,0,2,3,4,5,6,7,8,9,0,1 };
877     static const struct bitmap_data data_48bppRGB =
878     {
879         48, 2, 1, &GUID_WICPixelFormat48bppRGB, bits_48bppRGB
880     };
881     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 };
882     static const struct bitmap_data data_1bpsBGRA =
883     {
884         32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_1bpsBGRA
885     };
886     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 };
887     static const struct bitmap_data data_4bpsBGRA =
888     {
889         32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_4bpsBGRA
890     };
891     static const BYTE bits_8bpsBGRA[] = { 2,0,1,3,6,5,4,7,0,9,8,1,4,3,2,5 };
892     static const struct bitmap_data data_8bpsBGRA =
893     {
894         32, 4, 1, &GUID_WICPixelFormat32bppBGRA, bits_8bpsBGRA
895     };
896     static const BYTE bits_64bppRGBA[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 };
897     static const struct bitmap_data data_64bppRGBA =
898     {
899         64, 2, 1, &GUID_WICPixelFormat64bppRGBA, bits_64bppRGBA
900     };
901     static const BYTE bits_BlackWhite[] = { 85,195,184,85 };
902     static const struct bitmap_data data_BlackWhite =
903     {
904         1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite
905     };
906     static const BYTE bits_BlackWhite_xp[] = { 85,195,184,84 };
907     static const struct bitmap_data data_BlackWhite_xp =
908     {
909         1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite_xp
910     };
911     static const BYTE bits_4bppGray[] = { 85,195,184,85 };
912     static const struct bitmap_data data_4bppGray =
913     {
914         4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray
915     };
916     static const BYTE bits_4bppGray_xp[] = { 85,195,184,80 };
917     static const struct bitmap_data data_4bppGray_xp =
918     {
919         4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray_xp
920     };
921     static const BYTE bits_8bppGray[] = { 1,0,2,3,4,5,6,7,8,9 };
922     static const struct bitmap_data data_8bppGray =
923     {
924         8, 10, 1, &GUID_WICPixelFormat8bppGray, bits_8bppGray
925     };
926     static const BYTE bits_16bppGray[] = { 1,0,2,3,4,5 };
927     static const struct bitmap_data data_16bppGray =
928     {
929         16, 3, 1, &GUID_WICPixelFormat16bppGray, bits_16bppGray
930     };
931     static const BYTE bits_32bppGrayFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1 };
932     static const struct bitmap_data data_32bppGrayFloat =
933     {
934         32, 3, 1, &GUID_WICPixelFormat32bppGrayFloat, bits_32bppGrayFloat
935     };
936 #if 0 /* FIXME */
937     static const BYTE bits_96bpp3Channels[] = { 0 };
938     static const struct bitmap_data data_96bpp3Channels =
939     {
940         64, 1, 1, &GUID_WICPixelFormat96bpp3Channels, bits_96bpp3Channels
941     };
942 #endif
943     static const BYTE bits_128bppRGBAFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 };
944     static const struct bitmap_data data_128bppRGBAFloat =
945     {
946         128, 1, 1, &GUID_WICPixelFormat128bppRGBAFloat, bits_128bppRGBAFloat
947     };
948     static const BYTE bits_1bppIndexed[] = { 85,195,184,85 };
949     static const struct bitmap_data data_1bppIndexed =
950     {
951         1, 32, 1, &GUID_WICPixelFormat1bppIndexed, bits_1bppIndexed
952     };
953     static const BYTE bits_4bppIndexed[] = { 85,195,184,85 };
954     static const struct bitmap_data data_4bppIndexed =
955     {
956         4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed
957     };
958     static const BYTE bits_4bppIndexed_xp[] = { 85,195,184,80 };
959     static const struct bitmap_data data_4bppIndexed_xp =
960     {
961         4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed_xp
962     };
963     static const BYTE bits_8bppIndexed[] = { 1,0,2,3,4,5,6,7,8,9 };
964     static const struct bitmap_data data_8bppIndexed =
965     {
966         8, 3, 1, &GUID_WICPixelFormat8bppIndexed, bits_8bppIndexed
967     };
968     static const BYTE bits_32bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1 };
969     static const struct bitmap_data data_32bppCMYK =
970     {
971         32, 3, 1, &GUID_WICPixelFormat32bppCMYK, bits_32bppCMYK
972     };
973     static const BYTE bits_64bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 };
974     static const struct bitmap_data data_64bppCMYK =
975     {
976         64, 2, 1, &GUID_WICPixelFormat64bppCMYK, bits_64bppCMYK
977     };
978     static const struct
979     {
980         int photometric; /* PhotometricInterpretation */
981         int samples; /* SamplesPerPixel */
982         int bps; /* BitsPerSample */
983         const struct bitmap_data *data;
984         const struct bitmap_data *alt_data;
985     } td[] =
986     {
987         /* 2 - RGB */
988         { 2, 3, 1, &data_1bpsBGR },
989         { 2, 3, 4, &data_4bpsBGR },
990         { 2, 3, 8, &data_8bpsBGR },
991         { 2, 3, 16, &data_48bppRGB },
992         { 2, 3, 24, NULL },
993 #if 0 /* FIXME */
994         { 2, 3, 32, &data_96bpp3Channels },
995 #endif
996         { 2, 4, 1, &data_1bpsBGRA },
997         { 2, 4, 4, &data_4bpsBGRA },
998         { 2, 4, 8, &data_8bpsBGRA },
999         { 2, 4, 16, &data_64bppRGBA },
1000         { 2, 4, 24, NULL },
1001         { 2, 4, 32, &data_128bppRGBAFloat },
1002         /* 1 - BlackIsZero (Bilevel) */
1003         { 1, 1, 1, &data_BlackWhite, &data_BlackWhite_xp },
1004         { 1, 1, 4, &data_4bppGray, &data_4bppGray_xp },
1005         { 1, 1, 8, &data_8bppGray },
1006         { 1, 1, 16, &data_16bppGray },
1007         { 1, 1, 24, NULL },
1008         { 1, 1, 32, &data_32bppGrayFloat },
1009         /* 3 - Palette Color */
1010         { 3, 1, 1, &data_1bppIndexed },
1011         { 3, 1, 4, &data_4bppIndexed, &data_4bppIndexed_xp },
1012         { 3, 1, 8, &data_8bppIndexed },
1013 #if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */
1014         { 3, 1, 16, &data_8bppIndexed },
1015         { 3, 1, 24, &data_8bppIndexed },
1016         { 3, 1, 32, &data_8bppIndexed },
1017 #endif
1018         /* 5 - Separated */
1019         { 5, 4, 1, NULL },
1020         { 5, 4, 4, NULL },
1021         { 5, 4, 8, &data_32bppCMYK },
1022         { 5, 4, 16, &data_64bppCMYK },
1023         { 5, 4, 24, NULL },
1024         { 5, 4, 32, NULL },
1025     };
1026     BYTE buf[sizeof(tiff_1x1_data)];
1027     BYTE pixels[256];
1028     HRESULT hr;
1029     IWICBitmapDecoder *decoder;
1030     IWICBitmapFrameDecode *frame;
1031     GUID format;
1032     UINT count, i, bpp, channels, ret;
1033     BOOL trasparency;
1034     struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL;
1035     struct IFD_entry *tag_width = NULL, *tag_height = NULL;
1036     short *bps;
1037 
1038     memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data));
1039     generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_1x1_data, palette_data), 256);
1040 
1041     count = *(short *)(buf + tiff_1x1_data.dir_offset);
1042     tag = (struct IFD_entry *)(buf + tiff_1x1_data.dir_offset + sizeof(short));
1043 
1044     /* verify the TIFF structure */
1045     for (i = 0; i < count; i++)
1046     {
1047         if (tag[i].id == 0x100) /* ImageWidth */
1048             tag_width = &tag[i];
1049         else if (tag[i].id == 0x101) /* ImageLength */
1050             tag_height = &tag[i];
1051         else if (tag[i].id == 0x102) /* BitsPerSample */
1052             tag_bps = &tag[i];
1053         else if (tag[i].id == 0x106) /* PhotometricInterpretation */
1054             tag_photo = &tag[i];
1055         else if (tag[i].id == 0x115) /* SamplesPerPixel */
1056             tag_samples = &tag[i];
1057         else if (tag[i].id == 0x140) /* ColorMap */
1058             tag_colormap = &tag[i];
1059     }
1060 
1061     ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n");
1062     if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return;
1063 
1064     ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n");
1065     bps = (short *)(buf + tag_bps->value);
1066     ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0,
1067        "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]);
1068 
1069     for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
1070     {
1071         if (td[i].data)
1072         {
1073             bpp = td[i].samples * td[i].bps;
1074             if (winetest_debug > 1)
1075                 trace("samples %u, bps %u, bpp %u, width %u => width_bytes %u\n", td[i].samples, td[i].bps, bpp,
1076                       td[i].data->width, width_bytes(td[i].data->width, bpp));
1077             tag_width->value = td[i].data->width;
1078             tag_height->value = td[i].data->height;
1079         }
1080         else
1081         {
1082             tag_width->value = 1;
1083             tag_height->value = 1;
1084         }
1085 
1086         tag_colormap->count = (1 << td[i].bps) * 3;
1087 
1088         if (td[i].bps < 8)
1089         {
1090             buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 0x55;
1091             buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0xc3;
1092             buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 0xb8;
1093             buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 0x55;
1094         }
1095         else
1096         {
1097             buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 1;
1098             buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0;
1099             buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 2;
1100             buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 3;
1101         }
1102 
1103         tag_photo->value = td[i].photometric;
1104         tag_bps->count = td[i].samples;
1105         tag_samples->value = td[i].samples;
1106 
1107         if (td[i].samples == 1)
1108             tag_bps->value = td[i].bps;
1109         else if (td[i].samples == 2)
1110             tag_bps->value = MAKELONG(td[i].bps, td[i].bps);
1111         else if (td[i].samples == 3)
1112         {
1113             tag_bps->value = (BYTE *)bps - buf;
1114             bps[0] = bps[1] = bps[2] = td[i].bps;
1115         }
1116         else if (td[i].samples == 4)
1117         {
1118             tag_bps->value = (BYTE *)bps - buf;
1119             bps[0] = bps[1] = bps[2] = bps[3] = td[i].bps;
1120         }
1121         else
1122         {
1123             ok(0, "%u: unsupported samples count %d\n", i, td[i].samples);
1124             continue;
1125         }
1126 
1127         hr = create_decoder(buf, sizeof(buf), &decoder);
1128         if (!td[i].data)
1129         {
1130             ok(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_COMPONENTNOTFOUND /* win8+ */ || WINCODEC_ERR_BADIMAGE /* XP */,
1131                "%u: (%d,%d,%d) wrong error %#x\n", i, td[i].photometric, td[i].samples, td[i].bps, hr);
1132             if (hr == S_OK)
1133             {
1134                 IWICBitmapDecoder_Release(decoder);
1135                 dump_tiff(buf);
1136             }
1137             continue;
1138         }
1139         else
1140             ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_BADIMAGE) /* XP */,
1141                "%u: failed to load TIFF image data (%d,%d,%d) %#x\n",
1142                i, td[i].photometric, td[i].samples, td[i].bps, hr);
1143         if (hr != S_OK) continue;
1144 
1145         hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
1146         ok(hr == S_OK, "%u: GetFrame error %#x\n", i, hr);
1147 
1148         hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
1149         ok(hr == S_OK, "%u: GetPixelFormat error %#x\n", i, hr);
1150         ok(IsEqualGUID(&format, td[i].data->format),
1151            "%u (%d,%d,%d): expected %s, got %s\n",
1152             i, td[i].photometric, td[i].samples, td[i].bps,
1153             wine_dbgstr_guid(td[i].data->format), wine_dbgstr_guid(&format));
1154 
1155         trasparency = (td[i].photometric == 2 && td[i].samples == 4); /* for XP */
1156         hr = get_pixelformat_info(&format, &bpp, &channels, &trasparency);
1157         ok(hr == S_OK, "%u: get_pixelformat_bpp error %#x\n", i, hr);
1158         ok(bpp == td[i].data->bpp, "%u: expected %u, got %u\n", i, td[i].data->bpp, bpp);
1159         ok(channels == td[i].samples, "%u: expected %u, got %u\n", i, td[i].samples, channels);
1160         ok(trasparency == (td[i].photometric == 2 && td[i].samples == 4), "%u: got %u\n", i, trasparency);
1161 
1162         memset(pixels, 0, sizeof(pixels));
1163         hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, width_bytes(td[i].data->width, bpp), sizeof(pixels), pixels);
1164         ok(hr == S_OK, "%u: CopyPixels error %#x\n", i, hr);
1165         ret = memcmp(pixels, td[i].data->bits, width_bytes(td[i].data->width, bpp));
1166         if (ret && td[i].alt_data)
1167             ret = memcmp(pixels, td[i].alt_data->bits, width_bytes(td[i].data->width, bpp));
1168         ok(ret == 0, "%u: (%d,%d,%d) wrong pixel data\n", i, td[i].photometric, td[i].samples, td[i].bps);
1169         if (ret)
1170         {
1171             UINT j, n = width_bytes(td[i].data->width, bpp);
1172             for (j = 0; j < n; j++)
1173                 printf("%u%s", pixels[j], (j + 1) < n ? "," : "\n");
1174         }
1175 
1176         IWICBitmapFrameDecode_Release(frame);
1177         IWICBitmapDecoder_Release(decoder);
1178     }
1179 }
1180 
1181 START_TEST(tiffformat)
1182 {
1183     HRESULT hr;
1184 
1185     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1186 
1187     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1188                           &IID_IWICImagingFactory, (void **)&factory);
1189     ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
1190     if (FAILED(hr)) return;
1191 
1192     test_color_formats();
1193     test_tiff_1bpp_palette();
1194     test_tiff_8bpp_palette();
1195     test_QueryCapability();
1196     test_tiff_8bpp_alpha();
1197     test_tiff_resolution();
1198     test_tiff_24bpp();
1199 
1200     IWICImagingFactory_Release(factory);
1201     CoUninitialize();
1202 }
1203