windowscodecs: Implement IWICPixelFormatInfo2::GetNumericRepresentation.
[wine/multimedia.git] / dlls / windowscodecs / info.c
blob1b650d6c051297cff221d77d244f25b3346d969b
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};
52 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};
54 static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value,
55 UINT buffer_size, WCHAR *buffer, UINT *actual_size)
57 LONG ret;
58 DWORD cbdata=buffer_size * sizeof(WCHAR);
60 if (!actual_size)
61 return E_INVALIDARG;
63 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
64 buffer, &cbdata);
66 if (ret == ERROR_FILE_NOT_FOUND)
68 *actual_size = 0;
69 return S_OK;
72 if (ret == 0 || ret == ERROR_MORE_DATA)
73 *actual_size = cbdata/sizeof(WCHAR);
75 if (!buffer && buffer_size != 0)
76 /* Yes, native returns the correct size in this case. */
77 return E_INVALIDARG;
79 if (ret == ERROR_MORE_DATA)
80 return WINCODEC_ERR_INSUFFICIENTBUFFER;
82 return HRESULT_FROM_WIN32(ret);
85 static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value,
86 GUID *result)
88 LONG ret;
89 WCHAR guid_string[39];
90 DWORD cbdata = sizeof(guid_string);
91 HRESULT hr;
93 if (!result)
94 return E_INVALIDARG;
96 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
97 guid_string, &cbdata);
99 if (ret != ERROR_SUCCESS)
100 return HRESULT_FROM_WIN32(ret);
102 if (cbdata < sizeof(guid_string))
104 ERR("incomplete GUID value\n");
105 return E_FAIL;
108 hr = CLSIDFromString(guid_string, result);
110 return hr;
113 static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value,
114 DWORD *result)
116 LONG ret;
117 DWORD cbdata = sizeof(DWORD);
119 if (!result)
120 return E_INVALIDARG;
122 ret = RegGetValueW(classkey, NULL, value, RRF_RT_DWORD, NULL,
123 result, &cbdata);
125 if (ret == ERROR_FILE_NOT_FOUND)
127 *result = 0;
128 return S_OK;
131 return HRESULT_FROM_WIN32(ret);
134 typedef struct {
135 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface;
136 LONG ref;
137 HKEY classkey;
138 CLSID clsid;
139 } BitmapDecoderInfo;
141 static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo *iface)
143 return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface);
146 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid,
147 void **ppv)
149 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
150 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
152 if (!ppv) return E_INVALIDARG;
154 if (IsEqualIID(&IID_IUnknown, iid) ||
155 IsEqualIID(&IID_IWICComponentInfo, iid) ||
156 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
157 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
159 *ppv = This;
161 else
163 *ppv = NULL;
164 return E_NOINTERFACE;
167 IUnknown_AddRef((IUnknown*)*ppv);
168 return S_OK;
171 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
173 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
174 ULONG ref = InterlockedIncrement(&This->ref);
176 TRACE("(%p) refcount=%u\n", iface, ref);
178 return ref;
181 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
183 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
184 ULONG ref = InterlockedDecrement(&This->ref);
186 TRACE("(%p) refcount=%u\n", iface, ref);
188 if (ref == 0)
190 RegCloseKey(This->classkey);
191 HeapFree(GetProcessHeap(), 0, This);
194 return ref;
197 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface,
198 WICComponentType *pType)
200 TRACE("(%p,%p)\n", iface, pType);
201 if (!pType) return E_INVALIDARG;
202 *pType = WICDecoder;
203 return S_OK;
206 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid)
208 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
209 TRACE("(%p,%p)\n", iface, pclsid);
211 if (!pclsid)
212 return E_INVALIDARG;
214 memcpy(pclsid, &This->clsid, sizeof(CLSID));
216 return S_OK;
219 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus)
221 FIXME("(%p,%p): stub\n", iface, pStatus);
222 return E_NOTIMPL;
225 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor,
226 WCHAR *wzAuthor, UINT *pcchActual)
228 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
230 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
232 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
233 cchAuthor, wzAuthor, pcchActual);
236 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
238 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
240 TRACE("(%p,%p)\n", iface, pguidVendor);
242 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
245 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
246 WCHAR *wzVersion, UINT *pcchActual)
248 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
250 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
252 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
253 cchVersion, wzVersion, pcchActual);
256 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
257 WCHAR *wzSpecVersion, UINT *pcchActual)
259 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
260 return E_NOTIMPL;
263 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
264 WCHAR *wzFriendlyName, UINT *pcchActual)
266 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
268 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
270 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
271 cchFriendlyName, wzFriendlyName, pcchActual);
274 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
275 GUID *pguidContainerFormat)
277 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
278 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
279 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
282 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
283 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
285 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
286 return E_NOTIMPL;
289 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface,
290 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
292 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
293 return E_NOTIMPL;
296 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface,
297 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
299 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
300 return E_NOTIMPL;
303 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface,
304 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
306 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
307 return E_NOTIMPL;
310 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface,
311 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
313 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
315 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
317 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
318 cchMimeTypes, wzMimeTypes, pcchActual);
321 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface,
322 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
324 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
325 return E_NOTIMPL;
328 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface,
329 BOOL *pfSupportAnimation)
331 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
332 return E_NOTIMPL;
335 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface,
336 BOOL *pfSupportChromaKey)
338 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
339 return E_NOTIMPL;
342 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface,
343 BOOL *pfSupportLossless)
345 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
346 return E_NOTIMPL;
349 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface,
350 BOOL *pfSupportMultiframe)
352 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
353 return E_NOTIMPL;
356 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface,
357 LPCWSTR wzMimeType, BOOL *pfMatches)
359 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
360 return E_NOTIMPL;
363 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface,
364 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual)
366 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
367 UINT pattern_count=0, patterns_size=0;
368 WCHAR subkeyname[11];
369 LONG res;
370 HKEY patternskey, patternkey;
371 static const WCHAR uintformatW[] = {'%','u',0};
372 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0};
373 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
374 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0};
375 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
376 static const WCHAR maskW[] = {'M','a','s','k',0};
377 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
378 HRESULT hr=S_OK;
379 UINT i;
380 BYTE *bPatterns=(BYTE*)pPatterns;
381 DWORD length, valuesize;
383 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual);
385 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
386 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
388 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
389 if (res == ERROR_SUCCESS)
391 patterns_size = pattern_count * sizeof(WICBitmapPattern);
393 for (i=0; i<pattern_count; i++)
395 snprintfW(subkeyname, 11, uintformatW, i);
396 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
397 if (res == ERROR_SUCCESS)
399 valuesize = sizeof(ULONG);
400 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
401 &length, &valuesize);
402 patterns_size += length*2;
404 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS))
406 pPatterns[i].Length = length;
408 pPatterns[i].EndOfStream = 0;
409 valuesize = sizeof(BOOL);
410 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
411 &pPatterns[i].EndOfStream, &valuesize);
413 pPatterns[i].Position.QuadPart = 0;
414 valuesize = sizeof(ULARGE_INTEGER);
415 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
416 &pPatterns[i].Position, &valuesize);
418 if (res == ERROR_SUCCESS)
420 pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
421 valuesize = length;
422 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
423 pPatterns[i].Pattern, &valuesize);
426 if (res == ERROR_SUCCESS)
428 pPatterns[i].Mask = bPatterns+patterns_size-length;
429 valuesize = length;
430 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
431 pPatterns[i].Mask, &valuesize);
435 RegCloseKey(patternkey);
437 if (res != ERROR_SUCCESS)
439 hr = HRESULT_FROM_WIN32(res);
440 break;
444 else hr = HRESULT_FROM_WIN32(res);
446 RegCloseKey(patternskey);
448 if (hr == S_OK)
450 *pcPatterns = pattern_count;
451 *pcbPatternsActual = patterns_size;
452 if (pPatterns && cbSizePatterns < patterns_size)
453 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
456 return hr;
459 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
460 IStream *pIStream, BOOL *pfMatches)
462 WICBitmapPattern *patterns;
463 UINT pattern_count=0, patterns_size=0;
464 HRESULT hr;
465 int i, pos;
466 BYTE *data=NULL;
467 ULONG datasize=0;
468 ULONG bytesread;
469 LARGE_INTEGER seekpos;
471 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
473 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
474 if (FAILED(hr)) return hr;
476 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
477 if (!patterns) return E_OUTOFMEMORY;
479 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
480 if (FAILED(hr)) goto end;
482 for (i=0; i<pattern_count; i++)
484 if (datasize < patterns[i].Length)
486 HeapFree(GetProcessHeap(), 0, data);
487 datasize = patterns[i].Length;
488 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
489 if (!data)
491 hr = E_OUTOFMEMORY;
492 break;
496 if (patterns[i].EndOfStream)
497 seekpos.QuadPart = -patterns[i].Position.QuadPart;
498 else
499 seekpos.QuadPart = patterns[i].Position.QuadPart;
500 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
501 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
502 if (FAILED(hr)) break;
504 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
505 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
506 continue;
507 if (FAILED(hr)) break;
509 for (pos=0; pos<patterns[i].Length; pos++)
511 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
512 break;
514 if (pos == patterns[i].Length) /* matches pattern */
516 hr = S_OK;
517 *pfMatches = TRUE;
518 break;
522 if (i == pattern_count) /* does not match any pattern */
524 hr = S_OK;
525 *pfMatches = FALSE;
528 end:
529 HeapFree(GetProcessHeap(), 0, patterns);
530 HeapFree(GetProcessHeap(), 0, data);
532 return hr;
535 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
536 IWICBitmapDecoder **ppIBitmapDecoder)
538 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
540 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
542 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
543 &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
546 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
547 BitmapDecoderInfo_QueryInterface,
548 BitmapDecoderInfo_AddRef,
549 BitmapDecoderInfo_Release,
550 BitmapDecoderInfo_GetComponentType,
551 BitmapDecoderInfo_GetCLSID,
552 BitmapDecoderInfo_GetSigningStatus,
553 BitmapDecoderInfo_GetAuthor,
554 BitmapDecoderInfo_GetVendorGUID,
555 BitmapDecoderInfo_GetVersion,
556 BitmapDecoderInfo_GetSpecVersion,
557 BitmapDecoderInfo_GetFriendlyName,
558 BitmapDecoderInfo_GetContainerFormat,
559 BitmapDecoderInfo_GetPixelFormats,
560 BitmapDecoderInfo_GetColorManagementVersion,
561 BitmapDecoderInfo_GetDeviceManufacturer,
562 BitmapDecoderInfo_GetDeviceModels,
563 BitmapDecoderInfo_GetMimeTypes,
564 BitmapDecoderInfo_GetFileExtensions,
565 BitmapDecoderInfo_DoesSupportAnimation,
566 BitmapDecoderInfo_DoesSupportChromaKey,
567 BitmapDecoderInfo_DoesSupportLossless,
568 BitmapDecoderInfo_DoesSupportMultiframe,
569 BitmapDecoderInfo_MatchesMimeType,
570 BitmapDecoderInfo_GetPatterns,
571 BitmapDecoderInfo_MatchesPattern,
572 BitmapDecoderInfo_CreateInstance
575 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
577 BitmapDecoderInfo *This;
579 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
580 if (!This)
582 RegCloseKey(classkey);
583 return E_OUTOFMEMORY;
586 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
587 This->ref = 1;
588 This->classkey = classkey;
589 memcpy(&This->clsid, clsid, sizeof(CLSID));
591 *ppIInfo = (IWICComponentInfo*)This;
592 return S_OK;
595 typedef struct {
596 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
597 LONG ref;
598 HKEY classkey;
599 CLSID clsid;
600 } BitmapEncoderInfo;
602 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
604 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
607 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
608 void **ppv)
610 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
611 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
613 if (!ppv) return E_INVALIDARG;
615 if (IsEqualIID(&IID_IUnknown, iid) ||
616 IsEqualIID(&IID_IWICComponentInfo, iid) ||
617 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
618 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
620 *ppv = This;
622 else
624 *ppv = NULL;
625 return E_NOINTERFACE;
628 IUnknown_AddRef((IUnknown*)*ppv);
629 return S_OK;
632 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
634 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
635 ULONG ref = InterlockedIncrement(&This->ref);
637 TRACE("(%p) refcount=%u\n", iface, ref);
639 return ref;
642 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
644 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
645 ULONG ref = InterlockedDecrement(&This->ref);
647 TRACE("(%p) refcount=%u\n", iface, ref);
649 if (ref == 0)
651 RegCloseKey(This->classkey);
652 HeapFree(GetProcessHeap(), 0, This);
655 return ref;
658 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
659 WICComponentType *pType)
661 TRACE("(%p,%p)\n", iface, pType);
662 if (!pType) return E_INVALIDARG;
663 *pType = WICEncoder;
664 return S_OK;
667 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
669 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
670 TRACE("(%p,%p)\n", iface, pclsid);
672 if (!pclsid)
673 return E_INVALIDARG;
675 memcpy(pclsid, &This->clsid, sizeof(CLSID));
677 return S_OK;
680 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
682 FIXME("(%p,%p): stub\n", iface, pStatus);
683 return E_NOTIMPL;
686 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
687 WCHAR *wzAuthor, UINT *pcchActual)
689 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
691 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
693 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
694 cchAuthor, wzAuthor, pcchActual);
697 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
699 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
701 TRACE("(%p,%p)\n", iface, pguidVendor);
703 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
706 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
707 WCHAR *wzVersion, UINT *pcchActual)
709 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
711 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
713 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
714 cchVersion, wzVersion, pcchActual);
717 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
718 WCHAR *wzSpecVersion, UINT *pcchActual)
720 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
721 return E_NOTIMPL;
724 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
725 WCHAR *wzFriendlyName, UINT *pcchActual)
727 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
729 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
731 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
732 cchFriendlyName, wzFriendlyName, pcchActual);
735 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
736 GUID *pguidContainerFormat)
738 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
739 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
740 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
743 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
744 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
746 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
747 return E_NOTIMPL;
750 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
751 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
753 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
754 return E_NOTIMPL;
757 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
758 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
760 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
761 return E_NOTIMPL;
764 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
765 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
767 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
768 return E_NOTIMPL;
771 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
772 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
774 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
776 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
778 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
779 cchMimeTypes, wzMimeTypes, pcchActual);
782 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
783 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
785 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
786 return E_NOTIMPL;
789 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
790 BOOL *pfSupportAnimation)
792 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
793 return E_NOTIMPL;
796 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
797 BOOL *pfSupportChromaKey)
799 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
800 return E_NOTIMPL;
803 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
804 BOOL *pfSupportLossless)
806 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
807 return E_NOTIMPL;
810 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
811 BOOL *pfSupportMultiframe)
813 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
814 return E_NOTIMPL;
817 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
818 LPCWSTR wzMimeType, BOOL *pfMatches)
820 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
821 return E_NOTIMPL;
824 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
825 IWICBitmapEncoder **ppIBitmapEncoder)
827 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
829 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
831 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
832 &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
835 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
836 BitmapEncoderInfo_QueryInterface,
837 BitmapEncoderInfo_AddRef,
838 BitmapEncoderInfo_Release,
839 BitmapEncoderInfo_GetComponentType,
840 BitmapEncoderInfo_GetCLSID,
841 BitmapEncoderInfo_GetSigningStatus,
842 BitmapEncoderInfo_GetAuthor,
843 BitmapEncoderInfo_GetVendorGUID,
844 BitmapEncoderInfo_GetVersion,
845 BitmapEncoderInfo_GetSpecVersion,
846 BitmapEncoderInfo_GetFriendlyName,
847 BitmapEncoderInfo_GetContainerFormat,
848 BitmapEncoderInfo_GetPixelFormats,
849 BitmapEncoderInfo_GetColorManagementVersion,
850 BitmapEncoderInfo_GetDeviceManufacturer,
851 BitmapEncoderInfo_GetDeviceModels,
852 BitmapEncoderInfo_GetMimeTypes,
853 BitmapEncoderInfo_GetFileExtensions,
854 BitmapEncoderInfo_DoesSupportAnimation,
855 BitmapEncoderInfo_DoesSupportChromaKey,
856 BitmapEncoderInfo_DoesSupportLossless,
857 BitmapEncoderInfo_DoesSupportMultiframe,
858 BitmapEncoderInfo_MatchesMimeType,
859 BitmapEncoderInfo_CreateInstance
862 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
864 BitmapEncoderInfo *This;
866 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
867 if (!This)
869 RegCloseKey(classkey);
870 return E_OUTOFMEMORY;
873 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
874 This->ref = 1;
875 This->classkey = classkey;
876 memcpy(&This->clsid, clsid, sizeof(CLSID));
878 *ppIInfo = (IWICComponentInfo*)This;
879 return S_OK;
882 typedef struct {
883 IWICFormatConverterInfo IWICFormatConverterInfo_iface;
884 LONG ref;
885 HKEY classkey;
886 CLSID clsid;
887 } FormatConverterInfo;
889 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
891 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
894 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
895 void **ppv)
897 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
898 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
900 if (!ppv) return E_INVALIDARG;
902 if (IsEqualIID(&IID_IUnknown, iid) ||
903 IsEqualIID(&IID_IWICComponentInfo, iid) ||
904 IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
906 *ppv = This;
908 else
910 *ppv = NULL;
911 return E_NOINTERFACE;
914 IUnknown_AddRef((IUnknown*)*ppv);
915 return S_OK;
918 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
920 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
921 ULONG ref = InterlockedIncrement(&This->ref);
923 TRACE("(%p) refcount=%u\n", iface, ref);
925 return ref;
928 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
930 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
931 ULONG ref = InterlockedDecrement(&This->ref);
933 TRACE("(%p) refcount=%u\n", iface, ref);
935 if (ref == 0)
937 RegCloseKey(This->classkey);
938 HeapFree(GetProcessHeap(), 0, This);
941 return ref;
944 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
945 WICComponentType *pType)
947 TRACE("(%p,%p)\n", iface, pType);
948 if (!pType) return E_INVALIDARG;
949 *pType = WICPixelFormatConverter;
950 return S_OK;
953 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
955 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
956 TRACE("(%p,%p)\n", iface, pclsid);
958 if (!pclsid)
959 return E_INVALIDARG;
961 memcpy(pclsid, &This->clsid, sizeof(CLSID));
963 return S_OK;
966 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
968 FIXME("(%p,%p): stub\n", iface, pStatus);
969 return E_NOTIMPL;
972 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
973 WCHAR *wzAuthor, UINT *pcchActual)
975 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
977 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
979 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
980 cchAuthor, wzAuthor, pcchActual);
983 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
985 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
987 TRACE("(%p,%p)\n", iface, pguidVendor);
989 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
992 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
993 WCHAR *wzVersion, UINT *pcchActual)
995 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
997 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
999 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1000 cchVersion, wzVersion, pcchActual);
1003 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
1004 WCHAR *wzSpecVersion, UINT *pcchActual)
1006 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1007 return E_NOTIMPL;
1010 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
1011 WCHAR *wzFriendlyName, UINT *pcchActual)
1013 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1015 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1017 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1018 cchFriendlyName, wzFriendlyName, pcchActual);
1021 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
1022 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
1024 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
1025 return E_NOTIMPL;
1028 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
1029 IWICFormatConverter **ppIFormatConverter)
1031 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1033 TRACE("(%p,%p)\n", iface, ppIFormatConverter);
1035 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1036 &IID_IWICFormatConverter, (void**)ppIFormatConverter);
1039 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
1041 LONG res;
1042 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
1043 HKEY formats_key, guid_key;
1045 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
1046 would be O(n). A registry test should do better. */
1048 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
1049 if (res != ERROR_SUCCESS) return FALSE;
1051 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
1052 if (res == ERROR_SUCCESS) RegCloseKey(guid_key);
1054 RegCloseKey(formats_key);
1056 return (res == ERROR_SUCCESS);
1059 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
1060 FormatConverterInfo_QueryInterface,
1061 FormatConverterInfo_AddRef,
1062 FormatConverterInfo_Release,
1063 FormatConverterInfo_GetComponentType,
1064 FormatConverterInfo_GetCLSID,
1065 FormatConverterInfo_GetSigningStatus,
1066 FormatConverterInfo_GetAuthor,
1067 FormatConverterInfo_GetVendorGUID,
1068 FormatConverterInfo_GetVersion,
1069 FormatConverterInfo_GetSpecVersion,
1070 FormatConverterInfo_GetFriendlyName,
1071 FormatConverterInfo_GetPixelFormats,
1072 FormatConverterInfo_CreateInstance
1075 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1077 FormatConverterInfo *This;
1079 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
1080 if (!This)
1082 RegCloseKey(classkey);
1083 return E_OUTOFMEMORY;
1086 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
1087 This->ref = 1;
1088 This->classkey = classkey;
1089 memcpy(&This->clsid, clsid, sizeof(CLSID));
1091 *ppIInfo = (IWICComponentInfo*)This;
1092 return S_OK;
1095 typedef struct {
1096 IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface;
1097 LONG ref;
1098 HKEY classkey;
1099 CLSID clsid;
1100 } PixelFormatInfo;
1102 static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2 *iface)
1104 return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface);
1107 static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID iid,
1108 void **ppv)
1110 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1111 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1113 if (!ppv) return E_INVALIDARG;
1115 if (IsEqualIID(&IID_IUnknown, iid) ||
1116 IsEqualIID(&IID_IWICComponentInfo, iid) ||
1117 IsEqualIID(&IID_IWICPixelFormatInfo, iid) ||
1118 IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid))
1120 *ppv = This;
1122 else
1124 *ppv = NULL;
1125 return E_NOINTERFACE;
1128 IUnknown_AddRef((IUnknown*)*ppv);
1129 return S_OK;
1132 static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface)
1134 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1135 ULONG ref = InterlockedIncrement(&This->ref);
1137 TRACE("(%p) refcount=%u\n", iface, ref);
1139 return ref;
1142 static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface)
1144 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1145 ULONG ref = InterlockedDecrement(&This->ref);
1147 TRACE("(%p) refcount=%u\n", iface, ref);
1149 if (ref == 0)
1151 RegCloseKey(This->classkey);
1152 HeapFree(GetProcessHeap(), 0, This);
1155 return ref;
1158 static HRESULT WINAPI PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2 *iface,
1159 WICComponentType *pType)
1161 TRACE("(%p,%p)\n", iface, pType);
1162 if (!pType) return E_INVALIDARG;
1163 *pType = WICPixelFormat;
1164 return S_OK;
1167 static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2 *iface, CLSID *pclsid)
1169 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1170 TRACE("(%p,%p)\n", iface, pclsid);
1172 if (!pclsid)
1173 return E_INVALIDARG;
1175 memcpy(pclsid, &This->clsid, sizeof(CLSID));
1177 return S_OK;
1180 static HRESULT WINAPI PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2 *iface, DWORD *pStatus)
1182 TRACE("(%p,%p)\n", iface, pStatus);
1184 if (!pStatus)
1185 return E_INVALIDARG;
1187 /* Pixel formats don't require code, so they are considered signed. */
1188 *pStatus = WICComponentSigned;
1190 return S_OK;
1193 static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UINT cchAuthor,
1194 WCHAR *wzAuthor, UINT *pcchActual)
1196 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1198 TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);
1200 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1201 cchAuthor, wzAuthor, pcchActual);
1204 static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor)
1206 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1208 TRACE("(%p,%p)\n", iface, pguidVendor);
1210 return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
1213 static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion,
1214 WCHAR *wzVersion, UINT *pcchActual)
1216 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1218 TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);
1220 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1221 cchVersion, wzVersion, pcchActual);
1224 static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface, UINT cchSpecVersion,
1225 WCHAR *wzSpecVersion, UINT *pcchActual)
1227 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
1228 return E_NOTIMPL;
1231 static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *iface, UINT cchFriendlyName,
1232 WCHAR *wzFriendlyName, UINT *pcchActual)
1234 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1236 TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
1238 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1239 cchFriendlyName, wzFriendlyName, pcchActual);
1242 static HRESULT WINAPI PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface,
1243 GUID *pFormat)
1245 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1246 TRACE("(%p,%p)\n", iface, pFormat);
1248 if (!pFormat)
1249 return E_INVALIDARG;
1251 *pFormat = This->clsid;
1253 return S_OK;
1256 static HRESULT WINAPI PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2 *iface,
1257 IWICColorContext **ppIColorContext)
1259 FIXME("(%p,%p): stub\n", iface, ppIColorContext);
1260 return E_NOTIMPL;
1263 static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *iface,
1264 UINT *puiBitsPerPixel)
1266 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1268 TRACE("(%p,%p)\n", iface, puiBitsPerPixel);
1270 return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel);
1273 static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface,
1274 UINT *puiChannelCount)
1276 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1278 TRACE("(%p,%p)\n", iface, puiChannelCount);
1280 return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount);
1283 static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface,
1284 UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual)
1286 static const WCHAR uintformatW[] = {'%','u',0};
1287 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1288 UINT channel_count;
1289 HRESULT hr;
1290 LONG ret;
1291 WCHAR valuename[11];
1292 DWORD cbData;
1294 TRACE("(%p,%u,%u,%p,%p)\n", iface, uiChannelIndex, cbMaskBuffer, pbMaskBuffer, pcbActual);
1296 if (!pcbActual)
1297 return E_INVALIDARG;
1299 hr = PixelFormatInfo_GetChannelCount(iface, &channel_count);
1301 if (SUCCEEDED(hr) && uiChannelIndex >= channel_count)
1302 hr = E_INVALIDARG;
1304 if (SUCCEEDED(hr))
1306 snprintfW(valuename, 11, uintformatW, uiChannelIndex);
1308 cbData = cbMaskBuffer;
1310 ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData);
1312 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
1313 *pcbActual = cbData;
1315 if (ret == ERROR_MORE_DATA)
1316 hr = E_INVALIDARG;
1317 else
1318 hr = HRESULT_FROM_WIN32(ret);
1321 return hr;
1324 static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 *iface,
1325 BOOL *pfSupportsTransparency)
1327 FIXME("(%p,%p): stub\n", iface, pfSupportsTransparency);
1328 return E_NOTIMPL;
1331 static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface,
1332 WICPixelFormatNumericRepresentation *pNumericRepresentation)
1334 PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
1336 TRACE("(%p,%p)\n", iface, pNumericRepresentation);
1338 return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation);
1341 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = {
1342 PixelFormatInfo_QueryInterface,
1343 PixelFormatInfo_AddRef,
1344 PixelFormatInfo_Release,
1345 PixelFormatInfo_GetComponentType,
1346 PixelFormatInfo_GetCLSID,
1347 PixelFormatInfo_GetSigningStatus,
1348 PixelFormatInfo_GetAuthor,
1349 PixelFormatInfo_GetVendorGUID,
1350 PixelFormatInfo_GetVersion,
1351 PixelFormatInfo_GetSpecVersion,
1352 PixelFormatInfo_GetFriendlyName,
1353 PixelFormatInfo_GetFormatGUID,
1354 PixelFormatInfo_GetColorContext,
1355 PixelFormatInfo_GetBitsPerPixel,
1356 PixelFormatInfo_GetChannelCount,
1357 PixelFormatInfo_GetChannelMask,
1358 PixelFormatInfo_SupportsTransparency,
1359 PixelFormatInfo_GetNumericRepresentation
1362 static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
1364 PixelFormatInfo *This;
1366 This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo));
1367 if (!This)
1369 RegCloseKey(classkey);
1370 return E_OUTOFMEMORY;
1373 This->IWICPixelFormatInfo2_iface.lpVtbl = &PixelFormatInfo_Vtbl;
1374 This->ref = 1;
1375 This->classkey = classkey;
1376 memcpy(&This->clsid, clsid, sizeof(CLSID));
1378 *ppIInfo = (IWICComponentInfo*)This;
1379 return S_OK;
1382 typedef struct
1384 IWICMetadataReaderInfo IWICMetadataReaderInfo_iface;
1385 LONG ref;
1386 HKEY classkey;
1387 CLSID clsid;
1388 } MetadataReaderInfo;
1390 static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo *iface)
1392 return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface);
1395 static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface,
1396 REFIID riid, void **ppv)
1398 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1400 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
1402 if (!ppv) return E_INVALIDARG;
1404 if (IsEqualIID(&IID_IUnknown, riid) ||
1405 IsEqualIID(&IID_IWICComponentInfo, riid) ||
1406 IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) ||
1407 IsEqualIID(&IID_IWICMetadataReaderInfo, riid))
1409 *ppv = This;
1411 else
1413 *ppv = NULL;
1414 return E_NOINTERFACE;
1417 IUnknown_AddRef((IUnknown *)*ppv);
1418 return S_OK;
1421 static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
1423 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1424 ULONG ref = InterlockedIncrement(&This->ref);
1426 TRACE("(%p) refcount=%u\n", iface, ref);
1427 return ref;
1430 static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface)
1432 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1433 ULONG ref = InterlockedDecrement(&This->ref);
1435 TRACE("(%p) refcount=%u\n", iface, ref);
1437 if (!ref)
1439 RegCloseKey(This->classkey);
1440 HeapFree(GetProcessHeap(), 0, This);
1442 return ref;
1445 static HRESULT WINAPI MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo *iface,
1446 WICComponentType *type)
1448 TRACE("(%p,%p)\n", iface, type);
1450 if (!type) return E_INVALIDARG;
1451 *type = WICMetadataReader;
1452 return S_OK;
1455 static HRESULT WINAPI MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface,
1456 CLSID *clsid)
1458 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1460 TRACE("(%p,%p)\n", iface, clsid);
1462 if (!clsid) return E_INVALIDARG;
1463 *clsid = This->clsid;
1464 return S_OK;
1467 static HRESULT WINAPI MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo *iface,
1468 DWORD *status)
1470 FIXME("(%p,%p): stub\n", iface, status);
1471 return E_NOTIMPL;
1474 static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface,
1475 UINT length, WCHAR *author, UINT *actual_length)
1477 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1479 TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length);
1481 return ComponentInfo_GetStringValue(This->classkey, author_valuename,
1482 length, author, actual_length);
1485 static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface,
1486 GUID *vendor)
1488 FIXME("(%p,%p): stub\n", iface, vendor);
1489 return E_NOTIMPL;
1492 static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface,
1493 UINT length, WCHAR *version, UINT *actual_length)
1495 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1497 TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);
1499 return ComponentInfo_GetStringValue(This->classkey, version_valuename,
1500 length, version, actual_length);
1503 static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface,
1504 UINT length, WCHAR *version, UINT *actual_length)
1506 FIXME("(%p,%u,%p,%p): stub\n", iface, length, version, actual_length);
1507 return E_NOTIMPL;
1510 static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo *iface,
1511 UINT length, WCHAR *name, UINT *actual_length)
1513 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1515 TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length);
1517 return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
1518 length, name, actual_length);
1521 static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo *iface,
1522 GUID *format)
1524 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1525 TRACE("(%p,%p)\n", iface, format);
1526 return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format);
1529 static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface,
1530 UINT length, GUID *formats, UINT *actual_length)
1532 if (!actual_length) return E_INVALIDARG;
1534 FIXME("(%p,%u,%p,%p): stub\n", iface, length, formats, actual_length);
1535 return E_NOTIMPL;
1538 static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo *iface,
1539 UINT length, WCHAR *manufacturer, UINT *actual_length)
1541 FIXME("(%p,%u,%p,%p): stub\n", iface, length, manufacturer, actual_length);
1542 return E_NOTIMPL;
1545 static HRESULT WINAPI MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo *iface,
1546 UINT length, WCHAR *models, UINT *actual_length)
1548 FIXME("(%p,%u,%p,%p): stub\n", iface, length, models, actual_length);
1549 return E_NOTIMPL;
1552 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo *iface,
1553 BOOL *param)
1555 FIXME("(%p,%p): stub\n", iface, param);
1556 return E_NOTIMPL;
1559 static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface,
1560 BOOL *param)
1562 FIXME("(%p,%p): stub\n", iface, param);
1563 return E_NOTIMPL;
1566 static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface,
1567 BOOL *param)
1569 FIXME("(%p,%p): stub\n", iface, param);
1570 return E_NOTIMPL;
1573 static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface,
1574 REFGUID container, UINT length, WICMetadataPattern *pattern, UINT *count, UINT *actual_length)
1576 if (!actual_length) return E_INVALIDARG;
1578 FIXME("(%p,%s,%u,%p,%p,%p): stub\n", iface, debugstr_guid(container), length, pattern, count, actual_length);
1579 return E_NOTIMPL;
1582 static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface,
1583 REFGUID container, IStream *stream, BOOL *matches)
1585 FIXME("(%p,%s,%p,%p): stub\n", iface, debugstr_guid(container), stream, matches);
1586 return E_NOTIMPL;
1589 static HRESULT WINAPI MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *iface,
1590 IWICMetadataReader **reader)
1592 MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
1594 TRACE("(%p,%p)\n", iface, reader);
1596 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1597 &IID_IWICMetadataReader, (void **)reader);
1600 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = {
1601 MetadataReaderInfo_QueryInterface,
1602 MetadataReaderInfo_AddRef,
1603 MetadataReaderInfo_Release,
1604 MetadataReaderInfo_GetComponentType,
1605 MetadataReaderInfo_GetCLSID,
1606 MetadataReaderInfo_GetSigningStatus,
1607 MetadataReaderInfo_GetAuthor,
1608 MetadataReaderInfo_GetVendorGUID,
1609 MetadataReaderInfo_GetVersion,
1610 MetadataReaderInfo_GetSpecVersion,
1611 MetadataReaderInfo_GetFriendlyName,
1612 MetadataReaderInfo_GetMetadataFormat,
1613 MetadataReaderInfo_GetContainerFormats,
1614 MetadataReaderInfo_GetDeviceManufacturer,
1615 MetadataReaderInfo_GetDeviceModels,
1616 MetadataReaderInfo_DoesRequireFullStream,
1617 MetadataReaderInfo_DoesSupportPadding,
1618 MetadataReaderInfo_DoesRequireFixedSize,
1619 MetadataReaderInfo_GetPatterns,
1620 MetadataReaderInfo_MatchesPattern,
1621 MetadataReaderInfo_CreateInstance
1624 static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **info)
1626 MetadataReaderInfo *This;
1628 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1629 if (!This)
1631 RegCloseKey(classkey);
1632 return E_OUTOFMEMORY;
1635 This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl;
1636 This->ref = 1;
1637 This->classkey = classkey;
1638 This->clsid = *clsid;
1640 *info = (IWICComponentInfo *)This;
1641 return S_OK;
1644 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
1645 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
1647 struct category {
1648 WICComponentType type;
1649 const GUID *catid;
1650 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
1653 static const struct category categories[] = {
1654 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
1655 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
1656 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
1657 {WICPixelFormat, &CATID_WICPixelFormats, PixelFormatInfo_Constructor},
1658 {WICMetadataReader, &CATID_WICMetadataReader, MetadataReaderInfo_Constructor},
1662 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
1664 HKEY clsidkey;
1665 HKEY classkey;
1666 HKEY catidkey;
1667 HKEY instancekey;
1668 WCHAR guidstring[39];
1669 LONG res;
1670 const struct category *category;
1671 int found=0;
1672 HRESULT hr;
1674 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1675 if (res != ERROR_SUCCESS)
1676 return HRESULT_FROM_WIN32(res);
1678 for (category=categories; category->type; category++)
1680 StringFromGUID2(category->catid, guidstring, 39);
1681 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1682 if (res == ERROR_SUCCESS)
1684 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1685 if (res == ERROR_SUCCESS)
1687 StringFromGUID2(clsid, guidstring, 39);
1688 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
1689 if (res == ERROR_SUCCESS)
1691 RegCloseKey(classkey);
1692 found = 1;
1694 RegCloseKey(instancekey);
1696 RegCloseKey(catidkey);
1698 if (found) break;
1701 if (found)
1703 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
1704 if (res == ERROR_SUCCESS)
1705 hr = category->constructor(classkey, clsid, ppIInfo);
1706 else
1707 hr = HRESULT_FROM_WIN32(res);
1709 else
1711 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid));
1712 hr = E_FAIL;
1715 RegCloseKey(clsidkey);
1717 return hr;
1720 typedef struct {
1721 IEnumUnknown IEnumUnknown_iface;
1722 LONG ref;
1723 struct list objects;
1724 struct list *cursor;
1725 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
1726 } ComponentEnum;
1728 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
1730 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
1733 typedef struct {
1734 struct list entry;
1735 IUnknown *unk;
1736 } ComponentEnumItem;
1738 static const IEnumUnknownVtbl ComponentEnumVtbl;
1740 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
1741 void **ppv)
1743 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1744 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1746 if (!ppv) return E_INVALIDARG;
1748 if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IEnumUnknown, iid))
1750 *ppv = This;
1752 else
1754 *ppv = NULL;
1755 return E_NOINTERFACE;
1758 IUnknown_AddRef((IUnknown*)*ppv);
1759 return S_OK;
1762 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
1764 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1765 ULONG ref = InterlockedIncrement(&This->ref);
1767 TRACE("(%p) refcount=%u\n", iface, ref);
1769 return ref;
1772 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
1774 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1775 ULONG ref = InterlockedDecrement(&This->ref);
1776 ComponentEnumItem *cursor, *cursor2;
1778 TRACE("(%p) refcount=%u\n", iface, ref);
1780 if (ref == 0)
1782 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
1784 IUnknown_Release(cursor->unk);
1785 list_remove(&cursor->entry);
1786 HeapFree(GetProcessHeap(), 0, cursor);
1788 This->lock.DebugInfo->Spare[0] = 0;
1789 DeleteCriticalSection(&This->lock);
1790 HeapFree(GetProcessHeap(), 0, This);
1793 return ref;
1796 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
1797 IUnknown **rgelt, ULONG *pceltFetched)
1799 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1800 int num_fetched=0;
1801 ComponentEnumItem *item;
1802 HRESULT hr=S_OK;
1804 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
1806 EnterCriticalSection(&This->lock);
1807 while (num_fetched<celt)
1809 if (!This->cursor)
1811 hr = S_FALSE;
1812 break;
1814 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
1815 IUnknown_AddRef(item->unk);
1816 rgelt[num_fetched] = item->unk;
1817 num_fetched++;
1818 This->cursor = list_next(&This->objects, This->cursor);
1820 LeaveCriticalSection(&This->lock);
1821 if (pceltFetched)
1822 *pceltFetched = num_fetched;
1823 return hr;
1826 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
1828 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1829 int i;
1830 HRESULT hr=S_OK;
1832 TRACE("(%p,%u)\n", iface, celt);
1834 EnterCriticalSection(&This->lock);
1835 for (i=0; i<celt; i++)
1837 if (!This->cursor)
1839 hr = S_FALSE;
1840 break;
1842 This->cursor = list_next(&This->objects, This->cursor);
1844 LeaveCriticalSection(&This->lock);
1845 return hr;
1848 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
1850 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1852 TRACE("(%p)\n", iface);
1854 EnterCriticalSection(&This->lock);
1855 This->cursor = list_head(&This->objects);
1856 LeaveCriticalSection(&This->lock);
1857 return S_OK;
1860 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
1862 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1863 ComponentEnum *new_enum;
1864 ComponentEnumItem *old_item, *new_item;
1865 HRESULT ret=S_OK;
1866 struct list *old_cursor;
1868 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1869 if (!new_enum)
1871 *ppenum = NULL;
1872 return E_OUTOFMEMORY;
1875 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1876 new_enum->ref = 1;
1877 new_enum->cursor = NULL;
1878 list_init(&new_enum->objects);
1879 InitializeCriticalSection(&new_enum->lock);
1880 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1882 EnterCriticalSection(&This->lock);
1883 old_cursor = This->cursor;
1884 LeaveCriticalSection(&This->lock);
1886 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
1888 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1889 if (!new_item)
1891 ret = E_OUTOFMEMORY;
1892 break;
1894 new_item->unk = old_item->unk;
1895 list_add_tail(&new_enum->objects, &new_item->entry);
1896 IUnknown_AddRef(new_item->unk);
1897 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
1900 if (FAILED(ret))
1902 IUnknown_Release((IUnknown*)new_enum);
1903 *ppenum = NULL;
1905 else
1906 *ppenum = (IEnumUnknown*)new_enum;
1908 return ret;
1911 static const IEnumUnknownVtbl ComponentEnumVtbl = {
1912 ComponentEnum_QueryInterface,
1913 ComponentEnum_AddRef,
1914 ComponentEnum_Release,
1915 ComponentEnum_Next,
1916 ComponentEnum_Skip,
1917 ComponentEnum_Reset,
1918 ComponentEnum_Clone
1921 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
1923 ComponentEnum *This;
1924 ComponentEnumItem *item;
1925 const struct category *category;
1926 HKEY clsidkey, catidkey, instancekey;
1927 WCHAR guidstring[39];
1928 LONG res;
1929 int i;
1930 HRESULT hr=S_OK;
1931 CLSID clsid;
1933 if (options) FIXME("ignoring flags %x\n", options);
1935 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1936 if (res != ERROR_SUCCESS)
1937 return HRESULT_FROM_WIN32(res);
1939 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1940 if (!This)
1942 RegCloseKey(clsidkey);
1943 return E_OUTOFMEMORY;
1946 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1947 This->ref = 1;
1948 list_init(&This->objects);
1949 InitializeCriticalSection(&This->lock);
1950 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1952 for (category=categories; category->type && hr == S_OK; category++)
1954 if ((category->type & componentTypes) == 0) continue;
1955 StringFromGUID2(category->catid, guidstring, 39);
1956 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1957 if (res == ERROR_SUCCESS)
1959 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1960 if (res == ERROR_SUCCESS)
1962 i=0;
1963 for (;;i++)
1965 DWORD guidstring_size = 39;
1966 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
1967 if (res != ERROR_SUCCESS) break;
1969 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1970 if (!item) { hr = E_OUTOFMEMORY; break; }
1972 hr = CLSIDFromString(guidstring, &clsid);
1973 if (SUCCEEDED(hr))
1975 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
1976 if (SUCCEEDED(hr))
1977 list_add_tail(&This->objects, &item->entry);
1980 if (FAILED(hr))
1982 HeapFree(GetProcessHeap(), 0, item);
1983 hr = S_OK;
1986 RegCloseKey(instancekey);
1988 RegCloseKey(catidkey);
1990 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
1991 hr = HRESULT_FROM_WIN32(res);
1993 RegCloseKey(clsidkey);
1995 if (SUCCEEDED(hr))
1997 IEnumUnknown_Reset((IEnumUnknown*)This);
1998 *ppIEnumUnknown = (IEnumUnknown*)This;
2000 else
2002 *ppIEnumUnknown = NULL;
2003 IUnknown_Release((IUnknown*)This);
2006 return hr;
2009 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
2011 HRESULT res;
2012 IEnumUnknown *enumconverters;
2013 IUnknown *unkconverterinfo;
2014 IWICFormatConverterInfo *converterinfo=NULL;
2015 IWICFormatConverter *converter=NULL;
2016 GUID srcFormat;
2017 WCHAR srcformatstr[39], dstformatstr[39];
2018 BOOL canconvert;
2019 ULONG num_fetched;
2021 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
2022 if (FAILED(res)) return res;
2024 if (IsEqualGUID(&srcFormat, dstFormat))
2026 IWICBitmapSource_AddRef(pISrc);
2027 *ppIDst = pISrc;
2028 return S_OK;
2031 StringFromGUID2(&srcFormat, srcformatstr, 39);
2032 StringFromGUID2(dstFormat, dstformatstr, 39);
2034 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
2035 if (FAILED(res)) return res;
2037 while (!converter)
2039 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);
2041 if (res == S_OK)
2043 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);
2045 if (SUCCEEDED(res))
2047 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);
2049 if (canconvert)
2050 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);
2052 if (canconvert)
2054 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);
2056 if (SUCCEEDED(res))
2057 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);
2059 if (SUCCEEDED(res) && canconvert)
2060 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
2061 NULL, 0.0, WICBitmapPaletteTypeCustom);
2063 if (FAILED(res) || !canconvert)
2065 if (converter)
2067 IWICFormatConverter_Release(converter);
2068 converter = NULL;
2070 res = S_OK;
2074 IWICFormatConverterInfo_Release(converterinfo);
2077 IUnknown_Release(unkconverterinfo);
2079 else
2080 break;
2083 IEnumUnknown_Release(enumconverters);
2085 if (converter)
2087 *ppIDst = (IWICBitmapSource*)converter;
2088 return S_OK;
2090 else
2092 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
2093 *ppIDst = NULL;
2094 return WINCODEC_ERR_COMPONENTNOTFOUND;