[WINDOWSCODECS_WINETEST] 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 if (FAILED(hr)) return NULL;
180
181 hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guid);
182 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
183 ok(IsEqualGUID(&guid, &GUID_ContainerFormatTiff), "container format is not TIFF\n");
184
185 IStream_Release(stream);
186
187 return decoder;
188 }
189
190 static void test_tiff_palette(void)
191 {
192 HRESULT hr;
193 IWICBitmapDecoder *decoder;
194 IWICBitmapFrameDecode *frame;
195 IWICPalette *palette;
196 GUID format;
197
198 decoder = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data));
199 ok(decoder != 0, "Failed to load TIFF image data\n");
200 if (!decoder) return;
201
202 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
203 ok(hr == S_OK, "GetFrame error %#x\n", hr);
204
205 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
206 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
207 ok(IsEqualGUID(&format, &GUID_WICPixelFormatBlackWhite),
208 "got wrong format %s\n", wine_dbgstr_guid(&format));
209
210 hr = IWICImagingFactory_CreatePalette(factory, &palette);
211 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
212 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
213 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE,
214 "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr);
215
216 IWICPalette_Release(palette);
217 IWICBitmapFrameDecode_Release(frame);
218 IWICBitmapDecoder_Release(decoder);
219 }
220
221 static void test_QueryCapability(void)
222 {
223 HRESULT hr;
224 IStream *stream;
225 IWICBitmapDecoder *decoder;
226 IWICBitmapFrameDecode *frame;
227 static const DWORD exp_caps = WICBitmapDecoderCapabilityCanDecodeAllImages |
228 WICBitmapDecoderCapabilityCanDecodeSomeImages |
229 WICBitmapDecoderCapabilityCanEnumerateMetadata;
230 static const DWORD exp_caps_xp = WICBitmapDecoderCapabilityCanDecodeAllImages |
231 WICBitmapDecoderCapabilityCanDecodeSomeImages;
232 DWORD capability;
233 LARGE_INTEGER pos;
234 ULARGE_INTEGER cur_pos;
235 UINT frame_count;
236
237 stream = create_stream(&tiff_1bpp_data, sizeof(tiff_1bpp_data));
238 if (!stream) return;
239
240 hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatTiff, NULL, &decoder);
241 ok(hr == S_OK, "CreateDecoder error %#x\n", hr);
242 if (FAILED(hr)) return;
243
244 frame_count = 0xdeadbeef;
245 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
246 ok(hr == S_OK || broken(hr == E_POINTER) /* XP */, "GetFrameCount error %#x\n", hr);
247 ok(frame_count == 0, "expected 0, got %u\n", frame_count);
248
249 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
250 ok(hr == WINCODEC_ERR_FRAMEMISSING || broken(hr == E_POINTER) /* XP */, "expected WINCODEC_ERR_FRAMEMISSING, got %#x\n", hr);
251
252 pos.QuadPart = 4;
253 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
254 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
255
256 capability = 0xdeadbeef;
257 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
258 ok(hr == S_OK, "QueryCapability error %#x\n", hr);
259 ok(capability == exp_caps || capability == exp_caps_xp,
260 "expected %#x, got %#x\n", exp_caps, capability);
261
262 frame_count = 0xdeadbeef;
263 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
264 ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
265 ok(frame_count == 1, "expected 1, got %u\n", frame_count);
266
267 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
268 ok(hr == S_OK, "GetFrame error %#x\n", hr);
269 IWICBitmapFrameDecode_Release(frame);
270
271 pos.QuadPart = 0;
272 hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos);
273 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
274 ok(cur_pos.QuadPart > 4 && cur_pos.QuadPart < sizeof(tiff_1bpp_data),
275 "current stream pos is at %x/%x\n", cur_pos.u.LowPart, cur_pos.u.HighPart);
276
277 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
278 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
279
280 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
281 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
282
283 IWICBitmapDecoder_Release(decoder);
284
285 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
286 todo_wine
287 ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "expected WINCODEC_ERR_COMPONENTNOTFOUND, got %#x\n", hr);
288
289 if (SUCCEEDED(hr))
290 IWICBitmapDecoder_Release(decoder);
291
292 pos.QuadPart = 0;
293 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
294 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
295
296 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
297 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
298
299 frame_count = 0xdeadbeef;
300 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
301 ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
302 ok(frame_count == 1, "expected 1, got %u\n", frame_count);
303
304 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
305 ok(hr == S_OK, "GetFrame error %#x\n", hr);
306 IWICBitmapFrameDecode_Release(frame);
307
308 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
309 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
310
311 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
312 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
313
314 IWICBitmapDecoder_Release(decoder);
315 IStream_Release(stream);
316 }
317
318 static void test_tiff_8bpp_alpha(void)
319 {
320 HRESULT hr;
321 IWICBitmapDecoder *decoder;
322 IWICBitmapFrameDecode *frame;
323 UINT frame_count, width, height, i;
324 double dpi_x, dpi_y;
325 IWICPalette *palette;
326 GUID format;
327 WICRect rc;
328 BYTE data[16];
329 static const BYTE expected_data[16] = { 0x11,0x11,0x11,0x22,0x33,0x33,0x33,0x44,
330 0x55,0x55,0x55,0x66,0x77,0x77,0x77,0x88 };
331
332 decoder = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha));
333 ok(decoder != 0, "Failed to load TIFF image data\n");
334 if (!decoder) return;
335
336 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
337 ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
338 ok(frame_count == 1, "expected 1, got %u\n", frame_count);
339
340 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
341 ok(hr == S_OK, "GetFrame error %#x\n", hr);
342
343 hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height);
344 ok(hr == S_OK, "GetSize error %#x\n", hr);
345 ok(width == 2, "expected 2, got %u\n", width);
346 ok(height == 2, "expected 2, got %u\n", height);
347
348 hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y);
349 ok(hr == S_OK, "GetResolution error %#x\n", hr);
350 ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x);
351 ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y);
352
353 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
354 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
355 ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppPBGRA),
356 "got wrong format %s\n", wine_dbgstr_guid(&format));
357
358 hr = IWICImagingFactory_CreatePalette(factory, &palette);
359 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
360 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
361 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE,
362 "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr);
363 IWICPalette_Release(palette);
364
365 rc.X = 0;
366 rc.Y = 0;
367 rc.Width = 2;
368 rc.Height = 2;
369 hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 8, sizeof(data), data);
370 ok(hr == S_OK, "CopyPixels error %#x\n", hr);
371
372 for (i = 0; i < sizeof(data); i++)
373 ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]);
374
375 IWICBitmapFrameDecode_Release(frame);
376 IWICBitmapDecoder_Release(decoder);
377 }
378
379 START_TEST(tiffformat)
380 {
381 HRESULT hr;
382
383 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
384
385 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
386 &IID_IWICImagingFactory, (void **)&factory);
387 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
388 if (FAILED(hr)) return;
389
390 test_tiff_palette();
391 test_QueryCapability();
392 test_tiff_8bpp_alpha();
393
394 IWICImagingFactory_Release(factory);
395 CoUninitialize();
396 }