po: Remove English strings from the Spanish translation.
[wine/multimedia.git] / dlls / windowscodecs / info.c
blob50b520fb65843e516f9f24e460ae9c3f3ab0281f
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};
42 static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value,
43 UINT buffer_size, WCHAR *buffer, UINT *actual_size)
45 LONG ret;
46 DWORD cbdata=buffer_size * sizeof(WCHAR);
48 if (!actual_size)
49 return E_INVALIDARG;
51 ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
52 buffer, &cbdata);
54 if (ret == 0 || ret == ERROR_MORE_DATA)
55 *actual_size = cbdata/sizeof(WCHAR);
57 if (!buffer && buffer_size != 0)
58 /* Yes, native returns the correct size in this case. */
59 return E_INVALIDARG;
61 if (ret == ERROR_MORE_DATA)
62 return WINCODEC_ERR_INSUFFICIENTBUFFER;
64 return HRESULT_FROM_WIN32(ret);
67 typedef struct {
68 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface;
69 LONG ref;
70 HKEY classkey;
71 CLSID clsid;
72 } BitmapDecoderInfo;
74 static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo *iface)
76 return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface);
79 static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid,
80 void **ppv)
82 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
83 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
85 if (!ppv) return E_INVALIDARG;
87 if (IsEqualIID(&IID_IUnknown, iid) ||
88 IsEqualIID(&IID_IWICComponentInfo, iid) ||
89 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
90 IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
92 *ppv = This;
94 else
96 *ppv = NULL;
97 return E_NOINTERFACE;
100 IUnknown_AddRef((IUnknown*)*ppv);
101 return S_OK;
104 static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
106 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
107 ULONG ref = InterlockedIncrement(&This->ref);
109 TRACE("(%p) refcount=%u\n", iface, ref);
111 return ref;
114 static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
116 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
117 ULONG ref = InterlockedDecrement(&This->ref);
119 TRACE("(%p) refcount=%u\n", iface, ref);
121 if (ref == 0)
123 RegCloseKey(This->classkey);
124 HeapFree(GetProcessHeap(), 0, This);
127 return ref;
130 static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface,
131 WICComponentType *pType)
133 TRACE("(%p,%p)\n", iface, pType);
134 *pType = WICDecoder;
135 return S_OK;
138 static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid)
140 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
141 TRACE("(%p,%p)\n", iface, pclsid);
143 if (!pclsid)
144 return E_INVALIDARG;
146 memcpy(pclsid, &This->clsid, sizeof(CLSID));
148 return S_OK;
151 static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus)
153 FIXME("(%p,%p): stub\n", iface, pStatus);
154 return E_NOTIMPL;
157 static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor,
158 WCHAR *wzAuthor, UINT *pcchActual)
160 FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual);
161 return E_NOTIMPL;
164 static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
166 FIXME("(%p,%p): stub\n", iface, pguidVendor);
167 return E_NOTIMPL;
170 static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
171 WCHAR *wzVersion, UINT *pcchActual)
173 FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual);
174 return E_NOTIMPL;
177 static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
178 WCHAR *wzSpecVersion, UINT *pcchActual)
180 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
181 return E_NOTIMPL;
184 static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
185 WCHAR *wzFriendlyName, UINT *pcchActual)
187 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
188 return E_NOTIMPL;
191 static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
192 GUID *pguidContainerFormat)
194 FIXME("(%p,%p): stub\n", iface, pguidContainerFormat);
195 return E_NOTIMPL;
198 static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
199 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
201 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
202 return E_NOTIMPL;
205 static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface,
206 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
208 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
209 return E_NOTIMPL;
212 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface,
213 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
215 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
216 return E_NOTIMPL;
219 static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface,
220 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
222 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
223 return E_NOTIMPL;
226 static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface,
227 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
229 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
231 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
233 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
234 cchMimeTypes, wzMimeTypes, pcchActual);
237 static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface,
238 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
240 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
241 return E_NOTIMPL;
244 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface,
245 BOOL *pfSupportAnimation)
247 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
248 return E_NOTIMPL;
251 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface,
252 BOOL *pfSupportChromaKey)
254 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
255 return E_NOTIMPL;
258 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface,
259 BOOL *pfSupportLossless)
261 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
262 return E_NOTIMPL;
265 static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface,
266 BOOL *pfSupportMultiframe)
268 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
269 return E_NOTIMPL;
272 static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface,
273 LPCWSTR wzMimeType, BOOL *pfMatches)
275 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
276 return E_NOTIMPL;
279 static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface,
280 UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual)
282 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
283 UINT pattern_count=0, patterns_size=0;
284 WCHAR subkeyname[11];
285 LONG res;
286 HKEY patternskey, patternkey;
287 static const WCHAR uintformatW[] = {'%','u',0};
288 static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0};
289 static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
290 static const WCHAR lengthW[] = {'L','e','n','g','t','h',0};
291 static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
292 static const WCHAR maskW[] = {'M','a','s','k',0};
293 static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
294 HRESULT hr=S_OK;
295 UINT i;
296 BYTE *bPatterns=(BYTE*)pPatterns;
297 DWORD length, valuesize;
299 TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual);
301 res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
302 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
304 res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
305 if (res == ERROR_SUCCESS)
307 patterns_size = pattern_count * sizeof(WICBitmapPattern);
309 for (i=0; i<pattern_count; i++)
311 snprintfW(subkeyname, 11, uintformatW, i);
312 res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
313 if (res == ERROR_SUCCESS)
315 valuesize = sizeof(ULONG);
316 res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
317 &length, &valuesize);
318 patterns_size += length*2;
320 if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS))
322 pPatterns[i].Length = length;
324 pPatterns[i].EndOfStream = 0;
325 valuesize = sizeof(BOOL);
326 RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
327 &pPatterns[i].EndOfStream, &valuesize);
329 pPatterns[i].Position.QuadPart = 0;
330 valuesize = sizeof(ULARGE_INTEGER);
331 res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
332 &pPatterns[i].Position, &valuesize);
334 if (res == ERROR_SUCCESS)
336 pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
337 valuesize = length;
338 res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
339 pPatterns[i].Pattern, &valuesize);
342 if (res == ERROR_SUCCESS)
344 pPatterns[i].Mask = bPatterns+patterns_size-length;
345 valuesize = length;
346 res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
347 pPatterns[i].Mask, &valuesize);
351 RegCloseKey(patternkey);
353 if (res != ERROR_SUCCESS)
355 hr = HRESULT_FROM_WIN32(res);
356 break;
360 else hr = HRESULT_FROM_WIN32(res);
362 RegCloseKey(patternskey);
364 if (hr == S_OK)
366 *pcPatterns = pattern_count;
367 *pcbPatternsActual = patterns_size;
368 if (pPatterns && cbSizePatterns < patterns_size)
369 hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
372 return hr;
375 static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
376 IStream *pIStream, BOOL *pfMatches)
378 WICBitmapPattern *patterns;
379 UINT pattern_count=0, patterns_size=0;
380 HRESULT hr;
381 int i, pos;
382 BYTE *data=NULL;
383 ULONG datasize=0;
384 ULONG bytesread;
385 LARGE_INTEGER seekpos;
387 TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);
389 hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
390 if (FAILED(hr)) return hr;
392 patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
393 if (!patterns) return E_OUTOFMEMORY;
395 hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
396 if (FAILED(hr)) goto end;
398 for (i=0; i<pattern_count; i++)
400 if (datasize < patterns[i].Length)
402 HeapFree(GetProcessHeap(), 0, data);
403 datasize = patterns[i].Length;
404 data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
405 if (!data)
407 hr = E_OUTOFMEMORY;
408 break;
412 if (patterns[i].EndOfStream)
413 seekpos.QuadPart = -patterns[i].Position.QuadPart;
414 else
415 seekpos.QuadPart = patterns[i].Position.QuadPart;
416 hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
417 if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
418 if (FAILED(hr)) break;
420 hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
421 if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
422 continue;
423 if (FAILED(hr)) break;
425 for (pos=0; pos<patterns[i].Length; pos++)
427 if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
428 break;
430 if (pos == patterns[i].Length) /* matches pattern */
432 hr = S_OK;
433 *pfMatches = TRUE;
434 break;
438 if (i == pattern_count) /* does not match any pattern */
440 hr = S_OK;
441 *pfMatches = FALSE;
444 end:
445 HeapFree(GetProcessHeap(), 0, patterns);
446 HeapFree(GetProcessHeap(), 0, data);
448 return hr;
451 static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
452 IWICBitmapDecoder **ppIBitmapDecoder)
454 BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
456 TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);
458 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
459 &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
462 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
463 BitmapDecoderInfo_QueryInterface,
464 BitmapDecoderInfo_AddRef,
465 BitmapDecoderInfo_Release,
466 BitmapDecoderInfo_GetComponentType,
467 BitmapDecoderInfo_GetCLSID,
468 BitmapDecoderInfo_GetSigningStatus,
469 BitmapDecoderInfo_GetAuthor,
470 BitmapDecoderInfo_GetVendorGUID,
471 BitmapDecoderInfo_GetVersion,
472 BitmapDecoderInfo_GetSpecVersion,
473 BitmapDecoderInfo_GetFriendlyName,
474 BitmapDecoderInfo_GetContainerFormat,
475 BitmapDecoderInfo_GetPixelFormats,
476 BitmapDecoderInfo_GetColorManagementVersion,
477 BitmapDecoderInfo_GetDeviceManufacturer,
478 BitmapDecoderInfo_GetDeviceModels,
479 BitmapDecoderInfo_GetMimeTypes,
480 BitmapDecoderInfo_GetFileExtensions,
481 BitmapDecoderInfo_DoesSupportAnimation,
482 BitmapDecoderInfo_DoesSupportChromaKey,
483 BitmapDecoderInfo_DoesSupportLossless,
484 BitmapDecoderInfo_DoesSupportMultiframe,
485 BitmapDecoderInfo_MatchesMimeType,
486 BitmapDecoderInfo_GetPatterns,
487 BitmapDecoderInfo_MatchesPattern,
488 BitmapDecoderInfo_CreateInstance
491 static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
493 BitmapDecoderInfo *This;
495 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
496 if (!This)
498 RegCloseKey(classkey);
499 return E_OUTOFMEMORY;
502 This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
503 This->ref = 1;
504 This->classkey = classkey;
505 memcpy(&This->clsid, clsid, sizeof(CLSID));
507 *ppIInfo = (IWICComponentInfo*)This;
508 return S_OK;
511 typedef struct {
512 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
513 LONG ref;
514 HKEY classkey;
515 CLSID clsid;
516 } BitmapEncoderInfo;
518 static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
520 return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
523 static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
524 void **ppv)
526 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
527 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
529 if (!ppv) return E_INVALIDARG;
531 if (IsEqualIID(&IID_IUnknown, iid) ||
532 IsEqualIID(&IID_IWICComponentInfo, iid) ||
533 IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
534 IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
536 *ppv = This;
538 else
540 *ppv = NULL;
541 return E_NOINTERFACE;
544 IUnknown_AddRef((IUnknown*)*ppv);
545 return S_OK;
548 static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
550 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
551 ULONG ref = InterlockedIncrement(&This->ref);
553 TRACE("(%p) refcount=%u\n", iface, ref);
555 return ref;
558 static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
560 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
561 ULONG ref = InterlockedDecrement(&This->ref);
563 TRACE("(%p) refcount=%u\n", iface, ref);
565 if (ref == 0)
567 RegCloseKey(This->classkey);
568 HeapFree(GetProcessHeap(), 0, This);
571 return ref;
574 static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
575 WICComponentType *pType)
577 TRACE("(%p,%p)\n", iface, pType);
578 *pType = WICEncoder;
579 return S_OK;
582 static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
584 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
585 TRACE("(%p,%p)\n", iface, pclsid);
587 if (!pclsid)
588 return E_INVALIDARG;
590 memcpy(pclsid, &This->clsid, sizeof(CLSID));
592 return S_OK;
595 static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
597 FIXME("(%p,%p): stub\n", iface, pStatus);
598 return E_NOTIMPL;
601 static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
602 WCHAR *wzAuthor, UINT *pcchActual)
604 FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual);
605 return E_NOTIMPL;
608 static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
610 FIXME("(%p,%p): stub\n", iface, pguidVendor);
611 return E_NOTIMPL;
614 static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
615 WCHAR *wzVersion, UINT *pcchActual)
617 FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual);
618 return E_NOTIMPL;
621 static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
622 WCHAR *wzSpecVersion, UINT *pcchActual)
624 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
625 return E_NOTIMPL;
628 static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
629 WCHAR *wzFriendlyName, UINT *pcchActual)
631 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
632 return E_NOTIMPL;
635 static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
636 GUID *pguidContainerFormat)
638 FIXME("(%p,%p): stub\n", iface, pguidContainerFormat);
639 return E_NOTIMPL;
642 static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
643 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
645 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
646 return E_NOTIMPL;
649 static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
650 UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
652 FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
653 return E_NOTIMPL;
656 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
657 UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
659 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
660 return E_NOTIMPL;
663 static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
664 UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
666 FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
667 return E_NOTIMPL;
670 static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
671 UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
673 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
675 TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);
677 return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
678 cchMimeTypes, wzMimeTypes, pcchActual);
681 static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
682 UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
684 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
685 return E_NOTIMPL;
688 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
689 BOOL *pfSupportAnimation)
691 FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
692 return E_NOTIMPL;
695 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
696 BOOL *pfSupportChromaKey)
698 FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
699 return E_NOTIMPL;
702 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
703 BOOL *pfSupportLossless)
705 FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
706 return E_NOTIMPL;
709 static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
710 BOOL *pfSupportMultiframe)
712 FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
713 return E_NOTIMPL;
716 static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
717 LPCWSTR wzMimeType, BOOL *pfMatches)
719 FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
720 return E_NOTIMPL;
723 static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
724 IWICBitmapEncoder **ppIBitmapEncoder)
726 BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
728 TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);
730 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
731 &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
734 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
735 BitmapEncoderInfo_QueryInterface,
736 BitmapEncoderInfo_AddRef,
737 BitmapEncoderInfo_Release,
738 BitmapEncoderInfo_GetComponentType,
739 BitmapEncoderInfo_GetCLSID,
740 BitmapEncoderInfo_GetSigningStatus,
741 BitmapEncoderInfo_GetAuthor,
742 BitmapEncoderInfo_GetVendorGUID,
743 BitmapEncoderInfo_GetVersion,
744 BitmapEncoderInfo_GetSpecVersion,
745 BitmapEncoderInfo_GetFriendlyName,
746 BitmapEncoderInfo_GetContainerFormat,
747 BitmapEncoderInfo_GetPixelFormats,
748 BitmapEncoderInfo_GetColorManagementVersion,
749 BitmapEncoderInfo_GetDeviceManufacturer,
750 BitmapEncoderInfo_GetDeviceModels,
751 BitmapEncoderInfo_GetMimeTypes,
752 BitmapEncoderInfo_GetFileExtensions,
753 BitmapEncoderInfo_DoesSupportAnimation,
754 BitmapEncoderInfo_DoesSupportChromaKey,
755 BitmapEncoderInfo_DoesSupportLossless,
756 BitmapEncoderInfo_DoesSupportMultiframe,
757 BitmapEncoderInfo_MatchesMimeType,
758 BitmapEncoderInfo_CreateInstance
761 static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
763 BitmapEncoderInfo *This;
765 This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
766 if (!This)
768 RegCloseKey(classkey);
769 return E_OUTOFMEMORY;
772 This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
773 This->ref = 1;
774 This->classkey = classkey;
775 memcpy(&This->clsid, clsid, sizeof(CLSID));
777 *ppIInfo = (IWICComponentInfo*)This;
778 return S_OK;
781 typedef struct {
782 IWICFormatConverterInfo IWICFormatConverterInfo_iface;
783 LONG ref;
784 HKEY classkey;
785 CLSID clsid;
786 } FormatConverterInfo;
788 static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
790 return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
793 static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
794 void **ppv)
796 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
797 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
799 if (!ppv) return E_INVALIDARG;
801 if (IsEqualIID(&IID_IUnknown, iid) ||
802 IsEqualIID(&IID_IWICComponentInfo, iid) ||
803 IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
805 *ppv = This;
807 else
809 *ppv = NULL;
810 return E_NOINTERFACE;
813 IUnknown_AddRef((IUnknown*)*ppv);
814 return S_OK;
817 static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
819 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
820 ULONG ref = InterlockedIncrement(&This->ref);
822 TRACE("(%p) refcount=%u\n", iface, ref);
824 return ref;
827 static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
829 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
830 ULONG ref = InterlockedDecrement(&This->ref);
832 TRACE("(%p) refcount=%u\n", iface, ref);
834 if (ref == 0)
836 RegCloseKey(This->classkey);
837 HeapFree(GetProcessHeap(), 0, This);
840 return ref;
843 static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
844 WICComponentType *pType)
846 TRACE("(%p,%p)\n", iface, pType);
847 *pType = WICPixelFormatConverter;
848 return S_OK;
851 static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
853 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
854 TRACE("(%p,%p)\n", iface, pclsid);
856 if (!pclsid)
857 return E_INVALIDARG;
859 memcpy(pclsid, &This->clsid, sizeof(CLSID));
861 return S_OK;
864 static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
866 FIXME("(%p,%p): stub\n", iface, pStatus);
867 return E_NOTIMPL;
870 static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
871 WCHAR *wzAuthor, UINT *pcchActual)
873 FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual);
874 return E_NOTIMPL;
877 static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
879 FIXME("(%p,%p): stub\n", iface, pguidVendor);
880 return E_NOTIMPL;
883 static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
884 WCHAR *wzVersion, UINT *pcchActual)
886 FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual);
887 return E_NOTIMPL;
890 static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
891 WCHAR *wzSpecVersion, UINT *pcchActual)
893 FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
894 return E_NOTIMPL;
897 static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
898 WCHAR *wzFriendlyName, UINT *pcchActual)
900 FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
901 return E_NOTIMPL;
904 static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
905 UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
907 FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
908 return E_NOTIMPL;
911 static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
912 IWICFormatConverter **ppIFormatConverter)
914 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
916 TRACE("(%p,%p)\n", iface, ppIFormatConverter);
918 return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
919 &IID_IWICFormatConverter, (void**)ppIFormatConverter);
922 static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
924 LONG res;
925 FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
926 HKEY formats_key, guid_key;
928 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
929 would be O(n). A registry test should do better. */
931 res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
932 if (res != ERROR_SUCCESS) return FALSE;
934 res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
935 if (res == ERROR_SUCCESS) RegCloseKey(guid_key);
937 RegCloseKey(formats_key);
939 return (res == ERROR_SUCCESS);
942 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
943 FormatConverterInfo_QueryInterface,
944 FormatConverterInfo_AddRef,
945 FormatConverterInfo_Release,
946 FormatConverterInfo_GetComponentType,
947 FormatConverterInfo_GetCLSID,
948 FormatConverterInfo_GetSigningStatus,
949 FormatConverterInfo_GetAuthor,
950 FormatConverterInfo_GetVendorGUID,
951 FormatConverterInfo_GetVersion,
952 FormatConverterInfo_GetSpecVersion,
953 FormatConverterInfo_GetFriendlyName,
954 FormatConverterInfo_GetPixelFormats,
955 FormatConverterInfo_CreateInstance
958 static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
960 FormatConverterInfo *This;
962 This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
963 if (!This)
965 RegCloseKey(classkey);
966 return E_OUTOFMEMORY;
969 This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
970 This->ref = 1;
971 This->classkey = classkey;
972 memcpy(&This->clsid, clsid, sizeof(CLSID));
974 *ppIInfo = (IWICComponentInfo*)This;
975 return S_OK;
978 static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
979 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
981 struct category {
982 WICComponentType type;
983 const GUID *catid;
984 HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
987 static const struct category categories[] = {
988 {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
989 {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
990 {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
994 HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
996 HKEY clsidkey;
997 HKEY classkey;
998 HKEY catidkey;
999 HKEY instancekey;
1000 WCHAR guidstring[39];
1001 LONG res;
1002 const struct category *category;
1003 int found=0;
1004 HRESULT hr;
1006 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1007 if (res != ERROR_SUCCESS)
1008 return HRESULT_FROM_WIN32(res);
1010 for (category=categories; category->type; category++)
1012 StringFromGUID2(category->catid, guidstring, 39);
1013 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1014 if (res == ERROR_SUCCESS)
1016 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1017 if (res == ERROR_SUCCESS)
1019 StringFromGUID2(clsid, guidstring, 39);
1020 res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
1021 if (res == ERROR_SUCCESS)
1023 RegCloseKey(classkey);
1024 found = 1;
1026 RegCloseKey(instancekey);
1028 RegCloseKey(catidkey);
1030 if (found) break;
1033 if (found)
1035 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
1036 if (res == ERROR_SUCCESS)
1037 hr = category->constructor(classkey, clsid, ppIInfo);
1038 else
1039 hr = HRESULT_FROM_WIN32(res);
1041 else
1042 hr = E_FAIL;
1044 RegCloseKey(clsidkey);
1046 return hr;
1049 typedef struct {
1050 IEnumUnknown IEnumUnknown_iface;
1051 LONG ref;
1052 struct list objects;
1053 struct list *cursor;
1054 CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
1055 } ComponentEnum;
1057 static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
1059 return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
1062 typedef struct {
1063 struct list entry;
1064 IUnknown *unk;
1065 } ComponentEnumItem;
1067 static const IEnumUnknownVtbl ComponentEnumVtbl;
1069 static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
1070 void **ppv)
1072 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1073 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
1075 if (!ppv) return E_INVALIDARG;
1077 if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IEnumUnknown, iid))
1079 *ppv = This;
1081 else
1083 *ppv = NULL;
1084 return E_NOINTERFACE;
1087 IUnknown_AddRef((IUnknown*)*ppv);
1088 return S_OK;
1091 static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
1093 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1094 ULONG ref = InterlockedIncrement(&This->ref);
1096 TRACE("(%p) refcount=%u\n", iface, ref);
1098 return ref;
1101 static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
1103 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1104 ULONG ref = InterlockedDecrement(&This->ref);
1105 ComponentEnumItem *cursor, *cursor2;
1107 TRACE("(%p) refcount=%u\n", iface, ref);
1109 if (ref == 0)
1111 LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
1113 IUnknown_Release(cursor->unk);
1114 list_remove(&cursor->entry);
1115 HeapFree(GetProcessHeap(), 0, cursor);
1117 This->lock.DebugInfo->Spare[0] = 0;
1118 DeleteCriticalSection(&This->lock);
1119 HeapFree(GetProcessHeap(), 0, This);
1122 return ref;
1125 static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
1126 IUnknown **rgelt, ULONG *pceltFetched)
1128 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1129 int num_fetched=0;
1130 ComponentEnumItem *item;
1131 HRESULT hr=S_OK;
1133 TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);
1135 EnterCriticalSection(&This->lock);
1136 while (num_fetched<celt)
1138 if (!This->cursor)
1140 hr = S_FALSE;
1141 break;
1143 item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
1144 IUnknown_AddRef(item->unk);
1145 rgelt[num_fetched] = item->unk;
1146 num_fetched++;
1147 This->cursor = list_next(&This->objects, This->cursor);
1149 LeaveCriticalSection(&This->lock);
1150 if (pceltFetched)
1151 *pceltFetched = num_fetched;
1152 return hr;
1155 static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
1157 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1158 int i;
1159 HRESULT hr=S_OK;
1161 TRACE("(%p,%u)\n", iface, celt);
1163 EnterCriticalSection(&This->lock);
1164 for (i=0; i<celt; i++)
1166 if (!This->cursor)
1168 hr = S_FALSE;
1169 break;
1171 This->cursor = list_next(&This->objects, This->cursor);
1173 LeaveCriticalSection(&This->lock);
1174 return hr;
1177 static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
1179 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1181 TRACE("(%p)\n", iface);
1183 EnterCriticalSection(&This->lock);
1184 This->cursor = list_head(&This->objects);
1185 LeaveCriticalSection(&This->lock);
1186 return S_OK;
1189 static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
1191 ComponentEnum *This = impl_from_IEnumUnknown(iface);
1192 ComponentEnum *new_enum;
1193 ComponentEnumItem *old_item, *new_item;
1194 HRESULT ret=S_OK;
1195 struct list *old_cursor;
1197 new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1198 if (!new_enum)
1200 *ppenum = NULL;
1201 return E_OUTOFMEMORY;
1204 new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1205 new_enum->ref = 1;
1206 new_enum->cursor = NULL;
1207 list_init(&new_enum->objects);
1208 InitializeCriticalSection(&new_enum->lock);
1209 new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1211 EnterCriticalSection(&This->lock);
1212 old_cursor = This->cursor;
1213 LeaveCriticalSection(&This->lock);
1215 LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
1217 new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1218 if (!new_item)
1220 ret = E_OUTOFMEMORY;
1221 break;
1223 new_item->unk = old_item->unk;
1224 list_add_tail(&new_enum->objects, &new_item->entry);
1225 IUnknown_AddRef(new_item->unk);
1226 if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
1229 if (FAILED(ret))
1231 IUnknown_Release((IUnknown*)new_enum);
1232 *ppenum = NULL;
1234 else
1235 *ppenum = (IEnumUnknown*)new_enum;
1237 return ret;
1240 static const IEnumUnknownVtbl ComponentEnumVtbl = {
1241 ComponentEnum_QueryInterface,
1242 ComponentEnum_AddRef,
1243 ComponentEnum_Release,
1244 ComponentEnum_Next,
1245 ComponentEnum_Skip,
1246 ComponentEnum_Reset,
1247 ComponentEnum_Clone
1250 HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
1252 ComponentEnum *This;
1253 ComponentEnumItem *item;
1254 const struct category *category;
1255 HKEY clsidkey, catidkey, instancekey;
1256 WCHAR guidstring[39];
1257 LONG res;
1258 int i;
1259 HRESULT hr=S_OK;
1260 CLSID clsid;
1262 if (options) FIXME("ignoring flags %x\n", options);
1264 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
1265 if (res != ERROR_SUCCESS)
1266 return HRESULT_FROM_WIN32(res);
1268 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
1269 if (!This)
1271 RegCloseKey(clsidkey);
1272 return E_OUTOFMEMORY;
1275 This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
1276 This->ref = 1;
1277 list_init(&This->objects);
1278 InitializeCriticalSection(&This->lock);
1279 This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");
1281 for (category=categories; category->type && hr == S_OK; category++)
1283 if ((category->type & componentTypes) == 0) continue;
1284 StringFromGUID2(category->catid, guidstring, 39);
1285 res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
1286 if (res == ERROR_SUCCESS)
1288 res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
1289 if (res == ERROR_SUCCESS)
1291 i=0;
1292 for (;;i++)
1294 DWORD guidstring_size = 39;
1295 res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
1296 if (res != ERROR_SUCCESS) break;
1298 item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
1299 if (!item) { hr = E_OUTOFMEMORY; break; }
1301 hr = CLSIDFromString(guidstring, &clsid);
1302 if (SUCCEEDED(hr))
1304 hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
1305 if (SUCCEEDED(hr))
1306 list_add_tail(&This->objects, &item->entry);
1309 if (FAILED(hr))
1311 HeapFree(GetProcessHeap(), 0, item);
1312 hr = S_OK;
1315 RegCloseKey(instancekey);
1317 RegCloseKey(catidkey);
1319 if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
1320 hr = HRESULT_FROM_WIN32(res);
1322 RegCloseKey(clsidkey);
1324 if (SUCCEEDED(hr))
1326 IEnumUnknown_Reset((IEnumUnknown*)This);
1327 *ppIEnumUnknown = (IEnumUnknown*)This;
1329 else
1331 *ppIEnumUnknown = NULL;
1332 IUnknown_Release((IUnknown*)This);
1335 return hr;
1338 HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
1340 HRESULT res;
1341 IEnumUnknown *enumconverters;
1342 IUnknown *unkconverterinfo;
1343 IWICFormatConverterInfo *converterinfo=NULL;
1344 IWICFormatConverter *converter=NULL;
1345 GUID srcFormat;
1346 WCHAR srcformatstr[39], dstformatstr[39];
1347 BOOL canconvert;
1348 ULONG num_fetched;
1350 res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
1351 if (FAILED(res)) return res;
1353 if (IsEqualGUID(&srcFormat, dstFormat))
1355 IWICBitmapSource_AddRef(pISrc);
1356 *ppIDst = pISrc;
1357 return S_OK;
1360 StringFromGUID2(&srcFormat, srcformatstr, 39);
1361 StringFromGUID2(dstFormat, dstformatstr, 39);
1363 res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
1364 if (FAILED(res)) return res;
1366 while (!converter)
1368 res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);
1370 if (res == S_OK)
1372 res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);
1374 if (SUCCEEDED(res))
1376 canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);
1378 if (canconvert)
1379 canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);
1381 if (canconvert)
1383 res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);
1385 if (SUCCEEDED(res))
1386 res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);
1388 if (SUCCEEDED(res) && canconvert)
1389 res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
1390 NULL, 0.0, WICBitmapPaletteTypeCustom);
1392 if (FAILED(res) || !canconvert)
1394 if (converter)
1396 IWICFormatConverter_Release(converter);
1397 converter = NULL;
1399 res = S_OK;
1403 IWICFormatConverterInfo_Release(converterinfo);
1406 IUnknown_Release(unkconverterinfo);
1408 else
1409 break;
1412 IEnumUnknown_Release(enumconverters);
1414 if (converter)
1416 *ppIDst = (IWICBitmapSource*)converter;
1417 return S_OK;
1419 else
1421 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
1422 *ppIDst = NULL;
1423 return WINCODEC_ERR_COMPONENTNOTFOUND;