gdi32: Fix arguments for OSMesaMakeCurrent when using 16 bit formats.
[wine.git] / dlls / windowscodecs / info.c
blobf532ad1b001e2fc1dfec2759d636041080e4a04e
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;
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 CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
627 &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
630 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
631 BitmapDecoderInfo_QueryInterface,
632 BitmapDecoderInfo_AddRef,
633 BitmapDecoderInfo_Release,
634 BitmapDecoderInfo_GetComponentType,
635 BitmapDecoderInfo_GetCLSID,
636 BitmapDecoderInfo_GetSigningStatus,
637 BitmapDecoderInfo_GetAuthor,
638 BitmapDecoderInfo_GetVendorGUID,
639 BitmapDecoderInfo_GetVersion,
640 BitmapDecoderInfo_GetSpecVersion,
641 BitmapDecoderInfo_GetFriendlyName,
642 BitmapDecoderInfo_GetContainerFormat,
643 BitmapDecoderInfo_GetPixelFormats,
644 BitmapDecoderInfo_GetColorManagementVersion,
645 BitmapDecoderInfo_GetDeviceManufacturer,
646 BitmapDecoderInfo_GetDeviceModels,
647 BitmapDecoderInfo_GetMimeTypes,
648 BitmapDecoderInfo_GetFileExtensions,
649 BitmapDecoderInfo_DoesSupportAnimation,
650 BitmapDecoderInfo_DoesSupportChromaKey,
651 BitmapDecoderInfo_DoesSupportLossless,
652 BitmapDecoderInfo_DoesSupportMultiframe,
653 BitmapDecoderInfo_MatchesMimeType,
654 BitmapDecoderInfo_GetPatterns,
655 BitmapDecoderInfo_MatchesPattern,
656 BitmapDecoderInfo_CreateInstance
659 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
661 BitmapDecoderInfo *This;
663 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
664 if (!This)
666 RegCloseKey(classkey);
667 return E_OUTOFMEMORY;
670 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
671 This->ref = 1;
672 This->classkey = classkey;
673 memcpy(&This->clsid, clsid, sizeof(CLSID));
675 *ppIInfo = (IWICComponentInfo*)This;
676 return S_OK;
679 typedef struct {
680 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
681 LONG ref;
682 HKEY classkey;
683 CLSID clsid;
684 } BitmapEncoderInfo;
686 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
688 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
691 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
692 void **ppv)
694 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
695 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
697 if (!ppv) return E_INVALIDARG;
699 if (IsEqualIID(&IID_IUnknown, iid) ||
700 IsEqualIID(&IID_IWICComponentInfo, iid) ||
701 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
702 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
704 *ppv = This;
706 else
708 *ppv = NULL;
709 return E_NOINTERFACE;
712 IUnknown_AddRef((IUnknown*)*ppv);
713 return S_OK;
716 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
718 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
719 ULONG ref = InterlockedIncrement(&This->ref);
721 TRACE("(%p) refcount=%u\n", iface, ref);
723 return ref;
726 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
728 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
729 ULONG ref = InterlockedDecrement(&This->ref);
731 TRACE("(%p) refcount=%u\n", iface, ref);
733 if (ref == 0)
735 RegCloseKey(This->classkey);
736 HeapFree(GetProcessHeap(), 0, This);
739 return ref;
742 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
743 WICComponentType *pType)
745 TRACE("(%p,%p)\n", iface, pType);
746 if (!pType) return E_INVALIDARG;
747 *pType = WICEncoder;
748 return S_OK;
751 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
753 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
754 TRACE("(%p,%p)\n", iface, pclsid);
756 if (!pclsid)
757 return E_INVALIDARG;
759 memcpy(pclsid, &This->clsid, sizeof(CLSID));
761 return S_OK;
764 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
766 FIXME("(%p,%p): stub\n", iface, pStatus);
767 return E_NOTIMPL;
770 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
771 WCHAR *wzAuthor, UINT *pcchActual)
773 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
775 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
777 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
778 cchAuthor, wzAuthor, pcchActual);
781 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
783 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
785 TRACE("(%p,%p)\n", iface, pguidVendor);
787 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
790 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
791 WCHAR *wzVersion, UINT *pcchActual)
793 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
795 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
797 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
798 cchVersion, wzVersion, pcchActual);
801 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
802 WCHAR *wzSpecVersion, UINT *pcchActual)
804 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
806 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
808 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
809 cchSpecVersion, wzSpecVersion, pcchActual);
812 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
813 WCHAR *wzFriendlyName, UINT *pcchActual)
815 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
817 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
819 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
820 cchFriendlyName, wzFriendlyName, pcchActual);
823 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
824 GUID *pguidContainerFormat)
826 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
827 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
828 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
831 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
832 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
834 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
835 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
836 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
839 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
840 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
842 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
843 return E_NOTIMPL;
846 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
847 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
849 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
850 return E_NOTIMPL;
853 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
854 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
856 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
857 return E_NOTIMPL;
860 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
861 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
863 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
865 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
867 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
868 cchMimeTypes, wzMimeTypes, pcchActual);
871 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
872 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
874 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
875 return E_NOTIMPL;
878 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
879 BOOL *pfSupportAnimation)
881 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
882 return E_NOTIMPL;
885 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
886 BOOL *pfSupportChromaKey)
888 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
889 return E_NOTIMPL;
892 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
893 BOOL *pfSupportLossless)
895 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
896 return E_NOTIMPL;
899 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
900 BOOL *pfSupportMultiframe)
902 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
903 return E_NOTIMPL;
906 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
907 LPCWSTR wzMimeType, BOOL *pfMatches)
909 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
910 return E_NOTIMPL;
913 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
914 IWICBitmapEncoder **ppIBitmapEncoder)
916 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
918 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
920 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
921 &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
924 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
925 BitmapEncoderInfo_QueryInterface,
926 BitmapEncoderInfo_AddRef,
927 BitmapEncoderInfo_Release,
928 BitmapEncoderInfo_GetComponentType,
929 BitmapEncoderInfo_GetCLSID,
930 BitmapEncoderInfo_GetSigningStatus,
931 BitmapEncoderInfo_GetAuthor,
932 BitmapEncoderInfo_GetVendorGUID,
933 BitmapEncoderInfo_GetVersion,
934 BitmapEncoderInfo_GetSpecVersion,
935 BitmapEncoderInfo_GetFriendlyName,
936 BitmapEncoderInfo_GetContainerFormat,
937 BitmapEncoderInfo_GetPixelFormats,
938 BitmapEncoderInfo_GetColorManagementVersion,
939 BitmapEncoderInfo_GetDeviceManufacturer,
940 BitmapEncoderInfo_GetDeviceModels,
941 BitmapEncoderInfo_GetMimeTypes,
942 BitmapEncoderInfo_GetFileExtensions,
943 BitmapEncoderInfo_DoesSupportAnimation,
944 BitmapEncoderInfo_DoesSupportChromaKey,
945 BitmapEncoderInfo_DoesSupportLossless,
946 BitmapEncoderInfo_DoesSupportMultiframe,
947 BitmapEncoderInfo_MatchesMimeType,
948 BitmapEncoderInfo_CreateInstance
951 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
953 BitmapEncoderInfo *This;
955 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
956 if (!This)
958 RegCloseKey(classkey);
959 return E_OUTOFMEMORY;
962 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
963 This->ref = 1;
964 This->classkey = classkey;
965 memcpy(&This->clsid, clsid, sizeof(CLSID));
967 *ppIInfo = (IWICComponentInfo*)This;
968 return S_OK;
971 typedef struct {
972 IWICFormatConverterInfo IWICFormatConverterInfo_iface;
973 LONG ref;
974 HKEY classkey;
975 CLSID clsid;
976 } FormatConverterInfo;
978 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
980 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
983 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
984 void **ppv)
986 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
987 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
989 if (!ppv) return E_INVALIDARG;
991 if (IsEqualIID(&IID_IUnknown, iid) ||
992 IsEqualIID(&IID_IWICComponentInfo, iid) ||
993 IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
995 *ppv = This;
997 else
999 *ppv = NULL;
1000 return E_NOINTERFACE;
1003 IUnknown_AddRef((IUnknown*)*ppv);
1004 return S_OK;
1007 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
1009 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1010 ULONG ref = InterlockedIncrement(&This->ref);
1012 TRACE("(%p) refcount=%u\n", iface, ref);
1014 return ref;
1017 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
1019 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1020 ULONG ref = InterlockedDecrement(&This->ref);
1022 TRACE("(%p) refcount=%u\n", iface, ref);
1024 if (ref == 0)
1026 RegCloseKey(This->classkey);
1027 HeapFree(GetProcessHeap(), 0, This);
1030 return ref;
1033 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
1034 WICComponentType *pType)
1036 TRACE("(%p,%p)\n", iface, pType);
1037 if (!pType) return E_INVALIDARG;
1038 *pType = WICPixelFormatConverter;
1039 return S_OK;
1042 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
1044 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1045 TRACE("(%p,%p)\n", iface, pclsid);
1047 if (!pclsid)
1048 return E_INVALIDARG;
1050 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1052 return S_OK;
1055 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
1057 FIXME("(%p,%p): stub\n", iface, pStatus);
1058 return E_NOTIMPL;
1061 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
1062 WCHAR *wzAuthor, UINT *pcchActual)
1064 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1066 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1068 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1069 cchAuthor, wzAuthor, pcchActual);
1072 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
1074 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1076 TRACE("(%p,%p)\n", iface, pguidVendor);
1078 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1081 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
1082 WCHAR *wzVersion, UINT *pcchActual)
1084 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1086 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1088 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1089 cchVersion, wzVersion, pcchActual);
1092 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
1093 WCHAR *wzSpecVersion, UINT *pcchActual)
1095 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1097 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1099 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1100 cchSpecVersion, wzSpecVersion, pcchActual);
1103 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
1104 WCHAR *wzFriendlyName, UINT *pcchActual)
1106 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1108 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1110 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1111 cchFriendlyName, wzFriendlyName, pcchActual);
1114 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
1115 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
1117 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
1118 return E_NOTIMPL;
1121 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
1122 IWICFormatConverter **ppIFormatConverter)
1124 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1126 TRACE("(%p,%p)\n", iface, ppIFormatConverter);
1128 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1129 &IID_IWICFormatConverter, (void**)ppIFormatConverter);
1132 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
1134 LONG res;
1135 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1136 HKEY formats_key, guid_key;
1138 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
1139 would be O(n). A registry test should do better. */
1141 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
1142 if (res != ERROR_SUCCESS) return FALSE;
1144 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
1145 if (res == ERROR_SUCCESS) RegCloseKey(guid_key);
1147 RegCloseKey(formats_key);
1149 return (res == ERROR_SUCCESS);
1152 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
1153 FormatConverterInfo_QueryInterface,
1154 FormatConverterInfo_AddRef,
1155 FormatConverterInfo_Release,
1156 FormatConverterInfo_GetComponentType,
1157 FormatConverterInfo_GetCLSID,
1158 FormatConverterInfo_GetSigningStatus,
1159 FormatConverterInfo_GetAuthor,
1160 FormatConverterInfo_GetVendorGUID,
1161 FormatConverterInfo_GetVersion,
1162 FormatConverterInfo_GetSpecVersion,
1163 FormatConverterInfo_GetFriendlyName,
1164 FormatConverterInfo_GetPixelFormats,
1165 FormatConverterInfo_CreateInstance
1168 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1170 FormatConverterInfo *This;
1172 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
1173 if (!This)
1175 RegCloseKey(classkey);
1176 return E_OUTOFMEMORY;
1179 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
1180 This->ref = 1;
1181 This->classkey = classkey;
1182 memcpy(&This->clsid, clsid, sizeof(CLSID));
1184 *ppIInfo = (IWICComponentInfo*)This;
1185 return S_OK;
1188 typedef struct {
1189 IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface;
1190 LONG ref;
1191 HKEY classkey;
1192 CLSID clsid;
1193 } PixelFormatInfo;
1195 static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2 *iface)
1197 return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface);
1200 static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID iid,
1201 void **ppv)
1203 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1204 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1206 if (!ppv) return E_INVALIDARG;
1208 if (IsEqualIID(&IID_IUnknown, iid) ||
1209 IsEqualIID(&IID_IWICComponentInfo, iid) ||
1210 IsEqualIID(&IID_IWICPixelFormatInfo, iid) ||
1211 IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid))
1213 *ppv = This;
1215 else
1217 *ppv = NULL;
1218 return E_NOINTERFACE;
1221 IUnknown_AddRef((IUnknown*)*ppv);
1222 return S_OK;
1225 static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface)
1227 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1228 ULONG ref = InterlockedIncrement(&This->ref);
1230 TRACE("(%p) refcount=%u\n", iface, ref);
1232 return ref;
1235 static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface)
1237 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1238 ULONG ref = InterlockedDecrement(&This->ref);
1240 TRACE("(%p) refcount=%u\n", iface, ref);
1242 if (ref == 0)
1244 RegCloseKey(This->classkey);
1245 HeapFree(GetProcessHeap(), 0, This);
1248 return ref;
1251 static HRESULT WINAPI PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2 *iface,
1252 WICComponentType *pType)
1254 TRACE("(%p,%p)\n", iface, pType);
1255 if (!pType) return E_INVALIDARG;
1256 *pType = WICPixelFormat;
1257 return S_OK;
1260 static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2 *iface, CLSID *pclsid)
1262 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1263 TRACE("(%p,%p)\n", iface, pclsid);
1265 if (!pclsid)
1266 return E_INVALIDARG;
1268 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1270 return S_OK;
1273 static HRESULT WINAPI PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2 *iface, DWORD *pStatus)
1275 TRACE("(%p,%p)\n", iface, pStatus);
1277 if (!pStatus)
1278 return E_INVALIDARG;
1280 /* Pixel formats don't require code, so they are considered signed. */
1281 *pStatus = WICComponentSigned;
1283 return S_OK;
1286 static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UINT cchAuthor,
1287 WCHAR *wzAuthor, UINT *pcchActual)
1289 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1291 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1293 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1294 cchAuthor, wzAuthor, pcchActual);
1297 static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor)
1299 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1301 TRACE("(%p,%p)\n", iface, pguidVendor);
1303 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1306 static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion,
1307 WCHAR *wzVersion, UINT *pcchActual)
1309 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1311 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1313 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1314 cchVersion, wzVersion, pcchActual);
1317 static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface, UINT cchSpecVersion,
1318 WCHAR *wzSpecVersion, UINT *pcchActual)
1320 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1322 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1324 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1325 cchSpecVersion, wzSpecVersion, pcchActual);
1328 static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *iface, UINT cchFriendlyName,
1329 WCHAR *wzFriendlyName, UINT *pcchActual)
1331 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1333 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1335 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1336 cchFriendlyName, wzFriendlyName, pcchActual);
1339 static HRESULT WINAPI PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface,
1340 GUID *pFormat)
1342 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1343 TRACE("(%p,%p)\n", iface, pFormat);
1345 if (!pFormat)
1346 return E_INVALIDARG;
1348 *pFormat = This->clsid;
1350 return S_OK;
1353 static HRESULT WINAPI PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2 *iface,
1354 IWICColorContext **ppIColorContext)
1356 FIXME("(%p,%p): stub\n", iface, ppIColorContext);
1357 return E_NOTIMPL;
1360 static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *iface,
1361 UINT *puiBitsPerPixel)
1363 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1365 TRACE("(%p,%p)\n", iface, puiBitsPerPixel);
1367 return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel);
1370 static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface,
1371 UINT *puiChannelCount)
1373 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1375 TRACE("(%p,%p)\n", iface, puiChannelCount);
1377 return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount);
1380 static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface,
1381 UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual)
1383 static const WCHAR uintformatW[] = {'%','u',0};
1384 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1385 UINT channel_count;
1386 HRESULT hr;
1387 LONG ret;
1388 WCHAR valuename[11];
1389 DWORD cbData;
1391 TRACE("(%p,%u,%u,%p,%p)\n", iface, uiChannelIndex, cbMaskBuffer, pbMaskBuffer, pcbActual);
1393 if (!pcbActual)
1394 return E_INVALIDARG;
1396 hr = PixelFormatInfo_GetChannelCount(iface, &channel_count);
1398 if (SUCCEEDED(hr) && uiChannelIndex >= channel_count)
1399 hr = E_INVALIDARG;
1401 if (SUCCEEDED(hr))
1403 snprintfW(valuename, 11, uintformatW, uiChannelIndex);
1405 cbData = cbMaskBuffer;
1407 ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData);
1409 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
1410 *pcbActual = cbData;
1412 if (ret == ERROR_MORE_DATA)
1413 hr = E_INVALIDARG;
1414 else
1415 hr = HRESULT_FROM_WIN32(ret);
1418 return hr;
1421 static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 *iface,
1422 BOOL *pfSupportsTransparency)
1424 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1426 TRACE("(%p,%p)\n", iface, pfSupportsTransparency);
1428 return ComponentInfo_GetDWORDValue(This->classkey, supportstransparency_valuename, (DWORD*)pfSupportsTransparency);
1431 static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface,
1432 WICPixelFormatNumericRepresentation *pNumericRepresentation)
1434 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1436 TRACE("(%p,%p)\n", iface, pNumericRepresentation);
1438 return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation);
1441 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = {
1442 PixelFormatInfo_QueryInterface,
1443 PixelFormatInfo_AddRef,
1444 PixelFormatInfo_Release,
1445 PixelFormatInfo_GetComponentType,
1446 PixelFormatInfo_GetCLSID,
1447 PixelFormatInfo_GetSigningStatus,
1448 PixelFormatInfo_GetAuthor,
1449 PixelFormatInfo_GetVendorGUID,
1450 PixelFormatInfo_GetVersion,
1451 PixelFormatInfo_GetSpecVersion,
1452 PixelFormatInfo_GetFriendlyName,
1453 PixelFormatInfo_GetFormatGUID,
1454 PixelFormatInfo_GetColorContext,
1455 PixelFormatInfo_GetBitsPerPixel,
1456 PixelFormatInfo_GetChannelCount,
1457 PixelFormatInfo_GetChannelMask,
1458 PixelFormatInfo_SupportsTransparency,
1459 PixelFormatInfo_GetNumericRepresentation
1462 static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1464 PixelFormatInfo *This;
1466 This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo));
1467 if (!This)
1469 RegCloseKey(classkey);
1470 return E_OUTOFMEMORY;
1473 This->IWICPixelFormatInfo2_iface.lpVtbl = &PixelFormatInfo_Vtbl;
1474 This->ref = 1;
1475 This->classkey = classkey;
1476 memcpy(&This->clsid, clsid, sizeof(CLSID));
1478 *ppIInfo = (IWICComponentInfo*)This;
1479 return S_OK;
1482 typedef struct
1484 IWICMetadataReaderInfo IWICMetadataReaderInfo_iface;
1485 LONG ref;
1486 HKEY classkey;
1487 CLSID clsid;
1488 } MetadataReaderInfo;
1490 static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo *iface)
1492 return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface);
1495 static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface,
1496 REFIID riid, void **ppv)
1498 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1500 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
1502 if (!ppv) return E_INVALIDARG;
1504 if (IsEqualIID(&IID_IUnknown, riid) ||
1505 IsEqualIID(&IID_IWICComponentInfo, riid) ||
1506 IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) ||
1507 IsEqualIID(&IID_IWICMetadataReaderInfo, riid))
1509 *ppv = This;
1511 else
1513 *ppv = NULL;
1514 return E_NOINTERFACE;
1517 IUnknown_AddRef((IUnknown *)*ppv);
1518 return S_OK;
1521 static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
1523 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1524 ULONG ref = InterlockedIncrement(&This->ref);
1526 TRACE("(%p) refcount=%u\n", iface, ref);
1527 return ref;
1530 static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface)
1532 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1533 ULONG ref = InterlockedDecrement(&This->ref);
1535 TRACE("(%p) refcount=%u\n", iface, ref);
1537 if (!ref)
1539 RegCloseKey(This->classkey);
1540 HeapFree(GetProcessHeap(), 0, This);
1542 return ref;
1545 static HRESULT WINAPI MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo *iface,
1546 WICComponentType *type)
1548 TRACE("(%p,%p)\n", iface, type);
1550 if (!type) return E_INVALIDARG;
1551 *type = WICMetadataReader;
1552 return S_OK;
1555 static HRESULT WINAPI MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface,
1556 CLSID *clsid)
1558 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1560 TRACE("(%p,%p)\n", iface, clsid);
1562 if (!clsid) return E_INVALIDARG;
1563 *clsid = This->clsid;
1564 return S_OK;
1567 static HRESULT WINAPI MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo *iface,
1568 DWORD *status)
1570 FIXME("(%p,%p): stub\n", iface, status);
1571 return E_NOTIMPL;
1574 static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface,
1575 UINT length, WCHAR *author, UINT *actual_length)
1577 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1579 TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length);
1581 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1582 length, author, actual_length);
1585 static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface,
1586 GUID *vendor)
1588 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1590 TRACE("(%p,%p)\n", iface, vendor);
1592 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, vendor);
1595 static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface,
1596 UINT length, WCHAR *version, UINT *actual_length)
1598 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1600 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1602 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1603 length, version, actual_length);
1606 static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface,
1607 UINT length, WCHAR *version, UINT *actual_length)
1609 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1611 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1613 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1614 length, version, actual_length);
1617 static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo *iface,
1618 UINT length, WCHAR *name, UINT *actual_length)
1620 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1622 TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length);
1624 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1625 length, name, actual_length);
1628 static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo *iface,
1629 GUID *format)
1631 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1632 TRACE("(%p,%p)\n", iface, format);
1633 return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format);
1636 static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface,
1637 UINT length, GUID *formats, UINT *actual_length)
1639 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1640 TRACE("(%p,%u,%p,%p)\n", iface, length, formats, actual_length);
1642 return ComponentInfo_GetGuidList(This->classkey, containers_keyname, length,
1643 formats, actual_length);
1646 static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo *iface,
1647 UINT length, WCHAR *manufacturer, UINT *actual_length)
1649 FIXME("(%p,%u,%p,%p): stub\n", iface, length, manufacturer, actual_length);
1650 return E_NOTIMPL;
1653 static HRESULT WINAPI MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo *iface,
1654 UINT length, WCHAR *models, UINT *actual_length)
1656 FIXME("(%p,%u,%p,%p): stub\n", iface, length, models, actual_length);
1657 return E_NOTIMPL;
1660 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo *iface,
1661 BOOL *param)
1663 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1664 TRACE("(%p,%p)\n", iface, param);
1665 return ComponentInfo_GetDWORDValue(This->classkey, requiresfullstream_valuename, (DWORD *)param);
1668 static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface,
1669 BOOL *param)
1671 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1672 TRACE("(%p,%p)\n", iface, param);
1673 return ComponentInfo_GetDWORDValue(This->classkey, supportspadding_valuename, (DWORD *)param);
1676 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface,
1677 BOOL *param)
1679 FIXME("(%p,%p): stub\n", iface, param);
1680 return E_NOTIMPL;
1683 static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface,
1684 REFGUID container, UINT length, WICMetadataPattern *patterns, UINT *count, UINT *actual_length)
1686 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1687 HRESULT hr=S_OK;
1688 LONG res;
1689 UINT pattern_count=0, patterns_size=0;
1690 DWORD valuesize, patternsize;
1691 BYTE *bPatterns=(BYTE*)patterns;
1692 HKEY containers_key, guid_key, pattern_key;
1693 WCHAR subkeyname[11];
1694 WCHAR guidkeyname[39];
1695 int i;
1696 static const WCHAR uintformatW[] = {'%','u',0};
1697 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
1698 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
1699 static const WCHAR maskW[] = {'M','a','s','k',0};
1700 static const WCHAR dataoffsetW[] = {'D','a','t','a','O','f','f','s','e','t',0};
1702 TRACE("(%p,%s,%u,%p,%p,%p)\n", iface, debugstr_guid(container), length, patterns, count, actual_length);
1704 if (!actual_length || !container) return E_INVALIDARG;
1706 res = RegOpenKeyExW(This->classkey, containers_keyname, 0, KEY_READ, &containers_key);
1707 if (res == ERROR_SUCCESS)
1709 StringFromGUID2(container, guidkeyname, 39);
1711 res = RegOpenKeyExW(containers_key, guidkeyname, 0, KEY_READ, &guid_key);
1712 if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND;
1713 else if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res);
1715 RegCloseKey(containers_key);
1717 else if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND;
1718 else hr = HRESULT_FROM_WIN32(res);
1720 if (SUCCEEDED(hr))
1722 res = RegQueryInfoKeyW(guid_key, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1723 if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res);
1725 if (SUCCEEDED(hr))
1727 patterns_size = pattern_count * sizeof(WICMetadataPattern);
1729 for (i=0; i<pattern_count; i++)
1731 snprintfW(subkeyname, 11, uintformatW, i);
1732 res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &pattern_key);
1733 if (res == ERROR_SUCCESS)
1735 res = RegGetValueW(pattern_key, NULL, patternW, RRF_RT_REG_BINARY, NULL,
1736 NULL, &patternsize);
1737 patterns_size += patternsize*2;
1739 if ((length >= patterns_size) && (res == ERROR_SUCCESS))
1741 patterns[i].Length = patternsize;
1743 patterns[i].DataOffset.QuadPart = 0;
1744 valuesize = sizeof(ULARGE_INTEGER);
1745 RegGetValueW(pattern_key, NULL, dataoffsetW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
1746 &patterns[i].DataOffset, &valuesize);
1748 patterns[i].Position.QuadPart = 0;
1749 valuesize = sizeof(ULARGE_INTEGER);
1750 res = RegGetValueW(pattern_key, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
1751 &patterns[i].Position, &valuesize);
1753 if (res == ERROR_SUCCESS)
1755 patterns[i].Pattern = bPatterns+patterns_size-patternsize*2;
1756 valuesize = patternsize;
1757 res = RegGetValueW(pattern_key, NULL, patternW, RRF_RT_REG_BINARY, NULL,
1758 patterns[i].Pattern, &valuesize);
1761 if (res == ERROR_SUCCESS)
1763 patterns[i].Mask = bPatterns+patterns_size-patternsize;
1764 valuesize = patternsize;
1765 res = RegGetValueW(pattern_key, NULL, maskW, RRF_RT_REG_BINARY, NULL,
1766 patterns[i].Mask, &valuesize);
1770 RegCloseKey(pattern_key);
1772 if (res != ERROR_SUCCESS)
1774 hr = HRESULT_FROM_WIN32(res);
1775 break;
1780 RegCloseKey(guid_key);
1783 if (hr == S_OK)
1785 *count = pattern_count;
1786 *actual_length = patterns_size;
1787 if (patterns && length < patterns_size)
1788 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
1791 return hr;
1794 static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface,
1795 REFGUID container, IStream *stream, BOOL *matches)
1797 HRESULT hr;
1798 WICMetadataPattern *patterns;
1799 UINT pattern_count=0, patterns_size=0;
1800 ULONG datasize=0;
1801 BYTE *data=NULL;
1802 ULONG bytesread;
1803 UINT i;
1804 LARGE_INTEGER seekpos;
1805 ULONG pos;
1807 TRACE("(%p,%s,%p,%p)\n", iface, debugstr_guid(container), stream, matches);
1809 hr = MetadataReaderInfo_GetPatterns(iface, container, 0, NULL, &pattern_count, &patterns_size);
1810 if (FAILED(hr)) return hr;
1812 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
1813 if (!patterns) return E_OUTOFMEMORY;
1815 hr = MetadataReaderInfo_GetPatterns(iface, container, patterns_size, patterns, &pattern_count, &patterns_size);
1816 if (FAILED(hr)) goto end;
1818 for (i=0; i<pattern_count; i++)
1820 if (datasize < patterns[i].Length)
1822 HeapFree(GetProcessHeap(), 0, data);
1823 datasize = patterns[i].Length;
1824 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
1825 if (!data)
1827 hr = E_OUTOFMEMORY;
1828 break;
1832 seekpos.QuadPart = patterns[i].Position.QuadPart;
1833 hr = IStream_Seek(stream, seekpos, STREAM_SEEK_SET, NULL);
1834 if (FAILED(hr)) break;
1836 hr = IStream_Read(stream, data, patterns[i].Length, &bytesread);
1837 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
1838 continue;
1839 if (FAILED(hr)) break;
1841 for (pos=0; pos<patterns[i].Length; pos++)
1843 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
1844 break;
1846 if (pos == patterns[i].Length) /* matches pattern */
1848 hr = S_OK;
1849 *matches = TRUE;
1850 break;
1854 if (i == pattern_count) /* does not match any pattern */
1856 hr = S_OK;
1857 *matches = FALSE;
1860 end:
1861 HeapFree(GetProcessHeap(), 0, patterns);
1862 HeapFree(GetProcessHeap(), 0, data);
1864 return hr;
1867 static HRESULT WINAPI MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *iface,
1868 IWICMetadataReader **reader)
1870 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1872 TRACE("(%p,%p)\n", iface, reader);
1874 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1875 &IID_IWICMetadataReader, (void **)reader);
1878 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = {
1879 MetadataReaderInfo_QueryInterface,
1880 MetadataReaderInfo_AddRef,
1881 MetadataReaderInfo_Release,
1882 MetadataReaderInfo_GetComponentType,
1883 MetadataReaderInfo_GetCLSID,
1884 MetadataReaderInfo_GetSigningStatus,
1885 MetadataReaderInfo_GetAuthor,
1886 MetadataReaderInfo_GetVendorGUID,
1887 MetadataReaderInfo_GetVersion,
1888 MetadataReaderInfo_GetSpecVersion,
1889 MetadataReaderInfo_GetFriendlyName,
1890 MetadataReaderInfo_GetMetadataFormat,
1891 MetadataReaderInfo_GetContainerFormats,
1892 MetadataReaderInfo_GetDeviceManufacturer,
1893 MetadataReaderInfo_GetDeviceModels,
1894 MetadataReaderInfo_DoesRequireFullStream,
1895 MetadataReaderInfo_DoesSupportPadding,
1896 MetadataReaderInfo_DoesRequireFixedSize,
1897 MetadataReaderInfo_GetPatterns,
1898 MetadataReaderInfo_MatchesPattern,
1899 MetadataReaderInfo_CreateInstance
1902 static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **info)
1904 MetadataReaderInfo *This;
1906 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1907 if (!This)
1909 RegCloseKey(classkey);
1910 return E_OUTOFMEMORY;
1913 This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl;
1914 This->ref = 1;
1915 This->classkey = classkey;
1916 This->clsid = *clsid;
1918 *info = (IWICComponentInfo *)This;
1919 return S_OK;
1922 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
1923 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
1925 struct category {
1926 WICComponentType type;
1927 const GUID *catid;
1928 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
1931 static const struct category categories[] = {
1932 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
1933 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
1934 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
1935 {WICPixelFormat, &CATID_WICPixelFormats, PixelFormatInfo_Constructor},
1936 {WICMetadataReader, &CATID_WICMetadataReader, MetadataReaderInfo_Constructor},
1940 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
1942 HKEY clsidkey;
1943 HKEY classkey;
1944 HKEY catidkey;
1945 HKEY instancekey;
1946 WCHAR guidstring[39];
1947 LONG res;
1948 const struct category *category;
1949 BOOL found = FALSE;
1950 HRESULT hr;
1952 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1953 if (res != ERROR_SUCCESS)
1954 return HRESULT_FROM_WIN32(res);
1956 for (category=categories; category->type; category++)
1958 StringFromGUID2(category->catid, guidstring, 39);
1959 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1960 if (res == ERROR_SUCCESS)
1962 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1963 if (res == ERROR_SUCCESS)
1965 StringFromGUID2(clsid, guidstring, 39);
1966 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
1967 if (res == ERROR_SUCCESS)
1969 RegCloseKey(classkey);
1970 found = TRUE;
1972 RegCloseKey(instancekey);
1974 RegCloseKey(catidkey);
1976 if (found) break;
1979 if (found)
1981 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
1982 if (res == ERROR_SUCCESS)
1983 hr = category->constructor(classkey, clsid, ppIInfo);
1984 else
1985 hr = HRESULT_FROM_WIN32(res);
1987 else
1989 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid));
1990 hr = E_FAIL;
1993 RegCloseKey(clsidkey);
1995 return hr;
1998 typedef struct {
1999 IEnumUnknown IEnumUnknown_iface;
2000 LONG ref;
2001 struct list objects;
2002 struct list *cursor;
2003 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
2004 } ComponentEnum;
2006 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
2008 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
2011 typedef struct {
2012 struct list entry;
2013 IUnknown *unk;
2014 } ComponentEnumItem;
2016 static const IEnumUnknownVtbl ComponentEnumVtbl;
2018 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
2019 void **ppv)
2021 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2022 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
2024 if (!ppv) return E_INVALIDARG;
2026 if (IsEqualIID(&IID_IUnknown, iid) ||
2027 IsEqualIID(&IID_IEnumUnknown, iid))
2029 *ppv = &This->IEnumUnknown_iface;
2031 else
2033 *ppv = NULL;
2034 return E_NOINTERFACE;
2037 IUnknown_AddRef((IUnknown*)*ppv);
2038 return S_OK;
2041 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
2043 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2044 ULONG ref = InterlockedIncrement(&This->ref);
2046 TRACE("(%p) refcount=%u\n", iface, ref);
2048 return ref;
2051 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
2053 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2054 ULONG ref = InterlockedDecrement(&This->ref);
2055 ComponentEnumItem *cursor, *cursor2;
2057 TRACE("(%p) refcount=%u\n", iface, ref);
2059 if (ref == 0)
2061 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
2063 IUnknown_Release(cursor->unk);
2064 list_remove(&cursor->entry);
2065 HeapFree(GetProcessHeap(), 0, cursor);
2067 This->lock.DebugInfo->Spare[0] = 0;
2068 DeleteCriticalSection(&This->lock);
2069 HeapFree(GetProcessHeap(), 0, This);
2072 return ref;
2075 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
2076 IUnknown **rgelt, ULONG *pceltFetched)
2078 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2079 ULONG num_fetched=0;
2080 ComponentEnumItem *item;
2081 HRESULT hr=S_OK;
2083 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
2085 EnterCriticalSection(&This->lock);
2086 while (num_fetched<celt)
2088 if (!This->cursor)
2090 hr = S_FALSE;
2091 break;
2093 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
2094 IUnknown_AddRef(item->unk);
2095 rgelt[num_fetched] = item->unk;
2096 num_fetched++;
2097 This->cursor = list_next(&This->objects, This->cursor);
2099 LeaveCriticalSection(&This->lock);
2100 if (pceltFetched)
2101 *pceltFetched = num_fetched;
2102 return hr;
2105 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
2107 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2108 ULONG i;
2109 HRESULT hr=S_OK;
2111 TRACE("(%p,%u)\n", iface, celt);
2113 EnterCriticalSection(&This->lock);
2114 for (i=0; i<celt; i++)
2116 if (!This->cursor)
2118 hr = S_FALSE;
2119 break;
2121 This->cursor = list_next(&This->objects, This->cursor);
2123 LeaveCriticalSection(&This->lock);
2124 return hr;
2127 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
2129 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2131 TRACE("(%p)\n", iface);
2133 EnterCriticalSection(&This->lock);
2134 This->cursor = list_head(&This->objects);
2135 LeaveCriticalSection(&This->lock);
2136 return S_OK;
2139 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
2141 ComponentEnum *This = impl_from_IEnumUnknown(iface);
2142 ComponentEnum *new_enum;
2143 ComponentEnumItem *old_item, *new_item;
2144 HRESULT ret=S_OK;
2145 struct list *old_cursor;
2147 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
2148 if (!new_enum)
2150 *ppenum = NULL;
2151 return E_OUTOFMEMORY;
2154 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
2155 new_enum->ref = 1;
2156 new_enum->cursor = NULL;
2157 list_init(&new_enum->objects);
2158 InitializeCriticalSection(&new_enum->lock);
2159 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
2161 EnterCriticalSection(&This->lock);
2162 old_cursor = This->cursor;
2163 LeaveCriticalSection(&This->lock);
2165 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
2167 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
2168 if (!new_item)
2170 ret = E_OUTOFMEMORY;
2171 break;
2173 new_item->unk = old_item->unk;
2174 list_add_tail(&new_enum->objects, &new_item->entry);
2175 IUnknown_AddRef(new_item->unk);
2176 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
2179 if (FAILED(ret))
2181 IEnumUnknown_Release(&new_enum->IEnumUnknown_iface);
2182 *ppenum = NULL;
2184 else
2185 *ppenum = &new_enum->IEnumUnknown_iface;
2187 return ret;
2190 static const IEnumUnknownVtbl ComponentEnumVtbl = {
2191 ComponentEnum_QueryInterface,
2192 ComponentEnum_AddRef,
2193 ComponentEnum_Release,
2194 ComponentEnum_Next,
2195 ComponentEnum_Skip,
2196 ComponentEnum_Reset,
2197 ComponentEnum_Clone
2200 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
2202 ComponentEnum *This;
2203 ComponentEnumItem *item;
2204 const struct category *category;
2205 HKEY clsidkey, catidkey, instancekey;
2206 WCHAR guidstring[39];
2207 LONG res;
2208 int i;
2209 HRESULT hr=S_OK;
2210 CLSID clsid;
2212 if (options) FIXME("ignoring flags %x\n", options);
2214 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
2215 if (res != ERROR_SUCCESS)
2216 return HRESULT_FROM_WIN32(res);
2218 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
2219 if (!This)
2221 RegCloseKey(clsidkey);
2222 return E_OUTOFMEMORY;
2225 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
2226 This->ref = 1;
2227 list_init(&This->objects);
2228 InitializeCriticalSection(&This->lock);
2229 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
2231 for (category=categories; category->type && hr == S_OK; category++)
2233 if ((category->type & componentTypes) == 0) continue;
2234 StringFromGUID2(category->catid, guidstring, 39);
2235 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
2236 if (res == ERROR_SUCCESS)
2238 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
2239 if (res == ERROR_SUCCESS)
2241 i=0;
2242 for (;;i++)
2244 DWORD guidstring_size = 39;
2245 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
2246 if (res != ERROR_SUCCESS) break;
2248 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
2249 if (!item) { hr = E_OUTOFMEMORY; break; }
2251 hr = CLSIDFromString(guidstring, &clsid);
2252 if (SUCCEEDED(hr))
2254 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
2255 if (SUCCEEDED(hr))
2256 list_add_tail(&This->objects, &item->entry);
2259 if (FAILED(hr))
2261 HeapFree(GetProcessHeap(), 0, item);
2262 hr = S_OK;
2265 RegCloseKey(instancekey);
2267 RegCloseKey(catidkey);
2269 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
2270 hr = HRESULT_FROM_WIN32(res);
2272 RegCloseKey(clsidkey);
2274 if (SUCCEEDED(hr))
2276 IEnumUnknown_Reset(&This->IEnumUnknown_iface);
2277 *ppIEnumUnknown = &This->IEnumUnknown_iface;
2279 else
2281 *ppIEnumUnknown = NULL;
2282 IEnumUnknown_Release(&This->IEnumUnknown_iface);
2285 return hr;
2288 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
2290 HRESULT res;
2291 IEnumUnknown *enumconverters;
2292 IUnknown *unkconverterinfo;
2293 IWICFormatConverterInfo *converterinfo=NULL;
2294 IWICFormatConverter *converter=NULL;
2295 GUID srcFormat;
2296 WCHAR srcformatstr[39], dstformatstr[39];
2297 BOOL canconvert;
2298 ULONG num_fetched;
2300 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
2301 if (FAILED(res)) return res;
2303 if (IsEqualGUID(&srcFormat, dstFormat))
2305 IWICBitmapSource_AddRef(pISrc);
2306 *ppIDst = pISrc;
2307 return S_OK;
2310 StringFromGUID2(&srcFormat, srcformatstr, 39);
2311 StringFromGUID2(dstFormat, dstformatstr, 39);
2313 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
2314 if (FAILED(res)) return res;
2316 while (!converter)
2318 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);
2320 if (res == S_OK)
2322 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);
2324 if (SUCCEEDED(res))
2326 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);
2328 if (canconvert)
2329 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);
2331 if (canconvert)
2333 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);
2335 if (SUCCEEDED(res))
2336 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);
2338 if (SUCCEEDED(res) && canconvert)
2339 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
2340 NULL, 0.0, WICBitmapPaletteTypeCustom);
2342 if (FAILED(res) || !canconvert)
2344 if (converter)
2346 IWICFormatConverter_Release(converter);
2347 converter = NULL;
2349 res = S_OK;
2353 IWICFormatConverterInfo_Release(converterinfo);
2356 IUnknown_Release(unkconverterinfo);
2358 else
2359 break;
2362 IEnumUnknown_Release(enumconverters);
2364 if (converter)
2366 res = IWICFormatConverter_QueryInterface(converter, &IID_IWICBitmapSource, (void **)ppIDst);
2367 IWICFormatConverter_Release(converter);
2368 return res;
2370 else
2372 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
2373 *ppIDst = NULL;
2374 return WINCODEC_ERR_COMPONENTNOTFOUND;