a6d4915cf744295ebf973b02529ad6b603adc94b
[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 #include <poppack.h>
102
103 static IWICImagingFactory *factory;
104
105 static IStream *create_stream(const void *data, int data_size)
106 {
107 HRESULT hr;
108 IStream *stream;
109 HGLOBAL hdata;
110 void *locked_data;
111
112 hdata = GlobalAlloc(GMEM_MOVEABLE, data_size);
113 ok(hdata != 0, "GlobalAlloc failed\n");
114 if (!hdata) return NULL;
115
116 locked_data = GlobalLock(hdata);
117 memcpy(locked_data, data, data_size);
118 GlobalUnlock(hdata);
119
120 hr = CreateStreamOnHGlobal(hdata, TRUE, &stream);
121 ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr);
122
123 return stream;
124 }
125
126 static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size)
127 {
128 HRESULT hr;
129 IStream *stream;
130 IWICBitmapDecoder *decoder = NULL;
131 GUID guid;
132
133 stream = create_stream(image_data, image_size);
134
135 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
136 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
137
138 hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guid);
139 ok(hr == S_OK, "GetContainerFormat error %#x\n", hr);
140 ok(IsEqualGUID(&guid, &GUID_ContainerFormatTiff), "container format is not TIFF\n");
141
142 IStream_Release(stream);
143
144 return decoder;
145 }
146
147 static void test_tiff_palette(void)
148 {
149 HRESULT hr;
150 IWICBitmapDecoder *decoder;
151 IWICBitmapFrameDecode *frame;
152 IWICPalette *palette;
153 GUID format;
154
155 decoder = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data));
156 ok(decoder != 0, "Failed to load TIFF image data\n");
157
158 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
159 ok(hr == S_OK, "GetFrame error %#x\n", hr);
160
161 hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
162 ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
163 ok(IsEqualGUID(&format, &GUID_WICPixelFormatBlackWhite),
164 "got wrong format %s\n", wine_dbgstr_guid(&format));
165
166 hr = IWICImagingFactory_CreatePalette(factory, &palette);
167 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
168 hr = IWICBitmapFrameDecode_CopyPalette(frame, palette);
169 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE,
170 "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr);
171
172 IWICPalette_Release(palette);
173 IWICBitmapFrameDecode_Release(frame);
174 IWICBitmapDecoder_Release(decoder);
175 }
176
177 static void test_QueryCapability(void)
178 {
179 HRESULT hr;
180 IStream *stream;
181 IWICBitmapDecoder *decoder;
182 IWICBitmapFrameDecode *frame;
183 static const DWORD exp_caps = WICBitmapDecoderCapabilityCanDecodeAllImages |
184 WICBitmapDecoderCapabilityCanDecodeSomeImages |
185 WICBitmapDecoderCapabilityCanEnumerateMetadata;
186 static const DWORD exp_caps_xp = WICBitmapDecoderCapabilityCanDecodeAllImages |
187 WICBitmapDecoderCapabilityCanDecodeSomeImages;
188 DWORD capability;
189 LARGE_INTEGER pos;
190 ULARGE_INTEGER cur_pos;
191 UINT frame_count;
192
193 stream = create_stream(&tiff_1bpp_data, sizeof(tiff_1bpp_data));
194 if (!stream) return;
195
196 hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatTiff, NULL, &decoder);
197 ok(hr == S_OK, "CreateDecoder error %#x\n", hr);
198
199 frame_count = 0xdeadbeef;
200 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
201 ok(hr == S_OK || broken(hr == E_POINTER) /* XP */, "GetFrameCount error %#x\n", hr);
202 ok(frame_count == 0, "expected 0, got %u\n", frame_count);
203
204 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
205 ok(hr == WINCODEC_ERR_FRAMEMISSING || broken(hr == E_POINTER) /* XP */, "expected WINCODEC_ERR_FRAMEMISSING, got %#x\n", hr);
206
207 pos.QuadPart = 4;
208 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
209 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
210
211 capability = 0xdeadbeef;
212 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
213 ok(hr == S_OK, "QueryCapability error %#x\n", hr);
214 ok(capability == exp_caps || capability == exp_caps_xp,
215 "expected %#x, got %#x\n", exp_caps, capability);
216
217 frame_count = 0xdeadbeef;
218 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
219 ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
220 ok(frame_count == 1, "expected 1, got %u\n", frame_count);
221
222 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
223 ok(hr == S_OK, "GetFrame error %#x\n", hr);
224 IWICBitmapFrameDecode_Release(frame);
225
226 pos.QuadPart = 0;
227 hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos);
228 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
229 ok(cur_pos.QuadPart > 4 && cur_pos.QuadPart < sizeof(tiff_1bpp_data),
230 "current stream pos is at %x/%x\n", cur_pos.u.LowPart, cur_pos.u.HighPart);
231
232 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
233 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
234
235 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
236 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
237
238 IWICBitmapDecoder_Release(decoder);
239
240 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
241 todo_wine
242 ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "expected WINCODEC_ERR_COMPONENTNOTFOUND, got %#x\n", hr);
243
244 pos.QuadPart = 0;
245 hr = IStream_Seek(stream, pos, SEEK_SET, NULL);
246 ok(hr == S_OK, "IStream_Seek error %#x\n", hr);
247
248 hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder);
249 ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr);
250
251 frame_count = 0xdeadbeef;
252 hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
253 ok(hr == S_OK, "GetFrameCount error %#x\n", hr);
254 ok(frame_count == 1, "expected 1, got %u\n", frame_count);
255
256 hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
257 ok(hr == S_OK, "GetFrame error %#x\n", hr);
258 IWICBitmapFrameDecode_Release(frame);
259
260 hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand);
261 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
262
263 hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability);
264 ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr);
265
266 IWICBitmapDecoder_Release(decoder);
267 IStream_Release(stream);
268 }
269
270 START_TEST(tiffformat)
271 {
272 HRESULT hr;
273
274 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
275
276 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
277 &IID_IWICImagingFactory, (void **)&factory);
278 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
279 if (FAILED(hr)) return;
280
281 test_tiff_palette();
282 test_QueryCapability();
283
284 IWICImagingFactory_Release(factory);
285 CoUninitialize();
286 }