1 /*
2  * Copyright 2009 Vincent Povirk for CodeWeavers
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 <stdio.h>
20 #include <stdarg.h>
21 #include <math.h>
22 
23 #define COBJMACROS
24 
25 #include "windef.h"
26 #include "objbase.h"
27 #include "wincodec.h"
28 #include "wincodecsdk.h"
29 #include "wine/test.h"
30 
31 #include "initguid.h"
32 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
33 
34 static HRESULT get_component_info(const GUID *clsid, IWICComponentInfo **result)
35 {
36     IWICImagingFactory *factory;
37     HRESULT hr;
38 
39     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
40         &IID_IWICImagingFactory, (void**)&factory);
41     ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
42     if (FAILED(hr)) return hr;
43 
44     hr = IWICImagingFactory_CreateComponentInfo(factory, clsid, result);
45 
46     IWICImagingFactory_Release(factory);
47 
48     return hr;
49 }
50 
51 static BOOL is_pixelformat(GUID *format)
52 {
53     IWICComponentInfo *info;
54     HRESULT hr;
55     WICComponentType componenttype;
56 
57     hr = get_component_info(format, &info);
58     if (FAILED(hr))
59         return FALSE;
60 
61     hr = IWICComponentInfo_GetComponentType(info, &componenttype);
62 
63     IWICComponentInfo_Release(info);
64 
65     return SUCCEEDED(hr) && componenttype == WICPixelFormat;
66 }
67 
68 static void test_decoder_info(void)
69 {
70     struct decoder_info_test
71     {
72         const CLSID *clsid;
73         const char *mimetype;
74         const char *extensions;
75         unsigned int todo;
76     } decoder_info_tests[] =
77     {
78         {
79             &CLSID_WICBmpDecoder,
80             "image/bmp",
81             ".bmp,.dib,.rle"
82         },
83         {
84             &CLSID_WICGifDecoder,
85             "image/gif",
86             ".gif"
87         },
88         {
89             &CLSID_WICIcoDecoder,
90             "image/ico,image/x-icon",
91             ".ico,.icon",
92             1
93         },
94         {
95             &CLSID_WICJpegDecoder,
96             "image/jpeg,image/jpe,image/jpg",
97             ".jpeg,.jpe,.jpg,.jfif,.exif",
98             1
99         },
100         {
101             &CLSID_WICPngDecoder,
102             "image/png",
103             ".png"
104         },
105         {
106             &CLSID_WICTiffDecoder,
107             "image/tiff,image/tif",
108             ".tiff,.tif",
109             1
110         },
111     };
112     IWICBitmapDecoderInfo *decoder_info, *decoder_info2;
113     IWICComponentInfo *info;
114     HRESULT hr;
115     ULONG len;
116     WCHAR value[256];
117     CLSID clsid;
118     GUID pixelformats[32];
119     UINT num_formats, count;
120     int i, j;
121 
122     for (i = 0; i < sizeof(decoder_info_tests)/sizeof(decoder_info_tests[0]); i++)
123     {
124         struct decoder_info_test *test = &decoder_info_tests[i];
125         IWICBitmapDecoder *decoder, *decoder2;
126         WCHAR extensionsW[64];
127         WCHAR mimetypeW[64];
128 
129         hr = CoCreateInstance(test->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void **)&decoder);
130         ok(SUCCEEDED(hr), "Failed to create decoder, hr %#x.\n", hr);
131 
132         decoder_info = NULL;
133         hr = IWICBitmapDecoder_GetDecoderInfo(decoder, &decoder_info);
134         ok(hr == S_OK || broken(IsEqualCLSID(&CLSID_WICBmpDecoder, test->clsid) && FAILED(hr)) /* Fails on Windows */,
135             "%u: failed to get decoder info, hr %#x.\n", i, hr);
136 
137         if (hr == S_OK)
138         {
139             decoder_info2 = NULL;
140             hr = IWICBitmapDecoder_GetDecoderInfo(decoder, &decoder_info2);
141             ok(hr == S_OK, "Failed to get decoder info, hr %#x.\n", hr);
142         todo_wine
143             ok(decoder_info == decoder_info2, "Unexpected decoder info instance.\n");
144 
145             hr = IWICBitmapDecoderInfo_QueryInterface(decoder_info, &IID_IWICBitmapDecoder, (void **)&decoder2);
146             ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
147 
148             IWICBitmapDecoderInfo_Release(decoder_info);
149             IWICBitmapDecoderInfo_Release(decoder_info2);
150         }
151         IWICBitmapDecoder_Release(decoder);
152 
153         MultiByteToWideChar(CP_ACP, 0, test->mimetype, -1, mimetypeW, sizeof(mimetypeW)/sizeof(mimetypeW[0]));
154         MultiByteToWideChar(CP_ACP, 0, test->extensions, -1, extensionsW, sizeof(extensionsW)/sizeof(extensionsW[0]));
155 
156         hr = get_component_info(test->clsid, &info);
157         ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr);
158 
159         hr = IWICComponentInfo_QueryInterface(info, &IID_IWICBitmapDecoderInfo, (void **)&decoder_info);
160         ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
161 
162         hr = IWICBitmapDecoderInfo_GetCLSID(decoder_info, NULL);
163         ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr);
164 
165         hr = IWICBitmapDecoderInfo_GetCLSID(decoder_info, &clsid);
166         ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr);
167         ok(IsEqualGUID(test->clsid, &clsid), "GetCLSID returned wrong result\n");
168 
169         hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 0, NULL, NULL);
170         ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr);
171 
172         len = 0;
173         hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 1, NULL, &len);
174         ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr);
175     todo_wine_if(test->todo)
176         ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len);
177 
178         hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, len, value, NULL);
179         ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr);
180 
181         len = 0;
182         hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 0, NULL, &len);
183         ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr);
184     todo_wine_if(test->todo)
185         ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len);
186 
187         value[0] = 0;
188         hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, len, value, &len);
189         ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr);
190     todo_wine_if(test->todo) {
191         ok(lstrcmpW(value, mimetypeW) == 0, "GetMimeType returned wrong value %s\n", wine_dbgstr_w(value));
192         ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len);
193     }
194         hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 1, value, &len);
195         ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetMimeType failed, hr=%x\n", hr);
196     todo_wine_if(test->todo)
197         ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len);
198 
199         hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 256, value, &len);
200         ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr);
201     todo_wine_if(test->todo) {
202         ok(lstrcmpW(value, mimetypeW) == 0, "GetMimeType returned wrong value %s\n", wine_dbgstr_w(value));
203         ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len);
204     }
205         num_formats = 0xdeadbeef;
206         hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, NULL, &num_formats);
207         ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr);
208         ok((num_formats <= 21 && num_formats >= 1) ||
209             broken(IsEqualCLSID(test->clsid, &CLSID_WICIcoDecoder) && num_formats == 0) /* WinXP */,
210             "%u: got %d formats\n", i, num_formats);
211 
212         hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, NULL, NULL);
213         ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%x\n", hr);
214 
215         count = 0xdeadbeef;
216         hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, pixelformats, &count);
217         ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr);
218         ok(count == 0, "got %d formats\n", count);
219 
220         count = 0xdeadbeef;
221         hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 1, pixelformats, &count);
222         ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr);
223         ok((count == 1) || broken(IsEqualCLSID(test->clsid, &CLSID_WICIcoDecoder) && count == 0) /* WinXP */,
224             "%u: got %d formats\n", i, num_formats);
225         ok(is_pixelformat(&pixelformats[0]), "got invalid pixel format\n");
226 
227         count = 0xdeadbeef;
228         hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, num_formats, pixelformats, &count);
229         ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr);
230         ok(count == num_formats, "got %d formats, expected %d\n", count, num_formats);
231         for (j = 0; j < num_formats; j++)
232             ok(is_pixelformat(&pixelformats[j]), "got invalid pixel format\n");
233 
234         hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, num_formats, pixelformats, NULL);
235         ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%x\n", hr);
236 
237         count = 0xdeadbeef;
238         hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, sizeof(pixelformats)/sizeof(pixelformats[0]),
239             pixelformats, &count);
240         ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr);
241         ok(count == num_formats, "got %d formats, expected %d\n", count, num_formats);
242 
243         hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 0, NULL, NULL);
244         ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr);
245 
246         hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 1, NULL, &len);
247         ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr);
248     todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder))
249         ok(len == lstrlenW(extensionsW) + 1, "%u: GetFileExtensions returned wrong len %i\n", i, len);
250 
251         hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, len, value, NULL);
252         ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr);
253 
254         hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 0, NULL, &len);
255         ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr);
256     todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder))
257         ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len);
258 
259         value[0] = 0;
260         hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, len, value, &len);
261         ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr);
262     todo_wine_if(test->todo)
263         ok(lstrcmpW(value, extensionsW) == 0, "GetFileExtensions returned wrong value %s\n", wine_dbgstr_w(value));
264     todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder))
265         ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len);
266 
267         hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 1, value, &len);
268         ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetFileExtensions failed, hr=%x\n", hr);
269     todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder))
270         ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len);
271 
272         hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 256, value, &len);
273         ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr);
274     todo_wine_if(test->todo)
275         ok(lstrcmpW(value, extensionsW) == 0, "GetFileExtensions returned wrong value %s\n", wine_dbgstr_w(value));
276     todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder))
277         ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len);
278 
279         IWICBitmapDecoderInfo_Release(decoder_info);
280         IWICComponentInfo_Release(info);
281     }
282 }
283 
284 static void test_pixelformat_info(void)
285 {
286     IWICComponentInfo *info;
287     IWICPixelFormatInfo *pixelformat_info;
288     IWICPixelFormatInfo2 *pixelformat_info2;
289     HRESULT hr;
290     ULONG len, known_len;
291     WCHAR value[256];
292     GUID guid;
293     WICComponentType componenttype;
294     WICPixelFormatNumericRepresentation numericrepresentation;
295     DWORD signing;
296     UINT uiresult;
297     BYTE abbuffer[256];
298     BOOL supportstransparency;
299 
300     hr = get_component_info(&GUID_WICPixelFormat32bppBGRA, &info);
301     ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr);
302 
303     if (FAILED(hr))
304         return;
305 
306     hr = IWICComponentInfo_GetAuthor(info, 0, NULL, 0);
307     ok(hr == E_INVALIDARG, "GetAuthor failed, hr=%x\n", hr);
308 
309     len = 0xdeadbeef;
310     hr = IWICComponentInfo_GetAuthor(info, 0, NULL, &len);
311     ok(hr == S_OK, "GetAuthor failed, hr=%x\n", hr);
312     ok(len < 255 && len > 0, "invalid length 0x%x\n", len);
313     known_len = len;
314 
315     memset(value, 0xaa, 256 * sizeof(WCHAR));
316     hr = IWICComponentInfo_GetAuthor(info, len-1, value, NULL);
317     ok(hr == E_INVALIDARG, "GetAuthor failed, hr=%x\n", hr);
318     ok(value[0] == 0xaaaa, "string modified\n");
319 
320     len = 0xdeadbeef;
321     memset(value, 0xaa, 256 * sizeof(WCHAR));
322     hr = IWICComponentInfo_GetAuthor(info, known_len-1, value, &len);
323     ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetAuthor failed, hr=%x\n", hr);
324     ok(len == known_len, "got length of 0x%x, expected 0x%x\n", len, known_len);
325     ok(value[known_len-1] == 0xaaaa, "string modified past given length\n");
326     ok(value[0] == 0xaaaa, "string modified\n");
327 
328     len = 0xdeadbeef;
329     memset(value, 0xaa, 256 * sizeof(WCHAR));
330     hr = IWICComponentInfo_GetAuthor(info, known_len, value, &len);
331     ok(hr == S_OK, "GetAuthor failed, hr=%x\n", hr);
332     ok(len == known_len, "got length of 0x%x, expected 0x%x\n", len, known_len);
333     ok(value[known_len-1] == 0, "string not terminated at expected length\n");
334     ok(value[known_len-2] != 0xaaaa, "string not modified at given length\n");
335 
336     len = 0xdeadbeef;
337     memset(value, 0xaa, 256 * sizeof(WCHAR));
338     hr = IWICComponentInfo_GetAuthor(info, known_len+1, value, &len);
339     ok(hr == S_OK, "GetAuthor failed, hr=%x\n", hr);
340     ok(len == known_len, "got length of 0x%x, expected 0x%x\n", len, known_len);
341     ok(value[known_len] == 0xaaaa, "string modified past end\n");
342     ok(value[known_len-1] == 0, "string not terminated at expected length\n");
343     ok(value[known_len-2] != 0xaaaa, "string not modified at given length\n");
344 
345     hr = IWICComponentInfo_GetCLSID(info, NULL);
346     ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr);
347 
348     memset(&guid, 0xaa, sizeof(guid));
349     hr = IWICComponentInfo_GetCLSID(info, &guid);
350     ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr);
351     ok(IsEqualGUID(&guid, &GUID_WICPixelFormat32bppBGRA), "unexpected CLSID %s\n", wine_dbgstr_guid(&guid));
352 
353     hr = IWICComponentInfo_GetComponentType(info, NULL);
354     ok(hr == E_INVALIDARG, "GetComponentType failed, hr=%x\n", hr);
355 
356     hr = IWICComponentInfo_GetComponentType(info, &componenttype);
357     ok(hr == S_OK, "GetComponentType failed, hr=%x\n", hr);
358     ok(componenttype == WICPixelFormat, "unexpected component type 0x%x\n", componenttype);
359 
360     len = 0xdeadbeef;
361     hr = IWICComponentInfo_GetFriendlyName(info, 0, NULL, &len);
362     ok(hr == S_OK, "GetFriendlyName failed, hr=%x\n", hr);
363     ok(len < 255 && len > 0, "invalid length 0x%x\n", len);
364 
365     hr = IWICComponentInfo_GetSigningStatus(info, NULL);
366     ok(hr == E_INVALIDARG, "GetSigningStatus failed, hr=%x\n", hr);
367 
368     hr = IWICComponentInfo_GetSigningStatus(info, &signing);
369     ok(hr == S_OK, "GetSigningStatus failed, hr=%x\n", hr);
370     ok(signing == WICComponentSigned, "unexpected signing status 0x%x\n", signing);
371 
372     len = 0xdeadbeef;
373     hr = IWICComponentInfo_GetSpecVersion(info, 0, NULL, &len);
374     ok(hr == S_OK, "GetSpecVersion failed, hr=%x\n", hr);
375     ok(len == 0, "invalid length 0x%x\n", len); /* spec version does not apply to pixel formats */
376 
377     memset(&guid, 0xaa, sizeof(guid));
378     hr = IWICComponentInfo_GetVendorGUID(info, &guid);
379     ok(hr == S_OK, "GetVendorGUID failed, hr=%x\n", hr);
380     ok(IsEqualGUID(&guid, &GUID_VendorMicrosoft) ||
381        broken(IsEqualGUID(&guid, &GUID_NULL)) /* XP */, "unexpected GUID %s\n", wine_dbgstr_guid(&guid));
382 
383     len = 0xdeadbeef;
384     hr = IWICComponentInfo_GetVersion(info, 0, NULL, &len);
385     ok(hr == S_OK, "GetVersion failed, hr=%x\n", hr);
386     ok(len == 0, "invalid length 0x%x\n", len); /* version does not apply to pixel formats */
387 
388     hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void**)&pixelformat_info);
389     ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
390 
391     if (SUCCEEDED(hr))
392     {
393         hr = IWICPixelFormatInfo_GetBitsPerPixel(pixelformat_info, NULL);
394         ok(hr == E_INVALIDARG, "GetBitsPerPixel failed, hr=%x\n", hr);
395 
396         hr = IWICPixelFormatInfo_GetBitsPerPixel(pixelformat_info, &uiresult);
397         ok(hr == S_OK, "GetBitsPerPixel failed, hr=%x\n", hr);
398         ok(uiresult == 32, "unexpected bpp %i\n", uiresult);
399 
400         hr = IWICPixelFormatInfo_GetChannelCount(pixelformat_info, &uiresult);
401         ok(hr == S_OK, "GetChannelCount failed, hr=%x\n", hr);
402         ok(uiresult == 4, "unexpected channel count %i\n", uiresult);
403 
404         hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 0, NULL, NULL);
405         ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%x\n", hr);
406 
407         uiresult = 0xdeadbeef;
408         hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 0, NULL, &uiresult);
409         ok(hr == S_OK, "GetChannelMask failed, hr=%x\n", hr);
410         ok(uiresult == 4, "unexpected length %i\n", uiresult);
411 
412         memset(abbuffer, 0xaa, sizeof(abbuffer));
413         hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, known_len, abbuffer, NULL);
414         ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%x\n", hr);
415         ok(abbuffer[0] == 0xaa, "buffer modified\n");
416 
417         uiresult = 0xdeadbeef;
418         memset(abbuffer, 0xaa, sizeof(abbuffer));
419         hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 3, abbuffer, &uiresult);
420         ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%x\n", hr);
421         ok(abbuffer[0] == 0xaa, "buffer modified\n");
422         ok(uiresult == 4, "unexpected length %i\n", uiresult);
423 
424         memset(abbuffer, 0xaa, sizeof(abbuffer));
425         hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 4, abbuffer, &uiresult);
426         ok(hr == S_OK, "GetChannelMask failed, hr=%x\n", hr);
427         ok(*((ULONG*)abbuffer) == 0xff, "unexpected mask 0x%x\n", *((ULONG*)abbuffer));
428         ok(uiresult == 4, "unexpected length %i\n", uiresult);
429 
430         memset(abbuffer, 0xaa, sizeof(abbuffer));
431         hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 5, abbuffer, &uiresult);
432         ok(hr == S_OK, "GetChannelMask failed, hr=%x\n", hr);
433         ok(*((ULONG*)abbuffer) == 0xff, "unexpected mask 0x%x\n", *((ULONG*)abbuffer));
434         ok(abbuffer[4] == 0xaa, "buffer modified past actual length\n");
435         ok(uiresult == 4, "unexpected length %i\n", uiresult);
436 
437         memset(&guid, 0xaa, sizeof(guid));
438         hr = IWICPixelFormatInfo_GetFormatGUID(pixelformat_info, &guid);
439         ok(hr == S_OK, "GetFormatGUID failed, hr=%x\n", hr);
440         ok(IsEqualGUID(&guid, &GUID_WICPixelFormat32bppBGRA), "unexpected GUID %s\n", wine_dbgstr_guid(&guid));
441 
442         IWICPixelFormatInfo_Release(pixelformat_info);
443     }
444 
445     hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void**)&pixelformat_info2);
446 
447     if (FAILED(hr))
448         win_skip("IWICPixelFormatInfo2 not supported\n");
449     else
450     {
451         hr = IWICPixelFormatInfo2_GetNumericRepresentation(pixelformat_info2, NULL);
452         ok(hr == E_INVALIDARG, "GetNumericRepresentation failed, hr=%x\n", hr);
453 
454         numericrepresentation = 0xdeadbeef;
455         hr = IWICPixelFormatInfo2_GetNumericRepresentation(pixelformat_info2, &numericrepresentation);
456         ok(hr == S_OK, "GetNumericRepresentation failed, hr=%x\n", hr);
457         ok(numericrepresentation == WICPixelFormatNumericRepresentationUnsignedInteger, "unexpected numeric representation %i\n", numericrepresentation);
458 
459         hr = IWICPixelFormatInfo2_SupportsTransparency(pixelformat_info2, NULL);
460         ok(hr == E_INVALIDARG, "SupportsTransparency failed, hr=%x\n", hr);
461 
462         supportstransparency = 0xdeadbeef;
463         hr = IWICPixelFormatInfo2_SupportsTransparency(pixelformat_info2, &supportstransparency);
464         ok(hr == S_OK, "SupportsTransparency failed, hr=%x\n", hr);
465         ok(supportstransparency == 1, "unexpected value %i\n", supportstransparency);
466 
467         IWICPixelFormatInfo2_Release(pixelformat_info2);
468     }
469 
470     IWICComponentInfo_Release(info);
471 }
472 
473 static void test_reader_info(void)
474 {
475     IWICImagingFactory *factory;
476     IWICComponentInfo *info;
477     IWICMetadataReaderInfo *reader_info;
478     HRESULT hr;
479     CLSID clsid;
480     GUID container_formats[10];
481     UINT count, size;
482     WICMetadataPattern *patterns;
483 
484     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
485         &IID_IWICImagingFactory, (void**)&factory);
486     ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
487     if (FAILED(hr)) return;
488 
489     hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICUnknownMetadataReader, &info);
490     ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr);
491 
492     hr = IWICComponentInfo_QueryInterface(info, &IID_IWICMetadataReaderInfo, (void**)&reader_info);
493     ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
494 
495     hr = IWICMetadataReaderInfo_GetCLSID(reader_info, NULL);
496     ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr);
497 
498     hr = IWICMetadataReaderInfo_GetCLSID(reader_info, &clsid);
499     ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr);
500     ok(IsEqualGUID(&CLSID_WICUnknownMetadataReader, &clsid), "GetCLSID returned wrong result\n");
501 
502     hr = IWICMetadataReaderInfo_GetMetadataFormat(reader_info, &clsid);
503     ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
504     ok(IsEqualGUID(&GUID_MetadataFormatUnknown, &clsid), "GetMetadataFormat returned wrong result\n");
505 
506     hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, NULL);
507     ok(hr == E_INVALIDARG, "GetContainerFormats failed, hr=%x\n", hr);
508 
509     count = 0xdeadbeef;
510     hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, &count);
511     ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr);
512     ok(count == 0, "unexpected count %d\n", count);
513 
514     hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_ContainerFormatPng,
515         0, NULL, NULL, NULL);
516     ok(hr == E_INVALIDARG, "GetPatterns failed, hr=%x\n", hr);
517 
518     count = size = 0xdeadbeef;
519     hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_ContainerFormatPng,
520         0, NULL, &count, &size);
521     ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND || broken(hr == S_OK) /* Windows XP */,
522         "GetPatterns failed, hr=%x\n", hr);
523     ok(count == 0xdeadbeef, "unexpected count %d\n", count);
524     ok(size == 0xdeadbeef, "unexpected size %d\n", size);
525 
526     IWICMetadataReaderInfo_Release(reader_info);
527 
528     IWICComponentInfo_Release(info);
529 
530     hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICXMPStructMetadataReader, &info);
531 todo_wine
532     ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr);
533 
534     if (FAILED(hr))
535     {
536         IWICImagingFactory_Release(factory);
537         return;
538     }
539 
540     hr = IWICComponentInfo_QueryInterface(info, &IID_IWICMetadataReaderInfo, (void**)&reader_info);
541     ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
542 
543     hr = IWICMetadataReaderInfo_GetCLSID(reader_info, NULL);
544     ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr);
545 
546     hr = IWICMetadataReaderInfo_GetCLSID(reader_info, &clsid);
547     ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr);
548     ok(IsEqualGUID(&CLSID_WICXMPStructMetadataReader, &clsid), "GetCLSID returned wrong result\n");
549 
550     hr = IWICMetadataReaderInfo_GetMetadataFormat(reader_info, &clsid);
551     ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
552     ok(IsEqualGUID(&GUID_MetadataFormatXMPStruct, &clsid), "GetMetadataFormat returned wrong result\n");
553 
554     hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, NULL);
555     ok(hr == E_INVALIDARG, "GetContainerFormats failed, hr=%x\n", hr);
556 
557     count = 0xdeadbeef;
558     hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, &count);
559     ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr);
560     ok(count >= 2, "unexpected count %d\n", count);
561 
562     count = 0xdeadbeef;
563     hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 1, container_formats, &count);
564     ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr);
565     ok(count == 1, "unexpected count %d\n", count);
566 
567     count = 0xdeadbeef;
568     hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 10, container_formats, &count);
569     ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr);
570     ok(count == min(count, 10), "unexpected count %d\n", count);
571 
572     count = size = 0xdeadbeef;
573     hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_ContainerFormatPng,
574         0, NULL, &count, &size);
575     ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND || broken(hr == S_OK) /* Windows XP */,
576         "GetPatterns failed, hr=%x\n", hr);
577     ok(count == 0xdeadbeef, "unexpected count %d\n", count);
578     ok(size == 0xdeadbeef, "unexpected size %d\n", size);
579 
580     count = size = 0xdeadbeef;
581     hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_MetadataFormatXMP,
582         0, NULL, &count, &size);
583     ok(hr == S_OK, "GetPatterns failed, hr=%x\n", hr);
584     ok(count == 1, "unexpected count %d\n", count);
585     ok(size > sizeof(WICMetadataPattern), "unexpected size %d\n", size);
586 
587     if (hr == S_OK)
588     {
589         patterns = HeapAlloc(GetProcessHeap(), 0, size);
590 
591         count = size = 0xdeadbeef;
592         hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_MetadataFormatXMP,
593             size-1, patterns, &count, &size);
594         ok(hr == S_OK, "GetPatterns failed, hr=%x\n", hr);
595         ok(count == 1, "unexpected count %d\n", count);
596         ok(size > sizeof(WICMetadataPattern), "unexpected size %d\n", size);
597 
598         count = size = 0xdeadbeef;
599         hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_MetadataFormatXMP,
600             size, patterns, &count, &size);
601         ok(hr == S_OK, "GetPatterns failed, hr=%x\n", hr);
602         ok(count == 1, "unexpected count %d\n", count);
603         ok(size == sizeof(WICMetadataPattern) + patterns->Length * 2, "unexpected size %d\n", size);
604 
605         HeapFree(GetProcessHeap(), 0, patterns);
606     }
607 
608     IWICMetadataReaderInfo_Release(reader_info);
609 
610     IWICComponentInfo_Release(info);
611 
612     IWICImagingFactory_Release(factory);
613 }
614 
615 START_TEST(info)
616 {
617     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
618 
619     test_decoder_info();
620     test_reader_info();
621     test_pixelformat_info();
622 
623     CoUninitialize();
624 }
625