TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / dlls / windowscodecs / info.c
blobcf3c38a2e978e213cdec36317af1b78cd9f946b1
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"
30 #include "wincodec.h"
31 #include "wincodecsdk.h"
33 #include "wincodecs_private.h"
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
37 #include "wine/list.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
41 static const WCHAR mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0};
42 static const WCHAR author_valuename[] = {'A','u','t','h','o','r',0};
43 static const WCHAR friendlyname_valuename[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
44 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
45 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
46 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
47 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
48 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
49 static const WCHAR version_valuename[] = {'V','e','r','s','i','o','n',0};
50 static const WCHAR specversion_valuename[] = {'S','p','e','c','V','e','r','s','i','o','n',0};
51 static const WCHAR bitsperpixel_valuename[] = {'B','i','t','L','e','n','g','t','h',0};
52 static const WCHAR channelcount_valuename[] = {'C','h','a','n','n','e','l','C','o','u','n','t',0};
53 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
54 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};
55 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};
56 static const WCHAR requiresfullstream_valuename[] = {'R','e','q','u','i','r','e','s','F','u','l','l','S','t','r','e','a','m',0};
57 static const WCHAR supportspadding_valuename[] = {'S','u','p','p','o','r','t','s','P','a','d','d','i','n','g',0};
58 static const WCHAR fileextensions_valuename[] = {'F','i','l','e','E','x','t','e','n','s','i','o','n','s',0};
59 static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0};
61 static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value,
62 UINT buffer_size, WCHAR *buffer, UINT *actual_size)
64 LONG ret;
65 DWORD cbdata=buffer_size * sizeof(WCHAR);
67 if (!actual_size)
68 return E_INVALIDARG;
70 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
71 buffer, &cbdata);
73 if (ret == ERROR_FILE_NOT_FOUND)
75 *actual_size = 0;
76 return S_OK;
79 if (ret == 0 || ret == ERROR_MORE_DATA)
80 *actual_size = cbdata/sizeof(WCHAR);
82 if (!buffer && buffer_size != 0)
83 /* Yes, native returns the correct size in this case. */
84 return E_INVALIDARG;
86 if (ret == ERROR_MORE_DATA)
87 return WINCODEC_ERR_INSUFFICIENTBUFFER;
89 return HRESULT_FROM_WIN32(ret);
92 static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value,
93 GUID *result)
95 LONG ret;
96 WCHAR guid_string[39];
97 DWORD cbdata = sizeof(guid_string);
98 HRESULT hr;
100 if (!result)
101 return E_INVALIDARG;
103 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
104 guid_string, &cbdata);
106 if (ret != ERROR_SUCCESS)
107 return HRESULT_FROM_WIN32(ret);
109 if (cbdata < sizeof(guid_string))
111 ERR("incomplete GUID value\n");
112 return E_FAIL;
115 hr = CLSIDFromString(guid_string, result);
117 return hr;
120 static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value,
121 DWORD *result)
123 LONG ret;
124 DWORD cbdata = sizeof(DWORD);
126 if (!result)
127 return E_INVALIDARG;
129 ret = RegGetValueW(classkey, NULL, value, RRF_RT_DWORD, NULL,
130 result, &cbdata);
132 if (ret == ERROR_FILE_NOT_FOUND)
134 *result = 0;
135 return S_OK;
138 return HRESULT_FROM_WIN32(ret);
141 static HRESULT ComponentInfo_GetGuidList(HKEY classkey, LPCWSTR subkeyname,
142 UINT buffersize, GUID *buffer, UINT *actual_size)
144 LONG ret;
145 HKEY subkey;
146 UINT items_returned;
147 WCHAR guid_string[39];
148 DWORD guid_string_size;
149 HRESULT hr=S_OK;
151 if (!actual_size)
152 return E_INVALIDARG;
154 ret = RegOpenKeyExW(classkey, subkeyname, 0, KEY_READ, &subkey);
155 if (ret == ERROR_FILE_NOT_FOUND)
157 *actual_size = 0;
158 return S_OK;
160 else if (ret != ERROR_SUCCESS) return HRESULT_FROM_WIN32(ret);
162 if (buffer)
164 items_returned = 0;
165 guid_string_size = 39;
166 while (items_returned < buffersize)
168 ret = RegEnumKeyExW(subkey, items_returned, guid_string,
169 &guid_string_size, NULL, NULL, NULL, NULL);
171 if (ret != ERROR_SUCCESS)
173 hr = HRESULT_FROM_WIN32(ret);
174 break;
177 if (guid_string_size != 38)
179 hr = E_FAIL;
180 break;
183 hr = CLSIDFromString(guid_string, &buffer[items_returned]);
184 if (FAILED(hr))
185 break;
187 items_returned++;
188 guid_string_size = 39;
191 if (ret == ERROR_NO_MORE_ITEMS)
192 hr = S_OK;
194 *actual_size = items_returned;
196 else
198 ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, actual_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
199 if (ret != ERROR_SUCCESS)
200 hr = HRESULT_FROM_WIN32(ret);
203 RegCloseKey(subkey);
205 return hr;
208 typedef struct {
209 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface;
210 LONG ref;
211 HKEY classkey;
212 CLSID clsid;
213 } BitmapDecoderInfo;
215 static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo *iface)
217 return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface);
220 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid,
221 void **ppv)
223 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
224 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
226 if (!ppv) return E_INVALIDARG;
228 if (IsEqualIID(&IID_IUnknown, iid) ||
229 IsEqualIID(&IID_IWICComponentInfo, iid) ||
230 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
231 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
233 *ppv = &This->IWICBitmapDecoderInfo_iface;
235 else
237 *ppv = NULL;
238 return E_NOINTERFACE;
241 IUnknown_AddRef((IUnknown*)*ppv);
242 return S_OK;
245 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
247 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
248 ULONG ref = InterlockedIncrement(&This->ref);
250 TRACE("(%p) refcount=%u\n", iface, ref);
252 return ref;
255 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
257 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
258 ULONG ref = InterlockedDecrement(&This->ref);
260 TRACE("(%p) refcount=%u\n", iface, ref);
262 if (ref == 0)
264 RegCloseKey(This->classkey);
265 HeapFree(GetProcessHeap(), 0, This);
268 return ref;
271 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface,
272 WICComponentType *pType)
274 TRACE("(%p,%p)\n", iface, pType);
275 if (!pType) return E_INVALIDARG;
276 *pType = WICDecoder;
277 return S_OK;
280 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid)
282 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
283 TRACE("(%p,%p)\n", iface, pclsid);
285 if (!pclsid)
286 return E_INVALIDARG;
288 memcpy(pclsid, &This->clsid, sizeof(CLSID));
290 return S_OK;
293 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus)
295 FIXME("(%p,%p): stub\n", iface, pStatus);
296 return E_NOTIMPL;
299 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor,
300 WCHAR *wzAuthor, UINT *pcchActual)
302 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
304 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
306 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
307 cchAuthor, wzAuthor, pcchActual);
310 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
312 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
314 TRACE("(%p,%p)\n", iface, pguidVendor);
316 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
319 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
320 WCHAR *wzVersion, UINT *pcchActual)
322 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
324 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
326 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
327 cchVersion, wzVersion, pcchActual);
330 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
331 WCHAR *wzSpecVersion, UINT *pcchActual)
333 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
335 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
337 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
338 cchSpecVersion, wzSpecVersion, pcchActual);
341 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
342 WCHAR *wzFriendlyName, UINT *pcchActual)
344 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
346 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
348 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
349 cchFriendlyName, wzFriendlyName, pcchActual);
352 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
353 GUID *pguidContainerFormat)
355 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
356 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
357 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
360 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
361 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
363 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
364 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
365 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
368 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface,
369 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
371 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
372 return E_NOTIMPL;
375 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface,
376 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
378 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
379 return E_NOTIMPL;
382 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface,
383 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
385 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
386 return E_NOTIMPL;
389 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface,
390 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
392 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
394 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
396 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
397 cchMimeTypes, wzMimeTypes, pcchActual);
400 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface,
401 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
403 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
405 TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
407 return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename,
408 cchFileExtensions, wzFileExtensions, pcchActual);
411 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface,
412 BOOL *pfSupportAnimation)
414 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
415 return E_NOTIMPL;
418 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface,
419 BOOL *pfSupportChromaKey)
421 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
422 return E_NOTIMPL;
425 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface,
426 BOOL *pfSupportLossless)
428 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
429 return E_NOTIMPL;
432 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface,
433 BOOL *pfSupportMultiframe)
435 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
436 return E_NOTIMPL;
439 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface,
440 LPCWSTR wzMimeType, BOOL *pfMatches)
442 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
443 return E_NOTIMPL;
446 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface,
447 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual)
449 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
450 UINT pattern_count=0, patterns_size=0;
451 WCHAR subkeyname[11];
452 LONG res;
453 HKEY patternskey, patternkey;
454 static const WCHAR uintformatW[] = {'%','u',0};
455 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0};
456 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
457 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0};
458 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
459 static const WCHAR maskW[] = {'M','a','s','k',0};
460 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
461 HRESULT hr=S_OK;
462 UINT i;
463 BYTE *bPatterns=(BYTE*)pPatterns;
464 DWORD length, valuesize;
466 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual);
468 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
469 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
471 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
472 if (res == ERROR_SUCCESS)
474 patterns_size = pattern_count * sizeof(WICBitmapPattern);
476 for (i=0; i<pattern_count; i++)
478 snprintfW(subkeyname, 11, uintformatW, i);
479 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
480 if (res == ERROR_SUCCESS)
482 valuesize = sizeof(ULONG);
483 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
484 &length, &valuesize);
485 patterns_size += length*2;
487 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS))
489 pPatterns[i].Length = length;
491 pPatterns[i].EndOfStream = 0;
492 valuesize = sizeof(BOOL);
493 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
494 &pPatterns[i].EndOfStream, &valuesize);
496 pPatterns[i].Position.QuadPart = 0;
497 valuesize = sizeof(ULARGE_INTEGER);
498 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
499 &pPatterns[i].Position, &valuesize);
501 if (res == ERROR_SUCCESS)
503 pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
504 valuesize = length;
505 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
506 pPatterns[i].Pattern, &valuesize);
509 if (res == ERROR_SUCCESS)
511 pPatterns[i].Mask = bPatterns+patterns_size-length;
512 valuesize = length;
513 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
514 pPatterns[i].Mask, &valuesize);
518 RegCloseKey(patternkey);
520 if (res != ERROR_SUCCESS)
522 hr = HRESULT_FROM_WIN32(res);
523 break;
527 else hr = HRESULT_FROM_WIN32(res);
529 RegCloseKey(patternskey);
531 if (hr == S_OK)
533 *pcPatterns = pattern_count;
534 *pcbPatternsActual = patterns_size;
535 if (pPatterns && cbSizePatterns < patterns_size)
536 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
539 return hr;
542 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
543 IStream *pIStream, BOOL *pfMatches)
545 WICBitmapPattern *patterns;
546 UINT pattern_count=0, patterns_size=0;
547 HRESULT hr;
548 UINT i;
549 ULONG pos;
550 BYTE *data=NULL;
551 ULONG datasize=0;
552 ULONG bytesread;
553 LARGE_INTEGER seekpos;
555 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
557 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
558 if (FAILED(hr)) return hr;
560 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
561 if (!patterns) return E_OUTOFMEMORY;
563 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
564 if (FAILED(hr)) goto end;
566 for (i=0; i<pattern_count; i++)
568 if (datasize < patterns[i].Length)
570 HeapFree(GetProcessHeap(), 0, data);
571 datasize = patterns[i].Length;
572 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
573 if (!data)
575 hr = E_OUTOFMEMORY;
576 break;
580 if (patterns[i].EndOfStream)
581 seekpos.QuadPart = -patterns[i].Position.QuadPart;
582 else
583 seekpos.QuadPart = patterns[i].Position.QuadPart;
584 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
585 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
586 if (FAILED(hr)) break;
588 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
589 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
590 continue;
591 if (FAILED(hr)) break;
593 for (pos=0; pos<patterns[i].Length; pos++)
595 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
596 break;
598 if (pos == patterns[i].Length) /* matches pattern */
600 hr = S_OK;
601 *pfMatches = TRUE;
602 break;
606 if (i == pattern_count) /* does not match any pattern */
608 hr = S_OK;
609 *pfMatches = FALSE;
612 end:
613 HeapFree(GetProcessHeap(), 0, patterns);
614 HeapFree(GetProcessHeap(), 0, data);
616 return hr;
619 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
620 IWICBitmapDecoder **ppIBitmapDecoder)
622 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
624 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
626 return create_instance(&This->clsid, &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
629 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
630 BitmapDecoderInfo_QueryInterface,
631 BitmapDecoderInfo_AddRef,
632 BitmapDecoderInfo_Release,
633 BitmapDecoderInfo_GetComponentType,
634 BitmapDecoderInfo_GetCLSID,
635 BitmapDecoderInfo_GetSigningStatus,
636 BitmapDecoderInfo_GetAuthor,
637 BitmapDecoderInfo_GetVendorGUID,
638 BitmapDecoderInfo_GetVersion,
639 BitmapDecoderInfo_GetSpecVersion,
640 BitmapDecoderInfo_GetFriendlyName,
641 BitmapDecoderInfo_GetContainerFormat,
642 BitmapDecoderInfo_GetPixelFormats,
643 BitmapDecoderInfo_GetColorManagementVersion,
644 BitmapDecoderInfo_GetDeviceManufacturer,
645 BitmapDecoderInfo_GetDeviceModels,
646 BitmapDecoderInfo_GetMimeTypes,
647 BitmapDecoderInfo_GetFileExtensions,
648 BitmapDecoderInfo_DoesSupportAnimation,
649 BitmapDecoderInfo_DoesSupportChromaKey,
650 BitmapDecoderInfo_DoesSupportLossless,
651 BitmapDecoderInfo_DoesSupportMultiframe,
652 BitmapDecoderInfo_MatchesMimeType,
653 BitmapDecoderInfo_GetPatterns,
654 BitmapDecoderInfo_MatchesPattern,
655 BitmapDecoderInfo_CreateInstance
658 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
660 BitmapDecoderInfo *This;
662 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
663 if (!This)
665 RegCloseKey(classkey);
666 return E_OUTOFMEMORY;
669 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
670 This->ref = 1;
671 This->classkey = classkey;
672 memcpy(&This->clsid, clsid, sizeof(CLSID));
674 *ppIInfo = (IWICComponentInfo *)&This->IWICBitmapDecoderInfo_iface;
675 return S_OK;
678 typedef struct {
679 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
680 LONG ref;
681 HKEY classkey;
682 CLSID clsid;
683 } BitmapEncoderInfo;
685 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
687 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
690 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
691 void **ppv)
693 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
694 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
696 if (!ppv) return E_INVALIDARG;
698 if (IsEqualIID(&IID_IUnknown, iid) ||
699 IsEqualIID(&IID_IWICComponentInfo, iid) ||
700 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
701 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
703 *ppv = &This->IWICBitmapEncoderInfo_iface;
705 else
707 *ppv = NULL;
708 return E_NOINTERFACE;
711 IUnknown_AddRef((IUnknown*)*ppv);
712 return S_OK;
715 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
717 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
718 ULONG ref = InterlockedIncrement(&This->ref);
720 TRACE("(%p) refcount=%u\n", iface, ref);
722 return ref;
725 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
727 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
728 ULONG ref = InterlockedDecrement(&This->ref);
730 TRACE("(%p) refcount=%u\n", iface, ref);
732 if (ref == 0)
734 RegCloseKey(This->classkey);
735 HeapFree(GetProcessHeap(), 0, This);
738 return ref;
741 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
742 WICComponentType *pType)
744 TRACE("(%p,%p)\n", iface, pType);
745 if (!pType) return E_INVALIDARG;
746 *pType = WICEncoder;
747 return S_OK;
750 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
752 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
753 TRACE("(%p,%p)\n", iface, pclsid);
755 if (!pclsid)
756 return E_INVALIDARG;
758 memcpy(pclsid, &This->clsid, sizeof(CLSID));
760 return S_OK;
763 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
765 FIXME("(%p,%p): stub\n", iface, pStatus);
766 return E_NOTIMPL;
769 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
770 WCHAR *wzAuthor, UINT *pcchActual)
772 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
774 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
776 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
777 cchAuthor, wzAuthor, pcchActual);
780 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
782 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
784 TRACE("(%p,%p)\n", iface, pguidVendor);
786 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
789 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
790 WCHAR *wzVersion, UINT *pcchActual)
792 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
794 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
796 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
797 cchVersion, wzVersion, pcchActual);
800 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
801 WCHAR *wzSpecVersion, UINT *pcchActual)
803 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
805 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
807 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
808 cchSpecVersion, wzSpecVersion, pcchActual);
811 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
812 WCHAR *wzFriendlyName, UINT *pcchActual)
814 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
816 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
818 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
819 cchFriendlyName, wzFriendlyName, pcchActual);
822 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
823 GUID *pguidContainerFormat)
825 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
826 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
827 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
830 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
831 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
833 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
834 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
835 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
838 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
839 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
841 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
842 return E_NOTIMPL;
845 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
846 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
848 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
849 return E_NOTIMPL;
852 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
853 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
855 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
856 return E_NOTIMPL;
859 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
860 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
862 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
864 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
866 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
867 cchMimeTypes, wzMimeTypes, pcchActual);
870 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
871 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
873 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
874 return E_NOTIMPL;
877 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
878 BOOL *pfSupportAnimation)
880 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
881 return E_NOTIMPL;
884 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
885 BOOL *pfSupportChromaKey)
887 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
888 return E_NOTIMPL;
891 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
892 BOOL *pfSupportLossless)
894 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
895 return E_NOTIMPL;
898 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
899 BOOL *pfSupportMultiframe)
901 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
902 return E_NOTIMPL;
905 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
906 LPCWSTR wzMimeType, BOOL *pfMatches)
908 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
909 return E_NOTIMPL;
912 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
913 IWICBitmapEncoder **ppIBitmapEncoder)
915 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
917 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
919 return create_instance(&This->clsid, &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
922 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
923 BitmapEncoderInfo_QueryInterface,
924 BitmapEncoderInfo_AddRef,
925 BitmapEncoderInfo_Release,
926 BitmapEncoderInfo_GetComponentType,
927 BitmapEncoderInfo_GetCLSID,
928 BitmapEncoderInfo_GetSigningStatus,
929 BitmapEncoderInfo_GetAuthor,
930 BitmapEncoderInfo_GetVendorGUID,
931 BitmapEncoderInfo_GetVersion,
932 BitmapEncoderInfo_GetSpecVersion,
933 BitmapEncoderInfo_GetFriendlyName,
934 BitmapEncoderInfo_GetContainerFormat,
935 BitmapEncoderInfo_GetPixelFormats,
936 BitmapEncoderInfo_GetColorManagementVersion,
937 BitmapEncoderInfo_GetDeviceManufacturer,
938 BitmapEncoderInfo_GetDeviceModels,
939 BitmapEncoderInfo_GetMimeTypes,
940 BitmapEncoderInfo_GetFileExtensions,
941 BitmapEncoderInfo_DoesSupportAnimation,
942 BitmapEncoderInfo_DoesSupportChromaKey,
943 BitmapEncoderInfo_DoesSupportLossless,
944 BitmapEncoderInfo_DoesSupportMultiframe,
945 BitmapEncoderInfo_MatchesMimeType,
946 BitmapEncoderInfo_CreateInstance
949 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
951 BitmapEncoderInfo *This;
953 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
954 if (!This)
956 RegCloseKey(classkey);
957 return E_OUTOFMEMORY;
960 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
961 This->ref = 1;
962 This->classkey = classkey;
963 memcpy(&This->clsid, clsid, sizeof(CLSID));
965 *ppIInfo = (IWICComponentInfo *)&This->IWICBitmapEncoderInfo_iface;
966 return S_OK;
969 typedef struct {
970 IWICFormatConverterInfo IWICFormatConverterInfo_iface;
971 LONG ref;
972 HKEY classkey;
973 CLSID clsid;
974 } FormatConverterInfo;
976 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
978 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
981 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
982 void **ppv)
984 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
985 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
987 if (!ppv) return E_INVALIDARG;
989 if (IsEqualIID(&IID_IUnknown, iid) ||
990 IsEqualIID(&IID_IWICComponentInfo, iid) ||
991 IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
993 *ppv = &This->IWICFormatConverterInfo_iface;
995 else
997 *ppv = NULL;
998 return E_NOINTERFACE;
1001 IUnknown_AddRef((IUnknown*)*ppv);
1002 return S_OK;
1005 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
1007 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1008 ULONG ref = InterlockedIncrement(&This->ref);
1010 TRACE("(%p) refcount=%u\n", iface, ref);
1012 return ref;
1015 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
1017 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1018 ULONG ref = InterlockedDecrement(&This->ref);
1020 TRACE("(%p) refcount=%u\n", iface, ref);
1022 if (ref == 0)
1024 RegCloseKey(This->classkey);
1025 HeapFree(GetProcessHeap(), 0, This);
1028 return ref;
1031 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
1032 WICComponentType *pType)
1034 TRACE("(%p,%p)\n", iface, pType);
1035 if (!pType) return E_INVALIDARG;
1036 *pType = WICPixelFormatConverter;
1037 return S_OK;
1040 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
1042 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1043 TRACE("(%p,%p)\n", iface, pclsid);
1045 if (!pclsid)
1046 return E_INVALIDARG;
1048 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1050 return S_OK;
1053 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
1055 FIXME("(%p,%p): stub\n", iface, pStatus);
1056 return E_NOTIMPL;
1059 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
1060 WCHAR *wzAuthor, UINT *pcchActual)
1062 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1064 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1066 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1067 cchAuthor, wzAuthor, pcchActual);
1070 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
1072 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1074 TRACE("(%p,%p)\n", iface, pguidVendor);
1076 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1079 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
1080 WCHAR *wzVersion, UINT *pcchActual)
1082 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1084 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1086 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1087 cchVersion, wzVersion, pcchActual);
1090 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
1091 WCHAR *wzSpecVersion, UINT *pcchActual)
1093 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1095 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1097 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1098 cchSpecVersion, wzSpecVersion, pcchActual);
1101 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
1102 WCHAR *wzFriendlyName, UINT *pcchActual)
1104 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1106 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1108 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1109 cchFriendlyName, wzFriendlyName, pcchActual);
1112 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
1113 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
1115 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
1116 return E_NOTIMPL;
1119 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
1120 IWICFormatConverter **ppIFormatConverter)
1122 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1124 TRACE("(%p,%p)\n", iface, ppIFormatConverter);
1126 return create_instance(&This->clsid, &IID_IWICFormatConverter,
1127 (void**)ppIFormatConverter);
1130 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
1132 LONG res;
1133 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1134 HKEY formats_key, guid_key;
1136 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
1137 would be O(n). A registry test should do better. */
1139 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
1140 if (res != ERROR_SUCCESS) return FALSE;
1142 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
1143 if (res == ERROR_SUCCESS) RegCloseKey(guid_key);
1145 RegCloseKey(formats_key);
1147 return (res == ERROR_SUCCESS);
1150 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
1151 FormatConverterInfo_QueryInterface,
1152 FormatConverterInfo_AddRef,
1153 FormatConverterInfo_Release,
1154 FormatConverterInfo_GetComponentType,
1155 FormatConverterInfo_GetCLSID,
1156 FormatConverterInfo_GetSigningStatus,
1157 FormatConverterInfo_GetAuthor,
1158 FormatConverterInfo_GetVendorGUID,
1159 FormatConverterInfo_GetVersion,
1160 FormatConverterInfo_GetSpecVersion,
1161 FormatConverterInfo_GetFriendlyName,
1162 FormatConverterInfo_GetPixelFormats,
1163 FormatConverterInfo_CreateInstance
1166 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1168 FormatConverterInfo *This;
1170 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
1171 if (!This)
1173 RegCloseKey(classkey);
1174 return E_OUTOFMEMORY;
1177 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
1178 This->ref = 1;
1179 This->classkey = classkey;
1180 memcpy(&This->clsid, clsid, sizeof(CLSID));
1182 *ppIInfo = (IWICComponentInfo *)&This->IWICFormatConverterInfo_iface;
1183 return S_OK;
1186 typedef struct {
1187 IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface;
1188 LONG ref;
1189 HKEY classkey;
1190 CLSID clsid;
1191 } PixelFormatInfo;
1193 static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2 *iface)
1195 return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface);
1198 static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID iid,
1199 void **ppv)
1201 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1202 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1204 if (!ppv) return E_INVALIDARG;
1206 if (IsEqualIID(&IID_IUnknown, iid) ||
1207 IsEqualIID(&IID_IWICComponentInfo, iid) ||
1208 IsEqualIID(&IID_IWICPixelFormatInfo, iid) ||
1209 IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid))
1211 *ppv = &This->IWICPixelFormatInfo2_iface;
1213 else
1215 *ppv = NULL;
1216 return E_NOINTERFACE;
1219 IUnknown_AddRef((IUnknown*)*ppv);
1220 return S_OK;
1223 static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface)
1225 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1226 ULONG ref = InterlockedIncrement(&This->ref);
1228 TRACE("(%p) refcount=%u\n", iface, ref);
1230 return ref;
1233 static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface)
1235 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1236 ULONG ref = InterlockedDecrement(&This->ref);
1238 TRACE("(%p) refcount=%u\n", iface, ref);
1240 if (ref == 0)
1242 RegCloseKey(This->classkey);
1243 HeapFree(GetProcessHeap(), 0, This);
1246 return ref;
1249 static HRESULT WINAPI PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2 *iface,
1250 WICComponentType *pType)
1252 TRACE("(%p,%p)\n", iface, pType);
1253 if (!pType) return E_INVALIDARG;
1254 *pType = WICPixelFormat;
1255 return S_OK;
1258 static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2 *iface, CLSID *pclsid)
1260 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1261 TRACE("(%p,%p)\n", iface, pclsid);
1263 if (!pclsid)
1264 return E_INVALIDARG;
1266 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1268 return S_OK;
1271 static HRESULT WINAPI PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2 *iface, DWORD *pStatus)
1273 TRACE("(%p,%p)\n", iface, pStatus);
1275 if (!pStatus)
1276 return E_INVALIDARG;
1278 /* Pixel formats don't require code, so they are considered signed. */
1279 *pStatus = WICComponentSigned;
1281 return S_OK;
1284 static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UINT cchAuthor,
1285 WCHAR *wzAuthor, UINT *pcchActual)
1287 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1289 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1291 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1292 cchAuthor, wzAuthor, pcchActual);
1295 static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor)
1297 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1299 TRACE("(%p,%p)\n", iface, pguidVendor);
1301 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1304 static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion,
1305 WCHAR *wzVersion, UINT *pcchActual)
1307 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1309 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1311 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1312 cchVersion, wzVersion, pcchActual);
1315 static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface, UINT cchSpecVersion,
1316 WCHAR *wzSpecVersion, UINT *pcchActual)
1318 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1320 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1322 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1323 cchSpecVersion, wzSpecVersion, pcchActual);
1326 static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *iface, UINT cchFriendlyName,
1327 WCHAR *wzFriendlyName, UINT *pcchActual)
1329 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1331 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1333 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1334 cchFriendlyName, wzFriendlyName, pcchActual);
1337 static HRESULT WINAPI PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface,
1338 GUID *pFormat)
1340 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1341 TRACE("(%p,%p)\n", iface, pFormat);
1343 if (!pFormat)
1344 return E_INVALIDARG;
1346 *pFormat = This->clsid;
1348 return S_OK;
1351 static HRESULT WINAPI PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2 *iface,
1352 IWICColorContext **ppIColorContext)
1354 FIXME("(%p,%p): stub\n", iface, ppIColorContext);
1355 return E_NOTIMPL;
1358 static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *iface,
1359 UINT *puiBitsPerPixel)
1361 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1363 TRACE("(%p,%p)\n", iface, puiBitsPerPixel);
1365 return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel);
1368 static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface,
1369 UINT *puiChannelCount)
1371 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1373 TRACE("(%p,%p)\n", iface, puiChannelCount);
1375 return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount);
1378 static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface,
1379 UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual)
1381 static const WCHAR uintformatW[] = {'%','u',0};
1382 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1383 UINT channel_count;
1384 HRESULT hr;
1385 LONG ret;
1386 WCHAR valuename[11];
1387 DWORD cbData;
1389 TRACE("(%p,%u,%u,%p,%p)\n", iface, uiChannelIndex, cbMaskBuffer, pbMaskBuffer, pcbActual);
1391 if (!pcbActual)
1392 return E_INVALIDARG;
1394 hr = PixelFormatInfo_GetChannelCount(iface, &channel_count);
1396 if (SUCCEEDED(hr) && uiChannelIndex >= channel_count)
1397 hr = E_INVALIDARG;
1399 if (SUCCEEDED(hr))
1401 snprintfW(valuename, 11, uintformatW, uiChannelIndex);
1403 cbData = cbMaskBuffer;
1405 ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData);
1407 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
1408 *pcbActual = cbData;
1410 if (ret == ERROR_MORE_DATA)
1411 hr = E_INVALIDARG;
1412 else
1413 hr = HRESULT_FROM_WIN32(ret);
1416 return hr;
1419 static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 *iface,
1420 BOOL *pfSupportsTransparency)
1422 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1424 TRACE("(%p,%p)\n", iface, pfSupportsTransparency);
1426 return ComponentInfo_GetDWORDValue(This->classkey, supportstransparency_valuename, (DWORD*)pfSupportsTransparency);
1429 static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface,
1430 WICPixelFormatNumericRepresentation *pNumericRepresentation)
1432 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1434 TRACE("(%p,%p)\n", iface, pNumericRepresentation);
1436 return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation);
1439 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = {
1440 PixelFormatInfo_QueryInterface,
1441 PixelFormatInfo_AddRef,
1442 PixelFormatInfo_Release,
1443 PixelFormatInfo_GetComponentType,
1444 PixelFormatInfo_GetCLSID,
1445 PixelFormatInfo_GetSigningStatus,
1446 PixelFormatInfo_GetAuthor,
1447 PixelFormatInfo_GetVendorGUID,
1448 PixelFormatInfo_GetVersion,
1449 PixelFormatInfo_GetSpecVersion,
1450 PixelFormatInfo_GetFriendlyName,
1451 PixelFormatInfo_GetFormatGUID,
1452 PixelFormatInfo_GetColorContext,
1453 PixelFormatInfo_GetBitsPerPixel,
1454 PixelFormatInfo_GetChannelCount,
1455 PixelFormatInfo_GetChannelMask,
1456 PixelFormatInfo_SupportsTransparency,
1457 PixelFormatInfo_GetNumericRepresentation
1460 static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1462 PixelFormatInfo *This;
1464 This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo));
1465 if (!This)
1467 RegCloseKey(classkey);
1468 return E_OUTOFMEMORY;
1471 This->IWICPixelFormatInfo2_iface.lpVtbl = &PixelFormatInfo_Vtbl;
1472 This->ref = 1;
1473 This->classkey = classkey;
1474 memcpy(&This->clsid, clsid, sizeof(CLSID));
1476 *ppIInfo = (IWICComponentInfo *)&This->IWICPixelFormatInfo2_iface;
1477 return S_OK;
1480 typedef struct
1482 IWICMetadataReaderInfo IWICMetadataReaderInfo_iface;
1483 LONG ref;
1484 HKEY classkey;
1485 CLSID clsid;
1486 } MetadataReaderInfo;
1488 static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo *iface)
1490 return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface);
1493 static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface,
1494 REFIID riid, void **ppv)
1496 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1498 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
1500 if (!ppv) return E_INVALIDARG;
1502 if (IsEqualIID(&IID_IUnknown, riid) ||
1503 IsEqualIID(&IID_IWICComponentInfo, riid) ||
1504 IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) ||
1505 IsEqualIID(&IID_IWICMetadataReaderInfo, riid))
1507 *ppv = &This->IWICMetadataReaderInfo_iface;
1509 else
1511 *ppv = NULL;
1512 return E_NOINTERFACE;
1515 IUnknown_AddRef((IUnknown *)*ppv);
1516 return S_OK;
1519 static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
1521 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1522 ULONG ref = InterlockedIncrement(&This->ref);
1524 TRACE("(%p) refcount=%u\n", iface, ref);
1525 return ref;
1528 static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface)
1530 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1531 ULONG ref = InterlockedDecrement(&This->ref);
1533 TRACE("(%p) refcount=%u\n", iface, ref);
1535 if (!ref)
1537 RegCloseKey(This->classkey);
1538 HeapFree(GetProcessHeap(), 0, This);
1540 return ref;
1543 static HRESULT WINAPI MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo *iface,
1544 WICComponentType *type)
1546 TRACE("(%p,%p)\n", iface, type);
1548 if (!type) return E_INVALIDARG;
1549 *type = WICMetadataReader;
1550 return S_OK;
1553 static HRESULT WINAPI MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface,
1554 CLSID *clsid)
1556 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1558 TRACE("(%p,%p)\n", iface, clsid);
1560 if (!clsid) return E_INVALIDARG;
1561 *clsid = This->clsid;
1562 return S_OK;
1565 static HRESULT WINAPI MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo *iface,
1566 DWORD *status)
1568 FIXME("(%p,%p): stub\n", iface, status);
1569 return E_NOTIMPL;
1572 static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface,
1573 UINT length, WCHAR *author, UINT *actual_length)
1575 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1577 TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length);
1579 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1580 length, author, actual_length);
1583 static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface,
1584 GUID *vendor)
1586 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1588 TRACE("(%p,%p)\n", iface, vendor);
1590 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, vendor);
1593 static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface,
1594 UINT length, WCHAR *version, UINT *actual_length)
1596 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1598 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1600 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1601 length, version, actual_length);
1604 static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface,
1605 UINT length, WCHAR *version, UINT *actual_length)
1607 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1609 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1611 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1612 length, version, actual_length);
1615 static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo *iface,
1616 UINT length, WCHAR *name, UINT *actual_length)
1618 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1620 TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length);
1622 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1623 length, name, actual_length);
1626 static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo *iface,
1627 GUID *format)
1629 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1630 TRACE("(%p,%p)\n", iface, format);
1631 return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format);
1634 static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface,
1635 UINT length, GUID *formats, UINT *actual_length)
1637 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1638 TRACE("(%p,%u,%p,%p)\n", iface, length, formats, actual_length);
1640 return ComponentInfo_GetGuidList(This->classkey, containers_keyname, length,
1641 formats, actual_length);
1644 static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo *iface,
1645 UINT length, WCHAR *manufacturer, UINT *actual_length)
1647 FIXME("(%p,%u,%p,%p): stub\n", iface, length, manufacturer, actual_length);
1648 return E_NOTIMPL;
1651 static HRESULT WINAPI MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo *iface,
1652 UINT length, WCHAR *models, UINT *actual_length)
1654 FIXME("(%p,%u,%p,%p): stub\n", iface, length, models, actual_length);
1655 return E_NOTIMPL;
1658 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo *iface,
1659 BOOL *param)
1661 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1662 TRACE("(%p,%p)\n", iface, param);
1663 return ComponentInfo_GetDWORDValue(This->classkey, requiresfullstream_valuename, (DWORD *)param);
1666 static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface,
1667 BOOL *param)
1669 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1670 TRACE("(%p,%p)\n", iface, param);
1671 return ComponentInfo_GetDWORDValue(This->classkey, supportspadding_valuename, (DWORD *)param);
1674 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface,
1675 BOOL *param)
1677 FIXME("(%p,%p): stub\n", iface, param);
1678 return E_NOTIMPL;
1681 static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface,
1682 REFGUID container, UINT length, WICMetadataPattern *patterns, UINT *count, UINT *actual_length)
1684 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1685 HRESULT hr=S_OK;
1686 LONG res;
1687 UINT pattern_count=0, patterns_size=0;
1688 DWORD valuesize, patternsize;
1689 BYTE *bPatterns=(BYTE*)patterns;
1690 HKEY containers_key, guid_key, pattern_key;
1691 WCHAR subkeyname[11];
1692 WCHAR guidkeyname[39];
1693 int i;
1694 static const WCHAR uintformatW[] = {'%','u',0};
1695 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
1696 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
1697 static const WCHAR maskW[] = {'M','a','s','k',0};
1698 static const WCHAR dataoffsetW[] = {'D','a','t','a','O','f','f','s','e','t',0};
1700 TRACE("(%p,%s,%u,%p,%p,%p)\n", iface, debugstr_guid(container), length, patterns, count, actual_length);
1702 if (!actual_length || !container) return E_INVALIDARG;
1704 res = RegOpenKeyExW(This->classkey, containers_keyname, 0, KEY_READ, &containers_key);
1705 if (res == ERROR_SUCCESS)
1707 StringFromGUID2(container, guidkeyname, 39);
1709 res = RegOpenKeyExW(containers_key, guidkeyname, 0, KEY_READ, &guid_key);
1710 if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND;
1711 else if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res);
1713 RegCloseKey(containers_key);
1715 else if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND;
1716 else hr = HRESULT_FROM_WIN32(res);
1718 if (SUCCEEDED(hr))
1720 res = RegQueryInfoKeyW(guid_key, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1721 if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res);
1723 if (SUCCEEDED(hr))
1725 patterns_size = pattern_count * sizeof(WICMetadataPattern);
1727 for (i=0; i<pattern_count; i++)
1729 snprintfW(subkeyname, 11, uintformatW, i);
1730 res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &pattern_key);
1731 if (res == ERROR_SUCCESS)
1733 res = RegGetValueW(pattern_key, NULL, patternW, RRF_RT_REG_BINARY, NULL,
1734 NULL, &patternsize);
1735 patterns_size += patternsize*2;
1737 if ((length >= patterns_size) && (res == ERROR_SUCCESS))
1739 patterns[i].Length = patternsize;
1741 patterns[i].DataOffset.QuadPart = 0;
1742 valuesize = sizeof(ULARGE_INTEGER);
1743 RegGetValueW(pattern_key, NULL, dataoffsetW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
1744 &patterns[i].DataOffset, &valuesize);
1746 patterns[i].Position.QuadPart = 0;
1747 valuesize = sizeof(ULARGE_INTEGER);
1748 res = RegGetValueW(pattern_key, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
1749 &patterns[i].Position, &valuesize);
1751 if (res == ERROR_SUCCESS)
1753 patterns[i].Pattern = bPatterns+patterns_size-patternsize*2;
1754 valuesize = patternsize;
1755 res = RegGetValueW(pattern_key, NULL, patternW, RRF_RT_REG_BINARY, NULL,
1756 patterns[i].Pattern, &valuesize);
1759 if (res == ERROR_SUCCESS)
1761 patterns[i].Mask = bPatterns+patterns_size-patternsize;
1762 valuesize = patternsize;
1763 res = RegGetValueW(pattern_key, NULL, maskW, RRF_RT_REG_BINARY, NULL,
1764 patterns[i].Mask, &valuesize);
1768 RegCloseKey(pattern_key);
1770 if (res != ERROR_SUCCESS)
1772 hr = HRESULT_FROM_WIN32(res);
1773 break;
1778 RegCloseKey(guid_key);
1781 if (hr == S_OK)
1783 *count = pattern_count;
1784 *actual_length = patterns_size;
1785 if (patterns && length < patterns_size)
1786 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
1789 return hr;
1792 static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface,
1793 REFGUID container, IStream *stream, BOOL *matches)
1795 HRESULT hr;
1796 WICMetadataPattern *patterns;
1797 UINT pattern_count=0, patterns_size=0;
1798 ULONG datasize=0;
1799 BYTE *data=NULL;
1800 ULONG bytesread;
1801 UINT i;
1802 LARGE_INTEGER seekpos;
1803 ULONG pos;
1805 TRACE("(%p,%s,%p,%p)\n", iface, debugstr_guid(container), stream, matches);
1807 hr = MetadataReaderInfo_GetPatterns(iface, container, 0, NULL, &pattern_count, &patterns_size);
1808 if (FAILED(hr)) return hr;
1810 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
1811 if (!patterns) return E_OUTOFMEMORY;
1813 hr = MetadataReaderInfo_GetPatterns(iface, container, patterns_size, patterns, &pattern_count, &patterns_size);
1814 if (FAILED(hr)) goto end;
1816 for (i=0; i<pattern_count; i++)
1818 if (datasize < patterns[i].Length)
1820 HeapFree(GetProcessHeap(), 0, data);
1821 datasize = patterns[i].Length;
1822 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
1823 if (!data)
1825 hr = E_OUTOFMEMORY;
1826 break;
1830 seekpos.QuadPart = patterns[i].Position.QuadPart;
1831 hr = IStream_Seek(stream, seekpos, STREAM_SEEK_SET, NULL);
1832 if (FAILED(hr)) break;
1834 hr = IStream_Read(stream, data, patterns[i].Length, &bytesread);
1835 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
1836 continue;
1837 if (FAILED(hr)) break;
1839 for (pos=0; pos<patterns[i].Length; pos++)
1841 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
1842 break;
1844 if (pos == patterns[i].Length) /* matches pattern */
1846 hr = S_OK;
1847 *matches = TRUE;
1848 break;
1852 if (i == pattern_count) /* does not match any pattern */
1854 hr = S_OK;
1855 *matches = FALSE;
1858 end:
1859 HeapFree(GetProcessHeap(), 0, patterns);
1860 HeapFree(GetProcessHeap(), 0, data);
1862 return hr;
1865 static HRESULT WINAPI MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *iface,
1866 IWICMetadataReader **reader)
1868 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1870 TRACE("(%p,%p)\n", iface, reader);
1872 return create_instance(&This->clsid, &IID_IWICMetadataReader, (void **)reader);
1875 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = {
1876 MetadataReaderInfo_QueryInterface,
1877 MetadataReaderInfo_AddRef,
1878 MetadataReaderInfo_Release,
1879 MetadataReaderInfo_GetComponentType,
1880 MetadataReaderInfo_GetCLSID,
1881 MetadataReaderInfo_GetSigningStatus,
1882 MetadataReaderInfo_GetAuthor,
1883 MetadataReaderInfo_GetVendorGUID,
1884 MetadataReaderInfo_GetVersion,
1885 MetadataReaderInfo_GetSpecVersion,
1886 MetadataReaderInfo_GetFriendlyName,
1887 MetadataReaderInfo_GetMetadataFormat,
1888 MetadataReaderInfo_GetContainerFormats,
1889 MetadataReaderInfo_GetDeviceManufacturer,
1890 MetadataReaderInfo_GetDeviceModels,
1891 MetadataReaderInfo_DoesRequireFullStream,
1892 MetadataReaderInfo_DoesSupportPadding,
1893 MetadataReaderInfo_DoesRequireFixedSize,
1894 MetadataReaderInfo_GetPatterns,
1895 MetadataReaderInfo_MatchesPattern,
1896 MetadataReaderInfo_CreateInstance
1899 static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **info)
1901 MetadataReaderInfo *This;
1903 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1904 if (!This)
1906 RegCloseKey(classkey);
1907 return E_OUTOFMEMORY;
1910 This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl;
1911 This->ref = 1;
1912 This->classkey = classkey;
1913 This->clsid = *clsid;
1915 *info = (IWICComponentInfo *)&This->IWICMetadataReaderInfo_iface;
1916 return S_OK;
1919 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
1920 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
1922 struct category {
1923 WICComponentType type;
1924 const GUID *catid;
1925 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
1928 static const struct category categories[] = {
1929 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
1930 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
1931 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
1932 {WICPixelFormat, &CATID_WICPixelFormats, PixelFormatInfo_Constructor},
1933 {WICMetadataReader, &CATID_WICMetadataReader, MetadataReaderInfo_Constructor},
1937 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
1939 HKEY clsidkey;
1940 HKEY classkey;
1941 HKEY catidkey;
1942 HKEY instancekey;
1943 WCHAR guidstring[39];
1944 LONG res;
1945 const struct category *category;
1946 BOOL found = FALSE;
1947 HRESULT hr;
1949 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1950 if (res != ERROR_SUCCESS)
1951 return HRESULT_FROM_WIN32(res);
1953 for (category=categories; category->type; category++)
1955 StringFromGUID2(category->catid, guidstring, 39);
1956 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1957 if (res == ERROR_SUCCESS)
1959 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1960 if (res == ERROR_SUCCESS)
1962 StringFromGUID2(clsid, guidstring, 39);
1963 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
1964 if (res == ERROR_SUCCESS)
1966 RegCloseKey(classkey);
1967 found = TRUE;
1969 RegCloseKey(instancekey);
1971 RegCloseKey(catidkey);
1973 if (found) break;
1976 if (found)
1978 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
1979 if (res == ERROR_SUCCESS)
1980 hr = category->constructor(classkey, clsid, ppIInfo);
1981 else
1982 hr = HRESULT_FROM_WIN32(res);
1984 else
1986 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid));
1987 hr = E_FAIL;
1990 RegCloseKey(clsidkey);
1992 return hr;
1995 typedef struct {
1996 IEnumUnknown IEnumUnknown_iface;
1997 LONG ref;
1998 struct list objects;
1999 struct list *cursor;
2000 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
2001 } ComponentEnum;
2003 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
2005 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
2008 typedef struct {
2009 struct list entry;
2010 IUnknown *unk;
2011 } ComponentEnumItem;
2013 static const IEnumUnknownVtbl ComponentEnumVtbl;
2015 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
2016 void **ppv)
2018 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2019 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
2021 if (!ppv) return E_INVALIDARG;
2023 if (IsEqualIID(&IID_IUnknown, iid) ||
2024 IsEqualIID(&IID_IEnumUnknown, iid))
2026 *ppv = &This->IEnumUnknown_iface;
2028 else
2030 *ppv = NULL;
2031 return E_NOINTERFACE;
2034 IUnknown_AddRef((IUnknown*)*ppv);
2035 return S_OK;
2038 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
2040 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2041 ULONG ref = InterlockedIncrement(&This->ref);
2043 TRACE("(%p) refcount=%u\n", iface, ref);
2045 return ref;
2048 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
2050 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2051 ULONG ref = InterlockedDecrement(&This->ref);
2052 ComponentEnumItem *cursor, *cursor2;
2054 TRACE("(%p) refcount=%u\n", iface, ref);
2056 if (ref == 0)
2058 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
2060 IUnknown_Release(cursor->unk);
2061 list_remove(&cursor->entry);
2062 HeapFree(GetProcessHeap(), 0, cursor);
2064 This->lock.DebugInfo->Spare[0] = 0;
2065 DeleteCriticalSection(&This->lock);
2066 HeapFree(GetProcessHeap(), 0, This);
2069 return ref;
2072 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
2073 IUnknown **rgelt, ULONG *pceltFetched)
2075 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2076 ULONG num_fetched=0;
2077 ComponentEnumItem *item;
2078 HRESULT hr=S_OK;
2080 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
2082 EnterCriticalSection(&This->lock);
2083 while (num_fetched<celt)
2085 if (!This->cursor)
2087 hr = S_FALSE;
2088 break;
2090 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
2091 IUnknown_AddRef(item->unk);
2092 rgelt[num_fetched] = item->unk;
2093 num_fetched++;
2094 This->cursor = list_next(&This->objects, This->cursor);
2096 LeaveCriticalSection(&This->lock);
2097 if (pceltFetched)
2098 *pceltFetched = num_fetched;
2099 return hr;
2102 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
2104 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2105 ULONG i;
2106 HRESULT hr=S_OK;
2108 TRACE("(%p,%u)\n", iface, celt);
2110 EnterCriticalSection(&This->lock);
2111 for (i=0; i<celt; i++)
2113 if (!This->cursor)
2115 hr = S_FALSE;
2116 break;
2118 This->cursor = list_next(&This->objects, This->cursor);
2120 LeaveCriticalSection(&This->lock);
2121 return hr;
2124 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
2126 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2128 TRACE("(%p)\n", iface);
2130 EnterCriticalSection(&This->lock);
2131 This->cursor = list_head(&This->objects);
2132 LeaveCriticalSection(&This->lock);
2133 return S_OK;
2136 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
2138 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2139 ComponentEnum *new_enum;
2140 ComponentEnumItem *old_item, *new_item;
2141 HRESULT ret=S_OK;
2142 struct list *old_cursor;
2144 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
2145 if (!new_enum)
2147 *ppenum = NULL;
2148 return E_OUTOFMEMORY;
2151 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
2152 new_enum->ref = 1;
2153 new_enum->cursor = NULL;
2154 list_init(&new_enum->objects);
2155 InitializeCriticalSection(&new_enum->lock);
2156 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
2158 EnterCriticalSection(&This->lock);
2159 old_cursor = This->cursor;
2160 LeaveCriticalSection(&This->lock);
2162 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
2164 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
2165 if (!new_item)
2167 ret = E_OUTOFMEMORY;
2168 break;
2170 new_item->unk = old_item->unk;
2171 list_add_tail(&new_enum->objects, &new_item->entry);
2172 IUnknown_AddRef(new_item->unk);
2173 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
2176 if (FAILED(ret))
2178 IEnumUnknown_Release(&new_enum->IEnumUnknown_iface);
2179 *ppenum = NULL;
2181 else
2182 *ppenum = &new_enum->IEnumUnknown_iface;
2184 return ret;
2187 static const IEnumUnknownVtbl ComponentEnumVtbl = {
2188 ComponentEnum_QueryInterface,
2189 ComponentEnum_AddRef,
2190 ComponentEnum_Release,
2191 ComponentEnum_Next,
2192 ComponentEnum_Skip,
2193 ComponentEnum_Reset,
2194 ComponentEnum_Clone
2197 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
2199 ComponentEnum *This;
2200 ComponentEnumItem *item;
2201 const struct category *category;
2202 HKEY clsidkey, catidkey, instancekey;
2203 WCHAR guidstring[39];
2204 LONG res;
2205 int i;
2206 HRESULT hr=S_OK;
2207 CLSID clsid;
2209 if (options) FIXME("ignoring flags %x\n", options);
2211 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
2212 if (res != ERROR_SUCCESS)
2213 return HRESULT_FROM_WIN32(res);
2215 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
2216 if (!This)
2218 RegCloseKey(clsidkey);
2219 return E_OUTOFMEMORY;
2222 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
2223 This->ref = 1;
2224 list_init(&This->objects);
2225 InitializeCriticalSection(&This->lock);
2226 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
2228 for (category=categories; category->type && hr == S_OK; category++)
2230 if ((category->type & componentTypes) == 0) continue;
2231 StringFromGUID2(category->catid, guidstring, 39);
2232 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
2233 if (res == ERROR_SUCCESS)
2235 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
2236 if (res == ERROR_SUCCESS)
2238 i=0;
2239 for (;;i++)
2241 DWORD guidstring_size = 39;
2242 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
2243 if (res != ERROR_SUCCESS) break;
2245 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
2246 if (!item) { hr = E_OUTOFMEMORY; break; }
2248 hr = CLSIDFromString(guidstring, &clsid);
2249 if (SUCCEEDED(hr))
2251 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
2252 if (SUCCEEDED(hr))
2253 list_add_tail(&This->objects, &item->entry);
2256 if (FAILED(hr))
2258 HeapFree(GetProcessHeap(), 0, item);
2259 hr = S_OK;
2262 RegCloseKey(instancekey);
2264 RegCloseKey(catidkey);
2266 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
2267 hr = HRESULT_FROM_WIN32(res);
2269 RegCloseKey(clsidkey);
2271 if (SUCCEEDED(hr))
2273 IEnumUnknown_Reset(&This->IEnumUnknown_iface);
2274 *ppIEnumUnknown = &This->IEnumUnknown_iface;
2276 else
2278 *ppIEnumUnknown = NULL;
2279 IEnumUnknown_Release(&This->IEnumUnknown_iface);
2282 return hr;
2285 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
2287 HRESULT res;
2288 IEnumUnknown *enumconverters;
2289 IUnknown *unkconverterinfo;
2290 IWICFormatConverterInfo *converterinfo=NULL;
2291 IWICFormatConverter *converter=NULL;
2292 GUID srcFormat;
2293 WCHAR srcformatstr[39], dstformatstr[39];
2294 BOOL canconvert;
2295 ULONG num_fetched;
2297 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
2298 if (FAILED(res)) return res;
2300 if (IsEqualGUID(&srcFormat, dstFormat))
2302 IWICBitmapSource_AddRef(pISrc);
2303 *ppIDst = pISrc;
2304 return S_OK;
2307 StringFromGUID2(&srcFormat, srcformatstr, 39);
2308 StringFromGUID2(dstFormat, dstformatstr, 39);
2310 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
2311 if (FAILED(res)) return res;
2313 while (!converter)
2315 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);
2317 if (res == S_OK)
2319 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);
2321 if (SUCCEEDED(res))
2323 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);
2325 if (canconvert)
2326 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);
2328 if (canconvert)
2330 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);
2332 if (SUCCEEDED(res))
2333 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);
2335 if (SUCCEEDED(res) && canconvert)
2336 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
2337 NULL, 0.0, WICBitmapPaletteTypeCustom);
2339 if (FAILED(res) || !canconvert)
2341 if (converter)
2343 IWICFormatConverter_Release(converter);
2344 converter = NULL;
2346 res = S_OK;
2350 IWICFormatConverterInfo_Release(converterinfo);
2353 IUnknown_Release(unkconverterinfo);
2355 else
2356 break;
2359 IEnumUnknown_Release(enumconverters);
2361 if (converter)
2363 res = IWICFormatConverter_QueryInterface(converter, &IID_IWICBitmapSource, (void **)ppIDst);
2364 IWICFormatConverter_Release(converter);
2365 return res;
2367 else
2369 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
2370 *ppIDst = NULL;
2371 return WINCODEC_ERR_COMPONENTNOTFOUND;