po: Update Japanese translation.
[wine/multimedia.git] / dlls / windowscodecs / info.c
blob86f0adbdde640efc9be7f7a0fdd5ffbe08863a96
1 /*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "config.h"
21 #include <stdarg.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winreg.h"
28 #include "objbase.h"
29 #include "wincodec.h"
31 #include "wincodecs_private.h"
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
35 #include "wine/list.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
39 static const WCHAR mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0};
40 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
41 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
43 static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value,
44 UINT buffer_size, WCHAR *buffer, UINT *actual_size)
46 LONG ret;
47 DWORD cbdata=buffer_size * sizeof(WCHAR);
49 if (!actual_size)
50 return E_INVALIDARG;
52 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
53 buffer, &cbdata);
55 if (ret == 0 || ret == ERROR_MORE_DATA)
56 *actual_size = cbdata/sizeof(WCHAR);
58 if (!buffer && buffer_size != 0)
59 /* Yes, native returns the correct size in this case. */
60 return E_INVALIDARG;
62 if (ret == ERROR_MORE_DATA)
63 return WINCODEC_ERR_INSUFFICIENTBUFFER;
65 return HRESULT_FROM_WIN32(ret);
68 static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value,
69 GUID *result)
71 LONG ret;
72 WCHAR guid_string[39];
73 DWORD cbdata = sizeof(guid_string);
74 HRESULT hr;
76 if (!result)
77 return E_INVALIDARG;
79 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
80 guid_string, &cbdata);
82 if (ret != ERROR_SUCCESS)
83 return HRESULT_FROM_WIN32(ret);
85 if (cbdata < sizeof(guid_string))
87 ERR("incomplete GUID value\n");
88 return E_FAIL;
91 hr = CLSIDFromString(guid_string, result);
93 return hr;
96 typedef struct {
97 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface;
98 LONG ref;
99 HKEY classkey;
100 CLSID clsid;
101 } BitmapDecoderInfo;
103 static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo *iface)
105 return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface);
108 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid,
109 void **ppv)
111 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
112 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
114 if (!ppv) return E_INVALIDARG;
116 if (IsEqualIID(&IID_IUnknown, iid) ||
117 IsEqualIID(&IID_IWICComponentInfo, iid) ||
118 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
119 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
121 *ppv = This;
123 else
125 *ppv = NULL;
126 return E_NOINTERFACE;
129 IUnknown_AddRef((IUnknown*)*ppv);
130 return S_OK;
133 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
135 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
136 ULONG ref = InterlockedIncrement(&This->ref);
138 TRACE("(%p) refcount=%u\n", iface, ref);
140 return ref;
143 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
145 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
146 ULONG ref = InterlockedDecrement(&This->ref);
148 TRACE("(%p) refcount=%u\n", iface, ref);
150 if (ref == 0)
152 RegCloseKey(This->classkey);
153 HeapFree(GetProcessHeap(), 0, This);
156 return ref;
159 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface,
160 WICComponentType *pType)
162 TRACE("(%p,%p)\n", iface, pType);
163 *pType = WICDecoder;
164 return S_OK;
167 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid)
169 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
170 TRACE("(%p,%p)\n", iface, pclsid);
172 if (!pclsid)
173 return E_INVALIDARG;
175 memcpy(pclsid, &This->clsid, sizeof(CLSID));
177 return S_OK;
180 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus)
182 FIXME("(%p,%p): stub\n", iface, pStatus);
183 return E_NOTIMPL;
186 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor,
187 WCHAR *wzAuthor, UINT *pcchActual)
189 FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual);
190 return E_NOTIMPL;
193 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
195 FIXME("(%p,%p): stub\n", iface, pguidVendor);
196 return E_NOTIMPL;
199 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
200 WCHAR *wzVersion, UINT *pcchActual)
202 FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual);
203 return E_NOTIMPL;
206 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
207 WCHAR *wzSpecVersion, UINT *pcchActual)
209 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
210 return E_NOTIMPL;
213 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
214 WCHAR *wzFriendlyName, UINT *pcchActual)
216 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
217 return E_NOTIMPL;
220 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
221 GUID *pguidContainerFormat)
223 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
224 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
225 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
228 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
229 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
231 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
232 return E_NOTIMPL;
235 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface,
236 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
238 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
239 return E_NOTIMPL;
242 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface,
243 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
245 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
246 return E_NOTIMPL;
249 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface,
250 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
252 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
253 return E_NOTIMPL;
256 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface,
257 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
259 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
261 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
263 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
264 cchMimeTypes, wzMimeTypes, pcchActual);
267 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface,
268 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
270 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
271 return E_NOTIMPL;
274 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface,
275 BOOL *pfSupportAnimation)
277 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
278 return E_NOTIMPL;
281 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface,
282 BOOL *pfSupportChromaKey)
284 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
285 return E_NOTIMPL;
288 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface,
289 BOOL *pfSupportLossless)
291 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
292 return E_NOTIMPL;
295 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface,
296 BOOL *pfSupportMultiframe)
298 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
299 return E_NOTIMPL;
302 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface,
303 LPCWSTR wzMimeType, BOOL *pfMatches)
305 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
306 return E_NOTIMPL;
309 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface,
310 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual)
312 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
313 UINT pattern_count=0, patterns_size=0;
314 WCHAR subkeyname[11];
315 LONG res;
316 HKEY patternskey, patternkey;
317 static const WCHAR uintformatW[] = {'%','u',0};
318 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0};
319 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
320 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0};
321 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
322 static const WCHAR maskW[] = {'M','a','s','k',0};
323 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
324 HRESULT hr=S_OK;
325 UINT i;
326 BYTE *bPatterns=(BYTE*)pPatterns;
327 DWORD length, valuesize;
329 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual);
331 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
332 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
334 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
335 if (res == ERROR_SUCCESS)
337 patterns_size = pattern_count * sizeof(WICBitmapPattern);
339 for (i=0; i<pattern_count; i++)
341 snprintfW(subkeyname, 11, uintformatW, i);
342 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
343 if (res == ERROR_SUCCESS)
345 valuesize = sizeof(ULONG);
346 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
347 &length, &valuesize);
348 patterns_size += length*2;
350 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS))
352 pPatterns[i].Length = length;
354 pPatterns[i].EndOfStream = 0;
355 valuesize = sizeof(BOOL);
356 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
357 &pPatterns[i].EndOfStream, &valuesize);
359 pPatterns[i].Position.QuadPart = 0;
360 valuesize = sizeof(ULARGE_INTEGER);
361 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
362 &pPatterns[i].Position, &valuesize);
364 if (res == ERROR_SUCCESS)
366 pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
367 valuesize = length;
368 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
369 pPatterns[i].Pattern, &valuesize);
372 if (res == ERROR_SUCCESS)
374 pPatterns[i].Mask = bPatterns+patterns_size-length;
375 valuesize = length;
376 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
377 pPatterns[i].Mask, &valuesize);
381 RegCloseKey(patternkey);
383 if (res != ERROR_SUCCESS)
385 hr = HRESULT_FROM_WIN32(res);
386 break;
390 else hr = HRESULT_FROM_WIN32(res);
392 RegCloseKey(patternskey);
394 if (hr == S_OK)
396 *pcPatterns = pattern_count;
397 *pcbPatternsActual = patterns_size;
398 if (pPatterns && cbSizePatterns < patterns_size)
399 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
402 return hr;
405 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
406 IStream *pIStream, BOOL *pfMatches)
408 WICBitmapPattern *patterns;
409 UINT pattern_count=0, patterns_size=0;
410 HRESULT hr;
411 int i, pos;
412 BYTE *data=NULL;
413 ULONG datasize=0;
414 ULONG bytesread;
415 LARGE_INTEGER seekpos;
417 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
419 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
420 if (FAILED(hr)) return hr;
422 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
423 if (!patterns) return E_OUTOFMEMORY;
425 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
426 if (FAILED(hr)) goto end;
428 for (i=0; i<pattern_count; i++)
430 if (datasize < patterns[i].Length)
432 HeapFree(GetProcessHeap(), 0, data);
433 datasize = patterns[i].Length;
434 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
435 if (!data)
437 hr = E_OUTOFMEMORY;
438 break;
442 if (patterns[i].EndOfStream)
443 seekpos.QuadPart = -patterns[i].Position.QuadPart;
444 else
445 seekpos.QuadPart = patterns[i].Position.QuadPart;
446 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
447 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
448 if (FAILED(hr)) break;
450 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
451 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
452 continue;
453 if (FAILED(hr)) break;
455 for (pos=0; pos<patterns[i].Length; pos++)
457 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
458 break;
460 if (pos == patterns[i].Length) /* matches pattern */
462 hr = S_OK;
463 *pfMatches = TRUE;
464 break;
468 if (i == pattern_count) /* does not match any pattern */
470 hr = S_OK;
471 *pfMatches = FALSE;
474 end:
475 HeapFree(GetProcessHeap(), 0, patterns);
476 HeapFree(GetProcessHeap(), 0, data);
478 return hr;
481 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
482 IWICBitmapDecoder **ppIBitmapDecoder)
484 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
486 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
488 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
489 &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
492 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
493 BitmapDecoderInfo_QueryInterface,
494 BitmapDecoderInfo_AddRef,
495 BitmapDecoderInfo_Release,
496 BitmapDecoderInfo_GetComponentType,
497 BitmapDecoderInfo_GetCLSID,
498 BitmapDecoderInfo_GetSigningStatus,
499 BitmapDecoderInfo_GetAuthor,
500 BitmapDecoderInfo_GetVendorGUID,
501 BitmapDecoderInfo_GetVersion,
502 BitmapDecoderInfo_GetSpecVersion,
503 BitmapDecoderInfo_GetFriendlyName,
504 BitmapDecoderInfo_GetContainerFormat,
505 BitmapDecoderInfo_GetPixelFormats,
506 BitmapDecoderInfo_GetColorManagementVersion,
507 BitmapDecoderInfo_GetDeviceManufacturer,
508 BitmapDecoderInfo_GetDeviceModels,
509 BitmapDecoderInfo_GetMimeTypes,
510 BitmapDecoderInfo_GetFileExtensions,
511 BitmapDecoderInfo_DoesSupportAnimation,
512 BitmapDecoderInfo_DoesSupportChromaKey,
513 BitmapDecoderInfo_DoesSupportLossless,
514 BitmapDecoderInfo_DoesSupportMultiframe,
515 BitmapDecoderInfo_MatchesMimeType,
516 BitmapDecoderInfo_GetPatterns,
517 BitmapDecoderInfo_MatchesPattern,
518 BitmapDecoderInfo_CreateInstance
521 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
523 BitmapDecoderInfo *This;
525 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
526 if (!This)
528 RegCloseKey(classkey);
529 return E_OUTOFMEMORY;
532 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
533 This->ref = 1;
534 This->classkey = classkey;
535 memcpy(&This->clsid, clsid, sizeof(CLSID));
537 *ppIInfo = (IWICComponentInfo*)This;
538 return S_OK;
541 typedef struct {
542 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
543 LONG ref;
544 HKEY classkey;
545 CLSID clsid;
546 } BitmapEncoderInfo;
548 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
550 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
553 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
554 void **ppv)
556 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
557 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
559 if (!ppv) return E_INVALIDARG;
561 if (IsEqualIID(&IID_IUnknown, iid) ||
562 IsEqualIID(&IID_IWICComponentInfo, iid) ||
563 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
564 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
566 *ppv = This;
568 else
570 *ppv = NULL;
571 return E_NOINTERFACE;
574 IUnknown_AddRef((IUnknown*)*ppv);
575 return S_OK;
578 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
580 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
581 ULONG ref = InterlockedIncrement(&This->ref);
583 TRACE("(%p) refcount=%u\n", iface, ref);
585 return ref;
588 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
590 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
591 ULONG ref = InterlockedDecrement(&This->ref);
593 TRACE("(%p) refcount=%u\n", iface, ref);
595 if (ref == 0)
597 RegCloseKey(This->classkey);
598 HeapFree(GetProcessHeap(), 0, This);
601 return ref;
604 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
605 WICComponentType *pType)
607 TRACE("(%p,%p)\n", iface, pType);
608 *pType = WICEncoder;
609 return S_OK;
612 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
614 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
615 TRACE("(%p,%p)\n", iface, pclsid);
617 if (!pclsid)
618 return E_INVALIDARG;
620 memcpy(pclsid, &This->clsid, sizeof(CLSID));
622 return S_OK;
625 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
627 FIXME("(%p,%p): stub\n", iface, pStatus);
628 return E_NOTIMPL;
631 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
632 WCHAR *wzAuthor, UINT *pcchActual)
634 FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual);
635 return E_NOTIMPL;
638 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
640 FIXME("(%p,%p): stub\n", iface, pguidVendor);
641 return E_NOTIMPL;
644 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
645 WCHAR *wzVersion, UINT *pcchActual)
647 FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual);
648 return E_NOTIMPL;
651 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
652 WCHAR *wzSpecVersion, UINT *pcchActual)
654 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
655 return E_NOTIMPL;
658 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
659 WCHAR *wzFriendlyName, UINT *pcchActual)
661 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
662 return E_NOTIMPL;
665 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
666 GUID *pguidContainerFormat)
668 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
669 TRACE("(%p,%p)\n", iface, pguidContainerFormat);
670 return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
673 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
674 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
676 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
677 return E_NOTIMPL;
680 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
681 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
683 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
684 return E_NOTIMPL;
687 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
688 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
690 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
691 return E_NOTIMPL;
694 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
695 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
697 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
698 return E_NOTIMPL;
701 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
702 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
704 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
706 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
708 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
709 cchMimeTypes, wzMimeTypes, pcchActual);
712 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
713 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
715 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
716 return E_NOTIMPL;
719 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
720 BOOL *pfSupportAnimation)
722 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
723 return E_NOTIMPL;
726 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
727 BOOL *pfSupportChromaKey)
729 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
730 return E_NOTIMPL;
733 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
734 BOOL *pfSupportLossless)
736 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
737 return E_NOTIMPL;
740 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
741 BOOL *pfSupportMultiframe)
743 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
744 return E_NOTIMPL;
747 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
748 LPCWSTR wzMimeType, BOOL *pfMatches)
750 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
751 return E_NOTIMPL;
754 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
755 IWICBitmapEncoder **ppIBitmapEncoder)
757 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
759 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
761 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
762 &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
765 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
766 BitmapEncoderInfo_QueryInterface,
767 BitmapEncoderInfo_AddRef,
768 BitmapEncoderInfo_Release,
769 BitmapEncoderInfo_GetComponentType,
770 BitmapEncoderInfo_GetCLSID,
771 BitmapEncoderInfo_GetSigningStatus,
772 BitmapEncoderInfo_GetAuthor,
773 BitmapEncoderInfo_GetVendorGUID,
774 BitmapEncoderInfo_GetVersion,
775 BitmapEncoderInfo_GetSpecVersion,
776 BitmapEncoderInfo_GetFriendlyName,
777 BitmapEncoderInfo_GetContainerFormat,
778 BitmapEncoderInfo_GetPixelFormats,
779 BitmapEncoderInfo_GetColorManagementVersion,
780 BitmapEncoderInfo_GetDeviceManufacturer,
781 BitmapEncoderInfo_GetDeviceModels,
782 BitmapEncoderInfo_GetMimeTypes,
783 BitmapEncoderInfo_GetFileExtensions,
784 BitmapEncoderInfo_DoesSupportAnimation,
785 BitmapEncoderInfo_DoesSupportChromaKey,
786 BitmapEncoderInfo_DoesSupportLossless,
787 BitmapEncoderInfo_DoesSupportMultiframe,
788 BitmapEncoderInfo_MatchesMimeType,
789 BitmapEncoderInfo_CreateInstance
792 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
794 BitmapEncoderInfo *This;
796 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
797 if (!This)
799 RegCloseKey(classkey);
800 return E_OUTOFMEMORY;
803 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
804 This->ref = 1;
805 This->classkey = classkey;
806 memcpy(&This->clsid, clsid, sizeof(CLSID));
808 *ppIInfo = (IWICComponentInfo*)This;
809 return S_OK;
812 typedef struct {
813 IWICFormatConverterInfo IWICFormatConverterInfo_iface;
814 LONG ref;
815 HKEY classkey;
816 CLSID clsid;
817 } FormatConverterInfo;
819 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
821 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
824 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
825 void **ppv)
827 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
828 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
830 if (!ppv) return E_INVALIDARG;
832 if (IsEqualIID(&IID_IUnknown, iid) ||
833 IsEqualIID(&IID_IWICComponentInfo, iid) ||
834 IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
836 *ppv = This;
838 else
840 *ppv = NULL;
841 return E_NOINTERFACE;
844 IUnknown_AddRef((IUnknown*)*ppv);
845 return S_OK;
848 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
850 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
851 ULONG ref = InterlockedIncrement(&This->ref);
853 TRACE("(%p) refcount=%u\n", iface, ref);
855 return ref;
858 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
860 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
861 ULONG ref = InterlockedDecrement(&This->ref);
863 TRACE("(%p) refcount=%u\n", iface, ref);
865 if (ref == 0)
867 RegCloseKey(This->classkey);
868 HeapFree(GetProcessHeap(), 0, This);
871 return ref;
874 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
875 WICComponentType *pType)
877 TRACE("(%p,%p)\n", iface, pType);
878 *pType = WICPixelFormatConverter;
879 return S_OK;
882 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
884 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
885 TRACE("(%p,%p)\n", iface, pclsid);
887 if (!pclsid)
888 return E_INVALIDARG;
890 memcpy(pclsid, &This->clsid, sizeof(CLSID));
892 return S_OK;
895 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
897 FIXME("(%p,%p): stub\n", iface, pStatus);
898 return E_NOTIMPL;
901 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
902 WCHAR *wzAuthor, UINT *pcchActual)
904 FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual);
905 return E_NOTIMPL;
908 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
910 FIXME("(%p,%p): stub\n", iface, pguidVendor);
911 return E_NOTIMPL;
914 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
915 WCHAR *wzVersion, UINT *pcchActual)
917 FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual);
918 return E_NOTIMPL;
921 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
922 WCHAR *wzSpecVersion, UINT *pcchActual)
924 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
925 return E_NOTIMPL;
928 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
929 WCHAR *wzFriendlyName, UINT *pcchActual)
931 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
932 return E_NOTIMPL;
935 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
936 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
938 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
939 return E_NOTIMPL;
942 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
943 IWICFormatConverter **ppIFormatConverter)
945 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
947 TRACE("(%p,%p)\n", iface, ppIFormatConverter);
949 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
950 &IID_IWICFormatConverter, (void**)ppIFormatConverter);
953 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
955 LONG res;
956 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
957 HKEY formats_key, guid_key;
959 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
960 would be O(n). A registry test should do better. */
962 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
963 if (res != ERROR_SUCCESS) return FALSE;
965 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
966 if (res == ERROR_SUCCESS) RegCloseKey(guid_key);
968 RegCloseKey(formats_key);
970 return (res == ERROR_SUCCESS);
973 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
974 FormatConverterInfo_QueryInterface,
975 FormatConverterInfo_AddRef,
976 FormatConverterInfo_Release,
977 FormatConverterInfo_GetComponentType,
978 FormatConverterInfo_GetCLSID,
979 FormatConverterInfo_GetSigningStatus,
980 FormatConverterInfo_GetAuthor,
981 FormatConverterInfo_GetVendorGUID,
982 FormatConverterInfo_GetVersion,
983 FormatConverterInfo_GetSpecVersion,
984 FormatConverterInfo_GetFriendlyName,
985 FormatConverterInfo_GetPixelFormats,
986 FormatConverterInfo_CreateInstance
989 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
991 FormatConverterInfo *This;
993 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
994 if (!This)
996 RegCloseKey(classkey);
997 return E_OUTOFMEMORY;
1000 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
1001 This->ref = 1;
1002 This->classkey = classkey;
1003 memcpy(&This->clsid, clsid, sizeof(CLSID));
1005 *ppIInfo = (IWICComponentInfo*)This;
1006 return S_OK;
1009 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
1010 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
1012 struct category {
1013 WICComponentType type;
1014 const GUID *catid;
1015 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
1018 static const struct category categories[] = {
1019 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
1020 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
1021 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
1025 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
1027 HKEY clsidkey;
1028 HKEY classkey;
1029 HKEY catidkey;
1030 HKEY instancekey;
1031 WCHAR guidstring[39];
1032 LONG res;
1033 const struct category *category;
1034 int found=0;
1035 HRESULT hr;
1037 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1038 if (res != ERROR_SUCCESS)
1039 return HRESULT_FROM_WIN32(res);
1041 for (category=categories; category->type; category++)
1043 StringFromGUID2(category->catid, guidstring, 39);
1044 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1045 if (res == ERROR_SUCCESS)
1047 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1048 if (res == ERROR_SUCCESS)
1050 StringFromGUID2(clsid, guidstring, 39);
1051 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
1052 if (res == ERROR_SUCCESS)
1054 RegCloseKey(classkey);
1055 found = 1;
1057 RegCloseKey(instancekey);
1059 RegCloseKey(catidkey);
1061 if (found) break;
1064 if (found)
1066 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
1067 if (res == ERROR_SUCCESS)
1068 hr = category->constructor(classkey, clsid, ppIInfo);
1069 else
1070 hr = HRESULT_FROM_WIN32(res);
1072 else
1073 hr = E_FAIL;
1075 RegCloseKey(clsidkey);
1077 return hr;
1080 typedef struct {
1081 IEnumUnknown IEnumUnknown_iface;
1082 LONG ref;
1083 struct list objects;
1084 struct list *cursor;
1085 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
1086 } ComponentEnum;
1088 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
1090 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
1093 typedef struct {
1094 struct list entry;
1095 IUnknown *unk;
1096 } ComponentEnumItem;
1098 static const IEnumUnknownVtbl ComponentEnumVtbl;
1100 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
1101 void **ppv)
1103 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1104 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1106 if (!ppv) return E_INVALIDARG;
1108 if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IEnumUnknown, iid))
1110 *ppv = This;
1112 else
1114 *ppv = NULL;
1115 return E_NOINTERFACE;
1118 IUnknown_AddRef((IUnknown*)*ppv);
1119 return S_OK;
1122 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
1124 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1125 ULONG ref = InterlockedIncrement(&This->ref);
1127 TRACE("(%p) refcount=%u\n", iface, ref);
1129 return ref;
1132 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
1134 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1135 ULONG ref = InterlockedDecrement(&This->ref);
1136 ComponentEnumItem *cursor, *cursor2;
1138 TRACE("(%p) refcount=%u\n", iface, ref);
1140 if (ref == 0)
1142 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
1144 IUnknown_Release(cursor->unk);
1145 list_remove(&cursor->entry);
1146 HeapFree(GetProcessHeap(), 0, cursor);
1148 This->lock.DebugInfo->Spare[0] = 0;
1149 DeleteCriticalSection(&This->lock);
1150 HeapFree(GetProcessHeap(), 0, This);
1153 return ref;
1156 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
1157 IUnknown **rgelt, ULONG *pceltFetched)
1159 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1160 int num_fetched=0;
1161 ComponentEnumItem *item;
1162 HRESULT hr=S_OK;
1164 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
1166 EnterCriticalSection(&This->lock);
1167 while (num_fetched<celt)
1169 if (!This->cursor)
1171 hr = S_FALSE;
1172 break;
1174 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
1175 IUnknown_AddRef(item->unk);
1176 rgelt[num_fetched] = item->unk;
1177 num_fetched++;
1178 This->cursor = list_next(&This->objects, This->cursor);
1180 LeaveCriticalSection(&This->lock);
1181 if (pceltFetched)
1182 *pceltFetched = num_fetched;
1183 return hr;
1186 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
1188 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1189 int i;
1190 HRESULT hr=S_OK;
1192 TRACE("(%p,%u)\n", iface, celt);
1194 EnterCriticalSection(&This->lock);
1195 for (i=0; i<celt; i++)
1197 if (!This->cursor)
1199 hr = S_FALSE;
1200 break;
1202 This->cursor = list_next(&This->objects, This->cursor);
1204 LeaveCriticalSection(&This->lock);
1205 return hr;
1208 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
1210 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1212 TRACE("(%p)\n", iface);
1214 EnterCriticalSection(&This->lock);
1215 This->cursor = list_head(&This->objects);
1216 LeaveCriticalSection(&This->lock);
1217 return S_OK;
1220 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
1222 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1223 ComponentEnum *new_enum;
1224 ComponentEnumItem *old_item, *new_item;
1225 HRESULT ret=S_OK;
1226 struct list *old_cursor;
1228 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1229 if (!new_enum)
1231 *ppenum = NULL;
1232 return E_OUTOFMEMORY;
1235 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1236 new_enum->ref = 1;
1237 new_enum->cursor = NULL;
1238 list_init(&new_enum->objects);
1239 InitializeCriticalSection(&new_enum->lock);
1240 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1242 EnterCriticalSection(&This->lock);
1243 old_cursor = This->cursor;
1244 LeaveCriticalSection(&This->lock);
1246 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
1248 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1249 if (!new_item)
1251 ret = E_OUTOFMEMORY;
1252 break;
1254 new_item->unk = old_item->unk;
1255 list_add_tail(&new_enum->objects, &new_item->entry);
1256 IUnknown_AddRef(new_item->unk);
1257 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
1260 if (FAILED(ret))
1262 IUnknown_Release((IUnknown*)new_enum);
1263 *ppenum = NULL;
1265 else
1266 *ppenum = (IEnumUnknown*)new_enum;
1268 return ret;
1271 static const IEnumUnknownVtbl ComponentEnumVtbl = {
1272 ComponentEnum_QueryInterface,
1273 ComponentEnum_AddRef,
1274 ComponentEnum_Release,
1275 ComponentEnum_Next,
1276 ComponentEnum_Skip,
1277 ComponentEnum_Reset,
1278 ComponentEnum_Clone
1281 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
1283 ComponentEnum *This;
1284 ComponentEnumItem *item;
1285 const struct category *category;
1286 HKEY clsidkey, catidkey, instancekey;
1287 WCHAR guidstring[39];
1288 LONG res;
1289 int i;
1290 HRESULT hr=S_OK;
1291 CLSID clsid;
1293 if (options) FIXME("ignoring flags %x\n", options);
1295 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1296 if (res != ERROR_SUCCESS)
1297 return HRESULT_FROM_WIN32(res);
1299 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1300 if (!This)
1302 RegCloseKey(clsidkey);
1303 return E_OUTOFMEMORY;
1306 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1307 This->ref = 1;
1308 list_init(&This->objects);
1309 InitializeCriticalSection(&This->lock);
1310 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1312 for (category=categories; category->type && hr == S_OK; category++)
1314 if ((category->type & componentTypes) == 0) continue;
1315 StringFromGUID2(category->catid, guidstring, 39);
1316 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1317 if (res == ERROR_SUCCESS)
1319 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1320 if (res == ERROR_SUCCESS)
1322 i=0;
1323 for (;;i++)
1325 DWORD guidstring_size = 39;
1326 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
1327 if (res != ERROR_SUCCESS) break;
1329 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1330 if (!item) { hr = E_OUTOFMEMORY; break; }
1332 hr = CLSIDFromString(guidstring, &clsid);
1333 if (SUCCEEDED(hr))
1335 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
1336 if (SUCCEEDED(hr))
1337 list_add_tail(&This->objects, &item->entry);
1340 if (FAILED(hr))
1342 HeapFree(GetProcessHeap(), 0, item);
1343 hr = S_OK;
1346 RegCloseKey(instancekey);
1348 RegCloseKey(catidkey);
1350 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
1351 hr = HRESULT_FROM_WIN32(res);
1353 RegCloseKey(clsidkey);
1355 if (SUCCEEDED(hr))
1357 IEnumUnknown_Reset((IEnumUnknown*)This);
1358 *ppIEnumUnknown = (IEnumUnknown*)This;
1360 else
1362 *ppIEnumUnknown = NULL;
1363 IUnknown_Release((IUnknown*)This);
1366 return hr;
1369 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
1371 HRESULT res;
1372 IEnumUnknown *enumconverters;
1373 IUnknown *unkconverterinfo;
1374 IWICFormatConverterInfo *converterinfo=NULL;
1375 IWICFormatConverter *converter=NULL;
1376 GUID srcFormat;
1377 WCHAR srcformatstr[39], dstformatstr[39];
1378 BOOL canconvert;
1379 ULONG num_fetched;
1381 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
1382 if (FAILED(res)) return res;
1384 if (IsEqualGUID(&srcFormat, dstFormat))
1386 IWICBitmapSource_AddRef(pISrc);
1387 *ppIDst = pISrc;
1388 return S_OK;
1391 StringFromGUID2(&srcFormat, srcformatstr, 39);
1392 StringFromGUID2(dstFormat, dstformatstr, 39);
1394 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
1395 if (FAILED(res)) return res;
1397 while (!converter)
1399 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);
1401 if (res == S_OK)
1403 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);
1405 if (SUCCEEDED(res))
1407 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);
1409 if (canconvert)
1410 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);
1412 if (canconvert)
1414 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);
1416 if (SUCCEEDED(res))
1417 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);
1419 if (SUCCEEDED(res) && canconvert)
1420 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
1421 NULL, 0.0, WICBitmapPaletteTypeCustom);
1423 if (FAILED(res) || !canconvert)
1425 if (converter)
1427 IWICFormatConverter_Release(converter);
1428 converter = NULL;
1430 res = S_OK;
1434 IWICFormatConverterInfo_Release(converterinfo);
1437 IUnknown_Release(unkconverterinfo);
1439 else
1440 break;
1443 IEnumUnknown_Release(enumconverters);
1445 if (converter)
1447 *ppIDst = (IWICBitmapSource*)converter;
1448 return S_OK;
1450 else
1452 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
1453 *ppIDst = NULL;
1454 return WINCODEC_ERR_COMPONENTNOTFOUND;