windowscodecs: Add test for CreateMetadataReaderFromContainer.
[wine] / dlls / windowscodecs / tests / metadata.c
1 /*
2  * Copyright 2011 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 #define expect_blob(propvar, data, length) do { \
32     ok((propvar).vt == VT_BLOB, "unexpected vt: %i\n", (propvar).vt); \
33     if ((propvar).vt == VT_BLOB) { \
34         ok((propvar).blob.cbSize == (length), "expected size %i, got %i\n", (length), (propvar).blob.cbSize); \
35         if ((propvar).blob.cbSize == (length)) { \
36             ok(!memcmp((propvar).blob.pBlobData, (data), (length)), "unexpected data\n"); \
37         } \
38     } \
39 } while (0)
40
41 static const char metadata_unknown[] = "lalala";
42
43 static const char metadata_tEXt[] = {
44     0,0,0,14, /* chunk length */
45     't','E','X','t', /* chunk type */
46     'w','i','n','e','t','e','s','t',0, /* keyword */
47     'v','a','l','u','e', /* text */
48     0x3f,0x64,0x19,0xf3 /* chunk CRC */
49 };
50
51 static const char *debugstr_guid(REFIID riid)
52 {
53     static char buf[50];
54
55     if(!riid)
56         return "(null)";
57
58     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
59             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
60             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
61             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
62
63     return buf;
64 }
65
66 static IStream *create_stream(const char *data, int data_size)
67 {
68     HRESULT hr;
69     IStream *stream;
70     HGLOBAL hdata;
71     void *locked_data;
72
73     hdata = GlobalAlloc(GMEM_MOVEABLE, data_size);
74     ok(hdata != 0, "GlobalAlloc failed\n");
75     if (!hdata) return NULL;
76
77     locked_data = GlobalLock(hdata);
78     memcpy(locked_data, data, data_size);
79     GlobalUnlock(hdata);
80
81     hr = CreateStreamOnHGlobal(hdata, TRUE, &stream);
82     ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr);
83
84     return stream;
85 }
86
87 static void load_stream(IUnknown *reader, const char *data, int data_size)
88 {
89     HRESULT hr;
90     IWICPersistStream *persist;
91     IStream *stream;
92
93     stream = create_stream(data, data_size);
94     if (!stream)
95         return;
96
97     hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void**)&persist);
98     ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
99
100     if (SUCCEEDED(hr))
101     {
102         hr = IWICPersistStream_LoadEx(persist, stream, NULL, WICPersistOptionsDefault);
103         ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr);
104
105         IWICPersistStream_Release(persist);
106     }
107
108     IStream_Release(stream);
109 }
110
111 static void test_metadata_unknown(void)
112 {
113     HRESULT hr;
114     IWICMetadataReader *reader;
115     IWICEnumMetadataItem *enumerator;
116     PROPVARIANT schema, id, value;
117     ULONG items_returned;
118
119     hr = CoCreateInstance(&CLSID_WICUnknownMetadataReader, NULL, CLSCTX_INPROC_SERVER,
120         &IID_IWICMetadataReader, (void**)&reader);
121     todo_wine ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
122     if (FAILED(hr)) return;
123
124     load_stream((IUnknown*)reader, metadata_unknown, sizeof(metadata_unknown));
125
126     hr = IWICMetadataReader_GetEnumerator(reader, &enumerator);
127     ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr);
128
129     if (SUCCEEDED(hr))
130     {
131         PropVariantInit(&schema);
132         PropVariantInit(&id);
133         PropVariantInit(&value);
134
135         hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned);
136         ok(hr == S_OK, "Next failed, hr=%x\n", hr);
137         ok(items_returned == 1, "unexpected item count %i\n", items_returned);
138
139         if (hr == S_OK && items_returned == 1)
140         {
141             ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt);
142             ok(id.vt == VT_EMPTY, "unexpected vt: %i\n", id.vt);
143             expect_blob(value, metadata_unknown, sizeof(metadata_unknown));
144
145             PropVariantClear(&schema);
146             PropVariantClear(&id);
147             PropVariantClear(&value);
148         }
149
150         hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned);
151         ok(hr == S_FALSE, "Next failed, hr=%x\n", hr);
152         ok(items_returned == 0, "unexpected item count %i\n", items_returned);
153
154         IWICEnumMetadataItem_Release(enumerator);
155     }
156
157     IWICMetadataReader_Release(reader);
158 }
159
160 static void test_metadata_tEXt(void)
161 {
162     HRESULT hr;
163     IWICMetadataReader *reader;
164     IWICEnumMetadataItem *enumerator;
165     PROPVARIANT schema, id, value;
166     ULONG items_returned;
167
168     hr = CoCreateInstance(&CLSID_WICPngTextMetadataReader, NULL, CLSCTX_INPROC_SERVER,
169         &IID_IWICMetadataReader, (void**)&reader);
170     todo_wine ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
171     if (FAILED(hr)) return;
172
173     load_stream((IUnknown*)reader, metadata_tEXt, sizeof(metadata_tEXt));
174
175     hr = IWICMetadataReader_GetEnumerator(reader, &enumerator);
176     ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr);
177
178     if (SUCCEEDED(hr))
179     {
180         PropVariantInit(&schema);
181         PropVariantInit(&id);
182         PropVariantInit(&value);
183
184         hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned);
185         ok(hr == S_OK, "Next failed, hr=%x\n", hr);
186         ok(items_returned == 1, "unexpected item count %i\n", items_returned);
187
188         if (hr == S_OK && items_returned == 1)
189         {
190             ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt);
191             ok(id.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt);
192             ok(!strcmp(id.pszVal, "winetest"), "unexpected id: %s\n", id.pszVal);
193             ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt);
194             ok(!strcmp(value.pszVal, "value"), "unexpected value: %s\n", id.pszVal);
195
196             PropVariantClear(&schema);
197             PropVariantClear(&id);
198             PropVariantClear(&value);
199         }
200
201         hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned);
202         ok(hr == S_FALSE, "Next failed, hr=%x\n", hr);
203         ok(items_returned == 0, "unexpected item count %i\n", items_returned);
204
205         IWICEnumMetadataItem_Release(enumerator);
206     }
207
208     IWICMetadataReader_Release(reader);
209 }
210
211 static void test_create_reader(void)
212 {
213     HRESULT hr;
214     IWICComponentFactory *factory;
215     IStream *stream;
216     IWICMetadataReader *reader;
217     UINT count=0;
218     GUID format;
219
220     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
221         &IID_IWICComponentFactory, (void**)&factory);
222     todo_wine ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
223     if (FAILED(hr)) return;
224
225     stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt));
226
227     hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
228         &GUID_ContainerFormatPng, NULL, WICPersistOptionsDefault,
229         stream, &reader);
230     ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
231
232     if (SUCCEEDED(hr))
233     {
234         hr = IWICMetadataReader_GetCount(reader, &count);
235         ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
236         ok(count == 1, "unexpected count %i\n", count);
237
238         hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
239         ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
240         ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "unexpected format %s\n", debugstr_guid(&format));
241
242         IWICMetadataReader_Release(reader);
243     }
244
245     hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
246         &GUID_ContainerFormatWmp, NULL, WICPersistOptionsDefault,
247         stream, &reader);
248     ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);
249
250     if (SUCCEEDED(hr))
251     {
252         hr = IWICMetadataReader_GetCount(reader, &count);
253         ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
254         ok(count == 1, "unexpected count %i\n", count);
255
256         hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
257         ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
258         ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "unexpected format %s\n", debugstr_guid(&format));
259
260         IWICMetadataReader_Release(reader);
261     }
262
263     IStream_Release(stream);
264
265     IWICComponentFactory_Release(factory);
266 }
267
268 START_TEST(metadata)
269 {
270     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
271
272     test_metadata_unknown();
273     test_metadata_tEXt();
274     test_create_reader();
275
276     CoUninitialize();
277 }