2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 * Copyright 2012 Dmitry Timoshkov
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wincodecs_private.h"
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
35 #include "wine/list.h"
36 #include "wine/rbtree.h"
37 #include "wine/heap.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
41 static const WCHAR mimetypes_valuename
[] = {'M','i','m','e','T','y','p','e','s',0};
42 static const WCHAR author_valuename
[] = {'A','u','t','h','o','r',0};
43 static const WCHAR friendlyname_valuename
[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
44 static const WCHAR pixelformats_keyname
[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
45 static const WCHAR formats_keyname
[] = {'F','o','r','m','a','t','s',0};
46 static const WCHAR containerformat_valuename
[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
47 static const WCHAR metadataformat_valuename
[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
48 static const WCHAR vendor_valuename
[] = {'V','e','n','d','o','r',0};
49 static const WCHAR version_valuename
[] = {'V','e','r','s','i','o','n',0};
50 static const WCHAR specversion_valuename
[] = {'S','p','e','c','V','e','r','s','i','o','n',0};
51 static const WCHAR bitsperpixel_valuename
[] = {'B','i','t','L','e','n','g','t','h',0};
52 static const WCHAR channelcount_valuename
[] = {'C','h','a','n','n','e','l','C','o','u','n','t',0};
53 static const WCHAR channelmasks_keyname
[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
54 static const WCHAR numericrepresentation_valuename
[] = {'N','u','m','e','r','i','c','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0};
55 static const WCHAR supportstransparency_valuename
[] = {'S','u','p','p','o','r','t','s','T','r','a','n','s','p','a','r','e','n','c','y',0};
56 static const WCHAR requiresfullstream_valuename
[] = {'R','e','q','u','i','r','e','s','F','u','l','l','S','t','r','e','a','m',0};
57 static const WCHAR supportspadding_valuename
[] = {'S','u','p','p','o','r','t','s','P','a','d','d','i','n','g',0};
58 static const WCHAR fileextensions_valuename
[] = {'F','i','l','e','E','x','t','e','n','s','i','o','n','s',0};
59 static const WCHAR containers_keyname
[] = {'C','o','n','t','a','i','n','e','r','s',0};
62 IWICComponentInfo IWICComponentInfo_iface
;
65 struct wine_rb_entry entry
;
68 static HRESULT
ComponentInfo_GetStringValue(HKEY classkey
, LPCWSTR value
,
69 UINT buffer_size
, WCHAR
*buffer
, UINT
*actual_size
)
72 DWORD cbdata
=buffer_size
* sizeof(WCHAR
);
77 ret
= RegGetValueW(classkey
, NULL
, value
, RRF_RT_REG_SZ
|RRF_NOEXPAND
, NULL
,
80 if (ret
== ERROR_FILE_NOT_FOUND
)
86 if (ret
== 0 || ret
== ERROR_MORE_DATA
)
87 *actual_size
= cbdata
/sizeof(WCHAR
);
89 if (!buffer
&& buffer_size
!= 0)
90 /* Yes, native returns the correct size in this case. */
93 if (ret
== ERROR_MORE_DATA
)
94 return WINCODEC_ERR_INSUFFICIENTBUFFER
;
96 return HRESULT_FROM_WIN32(ret
);
99 static HRESULT
ComponentInfo_GetGUIDValue(HKEY classkey
, LPCWSTR value
,
103 WCHAR guid_string
[39];
104 DWORD cbdata
= sizeof(guid_string
);
110 ret
= RegGetValueW(classkey
, NULL
, value
, RRF_RT_REG_SZ
|RRF_NOEXPAND
, NULL
,
111 guid_string
, &cbdata
);
113 if (ret
!= ERROR_SUCCESS
)
114 return HRESULT_FROM_WIN32(ret
);
116 if (cbdata
< sizeof(guid_string
))
118 ERR("incomplete GUID value\n");
122 hr
= CLSIDFromString(guid_string
, result
);
127 static HRESULT
ComponentInfo_GetDWORDValue(HKEY classkey
, LPCWSTR value
,
131 DWORD cbdata
= sizeof(DWORD
);
136 ret
= RegGetValueW(classkey
, NULL
, value
, RRF_RT_DWORD
, NULL
,
139 if (ret
== ERROR_FILE_NOT_FOUND
)
145 return HRESULT_FROM_WIN32(ret
);
148 static HRESULT
ComponentInfo_GetGuidList(HKEY classkey
, LPCWSTR subkeyname
,
149 UINT buffersize
, GUID
*buffer
, UINT
*actual_size
)
154 WCHAR guid_string
[39];
155 DWORD guid_string_size
;
161 ret
= RegOpenKeyExW(classkey
, subkeyname
, 0, KEY_READ
, &subkey
);
162 if (ret
== ERROR_FILE_NOT_FOUND
)
167 else if (ret
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(ret
);
172 guid_string_size
= 39;
173 while (items_returned
< buffersize
)
175 ret
= RegEnumKeyExW(subkey
, items_returned
, guid_string
,
176 &guid_string_size
, NULL
, NULL
, NULL
, NULL
);
178 if (ret
!= ERROR_SUCCESS
)
180 hr
= HRESULT_FROM_WIN32(ret
);
184 if (guid_string_size
!= 38)
190 hr
= CLSIDFromString(guid_string
, &buffer
[items_returned
]);
195 guid_string_size
= 39;
198 if (ret
== ERROR_NO_MORE_ITEMS
)
201 *actual_size
= items_returned
;
205 ret
= RegQueryInfoKeyW(subkey
, NULL
, NULL
, NULL
, actual_size
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
206 if (ret
!= ERROR_SUCCESS
)
207 hr
= HRESULT_FROM_WIN32(ret
);
218 WICBitmapPattern
*patterns
;
223 static inline BitmapDecoderInfo
*impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo
*iface
)
225 return CONTAINING_RECORD(iface
, BitmapDecoderInfo
, base
.IWICComponentInfo_iface
);
228 static HRESULT WINAPI
BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo
*iface
, REFIID iid
,
231 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
232 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
234 if (!ppv
) return E_INVALIDARG
;
236 if (IsEqualIID(&IID_IUnknown
, iid
) ||
237 IsEqualIID(&IID_IWICComponentInfo
, iid
) ||
238 IsEqualIID(&IID_IWICBitmapCodecInfo
, iid
) ||
239 IsEqualIID(&IID_IWICBitmapDecoderInfo
,iid
))
241 *ppv
= &This
->base
.IWICComponentInfo_iface
;
246 return E_NOINTERFACE
;
249 IUnknown_AddRef((IUnknown
*)*ppv
);
253 static ULONG WINAPI
BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo
*iface
)
255 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
256 ULONG ref
= InterlockedIncrement(&This
->base
.ref
);
258 TRACE("(%p) refcount=%u\n", iface
, ref
);
263 static ULONG WINAPI
BitmapDecoderInfo_Release(IWICBitmapDecoderInfo
*iface
)
265 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
266 ULONG ref
= InterlockedDecrement(&This
->base
.ref
);
268 TRACE("(%p) refcount=%u\n", iface
, ref
);
272 RegCloseKey(This
->classkey
);
273 heap_free(This
->patterns
);
274 HeapFree(GetProcessHeap(), 0, This
);
280 static HRESULT WINAPI
BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo
*iface
,
281 WICComponentType
*pType
)
283 TRACE("(%p,%p)\n", iface
, pType
);
284 if (!pType
) return E_INVALIDARG
;
289 static HRESULT WINAPI
BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo
*iface
, CLSID
*pclsid
)
291 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
292 TRACE("(%p,%p)\n", iface
, pclsid
);
297 *pclsid
= This
->base
.clsid
;
301 static HRESULT WINAPI
BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo
*iface
, DWORD
*pStatus
)
303 FIXME("(%p,%p): stub\n", iface
, pStatus
);
307 static HRESULT WINAPI
BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo
*iface
, UINT cchAuthor
,
308 WCHAR
*wzAuthor
, UINT
*pcchActual
)
310 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
312 TRACE("(%p,%u,%p,%p)\n", iface
, cchAuthor
, wzAuthor
, pcchActual
);
314 return ComponentInfo_GetStringValue(This
->classkey
, author_valuename
,
315 cchAuthor
, wzAuthor
, pcchActual
);
318 static HRESULT WINAPI
BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo
*iface
, GUID
*pguidVendor
)
320 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
322 TRACE("(%p,%p)\n", iface
, pguidVendor
);
324 return ComponentInfo_GetGUIDValue(This
->classkey
, vendor_valuename
, pguidVendor
);
327 static HRESULT WINAPI
BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo
*iface
, UINT cchVersion
,
328 WCHAR
*wzVersion
, UINT
*pcchActual
)
330 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
332 TRACE("(%p,%u,%p,%p)\n", iface
, cchVersion
, wzVersion
, pcchActual
);
334 return ComponentInfo_GetStringValue(This
->classkey
, version_valuename
,
335 cchVersion
, wzVersion
, pcchActual
);
338 static HRESULT WINAPI
BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo
*iface
, UINT cchSpecVersion
,
339 WCHAR
*wzSpecVersion
, UINT
*pcchActual
)
341 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
343 TRACE("(%p,%u,%p,%p)\n", iface
, cchSpecVersion
, wzSpecVersion
, pcchActual
);
345 return ComponentInfo_GetStringValue(This
->classkey
, specversion_valuename
,
346 cchSpecVersion
, wzSpecVersion
, pcchActual
);
349 static HRESULT WINAPI
BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo
*iface
, UINT cchFriendlyName
,
350 WCHAR
*wzFriendlyName
, UINT
*pcchActual
)
352 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
354 TRACE("(%p,%u,%p,%p)\n", iface
, cchFriendlyName
, wzFriendlyName
, pcchActual
);
356 return ComponentInfo_GetStringValue(This
->classkey
, friendlyname_valuename
,
357 cchFriendlyName
, wzFriendlyName
, pcchActual
);
360 static HRESULT WINAPI
BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo
*iface
,
361 GUID
*pguidContainerFormat
)
363 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
364 TRACE("(%p,%p)\n", iface
, pguidContainerFormat
);
365 return ComponentInfo_GetGUIDValue(This
->classkey
, containerformat_valuename
, pguidContainerFormat
);
368 static HRESULT WINAPI
BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo
*iface
,
369 UINT cFormats
, GUID
*pguidPixelFormats
, UINT
*pcActual
)
371 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
372 TRACE("(%p,%u,%p,%p)\n", iface
, cFormats
, pguidPixelFormats
, pcActual
);
373 return ComponentInfo_GetGuidList(This
->classkey
, formats_keyname
, cFormats
, pguidPixelFormats
, pcActual
);
376 static HRESULT WINAPI
BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo
*iface
,
377 UINT cchColorManagementVersion
, WCHAR
*wzColorManagementVersion
, UINT
*pcchActual
)
379 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchColorManagementVersion
, wzColorManagementVersion
, pcchActual
);
383 static HRESULT WINAPI
BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo
*iface
,
384 UINT cchDeviceManufacturer
, WCHAR
*wzDeviceManufacturer
, UINT
*pcchActual
)
386 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchDeviceManufacturer
, wzDeviceManufacturer
, pcchActual
);
390 static HRESULT WINAPI
BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo
*iface
,
391 UINT cchDeviceModels
, WCHAR
*wzDeviceModels
, UINT
*pcchActual
)
393 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchDeviceModels
, wzDeviceModels
, pcchActual
);
397 static HRESULT WINAPI
BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo
*iface
,
398 UINT cchMimeTypes
, WCHAR
*wzMimeTypes
, UINT
*pcchActual
)
400 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
402 TRACE("(%p,%u,%p,%p)\n", iface
, cchMimeTypes
, wzMimeTypes
, pcchActual
);
404 return ComponentInfo_GetStringValue(This
->classkey
, mimetypes_valuename
,
405 cchMimeTypes
, wzMimeTypes
, pcchActual
);
408 static HRESULT WINAPI
BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo
*iface
,
409 UINT cchFileExtensions
, WCHAR
*wzFileExtensions
, UINT
*pcchActual
)
411 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
413 TRACE("(%p,%u,%p,%p)\n", iface
, cchFileExtensions
, wzFileExtensions
, pcchActual
);
415 return ComponentInfo_GetStringValue(This
->classkey
, fileextensions_valuename
,
416 cchFileExtensions
, wzFileExtensions
, pcchActual
);
419 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo
*iface
,
420 BOOL
*pfSupportAnimation
)
422 FIXME("(%p,%p): stub\n", iface
, pfSupportAnimation
);
426 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo
*iface
,
427 BOOL
*pfSupportChromaKey
)
429 FIXME("(%p,%p): stub\n", iface
, pfSupportChromaKey
);
433 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo
*iface
,
434 BOOL
*pfSupportLossless
)
436 FIXME("(%p,%p): stub\n", iface
, pfSupportLossless
);
440 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo
*iface
,
441 BOOL
*pfSupportMultiframe
)
443 FIXME("(%p,%p): stub\n", iface
, pfSupportMultiframe
);
447 static HRESULT WINAPI
BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo
*iface
,
448 LPCWSTR wzMimeType
, BOOL
*pfMatches
)
450 FIXME("(%p,%s,%p): stub\n", iface
, debugstr_w(wzMimeType
), pfMatches
);
454 static HRESULT WINAPI
BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo
*iface
,
455 UINT cbSizePatterns
, WICBitmapPattern
*pPatterns
, UINT
*pcPatterns
, UINT
*pcbPatternsActual
)
457 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
459 TRACE("(%p,%i,%p,%p,%p)\n", iface
, cbSizePatterns
, pPatterns
, pcPatterns
, pcbPatternsActual
);
461 if (!pcPatterns
|| !pcbPatternsActual
) return E_INVALIDARG
;
463 *pcPatterns
= This
->pattern_count
;
464 *pcbPatternsActual
= This
->patterns_size
;
467 if (This
->patterns_size
&& cbSizePatterns
< This
->patterns_size
)
468 return WINCODEC_ERR_INSUFFICIENTBUFFER
;
469 memcpy(pPatterns
, This
->patterns
, This
->patterns_size
);
474 static HRESULT WINAPI
BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo
*iface
,
475 IStream
*pIStream
, BOOL
*pfMatches
)
477 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
484 LARGE_INTEGER seekpos
;
486 TRACE("(%p,%p,%p)\n", iface
, pIStream
, pfMatches
);
488 for (i
=0; i
< This
->pattern_count
; i
++)
490 if (datasize
< This
->patterns
[i
].Length
)
492 HeapFree(GetProcessHeap(), 0, data
);
493 datasize
= This
->patterns
[i
].Length
;
494 data
= HeapAlloc(GetProcessHeap(), 0, This
->patterns
[i
].Length
);
502 if (This
->patterns
[i
].EndOfStream
)
503 seekpos
.QuadPart
= -This
->patterns
[i
].Position
.QuadPart
;
505 seekpos
.QuadPart
= This
->patterns
[i
].Position
.QuadPart
;
506 hr
= IStream_Seek(pIStream
, seekpos
, This
->patterns
[i
].EndOfStream
? STREAM_SEEK_END
: STREAM_SEEK_SET
, NULL
);
507 if (hr
== STG_E_INVALIDFUNCTION
) continue; /* before start of stream */
508 if (FAILED(hr
)) break;
510 hr
= IStream_Read(pIStream
, data
, This
->patterns
[i
].Length
, &bytesread
);
511 if (hr
== S_FALSE
|| (hr
== S_OK
&& bytesread
!= This
->patterns
[i
].Length
)) /* past end of stream */
513 if (FAILED(hr
)) break;
515 for (pos
=0; pos
< This
->patterns
[i
].Length
; pos
++)
517 if ((data
[pos
] & This
->patterns
[i
].Mask
[pos
]) != This
->patterns
[i
].Pattern
[pos
])
520 if (pos
== This
->patterns
[i
].Length
) /* matches pattern */
528 if (i
== This
->pattern_count
) /* does not match any pattern */
534 HeapFree(GetProcessHeap(), 0, data
);
538 static HRESULT WINAPI
BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo
*iface
,
539 IWICBitmapDecoder
**ppIBitmapDecoder
)
541 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
543 TRACE("(%p,%p)\n", iface
, ppIBitmapDecoder
);
545 return create_instance(&This
->base
.clsid
, &IID_IWICBitmapDecoder
, (void**)ppIBitmapDecoder
);
548 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl
= {
549 BitmapDecoderInfo_QueryInterface
,
550 BitmapDecoderInfo_AddRef
,
551 BitmapDecoderInfo_Release
,
552 BitmapDecoderInfo_GetComponentType
,
553 BitmapDecoderInfo_GetCLSID
,
554 BitmapDecoderInfo_GetSigningStatus
,
555 BitmapDecoderInfo_GetAuthor
,
556 BitmapDecoderInfo_GetVendorGUID
,
557 BitmapDecoderInfo_GetVersion
,
558 BitmapDecoderInfo_GetSpecVersion
,
559 BitmapDecoderInfo_GetFriendlyName
,
560 BitmapDecoderInfo_GetContainerFormat
,
561 BitmapDecoderInfo_GetPixelFormats
,
562 BitmapDecoderInfo_GetColorManagementVersion
,
563 BitmapDecoderInfo_GetDeviceManufacturer
,
564 BitmapDecoderInfo_GetDeviceModels
,
565 BitmapDecoderInfo_GetMimeTypes
,
566 BitmapDecoderInfo_GetFileExtensions
,
567 BitmapDecoderInfo_DoesSupportAnimation
,
568 BitmapDecoderInfo_DoesSupportChromaKey
,
569 BitmapDecoderInfo_DoesSupportLossless
,
570 BitmapDecoderInfo_DoesSupportMultiframe
,
571 BitmapDecoderInfo_MatchesMimeType
,
572 BitmapDecoderInfo_GetPatterns
,
573 BitmapDecoderInfo_MatchesPattern
,
574 BitmapDecoderInfo_CreateInstance
577 static void read_bitmap_patterns(BitmapDecoderInfo
*info
)
579 UINT pattern_count
=0, patterns_size
=0;
580 WCHAR subkeyname
[11];
582 HKEY patternskey
, patternkey
;
583 static const WCHAR uintformatW
[] = {'%','u',0};
584 static const WCHAR patternsW
[] = {'P','a','t','t','e','r','n','s',0};
585 static const WCHAR positionW
[] = {'P','o','s','i','t','i','o','n',0};
586 static const WCHAR lengthW
[] = {'L','e','n','g','t','h',0};
587 static const WCHAR patternW
[] = {'P','a','t','t','e','r','n',0};
588 static const WCHAR maskW
[] = {'M','a','s','k',0};
589 static const WCHAR endofstreamW
[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
591 WICBitmapPattern
*patterns
;
593 DWORD length
, valuesize
;
595 res
= RegOpenKeyExW(info
->classkey
, patternsW
, 0, KEY_READ
, &patternskey
);
596 if (res
!= ERROR_SUCCESS
) return;
598 res
= RegQueryInfoKeyW(patternskey
, NULL
, NULL
, NULL
, &pattern_count
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
599 if (res
!= ERROR_SUCCESS
)
601 RegCloseKey(patternskey
);
605 patterns_size
= pattern_count
* sizeof(WICBitmapPattern
);
606 patterns
= heap_alloc(patterns_size
);
609 RegCloseKey(patternskey
);
613 for (i
=0; res
== ERROR_SUCCESS
&& i
< pattern_count
; i
++)
615 snprintfW(subkeyname
, 11, uintformatW
, i
);
616 res
= RegOpenKeyExW(patternskey
, subkeyname
, 0, KEY_READ
, &patternkey
);
617 if (res
!= ERROR_SUCCESS
) break;
619 valuesize
= sizeof(ULONG
);
620 res
= RegGetValueW(patternkey
, NULL
, lengthW
, RRF_RT_DWORD
, NULL
, &length
, &valuesize
);
621 if (res
== ERROR_SUCCESS
)
623 patterns_size
+= length
*2;
624 patterns
[i
].Length
= length
;
626 valuesize
= sizeof(BOOL
);
627 res
= RegGetValueW(patternkey
, NULL
, endofstreamW
, RRF_RT_DWORD
, NULL
,
628 &patterns
[i
].EndOfStream
, &valuesize
);
629 if (res
) patterns
[i
].EndOfStream
= 0;
631 patterns
[i
].Position
.QuadPart
= 0;
632 valuesize
= sizeof(ULARGE_INTEGER
);
633 res
= RegGetValueW(patternkey
, NULL
, positionW
, RRF_RT_DWORD
|RRF_RT_QWORD
, NULL
,
634 &patterns
[i
].Position
, &valuesize
);
637 RegCloseKey(patternkey
);
640 if (res
!= ERROR_SUCCESS
|| !(patterns_ptr
= heap_realloc(patterns
, patterns_size
)))
643 RegCloseKey(patternskey
);
646 patterns
= (WICBitmapPattern
*)patterns_ptr
;
647 patterns_ptr
+= pattern_count
* sizeof(*patterns
);
649 for (i
=0; res
== ERROR_SUCCESS
&& i
< pattern_count
; i
++)
651 snprintfW(subkeyname
, 11, uintformatW
, i
);
652 res
= RegOpenKeyExW(patternskey
, subkeyname
, 0, KEY_READ
, &patternkey
);
653 if (res
!= ERROR_SUCCESS
) break;
655 length
= patterns
[i
].Length
;
656 patterns
[i
].Pattern
= patterns_ptr
;
658 res
= RegGetValueW(patternkey
, NULL
, patternW
, RRF_RT_REG_BINARY
, NULL
,
659 patterns
[i
].Pattern
, &valuesize
);
660 patterns_ptr
+= length
;
662 if (res
== ERROR_SUCCESS
)
664 patterns
[i
].Mask
= patterns_ptr
;
666 res
= RegGetValueW(patternkey
, NULL
, maskW
, RRF_RT_REG_BINARY
, NULL
,
667 patterns
[i
].Mask
, &valuesize
);
668 patterns_ptr
+= length
;
671 RegCloseKey(patternkey
);
674 RegCloseKey(patternskey
);
676 if (res
!= ERROR_SUCCESS
)
682 info
->pattern_count
= pattern_count
;
683 info
->patterns_size
= patterns_size
;
684 info
->patterns
= patterns
;
687 static HRESULT
BitmapDecoderInfo_Constructor(HKEY classkey
, REFCLSID clsid
, ComponentInfo
**ret
)
689 BitmapDecoderInfo
*This
;
691 This
= heap_alloc_zero(sizeof(BitmapDecoderInfo
));
694 RegCloseKey(classkey
);
695 return E_OUTOFMEMORY
;
698 This
->base
.IWICComponentInfo_iface
.lpVtbl
= (const IWICComponentInfoVtbl
*)&BitmapDecoderInfo_Vtbl
;
700 This
->classkey
= classkey
;
701 This
->base
.clsid
= *clsid
;
703 read_bitmap_patterns(This
);
714 static inline BitmapEncoderInfo
*impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo
*iface
)
716 return CONTAINING_RECORD(iface
, BitmapEncoderInfo
, base
.IWICComponentInfo_iface
);
719 static HRESULT WINAPI
BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo
*iface
, REFIID iid
,
722 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
723 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
725 if (!ppv
) return E_INVALIDARG
;
727 if (IsEqualIID(&IID_IUnknown
, iid
) ||
728 IsEqualIID(&IID_IWICComponentInfo
, iid
) ||
729 IsEqualIID(&IID_IWICBitmapCodecInfo
, iid
) ||
730 IsEqualIID(&IID_IWICBitmapEncoderInfo
,iid
))
732 *ppv
= &This
->base
.IWICComponentInfo_iface
;
737 return E_NOINTERFACE
;
740 IUnknown_AddRef((IUnknown
*)*ppv
);
744 static ULONG WINAPI
BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo
*iface
)
746 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
747 ULONG ref
= InterlockedIncrement(&This
->base
.ref
);
749 TRACE("(%p) refcount=%u\n", iface
, ref
);
754 static ULONG WINAPI
BitmapEncoderInfo_Release(IWICBitmapEncoderInfo
*iface
)
756 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
757 ULONG ref
= InterlockedDecrement(&This
->base
.ref
);
759 TRACE("(%p) refcount=%u\n", iface
, ref
);
763 RegCloseKey(This
->classkey
);
764 HeapFree(GetProcessHeap(), 0, This
);
770 static HRESULT WINAPI
BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo
*iface
,
771 WICComponentType
*pType
)
773 TRACE("(%p,%p)\n", iface
, pType
);
774 if (!pType
) return E_INVALIDARG
;
779 static HRESULT WINAPI
BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo
*iface
, CLSID
*pclsid
)
781 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
782 TRACE("(%p,%p)\n", iface
, pclsid
);
787 *pclsid
= This
->base
.clsid
;
791 static HRESULT WINAPI
BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo
*iface
, DWORD
*pStatus
)
793 FIXME("(%p,%p): stub\n", iface
, pStatus
);
797 static HRESULT WINAPI
BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo
*iface
, UINT cchAuthor
,
798 WCHAR
*wzAuthor
, UINT
*pcchActual
)
800 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
802 TRACE("(%p,%u,%p,%p)\n", iface
, cchAuthor
, wzAuthor
, pcchActual
);
804 return ComponentInfo_GetStringValue(This
->classkey
, author_valuename
,
805 cchAuthor
, wzAuthor
, pcchActual
);
808 static HRESULT WINAPI
BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo
*iface
, GUID
*pguidVendor
)
810 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
812 TRACE("(%p,%p)\n", iface
, pguidVendor
);
814 return ComponentInfo_GetGUIDValue(This
->classkey
, vendor_valuename
, pguidVendor
);
817 static HRESULT WINAPI
BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo
*iface
, UINT cchVersion
,
818 WCHAR
*wzVersion
, UINT
*pcchActual
)
820 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
822 TRACE("(%p,%u,%p,%p)\n", iface
, cchVersion
, wzVersion
, pcchActual
);
824 return ComponentInfo_GetStringValue(This
->classkey
, version_valuename
,
825 cchVersion
, wzVersion
, pcchActual
);
828 static HRESULT WINAPI
BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo
*iface
, UINT cchSpecVersion
,
829 WCHAR
*wzSpecVersion
, UINT
*pcchActual
)
831 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
833 TRACE("(%p,%u,%p,%p)\n", iface
, cchSpecVersion
, wzSpecVersion
, pcchActual
);
835 return ComponentInfo_GetStringValue(This
->classkey
, specversion_valuename
,
836 cchSpecVersion
, wzSpecVersion
, pcchActual
);
839 static HRESULT WINAPI
BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo
*iface
, UINT cchFriendlyName
,
840 WCHAR
*wzFriendlyName
, UINT
*pcchActual
)
842 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
844 TRACE("(%p,%u,%p,%p)\n", iface
, cchFriendlyName
, wzFriendlyName
, pcchActual
);
846 return ComponentInfo_GetStringValue(This
->classkey
, friendlyname_valuename
,
847 cchFriendlyName
, wzFriendlyName
, pcchActual
);
850 static HRESULT WINAPI
BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo
*iface
,
851 GUID
*pguidContainerFormat
)
853 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
854 TRACE("(%p,%p)\n", iface
, pguidContainerFormat
);
855 return ComponentInfo_GetGUIDValue(This
->classkey
, containerformat_valuename
, pguidContainerFormat
);
858 static HRESULT WINAPI
BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo
*iface
,
859 UINT cFormats
, GUID
*pguidPixelFormats
, UINT
*pcActual
)
861 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
862 TRACE("(%p,%u,%p,%p)\n", iface
, cFormats
, pguidPixelFormats
, pcActual
);
863 return ComponentInfo_GetGuidList(This
->classkey
, formats_keyname
, cFormats
, pguidPixelFormats
, pcActual
);
866 static HRESULT WINAPI
BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo
*iface
,
867 UINT cchColorManagementVersion
, WCHAR
*wzColorManagementVersion
, UINT
*pcchActual
)
869 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchColorManagementVersion
, wzColorManagementVersion
, pcchActual
);
873 static HRESULT WINAPI
BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo
*iface
,
874 UINT cchDeviceManufacturer
, WCHAR
*wzDeviceManufacturer
, UINT
*pcchActual
)
876 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchDeviceManufacturer
, wzDeviceManufacturer
, pcchActual
);
880 static HRESULT WINAPI
BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo
*iface
,
881 UINT cchDeviceModels
, WCHAR
*wzDeviceModels
, UINT
*pcchActual
)
883 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchDeviceModels
, wzDeviceModels
, pcchActual
);
887 static HRESULT WINAPI
BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo
*iface
,
888 UINT cchMimeTypes
, WCHAR
*wzMimeTypes
, UINT
*pcchActual
)
890 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
892 TRACE("(%p,%u,%p,%p)\n", iface
, cchMimeTypes
, wzMimeTypes
, pcchActual
);
894 return ComponentInfo_GetStringValue(This
->classkey
, mimetypes_valuename
,
895 cchMimeTypes
, wzMimeTypes
, pcchActual
);
898 static HRESULT WINAPI
BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo
*iface
,
899 UINT cchFileExtensions
, WCHAR
*wzFileExtensions
, UINT
*pcchActual
)
901 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
903 TRACE("(%p,%u,%p,%p)\n", iface
, cchFileExtensions
, wzFileExtensions
, pcchActual
);
905 return ComponentInfo_GetStringValue(This
->classkey
, fileextensions_valuename
,
906 cchFileExtensions
, wzFileExtensions
, pcchActual
);
909 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo
*iface
,
910 BOOL
*pfSupportAnimation
)
912 FIXME("(%p,%p): stub\n", iface
, pfSupportAnimation
);
916 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo
*iface
,
917 BOOL
*pfSupportChromaKey
)
919 FIXME("(%p,%p): stub\n", iface
, pfSupportChromaKey
);
923 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo
*iface
,
924 BOOL
*pfSupportLossless
)
926 FIXME("(%p,%p): stub\n", iface
, pfSupportLossless
);
930 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo
*iface
,
931 BOOL
*pfSupportMultiframe
)
933 FIXME("(%p,%p): stub\n", iface
, pfSupportMultiframe
);
937 static HRESULT WINAPI
BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo
*iface
,
938 LPCWSTR wzMimeType
, BOOL
*pfMatches
)
940 FIXME("(%p,%s,%p): stub\n", iface
, debugstr_w(wzMimeType
), pfMatches
);
944 static HRESULT WINAPI
BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo
*iface
,
945 IWICBitmapEncoder
**ppIBitmapEncoder
)
947 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
949 TRACE("(%p,%p)\n", iface
, ppIBitmapEncoder
);
951 return create_instance(&This
->base
.clsid
, &IID_IWICBitmapEncoder
, (void**)ppIBitmapEncoder
);
954 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl
= {
955 BitmapEncoderInfo_QueryInterface
,
956 BitmapEncoderInfo_AddRef
,
957 BitmapEncoderInfo_Release
,
958 BitmapEncoderInfo_GetComponentType
,
959 BitmapEncoderInfo_GetCLSID
,
960 BitmapEncoderInfo_GetSigningStatus
,
961 BitmapEncoderInfo_GetAuthor
,
962 BitmapEncoderInfo_GetVendorGUID
,
963 BitmapEncoderInfo_GetVersion
,
964 BitmapEncoderInfo_GetSpecVersion
,
965 BitmapEncoderInfo_GetFriendlyName
,
966 BitmapEncoderInfo_GetContainerFormat
,
967 BitmapEncoderInfo_GetPixelFormats
,
968 BitmapEncoderInfo_GetColorManagementVersion
,
969 BitmapEncoderInfo_GetDeviceManufacturer
,
970 BitmapEncoderInfo_GetDeviceModels
,
971 BitmapEncoderInfo_GetMimeTypes
,
972 BitmapEncoderInfo_GetFileExtensions
,
973 BitmapEncoderInfo_DoesSupportAnimation
,
974 BitmapEncoderInfo_DoesSupportChromaKey
,
975 BitmapEncoderInfo_DoesSupportLossless
,
976 BitmapEncoderInfo_DoesSupportMultiframe
,
977 BitmapEncoderInfo_MatchesMimeType
,
978 BitmapEncoderInfo_CreateInstance
981 static HRESULT
BitmapEncoderInfo_Constructor(HKEY classkey
, REFCLSID clsid
, ComponentInfo
**ret
)
983 BitmapEncoderInfo
*This
;
985 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo
));
988 RegCloseKey(classkey
);
989 return E_OUTOFMEMORY
;
992 This
->base
.IWICComponentInfo_iface
.lpVtbl
= (const IWICComponentInfoVtbl
*)&BitmapEncoderInfo_Vtbl
;
994 This
->classkey
= classkey
;
995 This
->base
.clsid
= *clsid
;
1004 } FormatConverterInfo
;
1006 static inline FormatConverterInfo
*impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo
*iface
)
1008 return CONTAINING_RECORD(iface
, FormatConverterInfo
, base
.IWICComponentInfo_iface
);
1011 static HRESULT WINAPI
FormatConverterInfo_QueryInterface(IWICFormatConverterInfo
*iface
, REFIID iid
,
1014 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1015 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
1017 if (!ppv
) return E_INVALIDARG
;
1019 if (IsEqualIID(&IID_IUnknown
, iid
) ||
1020 IsEqualIID(&IID_IWICComponentInfo
, iid
) ||
1021 IsEqualIID(&IID_IWICFormatConverterInfo
,iid
))
1023 *ppv
= &This
->base
.IWICComponentInfo_iface
;
1028 return E_NOINTERFACE
;
1031 IUnknown_AddRef((IUnknown
*)*ppv
);
1035 static ULONG WINAPI
FormatConverterInfo_AddRef(IWICFormatConverterInfo
*iface
)
1037 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1038 ULONG ref
= InterlockedIncrement(&This
->base
.ref
);
1040 TRACE("(%p) refcount=%u\n", iface
, ref
);
1045 static ULONG WINAPI
FormatConverterInfo_Release(IWICFormatConverterInfo
*iface
)
1047 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1048 ULONG ref
= InterlockedDecrement(&This
->base
.ref
);
1050 TRACE("(%p) refcount=%u\n", iface
, ref
);
1054 RegCloseKey(This
->classkey
);
1055 HeapFree(GetProcessHeap(), 0, This
);
1061 static HRESULT WINAPI
FormatConverterInfo_GetComponentType(IWICFormatConverterInfo
*iface
,
1062 WICComponentType
*pType
)
1064 TRACE("(%p,%p)\n", iface
, pType
);
1065 if (!pType
) return E_INVALIDARG
;
1066 *pType
= WICPixelFormatConverter
;
1070 static HRESULT WINAPI
FormatConverterInfo_GetCLSID(IWICFormatConverterInfo
*iface
, CLSID
*pclsid
)
1072 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1073 TRACE("(%p,%p)\n", iface
, pclsid
);
1076 return E_INVALIDARG
;
1078 *pclsid
= This
->base
.clsid
;
1082 static HRESULT WINAPI
FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo
*iface
, DWORD
*pStatus
)
1084 FIXME("(%p,%p): stub\n", iface
, pStatus
);
1088 static HRESULT WINAPI
FormatConverterInfo_GetAuthor(IWICFormatConverterInfo
*iface
, UINT cchAuthor
,
1089 WCHAR
*wzAuthor
, UINT
*pcchActual
)
1091 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1093 TRACE("(%p,%u,%p,%p)\n", iface
, cchAuthor
, wzAuthor
, pcchActual
);
1095 return ComponentInfo_GetStringValue(This
->classkey
, author_valuename
,
1096 cchAuthor
, wzAuthor
, pcchActual
);
1099 static HRESULT WINAPI
FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo
*iface
, GUID
*pguidVendor
)
1101 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1103 TRACE("(%p,%p)\n", iface
, pguidVendor
);
1105 return ComponentInfo_GetGUIDValue(This
->classkey
, vendor_valuename
, pguidVendor
);
1108 static HRESULT WINAPI
FormatConverterInfo_GetVersion(IWICFormatConverterInfo
*iface
, UINT cchVersion
,
1109 WCHAR
*wzVersion
, UINT
*pcchActual
)
1111 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1113 TRACE("(%p,%u,%p,%p)\n", iface
, cchVersion
, wzVersion
, pcchActual
);
1115 return ComponentInfo_GetStringValue(This
->classkey
, version_valuename
,
1116 cchVersion
, wzVersion
, pcchActual
);
1119 static HRESULT WINAPI
FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo
*iface
, UINT cchSpecVersion
,
1120 WCHAR
*wzSpecVersion
, UINT
*pcchActual
)
1122 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1124 TRACE("(%p,%u,%p,%p)\n", iface
, cchSpecVersion
, wzSpecVersion
, pcchActual
);
1126 return ComponentInfo_GetStringValue(This
->classkey
, specversion_valuename
,
1127 cchSpecVersion
, wzSpecVersion
, pcchActual
);
1130 static HRESULT WINAPI
FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo
*iface
, UINT cchFriendlyName
,
1131 WCHAR
*wzFriendlyName
, UINT
*pcchActual
)
1133 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1135 TRACE("(%p,%u,%p,%p)\n", iface
, cchFriendlyName
, wzFriendlyName
, pcchActual
);
1137 return ComponentInfo_GetStringValue(This
->classkey
, friendlyname_valuename
,
1138 cchFriendlyName
, wzFriendlyName
, pcchActual
);
1141 static HRESULT WINAPI
FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo
*iface
,
1142 UINT cFormats
, GUID
*pguidPixelFormats
, UINT
*pcActual
)
1144 FIXME("(%p,%u,%p,%p): stub\n", iface
, cFormats
, pguidPixelFormats
, pcActual
);
1148 static HRESULT WINAPI
FormatConverterInfo_CreateInstance(IWICFormatConverterInfo
*iface
,
1149 IWICFormatConverter
**ppIFormatConverter
)
1151 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1153 TRACE("(%p,%p)\n", iface
, ppIFormatConverter
);
1155 return create_instance(&This
->base
.clsid
, &IID_IWICFormatConverter
,
1156 (void**)ppIFormatConverter
);
1159 static BOOL
ConverterSupportsFormat(IWICFormatConverterInfo
*iface
, const WCHAR
*formatguid
)
1162 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1163 HKEY formats_key
, guid_key
;
1165 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
1166 would be O(n). A registry test should do better. */
1168 res
= RegOpenKeyExW(This
->classkey
, pixelformats_keyname
, 0, KEY_READ
, &formats_key
);
1169 if (res
!= ERROR_SUCCESS
) return FALSE
;
1171 res
= RegOpenKeyExW(formats_key
, formatguid
, 0, KEY_READ
, &guid_key
);
1172 if (res
== ERROR_SUCCESS
) RegCloseKey(guid_key
);
1174 RegCloseKey(formats_key
);
1176 return (res
== ERROR_SUCCESS
);
1179 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl
= {
1180 FormatConverterInfo_QueryInterface
,
1181 FormatConverterInfo_AddRef
,
1182 FormatConverterInfo_Release
,
1183 FormatConverterInfo_GetComponentType
,
1184 FormatConverterInfo_GetCLSID
,
1185 FormatConverterInfo_GetSigningStatus
,
1186 FormatConverterInfo_GetAuthor
,
1187 FormatConverterInfo_GetVendorGUID
,
1188 FormatConverterInfo_GetVersion
,
1189 FormatConverterInfo_GetSpecVersion
,
1190 FormatConverterInfo_GetFriendlyName
,
1191 FormatConverterInfo_GetPixelFormats
,
1192 FormatConverterInfo_CreateInstance
1195 static HRESULT
FormatConverterInfo_Constructor(HKEY classkey
, REFCLSID clsid
, ComponentInfo
**ret
)
1197 FormatConverterInfo
*This
;
1199 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo
));
1202 RegCloseKey(classkey
);
1203 return E_OUTOFMEMORY
;
1206 This
->base
.IWICComponentInfo_iface
.lpVtbl
= (const IWICComponentInfoVtbl
*)&FormatConverterInfo_Vtbl
;
1208 This
->classkey
= classkey
;
1209 This
->base
.clsid
= *clsid
;
1220 static inline PixelFormatInfo
*impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2
*iface
)
1222 return CONTAINING_RECORD(iface
, PixelFormatInfo
, base
.IWICComponentInfo_iface
);
1225 static HRESULT WINAPI
PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2
*iface
, REFIID iid
,
1228 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1229 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
1231 if (!ppv
) return E_INVALIDARG
;
1233 if (IsEqualIID(&IID_IUnknown
, iid
) ||
1234 IsEqualIID(&IID_IWICComponentInfo
, iid
) ||
1235 IsEqualIID(&IID_IWICPixelFormatInfo
, iid
) ||
1236 IsEqualIID(&IID_IWICPixelFormatInfo2
,iid
))
1238 *ppv
= &This
->base
.IWICComponentInfo_iface
;
1243 return E_NOINTERFACE
;
1246 IUnknown_AddRef((IUnknown
*)*ppv
);
1250 static ULONG WINAPI
PixelFormatInfo_AddRef(IWICPixelFormatInfo2
*iface
)
1252 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1253 ULONG ref
= InterlockedIncrement(&This
->base
.ref
);
1255 TRACE("(%p) refcount=%u\n", iface
, ref
);
1260 static ULONG WINAPI
PixelFormatInfo_Release(IWICPixelFormatInfo2
*iface
)
1262 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1263 ULONG ref
= InterlockedDecrement(&This
->base
.ref
);
1265 TRACE("(%p) refcount=%u\n", iface
, ref
);
1269 RegCloseKey(This
->classkey
);
1270 HeapFree(GetProcessHeap(), 0, This
);
1276 static HRESULT WINAPI
PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2
*iface
,
1277 WICComponentType
*pType
)
1279 TRACE("(%p,%p)\n", iface
, pType
);
1280 if (!pType
) return E_INVALIDARG
;
1281 *pType
= WICPixelFormat
;
1285 static HRESULT WINAPI
PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2
*iface
, CLSID
*pclsid
)
1287 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1288 TRACE("(%p,%p)\n", iface
, pclsid
);
1291 return E_INVALIDARG
;
1293 *pclsid
= This
->base
.clsid
;
1297 static HRESULT WINAPI
PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2
*iface
, DWORD
*pStatus
)
1299 TRACE("(%p,%p)\n", iface
, pStatus
);
1302 return E_INVALIDARG
;
1304 /* Pixel formats don't require code, so they are considered signed. */
1305 *pStatus
= WICComponentSigned
;
1310 static HRESULT WINAPI
PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2
*iface
, UINT cchAuthor
,
1311 WCHAR
*wzAuthor
, UINT
*pcchActual
)
1313 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1315 TRACE("(%p,%u,%p,%p)\n", iface
, cchAuthor
, wzAuthor
, pcchActual
);
1317 return ComponentInfo_GetStringValue(This
->classkey
, author_valuename
,
1318 cchAuthor
, wzAuthor
, pcchActual
);
1321 static HRESULT WINAPI
PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2
*iface
, GUID
*pguidVendor
)
1323 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1325 TRACE("(%p,%p)\n", iface
, pguidVendor
);
1327 return ComponentInfo_GetGUIDValue(This
->classkey
, vendor_valuename
, pguidVendor
);
1330 static HRESULT WINAPI
PixelFormatInfo_GetVersion(IWICPixelFormatInfo2
*iface
, UINT cchVersion
,
1331 WCHAR
*wzVersion
, UINT
*pcchActual
)
1333 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1335 TRACE("(%p,%u,%p,%p)\n", iface
, cchVersion
, wzVersion
, pcchActual
);
1337 return ComponentInfo_GetStringValue(This
->classkey
, version_valuename
,
1338 cchVersion
, wzVersion
, pcchActual
);
1341 static HRESULT WINAPI
PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2
*iface
, UINT cchSpecVersion
,
1342 WCHAR
*wzSpecVersion
, UINT
*pcchActual
)
1344 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1346 TRACE("(%p,%u,%p,%p)\n", iface
, cchSpecVersion
, wzSpecVersion
, pcchActual
);
1348 return ComponentInfo_GetStringValue(This
->classkey
, specversion_valuename
,
1349 cchSpecVersion
, wzSpecVersion
, pcchActual
);
1352 static HRESULT WINAPI
PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2
*iface
, UINT cchFriendlyName
,
1353 WCHAR
*wzFriendlyName
, UINT
*pcchActual
)
1355 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1357 TRACE("(%p,%u,%p,%p)\n", iface
, cchFriendlyName
, wzFriendlyName
, pcchActual
);
1359 return ComponentInfo_GetStringValue(This
->classkey
, friendlyname_valuename
,
1360 cchFriendlyName
, wzFriendlyName
, pcchActual
);
1363 static HRESULT WINAPI
PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2
*iface
,
1366 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1367 TRACE("(%p,%p)\n", iface
, pFormat
);
1370 return E_INVALIDARG
;
1372 *pFormat
= This
->base
.clsid
;
1376 static HRESULT WINAPI
PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2
*iface
,
1377 IWICColorContext
**ppIColorContext
)
1379 FIXME("(%p,%p): stub\n", iface
, ppIColorContext
);
1383 static HRESULT WINAPI
PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2
*iface
,
1384 UINT
*puiBitsPerPixel
)
1386 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1388 TRACE("(%p,%p)\n", iface
, puiBitsPerPixel
);
1390 return ComponentInfo_GetDWORDValue(This
->classkey
, bitsperpixel_valuename
, puiBitsPerPixel
);
1393 static HRESULT WINAPI
PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2
*iface
,
1394 UINT
*puiChannelCount
)
1396 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1398 TRACE("(%p,%p)\n", iface
, puiChannelCount
);
1400 return ComponentInfo_GetDWORDValue(This
->classkey
, channelcount_valuename
, puiChannelCount
);
1403 static HRESULT WINAPI
PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2
*iface
,
1404 UINT uiChannelIndex
, UINT cbMaskBuffer
, BYTE
*pbMaskBuffer
, UINT
*pcbActual
)
1406 static const WCHAR uintformatW
[] = {'%','u',0};
1407 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1411 WCHAR valuename
[11];
1414 TRACE("(%p,%u,%u,%p,%p)\n", iface
, uiChannelIndex
, cbMaskBuffer
, pbMaskBuffer
, pcbActual
);
1417 return E_INVALIDARG
;
1419 hr
= PixelFormatInfo_GetChannelCount(iface
, &channel_count
);
1421 if (SUCCEEDED(hr
) && uiChannelIndex
>= channel_count
)
1426 snprintfW(valuename
, 11, uintformatW
, uiChannelIndex
);
1428 cbData
= cbMaskBuffer
;
1430 ret
= RegGetValueW(This
->classkey
, channelmasks_keyname
, valuename
, RRF_RT_REG_BINARY
, NULL
, pbMaskBuffer
, &cbData
);
1432 if (ret
== ERROR_SUCCESS
|| ret
== ERROR_MORE_DATA
)
1433 *pcbActual
= cbData
;
1435 if (ret
== ERROR_MORE_DATA
)
1438 hr
= HRESULT_FROM_WIN32(ret
);
1444 static HRESULT WINAPI
PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2
*iface
,
1445 BOOL
*pfSupportsTransparency
)
1447 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1449 TRACE("(%p,%p)\n", iface
, pfSupportsTransparency
);
1451 return ComponentInfo_GetDWORDValue(This
->classkey
, supportstransparency_valuename
, (DWORD
*)pfSupportsTransparency
);
1454 static HRESULT WINAPI
PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2
*iface
,
1455 WICPixelFormatNumericRepresentation
*pNumericRepresentation
)
1457 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1459 TRACE("(%p,%p)\n", iface
, pNumericRepresentation
);
1461 return ComponentInfo_GetDWORDValue(This
->classkey
, numericrepresentation_valuename
, pNumericRepresentation
);
1464 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl
= {
1465 PixelFormatInfo_QueryInterface
,
1466 PixelFormatInfo_AddRef
,
1467 PixelFormatInfo_Release
,
1468 PixelFormatInfo_GetComponentType
,
1469 PixelFormatInfo_GetCLSID
,
1470 PixelFormatInfo_GetSigningStatus
,
1471 PixelFormatInfo_GetAuthor
,
1472 PixelFormatInfo_GetVendorGUID
,
1473 PixelFormatInfo_GetVersion
,
1474 PixelFormatInfo_GetSpecVersion
,
1475 PixelFormatInfo_GetFriendlyName
,
1476 PixelFormatInfo_GetFormatGUID
,
1477 PixelFormatInfo_GetColorContext
,
1478 PixelFormatInfo_GetBitsPerPixel
,
1479 PixelFormatInfo_GetChannelCount
,
1480 PixelFormatInfo_GetChannelMask
,
1481 PixelFormatInfo_SupportsTransparency
,
1482 PixelFormatInfo_GetNumericRepresentation
1485 static HRESULT
PixelFormatInfo_Constructor(HKEY classkey
, REFCLSID clsid
, ComponentInfo
**ret
)
1487 PixelFormatInfo
*This
;
1489 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo
));
1492 RegCloseKey(classkey
);
1493 return E_OUTOFMEMORY
;
1496 This
->base
.IWICComponentInfo_iface
.lpVtbl
= (const IWICComponentInfoVtbl
*)&PixelFormatInfo_Vtbl
;
1498 This
->classkey
= classkey
;
1499 This
->base
.clsid
= *clsid
;
1505 struct metadata_container
1507 WICMetadataPattern
*patterns
;
1516 GUID
*container_formats
;
1517 struct metadata_container
*containers
;
1518 UINT container_count
;
1519 } MetadataReaderInfo
;
1521 static struct metadata_container
*get_metadata_container(MetadataReaderInfo
*info
, const GUID
*guid
)
1525 for (i
= 0; i
< info
->container_count
; i
++)
1526 if (IsEqualGUID(info
->container_formats
+ i
, guid
))
1527 return info
->containers
+ i
;
1532 static inline MetadataReaderInfo
*impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo
*iface
)
1534 return CONTAINING_RECORD(iface
, MetadataReaderInfo
, base
.IWICComponentInfo_iface
);
1537 static HRESULT WINAPI
MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo
*iface
,
1538 REFIID riid
, void **ppv
)
1540 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1542 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppv
);
1544 if (!ppv
) return E_INVALIDARG
;
1546 if (IsEqualIID(&IID_IUnknown
, riid
) ||
1547 IsEqualIID(&IID_IWICComponentInfo
, riid
) ||
1548 IsEqualIID(&IID_IWICMetadataHandlerInfo
, riid
) ||
1549 IsEqualIID(&IID_IWICMetadataReaderInfo
, riid
))
1551 *ppv
= &This
->base
.IWICComponentInfo_iface
;
1556 return E_NOINTERFACE
;
1559 IUnknown_AddRef((IUnknown
*)*ppv
);
1563 static ULONG WINAPI
MetadataReaderInfo_AddRef(IWICMetadataReaderInfo
*iface
)
1565 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1566 ULONG ref
= InterlockedIncrement(&This
->base
.ref
);
1568 TRACE("(%p) refcount=%u\n", iface
, ref
);
1572 static ULONG WINAPI
MetadataReaderInfo_Release(IWICMetadataReaderInfo
*iface
)
1574 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1575 ULONG ref
= InterlockedDecrement(&This
->base
.ref
);
1577 TRACE("(%p) refcount=%u\n", iface
, ref
);
1582 RegCloseKey(This
->classkey
);
1583 for (i
= 0; i
< This
->container_count
; i
++)
1584 heap_free(This
->containers
[i
].patterns
);
1585 heap_free(This
->containers
);
1586 heap_free(This
->container_formats
);
1587 HeapFree(GetProcessHeap(), 0, This
);
1592 static HRESULT WINAPI
MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo
*iface
,
1593 WICComponentType
*type
)
1595 TRACE("(%p,%p)\n", iface
, type
);
1597 if (!type
) return E_INVALIDARG
;
1598 *type
= WICMetadataReader
;
1602 static HRESULT WINAPI
MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo
*iface
,
1605 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1607 TRACE("(%p,%p)\n", iface
, clsid
);
1609 if (!clsid
) return E_INVALIDARG
;
1610 *clsid
= This
->base
.clsid
;
1614 static HRESULT WINAPI
MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo
*iface
,
1617 FIXME("(%p,%p): stub\n", iface
, status
);
1621 static HRESULT WINAPI
MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo
*iface
,
1622 UINT length
, WCHAR
*author
, UINT
*actual_length
)
1624 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1626 TRACE("(%p,%u,%p,%p)\n", iface
, length
, author
, actual_length
);
1628 return ComponentInfo_GetStringValue(This
->classkey
, author_valuename
,
1629 length
, author
, actual_length
);
1632 static HRESULT WINAPI
MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo
*iface
,
1635 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1637 TRACE("(%p,%p)\n", iface
, vendor
);
1639 return ComponentInfo_GetGUIDValue(This
->classkey
, vendor_valuename
, vendor
);
1642 static HRESULT WINAPI
MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo
*iface
,
1643 UINT length
, WCHAR
*version
, UINT
*actual_length
)
1645 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1647 TRACE("(%p,%u,%p,%p)\n", iface
, length
, version
, actual_length
);
1649 return ComponentInfo_GetStringValue(This
->classkey
, version_valuename
,
1650 length
, version
, actual_length
);
1653 static HRESULT WINAPI
MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo
*iface
,
1654 UINT length
, WCHAR
*version
, UINT
*actual_length
)
1656 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1658 TRACE("(%p,%u,%p,%p)\n", iface
, length
, version
, actual_length
);
1660 return ComponentInfo_GetStringValue(This
->classkey
, specversion_valuename
,
1661 length
, version
, actual_length
);
1664 static HRESULT WINAPI
MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo
*iface
,
1665 UINT length
, WCHAR
*name
, UINT
*actual_length
)
1667 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1669 TRACE("(%p,%u,%p,%p)\n", iface
, length
, name
, actual_length
);
1671 return ComponentInfo_GetStringValue(This
->classkey
, friendlyname_valuename
,
1672 length
, name
, actual_length
);
1675 static HRESULT WINAPI
MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo
*iface
,
1678 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1679 TRACE("(%p,%p)\n", iface
, format
);
1680 return ComponentInfo_GetGUIDValue(This
->classkey
, metadataformat_valuename
, format
);
1683 static HRESULT WINAPI
MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo
*iface
,
1684 UINT length
, GUID
*formats
, UINT
*actual_length
)
1686 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1688 TRACE("(%p,%u,%p,%p)\n", iface
, length
, formats
, actual_length
);
1691 return E_INVALIDARG
;
1693 *actual_length
= This
->container_count
;
1696 if (This
->container_count
&& length
< This
->container_count
)
1697 return WINCODEC_ERR_INSUFFICIENTBUFFER
;
1698 memcpy(formats
, This
->container_formats
, This
->container_count
);
1703 static HRESULT WINAPI
MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo
*iface
,
1704 UINT length
, WCHAR
*manufacturer
, UINT
*actual_length
)
1706 FIXME("(%p,%u,%p,%p): stub\n", iface
, length
, manufacturer
, actual_length
);
1710 static HRESULT WINAPI
MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo
*iface
,
1711 UINT length
, WCHAR
*models
, UINT
*actual_length
)
1713 FIXME("(%p,%u,%p,%p): stub\n", iface
, length
, models
, actual_length
);
1717 static HRESULT WINAPI
MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo
*iface
,
1720 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1721 TRACE("(%p,%p)\n", iface
, param
);
1722 return ComponentInfo_GetDWORDValue(This
->classkey
, requiresfullstream_valuename
, (DWORD
*)param
);
1725 static HRESULT WINAPI
MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo
*iface
,
1728 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1729 TRACE("(%p,%p)\n", iface
, param
);
1730 return ComponentInfo_GetDWORDValue(This
->classkey
, supportspadding_valuename
, (DWORD
*)param
);
1733 static HRESULT WINAPI
MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo
*iface
,
1736 FIXME("(%p,%p): stub\n", iface
, param
);
1740 static HRESULT WINAPI
MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo
*iface
,
1741 REFGUID container_guid
, UINT length
, WICMetadataPattern
*patterns
, UINT
*count
, UINT
*actual_length
)
1743 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1744 struct metadata_container
*container
;
1746 TRACE("(%p,%s,%u,%p,%p,%p)\n", iface
, debugstr_guid(container_guid
), length
, patterns
, count
, actual_length
);
1748 if (!actual_length
|| !container_guid
) return E_INVALIDARG
;
1750 if (!(container
= get_metadata_container(This
, container_guid
)))
1751 return WINCODEC_ERR_COMPONENTNOTFOUND
;
1753 *count
= container
->pattern_count
;
1754 *actual_length
= container
->patterns_size
;
1757 if (container
->patterns_size
&& length
< container
->patterns_size
)
1758 return WINCODEC_ERR_INSUFFICIENTBUFFER
;
1759 memcpy(patterns
, container
->patterns
, container
->patterns_size
);
1764 static HRESULT WINAPI
MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo
*iface
,
1765 REFGUID container_guid
, IStream
*stream
, BOOL
*matches
)
1767 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1768 struct metadata_container
*container
;
1774 LARGE_INTEGER seekpos
;
1777 TRACE("(%p,%s,%p,%p)\n", iface
, debugstr_guid(container_guid
), stream
, matches
);
1779 if (!(container
= get_metadata_container(This
, container_guid
)))
1780 return WINCODEC_ERR_COMPONENTNOTFOUND
;
1782 for (i
=0; i
< container
->pattern_count
; i
++)
1784 if (datasize
< container
->patterns
[i
].Length
)
1786 HeapFree(GetProcessHeap(), 0, data
);
1787 datasize
= container
->patterns
[i
].Length
;
1788 data
= HeapAlloc(GetProcessHeap(), 0, container
->patterns
[i
].Length
);
1796 seekpos
.QuadPart
= container
->patterns
[i
].Position
.QuadPart
;
1797 hr
= IStream_Seek(stream
, seekpos
, STREAM_SEEK_SET
, NULL
);
1798 if (FAILED(hr
)) break;
1800 hr
= IStream_Read(stream
, data
, container
->patterns
[i
].Length
, &bytesread
);
1801 if (hr
== S_FALSE
|| (hr
== S_OK
&& bytesread
!= container
->patterns
[i
].Length
)) /* past end of stream */
1803 if (FAILED(hr
)) break;
1805 for (pos
=0; pos
< container
->patterns
[i
].Length
; pos
++)
1807 if ((data
[pos
] & container
->patterns
[i
].Mask
[pos
]) != container
->patterns
[i
].Pattern
[pos
])
1810 if (pos
== container
->patterns
[i
].Length
) /* matches pattern */
1818 if (i
== container
->pattern_count
) /* does not match any pattern */
1824 HeapFree(GetProcessHeap(), 0, data
);
1829 static HRESULT WINAPI
MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo
*iface
,
1830 IWICMetadataReader
**reader
)
1832 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1834 TRACE("(%p,%p)\n", iface
, reader
);
1836 return create_instance(&This
->base
.clsid
, &IID_IWICMetadataReader
, (void **)reader
);
1839 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl
= {
1840 MetadataReaderInfo_QueryInterface
,
1841 MetadataReaderInfo_AddRef
,
1842 MetadataReaderInfo_Release
,
1843 MetadataReaderInfo_GetComponentType
,
1844 MetadataReaderInfo_GetCLSID
,
1845 MetadataReaderInfo_GetSigningStatus
,
1846 MetadataReaderInfo_GetAuthor
,
1847 MetadataReaderInfo_GetVendorGUID
,
1848 MetadataReaderInfo_GetVersion
,
1849 MetadataReaderInfo_GetSpecVersion
,
1850 MetadataReaderInfo_GetFriendlyName
,
1851 MetadataReaderInfo_GetMetadataFormat
,
1852 MetadataReaderInfo_GetContainerFormats
,
1853 MetadataReaderInfo_GetDeviceManufacturer
,
1854 MetadataReaderInfo_GetDeviceModels
,
1855 MetadataReaderInfo_DoesRequireFullStream
,
1856 MetadataReaderInfo_DoesSupportPadding
,
1857 MetadataReaderInfo_DoesRequireFixedSize
,
1858 MetadataReaderInfo_GetPatterns
,
1859 MetadataReaderInfo_MatchesPattern
,
1860 MetadataReaderInfo_CreateInstance
1863 static void read_metadata_patterns(MetadataReaderInfo
*info
, GUID
*container_guid
,
1864 struct metadata_container
*container
)
1866 UINT pattern_count
=0, patterns_size
=0;
1867 WCHAR subkeyname
[11], guidkeyname
[39];
1869 HKEY containers_key
, guid_key
, patternkey
;
1870 static const WCHAR uintformatW
[] = {'%','u',0};
1871 static const WCHAR patternW
[] = {'P','a','t','t','e','r','n',0};
1872 static const WCHAR positionW
[] = {'P','o','s','i','t','i','o','n',0};
1873 static const WCHAR maskW
[] = {'M','a','s','k',0};
1874 static const WCHAR dataoffsetW
[] = {'D','a','t','a','O','f','f','s','e','t',0};
1876 WICMetadataPattern
*patterns
;
1878 DWORD length
, valuesize
;
1880 res
= RegOpenKeyExW(info
->classkey
, containers_keyname
, 0, KEY_READ
, &containers_key
);
1881 if (res
!= ERROR_SUCCESS
) return;
1883 StringFromGUID2(container_guid
, guidkeyname
, 39);
1884 res
= RegOpenKeyExW(containers_key
, guidkeyname
, 0, KEY_READ
, &guid_key
);
1885 RegCloseKey(containers_key
);
1886 if (res
!= ERROR_SUCCESS
) return;
1888 res
= RegQueryInfoKeyW(guid_key
, NULL
, NULL
, NULL
, &pattern_count
,
1889 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
1890 if (res
!= ERROR_SUCCESS
)
1892 RegCloseKey(guid_key
);
1896 patterns_size
= pattern_count
* sizeof(WICMetadataPattern
);
1897 patterns
= heap_alloc(patterns_size
);
1900 RegCloseKey(guid_key
);
1904 for (i
=0; res
== ERROR_SUCCESS
&& i
< pattern_count
; i
++)
1906 snprintfW(subkeyname
, 11, uintformatW
, i
);
1907 res
= RegOpenKeyExW(guid_key
, subkeyname
, 0, KEY_READ
, &patternkey
);
1908 if (res
!= ERROR_SUCCESS
) break;
1910 res
= RegGetValueW(patternkey
, NULL
, patternW
, RRF_RT_REG_BINARY
, NULL
, NULL
, &length
);
1911 if (res
== ERROR_SUCCESS
)
1913 patterns_size
+= length
*2;
1914 patterns
[i
].Length
= length
;
1916 valuesize
= sizeof(DWORD64
);
1917 res
= RegGetValueW(patternkey
, NULL
, dataoffsetW
, RRF_RT_DWORD
|RRF_RT_QWORD
, NULL
,
1918 &patterns
[i
].DataOffset
, &valuesize
);
1919 if (res
) patterns
[i
].DataOffset
.QuadPart
= 0;
1921 patterns
[i
].Position
.QuadPart
= 0;
1922 valuesize
= sizeof(DWORD64
);
1923 res
= RegGetValueW(patternkey
, NULL
, positionW
, RRF_RT_DWORD
|RRF_RT_QWORD
, NULL
,
1924 &patterns
[i
].Position
, &valuesize
);
1927 RegCloseKey(patternkey
);
1930 if (res
!= ERROR_SUCCESS
|| !(patterns_ptr
= heap_realloc(patterns
, patterns_size
)))
1932 heap_free(patterns
);
1933 RegCloseKey(guid_key
);
1936 patterns
= (WICMetadataPattern
*)patterns_ptr
;
1937 patterns_ptr
+= pattern_count
* sizeof(*patterns
);
1939 for (i
=0; res
== ERROR_SUCCESS
&& i
< pattern_count
; i
++)
1941 snprintfW(subkeyname
, 11, uintformatW
, i
);
1942 res
= RegOpenKeyExW(guid_key
, subkeyname
, 0, KEY_READ
, &patternkey
);
1943 if (res
!= ERROR_SUCCESS
) break;
1945 length
= patterns
[i
].Length
;
1946 patterns
[i
].Pattern
= patterns_ptr
;
1948 res
= RegGetValueW(patternkey
, NULL
, patternW
, RRF_RT_REG_BINARY
, NULL
,
1949 patterns
[i
].Pattern
, &valuesize
);
1950 patterns_ptr
+= length
;
1952 if (res
== ERROR_SUCCESS
)
1954 patterns
[i
].Mask
= patterns_ptr
;
1956 res
= RegGetValueW(patternkey
, NULL
, maskW
, RRF_RT_REG_BINARY
, NULL
,
1957 patterns
[i
].Mask
, &valuesize
);
1958 patterns_ptr
+= length
;
1961 RegCloseKey(patternkey
);
1964 RegCloseKey(guid_key
);
1966 if (res
!= ERROR_SUCCESS
)
1968 heap_free(patterns
);
1972 container
->pattern_count
= pattern_count
;
1973 container
->patterns_size
= patterns_size
;
1974 container
->patterns
= patterns
;
1977 static BOOL
read_metadata_info(MetadataReaderInfo
*info
)
1983 hr
= ComponentInfo_GetGuidList(info
->classkey
, containers_keyname
, 0, NULL
, &format_count
);
1984 if (FAILED(hr
)) return TRUE
;
1986 formats
= heap_calloc(format_count
, sizeof(*formats
));
1987 if (!formats
) return FALSE
;
1989 hr
= ComponentInfo_GetGuidList(info
->classkey
, containers_keyname
, format_count
, formats
,
1997 info
->container_formats
= formats
;
1998 info
->container_count
= format_count
;
2004 info
->containers
= heap_calloc(format_count
, sizeof(*info
->containers
));
2005 if (!info
->containers
) return FALSE
;
2007 for (i
= 0; i
< format_count
; i
++)
2008 read_metadata_patterns(info
, info
->container_formats
+ i
, info
->containers
+ i
);
2014 static HRESULT
MetadataReaderInfo_Constructor(HKEY classkey
, REFCLSID clsid
, ComponentInfo
**info
)
2016 MetadataReaderInfo
*This
;
2018 This
= heap_alloc_zero(sizeof(*This
));
2021 RegCloseKey(classkey
);
2022 return E_OUTOFMEMORY
;
2025 This
->base
.IWICComponentInfo_iface
.lpVtbl
= (const IWICComponentInfoVtbl
*)&MetadataReaderInfo_Vtbl
;
2027 This
->classkey
= classkey
;
2028 This
->base
.clsid
= *clsid
;
2030 if (!read_metadata_info(This
))
2032 IWICComponentInfo_Release(&This
->base
.IWICComponentInfo_iface
);
2033 return WINCODEC_ERR_COMPONENTNOTFOUND
;
2036 *info
= &This
->base
;
2040 static const WCHAR clsid_keyname
[] = {'C','L','S','I','D',0};
2041 static const WCHAR instance_keyname
[] = {'I','n','s','t','a','n','c','e',0};
2044 WICComponentType type
;
2046 HRESULT (*constructor
)(HKEY
,REFCLSID
,ComponentInfo
**);
2049 static const struct category categories
[] = {
2050 {WICDecoder
, &CATID_WICBitmapDecoders
, BitmapDecoderInfo_Constructor
},
2051 {WICEncoder
, &CATID_WICBitmapEncoders
, BitmapEncoderInfo_Constructor
},
2052 {WICPixelFormatConverter
, &CATID_WICFormatConverters
, FormatConverterInfo_Constructor
},
2053 {WICPixelFormat
, &CATID_WICPixelFormats
, PixelFormatInfo_Constructor
},
2054 {WICMetadataReader
, &CATID_WICMetadataReader
, MetadataReaderInfo_Constructor
},
2058 static int ComponentInfo_Compare(const void *key
, const struct wine_rb_entry
*entry
)
2060 ComponentInfo
*info
= WINE_RB_ENTRY_VALUE(entry
, ComponentInfo
, entry
);
2061 return memcmp(key
, &info
->clsid
, sizeof(info
->clsid
));
2064 static struct wine_rb_tree component_info_cache
= { ComponentInfo_Compare
};
2066 static CRITICAL_SECTION component_info_cache_cs
;
2067 static CRITICAL_SECTION_DEBUG component_info_cache_cs_dbg
=
2069 0, 0, &component_info_cache_cs
,
2070 { &component_info_cache_cs_dbg
.ProcessLocksList
, &component_info_cache_cs_dbg
.ProcessLocksList
},
2071 0, 0, { (DWORD_PTR
)(__FILE__
": component_info_cache") }
2073 static CRITICAL_SECTION component_info_cache_cs
= { &component_info_cache_cs_dbg
, -1, 0, 0, 0, 0 };
2075 HRESULT
CreateComponentInfo(REFCLSID clsid
, IWICComponentInfo
**ppIInfo
)
2077 struct wine_rb_entry
*cache_entry
;
2078 ComponentInfo
*info
;
2083 WCHAR guidstring
[39];
2085 const struct category
*category
;
2089 EnterCriticalSection(&component_info_cache_cs
);
2091 cache_entry
= wine_rb_get(&component_info_cache
, clsid
);
2094 info
= WINE_RB_ENTRY_VALUE(cache_entry
, ComponentInfo
, entry
);
2095 IWICComponentInfo_AddRef(*ppIInfo
= &info
->IWICComponentInfo_iface
);
2096 LeaveCriticalSection(&component_info_cache_cs
);
2100 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, KEY_READ
, &clsidkey
);
2101 if (res
!= ERROR_SUCCESS
)
2103 LeaveCriticalSection(&component_info_cache_cs
);
2104 return HRESULT_FROM_WIN32(res
);
2107 for (category
=categories
; category
->type
; category
++)
2109 StringFromGUID2(category
->catid
, guidstring
, 39);
2110 res
= RegOpenKeyExW(clsidkey
, guidstring
, 0, KEY_READ
, &catidkey
);
2111 if (res
== ERROR_SUCCESS
)
2113 res
= RegOpenKeyExW(catidkey
, instance_keyname
, 0, KEY_READ
, &instancekey
);
2114 if (res
== ERROR_SUCCESS
)
2116 StringFromGUID2(clsid
, guidstring
, 39);
2117 res
= RegOpenKeyExW(instancekey
, guidstring
, 0, KEY_READ
, &classkey
);
2118 if (res
== ERROR_SUCCESS
)
2120 RegCloseKey(classkey
);
2123 RegCloseKey(instancekey
);
2125 RegCloseKey(catidkey
);
2132 res
= RegOpenKeyExW(clsidkey
, guidstring
, 0, KEY_READ
, &classkey
);
2133 if (res
== ERROR_SUCCESS
)
2134 hr
= category
->constructor(classkey
, clsid
, &info
);
2136 hr
= HRESULT_FROM_WIN32(res
);
2140 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid
));
2144 RegCloseKey(clsidkey
);
2148 wine_rb_put(&component_info_cache
, clsid
, &info
->entry
);
2149 IWICComponentInfo_AddRef(*ppIInfo
= &info
->IWICComponentInfo_iface
);
2151 LeaveCriticalSection(&component_info_cache_cs
);
2155 void ReleaseComponentInfos(void)
2157 ComponentInfo
*info
, *next_info
;
2158 WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(info
, next_info
, &component_info_cache
, ComponentInfo
, entry
)
2159 IWICComponentInfo_Release(&info
->IWICComponentInfo_iface
);
2162 HRESULT
get_decoder_info(REFCLSID clsid
, IWICBitmapDecoderInfo
**info
)
2164 IWICComponentInfo
*compinfo
;
2167 hr
= CreateComponentInfo(clsid
, &compinfo
);
2168 if (FAILED(hr
)) return hr
;
2170 hr
= IWICComponentInfo_QueryInterface(compinfo
, &IID_IWICBitmapDecoderInfo
,
2173 IWICComponentInfo_Release(compinfo
);
2179 IEnumUnknown IEnumUnknown_iface
;
2181 struct list objects
;
2182 struct list
*cursor
;
2183 CRITICAL_SECTION lock
; /* Must be held when reading or writing cursor */
2186 static inline ComponentEnum
*impl_from_IEnumUnknown(IEnumUnknown
*iface
)
2188 return CONTAINING_RECORD(iface
, ComponentEnum
, IEnumUnknown_iface
);
2194 } ComponentEnumItem
;
2196 static const IEnumUnknownVtbl ComponentEnumVtbl
;
2198 static HRESULT WINAPI
ComponentEnum_QueryInterface(IEnumUnknown
*iface
, REFIID iid
,
2201 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2202 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
2204 if (!ppv
) return E_INVALIDARG
;
2206 if (IsEqualIID(&IID_IUnknown
, iid
) ||
2207 IsEqualIID(&IID_IEnumUnknown
, iid
))
2209 *ppv
= &This
->IEnumUnknown_iface
;
2214 return E_NOINTERFACE
;
2217 IUnknown_AddRef((IUnknown
*)*ppv
);
2221 static ULONG WINAPI
ComponentEnum_AddRef(IEnumUnknown
*iface
)
2223 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2224 ULONG ref
= InterlockedIncrement(&This
->ref
);
2226 TRACE("(%p) refcount=%u\n", iface
, ref
);
2231 static ULONG WINAPI
ComponentEnum_Release(IEnumUnknown
*iface
)
2233 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2234 ULONG ref
= InterlockedDecrement(&This
->ref
);
2235 ComponentEnumItem
*cursor
, *cursor2
;
2237 TRACE("(%p) refcount=%u\n", iface
, ref
);
2241 LIST_FOR_EACH_ENTRY_SAFE(cursor
, cursor2
, &This
->objects
, ComponentEnumItem
, entry
)
2243 IUnknown_Release(cursor
->unk
);
2244 list_remove(&cursor
->entry
);
2245 HeapFree(GetProcessHeap(), 0, cursor
);
2247 This
->lock
.DebugInfo
->Spare
[0] = 0;
2248 DeleteCriticalSection(&This
->lock
);
2249 HeapFree(GetProcessHeap(), 0, This
);
2255 static HRESULT WINAPI
ComponentEnum_Next(IEnumUnknown
*iface
, ULONG celt
,
2256 IUnknown
**rgelt
, ULONG
*pceltFetched
)
2258 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2259 ULONG num_fetched
=0;
2260 ComponentEnumItem
*item
;
2263 TRACE("(%p,%u,%p,%p)\n", iface
, celt
, rgelt
, pceltFetched
);
2265 EnterCriticalSection(&This
->lock
);
2266 while (num_fetched
<celt
)
2273 item
= LIST_ENTRY(This
->cursor
, ComponentEnumItem
, entry
);
2274 IUnknown_AddRef(item
->unk
);
2275 rgelt
[num_fetched
] = item
->unk
;
2277 This
->cursor
= list_next(&This
->objects
, This
->cursor
);
2279 LeaveCriticalSection(&This
->lock
);
2281 *pceltFetched
= num_fetched
;
2285 static HRESULT WINAPI
ComponentEnum_Skip(IEnumUnknown
*iface
, ULONG celt
)
2287 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2291 TRACE("(%p,%u)\n", iface
, celt
);
2293 EnterCriticalSection(&This
->lock
);
2294 for (i
=0; i
<celt
; i
++)
2301 This
->cursor
= list_next(&This
->objects
, This
->cursor
);
2303 LeaveCriticalSection(&This
->lock
);
2307 static HRESULT WINAPI
ComponentEnum_Reset(IEnumUnknown
*iface
)
2309 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2311 TRACE("(%p)\n", iface
);
2313 EnterCriticalSection(&This
->lock
);
2314 This
->cursor
= list_head(&This
->objects
);
2315 LeaveCriticalSection(&This
->lock
);
2319 static HRESULT WINAPI
ComponentEnum_Clone(IEnumUnknown
*iface
, IEnumUnknown
**ppenum
)
2321 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2322 ComponentEnum
*new_enum
;
2323 ComponentEnumItem
*old_item
, *new_item
;
2325 struct list
*old_cursor
;
2327 new_enum
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum
));
2331 return E_OUTOFMEMORY
;
2334 new_enum
->IEnumUnknown_iface
.lpVtbl
= &ComponentEnumVtbl
;
2336 new_enum
->cursor
= NULL
;
2337 list_init(&new_enum
->objects
);
2338 InitializeCriticalSection(&new_enum
->lock
);
2339 new_enum
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": ComponentEnum.lock");
2341 EnterCriticalSection(&This
->lock
);
2342 old_cursor
= This
->cursor
;
2343 LeaveCriticalSection(&This
->lock
);
2345 LIST_FOR_EACH_ENTRY(old_item
, &This
->objects
, ComponentEnumItem
, entry
)
2347 new_item
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem
));
2350 ret
= E_OUTOFMEMORY
;
2353 new_item
->unk
= old_item
->unk
;
2354 list_add_tail(&new_enum
->objects
, &new_item
->entry
);
2355 IUnknown_AddRef(new_item
->unk
);
2356 if (&old_item
->entry
== old_cursor
) new_enum
->cursor
= &new_item
->entry
;
2361 IEnumUnknown_Release(&new_enum
->IEnumUnknown_iface
);
2365 *ppenum
= &new_enum
->IEnumUnknown_iface
;
2370 static const IEnumUnknownVtbl ComponentEnumVtbl
= {
2371 ComponentEnum_QueryInterface
,
2372 ComponentEnum_AddRef
,
2373 ComponentEnum_Release
,
2376 ComponentEnum_Reset
,
2380 HRESULT
CreateComponentEnumerator(DWORD componentTypes
, DWORD options
, IEnumUnknown
**ppIEnumUnknown
)
2382 ComponentEnum
*This
;
2383 ComponentEnumItem
*item
;
2384 const struct category
*category
;
2385 HKEY clsidkey
, catidkey
, instancekey
;
2386 WCHAR guidstring
[39];
2392 if (options
) FIXME("ignoring flags %x\n", options
);
2394 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, KEY_READ
, &clsidkey
);
2395 if (res
!= ERROR_SUCCESS
)
2396 return HRESULT_FROM_WIN32(res
);
2398 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum
));
2401 RegCloseKey(clsidkey
);
2402 return E_OUTOFMEMORY
;
2405 This
->IEnumUnknown_iface
.lpVtbl
= &ComponentEnumVtbl
;
2407 list_init(&This
->objects
);
2408 InitializeCriticalSection(&This
->lock
);
2409 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": ComponentEnum.lock");
2411 for (category
=categories
; category
->type
&& hr
== S_OK
; category
++)
2413 if ((category
->type
& componentTypes
) == 0) continue;
2414 StringFromGUID2(category
->catid
, guidstring
, 39);
2415 res
= RegOpenKeyExW(clsidkey
, guidstring
, 0, KEY_READ
, &catidkey
);
2416 if (res
== ERROR_SUCCESS
)
2418 res
= RegOpenKeyExW(catidkey
, instance_keyname
, 0, KEY_READ
, &instancekey
);
2419 if (res
== ERROR_SUCCESS
)
2424 DWORD guidstring_size
= 39;
2425 res
= RegEnumKeyExW(instancekey
, i
, guidstring
, &guidstring_size
, NULL
, NULL
, NULL
, NULL
);
2426 if (res
!= ERROR_SUCCESS
) break;
2428 item
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem
));
2429 if (!item
) { hr
= E_OUTOFMEMORY
; break; }
2431 hr
= CLSIDFromString(guidstring
, &clsid
);
2434 hr
= CreateComponentInfo(&clsid
, (IWICComponentInfo
**)&item
->unk
);
2436 list_add_tail(&This
->objects
, &item
->entry
);
2441 HeapFree(GetProcessHeap(), 0, item
);
2445 RegCloseKey(instancekey
);
2447 RegCloseKey(catidkey
);
2449 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_NO_MORE_ITEMS
)
2450 hr
= HRESULT_FROM_WIN32(res
);
2452 RegCloseKey(clsidkey
);
2456 IEnumUnknown_Reset(&This
->IEnumUnknown_iface
);
2457 *ppIEnumUnknown
= &This
->IEnumUnknown_iface
;
2461 *ppIEnumUnknown
= NULL
;
2462 IEnumUnknown_Release(&This
->IEnumUnknown_iface
);
2468 static BOOL
is_1bpp_format(const WICPixelFormatGUID
*format
)
2470 return IsEqualGUID(format
, &GUID_WICPixelFormatBlackWhite
) ||
2471 IsEqualGUID(format
, &GUID_WICPixelFormat1bppIndexed
);
2474 HRESULT WINAPI
WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat
, IWICBitmapSource
*pISrc
, IWICBitmapSource
**ppIDst
)
2477 IEnumUnknown
*enumconverters
;
2478 IUnknown
*unkconverterinfo
;
2479 IWICFormatConverterInfo
*converterinfo
=NULL
;
2480 IWICFormatConverter
*converter
=NULL
;
2482 WCHAR srcformatstr
[39], dstformatstr
[39];
2486 TRACE("%s,%p,%p\n", debugstr_guid(dstFormat
), pISrc
, ppIDst
);
2488 res
= IWICBitmapSource_GetPixelFormat(pISrc
, &srcFormat
);
2489 if (FAILED(res
)) return res
;
2491 if (IsEqualGUID(&srcFormat
, dstFormat
) || (is_1bpp_format(&srcFormat
) && is_1bpp_format(dstFormat
)))
2493 IWICBitmapSource_AddRef(pISrc
);
2498 StringFromGUID2(&srcFormat
, srcformatstr
, 39);
2499 StringFromGUID2(dstFormat
, dstformatstr
, 39);
2501 res
= CreateComponentEnumerator(WICPixelFormatConverter
, 0, &enumconverters
);
2502 if (FAILED(res
)) return res
;
2506 res
= IEnumUnknown_Next(enumconverters
, 1, &unkconverterinfo
, &num_fetched
);
2510 res
= IUnknown_QueryInterface(unkconverterinfo
, &IID_IWICFormatConverterInfo
, (void**)&converterinfo
);
2514 canconvert
= ConverterSupportsFormat(converterinfo
, srcformatstr
);
2517 canconvert
= ConverterSupportsFormat(converterinfo
, dstformatstr
);
2521 res
= IWICFormatConverterInfo_CreateInstance(converterinfo
, &converter
);
2524 res
= IWICFormatConverter_CanConvert(converter
, &srcFormat
, dstFormat
, &canconvert
);
2526 if (SUCCEEDED(res
) && canconvert
)
2527 res
= IWICFormatConverter_Initialize(converter
, pISrc
, dstFormat
, WICBitmapDitherTypeNone
,
2528 NULL
, 0.0, WICBitmapPaletteTypeMedianCut
);
2530 if (FAILED(res
) || !canconvert
)
2534 IWICFormatConverter_Release(converter
);
2540 IWICFormatConverterInfo_Release(converterinfo
);
2543 IUnknown_Release(unkconverterinfo
);
2549 IEnumUnknown_Release(enumconverters
);
2553 res
= IWICFormatConverter_QueryInterface(converter
, &IID_IWICBitmapSource
, (void **)ppIDst
);
2554 IWICFormatConverter_Release(converter
);
2559 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat
), debugstr_guid(dstFormat
));
2561 return WINCODEC_ERR_COMPONENTNOTFOUND
;