* Sync up to trunk HEAD (r62975).
[reactos.git] / dll / win32 / windowscodecs / info.c
1 /*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 * Copyright 2012 Dmitry Timoshkov
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20 #include "wincodecs_private.h"
21
22 #include <wine/list.h>
23
24 static const WCHAR mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0};
25 static const WCHAR author_valuename[] = {'A','u','t','h','o','r',0};
26 static const WCHAR friendlyname_valuename[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
27 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
28 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
29 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
30 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
31 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
32 static const WCHAR version_valuename[] = {'V','e','r','s','i','o','n',0};
33 static const WCHAR specversion_valuename[] = {'S','p','e','c','V','e','r','s','i','o','n',0};
34 static const WCHAR bitsperpixel_valuename[] = {'B','i','t','L','e','n','g','t','h',0};
35 static const WCHAR channelcount_valuename[] = {'C','h','a','n','n','e','l','C','o','u','n','t',0};
36 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
37 static const WCHAR numericrepresentation_valuename[] = {'N','u','m','e','r','i','c','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0};
38 static const WCHAR supportstransparency_valuename[] = {'S','u','p','p','o','r','t','s','T','r','a','n','s','p','a','r','e','n','c','y',0};
39 static const WCHAR requiresfullstream_valuename[] = {'R','e','q','u','i','r','e','s','F','u','l','l','S','t','r','e','a','m',0};
40 static const WCHAR supportspadding_valuename[] = {'S','u','p','p','o','r','t','s','P','a','d','d','i','n','g',0};
41 static const WCHAR fileextensions_valuename[] = {'F','i','l','e','E','x','t','e','n','s','i','o','n','s',0};
42
43 static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value,
44 UINT buffer_size, WCHAR *buffer, UINT *actual_size)
45 {
46 LONG ret;
47 DWORD cbdata=buffer_size * sizeof(WCHAR);
48
49 if (!actual_size)
50 return E_INVALIDARG;
51
52 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
53 buffer, &cbdata);
54
55 if (ret == ERROR_FILE_NOT_FOUND)
56 {
57 *actual_size = 0;
58 return S_OK;
59 }
60
61 if (ret == 0 || ret == ERROR_MORE_DATA)
62 *actual_size = cbdata/sizeof(WCHAR);
63
64 if (!buffer && buffer_size != 0)
65 /* Yes, native returns the correct size in this case. */
66 return E_INVALIDARG;
67
68 if (ret == ERROR_MORE_DATA)
69 return WINCODEC_ERR_INSUFFICIENTBUFFER;
70
71 return HRESULT_FROM_WIN32(ret);
72 }
73
74 static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value,
75 GUID *result)
76 {
77 LONG ret;
78 WCHAR guid_string[39];
79 DWORD cbdata = sizeof(guid_string);
80 HRESULT hr;
81
82 if (!result)
83 return E_INVALIDARG;
84
85 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
86 guid_string, &cbdata);
87
88 if (ret != ERROR_SUCCESS)
89 return HRESULT_FROM_WIN32(ret);
90
91 if (cbdata < sizeof(guid_string))
92 {
93 ERR("incomplete GUID value\n");
94 return E_FAIL;
95 }
96
97 hr = CLSIDFromString(guid_string, result);
98
99 return hr;
100 }
101
102 static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value,
103 DWORD *result)
104 {
105 LONG ret;
106 DWORD cbdata = sizeof(DWORD);
107
108 if (!result)
109 return E_INVALIDARG;
110
111 ret = RegGetValueW(classkey, NULL, value, RRF_RT_DWORD, NULL,
112 result, &cbdata);
113
114 if (ret == ERROR_FILE_NOT_FOUND)
115 {
116 *result = 0;
117 return S_OK;
118 }
119
120 return HRESULT_FROM_WIN32(ret);
121 }
122
123 static HRESULT ComponentInfo_GetGuidList(HKEY classkey, LPCWSTR subkeyname,
124 UINT buffersize, GUID *buffer, UINT *actual_size)
125 {
126 LONG ret;
127 HKEY subkey;
128 UINT items_returned;
129 WCHAR guid_string[39];
130 DWORD guid_string_size;
131 HRESULT hr=S_OK;
132
133 if (!actual_size)
134 return E_INVALIDARG;
135
136 ret = RegOpenKeyExW(classkey, subkeyname, 0, KEY_READ, &subkey);
137 if (ret != ERROR_SUCCESS) return HRESULT_FROM_WIN32(ret);
138
139 if (buffer)
140 {
141 items_returned = 0;
142 guid_string_size = 39;
143 while (items_returned < buffersize)
144 {
145 ret = RegEnumKeyExW(subkey, items_returned, guid_string,
146 &guid_string_size, NULL, NULL, NULL, NULL);
147
148 if (ret != ERROR_SUCCESS)
149 {
150 hr = HRESULT_FROM_WIN32(ret);
151 break;
152 }
153
154 if (guid_string_size != 38)
155 {
156 hr = E_FAIL;
157 break;
158 }
159
160 hr = CLSIDFromString(guid_string, &buffer[items_returned]);
161 if (FAILED(hr))
162 break;
163
164 items_returned++;
165 guid_string_size = 39;
166 }
167
168 if (ret == ERROR_NO_MORE_ITEMS)
169 hr = S_OK;
170
171 *actual_size = items_returned;
172 }
173 else
174 {
175 ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, actual_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
176 if (ret != ERROR_SUCCESS)
177 hr = HRESULT_FROM_WIN32(ret);
178 }
179
180 RegCloseKey(subkey);
181
182 return hr;
183 }
184
185 typedef struct {
186 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface;
187 LONG ref;
188 HKEY classkey;
189 CLSID clsid;
190 } BitmapDecoderInfo;
191
192 static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo *iface)
193 {
194 return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface);
195 }
196
197 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid,
198 void **ppv)
199 {
200 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
201 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
202
203 if (!ppv) return E_INVALIDARG;
204
205 if (IsEqualIID(&IID_IUnknown, iid) ||
206 IsEqualIID(&IID_IWICComponentInfo, iid) ||
207 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
208 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
209 {
210 *ppv = This;
211 }
212 else
213 {
214 *ppv = NULL;
215 return E_NOINTERFACE;
216 }
217
218 IUnknown_AddRef((IUnknown*)*ppv);
219 return S_OK;
220 }
221
222 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
223 {
224 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
225 ULONG ref = InterlockedIncrement(&This->ref);
226
227 TRACE("(%p) refcount=%u\n", iface, ref);
228
229 return ref;
230 }
231
232 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
233 {
234 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
235 ULONG ref = InterlockedDecrement(&This->ref);
236
237 TRACE("(%p) refcount=%u\n", iface, ref);
238
239 if (ref == 0)
240 {
241 RegCloseKey(This->classkey);
242 HeapFree(GetProcessHeap(), 0, This);
243 }
244
245 return ref;
246 }
247
248 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface,
249 WICComponentType *pType)
250 {
251 TRACE("(%p,%p)\n", iface, pType);
252 if (!pType) return E_INVALIDARG;
253 *pType = WICDecoder;
254 return S_OK;
255 }
256
257 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid)
258 {
259 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
260 TRACE("(%p,%p)\n", iface, pclsid);
261
262 if (!pclsid)
263 return E_INVALIDARG;
264
265 memcpy(pclsid, &This->clsid, sizeof(CLSID));
266
267 return S_OK;
268 }
269
270 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus)
271 {
272 FIXME("(%p,%p): stub\n", iface, pStatus);
273 return E_NOTIMPL;
274 }
275
276 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor,
277 WCHAR *wzAuthor, UINT *pcchActual)
278 {
279 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
280
281 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
282
283 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
284 cchAuthor, wzAuthor, pcchActual);
285 }
286
287 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
288 {
289 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
290
291 TRACE("(%p,%p)\n", iface, pguidVendor);
292
293 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
294 }
295
296 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
297 WCHAR *wzVersion, UINT *pcchActual)
298 {
299 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
300
301 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
302
303 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
304 cchVersion, wzVersion, pcchActual);
305 }
306
307 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
308 WCHAR *wzSpecVersion, UINT *pcchActual)
309 {
310 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
311
312 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
313
314 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
315 cchSpecVersion, wzSpecVersion, pcchActual);
316 }
317
318 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
319 WCHAR *wzFriendlyName, UINT *pcchActual)
320 {
321 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
322
323 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
324
325 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
326 cchFriendlyName, wzFriendlyName, pcchActual);
327 }
328
329 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
330 GUID *pguidContainerFormat)
331 {
332 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
333 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
334 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
335 }
336
337 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
338 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
339 {
340 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
341 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
342 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
343 }
344
345 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface,
346 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
347 {
348 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
349 return E_NOTIMPL;
350 }
351
352 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface,
353 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
354 {
355 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
356 return E_NOTIMPL;
357 }
358
359 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface,
360 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
361 {
362 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
363 return E_NOTIMPL;
364 }
365
366 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface,
367 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
368 {
369 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
370
371 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
372
373 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
374 cchMimeTypes, wzMimeTypes, pcchActual);
375 }
376
377 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface,
378 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
379 {
380 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
381
382 TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
383
384 return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename,
385 cchFileExtensions, wzFileExtensions, pcchActual);
386 }
387
388 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface,
389 BOOL *pfSupportAnimation)
390 {
391 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
392 return E_NOTIMPL;
393 }
394
395 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface,
396 BOOL *pfSupportChromaKey)
397 {
398 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
399 return E_NOTIMPL;
400 }
401
402 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface,
403 BOOL *pfSupportLossless)
404 {
405 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
406 return E_NOTIMPL;
407 }
408
409 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface,
410 BOOL *pfSupportMultiframe)
411 {
412 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
413 return E_NOTIMPL;
414 }
415
416 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface,
417 LPCWSTR wzMimeType, BOOL *pfMatches)
418 {
419 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
420 return E_NOTIMPL;
421 }
422
423 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface,
424 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual)
425 {
426 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
427 UINT pattern_count=0, patterns_size=0;
428 WCHAR subkeyname[11];
429 LONG res;
430 HKEY patternskey, patternkey;
431 static const WCHAR uintformatW[] = {'%','u',0};
432 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0};
433 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
434 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0};
435 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
436 static const WCHAR maskW[] = {'M','a','s','k',0};
437 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
438 HRESULT hr=S_OK;
439 UINT i;
440 BYTE *bPatterns=(BYTE*)pPatterns;
441 DWORD length, valuesize;
442
443 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual);
444
445 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
446 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
447
448 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
449 if (res == ERROR_SUCCESS)
450 {
451 patterns_size = pattern_count * sizeof(WICBitmapPattern);
452
453 for (i=0; i<pattern_count; i++)
454 {
455 snprintfW(subkeyname, 11, uintformatW, i);
456 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
457 if (res == ERROR_SUCCESS)
458 {
459 valuesize = sizeof(ULONG);
460 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
461 &length, &valuesize);
462 patterns_size += length*2;
463
464 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS))
465 {
466 pPatterns[i].Length = length;
467
468 pPatterns[i].EndOfStream = 0;
469 valuesize = sizeof(BOOL);
470 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
471 &pPatterns[i].EndOfStream, &valuesize);
472
473 pPatterns[i].Position.QuadPart = 0;
474 valuesize = sizeof(ULARGE_INTEGER);
475 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
476 &pPatterns[i].Position, &valuesize);
477
478 if (res == ERROR_SUCCESS)
479 {
480 pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
481 valuesize = length;
482 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
483 pPatterns[i].Pattern, &valuesize);
484 }
485
486 if (res == ERROR_SUCCESS)
487 {
488 pPatterns[i].Mask = bPatterns+patterns_size-length;
489 valuesize = length;
490 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
491 pPatterns[i].Mask, &valuesize);
492 }
493 }
494
495 RegCloseKey(patternkey);
496 }
497 if (res != ERROR_SUCCESS)
498 {
499 hr = HRESULT_FROM_WIN32(res);
500 break;
501 }
502 }
503 }
504 else hr = HRESULT_FROM_WIN32(res);
505
506 RegCloseKey(patternskey);
507
508 if (hr == S_OK)
509 {
510 *pcPatterns = pattern_count;
511 *pcbPatternsActual = patterns_size;
512 if (pPatterns && cbSizePatterns < patterns_size)
513 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
514 }
515
516 return hr;
517 }
518
519 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
520 IStream *pIStream, BOOL *pfMatches)
521 {
522 WICBitmapPattern *patterns;
523 UINT pattern_count=0, patterns_size=0;
524 HRESULT hr;
525 UINT i;
526 ULONG pos;
527 BYTE *data=NULL;
528 ULONG datasize=0;
529 ULONG bytesread;
530 LARGE_INTEGER seekpos;
531
532 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
533
534 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
535 if (FAILED(hr)) return hr;
536
537 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
538 if (!patterns) return E_OUTOFMEMORY;
539
540 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
541 if (FAILED(hr)) goto end;
542
543 for (i=0; i<pattern_count; i++)
544 {
545 if (datasize < patterns[i].Length)
546 {
547 HeapFree(GetProcessHeap(), 0, data);
548 datasize = patterns[i].Length;
549 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
550 if (!data)
551 {
552 hr = E_OUTOFMEMORY;
553 break;
554 }
555 }
556
557 if (patterns[i].EndOfStream)
558 seekpos.QuadPart = -patterns[i].Position.QuadPart;
559 else
560 seekpos.QuadPart = patterns[i].Position.QuadPart;
561 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
562 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
563 if (FAILED(hr)) break;
564
565 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
566 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
567 continue;
568 if (FAILED(hr)) break;
569
570 for (pos=0; pos<patterns[i].Length; pos++)
571 {
572 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
573 break;
574 }
575 if (pos == patterns[i].Length) /* matches pattern */
576 {
577 hr = S_OK;
578 *pfMatches = TRUE;
579 break;
580 }
581 }
582
583 if (i == pattern_count) /* does not match any pattern */
584 {
585 hr = S_OK;
586 *pfMatches = FALSE;
587 }
588
589 end:
590 HeapFree(GetProcessHeap(), 0, patterns);
591 HeapFree(GetProcessHeap(), 0, data);
592
593 return hr;
594 }
595
596 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
597 IWICBitmapDecoder **ppIBitmapDecoder)
598 {
599 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
600
601 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
602
603 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
604 &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
605 }
606
607 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
608 BitmapDecoderInfo_QueryInterface,
609 BitmapDecoderInfo_AddRef,
610 BitmapDecoderInfo_Release,
611 BitmapDecoderInfo_GetComponentType,
612 BitmapDecoderInfo_GetCLSID,
613 BitmapDecoderInfo_GetSigningStatus,
614 BitmapDecoderInfo_GetAuthor,
615 BitmapDecoderInfo_GetVendorGUID,
616 BitmapDecoderInfo_GetVersion,
617 BitmapDecoderInfo_GetSpecVersion,
618 BitmapDecoderInfo_GetFriendlyName,
619 BitmapDecoderInfo_GetContainerFormat,
620 BitmapDecoderInfo_GetPixelFormats,
621 BitmapDecoderInfo_GetColorManagementVersion,
622 BitmapDecoderInfo_GetDeviceManufacturer,
623 BitmapDecoderInfo_GetDeviceModels,
624 BitmapDecoderInfo_GetMimeTypes,
625 BitmapDecoderInfo_GetFileExtensions,
626 BitmapDecoderInfo_DoesSupportAnimation,
627 BitmapDecoderInfo_DoesSupportChromaKey,
628 BitmapDecoderInfo_DoesSupportLossless,
629 BitmapDecoderInfo_DoesSupportMultiframe,
630 BitmapDecoderInfo_MatchesMimeType,
631 BitmapDecoderInfo_GetPatterns,
632 BitmapDecoderInfo_MatchesPattern,
633 BitmapDecoderInfo_CreateInstance
634 };
635
636 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
637 {
638 BitmapDecoderInfo *This;
639
640 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
641 if (!This)
642 {
643 RegCloseKey(classkey);
644 return E_OUTOFMEMORY;
645 }
646
647 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
648 This->ref = 1;
649 This->classkey = classkey;
650 memcpy(&This->clsid, clsid, sizeof(CLSID));
651
652 *ppIInfo = (IWICComponentInfo*)This;
653 return S_OK;
654 }
655
656 typedef struct {
657 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
658 LONG ref;
659 HKEY classkey;
660 CLSID clsid;
661 } BitmapEncoderInfo;
662
663 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
664 {
665 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
666 }
667
668 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
669 void **ppv)
670 {
671 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
672 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
673
674 if (!ppv) return E_INVALIDARG;
675
676 if (IsEqualIID(&IID_IUnknown, iid) ||
677 IsEqualIID(&IID_IWICComponentInfo, iid) ||
678 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
679 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
680 {
681 *ppv = This;
682 }
683 else
684 {
685 *ppv = NULL;
686 return E_NOINTERFACE;
687 }
688
689 IUnknown_AddRef((IUnknown*)*ppv);
690 return S_OK;
691 }
692
693 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
694 {
695 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
696 ULONG ref = InterlockedIncrement(&This->ref);
697
698 TRACE("(%p) refcount=%u\n", iface, ref);
699
700 return ref;
701 }
702
703 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
704 {
705 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
706 ULONG ref = InterlockedDecrement(&This->ref);
707
708 TRACE("(%p) refcount=%u\n", iface, ref);
709
710 if (ref == 0)
711 {
712 RegCloseKey(This->classkey);
713 HeapFree(GetProcessHeap(), 0, This);
714 }
715
716 return ref;
717 }
718
719 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
720 WICComponentType *pType)
721 {
722 TRACE("(%p,%p)\n", iface, pType);
723 if (!pType) return E_INVALIDARG;
724 *pType = WICEncoder;
725 return S_OK;
726 }
727
728 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
729 {
730 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
731 TRACE("(%p,%p)\n", iface, pclsid);
732
733 if (!pclsid)
734 return E_INVALIDARG;
735
736 memcpy(pclsid, &This->clsid, sizeof(CLSID));
737
738 return S_OK;
739 }
740
741 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
742 {
743 FIXME("(%p,%p): stub\n", iface, pStatus);
744 return E_NOTIMPL;
745 }
746
747 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
748 WCHAR *wzAuthor, UINT *pcchActual)
749 {
750 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
751
752 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
753
754 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
755 cchAuthor, wzAuthor, pcchActual);
756 }
757
758 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
759 {
760 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
761
762 TRACE("(%p,%p)\n", iface, pguidVendor);
763
764 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
765 }
766
767 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
768 WCHAR *wzVersion, UINT *pcchActual)
769 {
770 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
771
772 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
773
774 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
775 cchVersion, wzVersion, pcchActual);
776 }
777
778 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
779 WCHAR *wzSpecVersion, UINT *pcchActual)
780 {
781 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
782
783 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
784
785 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
786 cchSpecVersion, wzSpecVersion, pcchActual);
787 }
788
789 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
790 WCHAR *wzFriendlyName, UINT *pcchActual)
791 {
792 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
793
794 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
795
796 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
797 cchFriendlyName, wzFriendlyName, pcchActual);
798 }
799
800 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
801 GUID *pguidContainerFormat)
802 {
803 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
804 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
805 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
806 }
807
808 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
809 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
810 {
811 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
812 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
813 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
814 }
815
816 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
817 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
818 {
819 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
820 return E_NOTIMPL;
821 }
822
823 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
824 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
825 {
826 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
827 return E_NOTIMPL;
828 }
829
830 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
831 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
832 {
833 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
834 return E_NOTIMPL;
835 }
836
837 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
838 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
839 {
840 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
841
842 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
843
844 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
845 cchMimeTypes, wzMimeTypes, pcchActual);
846 }
847
848 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
849 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
850 {
851 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
852 return E_NOTIMPL;
853 }
854
855 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
856 BOOL *pfSupportAnimation)
857 {
858 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
859 return E_NOTIMPL;
860 }
861
862 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
863 BOOL *pfSupportChromaKey)
864 {
865 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
866 return E_NOTIMPL;
867 }
868
869 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
870 BOOL *pfSupportLossless)
871 {
872 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
873 return E_NOTIMPL;
874 }
875
876 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
877 BOOL *pfSupportMultiframe)
878 {
879 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
880 return E_NOTIMPL;
881 }
882
883 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
884 LPCWSTR wzMimeType, BOOL *pfMatches)
885 {
886 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
887 return E_NOTIMPL;
888 }
889
890 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
891 IWICBitmapEncoder **ppIBitmapEncoder)
892 {
893 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
894
895 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
896
897 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
898 &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
899 }
900
901 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
902 BitmapEncoderInfo_QueryInterface,
903 BitmapEncoderInfo_AddRef,
904 BitmapEncoderInfo_Release,
905 BitmapEncoderInfo_GetComponentType,
906 BitmapEncoderInfo_GetCLSID,
907 BitmapEncoderInfo_GetSigningStatus,
908 BitmapEncoderInfo_GetAuthor,
909 BitmapEncoderInfo_GetVendorGUID,
910 BitmapEncoderInfo_GetVersion,
911 BitmapEncoderInfo_GetSpecVersion,
912 BitmapEncoderInfo_GetFriendlyName,
913 BitmapEncoderInfo_GetContainerFormat,
914 BitmapEncoderInfo_GetPixelFormats,
915 BitmapEncoderInfo_GetColorManagementVersion,
916 BitmapEncoderInfo_GetDeviceManufacturer,
917 BitmapEncoderInfo_GetDeviceModels,
918 BitmapEncoderInfo_GetMimeTypes,
919 BitmapEncoderInfo_GetFileExtensions,
920 BitmapEncoderInfo_DoesSupportAnimation,
921 BitmapEncoderInfo_DoesSupportChromaKey,
922 BitmapEncoderInfo_DoesSupportLossless,
923 BitmapEncoderInfo_DoesSupportMultiframe,
924 BitmapEncoderInfo_MatchesMimeType,
925 BitmapEncoderInfo_CreateInstance
926 };
927
928 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
929 {
930 BitmapEncoderInfo *This;
931
932 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
933 if (!This)
934 {
935 RegCloseKey(classkey);
936 return E_OUTOFMEMORY;
937 }
938
939 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
940 This->ref = 1;
941 This->classkey = classkey;
942 memcpy(&This->clsid, clsid, sizeof(CLSID));
943
944 *ppIInfo = (IWICComponentInfo*)This;
945 return S_OK;
946 }
947
948 typedef struct {
949 IWICFormatConverterInfo IWICFormatConverterInfo_iface;
950 LONG ref;
951 HKEY classkey;
952 CLSID clsid;
953 } FormatConverterInfo;
954
955 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
956 {
957 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
958 }
959
960 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
961 void **ppv)
962 {
963 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
964 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
965
966 if (!ppv) return E_INVALIDARG;
967
968 if (IsEqualIID(&IID_IUnknown, iid) ||
969 IsEqualIID(&IID_IWICComponentInfo, iid) ||
970 IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
971 {
972 *ppv = This;
973 }
974 else
975 {
976 *ppv = NULL;
977 return E_NOINTERFACE;
978 }
979
980 IUnknown_AddRef((IUnknown*)*ppv);
981 return S_OK;
982 }
983
984 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
985 {
986 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
987 ULONG ref = InterlockedIncrement(&This->ref);
988
989 TRACE("(%p) refcount=%u\n", iface, ref);
990
991 return ref;
992 }
993
994 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
995 {
996 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
997 ULONG ref = InterlockedDecrement(&This->ref);
998
999 TRACE("(%p) refcount=%u\n", iface, ref);
1000
1001 if (ref == 0)
1002 {
1003 RegCloseKey(This->classkey);
1004 HeapFree(GetProcessHeap(), 0, This);
1005 }
1006
1007 return ref;
1008 }
1009
1010 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
1011 WICComponentType *pType)
1012 {
1013 TRACE("(%p,%p)\n", iface, pType);
1014 if (!pType) return E_INVALIDARG;
1015 *pType = WICPixelFormatConverter;
1016 return S_OK;
1017 }
1018
1019 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
1020 {
1021 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1022 TRACE("(%p,%p)\n", iface, pclsid);
1023
1024 if (!pclsid)
1025 return E_INVALIDARG;
1026
1027 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1028
1029 return S_OK;
1030 }
1031
1032 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
1033 {
1034 FIXME("(%p,%p): stub\n", iface, pStatus);
1035 return E_NOTIMPL;
1036 }
1037
1038 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
1039 WCHAR *wzAuthor, UINT *pcchActual)
1040 {
1041 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1042
1043 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1044
1045 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1046 cchAuthor, wzAuthor, pcchActual);
1047 }
1048
1049 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
1050 {
1051 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1052
1053 TRACE("(%p,%p)\n", iface, pguidVendor);
1054
1055 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1056 }
1057
1058 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
1059 WCHAR *wzVersion, UINT *pcchActual)
1060 {
1061 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1062
1063 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1064
1065 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1066 cchVersion, wzVersion, pcchActual);
1067 }
1068
1069 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
1070 WCHAR *wzSpecVersion, UINT *pcchActual)
1071 {
1072 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1073
1074 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1075
1076 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1077 cchSpecVersion, wzSpecVersion, pcchActual);
1078 }
1079
1080 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
1081 WCHAR *wzFriendlyName, UINT *pcchActual)
1082 {
1083 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1084
1085 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1086
1087 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1088 cchFriendlyName, wzFriendlyName, pcchActual);
1089 }
1090
1091 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
1092 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
1093 {
1094 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
1095 return E_NOTIMPL;
1096 }
1097
1098 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
1099 IWICFormatConverter **ppIFormatConverter)
1100 {
1101 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1102
1103 TRACE("(%p,%p)\n", iface, ppIFormatConverter);
1104
1105 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1106 &IID_IWICFormatConverter, (void**)ppIFormatConverter);
1107 }
1108
1109 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
1110 {
1111 LONG res;
1112 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1113 HKEY formats_key, guid_key;
1114
1115 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
1116 would be O(n). A registry test should do better. */
1117
1118 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
1119 if (res != ERROR_SUCCESS) return FALSE;
1120
1121 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
1122 if (res == ERROR_SUCCESS) RegCloseKey(guid_key);
1123
1124 RegCloseKey(formats_key);
1125
1126 return (res == ERROR_SUCCESS);
1127 }
1128
1129 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
1130 FormatConverterInfo_QueryInterface,
1131 FormatConverterInfo_AddRef,
1132 FormatConverterInfo_Release,
1133 FormatConverterInfo_GetComponentType,
1134 FormatConverterInfo_GetCLSID,
1135 FormatConverterInfo_GetSigningStatus,
1136 FormatConverterInfo_GetAuthor,
1137 FormatConverterInfo_GetVendorGUID,
1138 FormatConverterInfo_GetVersion,
1139 FormatConverterInfo_GetSpecVersion,
1140 FormatConverterInfo_GetFriendlyName,
1141 FormatConverterInfo_GetPixelFormats,
1142 FormatConverterInfo_CreateInstance
1143 };
1144
1145 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1146 {
1147 FormatConverterInfo *This;
1148
1149 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
1150 if (!This)
1151 {
1152 RegCloseKey(classkey);
1153 return E_OUTOFMEMORY;
1154 }
1155
1156 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
1157 This->ref = 1;
1158 This->classkey = classkey;
1159 memcpy(&This->clsid, clsid, sizeof(CLSID));
1160
1161 *ppIInfo = (IWICComponentInfo*)This;
1162 return S_OK;
1163 }
1164
1165 typedef struct {
1166 IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface;
1167 LONG ref;
1168 HKEY classkey;
1169 CLSID clsid;
1170 } PixelFormatInfo;
1171
1172 static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2 *iface)
1173 {
1174 return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface);
1175 }
1176
1177 static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID iid,
1178 void **ppv)
1179 {
1180 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1181 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1182
1183 if (!ppv) return E_INVALIDARG;
1184
1185 if (IsEqualIID(&IID_IUnknown, iid) ||
1186 IsEqualIID(&IID_IWICComponentInfo, iid) ||
1187 IsEqualIID(&IID_IWICPixelFormatInfo, iid) ||
1188 IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid))
1189 {
1190 *ppv = This;
1191 }
1192 else
1193 {
1194 *ppv = NULL;
1195 return E_NOINTERFACE;
1196 }
1197
1198 IUnknown_AddRef((IUnknown*)*ppv);
1199 return S_OK;
1200 }
1201
1202 static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface)
1203 {
1204 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1205 ULONG ref = InterlockedIncrement(&This->ref);
1206
1207 TRACE("(%p) refcount=%u\n", iface, ref);
1208
1209 return ref;
1210 }
1211
1212 static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface)
1213 {
1214 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1215 ULONG ref = InterlockedDecrement(&This->ref);
1216
1217 TRACE("(%p) refcount=%u\n", iface, ref);
1218
1219 if (ref == 0)
1220 {
1221 RegCloseKey(This->classkey);
1222 HeapFree(GetProcessHeap(), 0, This);
1223 }
1224
1225 return ref;
1226 }
1227
1228 static HRESULT WINAPI PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2 *iface,
1229 WICComponentType *pType)
1230 {
1231 TRACE("(%p,%p)\n", iface, pType);
1232 if (!pType) return E_INVALIDARG;
1233 *pType = WICPixelFormat;
1234 return S_OK;
1235 }
1236
1237 static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2 *iface, CLSID *pclsid)
1238 {
1239 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1240 TRACE("(%p,%p)\n", iface, pclsid);
1241
1242 if (!pclsid)
1243 return E_INVALIDARG;
1244
1245 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1246
1247 return S_OK;
1248 }
1249
1250 static HRESULT WINAPI PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2 *iface, DWORD *pStatus)
1251 {
1252 TRACE("(%p,%p)\n", iface, pStatus);
1253
1254 if (!pStatus)
1255 return E_INVALIDARG;
1256
1257 /* Pixel formats don't require code, so they are considered signed. */
1258 *pStatus = WICComponentSigned;
1259
1260 return S_OK;
1261 }
1262
1263 static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UINT cchAuthor,
1264 WCHAR *wzAuthor, UINT *pcchActual)
1265 {
1266 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1267
1268 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1269
1270 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1271 cchAuthor, wzAuthor, pcchActual);
1272 }
1273
1274 static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor)
1275 {
1276 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1277
1278 TRACE("(%p,%p)\n", iface, pguidVendor);
1279
1280 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1281 }
1282
1283 static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion,
1284 WCHAR *wzVersion, UINT *pcchActual)
1285 {
1286 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1287
1288 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1289
1290 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1291 cchVersion, wzVersion, pcchActual);
1292 }
1293
1294 static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface, UINT cchSpecVersion,
1295 WCHAR *wzSpecVersion, UINT *pcchActual)
1296 {
1297 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1298
1299 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1300
1301 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1302 cchSpecVersion, wzSpecVersion, pcchActual);
1303 }
1304
1305 static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *iface, UINT cchFriendlyName,
1306 WCHAR *wzFriendlyName, UINT *pcchActual)
1307 {
1308 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1309
1310 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1311
1312 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1313 cchFriendlyName, wzFriendlyName, pcchActual);
1314 }
1315
1316 static HRESULT WINAPI PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface,
1317 GUID *pFormat)
1318 {
1319 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1320 TRACE("(%p,%p)\n", iface, pFormat);
1321
1322 if (!pFormat)
1323 return E_INVALIDARG;
1324
1325 *pFormat = This->clsid;
1326
1327 return S_OK;
1328 }
1329
1330 static HRESULT WINAPI PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2 *iface,
1331 IWICColorContext **ppIColorContext)
1332 {
1333 FIXME("(%p,%p): stub\n", iface, ppIColorContext);
1334 return E_NOTIMPL;
1335 }
1336
1337 static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *iface,
1338 UINT *puiBitsPerPixel)
1339 {
1340 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1341
1342 TRACE("(%p,%p)\n", iface, puiBitsPerPixel);
1343
1344 return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel);
1345 }
1346
1347 static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface,
1348 UINT *puiChannelCount)
1349 {
1350 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1351
1352 TRACE("(%p,%p)\n", iface, puiChannelCount);
1353
1354 return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount);
1355 }
1356
1357 static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface,
1358 UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual)
1359 {
1360 static const WCHAR uintformatW[] = {'%','u',0};
1361 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1362 UINT channel_count;
1363 HRESULT hr;
1364 LONG ret;
1365 WCHAR valuename[11];
1366 DWORD cbData;
1367
1368 TRACE("(%p,%u,%u,%p,%p)\n", iface, uiChannelIndex, cbMaskBuffer, pbMaskBuffer, pcbActual);
1369
1370 if (!pcbActual)
1371 return E_INVALIDARG;
1372
1373 hr = PixelFormatInfo_GetChannelCount(iface, &channel_count);
1374
1375 if (SUCCEEDED(hr) && uiChannelIndex >= channel_count)
1376 hr = E_INVALIDARG;
1377
1378 if (SUCCEEDED(hr))
1379 {
1380 snprintfW(valuename, 11, uintformatW, uiChannelIndex);
1381
1382 cbData = cbMaskBuffer;
1383
1384 ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData);
1385
1386 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
1387 *pcbActual = cbData;
1388
1389 if (ret == ERROR_MORE_DATA)
1390 hr = E_INVALIDARG;
1391 else
1392 hr = HRESULT_FROM_WIN32(ret);
1393 }
1394
1395 return hr;
1396 }
1397
1398 static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 *iface,
1399 BOOL *pfSupportsTransparency)
1400 {
1401 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1402
1403 TRACE("(%p,%p)\n", iface, pfSupportsTransparency);
1404
1405 return ComponentInfo_GetDWORDValue(This->classkey, supportstransparency_valuename, (DWORD*)pfSupportsTransparency);
1406 }
1407
1408 static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface,
1409 WICPixelFormatNumericRepresentation *pNumericRepresentation)
1410 {
1411 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1412
1413 TRACE("(%p,%p)\n", iface, pNumericRepresentation);
1414
1415 return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation);
1416 }
1417
1418 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = {
1419 PixelFormatInfo_QueryInterface,
1420 PixelFormatInfo_AddRef,
1421 PixelFormatInfo_Release,
1422 PixelFormatInfo_GetComponentType,
1423 PixelFormatInfo_GetCLSID,
1424 PixelFormatInfo_GetSigningStatus,
1425 PixelFormatInfo_GetAuthor,
1426 PixelFormatInfo_GetVendorGUID,
1427 PixelFormatInfo_GetVersion,
1428 PixelFormatInfo_GetSpecVersion,
1429 PixelFormatInfo_GetFriendlyName,
1430 PixelFormatInfo_GetFormatGUID,
1431 PixelFormatInfo_GetColorContext,
1432 PixelFormatInfo_GetBitsPerPixel,
1433 PixelFormatInfo_GetChannelCount,
1434 PixelFormatInfo_GetChannelMask,
1435 PixelFormatInfo_SupportsTransparency,
1436 PixelFormatInfo_GetNumericRepresentation
1437 };
1438
1439 static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1440 {
1441 PixelFormatInfo *This;
1442
1443 This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo));
1444 if (!This)
1445 {
1446 RegCloseKey(classkey);
1447 return E_OUTOFMEMORY;
1448 }
1449
1450 This->IWICPixelFormatInfo2_iface.lpVtbl = &PixelFormatInfo_Vtbl;
1451 This->ref = 1;
1452 This->classkey = classkey;
1453 memcpy(&This->clsid, clsid, sizeof(CLSID));
1454
1455 *ppIInfo = (IWICComponentInfo*)This;
1456 return S_OK;
1457 }
1458
1459 typedef struct
1460 {
1461 IWICMetadataReaderInfo IWICMetadataReaderInfo_iface;
1462 LONG ref;
1463 HKEY classkey;
1464 CLSID clsid;
1465 } MetadataReaderInfo;
1466
1467 static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo *iface)
1468 {
1469 return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface);
1470 }
1471
1472 static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface,
1473 REFIID riid, void **ppv)
1474 {
1475 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1476
1477 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
1478
1479 if (!ppv) return E_INVALIDARG;
1480
1481 if (IsEqualIID(&IID_IUnknown, riid) ||
1482 IsEqualIID(&IID_IWICComponentInfo, riid) ||
1483 IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) ||
1484 IsEqualIID(&IID_IWICMetadataReaderInfo, riid))
1485 {
1486 *ppv = This;
1487 }
1488 else
1489 {
1490 *ppv = NULL;
1491 return E_NOINTERFACE;
1492 }
1493
1494 IUnknown_AddRef((IUnknown *)*ppv);
1495 return S_OK;
1496 }
1497
1498 static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
1499 {
1500 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1501 ULONG ref = InterlockedIncrement(&This->ref);
1502
1503 TRACE("(%p) refcount=%u\n", iface, ref);
1504 return ref;
1505 }
1506
1507 static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface)
1508 {
1509 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1510 ULONG ref = InterlockedDecrement(&This->ref);
1511
1512 TRACE("(%p) refcount=%u\n", iface, ref);
1513
1514 if (!ref)
1515 {
1516 RegCloseKey(This->classkey);
1517 HeapFree(GetProcessHeap(), 0, This);
1518 }
1519 return ref;
1520 }
1521
1522 static HRESULT WINAPI MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo *iface,
1523 WICComponentType *type)
1524 {
1525 TRACE("(%p,%p)\n", iface, type);
1526
1527 if (!type) return E_INVALIDARG;
1528 *type = WICMetadataReader;
1529 return S_OK;
1530 }
1531
1532 static HRESULT WINAPI MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface,
1533 CLSID *clsid)
1534 {
1535 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1536
1537 TRACE("(%p,%p)\n", iface, clsid);
1538
1539 if (!clsid) return E_INVALIDARG;
1540 *clsid = This->clsid;
1541 return S_OK;
1542 }
1543
1544 static HRESULT WINAPI MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo *iface,
1545 DWORD *status)
1546 {
1547 FIXME("(%p,%p): stub\n", iface, status);
1548 return E_NOTIMPL;
1549 }
1550
1551 static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface,
1552 UINT length, WCHAR *author, UINT *actual_length)
1553 {
1554 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1555
1556 TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length);
1557
1558 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1559 length, author, actual_length);
1560 }
1561
1562 static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface,
1563 GUID *vendor)
1564 {
1565 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1566
1567 TRACE("(%p,%p)\n", iface, vendor);
1568
1569 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, vendor);
1570 }
1571
1572 static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface,
1573 UINT length, WCHAR *version, UINT *actual_length)
1574 {
1575 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1576
1577 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1578
1579 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1580 length, version, actual_length);
1581 }
1582
1583 static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface,
1584 UINT length, WCHAR *version, UINT *actual_length)
1585 {
1586 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1587
1588 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1589
1590 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1591 length, version, actual_length);
1592 }
1593
1594 static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo *iface,
1595 UINT length, WCHAR *name, UINT *actual_length)
1596 {
1597 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1598
1599 TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length);
1600
1601 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1602 length, name, actual_length);
1603 }
1604
1605 static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo *iface,
1606 GUID *format)
1607 {
1608 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1609 TRACE("(%p,%p)\n", iface, format);
1610 return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format);
1611 }
1612
1613 static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface,
1614 UINT length, GUID *formats, UINT *actual_length)
1615 {
1616 if (!actual_length) return E_INVALIDARG;
1617
1618 FIXME("(%p,%u,%p,%p): stub\n", iface, length, formats, actual_length);
1619 return E_NOTIMPL;
1620 }
1621
1622 static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo *iface,
1623 UINT length, WCHAR *manufacturer, UINT *actual_length)
1624 {
1625 FIXME("(%p,%u,%p,%p): stub\n", iface, length, manufacturer, actual_length);
1626 return E_NOTIMPL;
1627 }
1628
1629 static HRESULT WINAPI MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo *iface,
1630 UINT length, WCHAR *models, UINT *actual_length)
1631 {
1632 FIXME("(%p,%u,%p,%p): stub\n", iface, length, models, actual_length);
1633 return E_NOTIMPL;
1634 }
1635
1636 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo *iface,
1637 BOOL *param)
1638 {
1639 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1640 TRACE("(%p,%p)\n", iface, param);
1641 return ComponentInfo_GetDWORDValue(This->classkey, requiresfullstream_valuename, (DWORD *)param);
1642 }
1643
1644 static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface,
1645 BOOL *param)
1646 {
1647 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1648 TRACE("(%p,%p)\n", iface, param);
1649 return ComponentInfo_GetDWORDValue(This->classkey, supportspadding_valuename, (DWORD *)param);
1650 }
1651
1652 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface,
1653 BOOL *param)
1654 {
1655 FIXME("(%p,%p): stub\n", iface, param);
1656 return E_NOTIMPL;
1657 }
1658
1659 static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface,
1660 REFGUID container, UINT length, WICMetadataPattern *pattern, UINT *count, UINT *actual_length)
1661 {
1662 if (!actual_length) return E_INVALIDARG;
1663
1664 FIXME("(%p,%s,%u,%p,%p,%p): stub\n", iface, debugstr_guid(container), length, pattern, count, actual_length);
1665 return E_NOTIMPL;
1666 }
1667
1668 static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface,
1669 REFGUID container, IStream *stream, BOOL *matches)
1670 {
1671 FIXME("(%p,%s,%p,%p): stub\n", iface, debugstr_guid(container), stream, matches);
1672 return E_NOTIMPL;
1673 }
1674
1675 static HRESULT WINAPI MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *iface,
1676 IWICMetadataReader **reader)
1677 {
1678 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1679
1680 TRACE("(%p,%p)\n", iface, reader);
1681
1682 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1683 &IID_IWICMetadataReader, (void **)reader);
1684 }
1685
1686 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = {
1687 MetadataReaderInfo_QueryInterface,
1688 MetadataReaderInfo_AddRef,
1689 MetadataReaderInfo_Release,
1690 MetadataReaderInfo_GetComponentType,
1691 MetadataReaderInfo_GetCLSID,
1692 MetadataReaderInfo_GetSigningStatus,
1693 MetadataReaderInfo_GetAuthor,
1694 MetadataReaderInfo_GetVendorGUID,
1695 MetadataReaderInfo_GetVersion,
1696 MetadataReaderInfo_GetSpecVersion,
1697 MetadataReaderInfo_GetFriendlyName,
1698 MetadataReaderInfo_GetMetadataFormat,
1699 MetadataReaderInfo_GetContainerFormats,
1700 MetadataReaderInfo_GetDeviceManufacturer,
1701 MetadataReaderInfo_GetDeviceModels,
1702 MetadataReaderInfo_DoesRequireFullStream,
1703 MetadataReaderInfo_DoesSupportPadding,
1704 MetadataReaderInfo_DoesRequireFixedSize,
1705 MetadataReaderInfo_GetPatterns,
1706 MetadataReaderInfo_MatchesPattern,
1707 MetadataReaderInfo_CreateInstance
1708 };
1709
1710 static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **info)
1711 {
1712 MetadataReaderInfo *This;
1713
1714 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1715 if (!This)
1716 {
1717 RegCloseKey(classkey);
1718 return E_OUTOFMEMORY;
1719 }
1720
1721 This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl;
1722 This->ref = 1;
1723 This->classkey = classkey;
1724 This->clsid = *clsid;
1725
1726 *info = (IWICComponentInfo *)This;
1727 return S_OK;
1728 }
1729
1730 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
1731 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
1732
1733 struct category {
1734 WICComponentType type;
1735 const GUID *catid;
1736 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
1737 };
1738
1739 static const struct category categories[] = {
1740 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
1741 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
1742 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
1743 {WICPixelFormat, &CATID_WICPixelFormats, PixelFormatInfo_Constructor},
1744 {WICMetadataReader, &CATID_WICMetadataReader, MetadataReaderInfo_Constructor},
1745 {0}
1746 };
1747
1748 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
1749 {
1750 HKEY clsidkey;
1751 HKEY classkey;
1752 HKEY catidkey;
1753 HKEY instancekey;
1754 WCHAR guidstring[39];
1755 LONG res;
1756 const struct category *category;
1757 BOOL found = FALSE;
1758 HRESULT hr;
1759
1760 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1761 if (res != ERROR_SUCCESS)
1762 return HRESULT_FROM_WIN32(res);
1763
1764 for (category=categories; category->type; category++)
1765 {
1766 StringFromGUID2(category->catid, guidstring, 39);
1767 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1768 if (res == ERROR_SUCCESS)
1769 {
1770 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1771 if (res == ERROR_SUCCESS)
1772 {
1773 StringFromGUID2(clsid, guidstring, 39);
1774 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
1775 if (res == ERROR_SUCCESS)
1776 {
1777 RegCloseKey(classkey);
1778 found = TRUE;
1779 }
1780 RegCloseKey(instancekey);
1781 }
1782 RegCloseKey(catidkey);
1783 }
1784 if (found) break;
1785 }
1786
1787 if (found)
1788 {
1789 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
1790 if (res == ERROR_SUCCESS)
1791 hr = category->constructor(classkey, clsid, ppIInfo);
1792 else
1793 hr = HRESULT_FROM_WIN32(res);
1794 }
1795 else
1796 {
1797 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid));
1798 hr = E_FAIL;
1799 }
1800
1801 RegCloseKey(clsidkey);
1802
1803 return hr;
1804 }
1805
1806 typedef struct {
1807 IEnumUnknown IEnumUnknown_iface;
1808 LONG ref;
1809 struct list objects;
1810 struct list *cursor;
1811 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
1812 } ComponentEnum;
1813
1814 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
1815 {
1816 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
1817 }
1818
1819 typedef struct {
1820 struct list entry;
1821 IUnknown *unk;
1822 } ComponentEnumItem;
1823
1824 static const IEnumUnknownVtbl ComponentEnumVtbl;
1825
1826 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
1827 void **ppv)
1828 {
1829 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1830 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1831
1832 if (!ppv) return E_INVALIDARG;
1833
1834 if (IsEqualIID(&IID_IUnknown, iid) ||
1835 IsEqualIID(&IID_IEnumUnknown, iid))
1836 {
1837 *ppv = &This->IEnumUnknown_iface;
1838 }
1839 else
1840 {
1841 *ppv = NULL;
1842 return E_NOINTERFACE;
1843 }
1844
1845 IUnknown_AddRef((IUnknown*)*ppv);
1846 return S_OK;
1847 }
1848
1849 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
1850 {
1851 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1852 ULONG ref = InterlockedIncrement(&This->ref);
1853
1854 TRACE("(%p) refcount=%u\n", iface, ref);
1855
1856 return ref;
1857 }
1858
1859 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
1860 {
1861 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1862 ULONG ref = InterlockedDecrement(&This->ref);
1863 ComponentEnumItem *cursor, *cursor2;
1864
1865 TRACE("(%p) refcount=%u\n", iface, ref);
1866
1867 if (ref == 0)
1868 {
1869 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
1870 {
1871 IUnknown_Release(cursor->unk);
1872 list_remove(&cursor->entry);
1873 HeapFree(GetProcessHeap(), 0, cursor);
1874 }
1875 This->lock.DebugInfo->Spare[0] = 0;
1876 DeleteCriticalSection(&This->lock);
1877 HeapFree(GetProcessHeap(), 0, This);
1878 }
1879
1880 return ref;
1881 }
1882
1883 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
1884 IUnknown **rgelt, ULONG *pceltFetched)
1885 {
1886 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1887 ULONG num_fetched=0;
1888 ComponentEnumItem *item;
1889 HRESULT hr=S_OK;
1890
1891 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
1892
1893 EnterCriticalSection(&This->lock);
1894 while (num_fetched<celt)
1895 {
1896 if (!This->cursor)
1897 {
1898 hr = S_FALSE;
1899 break;
1900 }
1901 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
1902 IUnknown_AddRef(item->unk);
1903 rgelt[num_fetched] = item->unk;
1904 num_fetched++;
1905 This->cursor = list_next(&This->objects, This->cursor);
1906 }
1907 LeaveCriticalSection(&This->lock);
1908 if (pceltFetched)
1909 *pceltFetched = num_fetched;
1910 return hr;
1911 }
1912
1913 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
1914 {
1915 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1916 ULONG i;
1917 HRESULT hr=S_OK;
1918
1919 TRACE("(%p,%u)\n", iface, celt);
1920
1921 EnterCriticalSection(&This->lock);
1922 for (i=0; i<celt; i++)
1923 {
1924 if (!This->cursor)
1925 {
1926 hr = S_FALSE;
1927 break;
1928 }
1929 This->cursor = list_next(&This->objects, This->cursor);
1930 }
1931 LeaveCriticalSection(&This->lock);
1932 return hr;
1933 }
1934
1935 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
1936 {
1937 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1938
1939 TRACE("(%p)\n", iface);
1940
1941 EnterCriticalSection(&This->lock);
1942 This->cursor = list_head(&This->objects);
1943 LeaveCriticalSection(&This->lock);
1944 return S_OK;
1945 }
1946
1947 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
1948 {
1949 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1950 ComponentEnum *new_enum;
1951 ComponentEnumItem *old_item, *new_item;
1952 HRESULT ret=S_OK;
1953 struct list *old_cursor;
1954
1955 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1956 if (!new_enum)
1957 {
1958 *ppenum = NULL;
1959 return E_OUTOFMEMORY;
1960 }
1961
1962 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1963 new_enum->ref = 1;
1964 new_enum->cursor = NULL;
1965 list_init(&new_enum->objects);
1966 InitializeCriticalSection(&new_enum->lock);
1967 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1968
1969 EnterCriticalSection(&This->lock);
1970 old_cursor = This->cursor;
1971 LeaveCriticalSection(&This->lock);
1972
1973 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
1974 {
1975 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1976 if (!new_item)
1977 {
1978 ret = E_OUTOFMEMORY;
1979 break;
1980 }
1981 new_item->unk = old_item->unk;
1982 list_add_tail(&new_enum->objects, &new_item->entry);
1983 IUnknown_AddRef(new_item->unk);
1984 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
1985 }
1986
1987 if (FAILED(ret))
1988 {
1989 IEnumUnknown_Release(&new_enum->IEnumUnknown_iface);
1990 *ppenum = NULL;
1991 }
1992 else
1993 *ppenum = &new_enum->IEnumUnknown_iface;
1994
1995 return ret;
1996 }
1997
1998 static const IEnumUnknownVtbl ComponentEnumVtbl = {
1999 ComponentEnum_QueryInterface,
2000 ComponentEnum_AddRef,
2001 ComponentEnum_Release,
2002 ComponentEnum_Next,
2003 ComponentEnum_Skip,
2004 ComponentEnum_Reset,
2005 ComponentEnum_Clone
2006 };
2007
2008 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
2009 {
2010 ComponentEnum *This;
2011 ComponentEnumItem *item;
2012 const struct category *category;
2013 HKEY clsidkey, catidkey, instancekey;
2014 WCHAR guidstring[39];
2015 LONG res;
2016 int i;
2017 HRESULT hr=S_OK;
2018 CLSID clsid;
2019
2020 if (options) FIXME("ignoring flags %x\n", options);
2021
2022 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
2023 if (res != ERROR_SUCCESS)
2024 return HRESULT_FROM_WIN32(res);
2025
2026 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
2027 if (!This)
2028 {
2029 RegCloseKey(clsidkey);
2030 return E_OUTOFMEMORY;
2031 }
2032
2033 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
2034 This->ref = 1;
2035 list_init(&This->objects);
2036 InitializeCriticalSection(&This->lock);
2037 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
2038
2039 for (category=categories; category->type && hr == S_OK; category++)
2040 {
2041 if ((category->type & componentTypes) == 0) continue;
2042 StringFromGUID2(category->catid, guidstring, 39);
2043 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
2044 if (res == ERROR_SUCCESS)
2045 {
2046 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
2047 if (res == ERROR_SUCCESS)
2048 {
2049 i=0;
2050 for (;;i++)
2051 {
2052 DWORD guidstring_size = 39;
2053 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
2054 if (res != ERROR_SUCCESS) break;
2055
2056 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
2057 if (!item) { hr = E_OUTOFMEMORY; break; }
2058
2059 hr = CLSIDFromString(guidstring, &clsid);
2060 if (SUCCEEDED(hr))
2061 {
2062 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
2063 if (SUCCEEDED(hr))
2064 list_add_tail(&This->objects, &item->entry);
2065 }
2066
2067 if (FAILED(hr))
2068 {
2069 HeapFree(GetProcessHeap(), 0, item);
2070 hr = S_OK;
2071 }
2072 }
2073 RegCloseKey(instancekey);
2074 }
2075 RegCloseKey(catidkey);
2076 }
2077 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
2078 hr = HRESULT_FROM_WIN32(res);
2079 }
2080 RegCloseKey(clsidkey);
2081
2082 if (SUCCEEDED(hr))
2083 {
2084 IEnumUnknown_Reset(&This->IEnumUnknown_iface);
2085 *ppIEnumUnknown = &This->IEnumUnknown_iface;
2086 }
2087 else
2088 {
2089 *ppIEnumUnknown = NULL;
2090 IEnumUnknown_Release(&This->IEnumUnknown_iface);
2091 }
2092
2093 return hr;
2094 }
2095
2096 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
2097 {
2098 HRESULT res;
2099 IEnumUnknown *enumconverters;
2100 IUnknown *unkconverterinfo;
2101 IWICFormatConverterInfo *converterinfo=NULL;
2102 IWICFormatConverter *converter=NULL;
2103 GUID srcFormat;
2104 WCHAR srcformatstr[39], dstformatstr[39];
2105 BOOL canconvert;
2106 ULONG num_fetched;
2107
2108 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
2109 if (FAILED(res)) return res;
2110
2111 if (IsEqualGUID(&srcFormat, dstFormat))
2112 {
2113 IWICBitmapSource_AddRef(pISrc);
2114 *ppIDst = pISrc;
2115 return S_OK;
2116 }
2117
2118 StringFromGUID2(&srcFormat, srcformatstr, 39);
2119 StringFromGUID2(dstFormat, dstformatstr, 39);
2120
2121 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
2122 if (FAILED(res)) return res;
2123
2124 while (!converter)
2125 {
2126 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);
2127
2128 if (res == S_OK)
2129 {
2130 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);
2131
2132 if (SUCCEEDED(res))
2133 {
2134 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);
2135
2136 if (canconvert)
2137 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);
2138
2139 if (canconvert)
2140 {
2141 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);
2142
2143 if (SUCCEEDED(res))
2144 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);
2145
2146 if (SUCCEEDED(res) && canconvert)
2147 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
2148 NULL, 0.0, WICBitmapPaletteTypeCustom);
2149
2150 if (FAILED(res) || !canconvert)
2151 {
2152 if (converter)
2153 {
2154 IWICFormatConverter_Release(converter);
2155 converter = NULL;
2156 }
2157 res = S_OK;
2158 }
2159 }
2160
2161 IWICFormatConverterInfo_Release(converterinfo);
2162 }
2163
2164 IUnknown_Release(unkconverterinfo);
2165 }
2166 else
2167 break;
2168 }
2169
2170 IEnumUnknown_Release(enumconverters);
2171
2172 if (converter)
2173 {
2174 res = IWICFormatConverter_QueryInterface(converter, &IID_IWICBitmapSource, (void **)ppIDst);
2175 IWICFormatConverter_Release(converter);
2176 return res;
2177 }
2178 else
2179 {
2180 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
2181 *ppIDst = NULL;
2182 return WINCODEC_ERR_COMPONENTNOTFOUND;
2183 }
2184 }