windowscodecs: Implement IWICPixelFormatInfo::GetFormatGUID.
[wine/multimedia.git] / dlls / windowscodecs / info.c
blob21c291bbc4e77b0b66dd1fde0c8db9a4886e249b
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 containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
46 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
47 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
48 static const WCHAR version_valuename[] = {'V','e','r','s','i','o','n',0};
49 static const WCHAR bitsperpixel_valuename[] = {'B','i','t','L','e','n','g','t','h',0};
50 static const WCHAR channelcount_valuename[] = {'C','h','a','n','n','e','l','C','o','u','n','t',0};
51 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
53 static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value,
54 UINT buffer_size, WCHAR *buffer, UINT *actual_size)
56 LONG ret;
57 DWORD cbdata=buffer_size * sizeof(WCHAR);
59 if (!actual_size)
60 return E_INVALIDARG;
62 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
63 buffer, &cbdata);
65 if (ret == ERROR_FILE_NOT_FOUND)
67 *actual_size = 0;
68 return S_OK;
71 if (ret == 0 || ret == ERROR_MORE_DATA)
72 *actual_size = cbdata/sizeof(WCHAR);
74 if (!buffer && buffer_size != 0)
75 /* Yes, native returns the correct size in this case. */
76 return E_INVALIDARG;
78 if (ret == ERROR_MORE_DATA)
79 return WINCODEC_ERR_INSUFFICIENTBUFFER;
81 return HRESULT_FROM_WIN32(ret);
84 static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value,
85 GUID *result)
87 LONG ret;
88 WCHAR guid_string[39];
89 DWORD cbdata = sizeof(guid_string);
90 HRESULT hr;
92 if (!result)
93 return E_INVALIDARG;
95 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
96 guid_string, &cbdata);
98 if (ret != ERROR_SUCCESS)
99 return HRESULT_FROM_WIN32(ret);
101 if (cbdata < sizeof(guid_string))
103 ERR("incomplete GUID value\n");
104 return E_FAIL;
107 hr = CLSIDFromString(guid_string, result);
109 return hr;
112 static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value,
113 DWORD *result)
115 LONG ret;
116 DWORD cbdata = sizeof(DWORD);
118 if (!result)
119 return E_INVALIDARG;
121 ret = RegGetValueW(classkey, NULL, value, RRF_RT_DWORD, NULL,
122 result, &cbdata);
124 if (ret == ERROR_FILE_NOT_FOUND)
126 *result = 0;
127 return S_OK;
130 return HRESULT_FROM_WIN32(ret);
133 typedef struct {
134 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface;
135 LONG ref;
136 HKEY classkey;
137 CLSID clsid;
138 } BitmapDecoderInfo;
140 static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo *iface)
142 return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface);
145 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid,
146 void **ppv)
148 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
149 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
151 if (!ppv) return E_INVALIDARG;
153 if (IsEqualIID(&IID_IUnknown, iid) ||
154 IsEqualIID(&IID_IWICComponentInfo, iid) ||
155 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
156 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
158 *ppv = This;
160 else
162 *ppv = NULL;
163 return E_NOINTERFACE;
166 IUnknown_AddRef((IUnknown*)*ppv);
167 return S_OK;
170 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
172 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
173 ULONG ref = InterlockedIncrement(&This->ref);
175 TRACE("(%p) refcount=%u\n", iface, ref);
177 return ref;
180 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
182 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
183 ULONG ref = InterlockedDecrement(&This->ref);
185 TRACE("(%p) refcount=%u\n", iface, ref);
187 if (ref == 0)
189 RegCloseKey(This->classkey);
190 HeapFree(GetProcessHeap(), 0, This);
193 return ref;
196 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface,
197 WICComponentType *pType)
199 TRACE("(%p,%p)\n", iface, pType);
200 if (!pType) return E_INVALIDARG;
201 *pType = WICDecoder;
202 return S_OK;
205 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid)
207 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
208 TRACE("(%p,%p)\n", iface, pclsid);
210 if (!pclsid)
211 return E_INVALIDARG;
213 memcpy(pclsid, &This->clsid, sizeof(CLSID));
215 return S_OK;
218 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus)
220 FIXME("(%p,%p): stub\n", iface, pStatus);
221 return E_NOTIMPL;
224 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor,
225 WCHAR *wzAuthor, UINT *pcchActual)
227 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
229 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
231 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
232 cchAuthor, wzAuthor, pcchActual);
235 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
237 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
239 TRACE("(%p,%p)\n", iface, pguidVendor);
241 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
244 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
245 WCHAR *wzVersion, UINT *pcchActual)
247 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
249 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
251 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
252 cchVersion, wzVersion, pcchActual);
255 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
256 WCHAR *wzSpecVersion, UINT *pcchActual)
258 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
259 return E_NOTIMPL;
262 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
263 WCHAR *wzFriendlyName, UINT *pcchActual)
265 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
267 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
269 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
270 cchFriendlyName, wzFriendlyName, pcchActual);
273 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
274 GUID *pguidContainerFormat)
276 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
277 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
278 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
281 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
282 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
284 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
285 return E_NOTIMPL;
288 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface,
289 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
291 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
292 return E_NOTIMPL;
295 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface,
296 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
298 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
299 return E_NOTIMPL;
302 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface,
303 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
305 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
306 return E_NOTIMPL;
309 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface,
310 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
312 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
314 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
316 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
317 cchMimeTypes, wzMimeTypes, pcchActual);
320 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface,
321 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
323 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
324 return E_NOTIMPL;
327 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface,
328 BOOL *pfSupportAnimation)
330 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
331 return E_NOTIMPL;
334 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface,
335 BOOL *pfSupportChromaKey)
337 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
338 return E_NOTIMPL;
341 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface,
342 BOOL *pfSupportLossless)
344 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
345 return E_NOTIMPL;
348 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface,
349 BOOL *pfSupportMultiframe)
351 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
352 return E_NOTIMPL;
355 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface,
356 LPCWSTR wzMimeType, BOOL *pfMatches)
358 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
359 return E_NOTIMPL;
362 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface,
363 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual)
365 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
366 UINT pattern_count=0, patterns_size=0;
367 WCHAR subkeyname[11];
368 LONG res;
369 HKEY patternskey, patternkey;
370 static const WCHAR uintformatW[] = {'%','u',0};
371 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0};
372 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
373 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0};
374 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
375 static const WCHAR maskW[] = {'M','a','s','k',0};
376 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
377 HRESULT hr=S_OK;
378 UINT i;
379 BYTE *bPatterns=(BYTE*)pPatterns;
380 DWORD length, valuesize;
382 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual);
384 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
385 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
387 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
388 if (res == ERROR_SUCCESS)
390 patterns_size = pattern_count * sizeof(WICBitmapPattern);
392 for (i=0; i<pattern_count; i++)
394 snprintfW(subkeyname, 11, uintformatW, i);
395 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
396 if (res == ERROR_SUCCESS)
398 valuesize = sizeof(ULONG);
399 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
400 &length, &valuesize);
401 patterns_size += length*2;
403 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS))
405 pPatterns[i].Length = length;
407 pPatterns[i].EndOfStream = 0;
408 valuesize = sizeof(BOOL);
409 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
410 &pPatterns[i].EndOfStream, &valuesize);
412 pPatterns[i].Position.QuadPart = 0;
413 valuesize = sizeof(ULARGE_INTEGER);
414 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
415 &pPatterns[i].Position, &valuesize);
417 if (res == ERROR_SUCCESS)
419 pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
420 valuesize = length;
421 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
422 pPatterns[i].Pattern, &valuesize);
425 if (res == ERROR_SUCCESS)
427 pPatterns[i].Mask = bPatterns+patterns_size-length;
428 valuesize = length;
429 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
430 pPatterns[i].Mask, &valuesize);
434 RegCloseKey(patternkey);
436 if (res != ERROR_SUCCESS)
438 hr = HRESULT_FROM_WIN32(res);
439 break;
443 else hr = HRESULT_FROM_WIN32(res);
445 RegCloseKey(patternskey);
447 if (hr == S_OK)
449 *pcPatterns = pattern_count;
450 *pcbPatternsActual = patterns_size;
451 if (pPatterns && cbSizePatterns < patterns_size)
452 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
455 return hr;
458 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
459 IStream *pIStream, BOOL *pfMatches)
461 WICBitmapPattern *patterns;
462 UINT pattern_count=0, patterns_size=0;
463 HRESULT hr;
464 int i, pos;
465 BYTE *data=NULL;
466 ULONG datasize=0;
467 ULONG bytesread;
468 LARGE_INTEGER seekpos;
470 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
472 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
473 if (FAILED(hr)) return hr;
475 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
476 if (!patterns) return E_OUTOFMEMORY;
478 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
479 if (FAILED(hr)) goto end;
481 for (i=0; i<pattern_count; i++)
483 if (datasize < patterns[i].Length)
485 HeapFree(GetProcessHeap(), 0, data);
486 datasize = patterns[i].Length;
487 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
488 if (!data)
490 hr = E_OUTOFMEMORY;
491 break;
495 if (patterns[i].EndOfStream)
496 seekpos.QuadPart = -patterns[i].Position.QuadPart;
497 else
498 seekpos.QuadPart = patterns[i].Position.QuadPart;
499 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
500 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
501 if (FAILED(hr)) break;
503 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
504 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
505 continue;
506 if (FAILED(hr)) break;
508 for (pos=0; pos<patterns[i].Length; pos++)
510 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
511 break;
513 if (pos == patterns[i].Length) /* matches pattern */
515 hr = S_OK;
516 *pfMatches = TRUE;
517 break;
521 if (i == pattern_count) /* does not match any pattern */
523 hr = S_OK;
524 *pfMatches = FALSE;
527 end:
528 HeapFree(GetProcessHeap(), 0, patterns);
529 HeapFree(GetProcessHeap(), 0, data);
531 return hr;
534 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
535 IWICBitmapDecoder **ppIBitmapDecoder)
537 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
539 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
541 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
542 &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
545 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
546 BitmapDecoderInfo_QueryInterface,
547 BitmapDecoderInfo_AddRef,
548 BitmapDecoderInfo_Release,
549 BitmapDecoderInfo_GetComponentType,
550 BitmapDecoderInfo_GetCLSID,
551 BitmapDecoderInfo_GetSigningStatus,
552 BitmapDecoderInfo_GetAuthor,
553 BitmapDecoderInfo_GetVendorGUID,
554 BitmapDecoderInfo_GetVersion,
555 BitmapDecoderInfo_GetSpecVersion,
556 BitmapDecoderInfo_GetFriendlyName,
557 BitmapDecoderInfo_GetContainerFormat,
558 BitmapDecoderInfo_GetPixelFormats,
559 BitmapDecoderInfo_GetColorManagementVersion,
560 BitmapDecoderInfo_GetDeviceManufacturer,
561 BitmapDecoderInfo_GetDeviceModels,
562 BitmapDecoderInfo_GetMimeTypes,
563 BitmapDecoderInfo_GetFileExtensions,
564 BitmapDecoderInfo_DoesSupportAnimation,
565 BitmapDecoderInfo_DoesSupportChromaKey,
566 BitmapDecoderInfo_DoesSupportLossless,
567 BitmapDecoderInfo_DoesSupportMultiframe,
568 BitmapDecoderInfo_MatchesMimeType,
569 BitmapDecoderInfo_GetPatterns,
570 BitmapDecoderInfo_MatchesPattern,
571 BitmapDecoderInfo_CreateInstance
574 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
576 BitmapDecoderInfo *This;
578 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
579 if (!This)
581 RegCloseKey(classkey);
582 return E_OUTOFMEMORY;
585 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
586 This->ref = 1;
587 This->classkey = classkey;
588 memcpy(&This->clsid, clsid, sizeof(CLSID));
590 *ppIInfo = (IWICComponentInfo*)This;
591 return S_OK;
594 typedef struct {
595 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
596 LONG ref;
597 HKEY classkey;
598 CLSID clsid;
599 } BitmapEncoderInfo;
601 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
603 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
606 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
607 void **ppv)
609 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
610 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
612 if (!ppv) return E_INVALIDARG;
614 if (IsEqualIID(&IID_IUnknown, iid) ||
615 IsEqualIID(&IID_IWICComponentInfo, iid) ||
616 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
617 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
619 *ppv = This;
621 else
623 *ppv = NULL;
624 return E_NOINTERFACE;
627 IUnknown_AddRef((IUnknown*)*ppv);
628 return S_OK;
631 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
633 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
634 ULONG ref = InterlockedIncrement(&This->ref);
636 TRACE("(%p) refcount=%u\n", iface, ref);
638 return ref;
641 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
643 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
644 ULONG ref = InterlockedDecrement(&This->ref);
646 TRACE("(%p) refcount=%u\n", iface, ref);
648 if (ref == 0)
650 RegCloseKey(This->classkey);
651 HeapFree(GetProcessHeap(), 0, This);
654 return ref;
657 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
658 WICComponentType *pType)
660 TRACE("(%p,%p)\n", iface, pType);
661 if (!pType) return E_INVALIDARG;
662 *pType = WICEncoder;
663 return S_OK;
666 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
668 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
669 TRACE("(%p,%p)\n", iface, pclsid);
671 if (!pclsid)
672 return E_INVALIDARG;
674 memcpy(pclsid, &This->clsid, sizeof(CLSID));
676 return S_OK;
679 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
681 FIXME("(%p,%p): stub\n", iface, pStatus);
682 return E_NOTIMPL;
685 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
686 WCHAR *wzAuthor, UINT *pcchActual)
688 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
690 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
692 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
693 cchAuthor, wzAuthor, pcchActual);
696 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
698 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
700 TRACE("(%p,%p)\n", iface, pguidVendor);
702 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
705 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
706 WCHAR *wzVersion, UINT *pcchActual)
708 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
710 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
712 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
713 cchVersion, wzVersion, pcchActual);
716 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
717 WCHAR *wzSpecVersion, UINT *pcchActual)
719 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
720 return E_NOTIMPL;
723 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
724 WCHAR *wzFriendlyName, UINT *pcchActual)
726 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
728 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
730 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
731 cchFriendlyName, wzFriendlyName, pcchActual);
734 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
735 GUID *pguidContainerFormat)
737 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
738 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
739 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
742 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
743 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
745 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
746 return E_NOTIMPL;
749 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
750 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
752 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
753 return E_NOTIMPL;
756 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
757 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
759 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
760 return E_NOTIMPL;
763 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
764 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
766 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
767 return E_NOTIMPL;
770 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
771 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
773 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
775 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
777 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
778 cchMimeTypes, wzMimeTypes, pcchActual);
781 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
782 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
784 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
785 return E_NOTIMPL;
788 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
789 BOOL *pfSupportAnimation)
791 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
792 return E_NOTIMPL;
795 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
796 BOOL *pfSupportChromaKey)
798 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
799 return E_NOTIMPL;
802 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
803 BOOL *pfSupportLossless)
805 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
806 return E_NOTIMPL;
809 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
810 BOOL *pfSupportMultiframe)
812 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
813 return E_NOTIMPL;
816 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
817 LPCWSTR wzMimeType, BOOL *pfMatches)
819 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
820 return E_NOTIMPL;
823 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
824 IWICBitmapEncoder **ppIBitmapEncoder)
826 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
828 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
830 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
831 &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
834 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
835 BitmapEncoderInfo_QueryInterface,
836 BitmapEncoderInfo_AddRef,
837 BitmapEncoderInfo_Release,
838 BitmapEncoderInfo_GetComponentType,
839 BitmapEncoderInfo_GetCLSID,
840 BitmapEncoderInfo_GetSigningStatus,
841 BitmapEncoderInfo_GetAuthor,
842 BitmapEncoderInfo_GetVendorGUID,
843 BitmapEncoderInfo_GetVersion,
844 BitmapEncoderInfo_GetSpecVersion,
845 BitmapEncoderInfo_GetFriendlyName,
846 BitmapEncoderInfo_GetContainerFormat,
847 BitmapEncoderInfo_GetPixelFormats,
848 BitmapEncoderInfo_GetColorManagementVersion,
849 BitmapEncoderInfo_GetDeviceManufacturer,
850 BitmapEncoderInfo_GetDeviceModels,
851 BitmapEncoderInfo_GetMimeTypes,
852 BitmapEncoderInfo_GetFileExtensions,
853 BitmapEncoderInfo_DoesSupportAnimation,
854 BitmapEncoderInfo_DoesSupportChromaKey,
855 BitmapEncoderInfo_DoesSupportLossless,
856 BitmapEncoderInfo_DoesSupportMultiframe,
857 BitmapEncoderInfo_MatchesMimeType,
858 BitmapEncoderInfo_CreateInstance
861 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
863 BitmapEncoderInfo *This;
865 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
866 if (!This)
868 RegCloseKey(classkey);
869 return E_OUTOFMEMORY;
872 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
873 This->ref = 1;
874 This->classkey = classkey;
875 memcpy(&This->clsid, clsid, sizeof(CLSID));
877 *ppIInfo = (IWICComponentInfo*)This;
878 return S_OK;
881 typedef struct {
882 IWICFormatConverterInfo IWICFormatConverterInfo_iface;
883 LONG ref;
884 HKEY classkey;
885 CLSID clsid;
886 } FormatConverterInfo;
888 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
890 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
893 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
894 void **ppv)
896 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
897 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
899 if (!ppv) return E_INVALIDARG;
901 if (IsEqualIID(&IID_IUnknown, iid) ||
902 IsEqualIID(&IID_IWICComponentInfo, iid) ||
903 IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
905 *ppv = This;
907 else
909 *ppv = NULL;
910 return E_NOINTERFACE;
913 IUnknown_AddRef((IUnknown*)*ppv);
914 return S_OK;
917 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
919 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
920 ULONG ref = InterlockedIncrement(&This->ref);
922 TRACE("(%p) refcount=%u\n", iface, ref);
924 return ref;
927 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
929 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
930 ULONG ref = InterlockedDecrement(&This->ref);
932 TRACE("(%p) refcount=%u\n", iface, ref);
934 if (ref == 0)
936 RegCloseKey(This->classkey);
937 HeapFree(GetProcessHeap(), 0, This);
940 return ref;
943 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
944 WICComponentType *pType)
946 TRACE("(%p,%p)\n", iface, pType);
947 if (!pType) return E_INVALIDARG;
948 *pType = WICPixelFormatConverter;
949 return S_OK;
952 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
954 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
955 TRACE("(%p,%p)\n", iface, pclsid);
957 if (!pclsid)
958 return E_INVALIDARG;
960 memcpy(pclsid, &This->clsid, sizeof(CLSID));
962 return S_OK;
965 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
967 FIXME("(%p,%p): stub\n", iface, pStatus);
968 return E_NOTIMPL;
971 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
972 WCHAR *wzAuthor, UINT *pcchActual)
974 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
976 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
978 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
979 cchAuthor, wzAuthor, pcchActual);
982 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
984 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
986 TRACE("(%p,%p)\n", iface, pguidVendor);
988 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
991 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
992 WCHAR *wzVersion, UINT *pcchActual)
994 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
996 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
998 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
999 cchVersion, wzVersion, pcchActual);
1002 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
1003 WCHAR *wzSpecVersion, UINT *pcchActual)
1005 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1006 return E_NOTIMPL;
1009 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
1010 WCHAR *wzFriendlyName, UINT *pcchActual)
1012 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1014 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1016 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1017 cchFriendlyName, wzFriendlyName, pcchActual);
1020 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
1021 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
1023 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
1024 return E_NOTIMPL;
1027 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
1028 IWICFormatConverter **ppIFormatConverter)
1030 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1032 TRACE("(%p,%p)\n", iface, ppIFormatConverter);
1034 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1035 &IID_IWICFormatConverter, (void**)ppIFormatConverter);
1038 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
1040 LONG res;
1041 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1042 HKEY formats_key, guid_key;
1044 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
1045 would be O(n). A registry test should do better. */
1047 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
1048 if (res != ERROR_SUCCESS) return FALSE;
1050 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
1051 if (res == ERROR_SUCCESS) RegCloseKey(guid_key);
1053 RegCloseKey(formats_key);
1055 return (res == ERROR_SUCCESS);
1058 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
1059 FormatConverterInfo_QueryInterface,
1060 FormatConverterInfo_AddRef,
1061 FormatConverterInfo_Release,
1062 FormatConverterInfo_GetComponentType,
1063 FormatConverterInfo_GetCLSID,
1064 FormatConverterInfo_GetSigningStatus,
1065 FormatConverterInfo_GetAuthor,
1066 FormatConverterInfo_GetVendorGUID,
1067 FormatConverterInfo_GetVersion,
1068 FormatConverterInfo_GetSpecVersion,
1069 FormatConverterInfo_GetFriendlyName,
1070 FormatConverterInfo_GetPixelFormats,
1071 FormatConverterInfo_CreateInstance
1074 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1076 FormatConverterInfo *This;
1078 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
1079 if (!This)
1081 RegCloseKey(classkey);
1082 return E_OUTOFMEMORY;
1085 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
1086 This->ref = 1;
1087 This->classkey = classkey;
1088 memcpy(&This->clsid, clsid, sizeof(CLSID));
1090 *ppIInfo = (IWICComponentInfo*)This;
1091 return S_OK;
1094 typedef struct {
1095 IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface;
1096 LONG ref;
1097 HKEY classkey;
1098 CLSID clsid;
1099 } PixelFormatInfo;
1101 static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2 *iface)
1103 return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface);
1106 static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID iid,
1107 void **ppv)
1109 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1110 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1112 if (!ppv) return E_INVALIDARG;
1114 if (IsEqualIID(&IID_IUnknown, iid) ||
1115 IsEqualIID(&IID_IWICComponentInfo, iid) ||
1116 IsEqualIID(&IID_IWICPixelFormatInfo, iid) ||
1117 IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid))
1119 *ppv = This;
1121 else
1123 *ppv = NULL;
1124 return E_NOINTERFACE;
1127 IUnknown_AddRef((IUnknown*)*ppv);
1128 return S_OK;
1131 static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface)
1133 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1134 ULONG ref = InterlockedIncrement(&This->ref);
1136 TRACE("(%p) refcount=%u\n", iface, ref);
1138 return ref;
1141 static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface)
1143 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1144 ULONG ref = InterlockedDecrement(&This->ref);
1146 TRACE("(%p) refcount=%u\n", iface, ref);
1148 if (ref == 0)
1150 RegCloseKey(This->classkey);
1151 HeapFree(GetProcessHeap(), 0, This);
1154 return ref;
1157 static HRESULT WINAPI PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2 *iface,
1158 WICComponentType *pType)
1160 TRACE("(%p,%p)\n", iface, pType);
1161 if (!pType) return E_INVALIDARG;
1162 *pType = WICPixelFormat;
1163 return S_OK;
1166 static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2 *iface, CLSID *pclsid)
1168 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1169 TRACE("(%p,%p)\n", iface, pclsid);
1171 if (!pclsid)
1172 return E_INVALIDARG;
1174 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1176 return S_OK;
1179 static HRESULT WINAPI PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2 *iface, DWORD *pStatus)
1181 TRACE("(%p,%p)\n", iface, pStatus);
1183 if (!pStatus)
1184 return E_INVALIDARG;
1186 /* Pixel formats don't require code, so they are considered signed. */
1187 *pStatus = WICComponentSigned;
1189 return S_OK;
1192 static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UINT cchAuthor,
1193 WCHAR *wzAuthor, UINT *pcchActual)
1195 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1197 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1199 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1200 cchAuthor, wzAuthor, pcchActual);
1203 static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor)
1205 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1207 TRACE("(%p,%p)\n", iface, pguidVendor);
1209 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1212 static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion,
1213 WCHAR *wzVersion, UINT *pcchActual)
1215 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1217 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1219 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1220 cchVersion, wzVersion, pcchActual);
1223 static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface, UINT cchSpecVersion,
1224 WCHAR *wzSpecVersion, UINT *pcchActual)
1226 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1227 return E_NOTIMPL;
1230 static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *iface, UINT cchFriendlyName,
1231 WCHAR *wzFriendlyName, UINT *pcchActual)
1233 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1235 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1237 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1238 cchFriendlyName, wzFriendlyName, pcchActual);
1241 static HRESULT WINAPI PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface,
1242 GUID *pFormat)
1244 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1245 TRACE("(%p,%p)\n", iface, pFormat);
1247 if (!pFormat)
1248 return E_INVALIDARG;
1250 *pFormat = This->clsid;
1252 return S_OK;
1255 static HRESULT WINAPI PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2 *iface,
1256 IWICColorContext **ppIColorContext)
1258 FIXME("(%p,%p): stub\n", iface, ppIColorContext);
1259 return E_NOTIMPL;
1262 static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *iface,
1263 UINT *puiBitsPerPixel)
1265 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1267 TRACE("(%p,%p)\n", iface, puiBitsPerPixel);
1269 return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel);
1272 static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface,
1273 UINT *puiChannelCount)
1275 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1277 TRACE("(%p,%p)\n", iface, puiChannelCount);
1279 return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount);
1282 static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface,
1283 UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual)
1285 static const WCHAR uintformatW[] = {'%','u',0};
1286 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1287 UINT channel_count;
1288 HRESULT hr;
1289 LONG ret;
1290 WCHAR valuename[11];
1291 DWORD cbData;
1293 TRACE("(%p,%u,%u,%p,%p)\n", iface, uiChannelIndex, cbMaskBuffer, pbMaskBuffer, pcbActual);
1295 if (!pcbActual)
1296 return E_INVALIDARG;
1298 hr = PixelFormatInfo_GetChannelCount(iface, &channel_count);
1300 if (SUCCEEDED(hr) && uiChannelIndex >= channel_count)
1301 hr = E_INVALIDARG;
1303 if (SUCCEEDED(hr))
1305 snprintfW(valuename, 11, uintformatW, uiChannelIndex);
1307 cbData = cbMaskBuffer;
1309 ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData);
1311 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
1312 *pcbActual = cbData;
1314 if (ret == ERROR_MORE_DATA)
1315 hr = E_INVALIDARG;
1316 else
1317 hr = HRESULT_FROM_WIN32(ret);
1320 return hr;
1323 static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 *iface,
1324 BOOL *pfSupportsTransparency)
1326 FIXME("(%p,%p): stub\n", iface, pfSupportsTransparency);
1327 return E_NOTIMPL;
1330 static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface,
1331 WICPixelFormatNumericRepresentation *pNumericRepresentation)
1333 FIXME("(%p,%p): stub\n", iface, pNumericRepresentation);
1334 return E_NOTIMPL;
1337 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = {
1338 PixelFormatInfo_QueryInterface,
1339 PixelFormatInfo_AddRef,
1340 PixelFormatInfo_Release,
1341 PixelFormatInfo_GetComponentType,
1342 PixelFormatInfo_GetCLSID,
1343 PixelFormatInfo_GetSigningStatus,
1344 PixelFormatInfo_GetAuthor,
1345 PixelFormatInfo_GetVendorGUID,
1346 PixelFormatInfo_GetVersion,
1347 PixelFormatInfo_GetSpecVersion,
1348 PixelFormatInfo_GetFriendlyName,
1349 PixelFormatInfo_GetFormatGUID,
1350 PixelFormatInfo_GetColorContext,
1351 PixelFormatInfo_GetBitsPerPixel,
1352 PixelFormatInfo_GetChannelCount,
1353 PixelFormatInfo_GetChannelMask,
1354 PixelFormatInfo_SupportsTransparency,
1355 PixelFormatInfo_GetNumericRepresentation
1358 static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1360 PixelFormatInfo *This;
1362 This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo));
1363 if (!This)
1365 RegCloseKey(classkey);
1366 return E_OUTOFMEMORY;
1369 This->IWICPixelFormatInfo2_iface.lpVtbl = &PixelFormatInfo_Vtbl;
1370 This->ref = 1;
1371 This->classkey = classkey;
1372 memcpy(&This->clsid, clsid, sizeof(CLSID));
1374 *ppIInfo = (IWICComponentInfo*)This;
1375 return S_OK;
1378 typedef struct
1380 IWICMetadataReaderInfo IWICMetadataReaderInfo_iface;
1381 LONG ref;
1382 HKEY classkey;
1383 CLSID clsid;
1384 } MetadataReaderInfo;
1386 static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo *iface)
1388 return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface);
1391 static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface,
1392 REFIID riid, void **ppv)
1394 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1396 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
1398 if (!ppv) return E_INVALIDARG;
1400 if (IsEqualIID(&IID_IUnknown, riid) ||
1401 IsEqualIID(&IID_IWICComponentInfo, riid) ||
1402 IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) ||
1403 IsEqualIID(&IID_IWICMetadataReaderInfo, riid))
1405 *ppv = This;
1407 else
1409 *ppv = NULL;
1410 return E_NOINTERFACE;
1413 IUnknown_AddRef((IUnknown *)*ppv);
1414 return S_OK;
1417 static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
1419 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1420 ULONG ref = InterlockedIncrement(&This->ref);
1422 TRACE("(%p) refcount=%u\n", iface, ref);
1423 return ref;
1426 static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface)
1428 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1429 ULONG ref = InterlockedDecrement(&This->ref);
1431 TRACE("(%p) refcount=%u\n", iface, ref);
1433 if (!ref)
1435 RegCloseKey(This->classkey);
1436 HeapFree(GetProcessHeap(), 0, This);
1438 return ref;
1441 static HRESULT WINAPI MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo *iface,
1442 WICComponentType *type)
1444 TRACE("(%p,%p)\n", iface, type);
1446 if (!type) return E_INVALIDARG;
1447 *type = WICMetadataReader;
1448 return S_OK;
1451 static HRESULT WINAPI MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface,
1452 CLSID *clsid)
1454 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1456 TRACE("(%p,%p)\n", iface, clsid);
1458 if (!clsid) return E_INVALIDARG;
1459 *clsid = This->clsid;
1460 return S_OK;
1463 static HRESULT WINAPI MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo *iface,
1464 DWORD *status)
1466 FIXME("(%p,%p): stub\n", iface, status);
1467 return E_NOTIMPL;
1470 static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface,
1471 UINT length, WCHAR *author, UINT *actual_length)
1473 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1475 TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length);
1477 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1478 length, author, actual_length);
1481 static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface,
1482 GUID *vendor)
1484 FIXME("(%p,%p): stub\n", iface, vendor);
1485 return E_NOTIMPL;
1488 static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface,
1489 UINT length, WCHAR *version, UINT *actual_length)
1491 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1493 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1495 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1496 length, version, actual_length);
1499 static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface,
1500 UINT length, WCHAR *version, UINT *actual_length)
1502 FIXME("(%p,%u,%p,%p): stub\n", iface, length, version, actual_length);
1503 return E_NOTIMPL;
1506 static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo *iface,
1507 UINT length, WCHAR *name, UINT *actual_length)
1509 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1511 TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length);
1513 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1514 length, name, actual_length);
1517 static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo *iface,
1518 GUID *format)
1520 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1521 TRACE("(%p,%p)\n", iface, format);
1522 return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format);
1525 static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface,
1526 UINT length, GUID *formats, UINT *actual_length)
1528 if (!actual_length) return E_INVALIDARG;
1530 FIXME("(%p,%u,%p,%p): stub\n", iface, length, formats, actual_length);
1531 return E_NOTIMPL;
1534 static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo *iface,
1535 UINT length, WCHAR *manufacturer, UINT *actual_length)
1537 FIXME("(%p,%u,%p,%p): stub\n", iface, length, manufacturer, actual_length);
1538 return E_NOTIMPL;
1541 static HRESULT WINAPI MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo *iface,
1542 UINT length, WCHAR *models, UINT *actual_length)
1544 FIXME("(%p,%u,%p,%p): stub\n", iface, length, models, actual_length);
1545 return E_NOTIMPL;
1548 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo *iface,
1549 BOOL *param)
1551 FIXME("(%p,%p): stub\n", iface, param);
1552 return E_NOTIMPL;
1555 static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface,
1556 BOOL *param)
1558 FIXME("(%p,%p): stub\n", iface, param);
1559 return E_NOTIMPL;
1562 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface,
1563 BOOL *param)
1565 FIXME("(%p,%p): stub\n", iface, param);
1566 return E_NOTIMPL;
1569 static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface,
1570 REFGUID container, UINT length, WICMetadataPattern *pattern, UINT *count, UINT *actual_length)
1572 if (!actual_length) return E_INVALIDARG;
1574 FIXME("(%p,%s,%u,%p,%p,%p): stub\n", iface, debugstr_guid(container), length, pattern, count, actual_length);
1575 return E_NOTIMPL;
1578 static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface,
1579 REFGUID container, IStream *stream, BOOL *matches)
1581 FIXME("(%p,%s,%p,%p): stub\n", iface, debugstr_guid(container), stream, matches);
1582 return E_NOTIMPL;
1585 static HRESULT WINAPI MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *iface,
1586 IWICMetadataReader **reader)
1588 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1590 TRACE("(%p,%p)\n", iface, reader);
1592 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1593 &IID_IWICMetadataReader, (void **)reader);
1596 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = {
1597 MetadataReaderInfo_QueryInterface,
1598 MetadataReaderInfo_AddRef,
1599 MetadataReaderInfo_Release,
1600 MetadataReaderInfo_GetComponentType,
1601 MetadataReaderInfo_GetCLSID,
1602 MetadataReaderInfo_GetSigningStatus,
1603 MetadataReaderInfo_GetAuthor,
1604 MetadataReaderInfo_GetVendorGUID,
1605 MetadataReaderInfo_GetVersion,
1606 MetadataReaderInfo_GetSpecVersion,
1607 MetadataReaderInfo_GetFriendlyName,
1608 MetadataReaderInfo_GetMetadataFormat,
1609 MetadataReaderInfo_GetContainerFormats,
1610 MetadataReaderInfo_GetDeviceManufacturer,
1611 MetadataReaderInfo_GetDeviceModels,
1612 MetadataReaderInfo_DoesRequireFullStream,
1613 MetadataReaderInfo_DoesSupportPadding,
1614 MetadataReaderInfo_DoesRequireFixedSize,
1615 MetadataReaderInfo_GetPatterns,
1616 MetadataReaderInfo_MatchesPattern,
1617 MetadataReaderInfo_CreateInstance
1620 static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **info)
1622 MetadataReaderInfo *This;
1624 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1625 if (!This)
1627 RegCloseKey(classkey);
1628 return E_OUTOFMEMORY;
1631 This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl;
1632 This->ref = 1;
1633 This->classkey = classkey;
1634 This->clsid = *clsid;
1636 *info = (IWICComponentInfo *)This;
1637 return S_OK;
1640 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
1641 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
1643 struct category {
1644 WICComponentType type;
1645 const GUID *catid;
1646 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
1649 static const struct category categories[] = {
1650 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
1651 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
1652 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
1653 {WICPixelFormat, &CATID_WICPixelFormats, PixelFormatInfo_Constructor},
1654 {WICMetadataReader, &CATID_WICMetadataReader, MetadataReaderInfo_Constructor},
1658 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
1660 HKEY clsidkey;
1661 HKEY classkey;
1662 HKEY catidkey;
1663 HKEY instancekey;
1664 WCHAR guidstring[39];
1665 LONG res;
1666 const struct category *category;
1667 int found=0;
1668 HRESULT hr;
1670 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1671 if (res != ERROR_SUCCESS)
1672 return HRESULT_FROM_WIN32(res);
1674 for (category=categories; category->type; category++)
1676 StringFromGUID2(category->catid, guidstring, 39);
1677 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1678 if (res == ERROR_SUCCESS)
1680 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1681 if (res == ERROR_SUCCESS)
1683 StringFromGUID2(clsid, guidstring, 39);
1684 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
1685 if (res == ERROR_SUCCESS)
1687 RegCloseKey(classkey);
1688 found = 1;
1690 RegCloseKey(instancekey);
1692 RegCloseKey(catidkey);
1694 if (found) break;
1697 if (found)
1699 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
1700 if (res == ERROR_SUCCESS)
1701 hr = category->constructor(classkey, clsid, ppIInfo);
1702 else
1703 hr = HRESULT_FROM_WIN32(res);
1705 else
1707 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid));
1708 hr = E_FAIL;
1711 RegCloseKey(clsidkey);
1713 return hr;
1716 typedef struct {
1717 IEnumUnknown IEnumUnknown_iface;
1718 LONG ref;
1719 struct list objects;
1720 struct list *cursor;
1721 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
1722 } ComponentEnum;
1724 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
1726 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
1729 typedef struct {
1730 struct list entry;
1731 IUnknown *unk;
1732 } ComponentEnumItem;
1734 static const IEnumUnknownVtbl ComponentEnumVtbl;
1736 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
1737 void **ppv)
1739 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1740 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1742 if (!ppv) return E_INVALIDARG;
1744 if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IEnumUnknown, iid))
1746 *ppv = This;
1748 else
1750 *ppv = NULL;
1751 return E_NOINTERFACE;
1754 IUnknown_AddRef((IUnknown*)*ppv);
1755 return S_OK;
1758 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
1760 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1761 ULONG ref = InterlockedIncrement(&This->ref);
1763 TRACE("(%p) refcount=%u\n", iface, ref);
1765 return ref;
1768 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
1770 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1771 ULONG ref = InterlockedDecrement(&This->ref);
1772 ComponentEnumItem *cursor, *cursor2;
1774 TRACE("(%p) refcount=%u\n", iface, ref);
1776 if (ref == 0)
1778 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
1780 IUnknown_Release(cursor->unk);
1781 list_remove(&cursor->entry);
1782 HeapFree(GetProcessHeap(), 0, cursor);
1784 This->lock.DebugInfo->Spare[0] = 0;
1785 DeleteCriticalSection(&This->lock);
1786 HeapFree(GetProcessHeap(), 0, This);
1789 return ref;
1792 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
1793 IUnknown **rgelt, ULONG *pceltFetched)
1795 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1796 int num_fetched=0;
1797 ComponentEnumItem *item;
1798 HRESULT hr=S_OK;
1800 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
1802 EnterCriticalSection(&This->lock);
1803 while (num_fetched<celt)
1805 if (!This->cursor)
1807 hr = S_FALSE;
1808 break;
1810 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
1811 IUnknown_AddRef(item->unk);
1812 rgelt[num_fetched] = item->unk;
1813 num_fetched++;
1814 This->cursor = list_next(&This->objects, This->cursor);
1816 LeaveCriticalSection(&This->lock);
1817 if (pceltFetched)
1818 *pceltFetched = num_fetched;
1819 return hr;
1822 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
1824 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1825 int i;
1826 HRESULT hr=S_OK;
1828 TRACE("(%p,%u)\n", iface, celt);
1830 EnterCriticalSection(&This->lock);
1831 for (i=0; i<celt; i++)
1833 if (!This->cursor)
1835 hr = S_FALSE;
1836 break;
1838 This->cursor = list_next(&This->objects, This->cursor);
1840 LeaveCriticalSection(&This->lock);
1841 return hr;
1844 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
1846 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1848 TRACE("(%p)\n", iface);
1850 EnterCriticalSection(&This->lock);
1851 This->cursor = list_head(&This->objects);
1852 LeaveCriticalSection(&This->lock);
1853 return S_OK;
1856 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
1858 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1859 ComponentEnum *new_enum;
1860 ComponentEnumItem *old_item, *new_item;
1861 HRESULT ret=S_OK;
1862 struct list *old_cursor;
1864 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1865 if (!new_enum)
1867 *ppenum = NULL;
1868 return E_OUTOFMEMORY;
1871 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1872 new_enum->ref = 1;
1873 new_enum->cursor = NULL;
1874 list_init(&new_enum->objects);
1875 InitializeCriticalSection(&new_enum->lock);
1876 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1878 EnterCriticalSection(&This->lock);
1879 old_cursor = This->cursor;
1880 LeaveCriticalSection(&This->lock);
1882 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
1884 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1885 if (!new_item)
1887 ret = E_OUTOFMEMORY;
1888 break;
1890 new_item->unk = old_item->unk;
1891 list_add_tail(&new_enum->objects, &new_item->entry);
1892 IUnknown_AddRef(new_item->unk);
1893 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
1896 if (FAILED(ret))
1898 IUnknown_Release((IUnknown*)new_enum);
1899 *ppenum = NULL;
1901 else
1902 *ppenum = (IEnumUnknown*)new_enum;
1904 return ret;
1907 static const IEnumUnknownVtbl ComponentEnumVtbl = {
1908 ComponentEnum_QueryInterface,
1909 ComponentEnum_AddRef,
1910 ComponentEnum_Release,
1911 ComponentEnum_Next,
1912 ComponentEnum_Skip,
1913 ComponentEnum_Reset,
1914 ComponentEnum_Clone
1917 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
1919 ComponentEnum *This;
1920 ComponentEnumItem *item;
1921 const struct category *category;
1922 HKEY clsidkey, catidkey, instancekey;
1923 WCHAR guidstring[39];
1924 LONG res;
1925 int i;
1926 HRESULT hr=S_OK;
1927 CLSID clsid;
1929 if (options) FIXME("ignoring flags %x\n", options);
1931 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1932 if (res != ERROR_SUCCESS)
1933 return HRESULT_FROM_WIN32(res);
1935 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1936 if (!This)
1938 RegCloseKey(clsidkey);
1939 return E_OUTOFMEMORY;
1942 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1943 This->ref = 1;
1944 list_init(&This->objects);
1945 InitializeCriticalSection(&This->lock);
1946 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1948 for (category=categories; category->type && hr == S_OK; category++)
1950 if ((category->type & componentTypes) == 0) continue;
1951 StringFromGUID2(category->catid, guidstring, 39);
1952 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1953 if (res == ERROR_SUCCESS)
1955 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1956 if (res == ERROR_SUCCESS)
1958 i=0;
1959 for (;;i++)
1961 DWORD guidstring_size = 39;
1962 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
1963 if (res != ERROR_SUCCESS) break;
1965 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1966 if (!item) { hr = E_OUTOFMEMORY; break; }
1968 hr = CLSIDFromString(guidstring, &clsid);
1969 if (SUCCEEDED(hr))
1971 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
1972 if (SUCCEEDED(hr))
1973 list_add_tail(&This->objects, &item->entry);
1976 if (FAILED(hr))
1978 HeapFree(GetProcessHeap(), 0, item);
1979 hr = S_OK;
1982 RegCloseKey(instancekey);
1984 RegCloseKey(catidkey);
1986 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
1987 hr = HRESULT_FROM_WIN32(res);
1989 RegCloseKey(clsidkey);
1991 if (SUCCEEDED(hr))
1993 IEnumUnknown_Reset((IEnumUnknown*)This);
1994 *ppIEnumUnknown = (IEnumUnknown*)This;
1996 else
1998 *ppIEnumUnknown = NULL;
1999 IUnknown_Release((IUnknown*)This);
2002 return hr;
2005 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
2007 HRESULT res;
2008 IEnumUnknown *enumconverters;
2009 IUnknown *unkconverterinfo;
2010 IWICFormatConverterInfo *converterinfo=NULL;
2011 IWICFormatConverter *converter=NULL;
2012 GUID srcFormat;
2013 WCHAR srcformatstr[39], dstformatstr[39];
2014 BOOL canconvert;
2015 ULONG num_fetched;
2017 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
2018 if (FAILED(res)) return res;
2020 if (IsEqualGUID(&srcFormat, dstFormat))
2022 IWICBitmapSource_AddRef(pISrc);
2023 *ppIDst = pISrc;
2024 return S_OK;
2027 StringFromGUID2(&srcFormat, srcformatstr, 39);
2028 StringFromGUID2(dstFormat, dstformatstr, 39);
2030 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
2031 if (FAILED(res)) return res;
2033 while (!converter)
2035 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);
2037 if (res == S_OK)
2039 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);
2041 if (SUCCEEDED(res))
2043 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);
2045 if (canconvert)
2046 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);
2048 if (canconvert)
2050 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);
2052 if (SUCCEEDED(res))
2053 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);
2055 if (SUCCEEDED(res) && canconvert)
2056 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
2057 NULL, 0.0, WICBitmapPaletteTypeCustom);
2059 if (FAILED(res) || !canconvert)
2061 if (converter)
2063 IWICFormatConverter_Release(converter);
2064 converter = NULL;
2066 res = S_OK;
2070 IWICFormatConverterInfo_Release(converterinfo);
2073 IUnknown_Release(unkconverterinfo);
2075 else
2076 break;
2079 IEnumUnknown_Release(enumconverters);
2081 if (converter)
2083 *ppIDst = (IWICBitmapSource*)converter;
2084 return S_OK;
2086 else
2088 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
2089 *ppIDst = NULL;
2090 return WINCODEC_ERR_COMPONENTNOTFOUND;