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
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
)
47 DWORD cbdata
=buffer_size
* sizeof(WCHAR
);
52 ret
= RegGetValueW(classkey
, NULL
, value
, RRF_RT_REG_SZ
|RRF_NOEXPAND
, NULL
,
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. */
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
,
72 WCHAR guid_string
[39];
73 DWORD cbdata
= sizeof(guid_string
);
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");
91 hr
= CLSIDFromString(guid_string
, result
);
97 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface
;
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
,
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
))
126 return E_NOINTERFACE
;
129 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
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
);
152 RegCloseKey(This
->classkey
);
153 HeapFree(GetProcessHeap(), 0, This
);
159 static HRESULT WINAPI
BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo
*iface
,
160 WICComponentType
*pType
)
162 TRACE("(%p,%p)\n", iface
, pType
);
167 static HRESULT WINAPI
BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo
*iface
, CLSID
*pclsid
)
169 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
170 TRACE("(%p,%p)\n", iface
, pclsid
);
175 memcpy(pclsid
, &This
->clsid
, sizeof(CLSID
));
180 static HRESULT WINAPI
BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo
*iface
, DWORD
*pStatus
)
182 FIXME("(%p,%p): stub\n", iface
, pStatus
);
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
);
193 static HRESULT WINAPI
BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo
*iface
, GUID
*pguidVendor
)
195 FIXME("(%p,%p): stub\n", iface
, pguidVendor
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
274 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo
*iface
,
275 BOOL
*pfSupportAnimation
)
277 FIXME("(%p,%p): stub\n", iface
, pfSupportAnimation
);
281 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo
*iface
,
282 BOOL
*pfSupportChromaKey
)
284 FIXME("(%p,%p): stub\n", iface
, pfSupportChromaKey
);
288 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo
*iface
,
289 BOOL
*pfSupportLossless
)
291 FIXME("(%p,%p): stub\n", iface
, pfSupportLossless
);
295 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo
*iface
,
296 BOOL
*pfSupportMultiframe
)
298 FIXME("(%p,%p): stub\n", iface
, pfSupportMultiframe
);
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
);
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];
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};
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;
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
;
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
);
390 else hr
= HRESULT_FROM_WIN32(res
);
392 RegCloseKey(patternskey
);
396 *pcPatterns
= pattern_count
;
397 *pcbPatternsActual
= patterns_size
;
398 if (pPatterns
&& cbSizePatterns
< patterns_size
)
399 hr
= WINCODEC_ERR_INSUFFICIENTBUFFER
;
405 static HRESULT WINAPI
BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo
*iface
,
406 IStream
*pIStream
, BOOL
*pfMatches
)
408 WICBitmapPattern
*patterns
;
409 UINT pattern_count
=0, patterns_size
=0;
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
);
442 if (patterns
[i
].EndOfStream
)
443 seekpos
.QuadPart
= -patterns
[i
].Position
.QuadPart
;
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 */
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
])
460 if (pos
== patterns
[i
].Length
) /* matches pattern */
468 if (i
== pattern_count
) /* does not match any pattern */
475 HeapFree(GetProcessHeap(), 0, patterns
);
476 HeapFree(GetProcessHeap(), 0, data
);
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
));
528 RegCloseKey(classkey
);
529 return E_OUTOFMEMORY
;
532 This
->IWICBitmapDecoderInfo_iface
.lpVtbl
= &BitmapDecoderInfo_Vtbl
;
534 This
->classkey
= classkey
;
535 memcpy(&This
->clsid
, clsid
, sizeof(CLSID
));
537 *ppIInfo
= (IWICComponentInfo
*)This
;
542 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface
;
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
,
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
))
571 return E_NOINTERFACE
;
574 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
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
);
597 RegCloseKey(This
->classkey
);
598 HeapFree(GetProcessHeap(), 0, This
);
604 static HRESULT WINAPI
BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo
*iface
,
605 WICComponentType
*pType
)
607 TRACE("(%p,%p)\n", iface
, pType
);
612 static HRESULT WINAPI
BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo
*iface
, CLSID
*pclsid
)
614 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
615 TRACE("(%p,%p)\n", iface
, pclsid
);
620 memcpy(pclsid
, &This
->clsid
, sizeof(CLSID
));
625 static HRESULT WINAPI
BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo
*iface
, DWORD
*pStatus
)
627 FIXME("(%p,%p): stub\n", iface
, pStatus
);
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
);
638 static HRESULT WINAPI
BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo
*iface
, GUID
*pguidVendor
)
640 FIXME("(%p,%p): stub\n", iface
, pguidVendor
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
719 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo
*iface
,
720 BOOL
*pfSupportAnimation
)
722 FIXME("(%p,%p): stub\n", iface
, pfSupportAnimation
);
726 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo
*iface
,
727 BOOL
*pfSupportChromaKey
)
729 FIXME("(%p,%p): stub\n", iface
, pfSupportChromaKey
);
733 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo
*iface
,
734 BOOL
*pfSupportLossless
)
736 FIXME("(%p,%p): stub\n", iface
, pfSupportLossless
);
740 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo
*iface
,
741 BOOL
*pfSupportMultiframe
)
743 FIXME("(%p,%p): stub\n", iface
, pfSupportMultiframe
);
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
);
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
));
799 RegCloseKey(classkey
);
800 return E_OUTOFMEMORY
;
803 This
->IWICBitmapEncoderInfo_iface
.lpVtbl
= &BitmapEncoderInfo_Vtbl
;
805 This
->classkey
= classkey
;
806 memcpy(&This
->clsid
, clsid
, sizeof(CLSID
));
808 *ppIInfo
= (IWICComponentInfo
*)This
;
813 IWICFormatConverterInfo IWICFormatConverterInfo_iface
;
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
,
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
))
841 return E_NOINTERFACE
;
844 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
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
);
867 RegCloseKey(This
->classkey
);
868 HeapFree(GetProcessHeap(), 0, This
);
874 static HRESULT WINAPI
FormatConverterInfo_GetComponentType(IWICFormatConverterInfo
*iface
,
875 WICComponentType
*pType
)
877 TRACE("(%p,%p)\n", iface
, pType
);
878 *pType
= WICPixelFormatConverter
;
882 static HRESULT WINAPI
FormatConverterInfo_GetCLSID(IWICFormatConverterInfo
*iface
, CLSID
*pclsid
)
884 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
885 TRACE("(%p,%p)\n", iface
, pclsid
);
890 memcpy(pclsid
, &This
->clsid
, sizeof(CLSID
));
895 static HRESULT WINAPI
FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo
*iface
, DWORD
*pStatus
)
897 FIXME("(%p,%p): stub\n", iface
, pStatus
);
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
);
908 static HRESULT WINAPI
FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo
*iface
, GUID
*pguidVendor
)
910 FIXME("(%p,%p): stub\n", iface
, pguidVendor
);
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
);
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
);
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
);
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
);
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
)
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
));
996 RegCloseKey(classkey
);
997 return E_OUTOFMEMORY
;
1000 This
->IWICFormatConverterInfo_iface
.lpVtbl
= &FormatConverterInfo_Vtbl
;
1002 This
->classkey
= classkey
;
1003 memcpy(&This
->clsid
, clsid
, sizeof(CLSID
));
1005 *ppIInfo
= (IWICComponentInfo
*)This
;
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};
1013 WICComponentType type
;
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
)
1031 WCHAR guidstring
[39];
1033 const struct category
*category
;
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
);
1057 RegCloseKey(instancekey
);
1059 RegCloseKey(catidkey
);
1066 res
= RegOpenKeyExW(clsidkey
, guidstring
, 0, KEY_READ
, &classkey
);
1067 if (res
== ERROR_SUCCESS
)
1068 hr
= category
->constructor(classkey
, clsid
, ppIInfo
);
1070 hr
= HRESULT_FROM_WIN32(res
);
1075 RegCloseKey(clsidkey
);
1081 IEnumUnknown IEnumUnknown_iface
;
1083 struct list objects
;
1084 struct list
*cursor
;
1085 CRITICAL_SECTION lock
; /* Must be held when reading or writing cursor */
1088 static inline ComponentEnum
*impl_from_IEnumUnknown(IEnumUnknown
*iface
)
1090 return CONTAINING_RECORD(iface
, ComponentEnum
, IEnumUnknown_iface
);
1096 } ComponentEnumItem
;
1098 static const IEnumUnknownVtbl ComponentEnumVtbl
;
1100 static HRESULT WINAPI
ComponentEnum_QueryInterface(IEnumUnknown
*iface
, REFIID iid
,
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
))
1115 return E_NOINTERFACE
;
1118 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
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
);
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
);
1156 static HRESULT WINAPI
ComponentEnum_Next(IEnumUnknown
*iface
, ULONG celt
,
1157 IUnknown
**rgelt
, ULONG
*pceltFetched
)
1159 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
1161 ComponentEnumItem
*item
;
1164 TRACE("(%p,%u,%p,%p)\n", iface
, celt
, rgelt
, pceltFetched
);
1166 EnterCriticalSection(&This
->lock
);
1167 while (num_fetched
<celt
)
1174 item
= LIST_ENTRY(This
->cursor
, ComponentEnumItem
, entry
);
1175 IUnknown_AddRef(item
->unk
);
1176 rgelt
[num_fetched
] = item
->unk
;
1178 This
->cursor
= list_next(&This
->objects
, This
->cursor
);
1180 LeaveCriticalSection(&This
->lock
);
1182 *pceltFetched
= num_fetched
;
1186 static HRESULT WINAPI
ComponentEnum_Skip(IEnumUnknown
*iface
, ULONG celt
)
1188 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
1192 TRACE("(%p,%u)\n", iface
, celt
);
1194 EnterCriticalSection(&This
->lock
);
1195 for (i
=0; i
<celt
; i
++)
1202 This
->cursor
= list_next(&This
->objects
, This
->cursor
);
1204 LeaveCriticalSection(&This
->lock
);
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
);
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
;
1226 struct list
*old_cursor
;
1228 new_enum
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum
));
1232 return E_OUTOFMEMORY
;
1235 new_enum
->IEnumUnknown_iface
.lpVtbl
= &ComponentEnumVtbl
;
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
));
1251 ret
= E_OUTOFMEMORY
;
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
;
1262 IUnknown_Release((IUnknown
*)new_enum
);
1266 *ppenum
= (IEnumUnknown
*)new_enum
;
1271 static const IEnumUnknownVtbl ComponentEnumVtbl
= {
1272 ComponentEnum_QueryInterface
,
1273 ComponentEnum_AddRef
,
1274 ComponentEnum_Release
,
1277 ComponentEnum_Reset
,
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];
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
));
1302 RegCloseKey(clsidkey
);
1303 return E_OUTOFMEMORY
;
1306 This
->IEnumUnknown_iface
.lpVtbl
= &ComponentEnumVtbl
;
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
)
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
);
1335 hr
= CreateComponentInfo(&clsid
, (IWICComponentInfo
**)&item
->unk
);
1337 list_add_tail(&This
->objects
, &item
->entry
);
1342 HeapFree(GetProcessHeap(), 0, item
);
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
);
1357 IEnumUnknown_Reset((IEnumUnknown
*)This
);
1358 *ppIEnumUnknown
= (IEnumUnknown
*)This
;
1362 *ppIEnumUnknown
= NULL
;
1363 IUnknown_Release((IUnknown
*)This
);
1369 HRESULT WINAPI
WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat
, IWICBitmapSource
*pISrc
, IWICBitmapSource
**ppIDst
)
1372 IEnumUnknown
*enumconverters
;
1373 IUnknown
*unkconverterinfo
;
1374 IWICFormatConverterInfo
*converterinfo
=NULL
;
1375 IWICFormatConverter
*converter
=NULL
;
1377 WCHAR srcformatstr
[39], dstformatstr
[39];
1381 res
= IWICBitmapSource_GetPixelFormat(pISrc
, &srcFormat
);
1382 if (FAILED(res
)) return res
;
1384 if (IsEqualGUID(&srcFormat
, dstFormat
))
1386 IWICBitmapSource_AddRef(pISrc
);
1391 StringFromGUID2(&srcFormat
, srcformatstr
, 39);
1392 StringFromGUID2(dstFormat
, dstformatstr
, 39);
1394 res
= CreateComponentEnumerator(WICPixelFormatConverter
, 0, &enumconverters
);
1395 if (FAILED(res
)) return res
;
1399 res
= IEnumUnknown_Next(enumconverters
, 1, &unkconverterinfo
, &num_fetched
);
1403 res
= IUnknown_QueryInterface(unkconverterinfo
, &IID_IWICFormatConverterInfo
, (void**)&converterinfo
);
1407 canconvert
= ConverterSupportsFormat(converterinfo
, srcformatstr
);
1410 canconvert
= ConverterSupportsFormat(converterinfo
, dstformatstr
);
1414 res
= IWICFormatConverterInfo_CreateInstance(converterinfo
, &converter
);
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
)
1427 IWICFormatConverter_Release(converter
);
1434 IWICFormatConverterInfo_Release(converterinfo
);
1437 IUnknown_Release(unkconverterinfo
);
1443 IEnumUnknown_Release(enumconverters
);
1447 *ppIDst
= (IWICBitmapSource
*)converter
;
1452 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat
), debugstr_guid(dstFormat
));
1454 return WINCODEC_ERR_COMPONENTNOTFOUND
;