ntdll: Check for invalid %gs value in 32-bit code.
[wine/multimedia.git] / dlls / windowscodecs / info.c
blob3da5b2074160ee1b84a8d5b83fd869340b635a23
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};
60 static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value,
61 UINT buffer_size, WCHAR *buffer, UINT *actual_size)
63 LONG ret;
64 DWORD cbdata=buffer_size * sizeof(WCHAR);
66 if (!actual_size)
67 return E_INVALIDARG;
69 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
70 buffer, &cbdata);
72 if (ret == ERROR_FILE_NOT_FOUND)
74 *actual_size = 0;
75 return S_OK;
78 if (ret == 0 || ret == ERROR_MORE_DATA)
79 *actual_size = cbdata/sizeof(WCHAR);
81 if (!buffer && buffer_size != 0)
82 /* Yes, native returns the correct size in this case. */
83 return E_INVALIDARG;
85 if (ret == ERROR_MORE_DATA)
86 return WINCODEC_ERR_INSUFFICIENTBUFFER;
88 return HRESULT_FROM_WIN32(ret);
91 static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value,
92 GUID *result)
94 LONG ret;
95 WCHAR guid_string[39];
96 DWORD cbdata = sizeof(guid_string);
97 HRESULT hr;
99 if (!result)
100 return E_INVALIDARG;
102 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
103 guid_string, &cbdata);
105 if (ret != ERROR_SUCCESS)
106 return HRESULT_FROM_WIN32(ret);
108 if (cbdata < sizeof(guid_string))
110 ERR("incomplete GUID value\n");
111 return E_FAIL;
114 hr = CLSIDFromString(guid_string, result);
116 return hr;
119 static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value,
120 DWORD *result)
122 LONG ret;
123 DWORD cbdata = sizeof(DWORD);
125 if (!result)
126 return E_INVALIDARG;
128 ret = RegGetValueW(classkey, NULL, value, RRF_RT_DWORD, NULL,
129 result, &cbdata);
131 if (ret == ERROR_FILE_NOT_FOUND)
133 *result = 0;
134 return S_OK;
137 return HRESULT_FROM_WIN32(ret);
140 static HRESULT ComponentInfo_GetGuidList(HKEY classkey, LPCWSTR subkeyname,
141 UINT buffersize, GUID *buffer, UINT *actual_size)
143 LONG ret;
144 HKEY subkey;
145 UINT items_returned;
146 WCHAR guid_string[39];
147 DWORD guid_string_size;
148 HRESULT hr=S_OK;
150 if (!actual_size)
151 return E_INVALIDARG;
153 ret = RegOpenKeyExW(classkey, subkeyname, 0, KEY_READ, &subkey);
154 if (ret != ERROR_SUCCESS) return HRESULT_FROM_WIN32(ret);
156 if (buffer)
158 items_returned = 0;
159 guid_string_size = 39;
160 while (items_returned < buffersize)
162 ret = RegEnumKeyExW(subkey, items_returned, guid_string,
163 &guid_string_size, NULL, NULL, NULL, NULL);
165 if (ret != ERROR_SUCCESS)
167 hr = HRESULT_FROM_WIN32(ret);
168 break;
171 if (guid_string_size != 38)
173 hr = E_FAIL;
174 break;
177 hr = CLSIDFromString(guid_string, &buffer[items_returned]);
178 if (FAILED(hr))
179 break;
181 items_returned++;
182 guid_string_size = 39;
185 if (ret == ERROR_NO_MORE_ITEMS)
186 hr = S_OK;
188 *actual_size = items_returned;
190 else
192 ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, actual_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
193 if (ret != ERROR_SUCCESS)
194 hr = HRESULT_FROM_WIN32(ret);
197 RegCloseKey(subkey);
199 return hr;
202 typedef struct {
203 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface;
204 LONG ref;
205 HKEY classkey;
206 CLSID clsid;
207 } BitmapDecoderInfo;
209 static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo *iface)
211 return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface);
214 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid,
215 void **ppv)
217 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
218 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
220 if (!ppv) return E_INVALIDARG;
222 if (IsEqualIID(&IID_IUnknown, iid) ||
223 IsEqualIID(&IID_IWICComponentInfo, iid) ||
224 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
225 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
227 *ppv = This;
229 else
231 *ppv = NULL;
232 return E_NOINTERFACE;
235 IUnknown_AddRef((IUnknown*)*ppv);
236 return S_OK;
239 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
241 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
242 ULONG ref = InterlockedIncrement(&This->ref);
244 TRACE("(%p) refcount=%u\n", iface, ref);
246 return ref;
249 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
251 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
252 ULONG ref = InterlockedDecrement(&This->ref);
254 TRACE("(%p) refcount=%u\n", iface, ref);
256 if (ref == 0)
258 RegCloseKey(This->classkey);
259 HeapFree(GetProcessHeap(), 0, This);
262 return ref;
265 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface,
266 WICComponentType *pType)
268 TRACE("(%p,%p)\n", iface, pType);
269 if (!pType) return E_INVALIDARG;
270 *pType = WICDecoder;
271 return S_OK;
274 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid)
276 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
277 TRACE("(%p,%p)\n", iface, pclsid);
279 if (!pclsid)
280 return E_INVALIDARG;
282 memcpy(pclsid, &This->clsid, sizeof(CLSID));
284 return S_OK;
287 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus)
289 FIXME("(%p,%p): stub\n", iface, pStatus);
290 return E_NOTIMPL;
293 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor,
294 WCHAR *wzAuthor, UINT *pcchActual)
296 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
298 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
300 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
301 cchAuthor, wzAuthor, pcchActual);
304 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
306 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
308 TRACE("(%p,%p)\n", iface, pguidVendor);
310 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
313 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
314 WCHAR *wzVersion, UINT *pcchActual)
316 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
318 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
320 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
321 cchVersion, wzVersion, pcchActual);
324 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
325 WCHAR *wzSpecVersion, UINT *pcchActual)
327 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
329 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
331 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
332 cchSpecVersion, wzSpecVersion, pcchActual);
335 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
336 WCHAR *wzFriendlyName, UINT *pcchActual)
338 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
340 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
342 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
343 cchFriendlyName, wzFriendlyName, pcchActual);
346 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
347 GUID *pguidContainerFormat)
349 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
350 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
351 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
354 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
355 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
357 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
358 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
359 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
362 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface,
363 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
365 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
366 return E_NOTIMPL;
369 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface,
370 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
372 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
373 return E_NOTIMPL;
376 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface,
377 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
379 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
380 return E_NOTIMPL;
383 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface,
384 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
386 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
388 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
390 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
391 cchMimeTypes, wzMimeTypes, pcchActual);
394 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface,
395 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
397 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
399 TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
401 return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename,
402 cchFileExtensions, wzFileExtensions, pcchActual);
405 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface,
406 BOOL *pfSupportAnimation)
408 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
409 return E_NOTIMPL;
412 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface,
413 BOOL *pfSupportChromaKey)
415 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
416 return E_NOTIMPL;
419 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface,
420 BOOL *pfSupportLossless)
422 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
423 return E_NOTIMPL;
426 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface,
427 BOOL *pfSupportMultiframe)
429 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
430 return E_NOTIMPL;
433 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface,
434 LPCWSTR wzMimeType, BOOL *pfMatches)
436 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
437 return E_NOTIMPL;
440 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface,
441 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual)
443 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
444 UINT pattern_count=0, patterns_size=0;
445 WCHAR subkeyname[11];
446 LONG res;
447 HKEY patternskey, patternkey;
448 static const WCHAR uintformatW[] = {'%','u',0};
449 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0};
450 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
451 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0};
452 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
453 static const WCHAR maskW[] = {'M','a','s','k',0};
454 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
455 HRESULT hr=S_OK;
456 UINT i;
457 BYTE *bPatterns=(BYTE*)pPatterns;
458 DWORD length, valuesize;
460 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual);
462 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
463 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
465 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
466 if (res == ERROR_SUCCESS)
468 patterns_size = pattern_count * sizeof(WICBitmapPattern);
470 for (i=0; i<pattern_count; i++)
472 snprintfW(subkeyname, 11, uintformatW, i);
473 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
474 if (res == ERROR_SUCCESS)
476 valuesize = sizeof(ULONG);
477 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
478 &length, &valuesize);
479 patterns_size += length*2;
481 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS))
483 pPatterns[i].Length = length;
485 pPatterns[i].EndOfStream = 0;
486 valuesize = sizeof(BOOL);
487 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
488 &pPatterns[i].EndOfStream, &valuesize);
490 pPatterns[i].Position.QuadPart = 0;
491 valuesize = sizeof(ULARGE_INTEGER);
492 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
493 &pPatterns[i].Position, &valuesize);
495 if (res == ERROR_SUCCESS)
497 pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
498 valuesize = length;
499 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
500 pPatterns[i].Pattern, &valuesize);
503 if (res == ERROR_SUCCESS)
505 pPatterns[i].Mask = bPatterns+patterns_size-length;
506 valuesize = length;
507 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
508 pPatterns[i].Mask, &valuesize);
512 RegCloseKey(patternkey);
514 if (res != ERROR_SUCCESS)
516 hr = HRESULT_FROM_WIN32(res);
517 break;
521 else hr = HRESULT_FROM_WIN32(res);
523 RegCloseKey(patternskey);
525 if (hr == S_OK)
527 *pcPatterns = pattern_count;
528 *pcbPatternsActual = patterns_size;
529 if (pPatterns && cbSizePatterns < patterns_size)
530 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
533 return hr;
536 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
537 IStream *pIStream, BOOL *pfMatches)
539 WICBitmapPattern *patterns;
540 UINT pattern_count=0, patterns_size=0;
541 HRESULT hr;
542 int i, pos;
543 BYTE *data=NULL;
544 ULONG datasize=0;
545 ULONG bytesread;
546 LARGE_INTEGER seekpos;
548 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
550 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
551 if (FAILED(hr)) return hr;
553 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
554 if (!patterns) return E_OUTOFMEMORY;
556 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
557 if (FAILED(hr)) goto end;
559 for (i=0; i<pattern_count; i++)
561 if (datasize < patterns[i].Length)
563 HeapFree(GetProcessHeap(), 0, data);
564 datasize = patterns[i].Length;
565 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
566 if (!data)
568 hr = E_OUTOFMEMORY;
569 break;
573 if (patterns[i].EndOfStream)
574 seekpos.QuadPart = -patterns[i].Position.QuadPart;
575 else
576 seekpos.QuadPart = patterns[i].Position.QuadPart;
577 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
578 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
579 if (FAILED(hr)) break;
581 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
582 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
583 continue;
584 if (FAILED(hr)) break;
586 for (pos=0; pos<patterns[i].Length; pos++)
588 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
589 break;
591 if (pos == patterns[i].Length) /* matches pattern */
593 hr = S_OK;
594 *pfMatches = TRUE;
595 break;
599 if (i == pattern_count) /* does not match any pattern */
601 hr = S_OK;
602 *pfMatches = FALSE;
605 end:
606 HeapFree(GetProcessHeap(), 0, patterns);
607 HeapFree(GetProcessHeap(), 0, data);
609 return hr;
612 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
613 IWICBitmapDecoder **ppIBitmapDecoder)
615 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
617 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
619 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
620 &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
623 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
624 BitmapDecoderInfo_QueryInterface,
625 BitmapDecoderInfo_AddRef,
626 BitmapDecoderInfo_Release,
627 BitmapDecoderInfo_GetComponentType,
628 BitmapDecoderInfo_GetCLSID,
629 BitmapDecoderInfo_GetSigningStatus,
630 BitmapDecoderInfo_GetAuthor,
631 BitmapDecoderInfo_GetVendorGUID,
632 BitmapDecoderInfo_GetVersion,
633 BitmapDecoderInfo_GetSpecVersion,
634 BitmapDecoderInfo_GetFriendlyName,
635 BitmapDecoderInfo_GetContainerFormat,
636 BitmapDecoderInfo_GetPixelFormats,
637 BitmapDecoderInfo_GetColorManagementVersion,
638 BitmapDecoderInfo_GetDeviceManufacturer,
639 BitmapDecoderInfo_GetDeviceModels,
640 BitmapDecoderInfo_GetMimeTypes,
641 BitmapDecoderInfo_GetFileExtensions,
642 BitmapDecoderInfo_DoesSupportAnimation,
643 BitmapDecoderInfo_DoesSupportChromaKey,
644 BitmapDecoderInfo_DoesSupportLossless,
645 BitmapDecoderInfo_DoesSupportMultiframe,
646 BitmapDecoderInfo_MatchesMimeType,
647 BitmapDecoderInfo_GetPatterns,
648 BitmapDecoderInfo_MatchesPattern,
649 BitmapDecoderInfo_CreateInstance
652 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
654 BitmapDecoderInfo *This;
656 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
657 if (!This)
659 RegCloseKey(classkey);
660 return E_OUTOFMEMORY;
663 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
664 This->ref = 1;
665 This->classkey = classkey;
666 memcpy(&This->clsid, clsid, sizeof(CLSID));
668 *ppIInfo = (IWICComponentInfo*)This;
669 return S_OK;
672 typedef struct {
673 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
674 LONG ref;
675 HKEY classkey;
676 CLSID clsid;
677 } BitmapEncoderInfo;
679 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
681 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
684 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
685 void **ppv)
687 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
688 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
690 if (!ppv) return E_INVALIDARG;
692 if (IsEqualIID(&IID_IUnknown, iid) ||
693 IsEqualIID(&IID_IWICComponentInfo, iid) ||
694 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
695 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
697 *ppv = This;
699 else
701 *ppv = NULL;
702 return E_NOINTERFACE;
705 IUnknown_AddRef((IUnknown*)*ppv);
706 return S_OK;
709 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
711 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
712 ULONG ref = InterlockedIncrement(&This->ref);
714 TRACE("(%p) refcount=%u\n", iface, ref);
716 return ref;
719 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
721 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
722 ULONG ref = InterlockedDecrement(&This->ref);
724 TRACE("(%p) refcount=%u\n", iface, ref);
726 if (ref == 0)
728 RegCloseKey(This->classkey);
729 HeapFree(GetProcessHeap(), 0, This);
732 return ref;
735 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
736 WICComponentType *pType)
738 TRACE("(%p,%p)\n", iface, pType);
739 if (!pType) return E_INVALIDARG;
740 *pType = WICEncoder;
741 return S_OK;
744 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
746 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
747 TRACE("(%p,%p)\n", iface, pclsid);
749 if (!pclsid)
750 return E_INVALIDARG;
752 memcpy(pclsid, &This->clsid, sizeof(CLSID));
754 return S_OK;
757 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
759 FIXME("(%p,%p): stub\n", iface, pStatus);
760 return E_NOTIMPL;
763 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
764 WCHAR *wzAuthor, UINT *pcchActual)
766 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
768 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
770 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
771 cchAuthor, wzAuthor, pcchActual);
774 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
776 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
778 TRACE("(%p,%p)\n", iface, pguidVendor);
780 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
783 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
784 WCHAR *wzVersion, UINT *pcchActual)
786 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
788 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
790 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
791 cchVersion, wzVersion, pcchActual);
794 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
795 WCHAR *wzSpecVersion, UINT *pcchActual)
797 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
799 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
801 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
802 cchSpecVersion, wzSpecVersion, pcchActual);
805 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
806 WCHAR *wzFriendlyName, UINT *pcchActual)
808 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
810 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
812 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
813 cchFriendlyName, wzFriendlyName, pcchActual);
816 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
817 GUID *pguidContainerFormat)
819 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
820 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
821 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
824 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
825 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
827 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
828 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
829 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
832 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
833 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
835 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
836 return E_NOTIMPL;
839 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
840 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
842 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
843 return E_NOTIMPL;
846 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
847 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
849 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
850 return E_NOTIMPL;
853 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
854 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
856 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
858 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
860 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
861 cchMimeTypes, wzMimeTypes, pcchActual);
864 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
865 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
867 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
868 return E_NOTIMPL;
871 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
872 BOOL *pfSupportAnimation)
874 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
875 return E_NOTIMPL;
878 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
879 BOOL *pfSupportChromaKey)
881 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
882 return E_NOTIMPL;
885 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
886 BOOL *pfSupportLossless)
888 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
889 return E_NOTIMPL;
892 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
893 BOOL *pfSupportMultiframe)
895 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
896 return E_NOTIMPL;
899 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
900 LPCWSTR wzMimeType, BOOL *pfMatches)
902 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
903 return E_NOTIMPL;
906 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
907 IWICBitmapEncoder **ppIBitmapEncoder)
909 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
911 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
913 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
914 &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
917 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
918 BitmapEncoderInfo_QueryInterface,
919 BitmapEncoderInfo_AddRef,
920 BitmapEncoderInfo_Release,
921 BitmapEncoderInfo_GetComponentType,
922 BitmapEncoderInfo_GetCLSID,
923 BitmapEncoderInfo_GetSigningStatus,
924 BitmapEncoderInfo_GetAuthor,
925 BitmapEncoderInfo_GetVendorGUID,
926 BitmapEncoderInfo_GetVersion,
927 BitmapEncoderInfo_GetSpecVersion,
928 BitmapEncoderInfo_GetFriendlyName,
929 BitmapEncoderInfo_GetContainerFormat,
930 BitmapEncoderInfo_GetPixelFormats,
931 BitmapEncoderInfo_GetColorManagementVersion,
932 BitmapEncoderInfo_GetDeviceManufacturer,
933 BitmapEncoderInfo_GetDeviceModels,
934 BitmapEncoderInfo_GetMimeTypes,
935 BitmapEncoderInfo_GetFileExtensions,
936 BitmapEncoderInfo_DoesSupportAnimation,
937 BitmapEncoderInfo_DoesSupportChromaKey,
938 BitmapEncoderInfo_DoesSupportLossless,
939 BitmapEncoderInfo_DoesSupportMultiframe,
940 BitmapEncoderInfo_MatchesMimeType,
941 BitmapEncoderInfo_CreateInstance
944 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
946 BitmapEncoderInfo *This;
948 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
949 if (!This)
951 RegCloseKey(classkey);
952 return E_OUTOFMEMORY;
955 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
956 This->ref = 1;
957 This->classkey = classkey;
958 memcpy(&This->clsid, clsid, sizeof(CLSID));
960 *ppIInfo = (IWICComponentInfo*)This;
961 return S_OK;
964 typedef struct {
965 IWICFormatConverterInfo IWICFormatConverterInfo_iface;
966 LONG ref;
967 HKEY classkey;
968 CLSID clsid;
969 } FormatConverterInfo;
971 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
973 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
976 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
977 void **ppv)
979 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
980 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
982 if (!ppv) return E_INVALIDARG;
984 if (IsEqualIID(&IID_IUnknown, iid) ||
985 IsEqualIID(&IID_IWICComponentInfo, iid) ||
986 IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
988 *ppv = This;
990 else
992 *ppv = NULL;
993 return E_NOINTERFACE;
996 IUnknown_AddRef((IUnknown*)*ppv);
997 return S_OK;
1000 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
1002 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1003 ULONG ref = InterlockedIncrement(&This->ref);
1005 TRACE("(%p) refcount=%u\n", iface, ref);
1007 return ref;
1010 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
1012 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1013 ULONG ref = InterlockedDecrement(&This->ref);
1015 TRACE("(%p) refcount=%u\n", iface, ref);
1017 if (ref == 0)
1019 RegCloseKey(This->classkey);
1020 HeapFree(GetProcessHeap(), 0, This);
1023 return ref;
1026 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
1027 WICComponentType *pType)
1029 TRACE("(%p,%p)\n", iface, pType);
1030 if (!pType) return E_INVALIDARG;
1031 *pType = WICPixelFormatConverter;
1032 return S_OK;
1035 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
1037 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1038 TRACE("(%p,%p)\n", iface, pclsid);
1040 if (!pclsid)
1041 return E_INVALIDARG;
1043 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1045 return S_OK;
1048 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
1050 FIXME("(%p,%p): stub\n", iface, pStatus);
1051 return E_NOTIMPL;
1054 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
1055 WCHAR *wzAuthor, UINT *pcchActual)
1057 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1059 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1061 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1062 cchAuthor, wzAuthor, pcchActual);
1065 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
1067 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1069 TRACE("(%p,%p)\n", iface, pguidVendor);
1071 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1074 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
1075 WCHAR *wzVersion, UINT *pcchActual)
1077 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1079 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1081 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1082 cchVersion, wzVersion, pcchActual);
1085 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
1086 WCHAR *wzSpecVersion, UINT *pcchActual)
1088 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1090 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1092 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1093 cchSpecVersion, wzSpecVersion, pcchActual);
1096 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
1097 WCHAR *wzFriendlyName, UINT *pcchActual)
1099 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1101 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1103 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1104 cchFriendlyName, wzFriendlyName, pcchActual);
1107 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
1108 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
1110 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
1111 return E_NOTIMPL;
1114 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
1115 IWICFormatConverter **ppIFormatConverter)
1117 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1119 TRACE("(%p,%p)\n", iface, ppIFormatConverter);
1121 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1122 &IID_IWICFormatConverter, (void**)ppIFormatConverter);
1125 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
1127 LONG res;
1128 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1129 HKEY formats_key, guid_key;
1131 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
1132 would be O(n). A registry test should do better. */
1134 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
1135 if (res != ERROR_SUCCESS) return FALSE;
1137 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
1138 if (res == ERROR_SUCCESS) RegCloseKey(guid_key);
1140 RegCloseKey(formats_key);
1142 return (res == ERROR_SUCCESS);
1145 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
1146 FormatConverterInfo_QueryInterface,
1147 FormatConverterInfo_AddRef,
1148 FormatConverterInfo_Release,
1149 FormatConverterInfo_GetComponentType,
1150 FormatConverterInfo_GetCLSID,
1151 FormatConverterInfo_GetSigningStatus,
1152 FormatConverterInfo_GetAuthor,
1153 FormatConverterInfo_GetVendorGUID,
1154 FormatConverterInfo_GetVersion,
1155 FormatConverterInfo_GetSpecVersion,
1156 FormatConverterInfo_GetFriendlyName,
1157 FormatConverterInfo_GetPixelFormats,
1158 FormatConverterInfo_CreateInstance
1161 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1163 FormatConverterInfo *This;
1165 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
1166 if (!This)
1168 RegCloseKey(classkey);
1169 return E_OUTOFMEMORY;
1172 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
1173 This->ref = 1;
1174 This->classkey = classkey;
1175 memcpy(&This->clsid, clsid, sizeof(CLSID));
1177 *ppIInfo = (IWICComponentInfo*)This;
1178 return S_OK;
1181 typedef struct {
1182 IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface;
1183 LONG ref;
1184 HKEY classkey;
1185 CLSID clsid;
1186 } PixelFormatInfo;
1188 static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2 *iface)
1190 return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface);
1193 static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID iid,
1194 void **ppv)
1196 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1197 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1199 if (!ppv) return E_INVALIDARG;
1201 if (IsEqualIID(&IID_IUnknown, iid) ||
1202 IsEqualIID(&IID_IWICComponentInfo, iid) ||
1203 IsEqualIID(&IID_IWICPixelFormatInfo, iid) ||
1204 IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid))
1206 *ppv = This;
1208 else
1210 *ppv = NULL;
1211 return E_NOINTERFACE;
1214 IUnknown_AddRef((IUnknown*)*ppv);
1215 return S_OK;
1218 static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface)
1220 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1221 ULONG ref = InterlockedIncrement(&This->ref);
1223 TRACE("(%p) refcount=%u\n", iface, ref);
1225 return ref;
1228 static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface)
1230 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1231 ULONG ref = InterlockedDecrement(&This->ref);
1233 TRACE("(%p) refcount=%u\n", iface, ref);
1235 if (ref == 0)
1237 RegCloseKey(This->classkey);
1238 HeapFree(GetProcessHeap(), 0, This);
1241 return ref;
1244 static HRESULT WINAPI PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2 *iface,
1245 WICComponentType *pType)
1247 TRACE("(%p,%p)\n", iface, pType);
1248 if (!pType) return E_INVALIDARG;
1249 *pType = WICPixelFormat;
1250 return S_OK;
1253 static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2 *iface, CLSID *pclsid)
1255 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1256 TRACE("(%p,%p)\n", iface, pclsid);
1258 if (!pclsid)
1259 return E_INVALIDARG;
1261 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1263 return S_OK;
1266 static HRESULT WINAPI PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2 *iface, DWORD *pStatus)
1268 TRACE("(%p,%p)\n", iface, pStatus);
1270 if (!pStatus)
1271 return E_INVALIDARG;
1273 /* Pixel formats don't require code, so they are considered signed. */
1274 *pStatus = WICComponentSigned;
1276 return S_OK;
1279 static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UINT cchAuthor,
1280 WCHAR *wzAuthor, UINT *pcchActual)
1282 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1284 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1286 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1287 cchAuthor, wzAuthor, pcchActual);
1290 static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor)
1292 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1294 TRACE("(%p,%p)\n", iface, pguidVendor);
1296 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1299 static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion,
1300 WCHAR *wzVersion, UINT *pcchActual)
1302 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1304 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1306 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1307 cchVersion, wzVersion, pcchActual);
1310 static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface, UINT cchSpecVersion,
1311 WCHAR *wzSpecVersion, UINT *pcchActual)
1313 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1315 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1317 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1318 cchSpecVersion, wzSpecVersion, pcchActual);
1321 static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *iface, UINT cchFriendlyName,
1322 WCHAR *wzFriendlyName, UINT *pcchActual)
1324 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1326 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1328 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1329 cchFriendlyName, wzFriendlyName, pcchActual);
1332 static HRESULT WINAPI PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface,
1333 GUID *pFormat)
1335 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1336 TRACE("(%p,%p)\n", iface, pFormat);
1338 if (!pFormat)
1339 return E_INVALIDARG;
1341 *pFormat = This->clsid;
1343 return S_OK;
1346 static HRESULT WINAPI PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2 *iface,
1347 IWICColorContext **ppIColorContext)
1349 FIXME("(%p,%p): stub\n", iface, ppIColorContext);
1350 return E_NOTIMPL;
1353 static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *iface,
1354 UINT *puiBitsPerPixel)
1356 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1358 TRACE("(%p,%p)\n", iface, puiBitsPerPixel);
1360 return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel);
1363 static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface,
1364 UINT *puiChannelCount)
1366 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1368 TRACE("(%p,%p)\n", iface, puiChannelCount);
1370 return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount);
1373 static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface,
1374 UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual)
1376 static const WCHAR uintformatW[] = {'%','u',0};
1377 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1378 UINT channel_count;
1379 HRESULT hr;
1380 LONG ret;
1381 WCHAR valuename[11];
1382 DWORD cbData;
1384 TRACE("(%p,%u,%u,%p,%p)\n", iface, uiChannelIndex, cbMaskBuffer, pbMaskBuffer, pcbActual);
1386 if (!pcbActual)
1387 return E_INVALIDARG;
1389 hr = PixelFormatInfo_GetChannelCount(iface, &channel_count);
1391 if (SUCCEEDED(hr) && uiChannelIndex >= channel_count)
1392 hr = E_INVALIDARG;
1394 if (SUCCEEDED(hr))
1396 snprintfW(valuename, 11, uintformatW, uiChannelIndex);
1398 cbData = cbMaskBuffer;
1400 ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData);
1402 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
1403 *pcbActual = cbData;
1405 if (ret == ERROR_MORE_DATA)
1406 hr = E_INVALIDARG;
1407 else
1408 hr = HRESULT_FROM_WIN32(ret);
1411 return hr;
1414 static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 *iface,
1415 BOOL *pfSupportsTransparency)
1417 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1419 TRACE("(%p,%p)\n", iface, pfSupportsTransparency);
1421 return ComponentInfo_GetDWORDValue(This->classkey, supportstransparency_valuename, (DWORD*)pfSupportsTransparency);
1424 static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface,
1425 WICPixelFormatNumericRepresentation *pNumericRepresentation)
1427 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1429 TRACE("(%p,%p)\n", iface, pNumericRepresentation);
1431 return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation);
1434 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = {
1435 PixelFormatInfo_QueryInterface,
1436 PixelFormatInfo_AddRef,
1437 PixelFormatInfo_Release,
1438 PixelFormatInfo_GetComponentType,
1439 PixelFormatInfo_GetCLSID,
1440 PixelFormatInfo_GetSigningStatus,
1441 PixelFormatInfo_GetAuthor,
1442 PixelFormatInfo_GetVendorGUID,
1443 PixelFormatInfo_GetVersion,
1444 PixelFormatInfo_GetSpecVersion,
1445 PixelFormatInfo_GetFriendlyName,
1446 PixelFormatInfo_GetFormatGUID,
1447 PixelFormatInfo_GetColorContext,
1448 PixelFormatInfo_GetBitsPerPixel,
1449 PixelFormatInfo_GetChannelCount,
1450 PixelFormatInfo_GetChannelMask,
1451 PixelFormatInfo_SupportsTransparency,
1452 PixelFormatInfo_GetNumericRepresentation
1455 static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1457 PixelFormatInfo *This;
1459 This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo));
1460 if (!This)
1462 RegCloseKey(classkey);
1463 return E_OUTOFMEMORY;
1466 This->IWICPixelFormatInfo2_iface.lpVtbl = &PixelFormatInfo_Vtbl;
1467 This->ref = 1;
1468 This->classkey = classkey;
1469 memcpy(&This->clsid, clsid, sizeof(CLSID));
1471 *ppIInfo = (IWICComponentInfo*)This;
1472 return S_OK;
1475 typedef struct
1477 IWICMetadataReaderInfo IWICMetadataReaderInfo_iface;
1478 LONG ref;
1479 HKEY classkey;
1480 CLSID clsid;
1481 } MetadataReaderInfo;
1483 static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo *iface)
1485 return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface);
1488 static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface,
1489 REFIID riid, void **ppv)
1491 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1493 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
1495 if (!ppv) return E_INVALIDARG;
1497 if (IsEqualIID(&IID_IUnknown, riid) ||
1498 IsEqualIID(&IID_IWICComponentInfo, riid) ||
1499 IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) ||
1500 IsEqualIID(&IID_IWICMetadataReaderInfo, riid))
1502 *ppv = This;
1504 else
1506 *ppv = NULL;
1507 return E_NOINTERFACE;
1510 IUnknown_AddRef((IUnknown *)*ppv);
1511 return S_OK;
1514 static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
1516 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1517 ULONG ref = InterlockedIncrement(&This->ref);
1519 TRACE("(%p) refcount=%u\n", iface, ref);
1520 return ref;
1523 static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface)
1525 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1526 ULONG ref = InterlockedDecrement(&This->ref);
1528 TRACE("(%p) refcount=%u\n", iface, ref);
1530 if (!ref)
1532 RegCloseKey(This->classkey);
1533 HeapFree(GetProcessHeap(), 0, This);
1535 return ref;
1538 static HRESULT WINAPI MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo *iface,
1539 WICComponentType *type)
1541 TRACE("(%p,%p)\n", iface, type);
1543 if (!type) return E_INVALIDARG;
1544 *type = WICMetadataReader;
1545 return S_OK;
1548 static HRESULT WINAPI MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface,
1549 CLSID *clsid)
1551 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1553 TRACE("(%p,%p)\n", iface, clsid);
1555 if (!clsid) return E_INVALIDARG;
1556 *clsid = This->clsid;
1557 return S_OK;
1560 static HRESULT WINAPI MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo *iface,
1561 DWORD *status)
1563 FIXME("(%p,%p): stub\n", iface, status);
1564 return E_NOTIMPL;
1567 static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface,
1568 UINT length, WCHAR *author, UINT *actual_length)
1570 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1572 TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length);
1574 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1575 length, author, actual_length);
1578 static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface,
1579 GUID *vendor)
1581 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1583 TRACE("(%p,%p)\n", iface, vendor);
1585 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, vendor);
1588 static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface,
1589 UINT length, WCHAR *version, UINT *actual_length)
1591 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1593 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1595 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1596 length, version, actual_length);
1599 static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface,
1600 UINT length, WCHAR *version, UINT *actual_length)
1602 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1604 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1606 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1607 length, version, actual_length);
1610 static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo *iface,
1611 UINT length, WCHAR *name, UINT *actual_length)
1613 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1615 TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length);
1617 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1618 length, name, actual_length);
1621 static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo *iface,
1622 GUID *format)
1624 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1625 TRACE("(%p,%p)\n", iface, format);
1626 return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format);
1629 static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface,
1630 UINT length, GUID *formats, UINT *actual_length)
1632 if (!actual_length) return E_INVALIDARG;
1634 FIXME("(%p,%u,%p,%p): stub\n", iface, length, formats, actual_length);
1635 return E_NOTIMPL;
1638 static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo *iface,
1639 UINT length, WCHAR *manufacturer, UINT *actual_length)
1641 FIXME("(%p,%u,%p,%p): stub\n", iface, length, manufacturer, actual_length);
1642 return E_NOTIMPL;
1645 static HRESULT WINAPI MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo *iface,
1646 UINT length, WCHAR *models, UINT *actual_length)
1648 FIXME("(%p,%u,%p,%p): stub\n", iface, length, models, actual_length);
1649 return E_NOTIMPL;
1652 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo *iface,
1653 BOOL *param)
1655 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1656 TRACE("(%p,%p)\n", iface, param);
1657 return ComponentInfo_GetDWORDValue(This->classkey, requiresfullstream_valuename, (DWORD *)param);
1660 static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(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, supportspadding_valuename, (DWORD *)param);
1668 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface,
1669 BOOL *param)
1671 FIXME("(%p,%p): stub\n", iface, param);
1672 return E_NOTIMPL;
1675 static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface,
1676 REFGUID container, UINT length, WICMetadataPattern *pattern, UINT *count, UINT *actual_length)
1678 if (!actual_length) return E_INVALIDARG;
1680 FIXME("(%p,%s,%u,%p,%p,%p): stub\n", iface, debugstr_guid(container), length, pattern, count, actual_length);
1681 return E_NOTIMPL;
1684 static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface,
1685 REFGUID container, IStream *stream, BOOL *matches)
1687 FIXME("(%p,%s,%p,%p): stub\n", iface, debugstr_guid(container), stream, matches);
1688 return E_NOTIMPL;
1691 static HRESULT WINAPI MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *iface,
1692 IWICMetadataReader **reader)
1694 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1696 TRACE("(%p,%p)\n", iface, reader);
1698 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1699 &IID_IWICMetadataReader, (void **)reader);
1702 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = {
1703 MetadataReaderInfo_QueryInterface,
1704 MetadataReaderInfo_AddRef,
1705 MetadataReaderInfo_Release,
1706 MetadataReaderInfo_GetComponentType,
1707 MetadataReaderInfo_GetCLSID,
1708 MetadataReaderInfo_GetSigningStatus,
1709 MetadataReaderInfo_GetAuthor,
1710 MetadataReaderInfo_GetVendorGUID,
1711 MetadataReaderInfo_GetVersion,
1712 MetadataReaderInfo_GetSpecVersion,
1713 MetadataReaderInfo_GetFriendlyName,
1714 MetadataReaderInfo_GetMetadataFormat,
1715 MetadataReaderInfo_GetContainerFormats,
1716 MetadataReaderInfo_GetDeviceManufacturer,
1717 MetadataReaderInfo_GetDeviceModels,
1718 MetadataReaderInfo_DoesRequireFullStream,
1719 MetadataReaderInfo_DoesSupportPadding,
1720 MetadataReaderInfo_DoesRequireFixedSize,
1721 MetadataReaderInfo_GetPatterns,
1722 MetadataReaderInfo_MatchesPattern,
1723 MetadataReaderInfo_CreateInstance
1726 static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **info)
1728 MetadataReaderInfo *This;
1730 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1731 if (!This)
1733 RegCloseKey(classkey);
1734 return E_OUTOFMEMORY;
1737 This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl;
1738 This->ref = 1;
1739 This->classkey = classkey;
1740 This->clsid = *clsid;
1742 *info = (IWICComponentInfo *)This;
1743 return S_OK;
1746 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
1747 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
1749 struct category {
1750 WICComponentType type;
1751 const GUID *catid;
1752 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
1755 static const struct category categories[] = {
1756 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
1757 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
1758 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
1759 {WICPixelFormat, &CATID_WICPixelFormats, PixelFormatInfo_Constructor},
1760 {WICMetadataReader, &CATID_WICMetadataReader, MetadataReaderInfo_Constructor},
1764 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
1766 HKEY clsidkey;
1767 HKEY classkey;
1768 HKEY catidkey;
1769 HKEY instancekey;
1770 WCHAR guidstring[39];
1771 LONG res;
1772 const struct category *category;
1773 int found=0;
1774 HRESULT hr;
1776 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1777 if (res != ERROR_SUCCESS)
1778 return HRESULT_FROM_WIN32(res);
1780 for (category=categories; category->type; category++)
1782 StringFromGUID2(category->catid, guidstring, 39);
1783 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1784 if (res == ERROR_SUCCESS)
1786 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1787 if (res == ERROR_SUCCESS)
1789 StringFromGUID2(clsid, guidstring, 39);
1790 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
1791 if (res == ERROR_SUCCESS)
1793 RegCloseKey(classkey);
1794 found = 1;
1796 RegCloseKey(instancekey);
1798 RegCloseKey(catidkey);
1800 if (found) break;
1803 if (found)
1805 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
1806 if (res == ERROR_SUCCESS)
1807 hr = category->constructor(classkey, clsid, ppIInfo);
1808 else
1809 hr = HRESULT_FROM_WIN32(res);
1811 else
1813 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid));
1814 hr = E_FAIL;
1817 RegCloseKey(clsidkey);
1819 return hr;
1822 typedef struct {
1823 IEnumUnknown IEnumUnknown_iface;
1824 LONG ref;
1825 struct list objects;
1826 struct list *cursor;
1827 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
1828 } ComponentEnum;
1830 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
1832 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
1835 typedef struct {
1836 struct list entry;
1837 IUnknown *unk;
1838 } ComponentEnumItem;
1840 static const IEnumUnknownVtbl ComponentEnumVtbl;
1842 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
1843 void **ppv)
1845 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1846 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1848 if (!ppv) return E_INVALIDARG;
1850 if (IsEqualIID(&IID_IUnknown, iid) ||
1851 IsEqualIID(&IID_IEnumUnknown, iid))
1853 *ppv = &This->IEnumUnknown_iface;
1855 else
1857 *ppv = NULL;
1858 return E_NOINTERFACE;
1861 IUnknown_AddRef((IUnknown*)*ppv);
1862 return S_OK;
1865 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
1867 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1868 ULONG ref = InterlockedIncrement(&This->ref);
1870 TRACE("(%p) refcount=%u\n", iface, ref);
1872 return ref;
1875 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
1877 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1878 ULONG ref = InterlockedDecrement(&This->ref);
1879 ComponentEnumItem *cursor, *cursor2;
1881 TRACE("(%p) refcount=%u\n", iface, ref);
1883 if (ref == 0)
1885 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
1887 IUnknown_Release(cursor->unk);
1888 list_remove(&cursor->entry);
1889 HeapFree(GetProcessHeap(), 0, cursor);
1891 This->lock.DebugInfo->Spare[0] = 0;
1892 DeleteCriticalSection(&This->lock);
1893 HeapFree(GetProcessHeap(), 0, This);
1896 return ref;
1899 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
1900 IUnknown **rgelt, ULONG *pceltFetched)
1902 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1903 int num_fetched=0;
1904 ComponentEnumItem *item;
1905 HRESULT hr=S_OK;
1907 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
1909 EnterCriticalSection(&This->lock);
1910 while (num_fetched<celt)
1912 if (!This->cursor)
1914 hr = S_FALSE;
1915 break;
1917 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
1918 IUnknown_AddRef(item->unk);
1919 rgelt[num_fetched] = item->unk;
1920 num_fetched++;
1921 This->cursor = list_next(&This->objects, This->cursor);
1923 LeaveCriticalSection(&This->lock);
1924 if (pceltFetched)
1925 *pceltFetched = num_fetched;
1926 return hr;
1929 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
1931 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1932 int i;
1933 HRESULT hr=S_OK;
1935 TRACE("(%p,%u)\n", iface, celt);
1937 EnterCriticalSection(&This->lock);
1938 for (i=0; i<celt; i++)
1940 if (!This->cursor)
1942 hr = S_FALSE;
1943 break;
1945 This->cursor = list_next(&This->objects, This->cursor);
1947 LeaveCriticalSection(&This->lock);
1948 return hr;
1951 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
1953 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1955 TRACE("(%p)\n", iface);
1957 EnterCriticalSection(&This->lock);
1958 This->cursor = list_head(&This->objects);
1959 LeaveCriticalSection(&This->lock);
1960 return S_OK;
1963 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
1965 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1966 ComponentEnum *new_enum;
1967 ComponentEnumItem *old_item, *new_item;
1968 HRESULT ret=S_OK;
1969 struct list *old_cursor;
1971 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1972 if (!new_enum)
1974 *ppenum = NULL;
1975 return E_OUTOFMEMORY;
1978 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1979 new_enum->ref = 1;
1980 new_enum->cursor = NULL;
1981 list_init(&new_enum->objects);
1982 InitializeCriticalSection(&new_enum->lock);
1983 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1985 EnterCriticalSection(&This->lock);
1986 old_cursor = This->cursor;
1987 LeaveCriticalSection(&This->lock);
1989 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
1991 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1992 if (!new_item)
1994 ret = E_OUTOFMEMORY;
1995 break;
1997 new_item->unk = old_item->unk;
1998 list_add_tail(&new_enum->objects, &new_item->entry);
1999 IUnknown_AddRef(new_item->unk);
2000 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
2003 if (FAILED(ret))
2005 IEnumUnknown_Release(&new_enum->IEnumUnknown_iface);
2006 *ppenum = NULL;
2008 else
2009 *ppenum = &new_enum->IEnumUnknown_iface;
2011 return ret;
2014 static const IEnumUnknownVtbl ComponentEnumVtbl = {
2015 ComponentEnum_QueryInterface,
2016 ComponentEnum_AddRef,
2017 ComponentEnum_Release,
2018 ComponentEnum_Next,
2019 ComponentEnum_Skip,
2020 ComponentEnum_Reset,
2021 ComponentEnum_Clone
2024 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
2026 ComponentEnum *This;
2027 ComponentEnumItem *item;
2028 const struct category *category;
2029 HKEY clsidkey, catidkey, instancekey;
2030 WCHAR guidstring[39];
2031 LONG res;
2032 int i;
2033 HRESULT hr=S_OK;
2034 CLSID clsid;
2036 if (options) FIXME("ignoring flags %x\n", options);
2038 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
2039 if (res != ERROR_SUCCESS)
2040 return HRESULT_FROM_WIN32(res);
2042 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
2043 if (!This)
2045 RegCloseKey(clsidkey);
2046 return E_OUTOFMEMORY;
2049 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
2050 This->ref = 1;
2051 list_init(&This->objects);
2052 InitializeCriticalSection(&This->lock);
2053 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
2055 for (category=categories; category->type && hr == S_OK; category++)
2057 if ((category->type & componentTypes) == 0) continue;
2058 StringFromGUID2(category->catid, guidstring, 39);
2059 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
2060 if (res == ERROR_SUCCESS)
2062 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
2063 if (res == ERROR_SUCCESS)
2065 i=0;
2066 for (;;i++)
2068 DWORD guidstring_size = 39;
2069 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
2070 if (res != ERROR_SUCCESS) break;
2072 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
2073 if (!item) { hr = E_OUTOFMEMORY; break; }
2075 hr = CLSIDFromString(guidstring, &clsid);
2076 if (SUCCEEDED(hr))
2078 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
2079 if (SUCCEEDED(hr))
2080 list_add_tail(&This->objects, &item->entry);
2083 if (FAILED(hr))
2085 HeapFree(GetProcessHeap(), 0, item);
2086 hr = S_OK;
2089 RegCloseKey(instancekey);
2091 RegCloseKey(catidkey);
2093 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
2094 hr = HRESULT_FROM_WIN32(res);
2096 RegCloseKey(clsidkey);
2098 if (SUCCEEDED(hr))
2100 IEnumUnknown_Reset(&This->IEnumUnknown_iface);
2101 *ppIEnumUnknown = &This->IEnumUnknown_iface;
2103 else
2105 *ppIEnumUnknown = NULL;
2106 IEnumUnknown_Release(&This->IEnumUnknown_iface);
2109 return hr;
2112 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
2114 HRESULT res;
2115 IEnumUnknown *enumconverters;
2116 IUnknown *unkconverterinfo;
2117 IWICFormatConverterInfo *converterinfo=NULL;
2118 IWICFormatConverter *converter=NULL;
2119 GUID srcFormat;
2120 WCHAR srcformatstr[39], dstformatstr[39];
2121 BOOL canconvert;
2122 ULONG num_fetched;
2124 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
2125 if (FAILED(res)) return res;
2127 if (IsEqualGUID(&srcFormat, dstFormat))
2129 IWICBitmapSource_AddRef(pISrc);
2130 *ppIDst = pISrc;
2131 return S_OK;
2134 StringFromGUID2(&srcFormat, srcformatstr, 39);
2135 StringFromGUID2(dstFormat, dstformatstr, 39);
2137 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
2138 if (FAILED(res)) return res;
2140 while (!converter)
2142 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);
2144 if (res == S_OK)
2146 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);
2148 if (SUCCEEDED(res))
2150 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);
2152 if (canconvert)
2153 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);
2155 if (canconvert)
2157 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);
2159 if (SUCCEEDED(res))
2160 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);
2162 if (SUCCEEDED(res) && canconvert)
2163 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
2164 NULL, 0.0, WICBitmapPaletteTypeCustom);
2166 if (FAILED(res) || !canconvert)
2168 if (converter)
2170 IWICFormatConverter_Release(converter);
2171 converter = NULL;
2173 res = S_OK;
2177 IWICFormatConverterInfo_Release(converterinfo);
2180 IUnknown_Release(unkconverterinfo);
2182 else
2183 break;
2186 IEnumUnknown_Release(enumconverters);
2188 if (converter)
2190 res = IWICFormatConverter_QueryInterface(converter, &IID_IWICBitmapSource, (void **)ppIDst);
2191 IWICFormatConverter_Release(converter);
2192 return res;
2194 else
2196 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
2197 *ppIDst = NULL;
2198 return WINCODEC_ERR_COMPONENTNOTFOUND;