secur32/tests: Use importlib for functions available since Windows XP.
[wine.git] / dlls / windowscodecs / info.c
blob84b80bc82c2e95f9ff9cf4536917473ef7fe5950
1 /*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 * Copyright 2012 Dmitry Timoshkov
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.
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.
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
20 #include "config.h"
22 #include <stdarg.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "objbase.h"
31 #include "wincodecs_private.h"
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
35 #include "wine/list.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
39 static const WCHAR mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0};
40 static const WCHAR author_valuename[] = {'A','u','t','h','o','r',0};
41 static const WCHAR friendlyname_valuename[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
42 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
43 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
44 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
45 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
46 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
47 static const WCHAR version_valuename[] = {'V','e','r','s','i','o','n',0};
48 static const WCHAR specversion_valuename[] = {'S','p','e','c','V','e','r','s','i','o','n',0};
49 static const WCHAR bitsperpixel_valuename[] = {'B','i','t','L','e','n','g','t','h',0};
50 static const WCHAR channelcount_valuename[] = {'C','h','a','n','n','e','l','C','o','u','n','t',0};
51 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
52 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};
53 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};
54 static const WCHAR requiresfullstream_valuename[] = {'R','e','q','u','i','r','e','s','F','u','l','l','S','t','r','e','a','m',0};
55 static const WCHAR supportspadding_valuename[] = {'S','u','p','p','o','r','t','s','P','a','d','d','i','n','g',0};
56 static const WCHAR fileextensions_valuename[] = {'F','i','l','e','E','x','t','e','n','s','i','o','n','s',0};
57 static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0};
59 static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value,
60 UINT buffer_size, WCHAR *buffer, UINT *actual_size)
62 LONG ret;
63 DWORD cbdata=buffer_size * sizeof(WCHAR);
65 if (!actual_size)
66 return E_INVALIDARG;
68 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
69 buffer, &cbdata);
71 if (ret == ERROR_FILE_NOT_FOUND)
73 *actual_size = 0;
74 return S_OK;
77 if (ret == 0 || ret == ERROR_MORE_DATA)
78 *actual_size = cbdata/sizeof(WCHAR);
80 if (!buffer && buffer_size != 0)
81 /* Yes, native returns the correct size in this case. */
82 return E_INVALIDARG;
84 if (ret == ERROR_MORE_DATA)
85 return WINCODEC_ERR_INSUFFICIENTBUFFER;
87 return HRESULT_FROM_WIN32(ret);
90 static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value,
91 GUID *result)
93 LONG ret;
94 WCHAR guid_string[39];
95 DWORD cbdata = sizeof(guid_string);
96 HRESULT hr;
98 if (!result)
99 return E_INVALIDARG;
101 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
102 guid_string, &cbdata);
104 if (ret != ERROR_SUCCESS)
105 return HRESULT_FROM_WIN32(ret);
107 if (cbdata < sizeof(guid_string))
109 ERR("incomplete GUID value\n");
110 return E_FAIL;
113 hr = CLSIDFromString(guid_string, result);
115 return hr;
118 static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value,
119 DWORD *result)
121 LONG ret;
122 DWORD cbdata = sizeof(DWORD);
124 if (!result)
125 return E_INVALIDARG;
127 ret = RegGetValueW(classkey, NULL, value, RRF_RT_DWORD, NULL,
128 result, &cbdata);
130 if (ret == ERROR_FILE_NOT_FOUND)
132 *result = 0;
133 return S_OK;
136 return HRESULT_FROM_WIN32(ret);
139 static HRESULT ComponentInfo_GetGuidList(HKEY classkey, LPCWSTR subkeyname,
140 UINT buffersize, GUID *buffer, UINT *actual_size)
142 LONG ret;
143 HKEY subkey;
144 UINT items_returned;
145 WCHAR guid_string[39];
146 DWORD guid_string_size;
147 HRESULT hr=S_OK;
149 if (!actual_size)
150 return E_INVALIDARG;
152 ret = RegOpenKeyExW(classkey, subkeyname, 0, KEY_READ, &subkey);
153 if (ret == ERROR_FILE_NOT_FOUND)
155 *actual_size = 0;
156 return S_OK;
158 else if (ret != ERROR_SUCCESS) return HRESULT_FROM_WIN32(ret);
160 if (buffer)
162 items_returned = 0;
163 guid_string_size = 39;
164 while (items_returned < buffersize)
166 ret = RegEnumKeyExW(subkey, items_returned, guid_string,
167 &guid_string_size, NULL, NULL, NULL, NULL);
169 if (ret != ERROR_SUCCESS)
171 hr = HRESULT_FROM_WIN32(ret);
172 break;
175 if (guid_string_size != 38)
177 hr = E_FAIL;
178 break;
181 hr = CLSIDFromString(guid_string, &buffer[items_returned]);
182 if (FAILED(hr))
183 break;
185 items_returned++;
186 guid_string_size = 39;
189 if (ret == ERROR_NO_MORE_ITEMS)
190 hr = S_OK;
192 *actual_size = items_returned;
194 else
196 ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, actual_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
197 if (ret != ERROR_SUCCESS)
198 hr = HRESULT_FROM_WIN32(ret);
201 RegCloseKey(subkey);
203 return hr;
206 typedef struct {
207 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface;
208 LONG ref;
209 HKEY classkey;
210 CLSID clsid;
211 } BitmapDecoderInfo;
213 static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo *iface)
215 return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface);
218 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid,
219 void **ppv)
221 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
222 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
224 if (!ppv) return E_INVALIDARG;
226 if (IsEqualIID(&IID_IUnknown, iid) ||
227 IsEqualIID(&IID_IWICComponentInfo, iid) ||
228 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
229 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
231 *ppv = &This->IWICBitmapDecoderInfo_iface;
233 else
235 *ppv = NULL;
236 return E_NOINTERFACE;
239 IUnknown_AddRef((IUnknown*)*ppv);
240 return S_OK;
243 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
245 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
246 ULONG ref = InterlockedIncrement(&This->ref);
248 TRACE("(%p) refcount=%u\n", iface, ref);
250 return ref;
253 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
255 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
256 ULONG ref = InterlockedDecrement(&This->ref);
258 TRACE("(%p) refcount=%u\n", iface, ref);
260 if (ref == 0)
262 RegCloseKey(This->classkey);
263 HeapFree(GetProcessHeap(), 0, This);
266 return ref;
269 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface,
270 WICComponentType *pType)
272 TRACE("(%p,%p)\n", iface, pType);
273 if (!pType) return E_INVALIDARG;
274 *pType = WICDecoder;
275 return S_OK;
278 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid)
280 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
281 TRACE("(%p,%p)\n", iface, pclsid);
283 if (!pclsid)
284 return E_INVALIDARG;
286 memcpy(pclsid, &This->clsid, sizeof(CLSID));
288 return S_OK;
291 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus)
293 FIXME("(%p,%p): stub\n", iface, pStatus);
294 return E_NOTIMPL;
297 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor,
298 WCHAR *wzAuthor, UINT *pcchActual)
300 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
302 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
304 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
305 cchAuthor, wzAuthor, pcchActual);
308 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
310 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
312 TRACE("(%p,%p)\n", iface, pguidVendor);
314 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
317 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
318 WCHAR *wzVersion, UINT *pcchActual)
320 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
322 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
324 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
325 cchVersion, wzVersion, pcchActual);
328 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
329 WCHAR *wzSpecVersion, UINT *pcchActual)
331 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
333 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
335 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
336 cchSpecVersion, wzSpecVersion, pcchActual);
339 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
340 WCHAR *wzFriendlyName, UINT *pcchActual)
342 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
344 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
346 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
347 cchFriendlyName, wzFriendlyName, pcchActual);
350 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
351 GUID *pguidContainerFormat)
353 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
354 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
355 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
358 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
359 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
361 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
362 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
363 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
366 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface,
367 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
369 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
370 return E_NOTIMPL;
373 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface,
374 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
376 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
377 return E_NOTIMPL;
380 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface,
381 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
383 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
384 return E_NOTIMPL;
387 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface,
388 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
390 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
392 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
394 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
395 cchMimeTypes, wzMimeTypes, pcchActual);
398 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface,
399 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
401 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
403 TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
405 return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename,
406 cchFileExtensions, wzFileExtensions, pcchActual);
409 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface,
410 BOOL *pfSupportAnimation)
412 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
413 return E_NOTIMPL;
416 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface,
417 BOOL *pfSupportChromaKey)
419 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
420 return E_NOTIMPL;
423 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface,
424 BOOL *pfSupportLossless)
426 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
427 return E_NOTIMPL;
430 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface,
431 BOOL *pfSupportMultiframe)
433 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
434 return E_NOTIMPL;
437 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface,
438 LPCWSTR wzMimeType, BOOL *pfMatches)
440 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
441 return E_NOTIMPL;
444 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface,
445 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual)
447 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
448 UINT pattern_count=0, patterns_size=0;
449 WCHAR subkeyname[11];
450 LONG res;
451 HKEY patternskey, patternkey;
452 static const WCHAR uintformatW[] = {'%','u',0};
453 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0};
454 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
455 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0};
456 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
457 static const WCHAR maskW[] = {'M','a','s','k',0};
458 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
459 HRESULT hr=S_OK;
460 UINT i;
461 BYTE *bPatterns=(BYTE*)pPatterns;
462 DWORD length, valuesize;
464 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual);
466 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
467 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
469 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
470 if (res == ERROR_SUCCESS)
472 patterns_size = pattern_count * sizeof(WICBitmapPattern);
474 for (i=0; i<pattern_count; i++)
476 snprintfW(subkeyname, 11, uintformatW, i);
477 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
478 if (res == ERROR_SUCCESS)
480 valuesize = sizeof(ULONG);
481 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
482 &length, &valuesize);
483 patterns_size += length*2;
485 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS))
487 pPatterns[i].Length = length;
489 pPatterns[i].EndOfStream = 0;
490 valuesize = sizeof(BOOL);
491 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
492 &pPatterns[i].EndOfStream, &valuesize);
494 pPatterns[i].Position.QuadPart = 0;
495 valuesize = sizeof(ULARGE_INTEGER);
496 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
497 &pPatterns[i].Position, &valuesize);
499 if (res == ERROR_SUCCESS)
501 pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
502 valuesize = length;
503 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
504 pPatterns[i].Pattern, &valuesize);
507 if (res == ERROR_SUCCESS)
509 pPatterns[i].Mask = bPatterns+patterns_size-length;
510 valuesize = length;
511 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
512 pPatterns[i].Mask, &valuesize);
516 RegCloseKey(patternkey);
518 if (res != ERROR_SUCCESS)
520 hr = HRESULT_FROM_WIN32(res);
521 break;
525 else hr = HRESULT_FROM_WIN32(res);
527 RegCloseKey(patternskey);
529 if (hr == S_OK)
531 *pcPatterns = pattern_count;
532 *pcbPatternsActual = patterns_size;
533 if (pPatterns && cbSizePatterns < patterns_size)
534 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
537 return hr;
540 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
541 IStream *pIStream, BOOL *pfMatches)
543 WICBitmapPattern *patterns;
544 UINT pattern_count=0, patterns_size=0;
545 HRESULT hr;
546 UINT i;
547 ULONG pos;
548 BYTE *data=NULL;
549 ULONG datasize=0;
550 ULONG bytesread;
551 LARGE_INTEGER seekpos;
553 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
555 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
556 if (FAILED(hr)) return hr;
558 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
559 if (!patterns) return E_OUTOFMEMORY;
561 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
562 if (FAILED(hr)) goto end;
564 for (i=0; i<pattern_count; i++)
566 if (datasize < patterns[i].Length)
568 HeapFree(GetProcessHeap(), 0, data);
569 datasize = patterns[i].Length;
570 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
571 if (!data)
573 hr = E_OUTOFMEMORY;
574 break;
578 if (patterns[i].EndOfStream)
579 seekpos.QuadPart = -patterns[i].Position.QuadPart;
580 else
581 seekpos.QuadPart = patterns[i].Position.QuadPart;
582 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
583 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
584 if (FAILED(hr)) break;
586 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
587 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
588 continue;
589 if (FAILED(hr)) break;
591 for (pos=0; pos<patterns[i].Length; pos++)
593 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
594 break;
596 if (pos == patterns[i].Length) /* matches pattern */
598 hr = S_OK;
599 *pfMatches = TRUE;
600 break;
604 if (i == pattern_count) /* does not match any pattern */
606 hr = S_OK;
607 *pfMatches = FALSE;
610 end:
611 HeapFree(GetProcessHeap(), 0, patterns);
612 HeapFree(GetProcessHeap(), 0, data);
614 return hr;
617 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
618 IWICBitmapDecoder **ppIBitmapDecoder)
620 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
622 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
624 return create_instance(&This->clsid, &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
627 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
628 BitmapDecoderInfo_QueryInterface,
629 BitmapDecoderInfo_AddRef,
630 BitmapDecoderInfo_Release,
631 BitmapDecoderInfo_GetComponentType,
632 BitmapDecoderInfo_GetCLSID,
633 BitmapDecoderInfo_GetSigningStatus,
634 BitmapDecoderInfo_GetAuthor,
635 BitmapDecoderInfo_GetVendorGUID,
636 BitmapDecoderInfo_GetVersion,
637 BitmapDecoderInfo_GetSpecVersion,
638 BitmapDecoderInfo_GetFriendlyName,
639 BitmapDecoderInfo_GetContainerFormat,
640 BitmapDecoderInfo_GetPixelFormats,
641 BitmapDecoderInfo_GetColorManagementVersion,
642 BitmapDecoderInfo_GetDeviceManufacturer,
643 BitmapDecoderInfo_GetDeviceModels,
644 BitmapDecoderInfo_GetMimeTypes,
645 BitmapDecoderInfo_GetFileExtensions,
646 BitmapDecoderInfo_DoesSupportAnimation,
647 BitmapDecoderInfo_DoesSupportChromaKey,
648 BitmapDecoderInfo_DoesSupportLossless,
649 BitmapDecoderInfo_DoesSupportMultiframe,
650 BitmapDecoderInfo_MatchesMimeType,
651 BitmapDecoderInfo_GetPatterns,
652 BitmapDecoderInfo_MatchesPattern,
653 BitmapDecoderInfo_CreateInstance
656 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
658 BitmapDecoderInfo *This;
660 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
661 if (!This)
663 RegCloseKey(classkey);
664 return E_OUTOFMEMORY;
667 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
668 This->ref = 1;
669 This->classkey = classkey;
670 memcpy(&This->clsid, clsid, sizeof(CLSID));
672 *ppIInfo = (IWICComponentInfo *)&This->IWICBitmapDecoderInfo_iface;
673 return S_OK;
676 typedef struct {
677 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
678 LONG ref;
679 HKEY classkey;
680 CLSID clsid;
681 } BitmapEncoderInfo;
683 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
685 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
688 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
689 void **ppv)
691 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
692 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
694 if (!ppv) return E_INVALIDARG;
696 if (IsEqualIID(&IID_IUnknown, iid) ||
697 IsEqualIID(&IID_IWICComponentInfo, iid) ||
698 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
699 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
701 *ppv = &This->IWICBitmapEncoderInfo_iface;
703 else
705 *ppv = NULL;
706 return E_NOINTERFACE;
709 IUnknown_AddRef((IUnknown*)*ppv);
710 return S_OK;
713 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
715 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
716 ULONG ref = InterlockedIncrement(&This->ref);
718 TRACE("(%p) refcount=%u\n", iface, ref);
720 return ref;
723 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
725 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
726 ULONG ref = InterlockedDecrement(&This->ref);
728 TRACE("(%p) refcount=%u\n", iface, ref);
730 if (ref == 0)
732 RegCloseKey(This->classkey);
733 HeapFree(GetProcessHeap(), 0, This);
736 return ref;
739 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
740 WICComponentType *pType)
742 TRACE("(%p,%p)\n", iface, pType);
743 if (!pType) return E_INVALIDARG;
744 *pType = WICEncoder;
745 return S_OK;
748 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
750 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
751 TRACE("(%p,%p)\n", iface, pclsid);
753 if (!pclsid)
754 return E_INVALIDARG;
756 memcpy(pclsid, &This->clsid, sizeof(CLSID));
758 return S_OK;
761 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
763 FIXME("(%p,%p): stub\n", iface, pStatus);
764 return E_NOTIMPL;
767 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
768 WCHAR *wzAuthor, UINT *pcchActual)
770 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
772 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
774 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
775 cchAuthor, wzAuthor, pcchActual);
778 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
780 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
782 TRACE("(%p,%p)\n", iface, pguidVendor);
784 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
787 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
788 WCHAR *wzVersion, UINT *pcchActual)
790 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
792 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
794 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
795 cchVersion, wzVersion, pcchActual);
798 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
799 WCHAR *wzSpecVersion, UINT *pcchActual)
801 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
803 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
805 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
806 cchSpecVersion, wzSpecVersion, pcchActual);
809 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
810 WCHAR *wzFriendlyName, UINT *pcchActual)
812 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
814 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
816 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
817 cchFriendlyName, wzFriendlyName, pcchActual);
820 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
821 GUID *pguidContainerFormat)
823 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
824 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
825 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
828 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
829 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
831 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
832 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
833 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
836 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
837 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
839 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
840 return E_NOTIMPL;
843 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
844 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
846 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
847 return E_NOTIMPL;
850 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
851 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
853 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
854 return E_NOTIMPL;
857 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
858 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
860 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
862 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
864 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
865 cchMimeTypes, wzMimeTypes, pcchActual);
868 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
869 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
871 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
872 return E_NOTIMPL;
875 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
876 BOOL *pfSupportAnimation)
878 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
879 return E_NOTIMPL;
882 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
883 BOOL *pfSupportChromaKey)
885 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
886 return E_NOTIMPL;
889 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
890 BOOL *pfSupportLossless)
892 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
893 return E_NOTIMPL;
896 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
897 BOOL *pfSupportMultiframe)
899 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
900 return E_NOTIMPL;
903 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
904 LPCWSTR wzMimeType, BOOL *pfMatches)
906 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
907 return E_NOTIMPL;
910 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
911 IWICBitmapEncoder **ppIBitmapEncoder)
913 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
915 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
917 return create_instance(&This->clsid, &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
920 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
921 BitmapEncoderInfo_QueryInterface,
922 BitmapEncoderInfo_AddRef,
923 BitmapEncoderInfo_Release,
924 BitmapEncoderInfo_GetComponentType,
925 BitmapEncoderInfo_GetCLSID,
926 BitmapEncoderInfo_GetSigningStatus,
927 BitmapEncoderInfo_GetAuthor,
928 BitmapEncoderInfo_GetVendorGUID,
929 BitmapEncoderInfo_GetVersion,
930 BitmapEncoderInfo_GetSpecVersion,
931 BitmapEncoderInfo_GetFriendlyName,
932 BitmapEncoderInfo_GetContainerFormat,
933 BitmapEncoderInfo_GetPixelFormats,
934 BitmapEncoderInfo_GetColorManagementVersion,
935 BitmapEncoderInfo_GetDeviceManufacturer,
936 BitmapEncoderInfo_GetDeviceModels,
937 BitmapEncoderInfo_GetMimeTypes,
938 BitmapEncoderInfo_GetFileExtensions,
939 BitmapEncoderInfo_DoesSupportAnimation,
940 BitmapEncoderInfo_DoesSupportChromaKey,
941 BitmapEncoderInfo_DoesSupportLossless,
942 BitmapEncoderInfo_DoesSupportMultiframe,
943 BitmapEncoderInfo_MatchesMimeType,
944 BitmapEncoderInfo_CreateInstance
947 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
949 BitmapEncoderInfo *This;
951 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
952 if (!This)
954 RegCloseKey(classkey);
955 return E_OUTOFMEMORY;
958 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
959 This->ref = 1;
960 This->classkey = classkey;
961 memcpy(&This->clsid, clsid, sizeof(CLSID));
963 *ppIInfo = (IWICComponentInfo *)&This->IWICBitmapEncoderInfo_iface;
964 return S_OK;
967 typedef struct {
968 IWICFormatConverterInfo IWICFormatConverterInfo_iface;
969 LONG ref;
970 HKEY classkey;
971 CLSID clsid;
972 } FormatConverterInfo;
974 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
976 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
979 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
980 void **ppv)
982 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
983 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
985 if (!ppv) return E_INVALIDARG;
987 if (IsEqualIID(&IID_IUnknown, iid) ||
988 IsEqualIID(&IID_IWICComponentInfo, iid) ||
989 IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
991 *ppv = &This->IWICFormatConverterInfo_iface;
993 else
995 *ppv = NULL;
996 return E_NOINTERFACE;
999 IUnknown_AddRef((IUnknown*)*ppv);
1000 return S_OK;
1003 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
1005 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1006 ULONG ref = InterlockedIncrement(&This->ref);
1008 TRACE("(%p) refcount=%u\n", iface, ref);
1010 return ref;
1013 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
1015 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1016 ULONG ref = InterlockedDecrement(&This->ref);
1018 TRACE("(%p) refcount=%u\n", iface, ref);
1020 if (ref == 0)
1022 RegCloseKey(This->classkey);
1023 HeapFree(GetProcessHeap(), 0, This);
1026 return ref;
1029 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
1030 WICComponentType *pType)
1032 TRACE("(%p,%p)\n", iface, pType);
1033 if (!pType) return E_INVALIDARG;
1034 *pType = WICPixelFormatConverter;
1035 return S_OK;
1038 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
1040 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1041 TRACE("(%p,%p)\n", iface, pclsid);
1043 if (!pclsid)
1044 return E_INVALIDARG;
1046 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1048 return S_OK;
1051 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
1053 FIXME("(%p,%p): stub\n", iface, pStatus);
1054 return E_NOTIMPL;
1057 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
1058 WCHAR *wzAuthor, UINT *pcchActual)
1060 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1062 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1064 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1065 cchAuthor, wzAuthor, pcchActual);
1068 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
1070 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1072 TRACE("(%p,%p)\n", iface, pguidVendor);
1074 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1077 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
1078 WCHAR *wzVersion, UINT *pcchActual)
1080 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1082 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1084 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1085 cchVersion, wzVersion, pcchActual);
1088 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
1089 WCHAR *wzSpecVersion, UINT *pcchActual)
1091 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1093 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1095 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1096 cchSpecVersion, wzSpecVersion, pcchActual);
1099 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
1100 WCHAR *wzFriendlyName, UINT *pcchActual)
1102 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1104 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1106 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1107 cchFriendlyName, wzFriendlyName, pcchActual);
1110 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
1111 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
1113 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
1114 return E_NOTIMPL;
1117 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
1118 IWICFormatConverter **ppIFormatConverter)
1120 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1122 TRACE("(%p,%p)\n", iface, ppIFormatConverter);
1124 return create_instance(&This->clsid, &IID_IWICFormatConverter,
1125 (void**)ppIFormatConverter);
1128 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
1130 LONG res;
1131 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1132 HKEY formats_key, guid_key;
1134 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
1135 would be O(n). A registry test should do better. */
1137 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
1138 if (res != ERROR_SUCCESS) return FALSE;
1140 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
1141 if (res == ERROR_SUCCESS) RegCloseKey(guid_key);
1143 RegCloseKey(formats_key);
1145 return (res == ERROR_SUCCESS);
1148 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
1149 FormatConverterInfo_QueryInterface,
1150 FormatConverterInfo_AddRef,
1151 FormatConverterInfo_Release,
1152 FormatConverterInfo_GetComponentType,
1153 FormatConverterInfo_GetCLSID,
1154 FormatConverterInfo_GetSigningStatus,
1155 FormatConverterInfo_GetAuthor,
1156 FormatConverterInfo_GetVendorGUID,
1157 FormatConverterInfo_GetVersion,
1158 FormatConverterInfo_GetSpecVersion,
1159 FormatConverterInfo_GetFriendlyName,
1160 FormatConverterInfo_GetPixelFormats,
1161 FormatConverterInfo_CreateInstance
1164 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1166 FormatConverterInfo *This;
1168 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
1169 if (!This)
1171 RegCloseKey(classkey);
1172 return E_OUTOFMEMORY;
1175 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
1176 This->ref = 1;
1177 This->classkey = classkey;
1178 memcpy(&This->clsid, clsid, sizeof(CLSID));
1180 *ppIInfo = (IWICComponentInfo *)&This->IWICFormatConverterInfo_iface;
1181 return S_OK;
1184 typedef struct {
1185 IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface;
1186 LONG ref;
1187 HKEY classkey;
1188 CLSID clsid;
1189 } PixelFormatInfo;
1191 static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2 *iface)
1193 return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface);
1196 static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID iid,
1197 void **ppv)
1199 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1200 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1202 if (!ppv) return E_INVALIDARG;
1204 if (IsEqualIID(&IID_IUnknown, iid) ||
1205 IsEqualIID(&IID_IWICComponentInfo, iid) ||
1206 IsEqualIID(&IID_IWICPixelFormatInfo, iid) ||
1207 IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid))
1209 *ppv = &This->IWICPixelFormatInfo2_iface;
1211 else
1213 *ppv = NULL;
1214 return E_NOINTERFACE;
1217 IUnknown_AddRef((IUnknown*)*ppv);
1218 return S_OK;
1221 static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface)
1223 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1224 ULONG ref = InterlockedIncrement(&This->ref);
1226 TRACE("(%p) refcount=%u\n", iface, ref);
1228 return ref;
1231 static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface)
1233 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1234 ULONG ref = InterlockedDecrement(&This->ref);
1236 TRACE("(%p) refcount=%u\n", iface, ref);
1238 if (ref == 0)
1240 RegCloseKey(This->classkey);
1241 HeapFree(GetProcessHeap(), 0, This);
1244 return ref;
1247 static HRESULT WINAPI PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2 *iface,
1248 WICComponentType *pType)
1250 TRACE("(%p,%p)\n", iface, pType);
1251 if (!pType) return E_INVALIDARG;
1252 *pType = WICPixelFormat;
1253 return S_OK;
1256 static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2 *iface, CLSID *pclsid)
1258 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1259 TRACE("(%p,%p)\n", iface, pclsid);
1261 if (!pclsid)
1262 return E_INVALIDARG;
1264 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1266 return S_OK;
1269 static HRESULT WINAPI PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2 *iface, DWORD *pStatus)
1271 TRACE("(%p,%p)\n", iface, pStatus);
1273 if (!pStatus)
1274 return E_INVALIDARG;
1276 /* Pixel formats don't require code, so they are considered signed. */
1277 *pStatus = WICComponentSigned;
1279 return S_OK;
1282 static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UINT cchAuthor,
1283 WCHAR *wzAuthor, UINT *pcchActual)
1285 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1287 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1289 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1290 cchAuthor, wzAuthor, pcchActual);
1293 static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor)
1295 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1297 TRACE("(%p,%p)\n", iface, pguidVendor);
1299 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1302 static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion,
1303 WCHAR *wzVersion, UINT *pcchActual)
1305 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1307 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1309 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1310 cchVersion, wzVersion, pcchActual);
1313 static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface, UINT cchSpecVersion,
1314 WCHAR *wzSpecVersion, UINT *pcchActual)
1316 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1318 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1320 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1321 cchSpecVersion, wzSpecVersion, pcchActual);
1324 static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *iface, UINT cchFriendlyName,
1325 WCHAR *wzFriendlyName, UINT *pcchActual)
1327 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1329 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1331 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1332 cchFriendlyName, wzFriendlyName, pcchActual);
1335 static HRESULT WINAPI PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface,
1336 GUID *pFormat)
1338 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1339 TRACE("(%p,%p)\n", iface, pFormat);
1341 if (!pFormat)
1342 return E_INVALIDARG;
1344 *pFormat = This->clsid;
1346 return S_OK;
1349 static HRESULT WINAPI PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2 *iface,
1350 IWICColorContext **ppIColorContext)
1352 FIXME("(%p,%p): stub\n", iface, ppIColorContext);
1353 return E_NOTIMPL;
1356 static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *iface,
1357 UINT *puiBitsPerPixel)
1359 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1361 TRACE("(%p,%p)\n", iface, puiBitsPerPixel);
1363 return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel);
1366 static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface,
1367 UINT *puiChannelCount)
1369 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1371 TRACE("(%p,%p)\n", iface, puiChannelCount);
1373 return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount);
1376 static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface,
1377 UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual)
1379 static const WCHAR uintformatW[] = {'%','u',0};
1380 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1381 UINT channel_count;
1382 HRESULT hr;
1383 LONG ret;
1384 WCHAR valuename[11];
1385 DWORD cbData;
1387 TRACE("(%p,%u,%u,%p,%p)\n", iface, uiChannelIndex, cbMaskBuffer, pbMaskBuffer, pcbActual);
1389 if (!pcbActual)
1390 return E_INVALIDARG;
1392 hr = PixelFormatInfo_GetChannelCount(iface, &channel_count);
1394 if (SUCCEEDED(hr) && uiChannelIndex >= channel_count)
1395 hr = E_INVALIDARG;
1397 if (SUCCEEDED(hr))
1399 snprintfW(valuename, 11, uintformatW, uiChannelIndex);
1401 cbData = cbMaskBuffer;
1403 ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData);
1405 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
1406 *pcbActual = cbData;
1408 if (ret == ERROR_MORE_DATA)
1409 hr = E_INVALIDARG;
1410 else
1411 hr = HRESULT_FROM_WIN32(ret);
1414 return hr;
1417 static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 *iface,
1418 BOOL *pfSupportsTransparency)
1420 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1422 TRACE("(%p,%p)\n", iface, pfSupportsTransparency);
1424 return ComponentInfo_GetDWORDValue(This->classkey, supportstransparency_valuename, (DWORD*)pfSupportsTransparency);
1427 static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface,
1428 WICPixelFormatNumericRepresentation *pNumericRepresentation)
1430 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1432 TRACE("(%p,%p)\n", iface, pNumericRepresentation);
1434 return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation);
1437 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = {
1438 PixelFormatInfo_QueryInterface,
1439 PixelFormatInfo_AddRef,
1440 PixelFormatInfo_Release,
1441 PixelFormatInfo_GetComponentType,
1442 PixelFormatInfo_GetCLSID,
1443 PixelFormatInfo_GetSigningStatus,
1444 PixelFormatInfo_GetAuthor,
1445 PixelFormatInfo_GetVendorGUID,
1446 PixelFormatInfo_GetVersion,
1447 PixelFormatInfo_GetSpecVersion,
1448 PixelFormatInfo_GetFriendlyName,
1449 PixelFormatInfo_GetFormatGUID,
1450 PixelFormatInfo_GetColorContext,
1451 PixelFormatInfo_GetBitsPerPixel,
1452 PixelFormatInfo_GetChannelCount,
1453 PixelFormatInfo_GetChannelMask,
1454 PixelFormatInfo_SupportsTransparency,
1455 PixelFormatInfo_GetNumericRepresentation
1458 static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1460 PixelFormatInfo *This;
1462 This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo));
1463 if (!This)
1465 RegCloseKey(classkey);
1466 return E_OUTOFMEMORY;
1469 This->IWICPixelFormatInfo2_iface.lpVtbl = &PixelFormatInfo_Vtbl;
1470 This->ref = 1;
1471 This->classkey = classkey;
1472 memcpy(&This->clsid, clsid, sizeof(CLSID));
1474 *ppIInfo = (IWICComponentInfo *)&This->IWICPixelFormatInfo2_iface;
1475 return S_OK;
1478 typedef struct
1480 IWICMetadataReaderInfo IWICMetadataReaderInfo_iface;
1481 LONG ref;
1482 HKEY classkey;
1483 CLSID clsid;
1484 } MetadataReaderInfo;
1486 static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo *iface)
1488 return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface);
1491 static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface,
1492 REFIID riid, void **ppv)
1494 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1496 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
1498 if (!ppv) return E_INVALIDARG;
1500 if (IsEqualIID(&IID_IUnknown, riid) ||
1501 IsEqualIID(&IID_IWICComponentInfo, riid) ||
1502 IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) ||
1503 IsEqualIID(&IID_IWICMetadataReaderInfo, riid))
1505 *ppv = &This->IWICMetadataReaderInfo_iface;
1507 else
1509 *ppv = NULL;
1510 return E_NOINTERFACE;
1513 IUnknown_AddRef((IUnknown *)*ppv);
1514 return S_OK;
1517 static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
1519 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1520 ULONG ref = InterlockedIncrement(&This->ref);
1522 TRACE("(%p) refcount=%u\n", iface, ref);
1523 return ref;
1526 static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface)
1528 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1529 ULONG ref = InterlockedDecrement(&This->ref);
1531 TRACE("(%p) refcount=%u\n", iface, ref);
1533 if (!ref)
1535 RegCloseKey(This->classkey);
1536 HeapFree(GetProcessHeap(), 0, This);
1538 return ref;
1541 static HRESULT WINAPI MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo *iface,
1542 WICComponentType *type)
1544 TRACE("(%p,%p)\n", iface, type);
1546 if (!type) return E_INVALIDARG;
1547 *type = WICMetadataReader;
1548 return S_OK;
1551 static HRESULT WINAPI MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface,
1552 CLSID *clsid)
1554 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1556 TRACE("(%p,%p)\n", iface, clsid);
1558 if (!clsid) return E_INVALIDARG;
1559 *clsid = This->clsid;
1560 return S_OK;
1563 static HRESULT WINAPI MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo *iface,
1564 DWORD *status)
1566 FIXME("(%p,%p): stub\n", iface, status);
1567 return E_NOTIMPL;
1570 static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface,
1571 UINT length, WCHAR *author, UINT *actual_length)
1573 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1575 TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length);
1577 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1578 length, author, actual_length);
1581 static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface,
1582 GUID *vendor)
1584 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1586 TRACE("(%p,%p)\n", iface, vendor);
1588 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, vendor);
1591 static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface,
1592 UINT length, WCHAR *version, UINT *actual_length)
1594 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1596 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1598 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1599 length, version, actual_length);
1602 static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface,
1603 UINT length, WCHAR *version, UINT *actual_length)
1605 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1607 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1609 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1610 length, version, actual_length);
1613 static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo *iface,
1614 UINT length, WCHAR *name, UINT *actual_length)
1616 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1618 TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length);
1620 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1621 length, name, actual_length);
1624 static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo *iface,
1625 GUID *format)
1627 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1628 TRACE("(%p,%p)\n", iface, format);
1629 return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format);
1632 static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface,
1633 UINT length, GUID *formats, UINT *actual_length)
1635 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1636 TRACE("(%p,%u,%p,%p)\n", iface, length, formats, actual_length);
1638 return ComponentInfo_GetGuidList(This->classkey, containers_keyname, length,
1639 formats, actual_length);
1642 static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo *iface,
1643 UINT length, WCHAR *manufacturer, UINT *actual_length)
1645 FIXME("(%p,%u,%p,%p): stub\n", iface, length, manufacturer, actual_length);
1646 return E_NOTIMPL;
1649 static HRESULT WINAPI MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo *iface,
1650 UINT length, WCHAR *models, UINT *actual_length)
1652 FIXME("(%p,%u,%p,%p): stub\n", iface, length, models, actual_length);
1653 return E_NOTIMPL;
1656 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo *iface,
1657 BOOL *param)
1659 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1660 TRACE("(%p,%p)\n", iface, param);
1661 return ComponentInfo_GetDWORDValue(This->classkey, requiresfullstream_valuename, (DWORD *)param);
1664 static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface,
1665 BOOL *param)
1667 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1668 TRACE("(%p,%p)\n", iface, param);
1669 return ComponentInfo_GetDWORDValue(This->classkey, supportspadding_valuename, (DWORD *)param);
1672 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface,
1673 BOOL *param)
1675 FIXME("(%p,%p): stub\n", iface, param);
1676 return E_NOTIMPL;
1679 static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface,
1680 REFGUID container, UINT length, WICMetadataPattern *patterns, UINT *count, UINT *actual_length)
1682 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1683 HRESULT hr=S_OK;
1684 LONG res;
1685 UINT pattern_count=0, patterns_size=0;
1686 DWORD valuesize, patternsize;
1687 BYTE *bPatterns=(BYTE*)patterns;
1688 HKEY containers_key, guid_key, pattern_key;
1689 WCHAR subkeyname[11];
1690 WCHAR guidkeyname[39];
1691 int i;
1692 static const WCHAR uintformatW[] = {'%','u',0};
1693 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
1694 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
1695 static const WCHAR maskW[] = {'M','a','s','k',0};
1696 static const WCHAR dataoffsetW[] = {'D','a','t','a','O','f','f','s','e','t',0};
1698 TRACE("(%p,%s,%u,%p,%p,%p)\n", iface, debugstr_guid(container), length, patterns, count, actual_length);
1700 if (!actual_length || !container) return E_INVALIDARG;
1702 res = RegOpenKeyExW(This->classkey, containers_keyname, 0, KEY_READ, &containers_key);
1703 if (res == ERROR_SUCCESS)
1705 StringFromGUID2(container, guidkeyname, 39);
1707 res = RegOpenKeyExW(containers_key, guidkeyname, 0, KEY_READ, &guid_key);
1708 if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND;
1709 else if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res);
1711 RegCloseKey(containers_key);
1713 else if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND;
1714 else hr = HRESULT_FROM_WIN32(res);
1716 if (SUCCEEDED(hr))
1718 res = RegQueryInfoKeyW(guid_key, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1719 if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res);
1721 if (SUCCEEDED(hr))
1723 patterns_size = pattern_count * sizeof(WICMetadataPattern);
1725 for (i=0; i<pattern_count; i++)
1727 snprintfW(subkeyname, 11, uintformatW, i);
1728 res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &pattern_key);
1729 if (res == ERROR_SUCCESS)
1731 res = RegGetValueW(pattern_key, NULL, patternW, RRF_RT_REG_BINARY, NULL,
1732 NULL, &patternsize);
1733 patterns_size += patternsize*2;
1735 if ((length >= patterns_size) && (res == ERROR_SUCCESS))
1737 patterns[i].Length = patternsize;
1739 patterns[i].DataOffset.QuadPart = 0;
1740 valuesize = sizeof(ULARGE_INTEGER);
1741 RegGetValueW(pattern_key, NULL, dataoffsetW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
1742 &patterns[i].DataOffset, &valuesize);
1744 patterns[i].Position.QuadPart = 0;
1745 valuesize = sizeof(ULARGE_INTEGER);
1746 res = RegGetValueW(pattern_key, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
1747 &patterns[i].Position, &valuesize);
1749 if (res == ERROR_SUCCESS)
1751 patterns[i].Pattern = bPatterns+patterns_size-patternsize*2;
1752 valuesize = patternsize;
1753 res = RegGetValueW(pattern_key, NULL, patternW, RRF_RT_REG_BINARY, NULL,
1754 patterns[i].Pattern, &valuesize);
1757 if (res == ERROR_SUCCESS)
1759 patterns[i].Mask = bPatterns+patterns_size-patternsize;
1760 valuesize = patternsize;
1761 res = RegGetValueW(pattern_key, NULL, maskW, RRF_RT_REG_BINARY, NULL,
1762 patterns[i].Mask, &valuesize);
1766 RegCloseKey(pattern_key);
1768 if (res != ERROR_SUCCESS)
1770 hr = HRESULT_FROM_WIN32(res);
1771 break;
1776 RegCloseKey(guid_key);
1779 if (hr == S_OK)
1781 *count = pattern_count;
1782 *actual_length = patterns_size;
1783 if (patterns && length < patterns_size)
1784 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
1787 return hr;
1790 static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface,
1791 REFGUID container, IStream *stream, BOOL *matches)
1793 HRESULT hr;
1794 WICMetadataPattern *patterns;
1795 UINT pattern_count=0, patterns_size=0;
1796 ULONG datasize=0;
1797 BYTE *data=NULL;
1798 ULONG bytesread;
1799 UINT i;
1800 LARGE_INTEGER seekpos;
1801 ULONG pos;
1803 TRACE("(%p,%s,%p,%p)\n", iface, debugstr_guid(container), stream, matches);
1805 hr = MetadataReaderInfo_GetPatterns(iface, container, 0, NULL, &pattern_count, &patterns_size);
1806 if (FAILED(hr)) return hr;
1808 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
1809 if (!patterns) return E_OUTOFMEMORY;
1811 hr = MetadataReaderInfo_GetPatterns(iface, container, patterns_size, patterns, &pattern_count, &patterns_size);
1812 if (FAILED(hr)) goto end;
1814 for (i=0; i<pattern_count; i++)
1816 if (datasize < patterns[i].Length)
1818 HeapFree(GetProcessHeap(), 0, data);
1819 datasize = patterns[i].Length;
1820 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
1821 if (!data)
1823 hr = E_OUTOFMEMORY;
1824 break;
1828 seekpos.QuadPart = patterns[i].Position.QuadPart;
1829 hr = IStream_Seek(stream, seekpos, STREAM_SEEK_SET, NULL);
1830 if (FAILED(hr)) break;
1832 hr = IStream_Read(stream, data, patterns[i].Length, &bytesread);
1833 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
1834 continue;
1835 if (FAILED(hr)) break;
1837 for (pos=0; pos<patterns[i].Length; pos++)
1839 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
1840 break;
1842 if (pos == patterns[i].Length) /* matches pattern */
1844 hr = S_OK;
1845 *matches = TRUE;
1846 break;
1850 if (i == pattern_count) /* does not match any pattern */
1852 hr = S_OK;
1853 *matches = FALSE;
1856 end:
1857 HeapFree(GetProcessHeap(), 0, patterns);
1858 HeapFree(GetProcessHeap(), 0, data);
1860 return hr;
1863 static HRESULT WINAPI MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *iface,
1864 IWICMetadataReader **reader)
1866 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1868 TRACE("(%p,%p)\n", iface, reader);
1870 return create_instance(&This->clsid, &IID_IWICMetadataReader, (void **)reader);
1873 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = {
1874 MetadataReaderInfo_QueryInterface,
1875 MetadataReaderInfo_AddRef,
1876 MetadataReaderInfo_Release,
1877 MetadataReaderInfo_GetComponentType,
1878 MetadataReaderInfo_GetCLSID,
1879 MetadataReaderInfo_GetSigningStatus,
1880 MetadataReaderInfo_GetAuthor,
1881 MetadataReaderInfo_GetVendorGUID,
1882 MetadataReaderInfo_GetVersion,
1883 MetadataReaderInfo_GetSpecVersion,
1884 MetadataReaderInfo_GetFriendlyName,
1885 MetadataReaderInfo_GetMetadataFormat,
1886 MetadataReaderInfo_GetContainerFormats,
1887 MetadataReaderInfo_GetDeviceManufacturer,
1888 MetadataReaderInfo_GetDeviceModels,
1889 MetadataReaderInfo_DoesRequireFullStream,
1890 MetadataReaderInfo_DoesSupportPadding,
1891 MetadataReaderInfo_DoesRequireFixedSize,
1892 MetadataReaderInfo_GetPatterns,
1893 MetadataReaderInfo_MatchesPattern,
1894 MetadataReaderInfo_CreateInstance
1897 static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **info)
1899 MetadataReaderInfo *This;
1901 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1902 if (!This)
1904 RegCloseKey(classkey);
1905 return E_OUTOFMEMORY;
1908 This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl;
1909 This->ref = 1;
1910 This->classkey = classkey;
1911 This->clsid = *clsid;
1913 *info = (IWICComponentInfo *)&This->IWICMetadataReaderInfo_iface;
1914 return S_OK;
1917 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
1918 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
1920 struct category {
1921 WICComponentType type;
1922 const GUID *catid;
1923 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
1926 static const struct category categories[] = {
1927 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
1928 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
1929 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
1930 {WICPixelFormat, &CATID_WICPixelFormats, PixelFormatInfo_Constructor},
1931 {WICMetadataReader, &CATID_WICMetadataReader, MetadataReaderInfo_Constructor},
1935 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
1937 HKEY clsidkey;
1938 HKEY classkey;
1939 HKEY catidkey;
1940 HKEY instancekey;
1941 WCHAR guidstring[39];
1942 LONG res;
1943 const struct category *category;
1944 BOOL found = FALSE;
1945 HRESULT hr;
1947 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1948 if (res != ERROR_SUCCESS)
1949 return HRESULT_FROM_WIN32(res);
1951 for (category=categories; category->type; category++)
1953 StringFromGUID2(category->catid, guidstring, 39);
1954 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1955 if (res == ERROR_SUCCESS)
1957 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1958 if (res == ERROR_SUCCESS)
1960 StringFromGUID2(clsid, guidstring, 39);
1961 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
1962 if (res == ERROR_SUCCESS)
1964 RegCloseKey(classkey);
1965 found = TRUE;
1967 RegCloseKey(instancekey);
1969 RegCloseKey(catidkey);
1971 if (found) break;
1974 if (found)
1976 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
1977 if (res == ERROR_SUCCESS)
1978 hr = category->constructor(classkey, clsid, ppIInfo);
1979 else
1980 hr = HRESULT_FROM_WIN32(res);
1982 else
1984 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid));
1985 hr = E_FAIL;
1988 RegCloseKey(clsidkey);
1990 return hr;
1993 typedef struct {
1994 IEnumUnknown IEnumUnknown_iface;
1995 LONG ref;
1996 struct list objects;
1997 struct list *cursor;
1998 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
1999 } ComponentEnum;
2001 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
2003 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
2006 typedef struct {
2007 struct list entry;
2008 IUnknown *unk;
2009 } ComponentEnumItem;
2011 static const IEnumUnknownVtbl ComponentEnumVtbl;
2013 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
2014 void **ppv)
2016 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2017 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
2019 if (!ppv) return E_INVALIDARG;
2021 if (IsEqualIID(&IID_IUnknown, iid) ||
2022 IsEqualIID(&IID_IEnumUnknown, iid))
2024 *ppv = &This->IEnumUnknown_iface;
2026 else
2028 *ppv = NULL;
2029 return E_NOINTERFACE;
2032 IUnknown_AddRef((IUnknown*)*ppv);
2033 return S_OK;
2036 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
2038 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2039 ULONG ref = InterlockedIncrement(&This->ref);
2041 TRACE("(%p) refcount=%u\n", iface, ref);
2043 return ref;
2046 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
2048 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2049 ULONG ref = InterlockedDecrement(&This->ref);
2050 ComponentEnumItem *cursor, *cursor2;
2052 TRACE("(%p) refcount=%u\n", iface, ref);
2054 if (ref == 0)
2056 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
2058 IUnknown_Release(cursor->unk);
2059 list_remove(&cursor->entry);
2060 HeapFree(GetProcessHeap(), 0, cursor);
2062 This->lock.DebugInfo->Spare[0] = 0;
2063 DeleteCriticalSection(&This->lock);
2064 HeapFree(GetProcessHeap(), 0, This);
2067 return ref;
2070 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
2071 IUnknown **rgelt, ULONG *pceltFetched)
2073 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2074 ULONG num_fetched=0;
2075 ComponentEnumItem *item;
2076 HRESULT hr=S_OK;
2078 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
2080 EnterCriticalSection(&This->lock);
2081 while (num_fetched<celt)
2083 if (!This->cursor)
2085 hr = S_FALSE;
2086 break;
2088 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
2089 IUnknown_AddRef(item->unk);
2090 rgelt[num_fetched] = item->unk;
2091 num_fetched++;
2092 This->cursor = list_next(&This->objects, This->cursor);
2094 LeaveCriticalSection(&This->lock);
2095 if (pceltFetched)
2096 *pceltFetched = num_fetched;
2097 return hr;
2100 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
2102 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2103 ULONG i;
2104 HRESULT hr=S_OK;
2106 TRACE("(%p,%u)\n", iface, celt);
2108 EnterCriticalSection(&This->lock);
2109 for (i=0; i<celt; i++)
2111 if (!This->cursor)
2113 hr = S_FALSE;
2114 break;
2116 This->cursor = list_next(&This->objects, This->cursor);
2118 LeaveCriticalSection(&This->lock);
2119 return hr;
2122 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
2124 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2126 TRACE("(%p)\n", iface);
2128 EnterCriticalSection(&This->lock);
2129 This->cursor = list_head(&This->objects);
2130 LeaveCriticalSection(&This->lock);
2131 return S_OK;
2134 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
2136 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2137 ComponentEnum *new_enum;
2138 ComponentEnumItem *old_item, *new_item;
2139 HRESULT ret=S_OK;
2140 struct list *old_cursor;
2142 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
2143 if (!new_enum)
2145 *ppenum = NULL;
2146 return E_OUTOFMEMORY;
2149 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
2150 new_enum->ref = 1;
2151 new_enum->cursor = NULL;
2152 list_init(&new_enum->objects);
2153 InitializeCriticalSection(&new_enum->lock);
2154 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
2156 EnterCriticalSection(&This->lock);
2157 old_cursor = This->cursor;
2158 LeaveCriticalSection(&This->lock);
2160 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
2162 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
2163 if (!new_item)
2165 ret = E_OUTOFMEMORY;
2166 break;
2168 new_item->unk = old_item->unk;
2169 list_add_tail(&new_enum->objects, &new_item->entry);
2170 IUnknown_AddRef(new_item->unk);
2171 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
2174 if (FAILED(ret))
2176 IEnumUnknown_Release(&new_enum->IEnumUnknown_iface);
2177 *ppenum = NULL;
2179 else
2180 *ppenum = &new_enum->IEnumUnknown_iface;
2182 return ret;
2185 static const IEnumUnknownVtbl ComponentEnumVtbl = {
2186 ComponentEnum_QueryInterface,
2187 ComponentEnum_AddRef,
2188 ComponentEnum_Release,
2189 ComponentEnum_Next,
2190 ComponentEnum_Skip,
2191 ComponentEnum_Reset,
2192 ComponentEnum_Clone
2195 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
2197 ComponentEnum *This;
2198 ComponentEnumItem *item;
2199 const struct category *category;
2200 HKEY clsidkey, catidkey, instancekey;
2201 WCHAR guidstring[39];
2202 LONG res;
2203 int i;
2204 HRESULT hr=S_OK;
2205 CLSID clsid;
2207 if (options) FIXME("ignoring flags %x\n", options);
2209 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
2210 if (res != ERROR_SUCCESS)
2211 return HRESULT_FROM_WIN32(res);
2213 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
2214 if (!This)
2216 RegCloseKey(clsidkey);
2217 return E_OUTOFMEMORY;
2220 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
2221 This->ref = 1;
2222 list_init(&This->objects);
2223 InitializeCriticalSection(&This->lock);
2224 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
2226 for (category=categories; category->type && hr == S_OK; category++)
2228 if ((category->type & componentTypes) == 0) continue;
2229 StringFromGUID2(category->catid, guidstring, 39);
2230 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
2231 if (res == ERROR_SUCCESS)
2233 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
2234 if (res == ERROR_SUCCESS)
2236 i=0;
2237 for (;;i++)
2239 DWORD guidstring_size = 39;
2240 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
2241 if (res != ERROR_SUCCESS) break;
2243 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
2244 if (!item) { hr = E_OUTOFMEMORY; break; }
2246 hr = CLSIDFromString(guidstring, &clsid);
2247 if (SUCCEEDED(hr))
2249 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
2250 if (SUCCEEDED(hr))
2251 list_add_tail(&This->objects, &item->entry);
2254 if (FAILED(hr))
2256 HeapFree(GetProcessHeap(), 0, item);
2257 hr = S_OK;
2260 RegCloseKey(instancekey);
2262 RegCloseKey(catidkey);
2264 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
2265 hr = HRESULT_FROM_WIN32(res);
2267 RegCloseKey(clsidkey);
2269 if (SUCCEEDED(hr))
2271 IEnumUnknown_Reset(&This->IEnumUnknown_iface);
2272 *ppIEnumUnknown = &This->IEnumUnknown_iface;
2274 else
2276 *ppIEnumUnknown = NULL;
2277 IEnumUnknown_Release(&This->IEnumUnknown_iface);
2280 return hr;
2283 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
2285 HRESULT res;
2286 IEnumUnknown *enumconverters;
2287 IUnknown *unkconverterinfo;
2288 IWICFormatConverterInfo *converterinfo=NULL;
2289 IWICFormatConverter *converter=NULL;
2290 GUID srcFormat;
2291 WCHAR srcformatstr[39], dstformatstr[39];
2292 BOOL canconvert;
2293 ULONG num_fetched;
2295 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
2296 if (FAILED(res)) return res;
2298 if (IsEqualGUID(&srcFormat, dstFormat))
2300 IWICBitmapSource_AddRef(pISrc);
2301 *ppIDst = pISrc;
2302 return S_OK;
2305 StringFromGUID2(&srcFormat, srcformatstr, 39);
2306 StringFromGUID2(dstFormat, dstformatstr, 39);
2308 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
2309 if (FAILED(res)) return res;
2311 while (!converter)
2313 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);
2315 if (res == S_OK)
2317 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);
2319 if (SUCCEEDED(res))
2321 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);
2323 if (canconvert)
2324 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);
2326 if (canconvert)
2328 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);
2330 if (SUCCEEDED(res))
2331 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);
2333 if (SUCCEEDED(res) && canconvert)
2334 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
2335 NULL, 0.0, WICBitmapPaletteTypeCustom);
2337 if (FAILED(res) || !canconvert)
2339 if (converter)
2341 IWICFormatConverter_Release(converter);
2342 converter = NULL;
2344 res = S_OK;
2348 IWICFormatConverterInfo_Release(converterinfo);
2351 IUnknown_Release(unkconverterinfo);
2353 else
2354 break;
2357 IEnumUnknown_Release(enumconverters);
2359 if (converter)
2361 res = IWICFormatConverter_QueryInterface(converter, &IID_IWICBitmapSource, (void **)ppIDst);
2362 IWICFormatConverter_Release(converter);
2363 return res;
2365 else
2367 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
2368 *ppIDst = NULL;
2369 return WINCODEC_ERR_COMPONENTNOTFOUND;