[WINDOWSCODECS] Sync with Wine Staging 1.7.55. CORE-10536
[reactos.git] / rostests / winetests / windowscodecs / tiffformat.c
1 /*
2 * Copyright 2012 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 <stdarg.h>
20 #include <stdio.h>
21
22 #define WIN32_NO_STATUS
23 #define _INC_WINDOWS
24 #define COM_NO_WINDOWS_H
25
26 #define COBJMACROS
27
28 #include <windef.h>
29 #include <winbase.h>
30 #include <ole2.h>
31 #include <wincodec.h>
32 #include <wine/test.h>
33
34 #define IFD_BYTE 1
35 #define IFD_ASCII 2
36 #define IFD_SHORT 3
37 #define IFD_LONG 4
38 #define IFD_RATIONAL 5
39 #define IFD_SBYTE 6
40 #define IFD_UNDEFINED 7
41 #define IFD_SSHORT 8
42 #define IFD_SLONG 9
43 #define IFD_SRATIONAL 10
44 #define IFD_FLOAT 11
45 #define IFD_DOUBLE 12
46
47 #include <pshpack2.h>
48 struct IFD_entry
49 {
50 SHORT id;
51 SHORT type;
52 ULONG count;
53 LONG value;
54 };
55
56 struct IFD_rational
57 {
58 LONG numerator;
59 LONG denominator;
60 };
61
62 static const struct tiff_1bpp_data
63 {
64 USHORT byte_order;
65 USHORT version;
66 ULONG dir_offset;
67 USHORT number_of_entries;
68 struct IFD_entry entry[13];
69 ULONG next_IFD;
70 struct IFD_rational res;
71 BYTE pixel_data[4];
72 } tiff_1bpp_data =
73 {
74 #ifdef WORDS_BIGENDIAN
75 'M' | 'M' << 8,
76 #else
77 'I' | 'I' << 8,
78 #endif
79 42,
80 FIELD_OFFSET(struct tiff_1bpp_data, number_of_entries),
81 13,
82 {
83 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
84 { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */
85 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
86 { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */
87 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
88 { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */
89 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1bpp_data, pixel_data) }, /* STRIPOFFSETS */
90 { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */
91 { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */
92 { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */
93 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1bpp_data, res) },
94 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1bpp_data, res) },
95 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
96 },
97 0,
98 { 900, 3 },
99 { 0x11, 0x22, 0x33, 0 }
100 };
101
102 static const struct tiff_8bpp_alpha
103 {
104 USHORT byte_order;
105 USHORT version;
106 ULONG dir_offset;
107 USHORT number_of_entries;
108 struct IFD_entry entry[15];
109 ULONG next_IFD;
110 struct IFD_rational res;
111 BYTE pixel_data[8];
112 } tiff_8bpp_alpha =
113 {
114 #ifdef WORDS_BIGENDIAN
115 'M' | 'M' << 8,
116 #else
117 'I' | 'I' << 8,
118 #endif
119 42,
120 FIELD_OFFSET(struct tiff_8bpp_alpha, number_of_entries),
121 15,
122 {
123 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
124 { 0x100, IFD_LONG, 1, 2 }, /* IMAGEWIDTH */
125 { 0x101, IFD_LONG, 1, 2 }, /* IMAGELENGTH */
126 { 0x102, IFD_SHORT, 2, MAKELONG(8, 8) }, /* BITSPERSAMPLE */
127 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
128 { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */
129 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, pixel_data) }, /* STRIPOFFSETS */
130 { 0x115, IFD_SHORT, 1, 2 }, /* SAMPLESPERPIXEL */
131 { 0x116, IFD_LONG, 1, 2 }, /* ROWSPERSTRIP */
132 { 0x117, IFD_LONG, 1, 8 }, /* STRIPBYTECOUNT */
133 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, res) },
134 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_alpha, res) },
135 { 0x11c, IFD_SHORT, 1, 1 }, /* PLANARCONFIGURATION */
136 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
137 { 0x152, IFD_SHORT, 1, 1 } /* EXTRASAMPLES: 1 - Associated alpha with pre-multiplied color */
138 },
139 0,
140 { 96, 1 },
141 { 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88 }
142 };
143 #include "poppack.h"
144
145 static IWICImagingFactory *factory;
146
147 static IStream *create_stream(const void *data, int data_size)
148 {
149 HRESULT hr;
150 IStream *stream;
151 HGLOBAL hdata;
152 void *locked_data;
153
154 hdata = GlobalAlloc(GMEM_MOVEABLE, data_size);
155 ok(hdata != 0, "GlobalAlloc failed\n");
156 if (!hdata) return NULL;
157
158 locked_data = GlobalLock(hdata);
159 memcpy(locked_data, data, data_size);
160 GlobalUnlock(hdata);
161
162 hr = CreateStreamOnHGlobal(hdata, TRUE, &stream);
163 ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr);
164
165 return stream;
166 }
167
168 static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size)
169 {
170 HRESULT hr;
171 IStream *stream;
172 IWICBitmapDecoder *decoder = NULL;
173 GUID guid;
174
175 stream = create_stream(image_data, image_size);
176
177 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
178 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
179
180 hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guid);
181 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
182 ok(IsEqualGUID(&guid, &GUID_ContainerFormatTiff), "container format is not TIFF\n");
183
184 IStream_Release(stream);
185
186 return decoder;
187 }
188
189 static void test_tiff_palette(void)
190 {
191 HRESULT hr;
192 IWICBitmapDecoder *decoder;
193 IWICBitmapFrameDecode *frame;
194 IWICPalette *palette;
195 GUID format;
196
197 decoder = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data));
198 ok(decoder != 0, "Failed to load TIFF image data\n");
199
200 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
201 ok(hr == S_OK, "GetFrame error %#x\n", hr);
202
203 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
204 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
205 ok(IsEqualGUID(&format, &GUID_WICPixelFormatBlackWhite),
206 "got wrong format %s\n", wine_dbgstr_guid(&format));
207
208 hr = IWICImagingFactory_CreatePalette(factory, &palette);
209 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
210 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
211 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE,
212 "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr);
213
214 IWICPalette_Release(palette);
215 IWICBitmapFrameDecode_Release(frame);
216 IWICBitmapDecoder_Release(decoder);
217 }
218
219 static void test_QueryCapability(void)
220 {
221 HRESULT hr;
222 IStream *stream;
223 IWICBitmapDecoder *decoder;
224 IWICBitmapFrameDecode *frame;
225 static const DWORD exp_caps = WICBitmapDecoderCapabilityCanDecodeAllImages |
226 WICBitmapDecoderCapabilityCanDecodeSomeImages |
227 WICBitmapDecoderCapabilityCanEnumerateMetadata;
228 static const DWORD exp_caps_xp = WICBitmapDecoderCapabilityCanDecodeAllImages |
229 WICBitmapDecoderCapabilityCanDecodeSomeImages;
230 DWORD capability;
231 LARGE_INTEGER pos;
232 ULARGE_INTEGER cur_pos;
233 UINT frame_count;
234
235 stream = create_stream(&tiff_1bpp_data, sizeof(tiff_1bpp_data));
236 if (!stream) return;
237
238 hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatTiff, NULL, &decoder);
239 ok(hr == S_OK, "CreateDecoder error %#x\n", hr);
240
241 frame_count = 0xdeadbeef;
242 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
243 ok(hr == S_OK || broken(hr == E_POINTER) /* XP */, "GetFrameCount error %#x\n", hr);
244 ok(frame_count == 0, "expected 0, got %u\n", frame_count);
245
246 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
247 ok(hr == WINCODEC_ERR_FRAMEMISSING || broken(hr == E_POINTER) /* XP */, "expected WINCODEC_ERR_FRAMEMISSING, got %#x\n", hr);
248
249 pos.QuadPart = 4;
250 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
251 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
252
253 capability = 0xdeadbeef;
254 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
255 ok(hr == S_OK, "QueryCapability error %#x\n", hr);
256 ok(capability == exp_caps || capability == exp_caps_xp,
257 "expected %#x, got %#x\n", exp_caps, capability);
258
259 frame_count = 0xdeadbeef;
260 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
261 ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
262 ok(frame_count == 1, "expected 1, got %u\n", frame_count);
263
264 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
265 ok(hr == S_OK, "GetFrame error %#x\n", hr);
266 IWICBitmapFrameDecode_Release(frame);
267
268 pos.QuadPart = 0;
269 hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos);
270 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
271 ok(cur_pos.QuadPart > 4 && cur_pos.QuadPart < sizeof(tiff_1bpp_data),
272 "current stream pos is at %x/%x\n", cur_pos.u.LowPart, cur_pos.u.HighPart);
273
274 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
275 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
276
277 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
278 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
279
280 IWICBitmapDecoder_Release(decoder);
281
282 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
283 todo_wine
284 ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "expected WINCODEC_ERR_COMPONENTNOTFOUND, got %#x\n", hr);
285
286 if (SUCCEEDED(hr))
287 IWICBitmapDecoder_Release(decoder);
288
289 pos.QuadPart = 0;
290 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
291 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
292
293 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
294 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
295
296 frame_count = 0xdeadbeef;
297 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
298 ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
299 ok(frame_count == 1, "expected 1, got %u\n", frame_count);
300
301 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
302 ok(hr == S_OK, "GetFrame error %#x\n", hr);
303 IWICBitmapFrameDecode_Release(frame);
304
305 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
306 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
307
308 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
309 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
310
311 IWICBitmapDecoder_Release(decoder);
312 IStream_Release(stream);
313 }
314
315 static void test_tiff_8bpp_alpha(void)
316 {
317 HRESULT hr;
318 IWICBitmapDecoder *decoder;
319 IWICBitmapFrameDecode *frame;
320 UINT frame_count, width, height, i;
321 double dpi_x, dpi_y;
322 IWICPalette *palette;
323 GUID format;
324 WICRect rc;
325 BYTE data[16];
326 static const BYTE expected_data[16] = { 0x11,0x11,0x11,0x22,0x33,0x33,0x33,0x44,
327 0x55,0x55,0x55,0x66,0x77,0x77,0x77,0x88 };
328
329 decoder = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha));
330 ok(decoder != 0, "Failed to load TIFF image data\n");
331
332 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
333 ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
334 ok(frame_count == 1, "expected 1, got %u\n", frame_count);
335
336 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
337 ok(hr == S_OK, "GetFrame error %#x\n", hr);
338
339 hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
340 ok(hr == S_OK, "GetSize error %#x\n", hr);
341 ok(width == 2, "expected 2, got %u\n", width);
342 ok(height == 2, "expected 2, got %u\n", height);
343
344 hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y);
345 ok(hr == S_OK, "GetResolution error %#x\n", hr);
346 ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x);
347 ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y);
348
349 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
350 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
351 ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppPBGRA),
352 "got wrong format %s\n", wine_dbgstr_guid(&format));
353
354 hr = IWICImagingFactory_CreatePalette(factory, &palette);
355 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
356 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
357 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE,
358 "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr);
359 IWICPalette_Release(palette);
360
361 rc.X = 0;
362 rc.Y = 0;
363 rc.Width = 2;
364 rc.Height = 2;
365 hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 8, sizeof(data), data);
366 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
367
368 for (i = 0; i < sizeof(data); i++)
369 ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]);
370
371 IWICBitmapFrameDecode_Release(frame);
372 IWICBitmapDecoder_Release(decoder);
373 }
374
375 START_TEST(tiffformat)
376 {
377 HRESULT hr;
378
379 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
380
381 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
382 &IID_IWICImagingFactory, (void **)&factory);
383 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
384 if (FAILED(hr)) return;
385
386 test_tiff_palette();
387 test_QueryCapability();
388 test_tiff_8bpp_alpha();
389
390 IWICImagingFactory_Release(factory);
391 CoUninitialize();
392 }