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};
42 static HRESULT
ComponentInfo_GetStringValue(HKEY classkey
, LPCWSTR value
,
43 UINT buffer_size
, WCHAR
*buffer
, UINT
*actual_size
)
46 DWORD cbdata
=buffer_size
* sizeof(WCHAR
);
51 ret
= RegGetValueW(classkey
, NULL
, value
, RRF_RT_REG_SZ
|RRF_NOEXPAND
, NULL
,
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. */
61 if (ret
== ERROR_MORE_DATA
)
62 return WINCODEC_ERR_INSUFFICIENTBUFFER
;
64 return HRESULT_FROM_WIN32(ret
);
68 IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface
;
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
,
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
))
100 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
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
);
123 RegCloseKey(This
->classkey
);
124 HeapFree(GetProcessHeap(), 0, This
);
130 static HRESULT WINAPI
BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo
*iface
,
131 WICComponentType
*pType
)
133 TRACE("(%p,%p)\n", iface
, pType
);
138 static HRESULT WINAPI
BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo
*iface
, CLSID
*pclsid
)
140 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
141 TRACE("(%p,%p)\n", iface
, pclsid
);
146 memcpy(pclsid
, &This
->clsid
, sizeof(CLSID
));
151 static HRESULT WINAPI
BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo
*iface
, DWORD
*pStatus
)
153 FIXME("(%p,%p): stub\n", iface
, pStatus
);
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
);
164 static HRESULT WINAPI
BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo
*iface
, GUID
*pguidVendor
)
166 FIXME("(%p,%p): stub\n", iface
, pguidVendor
);
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
);
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
);
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
);
191 static HRESULT WINAPI
BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo
*iface
,
192 GUID
*pguidContainerFormat
)
194 FIXME("(%p,%p): stub\n", iface
, pguidContainerFormat
);
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
);
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
);
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
);
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
);
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
);
244 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo
*iface
,
245 BOOL
*pfSupportAnimation
)
247 FIXME("(%p,%p): stub\n", iface
, pfSupportAnimation
);
251 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo
*iface
,
252 BOOL
*pfSupportChromaKey
)
254 FIXME("(%p,%p): stub\n", iface
, pfSupportChromaKey
);
258 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo
*iface
,
259 BOOL
*pfSupportLossless
)
261 FIXME("(%p,%p): stub\n", iface
, pfSupportLossless
);
265 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo
*iface
,
266 BOOL
*pfSupportMultiframe
)
268 FIXME("(%p,%p): stub\n", iface
, pfSupportMultiframe
);
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
);
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];
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};
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;
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
;
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
);
360 else hr
= HRESULT_FROM_WIN32(res
);
362 RegCloseKey(patternskey
);
366 *pcPatterns
= pattern_count
;
367 *pcbPatternsActual
= patterns_size
;
368 if (pPatterns
&& cbSizePatterns
< patterns_size
)
369 hr
= WINCODEC_ERR_INSUFFICIENTBUFFER
;
375 static HRESULT WINAPI
BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo
*iface
,
376 IStream
*pIStream
, BOOL
*pfMatches
)
378 WICBitmapPattern
*patterns
;
379 UINT pattern_count
=0, patterns_size
=0;
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
);
412 if (patterns
[i
].EndOfStream
)
413 seekpos
.QuadPart
= -patterns
[i
].Position
.QuadPart
;
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 */
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
])
430 if (pos
== patterns
[i
].Length
) /* matches pattern */
438 if (i
== pattern_count
) /* does not match any pattern */
445 HeapFree(GetProcessHeap(), 0, patterns
);
446 HeapFree(GetProcessHeap(), 0, data
);
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
));
498 RegCloseKey(classkey
);
499 return E_OUTOFMEMORY
;
502 This
->IWICBitmapDecoderInfo_iface
.lpVtbl
= &BitmapDecoderInfo_Vtbl
;
504 This
->classkey
= classkey
;
505 memcpy(&This
->clsid
, clsid
, sizeof(CLSID
));
507 *ppIInfo
= (IWICComponentInfo
*)This
;
512 IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface
;
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
,
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
))
541 return E_NOINTERFACE
;
544 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
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
);
567 RegCloseKey(This
->classkey
);
568 HeapFree(GetProcessHeap(), 0, This
);
574 static HRESULT WINAPI
BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo
*iface
,
575 WICComponentType
*pType
)
577 TRACE("(%p,%p)\n", iface
, pType
);
582 static HRESULT WINAPI
BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo
*iface
, CLSID
*pclsid
)
584 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
585 TRACE("(%p,%p)\n", iface
, pclsid
);
590 memcpy(pclsid
, &This
->clsid
, sizeof(CLSID
));
595 static HRESULT WINAPI
BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo
*iface
, DWORD
*pStatus
)
597 FIXME("(%p,%p): stub\n", iface
, pStatus
);
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
);
608 static HRESULT WINAPI
BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo
*iface
, GUID
*pguidVendor
)
610 FIXME("(%p,%p): stub\n", iface
, pguidVendor
);
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
);
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
);
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
);
635 static HRESULT WINAPI
BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo
*iface
,
636 GUID
*pguidContainerFormat
)
638 FIXME("(%p,%p): stub\n", iface
, pguidContainerFormat
);
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
);
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
);
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
);
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
);
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
);
688 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo
*iface
,
689 BOOL
*pfSupportAnimation
)
691 FIXME("(%p,%p): stub\n", iface
, pfSupportAnimation
);
695 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo
*iface
,
696 BOOL
*pfSupportChromaKey
)
698 FIXME("(%p,%p): stub\n", iface
, pfSupportChromaKey
);
702 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo
*iface
,
703 BOOL
*pfSupportLossless
)
705 FIXME("(%p,%p): stub\n", iface
, pfSupportLossless
);
709 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo
*iface
,
710 BOOL
*pfSupportMultiframe
)
712 FIXME("(%p,%p): stub\n", iface
, pfSupportMultiframe
);
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
);
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
));
768 RegCloseKey(classkey
);
769 return E_OUTOFMEMORY
;
772 This
->IWICBitmapEncoderInfo_iface
.lpVtbl
= &BitmapEncoderInfo_Vtbl
;
774 This
->classkey
= classkey
;
775 memcpy(&This
->clsid
, clsid
, sizeof(CLSID
));
777 *ppIInfo
= (IWICComponentInfo
*)This
;
782 IWICFormatConverterInfo IWICFormatConverterInfo_iface
;
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
,
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
))
810 return E_NOINTERFACE
;
813 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
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
);
836 RegCloseKey(This
->classkey
);
837 HeapFree(GetProcessHeap(), 0, This
);
843 static HRESULT WINAPI
FormatConverterInfo_GetComponentType(IWICFormatConverterInfo
*iface
,
844 WICComponentType
*pType
)
846 TRACE("(%p,%p)\n", iface
, pType
);
847 *pType
= WICPixelFormatConverter
;
851 static HRESULT WINAPI
FormatConverterInfo_GetCLSID(IWICFormatConverterInfo
*iface
, CLSID
*pclsid
)
853 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
854 TRACE("(%p,%p)\n", iface
, pclsid
);
859 memcpy(pclsid
, &This
->clsid
, sizeof(CLSID
));
864 static HRESULT WINAPI
FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo
*iface
, DWORD
*pStatus
)
866 FIXME("(%p,%p): stub\n", iface
, pStatus
);
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
);
877 static HRESULT WINAPI
FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo
*iface
, GUID
*pguidVendor
)
879 FIXME("(%p,%p): stub\n", iface
, pguidVendor
);
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
);
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
);
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
);
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
);
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
)
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
));
965 RegCloseKey(classkey
);
966 return E_OUTOFMEMORY
;
969 This
->IWICFormatConverterInfo_iface
.lpVtbl
= &FormatConverterInfo_Vtbl
;
971 This
->classkey
= classkey
;
972 memcpy(&This
->clsid
, clsid
, sizeof(CLSID
));
974 *ppIInfo
= (IWICComponentInfo
*)This
;
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};
982 WICComponentType type
;
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
)
1000 WCHAR guidstring
[39];
1002 const struct category
*category
;
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
);
1026 RegCloseKey(instancekey
);
1028 RegCloseKey(catidkey
);
1035 res
= RegOpenKeyExW(clsidkey
, guidstring
, 0, KEY_READ
, &classkey
);
1036 if (res
== ERROR_SUCCESS
)
1037 hr
= category
->constructor(classkey
, clsid
, ppIInfo
);
1039 hr
= HRESULT_FROM_WIN32(res
);
1044 RegCloseKey(clsidkey
);
1050 IEnumUnknown IEnumUnknown_iface
;
1052 struct list objects
;
1053 struct list
*cursor
;
1054 CRITICAL_SECTION lock
; /* Must be held when reading or writing cursor */
1057 static inline ComponentEnum
*impl_from_IEnumUnknown(IEnumUnknown
*iface
)
1059 return CONTAINING_RECORD(iface
, ComponentEnum
, IEnumUnknown_iface
);
1065 } ComponentEnumItem
;
1067 static const IEnumUnknownVtbl ComponentEnumVtbl
;
1069 static HRESULT WINAPI
ComponentEnum_QueryInterface(IEnumUnknown
*iface
, REFIID iid
,
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
))
1084 return E_NOINTERFACE
;
1087 IUnknown_AddRef((IUnknown
*)*ppv
);
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
);
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
);
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
);
1125 static HRESULT WINAPI
ComponentEnum_Next(IEnumUnknown
*iface
, ULONG celt
,
1126 IUnknown
**rgelt
, ULONG
*pceltFetched
)
1128 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
1130 ComponentEnumItem
*item
;
1133 TRACE("(%p,%u,%p,%p)\n", iface
, celt
, rgelt
, pceltFetched
);
1135 EnterCriticalSection(&This
->lock
);
1136 while (num_fetched
<celt
)
1143 item
= LIST_ENTRY(This
->cursor
, ComponentEnumItem
, entry
);
1144 IUnknown_AddRef(item
->unk
);
1145 rgelt
[num_fetched
] = item
->unk
;
1147 This
->cursor
= list_next(&This
->objects
, This
->cursor
);
1149 LeaveCriticalSection(&This
->lock
);
1151 *pceltFetched
= num_fetched
;
1155 static HRESULT WINAPI
ComponentEnum_Skip(IEnumUnknown
*iface
, ULONG celt
)
1157 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
1161 TRACE("(%p,%u)\n", iface
, celt
);
1163 EnterCriticalSection(&This
->lock
);
1164 for (i
=0; i
<celt
; i
++)
1171 This
->cursor
= list_next(&This
->objects
, This
->cursor
);
1173 LeaveCriticalSection(&This
->lock
);
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
);
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
;
1195 struct list
*old_cursor
;
1197 new_enum
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum
));
1201 return E_OUTOFMEMORY
;
1204 new_enum
->IEnumUnknown_iface
.lpVtbl
= &ComponentEnumVtbl
;
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
));
1220 ret
= E_OUTOFMEMORY
;
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
;
1231 IUnknown_Release((IUnknown
*)new_enum
);
1235 *ppenum
= (IEnumUnknown
*)new_enum
;
1240 static const IEnumUnknownVtbl ComponentEnumVtbl
= {
1241 ComponentEnum_QueryInterface
,
1242 ComponentEnum_AddRef
,
1243 ComponentEnum_Release
,
1246 ComponentEnum_Reset
,
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];
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
));
1271 RegCloseKey(clsidkey
);
1272 return E_OUTOFMEMORY
;
1275 This
->IEnumUnknown_iface
.lpVtbl
= &ComponentEnumVtbl
;
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
)
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
);
1304 hr
= CreateComponentInfo(&clsid
, (IWICComponentInfo
**)&item
->unk
);
1306 list_add_tail(&This
->objects
, &item
->entry
);
1311 HeapFree(GetProcessHeap(), 0, item
);
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
);
1326 IEnumUnknown_Reset((IEnumUnknown
*)This
);
1327 *ppIEnumUnknown
= (IEnumUnknown
*)This
;
1331 *ppIEnumUnknown
= NULL
;
1332 IUnknown_Release((IUnknown
*)This
);
1338 HRESULT WINAPI
WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat
, IWICBitmapSource
*pISrc
, IWICBitmapSource
**ppIDst
)
1341 IEnumUnknown
*enumconverters
;
1342 IUnknown
*unkconverterinfo
;
1343 IWICFormatConverterInfo
*converterinfo
=NULL
;
1344 IWICFormatConverter
*converter
=NULL
;
1346 WCHAR srcformatstr
[39], dstformatstr
[39];
1350 res
= IWICBitmapSource_GetPixelFormat(pISrc
, &srcFormat
);
1351 if (FAILED(res
)) return res
;
1353 if (IsEqualGUID(&srcFormat
, dstFormat
))
1355 IWICBitmapSource_AddRef(pISrc
);
1360 StringFromGUID2(&srcFormat
, srcformatstr
, 39);
1361 StringFromGUID2(dstFormat
, dstformatstr
, 39);
1363 res
= CreateComponentEnumerator(WICPixelFormatConverter
, 0, &enumconverters
);
1364 if (FAILED(res
)) return res
;
1368 res
= IEnumUnknown_Next(enumconverters
, 1, &unkconverterinfo
, &num_fetched
);
1372 res
= IUnknown_QueryInterface(unkconverterinfo
, &IID_IWICFormatConverterInfo
, (void**)&converterinfo
);
1376 canconvert
= ConverterSupportsFormat(converterinfo
, srcformatstr
);
1379 canconvert
= ConverterSupportsFormat(converterinfo
, dstformatstr
);
1383 res
= IWICFormatConverterInfo_CreateInstance(converterinfo
, &converter
);
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
)
1396 IWICFormatConverter_Release(converter
);
1403 IWICFormatConverterInfo_Release(converterinfo
);
1406 IUnknown_Release(unkconverterinfo
);
1412 IEnumUnknown_Release(enumconverters
);
1416 *ppIDst
= (IWICBitmapSource
*)converter
;
1421 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat
), debugstr_guid(dstFormat
));
1423 return WINCODEC_ERR_COMPONENTNOTFOUND
;