1c2c66affSColin Finck /*
223ec1e5eSAmine Khaldi * Copyright 2012,2016 Dmitry Timoshkov
3c2c66affSColin Finck *
4c2c66affSColin Finck * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck * License as published by the Free Software Foundation; either
7c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck *
9c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12c2c66affSColin Finck * Lesser General Public License for more details.
13c2c66affSColin Finck *
14c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17c2c66affSColin Finck */
18c2c66affSColin Finck
1923ec1e5eSAmine Khaldi #include <math.h>
2023ec1e5eSAmine Khaldi #include <stdarg.h>
2123ec1e5eSAmine Khaldi #include <stdio.h>
2223ec1e5eSAmine Khaldi
2323ec1e5eSAmine Khaldi #define COBJMACROS
2423ec1e5eSAmine Khaldi
2523ec1e5eSAmine Khaldi #include "windef.h"
2623ec1e5eSAmine Khaldi #include "wincodec.h"
2723ec1e5eSAmine Khaldi #include "wine/test.h"
28c2c66affSColin Finck
29eea81f52SAmine Khaldi #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
_expect_ref(IUnknown * obj,ULONG ref,int line)30eea81f52SAmine Khaldi static void _expect_ref(IUnknown* obj, ULONG ref, int line)
31eea81f52SAmine Khaldi {
32eea81f52SAmine Khaldi ULONG rc;
33eea81f52SAmine Khaldi IUnknown_AddRef(obj);
34eea81f52SAmine Khaldi rc = IUnknown_Release(obj);
35eea81f52SAmine Khaldi ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
36eea81f52SAmine Khaldi }
37eea81f52SAmine Khaldi
38c2c66affSColin Finck #define IFD_BYTE 1
39c2c66affSColin Finck #define IFD_ASCII 2
40c2c66affSColin Finck #define IFD_SHORT 3
41c2c66affSColin Finck #define IFD_LONG 4
42c2c66affSColin Finck #define IFD_RATIONAL 5
43c2c66affSColin Finck #define IFD_SBYTE 6
44c2c66affSColin Finck #define IFD_UNDEFINED 7
45c2c66affSColin Finck #define IFD_SSHORT 8
46c2c66affSColin Finck #define IFD_SLONG 9
47c2c66affSColin Finck #define IFD_SRATIONAL 10
48c2c66affSColin Finck #define IFD_FLOAT 11
49c2c66affSColin Finck #define IFD_DOUBLE 12
50c2c66affSColin Finck
51a5cb9a0aSAmine Khaldi #include "pshpack2.h"
52c2c66affSColin Finck struct IFD_entry
53c2c66affSColin Finck {
54c2c66affSColin Finck SHORT id;
55c2c66affSColin Finck SHORT type;
56c2c66affSColin Finck ULONG count;
57c2c66affSColin Finck LONG value;
58c2c66affSColin Finck };
59c2c66affSColin Finck
60c2c66affSColin Finck struct IFD_rational
61c2c66affSColin Finck {
62c2c66affSColin Finck LONG numerator;
63c2c66affSColin Finck LONG denominator;
64c2c66affSColin Finck };
65c2c66affSColin Finck
66c2c66affSColin Finck static const struct tiff_1bpp_data
67c2c66affSColin Finck {
68c2c66affSColin Finck USHORT byte_order;
69c2c66affSColin Finck USHORT version;
70c2c66affSColin Finck ULONG dir_offset;
71c2c66affSColin Finck USHORT number_of_entries;
72c2c66affSColin Finck struct IFD_entry entry[13];
73c2c66affSColin Finck ULONG next_IFD;
74c2c66affSColin Finck struct IFD_rational res;
75c2c66affSColin Finck BYTE pixel_data[4];
76c2c66affSColin Finck } tiff_1bpp_data =
77c2c66affSColin Finck {
78c2c66affSColin Finck #ifdef WORDS_BIGENDIAN
79c2c66affSColin Finck 'M' | 'M' << 8,
80c2c66affSColin Finck #else
81c2c66affSColin Finck 'I' | 'I' << 8,
82c2c66affSColin Finck #endif
83c2c66affSColin Finck 42,
84c2c66affSColin Finck FIELD_OFFSET(struct tiff_1bpp_data, number_of_entries),
85c2c66affSColin Finck 13,
86c2c66affSColin Finck {
87c2c66affSColin Finck { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
88c2c66affSColin Finck { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */
89c2c66affSColin Finck { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
90c2c66affSColin Finck { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */
91c2c66affSColin Finck { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
92c2c66affSColin Finck { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */
93c2c66affSColin Finck { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1bpp_data, pixel_data) }, /* STRIPOFFSETS */
94c2c66affSColin Finck { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */
95c2c66affSColin Finck { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */
96c2c66affSColin Finck { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */
9723ec1e5eSAmine Khaldi { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1bpp_data, res) }, /* XRESOLUTION */
9823ec1e5eSAmine Khaldi { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1bpp_data, res) }, /* YRESOLUTION */
99c2c66affSColin Finck { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
100c2c66affSColin Finck },
101c2c66affSColin Finck 0,
102c2c66affSColin Finck { 900, 3 },
103c2c66affSColin Finck { 0x11, 0x22, 0x33, 0 }
104c2c66affSColin Finck };
105c2c66affSColin Finck
106c2c66affSColin Finck static const struct tiff_8bpp_alpha
107c2c66affSColin Finck {
108c2c66affSColin Finck USHORT byte_order;
109c2c66affSColin Finck USHORT version;
110c2c66affSColin Finck ULONG dir_offset;
111c2c66affSColin Finck USHORT number_of_entries;
112c2c66affSColin Finck struct IFD_entry entry[15];
113c2c66affSColin Finck ULONG next_IFD;
114c2c66affSColin Finck struct IFD_rational res;
115c2c66affSColin Finck BYTE pixel_data[8];
116c2c66affSColin Finck } tiff_8bpp_alpha =
117c2c66affSColin Finck {
118c2c66affSColin Finck #ifdef WORDS_BIGENDIAN
119c2c66affSColin Finck 'M' | 'M' << 8,
120c2c66affSColin Finck #else
121c2c66affSColin Finck 'I' | 'I' << 8,
122c2c66affSColin Finck #endif
123c2c66affSColin Finck 42,
124c2c66affSColin Finck FIELD_OFFSET(struct tiff_8bpp_alpha, number_of_entries),
125c2c66affSColin Finck 15,
126c2c66affSColin Finck {
127c2c66affSColin Finck { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
128c2c66affSColin Finck { 0x100, IFD_LONG, 1, 2 }, /* IMAGEWIDTH */
129c2c66affSColin Finck { 0x101, IFD_LONG, 1, 2 }, /* IMAGELENGTH */
130c2c66affSColin Finck { 0x102, IFD_SHORT, 2, MAKELONG(8, 8) }, /* BITSPERSAMPLE */
131c2c66affSColin Finck { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
132c2c66affSColin Finck { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */
133c2c66affSColin Finck { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, pixel_data) }, /* STRIPOFFSETS */
134c2c66affSColin Finck { 0x115, IFD_SHORT, 1, 2 }, /* SAMPLESPERPIXEL */
135c2c66affSColin Finck { 0x116, IFD_LONG, 1, 2 }, /* ROWSPERSTRIP */
136c2c66affSColin Finck { 0x117, IFD_LONG, 1, 8 }, /* STRIPBYTECOUNT */
13723ec1e5eSAmine Khaldi { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, res) }, /* XRESOLUTION */
13823ec1e5eSAmine Khaldi { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, res) }, /* YRESOLUTION */
139c2c66affSColin Finck { 0x11c, IFD_SHORT, 1, 1 }, /* PLANARCONFIGURATION */
140c2c66affSColin Finck { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
141c2c66affSColin Finck { 0x152, IFD_SHORT, 1, 1 } /* EXTRASAMPLES: 1 - Associated alpha with pre-multiplied color */
142c2c66affSColin Finck },
143c2c66affSColin Finck 0,
144c2c66affSColin Finck { 96, 1 },
145c2c66affSColin Finck { 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88 }
146c2c66affSColin Finck };
14723ec1e5eSAmine Khaldi
14823ec1e5eSAmine Khaldi static const struct tiff_8bpp_data
14923ec1e5eSAmine Khaldi {
15023ec1e5eSAmine Khaldi USHORT byte_order;
15123ec1e5eSAmine Khaldi USHORT version;
15223ec1e5eSAmine Khaldi ULONG dir_offset;
15323ec1e5eSAmine Khaldi USHORT number_of_entries;
15423ec1e5eSAmine Khaldi struct IFD_entry entry[14];
15523ec1e5eSAmine Khaldi ULONG next_IFD;
15623ec1e5eSAmine Khaldi struct IFD_rational res;
15723ec1e5eSAmine Khaldi short palette_data[3][256];
15823ec1e5eSAmine Khaldi BYTE pixel_data[4];
15923ec1e5eSAmine Khaldi } tiff_8bpp_data =
16023ec1e5eSAmine Khaldi {
16123ec1e5eSAmine Khaldi #ifdef WORDS_BIGENDIAN
16223ec1e5eSAmine Khaldi 'M' | 'M' << 8,
16323ec1e5eSAmine Khaldi #else
16423ec1e5eSAmine Khaldi 'I' | 'I' << 8,
16523ec1e5eSAmine Khaldi #endif
16623ec1e5eSAmine Khaldi 42,
16723ec1e5eSAmine Khaldi FIELD_OFFSET(struct tiff_8bpp_data, number_of_entries),
16823ec1e5eSAmine Khaldi 14,
16923ec1e5eSAmine Khaldi {
17023ec1e5eSAmine Khaldi { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
17123ec1e5eSAmine Khaldi { 0x100, IFD_LONG, 1, 4 }, /* IMAGEWIDTH */
17223ec1e5eSAmine Khaldi { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
17323ec1e5eSAmine Khaldi { 0x102, IFD_SHORT, 1, 8 }, /* BITSPERSAMPLE: XP doesn't accept IFD_LONG here */
17423ec1e5eSAmine Khaldi { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
17523ec1e5eSAmine Khaldi { 0x106, IFD_SHORT, 1, 3 }, /* PHOTOMETRIC */
17623ec1e5eSAmine Khaldi { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_8bpp_data, pixel_data) }, /* STRIPOFFSETS */
17723ec1e5eSAmine Khaldi { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */
17823ec1e5eSAmine Khaldi { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */
17923ec1e5eSAmine Khaldi { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */
18023ec1e5eSAmine Khaldi { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_data, res) },
18123ec1e5eSAmine Khaldi { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_data, res) },
18223ec1e5eSAmine Khaldi { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
18323ec1e5eSAmine Khaldi { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_8bpp_data, palette_data) } /* COLORMAP */
18423ec1e5eSAmine Khaldi },
18523ec1e5eSAmine Khaldi 0,
18623ec1e5eSAmine Khaldi { 96, 1 },
18723ec1e5eSAmine Khaldi { { 0 } },
18823ec1e5eSAmine Khaldi { 0,1,2,3 }
18923ec1e5eSAmine Khaldi };
19023ec1e5eSAmine Khaldi
19123ec1e5eSAmine Khaldi static const struct tiff_resolution_test_data
19223ec1e5eSAmine Khaldi {
19323ec1e5eSAmine Khaldi struct IFD_rational resx;
19423ec1e5eSAmine Khaldi struct IFD_rational resy;
19523ec1e5eSAmine Khaldi LONG resolution_unit;
19623ec1e5eSAmine Khaldi double expected_dpi_x;
19723ec1e5eSAmine Khaldi double expected_dpi_y;
19823ec1e5eSAmine Khaldi /* if != 0: values for different behavior of some Windows versions */
19923ec1e5eSAmine Khaldi double broken_dpi_x;
20023ec1e5eSAmine Khaldi double broken_dpi_y;
20123ec1e5eSAmine Khaldi } tiff_resolution_test_data[] =
20223ec1e5eSAmine Khaldi {
20323ec1e5eSAmine Khaldi { { 100, 1 }, { 50, 1 }, 0, 100.0, 50.0, 0, 0 }, /* invalid resolution unit */
20423ec1e5eSAmine Khaldi { { 50, 1 }, { 100, 1 }, 0, 50.0, 100.0, 0, 0 },
20523ec1e5eSAmine Khaldi
20623ec1e5eSAmine Khaldi { { 100, 1 }, { 50, 1 }, 1, 100.0, 50.0, 0, 0 }, /* RESUNIT_NONE */
20723ec1e5eSAmine Khaldi { { 50, 1 }, { 100, 1 }, 1, 50.0, 100.0, 0, 0 },
20823ec1e5eSAmine Khaldi
20923ec1e5eSAmine Khaldi { { 49, 1 }, { 49, 1 }, 2, 49.0, 49.0, 0, 0 }, /* same resolution for both X and Y */
21023ec1e5eSAmine Khaldi { { 33, 1 }, { 55, 1 }, 2, 33.0, 55.0, 0, 0 }, /* different resolutions for X and Y */
21123ec1e5eSAmine Khaldi { { 50, 2 }, { 66, 3 }, 2, 25.0, 22.0, 0, 0 }, /* denominator != 1 */
21223ec1e5eSAmine Khaldi
21323ec1e5eSAmine Khaldi { { 100, 1 }, { 200, 1 }, 3, 254.0, 508.0, 0, 0 }, /* unit = centimeters */
21423ec1e5eSAmine Khaldi
21523ec1e5eSAmine Khaldi /* XP and Server 2003 do not discard both resolution values if only one of them is invalid */
21623ec1e5eSAmine Khaldi { { 0, 1 }, { 29, 1 }, 2, 96.0, 96.0, 0, 29.0 }, /* resolution 0 */
21723ec1e5eSAmine Khaldi { { 58, 1 }, { 29, 0 }, 2, 96.0, 96.0, 58.0, 0 }, /* denominator 0 (division by zero) */
21823ec1e5eSAmine Khaldi
21923ec1e5eSAmine Khaldi /* XP and Server 2003 return 96 dots per centimeter (= 243.84 dpi) as fallback value */
22023ec1e5eSAmine Khaldi { { 0, 1 }, { 100, 1 }, 3, 96.0, 96.0, 243.84, 254.0 }, /* resolution 0 and unit = centimeters */
22123ec1e5eSAmine Khaldi { { 50, 1 }, { 72, 0 }, 3, 96.0, 96.0, 127.0, 243.84 } /* denominator 0 and unit = centimeters */
22223ec1e5eSAmine Khaldi };
22323ec1e5eSAmine Khaldi
22423ec1e5eSAmine Khaldi static struct tiff_resolution_image_data
22523ec1e5eSAmine Khaldi {
22623ec1e5eSAmine Khaldi USHORT byte_order;
22723ec1e5eSAmine Khaldi USHORT version;
22823ec1e5eSAmine Khaldi ULONG dir_offset;
22923ec1e5eSAmine Khaldi USHORT number_of_entries;
23023ec1e5eSAmine Khaldi struct IFD_entry entry[13];
23123ec1e5eSAmine Khaldi ULONG next_IFD;
23223ec1e5eSAmine Khaldi struct IFD_rational resx;
23323ec1e5eSAmine Khaldi struct IFD_rational resy;
23423ec1e5eSAmine Khaldi BYTE pixel_data[4];
23523ec1e5eSAmine Khaldi } tiff_resolution_image_data =
23623ec1e5eSAmine Khaldi {
23723ec1e5eSAmine Khaldi #ifdef WORDS_BIGENDIAN
23823ec1e5eSAmine Khaldi 'M' | 'M' << 8,
23923ec1e5eSAmine Khaldi #else
24023ec1e5eSAmine Khaldi 'I' | 'I' << 8,
24123ec1e5eSAmine Khaldi #endif
24223ec1e5eSAmine Khaldi 42,
24323ec1e5eSAmine Khaldi FIELD_OFFSET(struct tiff_resolution_image_data, number_of_entries),
24423ec1e5eSAmine Khaldi 13,
24523ec1e5eSAmine Khaldi {
24623ec1e5eSAmine Khaldi { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
24723ec1e5eSAmine Khaldi { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */
24823ec1e5eSAmine Khaldi { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
24923ec1e5eSAmine Khaldi { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */
25023ec1e5eSAmine Khaldi { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
25123ec1e5eSAmine Khaldi { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */
25223ec1e5eSAmine Khaldi { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_resolution_image_data, pixel_data) }, /* STRIPOFFSETS */
25323ec1e5eSAmine Khaldi { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */
25423ec1e5eSAmine Khaldi { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */
25523ec1e5eSAmine Khaldi { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */
25623ec1e5eSAmine Khaldi { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_resolution_image_data, resx) }, /* XRESOLUTION */
25723ec1e5eSAmine Khaldi { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_resolution_image_data, resy) }, /* YRESOLUTION */
25823ec1e5eSAmine Khaldi { 0x128, IFD_SHORT, 1, 1 }, /* RESOLUTIONUNIT -- value will be filled with test data */
25923ec1e5eSAmine Khaldi },
26023ec1e5eSAmine Khaldi 0,
26123ec1e5eSAmine Khaldi { 72, 1 }, /* value will be filled with test data */
26223ec1e5eSAmine Khaldi { 72, 1 }, /* value will be filled with test data */
26323ec1e5eSAmine Khaldi { 0x11, 0x22, 0x33, 0 }
26423ec1e5eSAmine Khaldi };
265eea81f52SAmine Khaldi
266eea81f52SAmine Khaldi static const struct tiff_24bpp_data
267eea81f52SAmine Khaldi {
268eea81f52SAmine Khaldi USHORT byte_order;
269eea81f52SAmine Khaldi USHORT version;
270eea81f52SAmine Khaldi ULONG dir_offset;
271eea81f52SAmine Khaldi USHORT number_of_entries;
272eea81f52SAmine Khaldi struct IFD_entry entry[13];
273eea81f52SAmine Khaldi ULONG next_IFD;
274eea81f52SAmine Khaldi struct IFD_rational res;
275eea81f52SAmine Khaldi BYTE pixel_data[3];
276eea81f52SAmine Khaldi } tiff_24bpp_data =
277eea81f52SAmine Khaldi {
278eea81f52SAmine Khaldi #ifdef WORDS_BIGENDIAN
279eea81f52SAmine Khaldi 'M' | 'M' << 8,
280eea81f52SAmine Khaldi #else
281eea81f52SAmine Khaldi 'I' | 'I' << 8,
282eea81f52SAmine Khaldi #endif
283eea81f52SAmine Khaldi 42,
284eea81f52SAmine Khaldi FIELD_OFFSET(struct tiff_1bpp_data, number_of_entries),
285eea81f52SAmine Khaldi 13,
286eea81f52SAmine Khaldi {
287eea81f52SAmine Khaldi { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
288eea81f52SAmine Khaldi { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */
289eea81f52SAmine Khaldi { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
290eea81f52SAmine Khaldi { 0x102, IFD_SHORT, 1, 8 }, /* BITSPERSAMPLE */
291eea81f52SAmine Khaldi { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
292eea81f52SAmine Khaldi { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */
293eea81f52SAmine Khaldi { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_24bpp_data, pixel_data) }, /* STRIPOFFSETS */
294eea81f52SAmine Khaldi { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */
295eea81f52SAmine Khaldi { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */
296eea81f52SAmine Khaldi { 0x117, IFD_LONG, 1, 3 }, /* STRIPBYTECOUNT */
297eea81f52SAmine Khaldi { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_24bpp_data, res) }, /* XRESOLUTION */
298eea81f52SAmine Khaldi { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_24bpp_data, res) }, /* YRESOLUTION */
299eea81f52SAmine Khaldi { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
300eea81f52SAmine Khaldi },
301eea81f52SAmine Khaldi 0,
302eea81f52SAmine Khaldi { 900, 3 },
303eea81f52SAmine Khaldi { 0x11, 0x22, 0x33 }
304eea81f52SAmine Khaldi };
305*3e9c4dadSThomas Faber
306*3e9c4dadSThomas Faber static const struct tiff_4bps_bgra
307*3e9c4dadSThomas Faber {
308*3e9c4dadSThomas Faber USHORT byte_order;
309*3e9c4dadSThomas Faber USHORT version;
310*3e9c4dadSThomas Faber ULONG dir_offset;
311*3e9c4dadSThomas Faber USHORT number_of_entries;
312*3e9c4dadSThomas Faber struct IFD_entry entry[14];
313*3e9c4dadSThomas Faber ULONG next_IFD;
314*3e9c4dadSThomas Faber struct IFD_rational res;
315*3e9c4dadSThomas Faber BYTE pixel_data[4];
316*3e9c4dadSThomas Faber } tiff_4bps_bgra =
317*3e9c4dadSThomas Faber {
318*3e9c4dadSThomas Faber #ifdef WORDS_BIGENDIAN
319*3e9c4dadSThomas Faber 'M' | 'M' << 8,
320*3e9c4dadSThomas Faber #else
321*3e9c4dadSThomas Faber 'I' | 'I' << 8,
322*3e9c4dadSThomas Faber #endif
323*3e9c4dadSThomas Faber 42,
324*3e9c4dadSThomas Faber FIELD_OFFSET(struct tiff_4bps_bgra, number_of_entries),
325*3e9c4dadSThomas Faber 14,
326*3e9c4dadSThomas Faber {
327*3e9c4dadSThomas Faber { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
328*3e9c4dadSThomas Faber { 0x100, IFD_LONG, 1, 3 }, /* IMAGEWIDTH */
329*3e9c4dadSThomas Faber { 0x101, IFD_LONG, 1, 2 }, /* IMAGELENGTH */
330*3e9c4dadSThomas Faber { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */
331*3e9c4dadSThomas Faber { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION */
332*3e9c4dadSThomas Faber { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */
333*3e9c4dadSThomas Faber { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_4bps_bgra, pixel_data) }, /* STRIPOFFSETS */
334*3e9c4dadSThomas Faber { 0x115, IFD_SHORT, 1, 4 }, /* SAMPLESPERPIXEL */
335*3e9c4dadSThomas Faber { 0x116, IFD_LONG, 1, 2 }, /* ROWSPERSTRIP */
336*3e9c4dadSThomas Faber { 0x117, IFD_LONG, 1, 4 }, /* STRIPBYTECOUNT */
337*3e9c4dadSThomas Faber { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_4bps_bgra, res) }, /* XRESOLUTION */
338*3e9c4dadSThomas Faber { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_4bps_bgra, res) }, /* YRESOLUTION */
339*3e9c4dadSThomas Faber { 0x11c, IFD_SHORT, 1, 1 }, /* PLANARCONFIGURATION */
340*3e9c4dadSThomas Faber { 0x128, IFD_SHORT, 1, 2 } /* RESOLUTIONUNIT */
341*3e9c4dadSThomas Faber },
342*3e9c4dadSThomas Faber 0,
343*3e9c4dadSThomas Faber { 96, 1 },
344*3e9c4dadSThomas Faber { 0x12,0x30, 0x47,0xe0 }
345*3e9c4dadSThomas Faber };
346c2c66affSColin Finck #include "poppack.h"
347c2c66affSColin Finck
348c2c66affSColin Finck static IWICImagingFactory *factory;
349c2c66affSColin Finck
create_stream(const void * data,int data_size)350c2c66affSColin Finck static IStream *create_stream(const void *data, int data_size)
351c2c66affSColin Finck {
352c2c66affSColin Finck HRESULT hr;
353c2c66affSColin Finck IStream *stream;
354c2c66affSColin Finck HGLOBAL hdata;
355c2c66affSColin Finck void *locked_data;
356c2c66affSColin Finck
357c2c66affSColin Finck hdata = GlobalAlloc(GMEM_MOVEABLE, data_size);
358c2c66affSColin Finck ok(hdata != 0, "GlobalAlloc failed\n");
359c2c66affSColin Finck if (!hdata) return NULL;
360c2c66affSColin Finck
361c2c66affSColin Finck locked_data = GlobalLock(hdata);
362c2c66affSColin Finck memcpy(locked_data, data, data_size);
363c2c66affSColin Finck GlobalUnlock(hdata);
364c2c66affSColin Finck
365c2c66affSColin Finck hr = CreateStreamOnHGlobal(hdata, TRUE, &stream);
366c2c66affSColin Finck ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr);
367c2c66affSColin Finck
368c2c66affSColin Finck return stream;
369c2c66affSColin Finck }
370c2c66affSColin Finck
create_decoder(const void * image_data,UINT image_size,IWICBitmapDecoder ** decoder)37123ec1e5eSAmine Khaldi static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitmapDecoder **decoder)
372c2c66affSColin Finck {
37323ec1e5eSAmine Khaldi HGLOBAL hmem;
37423ec1e5eSAmine Khaldi BYTE *data;
375c2c66affSColin Finck HRESULT hr;
376c2c66affSColin Finck IStream *stream;
37723ec1e5eSAmine Khaldi GUID format;
37823ec1e5eSAmine Khaldi LONG refcount;
379c2c66affSColin Finck
38023ec1e5eSAmine Khaldi *decoder = NULL;
381c2c66affSColin Finck
38223ec1e5eSAmine Khaldi hmem = GlobalAlloc(0, image_size);
38323ec1e5eSAmine Khaldi data = GlobalLock(hmem);
38423ec1e5eSAmine Khaldi memcpy(data, image_data, image_size);
38523ec1e5eSAmine Khaldi GlobalUnlock(hmem);
386c2c66affSColin Finck
38723ec1e5eSAmine Khaldi hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
38823ec1e5eSAmine Khaldi ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
38923ec1e5eSAmine Khaldi
39023ec1e5eSAmine Khaldi hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, decoder);
39123ec1e5eSAmine Khaldi if (hr == S_OK)
39223ec1e5eSAmine Khaldi {
39323ec1e5eSAmine Khaldi hr = IWICBitmapDecoder_GetContainerFormat(*decoder, &format);
394c2c66affSColin Finck ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
39523ec1e5eSAmine Khaldi ok(IsEqualGUID(&format, &GUID_ContainerFormatTiff),
39623ec1e5eSAmine Khaldi "wrong container format %s\n", wine_dbgstr_guid(&format));
397c2c66affSColin Finck
39823ec1e5eSAmine Khaldi refcount = IStream_Release(stream);
39923ec1e5eSAmine Khaldi ok(refcount > 0, "expected stream refcount > 0\n");
400c2c66affSColin Finck }
401c2c66affSColin Finck
40223ec1e5eSAmine Khaldi return hr;
40323ec1e5eSAmine Khaldi }
40423ec1e5eSAmine Khaldi
get_pixelformat_info(const GUID * format,UINT * bpp,UINT * channels,BOOL * trasparency)40523ec1e5eSAmine Khaldi static HRESULT get_pixelformat_info(const GUID *format, UINT *bpp, UINT *channels, BOOL *trasparency)
40623ec1e5eSAmine Khaldi {
40723ec1e5eSAmine Khaldi HRESULT hr;
40823ec1e5eSAmine Khaldi IWICComponentInfo *info;
40923ec1e5eSAmine Khaldi IWICPixelFormatInfo2 *formatinfo;
41023ec1e5eSAmine Khaldi
41123ec1e5eSAmine Khaldi hr = IWICImagingFactory_CreateComponentInfo(factory, format, &info);
41223ec1e5eSAmine Khaldi ok(hr == S_OK, "CreateComponentInfo(%s) error %#x\n", wine_dbgstr_guid(format), hr);
41323ec1e5eSAmine Khaldi if (hr == S_OK)
41423ec1e5eSAmine Khaldi {
41523ec1e5eSAmine Khaldi hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void **)&formatinfo);
41623ec1e5eSAmine Khaldi if (hr == S_OK)
41723ec1e5eSAmine Khaldi {
41823ec1e5eSAmine Khaldi hr = IWICPixelFormatInfo2_SupportsTransparency(formatinfo, trasparency);
41923ec1e5eSAmine Khaldi ok(hr == S_OK, "SupportsTransparency error %#x\n", hr);
42023ec1e5eSAmine Khaldi IWICPixelFormatInfo2_Release(formatinfo);
42123ec1e5eSAmine Khaldi }
42223ec1e5eSAmine Khaldi hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void **)&formatinfo);
42323ec1e5eSAmine Khaldi if (hr == S_OK)
42423ec1e5eSAmine Khaldi {
42523ec1e5eSAmine Khaldi hr = IWICPixelFormatInfo2_GetBitsPerPixel(formatinfo, bpp);
42623ec1e5eSAmine Khaldi ok(hr == S_OK, "GetBitsPerPixel error %#x\n", hr);
42723ec1e5eSAmine Khaldi hr = IWICPixelFormatInfo2_GetChannelCount(formatinfo, channels);
42823ec1e5eSAmine Khaldi ok(hr == S_OK, "GetChannelCount error %#x\n", hr);
42923ec1e5eSAmine Khaldi IWICPixelFormatInfo2_Release(formatinfo);
43023ec1e5eSAmine Khaldi }
43123ec1e5eSAmine Khaldi IWICComponentInfo_Release(info);
43223ec1e5eSAmine Khaldi }
43323ec1e5eSAmine Khaldi return hr;
43423ec1e5eSAmine Khaldi }
43523ec1e5eSAmine Khaldi
dump_tiff(void * buf)43623ec1e5eSAmine Khaldi static void dump_tiff(void *buf)
43723ec1e5eSAmine Khaldi {
43823ec1e5eSAmine Khaldi UINT count, i;
43923ec1e5eSAmine Khaldi struct tiff_1bpp_data *tiff;
44023ec1e5eSAmine Khaldi struct IFD_entry *tag;
44123ec1e5eSAmine Khaldi
44223ec1e5eSAmine Khaldi tiff = buf;
44323ec1e5eSAmine Khaldi count = *(short *)((char *)tiff + tiff->dir_offset);
44423ec1e5eSAmine Khaldi tag = (struct IFD_entry *)((char *)tiff + tiff->dir_offset + sizeof(short));
44523ec1e5eSAmine Khaldi
44623ec1e5eSAmine Khaldi for (i = 0; i < count; i++)
44723ec1e5eSAmine Khaldi {
44823ec1e5eSAmine Khaldi printf("tag %u: id %04x, type %04x, count %u, value %d",
44923ec1e5eSAmine Khaldi i, tag[i].id, tag[i].type, tag[i].count, tag[i].value);
45023ec1e5eSAmine Khaldi if (tag[i].id == 0x102 && tag[i].count > 2)
45123ec1e5eSAmine Khaldi {
45223ec1e5eSAmine Khaldi short *bps = (short *)((char *)tiff + tag[i].value);
45323ec1e5eSAmine Khaldi printf(" (%d,%d,%d,%d)\n", bps[0], bps[1], bps[2], bps[3]);
45423ec1e5eSAmine Khaldi }
45523ec1e5eSAmine Khaldi else
45623ec1e5eSAmine Khaldi printf("\n");
45723ec1e5eSAmine Khaldi }
45823ec1e5eSAmine Khaldi }
45923ec1e5eSAmine Khaldi
test_tiff_1bpp_palette(void)46023ec1e5eSAmine Khaldi static void test_tiff_1bpp_palette(void)
461c2c66affSColin Finck {
462c2c66affSColin Finck HRESULT hr;
463c2c66affSColin Finck IWICBitmapDecoder *decoder;
464c2c66affSColin Finck IWICBitmapFrameDecode *frame;
465c2c66affSColin Finck IWICPalette *palette;
466c2c66affSColin Finck GUID format;
467c2c66affSColin Finck
46823ec1e5eSAmine Khaldi hr = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data), &decoder);
46923ec1e5eSAmine Khaldi ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
47023ec1e5eSAmine Khaldi if (hr != S_OK) return;
471c2c66affSColin Finck
472c2c66affSColin Finck hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
473c2c66affSColin Finck ok(hr == S_OK, "GetFrame error %#x\n", hr);
474c2c66affSColin Finck
475c2c66affSColin Finck hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
476c2c66affSColin Finck ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
477c2c66affSColin Finck ok(IsEqualGUID(&format, &GUID_WICPixelFormatBlackWhite),
478c2c66affSColin Finck "got wrong format %s\n", wine_dbgstr_guid(&format));
479c2c66affSColin Finck
480c2c66affSColin Finck hr = IWICImagingFactory_CreatePalette(factory, &palette);
481c2c66affSColin Finck ok(hr == S_OK, "CreatePalette error %#x\n", hr);
482c2c66affSColin Finck hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
483c2c66affSColin Finck ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE,
484c2c66affSColin Finck "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr);
485c2c66affSColin Finck
486c2c66affSColin Finck IWICPalette_Release(palette);
487c2c66affSColin Finck IWICBitmapFrameDecode_Release(frame);
488c2c66affSColin Finck IWICBitmapDecoder_Release(decoder);
489c2c66affSColin Finck }
490c2c66affSColin Finck
test_QueryCapability(void)491c2c66affSColin Finck static void test_QueryCapability(void)
492c2c66affSColin Finck {
493c2c66affSColin Finck HRESULT hr;
494c2c66affSColin Finck IStream *stream;
495c2c66affSColin Finck IWICBitmapDecoder *decoder;
496c2c66affSColin Finck IWICBitmapFrameDecode *frame;
497c2c66affSColin Finck static const DWORD exp_caps = WICBitmapDecoderCapabilityCanDecodeAllImages |
498c2c66affSColin Finck WICBitmapDecoderCapabilityCanDecodeSomeImages |
499c2c66affSColin Finck WICBitmapDecoderCapabilityCanEnumerateMetadata;
500c2c66affSColin Finck static const DWORD exp_caps_xp = WICBitmapDecoderCapabilityCanDecodeAllImages |
501c2c66affSColin Finck WICBitmapDecoderCapabilityCanDecodeSomeImages;
502c2c66affSColin Finck DWORD capability;
503c2c66affSColin Finck LARGE_INTEGER pos;
504c2c66affSColin Finck ULARGE_INTEGER cur_pos;
505c2c66affSColin Finck UINT frame_count;
506c2c66affSColin Finck
507c2c66affSColin Finck stream = create_stream(&tiff_1bpp_data, sizeof(tiff_1bpp_data));
508c2c66affSColin Finck if (!stream) return;
509c2c66affSColin Finck
510c2c66affSColin Finck hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatTiff, NULL, &decoder);
511c2c66affSColin Finck ok(hr == S_OK, "CreateDecoder error %#x\n", hr);
512c2c66affSColin Finck if (FAILED(hr)) return;
513c2c66affSColin Finck
514c2c66affSColin Finck frame_count = 0xdeadbeef;
515c2c66affSColin Finck hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
516c2c66affSColin Finck ok(hr == S_OK || broken(hr == E_POINTER) /* XP */, "GetFrameCount error %#x\n", hr);
517c2c66affSColin Finck ok(frame_count == 0, "expected 0, got %u\n", frame_count);
518c2c66affSColin Finck
519c2c66affSColin Finck hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
520c2c66affSColin Finck ok(hr == WINCODEC_ERR_FRAMEMISSING || broken(hr == E_POINTER) /* XP */, "expected WINCODEC_ERR_FRAMEMISSING, got %#x\n", hr);
521c2c66affSColin Finck
522c2c66affSColin Finck pos.QuadPart = 4;
523c2c66affSColin Finck hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
524c2c66affSColin Finck ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
525c2c66affSColin Finck
526c2c66affSColin Finck capability = 0xdeadbeef;
527c2c66affSColin Finck hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
528c2c66affSColin Finck ok(hr == S_OK, "QueryCapability error %#x\n", hr);
529c2c66affSColin Finck ok(capability == exp_caps || capability == exp_caps_xp,
530c2c66affSColin Finck "expected %#x, got %#x\n", exp_caps, capability);
531c2c66affSColin Finck
532c2c66affSColin Finck frame_count = 0xdeadbeef;
533c2c66affSColin Finck hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
534c2c66affSColin Finck ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
535c2c66affSColin Finck ok(frame_count == 1, "expected 1, got %u\n", frame_count);
536c2c66affSColin Finck
537c2c66affSColin Finck hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
538c2c66affSColin Finck ok(hr == S_OK, "GetFrame error %#x\n", hr);
539c2c66affSColin Finck IWICBitmapFrameDecode_Release(frame);
540c2c66affSColin Finck
541c2c66affSColin Finck pos.QuadPart = 0;
542c2c66affSColin Finck hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos);
543c2c66affSColin Finck ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
544c2c66affSColin Finck ok(cur_pos.QuadPart > 4 && cur_pos.QuadPart < sizeof(tiff_1bpp_data),
545c2c66affSColin Finck "current stream pos is at %x/%x\n", cur_pos.u.LowPart, cur_pos.u.HighPart);
546c2c66affSColin Finck
547c2c66affSColin Finck hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
548c2c66affSColin Finck ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
549c2c66affSColin Finck
550c2c66affSColin Finck hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
551c2c66affSColin Finck ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
552c2c66affSColin Finck
553c2c66affSColin Finck IWICBitmapDecoder_Release(decoder);
554c2c66affSColin Finck
555c2c66affSColin Finck hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
556c2c66affSColin Finck todo_wine
557c2c66affSColin Finck ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "expected WINCODEC_ERR_COMPONENTNOTFOUND, got %#x\n", hr);
558c2c66affSColin Finck
559c2c66affSColin Finck if (SUCCEEDED(hr))
560c2c66affSColin Finck IWICBitmapDecoder_Release(decoder);
561c2c66affSColin Finck
562c2c66affSColin Finck pos.QuadPart = 0;
563c2c66affSColin Finck hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
564c2c66affSColin Finck ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
565c2c66affSColin Finck
566c2c66affSColin Finck hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
567c2c66affSColin Finck ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
568c2c66affSColin Finck
569c2c66affSColin Finck frame_count = 0xdeadbeef;
570c2c66affSColin Finck hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
571c2c66affSColin Finck ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
572c2c66affSColin Finck ok(frame_count == 1, "expected 1, got %u\n", frame_count);
573c2c66affSColin Finck
574c2c66affSColin Finck hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
575c2c66affSColin Finck ok(hr == S_OK, "GetFrame error %#x\n", hr);
576c2c66affSColin Finck IWICBitmapFrameDecode_Release(frame);
577c2c66affSColin Finck
578c2c66affSColin Finck hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
579c2c66affSColin Finck ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
580c2c66affSColin Finck
581c2c66affSColin Finck hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
582c2c66affSColin Finck ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
583c2c66affSColin Finck
584c2c66affSColin Finck IWICBitmapDecoder_Release(decoder);
585c2c66affSColin Finck IStream_Release(stream);
586c2c66affSColin Finck }
587c2c66affSColin Finck
test_tiff_8bpp_alpha(void)588c2c66affSColin Finck static void test_tiff_8bpp_alpha(void)
589c2c66affSColin Finck {
590c2c66affSColin Finck HRESULT hr;
591c2c66affSColin Finck IWICBitmapDecoder *decoder;
592c2c66affSColin Finck IWICBitmapFrameDecode *frame;
593c2c66affSColin Finck UINT frame_count, width, height, i;
594c2c66affSColin Finck double dpi_x, dpi_y;
595c2c66affSColin Finck IWICPalette *palette;
596c2c66affSColin Finck GUID format;
597c2c66affSColin Finck WICRect rc;
598c2c66affSColin Finck BYTE data[16];
599c2c66affSColin Finck static const BYTE expected_data[16] = { 0x11,0x11,0x11,0x22,0x33,0x33,0x33,0x44,
600c2c66affSColin Finck 0x55,0x55,0x55,0x66,0x77,0x77,0x77,0x88 };
601c2c66affSColin Finck
60223ec1e5eSAmine Khaldi hr = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha), &decoder);
60323ec1e5eSAmine Khaldi ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
60423ec1e5eSAmine Khaldi if (hr != S_OK) return;
605c2c66affSColin Finck
606c2c66affSColin Finck hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
607c2c66affSColin Finck ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
608c2c66affSColin Finck ok(frame_count == 1, "expected 1, got %u\n", frame_count);
609c2c66affSColin Finck
610eea81f52SAmine Khaldi EXPECT_REF(decoder, 1);
611c2c66affSColin Finck hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
612c2c66affSColin Finck ok(hr == S_OK, "GetFrame error %#x\n", hr);
613eea81f52SAmine Khaldi EXPECT_REF(decoder, 2);
614eea81f52SAmine Khaldi IWICBitmapDecoder_Release(decoder);
615c2c66affSColin Finck
616c2c66affSColin Finck hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
617c2c66affSColin Finck ok(hr == S_OK, "GetSize error %#x\n", hr);
618c2c66affSColin Finck ok(width == 2, "expected 2, got %u\n", width);
619c2c66affSColin Finck ok(height == 2, "expected 2, got %u\n", height);
620c2c66affSColin Finck
621c2c66affSColin Finck hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y);
622c2c66affSColin Finck ok(hr == S_OK, "GetResolution error %#x\n", hr);
623c2c66affSColin Finck ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x);
624c2c66affSColin Finck ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y);
625c2c66affSColin Finck
626c2c66affSColin Finck hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
627c2c66affSColin Finck ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
628c2c66affSColin Finck ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppPBGRA),
629c2c66affSColin Finck "got wrong format %s\n", wine_dbgstr_guid(&format));
630c2c66affSColin Finck
631c2c66affSColin Finck hr = IWICImagingFactory_CreatePalette(factory, &palette);
632c2c66affSColin Finck ok(hr == S_OK, "CreatePalette error %#x\n", hr);
633c2c66affSColin Finck hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
634c2c66affSColin Finck ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE,
635c2c66affSColin Finck "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr);
636c2c66affSColin Finck IWICPalette_Release(palette);
637c2c66affSColin Finck
638c2c66affSColin Finck rc.X = 0;
639c2c66affSColin Finck rc.Y = 0;
640c2c66affSColin Finck rc.Width = 2;
641c2c66affSColin Finck rc.Height = 2;
642c2c66affSColin Finck hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 8, sizeof(data), data);
643c2c66affSColin Finck ok(hr == S_OK, "CopyPixels error %#x\n", hr);
644c2c66affSColin Finck
645c2c66affSColin Finck for (i = 0; i < sizeof(data); i++)
646c2c66affSColin Finck ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]);
647c2c66affSColin Finck
648c2c66affSColin Finck IWICBitmapFrameDecode_Release(frame);
649c2c66affSColin Finck }
650c2c66affSColin Finck
generate_tiff_palette(void * buf,unsigned count)65123ec1e5eSAmine Khaldi static void generate_tiff_palette(void *buf, unsigned count)
65223ec1e5eSAmine Khaldi {
65323ec1e5eSAmine Khaldi unsigned short *r, *g, *b;
65423ec1e5eSAmine Khaldi unsigned i;
65523ec1e5eSAmine Khaldi
65623ec1e5eSAmine Khaldi r = buf;
65723ec1e5eSAmine Khaldi g = r + count;
65823ec1e5eSAmine Khaldi b = g + count;
65923ec1e5eSAmine Khaldi
66023ec1e5eSAmine Khaldi r[0] = 0x11 * 257;
66123ec1e5eSAmine Khaldi g[0] = 0x22 * 257;
66223ec1e5eSAmine Khaldi b[0] = 0x33 * 257;
66323ec1e5eSAmine Khaldi r[1] = 0x44 * 257;
66423ec1e5eSAmine Khaldi g[1] = 0x55 * 257;
66523ec1e5eSAmine Khaldi b[1] = 0x66 * 257;
66623ec1e5eSAmine Khaldi r[2] = 0x77 * 257;
66723ec1e5eSAmine Khaldi g[2] = 0x88 * 257;
66823ec1e5eSAmine Khaldi b[2] = 0x99 * 257;
66923ec1e5eSAmine Khaldi r[3] = 0xa1 * 257;
67023ec1e5eSAmine Khaldi g[3] = 0xb5 * 257;
67123ec1e5eSAmine Khaldi b[3] = 0xff * 257;
67223ec1e5eSAmine Khaldi
67323ec1e5eSAmine Khaldi for (i = 4; i < count; i++)
67423ec1e5eSAmine Khaldi {
67523ec1e5eSAmine Khaldi r[i] = i * 257;
67623ec1e5eSAmine Khaldi g[i] = (i | 0x40) * 257;
67723ec1e5eSAmine Khaldi b[i] = (i | 0x80) * 257;
67823ec1e5eSAmine Khaldi }
67923ec1e5eSAmine Khaldi }
68023ec1e5eSAmine Khaldi
test_tiff_8bpp_palette(void)68123ec1e5eSAmine Khaldi static void test_tiff_8bpp_palette(void)
68223ec1e5eSAmine Khaldi {
68323ec1e5eSAmine Khaldi char buf[sizeof(tiff_8bpp_data)];
68423ec1e5eSAmine Khaldi HRESULT hr;
68523ec1e5eSAmine Khaldi IWICBitmapDecoder *decoder;
68623ec1e5eSAmine Khaldi IWICBitmapFrameDecode *frame;
68723ec1e5eSAmine Khaldi IWICPalette *palette;
68823ec1e5eSAmine Khaldi GUID format;
68923ec1e5eSAmine Khaldi UINT count, ret;
69023ec1e5eSAmine Khaldi WICColor color[256];
69123ec1e5eSAmine Khaldi
69223ec1e5eSAmine Khaldi memcpy(buf, &tiff_8bpp_data, sizeof(tiff_8bpp_data));
69323ec1e5eSAmine Khaldi generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_8bpp_data, palette_data), 256);
69423ec1e5eSAmine Khaldi
69523ec1e5eSAmine Khaldi hr = create_decoder(buf, sizeof(buf), &decoder);
69623ec1e5eSAmine Khaldi ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
69723ec1e5eSAmine Khaldi if (hr != S_OK) return;
69823ec1e5eSAmine Khaldi
69923ec1e5eSAmine Khaldi hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
70023ec1e5eSAmine Khaldi ok(hr == S_OK, "GetFrame error %#x\n", hr);
70123ec1e5eSAmine Khaldi
70223ec1e5eSAmine Khaldi hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
70323ec1e5eSAmine Khaldi ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
70423ec1e5eSAmine Khaldi ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed),
70523ec1e5eSAmine Khaldi "expected GUID_WICPixelFormat8bppIndexed, got %s\n", wine_dbgstr_guid(&format));
70623ec1e5eSAmine Khaldi
70723ec1e5eSAmine Khaldi hr = IWICImagingFactory_CreatePalette(factory, &palette);
70823ec1e5eSAmine Khaldi ok(hr == S_OK, "CreatePalette error %#x\n", hr);
70923ec1e5eSAmine Khaldi hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
71023ec1e5eSAmine Khaldi ok(hr == S_OK, "CopyPalette error %#x\n", hr);
71123ec1e5eSAmine Khaldi
71223ec1e5eSAmine Khaldi hr = IWICPalette_GetColorCount(palette, &count);
71323ec1e5eSAmine Khaldi ok(hr == S_OK, "GetColorCount error %#x\n", hr);
71423ec1e5eSAmine Khaldi ok(count == 256, "expected 256, got %u\n", count);
71523ec1e5eSAmine Khaldi
71623ec1e5eSAmine Khaldi hr = IWICPalette_GetColors(palette, 256, color, &ret);
71723ec1e5eSAmine Khaldi ok(hr == S_OK, "GetColors error %#x\n", hr);
71823ec1e5eSAmine Khaldi ok(ret == count, "expected %u, got %u\n", count, ret);
71923ec1e5eSAmine Khaldi ok(color[0] == 0xff112233, "got %#x\n", color[0]);
72023ec1e5eSAmine Khaldi ok(color[1] == 0xff445566, "got %#x\n", color[1]);
72123ec1e5eSAmine Khaldi ok(color[2] == 0xff778899, "got %#x\n", color[2]);
72223ec1e5eSAmine Khaldi ok(color[3] == 0xffa1b5ff, "got %#x\n", color[3]);
72323ec1e5eSAmine Khaldi
72423ec1e5eSAmine Khaldi IWICPalette_Release(palette);
72523ec1e5eSAmine Khaldi IWICBitmapFrameDecode_Release(frame);
72623ec1e5eSAmine Khaldi IWICBitmapDecoder_Release(decoder);
72723ec1e5eSAmine Khaldi }
72823ec1e5eSAmine Khaldi
test_tiff_resolution(void)72923ec1e5eSAmine Khaldi static void test_tiff_resolution(void)
73023ec1e5eSAmine Khaldi {
73123ec1e5eSAmine Khaldi HRESULT hr;
73223ec1e5eSAmine Khaldi IWICBitmapDecoder *decoder;
73323ec1e5eSAmine Khaldi IWICBitmapFrameDecode *frame;
73423ec1e5eSAmine Khaldi double dpi_x, dpi_y;
73523ec1e5eSAmine Khaldi int i;
73623ec1e5eSAmine Khaldi
737eea81f52SAmine Khaldi for (i = 0; i < ARRAY_SIZE(tiff_resolution_test_data); i++)
73823ec1e5eSAmine Khaldi {
73923ec1e5eSAmine Khaldi const struct tiff_resolution_test_data *test_data = &tiff_resolution_test_data[i];
74023ec1e5eSAmine Khaldi tiff_resolution_image_data.resx = test_data->resx;
74123ec1e5eSAmine Khaldi tiff_resolution_image_data.resy = test_data->resy;
74223ec1e5eSAmine Khaldi tiff_resolution_image_data.entry[12].value = test_data->resolution_unit;
74323ec1e5eSAmine Khaldi
74423ec1e5eSAmine Khaldi hr = create_decoder(&tiff_resolution_image_data, sizeof(tiff_resolution_image_data), &decoder);
74523ec1e5eSAmine Khaldi ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
74623ec1e5eSAmine Khaldi if (hr != S_OK) return;
74723ec1e5eSAmine Khaldi
74823ec1e5eSAmine Khaldi hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
74923ec1e5eSAmine Khaldi ok(hr == S_OK, "%d: GetFrame error %#x\n", i, hr);
75023ec1e5eSAmine Khaldi
75123ec1e5eSAmine Khaldi hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y);
75223ec1e5eSAmine Khaldi ok(hr == S_OK, "%d: GetResolution error %#x\n", i, hr);
75323ec1e5eSAmine Khaldi
75423ec1e5eSAmine Khaldi if (test_data->broken_dpi_x != 0)
75523ec1e5eSAmine Khaldi {
75623ec1e5eSAmine Khaldi ok(fabs(dpi_x - test_data->expected_dpi_x) < 0.01 || broken(fabs(dpi_x - test_data->broken_dpi_x) < 0.01),
75723ec1e5eSAmine Khaldi "%d: x: expected %f or %f, got %f\n", i, test_data->expected_dpi_x, test_data->broken_dpi_x, dpi_x);
75823ec1e5eSAmine Khaldi }
75923ec1e5eSAmine Khaldi else
76023ec1e5eSAmine Khaldi {
76123ec1e5eSAmine Khaldi ok(fabs(dpi_x - test_data->expected_dpi_x) < 0.01,
76223ec1e5eSAmine Khaldi "%d: x: expected %f, got %f\n", i, test_data->expected_dpi_x, dpi_x);
76323ec1e5eSAmine Khaldi }
76423ec1e5eSAmine Khaldi
76523ec1e5eSAmine Khaldi if (test_data->broken_dpi_y != 0)
76623ec1e5eSAmine Khaldi {
76723ec1e5eSAmine Khaldi ok(fabs(dpi_y - test_data->expected_dpi_y) < 0.01 || broken(fabs(dpi_y - test_data->broken_dpi_y) < 0.01),
76823ec1e5eSAmine Khaldi "%d: y: expected %f or %f, got %f\n", i, test_data->expected_dpi_y, test_data->broken_dpi_y, dpi_y);
76923ec1e5eSAmine Khaldi }
77023ec1e5eSAmine Khaldi else
77123ec1e5eSAmine Khaldi {
77223ec1e5eSAmine Khaldi ok(fabs(dpi_y - test_data->expected_dpi_y) < 0.01,
77323ec1e5eSAmine Khaldi "%d: y: expected %f, got %f\n", i, test_data->expected_dpi_y, dpi_y);
77423ec1e5eSAmine Khaldi }
77523ec1e5eSAmine Khaldi
77623ec1e5eSAmine Khaldi IWICBitmapFrameDecode_Release(frame);
77723ec1e5eSAmine Khaldi IWICBitmapDecoder_Release(decoder);
77823ec1e5eSAmine Khaldi }
77923ec1e5eSAmine Khaldi }
78023ec1e5eSAmine Khaldi
test_tiff_24bpp(void)781eea81f52SAmine Khaldi static void test_tiff_24bpp(void)
782eea81f52SAmine Khaldi {
783eea81f52SAmine Khaldi HRESULT hr;
784eea81f52SAmine Khaldi IWICBitmapDecoder *decoder;
785eea81f52SAmine Khaldi IWICBitmapFrameDecode *frame;
786eea81f52SAmine Khaldi UINT count, width, height, i, stride;
787eea81f52SAmine Khaldi double dpi_x, dpi_y;
788eea81f52SAmine Khaldi GUID format;
789eea81f52SAmine Khaldi WICRect rc;
790eea81f52SAmine Khaldi BYTE data[3];
791eea81f52SAmine Khaldi static const BYTE expected_data[] = { 0x33,0x22,0x11 };
792eea81f52SAmine Khaldi
793eea81f52SAmine Khaldi hr = create_decoder(&tiff_24bpp_data, sizeof(tiff_24bpp_data), &decoder);
794cc48f9d4SAmine Khaldi ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
795cc48f9d4SAmine Khaldi if (hr != S_OK) return;
796eea81f52SAmine Khaldi ok(decoder != NULL, "Failed to load TIFF image data\n");
797eea81f52SAmine Khaldi
798eea81f52SAmine Khaldi hr = IWICBitmapDecoder_GetFrameCount(decoder, &count);
799eea81f52SAmine Khaldi ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
800eea81f52SAmine Khaldi ok(count == 1, "got %u\n", count);
801eea81f52SAmine Khaldi
802eea81f52SAmine Khaldi hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
803eea81f52SAmine Khaldi ok(hr == S_OK, "GetFrame error %#x\n", hr);
804eea81f52SAmine Khaldi
805eea81f52SAmine Khaldi hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
806eea81f52SAmine Khaldi ok(hr == S_OK, "GetSize error %#x\n", hr);
807eea81f52SAmine Khaldi ok(width == 1, "got %u\n", width);
808eea81f52SAmine Khaldi ok(height == 1, "got %u\n", height);
809eea81f52SAmine Khaldi
810eea81f52SAmine Khaldi hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y);
811eea81f52SAmine Khaldi ok(hr == S_OK, "GetResolution error %#x\n", hr);
812eea81f52SAmine Khaldi ok(dpi_x == 300.0, "got %f\n", dpi_x);
813eea81f52SAmine Khaldi ok(dpi_y == 300.0, "got %f\n", dpi_y);
814eea81f52SAmine Khaldi
815eea81f52SAmine Khaldi hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
816eea81f52SAmine Khaldi ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
817eea81f52SAmine Khaldi ok(IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR),
818eea81f52SAmine Khaldi "got wrong format %s\n", wine_dbgstr_guid(&format));
819eea81f52SAmine Khaldi
820eea81f52SAmine Khaldi for (stride = 0; stride <= 32; stride++)
821eea81f52SAmine Khaldi {
822eea81f52SAmine Khaldi memset(data, 0, sizeof(data));
823eea81f52SAmine Khaldi rc.X = 0;
824eea81f52SAmine Khaldi rc.Y = 0;
825eea81f52SAmine Khaldi rc.Width = 1;
826eea81f52SAmine Khaldi rc.Height = 1;
827eea81f52SAmine Khaldi hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, stride, sizeof(data), data);
828eea81f52SAmine Khaldi if (stride < 3)
829eea81f52SAmine Khaldi ok(hr == E_INVALIDARG, "CopyPixels(%u) should fail: %#x\n", stride, hr);
830eea81f52SAmine Khaldi else
831eea81f52SAmine Khaldi {
832eea81f52SAmine Khaldi ok(hr == S_OK, "CopyPixels(%u) error %#x\n", stride, hr);
833eea81f52SAmine Khaldi
834eea81f52SAmine Khaldi for (i = 0; i < sizeof(data); i++)
835eea81f52SAmine Khaldi ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]);
836eea81f52SAmine Khaldi }
837eea81f52SAmine Khaldi }
838eea81f52SAmine Khaldi
839eea81f52SAmine Khaldi IWICBitmapFrameDecode_Release(frame);
840eea81f52SAmine Khaldi IWICBitmapDecoder_Release(decoder);
841eea81f52SAmine Khaldi }
842eea81f52SAmine Khaldi
84323ec1e5eSAmine Khaldi #include "pshpack2.h"
84423ec1e5eSAmine Khaldi static const struct tiff_1x1_data
84523ec1e5eSAmine Khaldi {
84623ec1e5eSAmine Khaldi USHORT byte_order;
84723ec1e5eSAmine Khaldi USHORT version;
84823ec1e5eSAmine Khaldi ULONG dir_offset;
84923ec1e5eSAmine Khaldi USHORT number_of_entries;
85023ec1e5eSAmine Khaldi struct IFD_entry entry[12];
85123ec1e5eSAmine Khaldi ULONG next_IFD;
85223ec1e5eSAmine Khaldi struct IFD_rational res;
85323ec1e5eSAmine Khaldi short palette_data[3][256];
85423ec1e5eSAmine Khaldi short bps_data[4];
85523ec1e5eSAmine Khaldi BYTE pixel_data[32];
85623ec1e5eSAmine Khaldi } tiff_1x1_data =
85723ec1e5eSAmine Khaldi {
85823ec1e5eSAmine Khaldi #ifdef WORDS_BIGENDIAN
85923ec1e5eSAmine Khaldi 'M' | 'M' << 8,
86023ec1e5eSAmine Khaldi #else
86123ec1e5eSAmine Khaldi 'I' | 'I' << 8,
86223ec1e5eSAmine Khaldi #endif
86323ec1e5eSAmine Khaldi 42,
86423ec1e5eSAmine Khaldi FIELD_OFFSET(struct tiff_1x1_data, number_of_entries),
86523ec1e5eSAmine Khaldi 12,
86623ec1e5eSAmine Khaldi {
86723ec1e5eSAmine Khaldi { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
86823ec1e5eSAmine Khaldi { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */
86923ec1e5eSAmine Khaldi { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
87023ec1e5eSAmine Khaldi { 0x102, IFD_SHORT, 3, FIELD_OFFSET(struct tiff_1x1_data, bps_data) }, /* BITSPERSAMPLE */
87123ec1e5eSAmine Khaldi { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
87223ec1e5eSAmine Khaldi { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */
87323ec1e5eSAmine Khaldi { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1x1_data, pixel_data) }, /* STRIPOFFSETS */
87423ec1e5eSAmine Khaldi { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */
87523ec1e5eSAmine Khaldi { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) },
87623ec1e5eSAmine Khaldi { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) },
87723ec1e5eSAmine Khaldi { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
87823ec1e5eSAmine Khaldi { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */
87923ec1e5eSAmine Khaldi },
88023ec1e5eSAmine Khaldi 0,
88123ec1e5eSAmine Khaldi { 96, 1 },
88223ec1e5eSAmine Khaldi { { 0 } },
88323ec1e5eSAmine Khaldi { 8,8,8,0 },
88423ec1e5eSAmine Khaldi { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }
88523ec1e5eSAmine Khaldi };
88623ec1e5eSAmine Khaldi #include "poppack.h"
88723ec1e5eSAmine Khaldi
width_bytes(UINT width,UINT bpp)88823ec1e5eSAmine Khaldi static UINT width_bytes(UINT width, UINT bpp)
88923ec1e5eSAmine Khaldi {
89023ec1e5eSAmine Khaldi return (width * bpp + 7) / 8;
89123ec1e5eSAmine Khaldi }
89223ec1e5eSAmine Khaldi
test_color_formats(void)89323ec1e5eSAmine Khaldi static void test_color_formats(void)
89423ec1e5eSAmine Khaldi {
89523ec1e5eSAmine Khaldi struct bitmap_data
89623ec1e5eSAmine Khaldi {
89723ec1e5eSAmine Khaldi UINT bpp;
89823ec1e5eSAmine Khaldi UINT width;
89923ec1e5eSAmine Khaldi UINT height;
90023ec1e5eSAmine Khaldi const WICPixelFormatGUID *format;
90123ec1e5eSAmine Khaldi const BYTE *bits;
90223ec1e5eSAmine Khaldi };
90323ec1e5eSAmine Khaldi 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 };
90423ec1e5eSAmine Khaldi static const struct bitmap_data data_1bpsBGR =
90523ec1e5eSAmine Khaldi {
90623ec1e5eSAmine Khaldi 24, 10, 2, &GUID_WICPixelFormat24bppBGR, bits_1bpsBGR
90723ec1e5eSAmine Khaldi };
90823ec1e5eSAmine Khaldi 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 };
90923ec1e5eSAmine Khaldi static const struct bitmap_data data_4bpsBGR =
91023ec1e5eSAmine Khaldi {
91123ec1e5eSAmine Khaldi 24, 5, 2, &GUID_WICPixelFormat24bppBGR, bits_4bpsBGR
91223ec1e5eSAmine Khaldi };
91323ec1e5eSAmine Khaldi static const BYTE bits_8bpsBGR[] = { 2,0,1,5,4,3,8,7,6 };
91423ec1e5eSAmine Khaldi static const struct bitmap_data data_8bpsBGR =
91523ec1e5eSAmine Khaldi {
91623ec1e5eSAmine Khaldi 24, 3, 1, &GUID_WICPixelFormat24bppBGR, bits_8bpsBGR
91723ec1e5eSAmine Khaldi };
91823ec1e5eSAmine Khaldi static const BYTE bits_48bppRGB[] = { 1,0,2,3,4,5,6,7,8,9,0,1 };
91923ec1e5eSAmine Khaldi static const struct bitmap_data data_48bppRGB =
92023ec1e5eSAmine Khaldi {
92123ec1e5eSAmine Khaldi 48, 2, 1, &GUID_WICPixelFormat48bppRGB, bits_48bppRGB
92223ec1e5eSAmine Khaldi };
92323ec1e5eSAmine Khaldi 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 };
92423ec1e5eSAmine Khaldi static const struct bitmap_data data_1bpsBGRA =
92523ec1e5eSAmine Khaldi {
92623ec1e5eSAmine Khaldi 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_1bpsBGRA
92723ec1e5eSAmine Khaldi };
92823ec1e5eSAmine Khaldi 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 };
92923ec1e5eSAmine Khaldi static const struct bitmap_data data_4bpsBGRA =
93023ec1e5eSAmine Khaldi {
93123ec1e5eSAmine Khaldi 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_4bpsBGRA
93223ec1e5eSAmine Khaldi };
93323ec1e5eSAmine Khaldi static const BYTE bits_8bpsBGRA[] = { 2,0,1,3,6,5,4,7,0,9,8,1,4,3,2,5 };
93423ec1e5eSAmine Khaldi static const struct bitmap_data data_8bpsBGRA =
93523ec1e5eSAmine Khaldi {
93623ec1e5eSAmine Khaldi 32, 4, 1, &GUID_WICPixelFormat32bppBGRA, bits_8bpsBGRA
93723ec1e5eSAmine Khaldi };
93823ec1e5eSAmine Khaldi static const BYTE bits_64bppRGBA[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 };
93923ec1e5eSAmine Khaldi static const struct bitmap_data data_64bppRGBA =
94023ec1e5eSAmine Khaldi {
94123ec1e5eSAmine Khaldi 64, 2, 1, &GUID_WICPixelFormat64bppRGBA, bits_64bppRGBA
94223ec1e5eSAmine Khaldi };
94323ec1e5eSAmine Khaldi static const BYTE bits_BlackWhite[] = { 85,195,184,85 };
94423ec1e5eSAmine Khaldi static const struct bitmap_data data_BlackWhite =
94523ec1e5eSAmine Khaldi {
94623ec1e5eSAmine Khaldi 1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite
94723ec1e5eSAmine Khaldi };
94823ec1e5eSAmine Khaldi static const BYTE bits_BlackWhite_xp[] = { 85,195,184,84 };
94923ec1e5eSAmine Khaldi static const struct bitmap_data data_BlackWhite_xp =
95023ec1e5eSAmine Khaldi {
95123ec1e5eSAmine Khaldi 1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite_xp
95223ec1e5eSAmine Khaldi };
95323ec1e5eSAmine Khaldi static const BYTE bits_4bppGray[] = { 85,195,184,85 };
95423ec1e5eSAmine Khaldi static const struct bitmap_data data_4bppGray =
95523ec1e5eSAmine Khaldi {
95623ec1e5eSAmine Khaldi 4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray
95723ec1e5eSAmine Khaldi };
95823ec1e5eSAmine Khaldi static const BYTE bits_4bppGray_xp[] = { 85,195,184,80 };
95923ec1e5eSAmine Khaldi static const struct bitmap_data data_4bppGray_xp =
96023ec1e5eSAmine Khaldi {
96123ec1e5eSAmine Khaldi 4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray_xp
96223ec1e5eSAmine Khaldi };
96323ec1e5eSAmine Khaldi static const BYTE bits_8bppGray[] = { 1,0,2,3,4,5,6,7,8,9 };
96423ec1e5eSAmine Khaldi static const struct bitmap_data data_8bppGray =
96523ec1e5eSAmine Khaldi {
96623ec1e5eSAmine Khaldi 8, 10, 1, &GUID_WICPixelFormat8bppGray, bits_8bppGray
96723ec1e5eSAmine Khaldi };
96823ec1e5eSAmine Khaldi static const BYTE bits_16bppGray[] = { 1,0,2,3,4,5 };
96923ec1e5eSAmine Khaldi static const struct bitmap_data data_16bppGray =
97023ec1e5eSAmine Khaldi {
97123ec1e5eSAmine Khaldi 16, 3, 1, &GUID_WICPixelFormat16bppGray, bits_16bppGray
97223ec1e5eSAmine Khaldi };
97323ec1e5eSAmine Khaldi static const BYTE bits_32bppGrayFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1 };
97423ec1e5eSAmine Khaldi static const struct bitmap_data data_32bppGrayFloat =
97523ec1e5eSAmine Khaldi {
97623ec1e5eSAmine Khaldi 32, 3, 1, &GUID_WICPixelFormat32bppGrayFloat, bits_32bppGrayFloat
97723ec1e5eSAmine Khaldi };
97823ec1e5eSAmine Khaldi #if 0 /* FIXME */
97923ec1e5eSAmine Khaldi static const BYTE bits_96bpp3Channels[] = { 0 };
98023ec1e5eSAmine Khaldi static const struct bitmap_data data_96bpp3Channels =
98123ec1e5eSAmine Khaldi {
98223ec1e5eSAmine Khaldi 64, 1, 1, &GUID_WICPixelFormat96bpp3Channels, bits_96bpp3Channels
98323ec1e5eSAmine Khaldi };
98423ec1e5eSAmine Khaldi #endif
98523ec1e5eSAmine Khaldi static const BYTE bits_128bppRGBAFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 };
98623ec1e5eSAmine Khaldi static const struct bitmap_data data_128bppRGBAFloat =
98723ec1e5eSAmine Khaldi {
98823ec1e5eSAmine Khaldi 128, 1, 1, &GUID_WICPixelFormat128bppRGBAFloat, bits_128bppRGBAFloat
98923ec1e5eSAmine Khaldi };
99023ec1e5eSAmine Khaldi static const BYTE bits_1bppIndexed[] = { 85,195,184,85 };
99123ec1e5eSAmine Khaldi static const struct bitmap_data data_1bppIndexed =
99223ec1e5eSAmine Khaldi {
99323ec1e5eSAmine Khaldi 1, 32, 1, &GUID_WICPixelFormat1bppIndexed, bits_1bppIndexed
99423ec1e5eSAmine Khaldi };
99523ec1e5eSAmine Khaldi static const BYTE bits_4bppIndexed[] = { 85,195,184,85 };
99623ec1e5eSAmine Khaldi static const struct bitmap_data data_4bppIndexed =
99723ec1e5eSAmine Khaldi {
99823ec1e5eSAmine Khaldi 4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed
99923ec1e5eSAmine Khaldi };
100023ec1e5eSAmine Khaldi static const BYTE bits_4bppIndexed_xp[] = { 85,195,184,80 };
100123ec1e5eSAmine Khaldi static const struct bitmap_data data_4bppIndexed_xp =
100223ec1e5eSAmine Khaldi {
100323ec1e5eSAmine Khaldi 4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed_xp
100423ec1e5eSAmine Khaldi };
100523ec1e5eSAmine Khaldi static const BYTE bits_8bppIndexed[] = { 1,0,2,3,4,5,6,7,8,9 };
100623ec1e5eSAmine Khaldi static const struct bitmap_data data_8bppIndexed =
100723ec1e5eSAmine Khaldi {
100823ec1e5eSAmine Khaldi 8, 3, 1, &GUID_WICPixelFormat8bppIndexed, bits_8bppIndexed
100923ec1e5eSAmine Khaldi };
101023ec1e5eSAmine Khaldi static const BYTE bits_32bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1 };
101123ec1e5eSAmine Khaldi static const struct bitmap_data data_32bppCMYK =
101223ec1e5eSAmine Khaldi {
101323ec1e5eSAmine Khaldi 32, 3, 1, &GUID_WICPixelFormat32bppCMYK, bits_32bppCMYK
101423ec1e5eSAmine Khaldi };
101523ec1e5eSAmine Khaldi static const BYTE bits_64bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 };
101623ec1e5eSAmine Khaldi static const struct bitmap_data data_64bppCMYK =
101723ec1e5eSAmine Khaldi {
101823ec1e5eSAmine Khaldi 64, 2, 1, &GUID_WICPixelFormat64bppCMYK, bits_64bppCMYK
101923ec1e5eSAmine Khaldi };
102023ec1e5eSAmine Khaldi static const struct
102123ec1e5eSAmine Khaldi {
102223ec1e5eSAmine Khaldi int photometric; /* PhotometricInterpretation */
102323ec1e5eSAmine Khaldi int samples; /* SamplesPerPixel */
102423ec1e5eSAmine Khaldi int bps; /* BitsPerSample */
102523ec1e5eSAmine Khaldi const struct bitmap_data *data;
102623ec1e5eSAmine Khaldi const struct bitmap_data *alt_data;
102723ec1e5eSAmine Khaldi } td[] =
102823ec1e5eSAmine Khaldi {
102923ec1e5eSAmine Khaldi /* 2 - RGB */
103023ec1e5eSAmine Khaldi { 2, 3, 1, &data_1bpsBGR },
103123ec1e5eSAmine Khaldi { 2, 3, 4, &data_4bpsBGR },
103223ec1e5eSAmine Khaldi { 2, 3, 8, &data_8bpsBGR },
103323ec1e5eSAmine Khaldi { 2, 3, 16, &data_48bppRGB },
103423ec1e5eSAmine Khaldi { 2, 3, 24, NULL },
103523ec1e5eSAmine Khaldi #if 0 /* FIXME */
103623ec1e5eSAmine Khaldi { 2, 3, 32, &data_96bpp3Channels },
103723ec1e5eSAmine Khaldi #endif
103823ec1e5eSAmine Khaldi { 2, 4, 1, &data_1bpsBGRA },
103923ec1e5eSAmine Khaldi { 2, 4, 4, &data_4bpsBGRA },
104023ec1e5eSAmine Khaldi { 2, 4, 8, &data_8bpsBGRA },
104123ec1e5eSAmine Khaldi { 2, 4, 16, &data_64bppRGBA },
104223ec1e5eSAmine Khaldi { 2, 4, 24, NULL },
104323ec1e5eSAmine Khaldi { 2, 4, 32, &data_128bppRGBAFloat },
104423ec1e5eSAmine Khaldi /* 1 - BlackIsZero (Bilevel) */
104523ec1e5eSAmine Khaldi { 1, 1, 1, &data_BlackWhite, &data_BlackWhite_xp },
104623ec1e5eSAmine Khaldi { 1, 1, 4, &data_4bppGray, &data_4bppGray_xp },
104723ec1e5eSAmine Khaldi { 1, 1, 8, &data_8bppGray },
104823ec1e5eSAmine Khaldi { 1, 1, 16, &data_16bppGray },
104923ec1e5eSAmine Khaldi { 1, 1, 24, NULL },
105023ec1e5eSAmine Khaldi { 1, 1, 32, &data_32bppGrayFloat },
105123ec1e5eSAmine Khaldi /* 3 - Palette Color */
105223ec1e5eSAmine Khaldi { 3, 1, 1, &data_1bppIndexed },
105323ec1e5eSAmine Khaldi { 3, 1, 4, &data_4bppIndexed, &data_4bppIndexed_xp },
105423ec1e5eSAmine Khaldi { 3, 1, 8, &data_8bppIndexed },
105523ec1e5eSAmine Khaldi #if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */
105623ec1e5eSAmine Khaldi { 3, 1, 16, &data_8bppIndexed },
105723ec1e5eSAmine Khaldi { 3, 1, 24, &data_8bppIndexed },
105823ec1e5eSAmine Khaldi { 3, 1, 32, &data_8bppIndexed },
105923ec1e5eSAmine Khaldi #endif
106023ec1e5eSAmine Khaldi /* 5 - Separated */
106123ec1e5eSAmine Khaldi { 5, 4, 1, NULL },
106223ec1e5eSAmine Khaldi { 5, 4, 4, NULL },
106323ec1e5eSAmine Khaldi { 5, 4, 8, &data_32bppCMYK },
106423ec1e5eSAmine Khaldi { 5, 4, 16, &data_64bppCMYK },
106523ec1e5eSAmine Khaldi { 5, 4, 24, NULL },
106623ec1e5eSAmine Khaldi { 5, 4, 32, NULL },
106723ec1e5eSAmine Khaldi };
106823ec1e5eSAmine Khaldi BYTE buf[sizeof(tiff_1x1_data)];
106923ec1e5eSAmine Khaldi BYTE pixels[256];
107023ec1e5eSAmine Khaldi HRESULT hr;
107123ec1e5eSAmine Khaldi IWICBitmapDecoder *decoder;
107223ec1e5eSAmine Khaldi IWICBitmapFrameDecode *frame;
107323ec1e5eSAmine Khaldi GUID format;
107423ec1e5eSAmine Khaldi UINT count, i, bpp, channels, ret;
107523ec1e5eSAmine Khaldi BOOL trasparency;
107623ec1e5eSAmine Khaldi struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL;
107723ec1e5eSAmine Khaldi struct IFD_entry *tag_width = NULL, *tag_height = NULL;
107823ec1e5eSAmine Khaldi short *bps;
107923ec1e5eSAmine Khaldi
108023ec1e5eSAmine Khaldi memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data));
108123ec1e5eSAmine Khaldi generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_1x1_data, palette_data), 256);
108223ec1e5eSAmine Khaldi
108323ec1e5eSAmine Khaldi count = *(short *)(buf + tiff_1x1_data.dir_offset);
108423ec1e5eSAmine Khaldi tag = (struct IFD_entry *)(buf + tiff_1x1_data.dir_offset + sizeof(short));
108523ec1e5eSAmine Khaldi
108623ec1e5eSAmine Khaldi /* verify the TIFF structure */
108723ec1e5eSAmine Khaldi for (i = 0; i < count; i++)
108823ec1e5eSAmine Khaldi {
108923ec1e5eSAmine Khaldi if (tag[i].id == 0x100) /* ImageWidth */
109023ec1e5eSAmine Khaldi tag_width = &tag[i];
109123ec1e5eSAmine Khaldi else if (tag[i].id == 0x101) /* ImageLength */
109223ec1e5eSAmine Khaldi tag_height = &tag[i];
109323ec1e5eSAmine Khaldi else if (tag[i].id == 0x102) /* BitsPerSample */
109423ec1e5eSAmine Khaldi tag_bps = &tag[i];
109523ec1e5eSAmine Khaldi else if (tag[i].id == 0x106) /* PhotometricInterpretation */
109623ec1e5eSAmine Khaldi tag_photo = &tag[i];
109723ec1e5eSAmine Khaldi else if (tag[i].id == 0x115) /* SamplesPerPixel */
109823ec1e5eSAmine Khaldi tag_samples = &tag[i];
109923ec1e5eSAmine Khaldi else if (tag[i].id == 0x140) /* ColorMap */
110023ec1e5eSAmine Khaldi tag_colormap = &tag[i];
110123ec1e5eSAmine Khaldi }
110223ec1e5eSAmine Khaldi
110323ec1e5eSAmine Khaldi ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n");
110423ec1e5eSAmine Khaldi if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return;
110523ec1e5eSAmine Khaldi
110623ec1e5eSAmine Khaldi ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n");
110723ec1e5eSAmine Khaldi bps = (short *)(buf + tag_bps->value);
110823ec1e5eSAmine Khaldi ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0,
110923ec1e5eSAmine Khaldi "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]);
111023ec1e5eSAmine Khaldi
111123ec1e5eSAmine Khaldi for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
111223ec1e5eSAmine Khaldi {
111323ec1e5eSAmine Khaldi if (td[i].data)
111423ec1e5eSAmine Khaldi {
111523ec1e5eSAmine Khaldi bpp = td[i].samples * td[i].bps;
111623ec1e5eSAmine Khaldi if (winetest_debug > 1)
111723ec1e5eSAmine Khaldi trace("samples %u, bps %u, bpp %u, width %u => width_bytes %u\n", td[i].samples, td[i].bps, bpp,
111823ec1e5eSAmine Khaldi td[i].data->width, width_bytes(td[i].data->width, bpp));
111923ec1e5eSAmine Khaldi tag_width->value = td[i].data->width;
112023ec1e5eSAmine Khaldi tag_height->value = td[i].data->height;
112123ec1e5eSAmine Khaldi }
112223ec1e5eSAmine Khaldi else
112323ec1e5eSAmine Khaldi {
112423ec1e5eSAmine Khaldi tag_width->value = 1;
112523ec1e5eSAmine Khaldi tag_height->value = 1;
112623ec1e5eSAmine Khaldi }
112723ec1e5eSAmine Khaldi
112823ec1e5eSAmine Khaldi tag_colormap->count = (1 << td[i].bps) * 3;
112923ec1e5eSAmine Khaldi
113023ec1e5eSAmine Khaldi if (td[i].bps < 8)
113123ec1e5eSAmine Khaldi {
113223ec1e5eSAmine Khaldi buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 0x55;
113323ec1e5eSAmine Khaldi buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0xc3;
113423ec1e5eSAmine Khaldi buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 0xb8;
113523ec1e5eSAmine Khaldi buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 0x55;
113623ec1e5eSAmine Khaldi }
113723ec1e5eSAmine Khaldi else
113823ec1e5eSAmine Khaldi {
113923ec1e5eSAmine Khaldi buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 1;
114023ec1e5eSAmine Khaldi buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0;
114123ec1e5eSAmine Khaldi buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 2;
114223ec1e5eSAmine Khaldi buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 3;
114323ec1e5eSAmine Khaldi }
114423ec1e5eSAmine Khaldi
114523ec1e5eSAmine Khaldi tag_photo->value = td[i].photometric;
114623ec1e5eSAmine Khaldi tag_bps->count = td[i].samples;
114723ec1e5eSAmine Khaldi tag_samples->value = td[i].samples;
114823ec1e5eSAmine Khaldi
114923ec1e5eSAmine Khaldi if (td[i].samples == 1)
115023ec1e5eSAmine Khaldi tag_bps->value = td[i].bps;
115123ec1e5eSAmine Khaldi else if (td[i].samples == 2)
115223ec1e5eSAmine Khaldi tag_bps->value = MAKELONG(td[i].bps, td[i].bps);
115323ec1e5eSAmine Khaldi else if (td[i].samples == 3)
115423ec1e5eSAmine Khaldi {
115523ec1e5eSAmine Khaldi tag_bps->value = (BYTE *)bps - buf;
115623ec1e5eSAmine Khaldi bps[0] = bps[1] = bps[2] = td[i].bps;
115723ec1e5eSAmine Khaldi }
115823ec1e5eSAmine Khaldi else if (td[i].samples == 4)
115923ec1e5eSAmine Khaldi {
116023ec1e5eSAmine Khaldi tag_bps->value = (BYTE *)bps - buf;
116123ec1e5eSAmine Khaldi bps[0] = bps[1] = bps[2] = bps[3] = td[i].bps;
116223ec1e5eSAmine Khaldi }
116323ec1e5eSAmine Khaldi else
116423ec1e5eSAmine Khaldi {
116523ec1e5eSAmine Khaldi ok(0, "%u: unsupported samples count %d\n", i, td[i].samples);
116623ec1e5eSAmine Khaldi continue;
116723ec1e5eSAmine Khaldi }
116823ec1e5eSAmine Khaldi
116923ec1e5eSAmine Khaldi hr = create_decoder(buf, sizeof(buf), &decoder);
117023ec1e5eSAmine Khaldi if (!td[i].data)
117123ec1e5eSAmine Khaldi {
117223ec1e5eSAmine Khaldi ok(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_COMPONENTNOTFOUND /* win8+ */ || WINCODEC_ERR_BADIMAGE /* XP */,
117323ec1e5eSAmine Khaldi "%u: (%d,%d,%d) wrong error %#x\n", i, td[i].photometric, td[i].samples, td[i].bps, hr);
117423ec1e5eSAmine Khaldi if (hr == S_OK)
117523ec1e5eSAmine Khaldi {
117623ec1e5eSAmine Khaldi IWICBitmapDecoder_Release(decoder);
117723ec1e5eSAmine Khaldi dump_tiff(buf);
117823ec1e5eSAmine Khaldi }
117923ec1e5eSAmine Khaldi continue;
118023ec1e5eSAmine Khaldi }
118123ec1e5eSAmine Khaldi else
118223ec1e5eSAmine Khaldi ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_BADIMAGE) /* XP */,
118323ec1e5eSAmine Khaldi "%u: failed to load TIFF image data (%d,%d,%d) %#x\n",
118423ec1e5eSAmine Khaldi i, td[i].photometric, td[i].samples, td[i].bps, hr);
118523ec1e5eSAmine Khaldi if (hr != S_OK) continue;
118623ec1e5eSAmine Khaldi
118723ec1e5eSAmine Khaldi hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
118823ec1e5eSAmine Khaldi ok(hr == S_OK, "%u: GetFrame error %#x\n", i, hr);
118923ec1e5eSAmine Khaldi
119023ec1e5eSAmine Khaldi hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
119123ec1e5eSAmine Khaldi ok(hr == S_OK, "%u: GetPixelFormat error %#x\n", i, hr);
119223ec1e5eSAmine Khaldi ok(IsEqualGUID(&format, td[i].data->format),
119323ec1e5eSAmine Khaldi "%u (%d,%d,%d): expected %s, got %s\n",
119423ec1e5eSAmine Khaldi i, td[i].photometric, td[i].samples, td[i].bps,
119523ec1e5eSAmine Khaldi wine_dbgstr_guid(td[i].data->format), wine_dbgstr_guid(&format));
119623ec1e5eSAmine Khaldi
119723ec1e5eSAmine Khaldi trasparency = (td[i].photometric == 2 && td[i].samples == 4); /* for XP */
119823ec1e5eSAmine Khaldi hr = get_pixelformat_info(&format, &bpp, &channels, &trasparency);
119923ec1e5eSAmine Khaldi ok(hr == S_OK, "%u: get_pixelformat_bpp error %#x\n", i, hr);
120023ec1e5eSAmine Khaldi ok(bpp == td[i].data->bpp, "%u: expected %u, got %u\n", i, td[i].data->bpp, bpp);
120123ec1e5eSAmine Khaldi ok(channels == td[i].samples, "%u: expected %u, got %u\n", i, td[i].samples, channels);
120223ec1e5eSAmine Khaldi ok(trasparency == (td[i].photometric == 2 && td[i].samples == 4), "%u: got %u\n", i, trasparency);
120323ec1e5eSAmine Khaldi
120423ec1e5eSAmine Khaldi memset(pixels, 0, sizeof(pixels));
120523ec1e5eSAmine Khaldi hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, width_bytes(td[i].data->width, bpp), sizeof(pixels), pixels);
120623ec1e5eSAmine Khaldi ok(hr == S_OK, "%u: CopyPixels error %#x\n", i, hr);
120723ec1e5eSAmine Khaldi ret = memcmp(pixels, td[i].data->bits, width_bytes(td[i].data->width, bpp));
120823ec1e5eSAmine Khaldi if (ret && td[i].alt_data)
120923ec1e5eSAmine Khaldi ret = memcmp(pixels, td[i].alt_data->bits, width_bytes(td[i].data->width, bpp));
121023ec1e5eSAmine Khaldi ok(ret == 0, "%u: (%d,%d,%d) wrong pixel data\n", i, td[i].photometric, td[i].samples, td[i].bps);
121123ec1e5eSAmine Khaldi if (ret)
121223ec1e5eSAmine Khaldi {
121323ec1e5eSAmine Khaldi UINT j, n = width_bytes(td[i].data->width, bpp);
121423ec1e5eSAmine Khaldi for (j = 0; j < n; j++)
121523ec1e5eSAmine Khaldi printf("%u%s", pixels[j], (j + 1) < n ? "," : "\n");
121623ec1e5eSAmine Khaldi }
121723ec1e5eSAmine Khaldi
121823ec1e5eSAmine Khaldi IWICBitmapFrameDecode_Release(frame);
121923ec1e5eSAmine Khaldi IWICBitmapDecoder_Release(decoder);
122023ec1e5eSAmine Khaldi }
122123ec1e5eSAmine Khaldi }
122223ec1e5eSAmine Khaldi
test_tiff_4bps_bgra(void)1223*3e9c4dadSThomas Faber static void test_tiff_4bps_bgra(void)
1224*3e9c4dadSThomas Faber {
1225*3e9c4dadSThomas Faber HRESULT hr;
1226*3e9c4dadSThomas Faber IWICBitmapDecoder *decoder;
1227*3e9c4dadSThomas Faber IWICBitmapFrameDecode *frame;
1228*3e9c4dadSThomas Faber UINT frame_count, width, height, i;
1229*3e9c4dadSThomas Faber double dpi_x, dpi_y;
1230*3e9c4dadSThomas Faber IWICPalette *palette;
1231*3e9c4dadSThomas Faber GUID format;
1232*3e9c4dadSThomas Faber WICRect rc;
1233*3e9c4dadSThomas Faber BYTE data[24];
1234*3e9c4dadSThomas Faber static const BYTE expected_data[24] = { 0,0,0,0xff, 0xff,0,0,0, 0xff,0,0,0xff,
1235*3e9c4dadSThomas Faber 0,0xff,0,0, 0xff,0xff,0,0xff, 0xff,0xff,0xff,0 };
1236*3e9c4dadSThomas Faber
1237*3e9c4dadSThomas Faber hr = create_decoder(&tiff_4bps_bgra, sizeof(tiff_4bps_bgra), &decoder);
1238*3e9c4dadSThomas Faber ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr);
1239*3e9c4dadSThomas Faber if (hr != S_OK) return;
1240*3e9c4dadSThomas Faber
1241*3e9c4dadSThomas Faber hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
1242*3e9c4dadSThomas Faber ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
1243*3e9c4dadSThomas Faber ok(frame_count == 1, "expected 1, got %u\n", frame_count);
1244*3e9c4dadSThomas Faber
1245*3e9c4dadSThomas Faber hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
1246*3e9c4dadSThomas Faber ok(hr == S_OK, "GetFrame error %#x\n", hr);
1247*3e9c4dadSThomas Faber
1248*3e9c4dadSThomas Faber hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
1249*3e9c4dadSThomas Faber ok(hr == S_OK, "GetSize error %#x\n", hr);
1250*3e9c4dadSThomas Faber ok(width == 3, "got %u\n", width);
1251*3e9c4dadSThomas Faber ok(height == 2, "got %u\n", height);
1252*3e9c4dadSThomas Faber
1253*3e9c4dadSThomas Faber hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y);
1254*3e9c4dadSThomas Faber ok(hr == S_OK, "GetResolution error %#x\n", hr);
1255*3e9c4dadSThomas Faber ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x);
1256*3e9c4dadSThomas Faber ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y);
1257*3e9c4dadSThomas Faber
1258*3e9c4dadSThomas Faber hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
1259*3e9c4dadSThomas Faber ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
1260*3e9c4dadSThomas Faber ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA),
1261*3e9c4dadSThomas Faber "got wrong format %s\n", wine_dbgstr_guid(&format));
1262*3e9c4dadSThomas Faber
1263*3e9c4dadSThomas Faber hr = IWICImagingFactory_CreatePalette(factory, &palette);
1264*3e9c4dadSThomas Faber ok(hr == S_OK, "CreatePalette error %#x\n", hr);
1265*3e9c4dadSThomas Faber hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
1266*3e9c4dadSThomas Faber ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE,
1267*3e9c4dadSThomas Faber "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr);
1268*3e9c4dadSThomas Faber IWICPalette_Release(palette);
1269*3e9c4dadSThomas Faber
1270*3e9c4dadSThomas Faber memset(data, 0xaa, sizeof(data));
1271*3e9c4dadSThomas Faber rc.X = 0;
1272*3e9c4dadSThomas Faber rc.Y = 0;
1273*3e9c4dadSThomas Faber rc.Width = 3;
1274*3e9c4dadSThomas Faber rc.Height = 2;
1275*3e9c4dadSThomas Faber hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 12, sizeof(data), data);
1276*3e9c4dadSThomas Faber ok(hr == S_OK, "CopyPixels error %#x\n", hr);
1277*3e9c4dadSThomas Faber
1278*3e9c4dadSThomas Faber for (i = 0; i < sizeof(data); i++)
1279*3e9c4dadSThomas Faber ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]);
1280*3e9c4dadSThomas Faber
1281*3e9c4dadSThomas Faber IWICBitmapFrameDecode_Release(frame);
1282*3e9c4dadSThomas Faber IWICBitmapDecoder_Release(decoder);
1283*3e9c4dadSThomas Faber }
1284*3e9c4dadSThomas Faber
START_TEST(tiffformat)1285c2c66affSColin Finck START_TEST(tiffformat)
1286c2c66affSColin Finck {
1287c2c66affSColin Finck HRESULT hr;
1288c2c66affSColin Finck
1289c2c66affSColin Finck CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1290c2c66affSColin Finck
1291c2c66affSColin Finck hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
1292c2c66affSColin Finck &IID_IWICImagingFactory, (void **)&factory);
1293c2c66affSColin Finck ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
1294c2c66affSColin Finck if (FAILED(hr)) return;
1295c2c66affSColin Finck
1296*3e9c4dadSThomas Faber test_tiff_4bps_bgra();
129723ec1e5eSAmine Khaldi test_color_formats();
129823ec1e5eSAmine Khaldi test_tiff_1bpp_palette();
129923ec1e5eSAmine Khaldi test_tiff_8bpp_palette();
1300c2c66affSColin Finck test_QueryCapability();
1301c2c66affSColin Finck test_tiff_8bpp_alpha();
130223ec1e5eSAmine Khaldi test_tiff_resolution();
1303eea81f52SAmine Khaldi test_tiff_24bpp();
1304c2c66affSColin Finck
1305c2c66affSColin Finck IWICImagingFactory_Release(factory);
1306c2c66affSColin Finck CoUninitialize();
1307c2c66affSColin Finck }
1308