dplayx: Add a separate refcount for IDirectPlayLobby2A.
[wine.git] / dlls / windowscodecs / info.c
blob7c87c5d77edc82d731fe74e3a23fa3447b7c3aa8
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 UINT i;
543 ULONG pos;
544 BYTE *data=NULL;
545 ULONG datasize=0;
546 ULONG bytesread;
547 LARGE_INTEGER seekpos;
549 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
551 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
552 if (FAILED(hr)) return hr;
554 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
555 if (!patterns) return E_OUTOFMEMORY;
557 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
558 if (FAILED(hr)) goto end;
560 for (i=0; i<pattern_count; i++)
562 if (datasize < patterns[i].Length)
564 HeapFree(GetProcessHeap(), 0, data);
565 datasize = patterns[i].Length;
566 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
567 if (!data)
569 hr = E_OUTOFMEMORY;
570 break;
574 if (patterns[i].EndOfStream)
575 seekpos.QuadPart = -patterns[i].Position.QuadPart;
576 else
577 seekpos.QuadPart = patterns[i].Position.QuadPart;
578 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
579 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
580 if (FAILED(hr)) break;
582 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
583 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
584 continue;
585 if (FAILED(hr)) break;
587 for (pos=0; pos<patterns[i].Length; pos++)
589 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
590 break;
592 if (pos == patterns[i].Length) /* matches pattern */
594 hr = S_OK;
595 *pfMatches = TRUE;
596 break;
600 if (i == pattern_count) /* does not match any pattern */
602 hr = S_OK;
603 *pfMatches = FALSE;
606 end:
607 HeapFree(GetProcessHeap(), 0, patterns);
608 HeapFree(GetProcessHeap(), 0, data);
610 return hr;
613 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
614 IWICBitmapDecoder **ppIBitmapDecoder)
616 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
618 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
620 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
621 &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
624 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
625 BitmapDecoderInfo_QueryInterface,
626 BitmapDecoderInfo_AddRef,
627 BitmapDecoderInfo_Release,
628 BitmapDecoderInfo_GetComponentType,
629 BitmapDecoderInfo_GetCLSID,
630 BitmapDecoderInfo_GetSigningStatus,
631 BitmapDecoderInfo_GetAuthor,
632 BitmapDecoderInfo_GetVendorGUID,
633 BitmapDecoderInfo_GetVersion,
634 BitmapDecoderInfo_GetSpecVersion,
635 BitmapDecoderInfo_GetFriendlyName,
636 BitmapDecoderInfo_GetContainerFormat,
637 BitmapDecoderInfo_GetPixelFormats,
638 BitmapDecoderInfo_GetColorManagementVersion,
639 BitmapDecoderInfo_GetDeviceManufacturer,
640 BitmapDecoderInfo_GetDeviceModels,
641 BitmapDecoderInfo_GetMimeTypes,
642 BitmapDecoderInfo_GetFileExtensions,
643 BitmapDecoderInfo_DoesSupportAnimation,
644 BitmapDecoderInfo_DoesSupportChromaKey,
645 BitmapDecoderInfo_DoesSupportLossless,
646 BitmapDecoderInfo_DoesSupportMultiframe,
647 BitmapDecoderInfo_MatchesMimeType,
648 BitmapDecoderInfo_GetPatterns,
649 BitmapDecoderInfo_MatchesPattern,
650 BitmapDecoderInfo_CreateInstance
653 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
655 BitmapDecoderInfo *This;
657 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
658 if (!This)
660 RegCloseKey(classkey);
661 return E_OUTOFMEMORY;
664 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
665 This->ref = 1;
666 This->classkey = classkey;
667 memcpy(&This->clsid, clsid, sizeof(CLSID));
669 *ppIInfo = (IWICComponentInfo*)This;
670 return S_OK;
673 typedef struct {
674 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
675 LONG ref;
676 HKEY classkey;
677 CLSID clsid;
678 } BitmapEncoderInfo;
680 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
682 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
685 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
686 void **ppv)
688 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
689 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
691 if (!ppv) return E_INVALIDARG;
693 if (IsEqualIID(&IID_IUnknown, iid) ||
694 IsEqualIID(&IID_IWICComponentInfo, iid) ||
695 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
696 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
698 *ppv = This;
700 else
702 *ppv = NULL;
703 return E_NOINTERFACE;
706 IUnknown_AddRef((IUnknown*)*ppv);
707 return S_OK;
710 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
712 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
713 ULONG ref = InterlockedIncrement(&This->ref);
715 TRACE("(%p) refcount=%u\n", iface, ref);
717 return ref;
720 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
722 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
723 ULONG ref = InterlockedDecrement(&This->ref);
725 TRACE("(%p) refcount=%u\n", iface, ref);
727 if (ref == 0)
729 RegCloseKey(This->classkey);
730 HeapFree(GetProcessHeap(), 0, This);
733 return ref;
736 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
737 WICComponentType *pType)
739 TRACE("(%p,%p)\n", iface, pType);
740 if (!pType) return E_INVALIDARG;
741 *pType = WICEncoder;
742 return S_OK;
745 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
747 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
748 TRACE("(%p,%p)\n", iface, pclsid);
750 if (!pclsid)
751 return E_INVALIDARG;
753 memcpy(pclsid, &This->clsid, sizeof(CLSID));
755 return S_OK;
758 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
760 FIXME("(%p,%p): stub\n", iface, pStatus);
761 return E_NOTIMPL;
764 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
765 WCHAR *wzAuthor, UINT *pcchActual)
767 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
769 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
771 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
772 cchAuthor, wzAuthor, pcchActual);
775 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
777 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
779 TRACE("(%p,%p)\n", iface, pguidVendor);
781 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
784 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
785 WCHAR *wzVersion, UINT *pcchActual)
787 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
789 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
791 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
792 cchVersion, wzVersion, pcchActual);
795 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
796 WCHAR *wzSpecVersion, UINT *pcchActual)
798 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
800 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
802 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
803 cchSpecVersion, wzSpecVersion, pcchActual);
806 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
807 WCHAR *wzFriendlyName, UINT *pcchActual)
809 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
811 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
813 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
814 cchFriendlyName, wzFriendlyName, pcchActual);
817 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
818 GUID *pguidContainerFormat)
820 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
821 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
822 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
825 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
826 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
828 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
829 TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
830 return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
833 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
834 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
836 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
837 return E_NOTIMPL;
840 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
841 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
843 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
844 return E_NOTIMPL;
847 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
848 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
850 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
851 return E_NOTIMPL;
854 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
855 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
857 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
859 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
861 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
862 cchMimeTypes, wzMimeTypes, pcchActual);
865 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
866 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
868 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
869 return E_NOTIMPL;
872 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
873 BOOL *pfSupportAnimation)
875 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
876 return E_NOTIMPL;
879 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
880 BOOL *pfSupportChromaKey)
882 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
883 return E_NOTIMPL;
886 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
887 BOOL *pfSupportLossless)
889 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
890 return E_NOTIMPL;
893 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
894 BOOL *pfSupportMultiframe)
896 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
897 return E_NOTIMPL;
900 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
901 LPCWSTR wzMimeType, BOOL *pfMatches)
903 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
904 return E_NOTIMPL;
907 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
908 IWICBitmapEncoder **ppIBitmapEncoder)
910 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
912 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
914 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
915 &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
918 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
919 BitmapEncoderInfo_QueryInterface,
920 BitmapEncoderInfo_AddRef,
921 BitmapEncoderInfo_Release,
922 BitmapEncoderInfo_GetComponentType,
923 BitmapEncoderInfo_GetCLSID,
924 BitmapEncoderInfo_GetSigningStatus,
925 BitmapEncoderInfo_GetAuthor,
926 BitmapEncoderInfo_GetVendorGUID,
927 BitmapEncoderInfo_GetVersion,
928 BitmapEncoderInfo_GetSpecVersion,
929 BitmapEncoderInfo_GetFriendlyName,
930 BitmapEncoderInfo_GetContainerFormat,
931 BitmapEncoderInfo_GetPixelFormats,
932 BitmapEncoderInfo_GetColorManagementVersion,
933 BitmapEncoderInfo_GetDeviceManufacturer,
934 BitmapEncoderInfo_GetDeviceModels,
935 BitmapEncoderInfo_GetMimeTypes,
936 BitmapEncoderInfo_GetFileExtensions,
937 BitmapEncoderInfo_DoesSupportAnimation,
938 BitmapEncoderInfo_DoesSupportChromaKey,
939 BitmapEncoderInfo_DoesSupportLossless,
940 BitmapEncoderInfo_DoesSupportMultiframe,
941 BitmapEncoderInfo_MatchesMimeType,
942 BitmapEncoderInfo_CreateInstance
945 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
947 BitmapEncoderInfo *This;
949 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
950 if (!This)
952 RegCloseKey(classkey);
953 return E_OUTOFMEMORY;
956 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
957 This->ref = 1;
958 This->classkey = classkey;
959 memcpy(&This->clsid, clsid, sizeof(CLSID));
961 *ppIInfo = (IWICComponentInfo*)This;
962 return S_OK;
965 typedef struct {
966 IWICFormatConverterInfo IWICFormatConverterInfo_iface;
967 LONG ref;
968 HKEY classkey;
969 CLSID clsid;
970 } FormatConverterInfo;
972 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
974 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
977 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
978 void **ppv)
980 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
981 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
983 if (!ppv) return E_INVALIDARG;
985 if (IsEqualIID(&IID_IUnknown, iid) ||
986 IsEqualIID(&IID_IWICComponentInfo, iid) ||
987 IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
989 *ppv = This;
991 else
993 *ppv = NULL;
994 return E_NOINTERFACE;
997 IUnknown_AddRef((IUnknown*)*ppv);
998 return S_OK;
1001 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
1003 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1004 ULONG ref = InterlockedIncrement(&This->ref);
1006 TRACE("(%p) refcount=%u\n", iface, ref);
1008 return ref;
1011 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
1013 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1014 ULONG ref = InterlockedDecrement(&This->ref);
1016 TRACE("(%p) refcount=%u\n", iface, ref);
1018 if (ref == 0)
1020 RegCloseKey(This->classkey);
1021 HeapFree(GetProcessHeap(), 0, This);
1024 return ref;
1027 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
1028 WICComponentType *pType)
1030 TRACE("(%p,%p)\n", iface, pType);
1031 if (!pType) return E_INVALIDARG;
1032 *pType = WICPixelFormatConverter;
1033 return S_OK;
1036 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
1038 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1039 TRACE("(%p,%p)\n", iface, pclsid);
1041 if (!pclsid)
1042 return E_INVALIDARG;
1044 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1046 return S_OK;
1049 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
1051 FIXME("(%p,%p): stub\n", iface, pStatus);
1052 return E_NOTIMPL;
1055 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
1056 WCHAR *wzAuthor, UINT *pcchActual)
1058 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1060 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1062 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1063 cchAuthor, wzAuthor, pcchActual);
1066 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
1068 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1070 TRACE("(%p,%p)\n", iface, pguidVendor);
1072 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1075 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
1076 WCHAR *wzVersion, UINT *pcchActual)
1078 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1080 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1082 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1083 cchVersion, wzVersion, pcchActual);
1086 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
1087 WCHAR *wzSpecVersion, UINT *pcchActual)
1089 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1091 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1093 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1094 cchSpecVersion, wzSpecVersion, pcchActual);
1097 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
1098 WCHAR *wzFriendlyName, UINT *pcchActual)
1100 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1102 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1104 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1105 cchFriendlyName, wzFriendlyName, pcchActual);
1108 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
1109 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
1111 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
1112 return E_NOTIMPL;
1115 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
1116 IWICFormatConverter **ppIFormatConverter)
1118 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1120 TRACE("(%p,%p)\n", iface, ppIFormatConverter);
1122 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1123 &IID_IWICFormatConverter, (void**)ppIFormatConverter);
1126 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
1128 LONG res;
1129 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1130 HKEY formats_key, guid_key;
1132 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
1133 would be O(n). A registry test should do better. */
1135 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
1136 if (res != ERROR_SUCCESS) return FALSE;
1138 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
1139 if (res == ERROR_SUCCESS) RegCloseKey(guid_key);
1141 RegCloseKey(formats_key);
1143 return (res == ERROR_SUCCESS);
1146 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
1147 FormatConverterInfo_QueryInterface,
1148 FormatConverterInfo_AddRef,
1149 FormatConverterInfo_Release,
1150 FormatConverterInfo_GetComponentType,
1151 FormatConverterInfo_GetCLSID,
1152 FormatConverterInfo_GetSigningStatus,
1153 FormatConverterInfo_GetAuthor,
1154 FormatConverterInfo_GetVendorGUID,
1155 FormatConverterInfo_GetVersion,
1156 FormatConverterInfo_GetSpecVersion,
1157 FormatConverterInfo_GetFriendlyName,
1158 FormatConverterInfo_GetPixelFormats,
1159 FormatConverterInfo_CreateInstance
1162 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1164 FormatConverterInfo *This;
1166 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
1167 if (!This)
1169 RegCloseKey(classkey);
1170 return E_OUTOFMEMORY;
1173 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
1174 This->ref = 1;
1175 This->classkey = classkey;
1176 memcpy(&This->clsid, clsid, sizeof(CLSID));
1178 *ppIInfo = (IWICComponentInfo*)This;
1179 return S_OK;
1182 typedef struct {
1183 IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface;
1184 LONG ref;
1185 HKEY classkey;
1186 CLSID clsid;
1187 } PixelFormatInfo;
1189 static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2 *iface)
1191 return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface);
1194 static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID iid,
1195 void **ppv)
1197 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1198 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1200 if (!ppv) return E_INVALIDARG;
1202 if (IsEqualIID(&IID_IUnknown, iid) ||
1203 IsEqualIID(&IID_IWICComponentInfo, iid) ||
1204 IsEqualIID(&IID_IWICPixelFormatInfo, iid) ||
1205 IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid))
1207 *ppv = This;
1209 else
1211 *ppv = NULL;
1212 return E_NOINTERFACE;
1215 IUnknown_AddRef((IUnknown*)*ppv);
1216 return S_OK;
1219 static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface)
1221 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1222 ULONG ref = InterlockedIncrement(&This->ref);
1224 TRACE("(%p) refcount=%u\n", iface, ref);
1226 return ref;
1229 static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface)
1231 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1232 ULONG ref = InterlockedDecrement(&This->ref);
1234 TRACE("(%p) refcount=%u\n", iface, ref);
1236 if (ref == 0)
1238 RegCloseKey(This->classkey);
1239 HeapFree(GetProcessHeap(), 0, This);
1242 return ref;
1245 static HRESULT WINAPI PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2 *iface,
1246 WICComponentType *pType)
1248 TRACE("(%p,%p)\n", iface, pType);
1249 if (!pType) return E_INVALIDARG;
1250 *pType = WICPixelFormat;
1251 return S_OK;
1254 static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2 *iface, CLSID *pclsid)
1256 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1257 TRACE("(%p,%p)\n", iface, pclsid);
1259 if (!pclsid)
1260 return E_INVALIDARG;
1262 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1264 return S_OK;
1267 static HRESULT WINAPI PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2 *iface, DWORD *pStatus)
1269 TRACE("(%p,%p)\n", iface, pStatus);
1271 if (!pStatus)
1272 return E_INVALIDARG;
1274 /* Pixel formats don't require code, so they are considered signed. */
1275 *pStatus = WICComponentSigned;
1277 return S_OK;
1280 static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UINT cchAuthor,
1281 WCHAR *wzAuthor, UINT *pcchActual)
1283 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1285 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1287 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1288 cchAuthor, wzAuthor, pcchActual);
1291 static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor)
1293 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1295 TRACE("(%p,%p)\n", iface, pguidVendor);
1297 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1300 static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion,
1301 WCHAR *wzVersion, UINT *pcchActual)
1303 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1305 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1307 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1308 cchVersion, wzVersion, pcchActual);
1311 static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface, UINT cchSpecVersion,
1312 WCHAR *wzSpecVersion, UINT *pcchActual)
1314 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1316 TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1318 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1319 cchSpecVersion, wzSpecVersion, pcchActual);
1322 static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *iface, UINT cchFriendlyName,
1323 WCHAR *wzFriendlyName, UINT *pcchActual)
1325 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1327 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1329 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1330 cchFriendlyName, wzFriendlyName, pcchActual);
1333 static HRESULT WINAPI PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface,
1334 GUID *pFormat)
1336 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1337 TRACE("(%p,%p)\n", iface, pFormat);
1339 if (!pFormat)
1340 return E_INVALIDARG;
1342 *pFormat = This->clsid;
1344 return S_OK;
1347 static HRESULT WINAPI PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2 *iface,
1348 IWICColorContext **ppIColorContext)
1350 FIXME("(%p,%p): stub\n", iface, ppIColorContext);
1351 return E_NOTIMPL;
1354 static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *iface,
1355 UINT *puiBitsPerPixel)
1357 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1359 TRACE("(%p,%p)\n", iface, puiBitsPerPixel);
1361 return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel);
1364 static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface,
1365 UINT *puiChannelCount)
1367 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1369 TRACE("(%p,%p)\n", iface, puiChannelCount);
1371 return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount);
1374 static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface,
1375 UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual)
1377 static const WCHAR uintformatW[] = {'%','u',0};
1378 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1379 UINT channel_count;
1380 HRESULT hr;
1381 LONG ret;
1382 WCHAR valuename[11];
1383 DWORD cbData;
1385 TRACE("(%p,%u,%u,%p,%p)\n", iface, uiChannelIndex, cbMaskBuffer, pbMaskBuffer, pcbActual);
1387 if (!pcbActual)
1388 return E_INVALIDARG;
1390 hr = PixelFormatInfo_GetChannelCount(iface, &channel_count);
1392 if (SUCCEEDED(hr) && uiChannelIndex >= channel_count)
1393 hr = E_INVALIDARG;
1395 if (SUCCEEDED(hr))
1397 snprintfW(valuename, 11, uintformatW, uiChannelIndex);
1399 cbData = cbMaskBuffer;
1401 ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData);
1403 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
1404 *pcbActual = cbData;
1406 if (ret == ERROR_MORE_DATA)
1407 hr = E_INVALIDARG;
1408 else
1409 hr = HRESULT_FROM_WIN32(ret);
1412 return hr;
1415 static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 *iface,
1416 BOOL *pfSupportsTransparency)
1418 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1420 TRACE("(%p,%p)\n", iface, pfSupportsTransparency);
1422 return ComponentInfo_GetDWORDValue(This->classkey, supportstransparency_valuename, (DWORD*)pfSupportsTransparency);
1425 static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface,
1426 WICPixelFormatNumericRepresentation *pNumericRepresentation)
1428 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1430 TRACE("(%p,%p)\n", iface, pNumericRepresentation);
1432 return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation);
1435 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = {
1436 PixelFormatInfo_QueryInterface,
1437 PixelFormatInfo_AddRef,
1438 PixelFormatInfo_Release,
1439 PixelFormatInfo_GetComponentType,
1440 PixelFormatInfo_GetCLSID,
1441 PixelFormatInfo_GetSigningStatus,
1442 PixelFormatInfo_GetAuthor,
1443 PixelFormatInfo_GetVendorGUID,
1444 PixelFormatInfo_GetVersion,
1445 PixelFormatInfo_GetSpecVersion,
1446 PixelFormatInfo_GetFriendlyName,
1447 PixelFormatInfo_GetFormatGUID,
1448 PixelFormatInfo_GetColorContext,
1449 PixelFormatInfo_GetBitsPerPixel,
1450 PixelFormatInfo_GetChannelCount,
1451 PixelFormatInfo_GetChannelMask,
1452 PixelFormatInfo_SupportsTransparency,
1453 PixelFormatInfo_GetNumericRepresentation
1456 static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1458 PixelFormatInfo *This;
1460 This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo));
1461 if (!This)
1463 RegCloseKey(classkey);
1464 return E_OUTOFMEMORY;
1467 This->IWICPixelFormatInfo2_iface.lpVtbl = &PixelFormatInfo_Vtbl;
1468 This->ref = 1;
1469 This->classkey = classkey;
1470 memcpy(&This->clsid, clsid, sizeof(CLSID));
1472 *ppIInfo = (IWICComponentInfo*)This;
1473 return S_OK;
1476 typedef struct
1478 IWICMetadataReaderInfo IWICMetadataReaderInfo_iface;
1479 LONG ref;
1480 HKEY classkey;
1481 CLSID clsid;
1482 } MetadataReaderInfo;
1484 static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo *iface)
1486 return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface);
1489 static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface,
1490 REFIID riid, void **ppv)
1492 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1494 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
1496 if (!ppv) return E_INVALIDARG;
1498 if (IsEqualIID(&IID_IUnknown, riid) ||
1499 IsEqualIID(&IID_IWICComponentInfo, riid) ||
1500 IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) ||
1501 IsEqualIID(&IID_IWICMetadataReaderInfo, riid))
1503 *ppv = This;
1505 else
1507 *ppv = NULL;
1508 return E_NOINTERFACE;
1511 IUnknown_AddRef((IUnknown *)*ppv);
1512 return S_OK;
1515 static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
1517 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1518 ULONG ref = InterlockedIncrement(&This->ref);
1520 TRACE("(%p) refcount=%u\n", iface, ref);
1521 return ref;
1524 static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface)
1526 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1527 ULONG ref = InterlockedDecrement(&This->ref);
1529 TRACE("(%p) refcount=%u\n", iface, ref);
1531 if (!ref)
1533 RegCloseKey(This->classkey);
1534 HeapFree(GetProcessHeap(), 0, This);
1536 return ref;
1539 static HRESULT WINAPI MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo *iface,
1540 WICComponentType *type)
1542 TRACE("(%p,%p)\n", iface, type);
1544 if (!type) return E_INVALIDARG;
1545 *type = WICMetadataReader;
1546 return S_OK;
1549 static HRESULT WINAPI MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface,
1550 CLSID *clsid)
1552 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1554 TRACE("(%p,%p)\n", iface, clsid);
1556 if (!clsid) return E_INVALIDARG;
1557 *clsid = This->clsid;
1558 return S_OK;
1561 static HRESULT WINAPI MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo *iface,
1562 DWORD *status)
1564 FIXME("(%p,%p): stub\n", iface, status);
1565 return E_NOTIMPL;
1568 static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface,
1569 UINT length, WCHAR *author, UINT *actual_length)
1571 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1573 TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length);
1575 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1576 length, author, actual_length);
1579 static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface,
1580 GUID *vendor)
1582 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1584 TRACE("(%p,%p)\n", iface, vendor);
1586 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, vendor);
1589 static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface,
1590 UINT length, WCHAR *version, UINT *actual_length)
1592 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1594 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1596 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1597 length, version, actual_length);
1600 static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface,
1601 UINT length, WCHAR *version, UINT *actual_length)
1603 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1605 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1607 return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
1608 length, version, actual_length);
1611 static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo *iface,
1612 UINT length, WCHAR *name, UINT *actual_length)
1614 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1616 TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length);
1618 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1619 length, name, actual_length);
1622 static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo *iface,
1623 GUID *format)
1625 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1626 TRACE("(%p,%p)\n", iface, format);
1627 return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format);
1630 static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface,
1631 UINT length, GUID *formats, UINT *actual_length)
1633 if (!actual_length) return E_INVALIDARG;
1635 FIXME("(%p,%u,%p,%p): stub\n", iface, length, formats, actual_length);
1636 return E_NOTIMPL;
1639 static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo *iface,
1640 UINT length, WCHAR *manufacturer, UINT *actual_length)
1642 FIXME("(%p,%u,%p,%p): stub\n", iface, length, manufacturer, actual_length);
1643 return E_NOTIMPL;
1646 static HRESULT WINAPI MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo *iface,
1647 UINT length, WCHAR *models, UINT *actual_length)
1649 FIXME("(%p,%u,%p,%p): stub\n", iface, length, models, actual_length);
1650 return E_NOTIMPL;
1653 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo *iface,
1654 BOOL *param)
1656 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1657 TRACE("(%p,%p)\n", iface, param);
1658 return ComponentInfo_GetDWORDValue(This->classkey, requiresfullstream_valuename, (DWORD *)param);
1661 static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface,
1662 BOOL *param)
1664 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1665 TRACE("(%p,%p)\n", iface, param);
1666 return ComponentInfo_GetDWORDValue(This->classkey, supportspadding_valuename, (DWORD *)param);
1669 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface,
1670 BOOL *param)
1672 FIXME("(%p,%p): stub\n", iface, param);
1673 return E_NOTIMPL;
1676 static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface,
1677 REFGUID container, UINT length, WICMetadataPattern *pattern, UINT *count, UINT *actual_length)
1679 if (!actual_length) return E_INVALIDARG;
1681 FIXME("(%p,%s,%u,%p,%p,%p): stub\n", iface, debugstr_guid(container), length, pattern, count, actual_length);
1682 return E_NOTIMPL;
1685 static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface,
1686 REFGUID container, IStream *stream, BOOL *matches)
1688 FIXME("(%p,%s,%p,%p): stub\n", iface, debugstr_guid(container), stream, matches);
1689 return E_NOTIMPL;
1692 static HRESULT WINAPI MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *iface,
1693 IWICMetadataReader **reader)
1695 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1697 TRACE("(%p,%p)\n", iface, reader);
1699 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1700 &IID_IWICMetadataReader, (void **)reader);
1703 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = {
1704 MetadataReaderInfo_QueryInterface,
1705 MetadataReaderInfo_AddRef,
1706 MetadataReaderInfo_Release,
1707 MetadataReaderInfo_GetComponentType,
1708 MetadataReaderInfo_GetCLSID,
1709 MetadataReaderInfo_GetSigningStatus,
1710 MetadataReaderInfo_GetAuthor,
1711 MetadataReaderInfo_GetVendorGUID,
1712 MetadataReaderInfo_GetVersion,
1713 MetadataReaderInfo_GetSpecVersion,
1714 MetadataReaderInfo_GetFriendlyName,
1715 MetadataReaderInfo_GetMetadataFormat,
1716 MetadataReaderInfo_GetContainerFormats,
1717 MetadataReaderInfo_GetDeviceManufacturer,
1718 MetadataReaderInfo_GetDeviceModels,
1719 MetadataReaderInfo_DoesRequireFullStream,
1720 MetadataReaderInfo_DoesSupportPadding,
1721 MetadataReaderInfo_DoesRequireFixedSize,
1722 MetadataReaderInfo_GetPatterns,
1723 MetadataReaderInfo_MatchesPattern,
1724 MetadataReaderInfo_CreateInstance
1727 static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **info)
1729 MetadataReaderInfo *This;
1731 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1732 if (!This)
1734 RegCloseKey(classkey);
1735 return E_OUTOFMEMORY;
1738 This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl;
1739 This->ref = 1;
1740 This->classkey = classkey;
1741 This->clsid = *clsid;
1743 *info = (IWICComponentInfo *)This;
1744 return S_OK;
1747 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
1748 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
1750 struct category {
1751 WICComponentType type;
1752 const GUID *catid;
1753 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
1756 static const struct category categories[] = {
1757 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
1758 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
1759 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
1760 {WICPixelFormat, &CATID_WICPixelFormats, PixelFormatInfo_Constructor},
1761 {WICMetadataReader, &CATID_WICMetadataReader, MetadataReaderInfo_Constructor},
1765 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
1767 HKEY clsidkey;
1768 HKEY classkey;
1769 HKEY catidkey;
1770 HKEY instancekey;
1771 WCHAR guidstring[39];
1772 LONG res;
1773 const struct category *category;
1774 int found=0;
1775 HRESULT hr;
1777 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1778 if (res != ERROR_SUCCESS)
1779 return HRESULT_FROM_WIN32(res);
1781 for (category=categories; category->type; category++)
1783 StringFromGUID2(category->catid, guidstring, 39);
1784 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1785 if (res == ERROR_SUCCESS)
1787 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1788 if (res == ERROR_SUCCESS)
1790 StringFromGUID2(clsid, guidstring, 39);
1791 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
1792 if (res == ERROR_SUCCESS)
1794 RegCloseKey(classkey);
1795 found = 1;
1797 RegCloseKey(instancekey);
1799 RegCloseKey(catidkey);
1801 if (found) break;
1804 if (found)
1806 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
1807 if (res == ERROR_SUCCESS)
1808 hr = category->constructor(classkey, clsid, ppIInfo);
1809 else
1810 hr = HRESULT_FROM_WIN32(res);
1812 else
1814 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid));
1815 hr = E_FAIL;
1818 RegCloseKey(clsidkey);
1820 return hr;
1823 typedef struct {
1824 IEnumUnknown IEnumUnknown_iface;
1825 LONG ref;
1826 struct list objects;
1827 struct list *cursor;
1828 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
1829 } ComponentEnum;
1831 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
1833 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
1836 typedef struct {
1837 struct list entry;
1838 IUnknown *unk;
1839 } ComponentEnumItem;
1841 static const IEnumUnknownVtbl ComponentEnumVtbl;
1843 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
1844 void **ppv)
1846 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1847 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1849 if (!ppv) return E_INVALIDARG;
1851 if (IsEqualIID(&IID_IUnknown, iid) ||
1852 IsEqualIID(&IID_IEnumUnknown, iid))
1854 *ppv = &This->IEnumUnknown_iface;
1856 else
1858 *ppv = NULL;
1859 return E_NOINTERFACE;
1862 IUnknown_AddRef((IUnknown*)*ppv);
1863 return S_OK;
1866 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
1868 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1869 ULONG ref = InterlockedIncrement(&This->ref);
1871 TRACE("(%p) refcount=%u\n", iface, ref);
1873 return ref;
1876 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
1878 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1879 ULONG ref = InterlockedDecrement(&This->ref);
1880 ComponentEnumItem *cursor, *cursor2;
1882 TRACE("(%p) refcount=%u\n", iface, ref);
1884 if (ref == 0)
1886 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
1888 IUnknown_Release(cursor->unk);
1889 list_remove(&cursor->entry);
1890 HeapFree(GetProcessHeap(), 0, cursor);
1892 This->lock.DebugInfo->Spare[0] = 0;
1893 DeleteCriticalSection(&This->lock);
1894 HeapFree(GetProcessHeap(), 0, This);
1897 return ref;
1900 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
1901 IUnknown **rgelt, ULONG *pceltFetched)
1903 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1904 ULONG num_fetched=0;
1905 ComponentEnumItem *item;
1906 HRESULT hr=S_OK;
1908 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
1910 EnterCriticalSection(&This->lock);
1911 while (num_fetched<celt)
1913 if (!This->cursor)
1915 hr = S_FALSE;
1916 break;
1918 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
1919 IUnknown_AddRef(item->unk);
1920 rgelt[num_fetched] = item->unk;
1921 num_fetched++;
1922 This->cursor = list_next(&This->objects, This->cursor);
1924 LeaveCriticalSection(&This->lock);
1925 if (pceltFetched)
1926 *pceltFetched = num_fetched;
1927 return hr;
1930 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
1932 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1933 ULONG i;
1934 HRESULT hr=S_OK;
1936 TRACE("(%p,%u)\n", iface, celt);
1938 EnterCriticalSection(&This->lock);
1939 for (i=0; i<celt; i++)
1941 if (!This->cursor)
1943 hr = S_FALSE;
1944 break;
1946 This->cursor = list_next(&This->objects, This->cursor);
1948 LeaveCriticalSection(&This->lock);
1949 return hr;
1952 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
1954 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1956 TRACE("(%p)\n", iface);
1958 EnterCriticalSection(&This->lock);
1959 This->cursor = list_head(&This->objects);
1960 LeaveCriticalSection(&This->lock);
1961 return S_OK;
1964 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
1966 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1967 ComponentEnum *new_enum;
1968 ComponentEnumItem *old_item, *new_item;
1969 HRESULT ret=S_OK;
1970 struct list *old_cursor;
1972 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1973 if (!new_enum)
1975 *ppenum = NULL;
1976 return E_OUTOFMEMORY;
1979 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1980 new_enum->ref = 1;
1981 new_enum->cursor = NULL;
1982 list_init(&new_enum->objects);
1983 InitializeCriticalSection(&new_enum->lock);
1984 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1986 EnterCriticalSection(&This->lock);
1987 old_cursor = This->cursor;
1988 LeaveCriticalSection(&This->lock);
1990 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
1992 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1993 if (!new_item)
1995 ret = E_OUTOFMEMORY;
1996 break;
1998 new_item->unk = old_item->unk;
1999 list_add_tail(&new_enum->objects, &new_item->entry);
2000 IUnknown_AddRef(new_item->unk);
2001 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
2004 if (FAILED(ret))
2006 IEnumUnknown_Release(&new_enum->IEnumUnknown_iface);
2007 *ppenum = NULL;
2009 else
2010 *ppenum = &new_enum->IEnumUnknown_iface;
2012 return ret;
2015 static const IEnumUnknownVtbl ComponentEnumVtbl = {
2016 ComponentEnum_QueryInterface,
2017 ComponentEnum_AddRef,
2018 ComponentEnum_Release,
2019 ComponentEnum_Next,
2020 ComponentEnum_Skip,
2021 ComponentEnum_Reset,
2022 ComponentEnum_Clone
2025 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
2027 ComponentEnum *This;
2028 ComponentEnumItem *item;
2029 const struct category *category;
2030 HKEY clsidkey, catidkey, instancekey;
2031 WCHAR guidstring[39];
2032 LONG res;
2033 int i;
2034 HRESULT hr=S_OK;
2035 CLSID clsid;
2037 if (options) FIXME("ignoring flags %x\n", options);
2039 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
2040 if (res != ERROR_SUCCESS)
2041 return HRESULT_FROM_WIN32(res);
2043 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
2044 if (!This)
2046 RegCloseKey(clsidkey);
2047 return E_OUTOFMEMORY;
2050 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
2051 This->ref = 1;
2052 list_init(&This->objects);
2053 InitializeCriticalSection(&This->lock);
2054 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
2056 for (category=categories; category->type && hr == S_OK; category++)
2058 if ((category->type & componentTypes) == 0) continue;
2059 StringFromGUID2(category->catid, guidstring, 39);
2060 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
2061 if (res == ERROR_SUCCESS)
2063 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
2064 if (res == ERROR_SUCCESS)
2066 i=0;
2067 for (;;i++)
2069 DWORD guidstring_size = 39;
2070 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
2071 if (res != ERROR_SUCCESS) break;
2073 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
2074 if (!item) { hr = E_OUTOFMEMORY; break; }
2076 hr = CLSIDFromString(guidstring, &clsid);
2077 if (SUCCEEDED(hr))
2079 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
2080 if (SUCCEEDED(hr))
2081 list_add_tail(&This->objects, &item->entry);
2084 if (FAILED(hr))
2086 HeapFree(GetProcessHeap(), 0, item);
2087 hr = S_OK;
2090 RegCloseKey(instancekey);
2092 RegCloseKey(catidkey);
2094 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
2095 hr = HRESULT_FROM_WIN32(res);
2097 RegCloseKey(clsidkey);
2099 if (SUCCEEDED(hr))
2101 IEnumUnknown_Reset(&This->IEnumUnknown_iface);
2102 *ppIEnumUnknown = &This->IEnumUnknown_iface;
2104 else
2106 *ppIEnumUnknown = NULL;
2107 IEnumUnknown_Release(&This->IEnumUnknown_iface);
2110 return hr;
2113 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
2115 HRESULT res;
2116 IEnumUnknown *enumconverters;
2117 IUnknown *unkconverterinfo;
2118 IWICFormatConverterInfo *converterinfo=NULL;
2119 IWICFormatConverter *converter=NULL;
2120 GUID srcFormat;
2121 WCHAR srcformatstr[39], dstformatstr[39];
2122 BOOL canconvert;
2123 ULONG num_fetched;
2125 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
2126 if (FAILED(res)) return res;
2128 if (IsEqualGUID(&srcFormat, dstFormat))
2130 IWICBitmapSource_AddRef(pISrc);
2131 *ppIDst = pISrc;
2132 return S_OK;
2135 StringFromGUID2(&srcFormat, srcformatstr, 39);
2136 StringFromGUID2(dstFormat, dstformatstr, 39);
2138 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
2139 if (FAILED(res)) return res;
2141 while (!converter)
2143 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);
2145 if (res == S_OK)
2147 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);
2149 if (SUCCEEDED(res))
2151 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);
2153 if (canconvert)
2154 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);
2156 if (canconvert)
2158 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);
2160 if (SUCCEEDED(res))
2161 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);
2163 if (SUCCEEDED(res) && canconvert)
2164 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
2165 NULL, 0.0, WICBitmapPaletteTypeCustom);
2167 if (FAILED(res) || !canconvert)
2169 if (converter)
2171 IWICFormatConverter_Release(converter);
2172 converter = NULL;
2174 res = S_OK;
2178 IWICFormatConverterInfo_Release(converterinfo);
2181 IUnknown_Release(unkconverterinfo);
2183 else
2184 break;
2187 IEnumUnknown_Release(enumconverters);
2189 if (converter)
2191 res = IWICFormatConverter_QueryInterface(converter, &IID_IWICBitmapSource, (void **)ppIDst);
2192 IWICFormatConverter_Release(converter);
2193 return res;
2195 else
2197 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
2198 *ppIDst = NULL;
2199 return WINCODEC_ERR_COMPONENTNOTFOUND;