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
29 #include "wincodecs_private.h"
31 #include "wine/debug.h"
32 #include "wine/list.h"
33 #include "wine/rbtree.h"
34 #include "wine/heap.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
39 IWICComponentInfo IWICComponentInfo_iface
;
42 struct wine_rb_entry entry
;
45 static HRESULT
ComponentInfo_GetStringValue(HKEY classkey
, LPCWSTR value
,
46 UINT buffer_size
, WCHAR
*buffer
, UINT
*actual_size
)
49 DWORD cbdata
=buffer_size
* sizeof(WCHAR
);
54 ret
= RegGetValueW(classkey
, NULL
, value
, RRF_RT_REG_SZ
|RRF_NOEXPAND
, NULL
,
57 if (ret
== ERROR_FILE_NOT_FOUND
)
63 if (ret
== 0 || ret
== ERROR_MORE_DATA
)
64 *actual_size
= cbdata
/sizeof(WCHAR
);
66 if (!buffer
&& buffer_size
!= 0)
67 /* Yes, native returns the correct size in this case. */
70 if (ret
== ERROR_MORE_DATA
)
71 return WINCODEC_ERR_INSUFFICIENTBUFFER
;
73 return HRESULT_FROM_WIN32(ret
);
76 static HRESULT
ComponentInfo_GetGUIDValue(HKEY classkey
, LPCWSTR value
,
80 WCHAR guid_string
[39];
81 DWORD cbdata
= sizeof(guid_string
);
87 ret
= RegGetValueW(classkey
, NULL
, value
, RRF_RT_REG_SZ
|RRF_NOEXPAND
, NULL
,
88 guid_string
, &cbdata
);
90 if (ret
!= ERROR_SUCCESS
)
91 return HRESULT_FROM_WIN32(ret
);
93 if (cbdata
< sizeof(guid_string
))
95 ERR("incomplete GUID value\n");
99 hr
= CLSIDFromString(guid_string
, result
);
104 static HRESULT
ComponentInfo_GetUINTValue(HKEY classkey
, LPCWSTR value
,
108 DWORD cbdata
= sizeof(DWORD
);
113 ret
= RegGetValueW(classkey
, NULL
, value
, RRF_RT_DWORD
, NULL
,
114 (DWORD
*)result
, &cbdata
);
116 if (ret
== ERROR_FILE_NOT_FOUND
)
122 return HRESULT_FROM_WIN32(ret
);
125 static HRESULT
ComponentInfo_GetGuidList(HKEY classkey
, LPCWSTR subkeyname
,
126 UINT buffersize
, GUID
*buffer
, UINT
*actual_size
)
131 WCHAR guid_string
[39];
132 DWORD guid_string_size
;
138 ret
= RegOpenKeyExW(classkey
, subkeyname
, 0, KEY_READ
, &subkey
);
139 if (ret
== ERROR_FILE_NOT_FOUND
)
144 else if (ret
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(ret
);
149 guid_string_size
= 39;
150 while (items_returned
< buffersize
)
152 ret
= RegEnumKeyExW(subkey
, items_returned
, guid_string
,
153 &guid_string_size
, NULL
, NULL
, NULL
, NULL
);
155 if (ret
!= ERROR_SUCCESS
)
157 hr
= HRESULT_FROM_WIN32(ret
);
161 if (guid_string_size
!= 38)
167 hr
= CLSIDFromString(guid_string
, &buffer
[items_returned
]);
172 guid_string_size
= 39;
175 if (ret
== ERROR_NO_MORE_ITEMS
)
178 *actual_size
= items_returned
;
182 ret
= RegQueryInfoKeyW(subkey
, NULL
, NULL
, NULL
, (DWORD
*)actual_size
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
183 if (ret
!= ERROR_SUCCESS
)
184 hr
= HRESULT_FROM_WIN32(ret
);
195 WICBitmapPattern
*patterns
;
200 static inline BitmapDecoderInfo
*impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo
*iface
)
202 return CONTAINING_RECORD(iface
, BitmapDecoderInfo
, base
.IWICComponentInfo_iface
);
205 static HRESULT WINAPI
BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo
*iface
, REFIID iid
,
208 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
209 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
211 if (!ppv
) return E_INVALIDARG
;
213 if (IsEqualIID(&IID_IUnknown
, iid
) ||
214 IsEqualIID(&IID_IWICComponentInfo
, iid
) ||
215 IsEqualIID(&IID_IWICBitmapCodecInfo
, iid
) ||
216 IsEqualIID(&IID_IWICBitmapDecoderInfo
,iid
))
218 *ppv
= &This
->base
.IWICComponentInfo_iface
;
223 return E_NOINTERFACE
;
226 IUnknown_AddRef((IUnknown
*)*ppv
);
230 static ULONG WINAPI
BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo
*iface
)
232 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
233 ULONG ref
= InterlockedIncrement(&This
->base
.ref
);
235 TRACE("(%p) refcount=%lu\n", iface
, ref
);
240 static ULONG WINAPI
BitmapDecoderInfo_Release(IWICBitmapDecoderInfo
*iface
)
242 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
243 ULONG ref
= InterlockedDecrement(&This
->base
.ref
);
245 TRACE("(%p) refcount=%lu\n", iface
, ref
);
249 RegCloseKey(This
->classkey
);
250 heap_free(This
->patterns
);
251 HeapFree(GetProcessHeap(), 0, This
);
257 static HRESULT WINAPI
BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo
*iface
,
258 WICComponentType
*pType
)
260 TRACE("(%p,%p)\n", iface
, pType
);
261 if (!pType
) return E_INVALIDARG
;
266 static HRESULT WINAPI
BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo
*iface
, CLSID
*pclsid
)
268 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
269 TRACE("(%p,%p)\n", iface
, pclsid
);
274 *pclsid
= This
->base
.clsid
;
278 static HRESULT WINAPI
BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo
*iface
, DWORD
*pStatus
)
280 FIXME("(%p,%p): stub\n", iface
, pStatus
);
284 static HRESULT WINAPI
BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo
*iface
, UINT cchAuthor
,
285 WCHAR
*wzAuthor
, UINT
*pcchActual
)
287 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
289 TRACE("(%p,%u,%p,%p)\n", iface
, cchAuthor
, wzAuthor
, pcchActual
);
291 return ComponentInfo_GetStringValue(This
->classkey
, L
"Author", cchAuthor
, wzAuthor
, pcchActual
);
294 static HRESULT WINAPI
BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo
*iface
, GUID
*pguidVendor
)
296 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
298 TRACE("(%p,%p)\n", iface
, pguidVendor
);
300 return ComponentInfo_GetGUIDValue(This
->classkey
, L
"Vendor", pguidVendor
);
303 static HRESULT WINAPI
BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo
*iface
, UINT cchVersion
,
304 WCHAR
*wzVersion
, UINT
*pcchActual
)
306 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
308 TRACE("(%p,%u,%p,%p)\n", iface
, cchVersion
, wzVersion
, pcchActual
);
310 return ComponentInfo_GetStringValue(This
->classkey
, L
"Version",
311 cchVersion
, wzVersion
, pcchActual
);
314 static HRESULT WINAPI
BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo
*iface
, UINT cchSpecVersion
,
315 WCHAR
*wzSpecVersion
, UINT
*pcchActual
)
317 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
319 TRACE("(%p,%u,%p,%p)\n", iface
, cchSpecVersion
, wzSpecVersion
, pcchActual
);
321 return ComponentInfo_GetStringValue(This
->classkey
, L
"SpecVersion",
322 cchSpecVersion
, wzSpecVersion
, pcchActual
);
325 static HRESULT WINAPI
BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo
*iface
, UINT cchFriendlyName
,
326 WCHAR
*wzFriendlyName
, UINT
*pcchActual
)
328 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
330 TRACE("(%p,%u,%p,%p)\n", iface
, cchFriendlyName
, wzFriendlyName
, pcchActual
);
332 return ComponentInfo_GetStringValue(This
->classkey
, L
"FriendlyName",
333 cchFriendlyName
, wzFriendlyName
, pcchActual
);
336 static HRESULT WINAPI
BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo
*iface
,
337 GUID
*pguidContainerFormat
)
339 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
340 TRACE("(%p,%p)\n", iface
, pguidContainerFormat
);
341 return ComponentInfo_GetGUIDValue(This
->classkey
, L
"ContainerFormat", pguidContainerFormat
);
344 static HRESULT WINAPI
BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo
*iface
,
345 UINT cFormats
, GUID
*pguidPixelFormats
, UINT
*pcActual
)
347 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
348 TRACE("(%p,%u,%p,%p)\n", iface
, cFormats
, pguidPixelFormats
, pcActual
);
349 return ComponentInfo_GetGuidList(This
->classkey
, L
"Formats", cFormats
, pguidPixelFormats
, pcActual
);
352 static HRESULT WINAPI
BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo
*iface
,
353 UINT cchColorManagementVersion
, WCHAR
*wzColorManagementVersion
, UINT
*pcchActual
)
355 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchColorManagementVersion
, wzColorManagementVersion
, pcchActual
);
359 static HRESULT WINAPI
BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo
*iface
,
360 UINT cchDeviceManufacturer
, WCHAR
*wzDeviceManufacturer
, UINT
*pcchActual
)
362 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchDeviceManufacturer
, wzDeviceManufacturer
, pcchActual
);
366 static HRESULT WINAPI
BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo
*iface
,
367 UINT cchDeviceModels
, WCHAR
*wzDeviceModels
, UINT
*pcchActual
)
369 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchDeviceModels
, wzDeviceModels
, pcchActual
);
373 static HRESULT WINAPI
BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo
*iface
,
374 UINT cchMimeTypes
, WCHAR
*wzMimeTypes
, UINT
*pcchActual
)
376 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
378 TRACE("(%p,%u,%p,%p)\n", iface
, cchMimeTypes
, wzMimeTypes
, pcchActual
);
380 return ComponentInfo_GetStringValue(This
->classkey
, L
"MimeTypes",
381 cchMimeTypes
, wzMimeTypes
, pcchActual
);
384 static HRESULT WINAPI
BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo
*iface
,
385 UINT cchFileExtensions
, WCHAR
*wzFileExtensions
, UINT
*pcchActual
)
387 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
389 TRACE("(%p,%u,%p,%p)\n", iface
, cchFileExtensions
, wzFileExtensions
, pcchActual
);
391 return ComponentInfo_GetStringValue(This
->classkey
, L
"FileExtensions",
392 cchFileExtensions
, wzFileExtensions
, pcchActual
);
395 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo
*iface
,
396 BOOL
*pfSupportAnimation
)
398 FIXME("(%p,%p): stub\n", iface
, pfSupportAnimation
);
402 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo
*iface
,
403 BOOL
*pfSupportChromaKey
)
405 FIXME("(%p,%p): stub\n", iface
, pfSupportChromaKey
);
409 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo
*iface
,
410 BOOL
*pfSupportLossless
)
412 FIXME("(%p,%p): stub\n", iface
, pfSupportLossless
);
416 static HRESULT WINAPI
BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo
*iface
,
417 BOOL
*pfSupportMultiframe
)
419 FIXME("(%p,%p): stub\n", iface
, pfSupportMultiframe
);
423 static HRESULT WINAPI
BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo
*iface
,
424 LPCWSTR wzMimeType
, BOOL
*pfMatches
)
426 FIXME("(%p,%s,%p): stub\n", iface
, debugstr_w(wzMimeType
), pfMatches
);
430 static HRESULT WINAPI
BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo
*iface
,
431 UINT cbSizePatterns
, WICBitmapPattern
*pPatterns
, UINT
*pcPatterns
, UINT
*pcbPatternsActual
)
433 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
435 TRACE("(%p,%i,%p,%p,%p)\n", iface
, cbSizePatterns
, pPatterns
, pcPatterns
, pcbPatternsActual
);
437 if (!pcPatterns
|| !pcbPatternsActual
) return E_INVALIDARG
;
439 *pcPatterns
= This
->pattern_count
;
440 *pcbPatternsActual
= This
->patterns_size
;
443 if (This
->patterns_size
&& cbSizePatterns
< This
->patterns_size
)
444 return WINCODEC_ERR_INSUFFICIENTBUFFER
;
445 memcpy(pPatterns
, This
->patterns
, This
->patterns_size
);
450 static HRESULT WINAPI
BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo
*iface
,
451 IStream
*pIStream
, BOOL
*pfMatches
)
453 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
460 LARGE_INTEGER seekpos
;
462 TRACE("(%p,%p,%p)\n", iface
, pIStream
, pfMatches
);
464 for (i
=0; i
< This
->pattern_count
; i
++)
466 if (datasize
< This
->patterns
[i
].Length
)
468 HeapFree(GetProcessHeap(), 0, data
);
469 datasize
= This
->patterns
[i
].Length
;
470 data
= HeapAlloc(GetProcessHeap(), 0, This
->patterns
[i
].Length
);
478 if (This
->patterns
[i
].EndOfStream
)
479 seekpos
.QuadPart
= -This
->patterns
[i
].Position
.QuadPart
;
481 seekpos
.QuadPart
= This
->patterns
[i
].Position
.QuadPart
;
482 hr
= IStream_Seek(pIStream
, seekpos
, This
->patterns
[i
].EndOfStream
? STREAM_SEEK_END
: STREAM_SEEK_SET
, NULL
);
483 if (hr
== STG_E_INVALIDFUNCTION
) continue; /* before start of stream */
484 if (FAILED(hr
)) break;
486 hr
= IStream_Read(pIStream
, data
, This
->patterns
[i
].Length
, &bytesread
);
487 if (hr
== S_FALSE
|| (hr
== S_OK
&& bytesread
!= This
->patterns
[i
].Length
)) /* past end of stream */
489 if (FAILED(hr
)) break;
491 for (pos
=0; pos
< This
->patterns
[i
].Length
; pos
++)
493 if ((data
[pos
] & This
->patterns
[i
].Mask
[pos
]) != This
->patterns
[i
].Pattern
[pos
])
496 if (pos
== This
->patterns
[i
].Length
) /* matches pattern */
504 if (i
== This
->pattern_count
) /* does not match any pattern */
510 HeapFree(GetProcessHeap(), 0, data
);
514 static HRESULT WINAPI
BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo
*iface
,
515 IWICBitmapDecoder
**ppIBitmapDecoder
)
517 BitmapDecoderInfo
*This
= impl_from_IWICBitmapDecoderInfo(iface
);
519 TRACE("(%p,%p)\n", iface
, ppIBitmapDecoder
);
521 return create_instance(&This
->base
.clsid
, &IID_IWICBitmapDecoder
, (void**)ppIBitmapDecoder
);
524 static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl
= {
525 BitmapDecoderInfo_QueryInterface
,
526 BitmapDecoderInfo_AddRef
,
527 BitmapDecoderInfo_Release
,
528 BitmapDecoderInfo_GetComponentType
,
529 BitmapDecoderInfo_GetCLSID
,
530 BitmapDecoderInfo_GetSigningStatus
,
531 BitmapDecoderInfo_GetAuthor
,
532 BitmapDecoderInfo_GetVendorGUID
,
533 BitmapDecoderInfo_GetVersion
,
534 BitmapDecoderInfo_GetSpecVersion
,
535 BitmapDecoderInfo_GetFriendlyName
,
536 BitmapDecoderInfo_GetContainerFormat
,
537 BitmapDecoderInfo_GetPixelFormats
,
538 BitmapDecoderInfo_GetColorManagementVersion
,
539 BitmapDecoderInfo_GetDeviceManufacturer
,
540 BitmapDecoderInfo_GetDeviceModels
,
541 BitmapDecoderInfo_GetMimeTypes
,
542 BitmapDecoderInfo_GetFileExtensions
,
543 BitmapDecoderInfo_DoesSupportAnimation
,
544 BitmapDecoderInfo_DoesSupportChromaKey
,
545 BitmapDecoderInfo_DoesSupportLossless
,
546 BitmapDecoderInfo_DoesSupportMultiframe
,
547 BitmapDecoderInfo_MatchesMimeType
,
548 BitmapDecoderInfo_GetPatterns
,
549 BitmapDecoderInfo_MatchesPattern
,
550 BitmapDecoderInfo_CreateInstance
553 static void read_bitmap_patterns(BitmapDecoderInfo
*info
)
555 DWORD pattern_count
=0;
556 UINT patterns_size
=0;
557 WCHAR subkeyname
[11];
559 HKEY patternskey
, patternkey
;
561 WICBitmapPattern
*patterns
;
563 DWORD length
, valuesize
;
565 res
= RegOpenKeyExW(info
->classkey
, L
"Patterns", 0, KEY_READ
, &patternskey
);
566 if (res
!= ERROR_SUCCESS
) return;
568 res
= RegQueryInfoKeyW(patternskey
, NULL
, NULL
, NULL
, &pattern_count
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
569 if (res
!= ERROR_SUCCESS
)
571 RegCloseKey(patternskey
);
575 patterns_size
= pattern_count
* sizeof(WICBitmapPattern
);
576 patterns
= heap_alloc(patterns_size
);
579 RegCloseKey(patternskey
);
583 for (i
=0; res
== ERROR_SUCCESS
&& i
< pattern_count
; i
++)
585 swprintf(subkeyname
, 11, L
"%u", i
);
586 res
= RegOpenKeyExW(patternskey
, subkeyname
, 0, KEY_READ
, &patternkey
);
587 if (res
!= ERROR_SUCCESS
) break;
589 valuesize
= sizeof(ULONG
);
590 res
= RegGetValueW(patternkey
, NULL
, L
"Length", RRF_RT_DWORD
, NULL
, &length
, &valuesize
);
591 if (res
== ERROR_SUCCESS
)
593 patterns_size
+= length
*2;
594 patterns
[i
].Length
= length
;
596 valuesize
= sizeof(BOOL
);
597 res
= RegGetValueW(patternkey
, NULL
, L
"EndOfStream", RRF_RT_DWORD
, NULL
,
598 &patterns
[i
].EndOfStream
, &valuesize
);
599 if (res
) patterns
[i
].EndOfStream
= 0;
601 patterns
[i
].Position
.QuadPart
= 0;
602 valuesize
= sizeof(ULARGE_INTEGER
);
603 res
= RegGetValueW(patternkey
, NULL
, L
"Position", RRF_RT_DWORD
|RRF_RT_QWORD
, NULL
,
604 &patterns
[i
].Position
, &valuesize
);
607 RegCloseKey(patternkey
);
610 if (res
!= ERROR_SUCCESS
|| !(patterns_ptr
= heap_realloc(patterns
, patterns_size
)))
613 RegCloseKey(patternskey
);
616 patterns
= (WICBitmapPattern
*)patterns_ptr
;
617 patterns_ptr
+= pattern_count
* sizeof(*patterns
);
619 for (i
=0; res
== ERROR_SUCCESS
&& i
< pattern_count
; i
++)
621 swprintf(subkeyname
, 11, L
"%u", i
);
622 res
= RegOpenKeyExW(patternskey
, subkeyname
, 0, KEY_READ
, &patternkey
);
623 if (res
!= ERROR_SUCCESS
) break;
625 length
= patterns
[i
].Length
;
626 patterns
[i
].Pattern
= patterns_ptr
;
628 res
= RegGetValueW(patternkey
, NULL
, L
"Pattern", RRF_RT_REG_BINARY
, NULL
,
629 patterns
[i
].Pattern
, &valuesize
);
630 patterns_ptr
+= length
;
632 if (res
== ERROR_SUCCESS
)
634 patterns
[i
].Mask
= patterns_ptr
;
636 res
= RegGetValueW(patternkey
, NULL
, L
"Mask", RRF_RT_REG_BINARY
, NULL
,
637 patterns
[i
].Mask
, &valuesize
);
638 patterns_ptr
+= length
;
641 RegCloseKey(patternkey
);
644 RegCloseKey(patternskey
);
646 if (res
!= ERROR_SUCCESS
)
652 info
->pattern_count
= pattern_count
;
653 info
->patterns_size
= patterns_size
;
654 info
->patterns
= patterns
;
657 static HRESULT
BitmapDecoderInfo_Constructor(HKEY classkey
, REFCLSID clsid
, ComponentInfo
**ret
)
659 BitmapDecoderInfo
*This
;
661 This
= heap_alloc_zero(sizeof(BitmapDecoderInfo
));
664 RegCloseKey(classkey
);
665 return E_OUTOFMEMORY
;
668 This
->base
.IWICComponentInfo_iface
.lpVtbl
= (const IWICComponentInfoVtbl
*)&BitmapDecoderInfo_Vtbl
;
670 This
->classkey
= classkey
;
671 This
->base
.clsid
= *clsid
;
673 read_bitmap_patterns(This
);
684 static inline BitmapEncoderInfo
*impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo
*iface
)
686 return CONTAINING_RECORD(iface
, BitmapEncoderInfo
, base
.IWICComponentInfo_iface
);
689 static HRESULT WINAPI
BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo
*iface
, REFIID iid
,
692 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
693 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
695 if (!ppv
) return E_INVALIDARG
;
697 if (IsEqualIID(&IID_IUnknown
, iid
) ||
698 IsEqualIID(&IID_IWICComponentInfo
, iid
) ||
699 IsEqualIID(&IID_IWICBitmapCodecInfo
, iid
) ||
700 IsEqualIID(&IID_IWICBitmapEncoderInfo
,iid
))
702 *ppv
= &This
->base
.IWICComponentInfo_iface
;
707 return E_NOINTERFACE
;
710 IUnknown_AddRef((IUnknown
*)*ppv
);
714 static ULONG WINAPI
BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo
*iface
)
716 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
717 ULONG ref
= InterlockedIncrement(&This
->base
.ref
);
719 TRACE("(%p) refcount=%lu\n", iface
, ref
);
724 static ULONG WINAPI
BitmapEncoderInfo_Release(IWICBitmapEncoderInfo
*iface
)
726 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
727 ULONG ref
= InterlockedDecrement(&This
->base
.ref
);
729 TRACE("(%p) refcount=%lu\n", iface
, ref
);
733 RegCloseKey(This
->classkey
);
734 HeapFree(GetProcessHeap(), 0, This
);
740 static HRESULT WINAPI
BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo
*iface
,
741 WICComponentType
*pType
)
743 TRACE("(%p,%p)\n", iface
, pType
);
744 if (!pType
) return E_INVALIDARG
;
749 static HRESULT WINAPI
BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo
*iface
, CLSID
*pclsid
)
751 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
752 TRACE("(%p,%p)\n", iface
, pclsid
);
757 *pclsid
= This
->base
.clsid
;
761 static HRESULT WINAPI
BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo
*iface
, DWORD
*pStatus
)
763 FIXME("(%p,%p): stub\n", iface
, pStatus
);
767 static HRESULT WINAPI
BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo
*iface
, UINT cchAuthor
,
768 WCHAR
*wzAuthor
, UINT
*pcchActual
)
770 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
772 TRACE("(%p,%u,%p,%p)\n", iface
, cchAuthor
, wzAuthor
, pcchActual
);
774 return ComponentInfo_GetStringValue(This
->classkey
, L
"Author", cchAuthor
, wzAuthor
, pcchActual
);
777 static HRESULT WINAPI
BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo
*iface
, GUID
*pguidVendor
)
779 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
781 TRACE("(%p,%p)\n", iface
, pguidVendor
);
783 return ComponentInfo_GetGUIDValue(This
->classkey
, L
"Vendor", pguidVendor
);
786 static HRESULT WINAPI
BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo
*iface
, UINT cchVersion
,
787 WCHAR
*wzVersion
, UINT
*pcchActual
)
789 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
791 TRACE("(%p,%u,%p,%p)\n", iface
, cchVersion
, wzVersion
, pcchActual
);
793 return ComponentInfo_GetStringValue(This
->classkey
, L
"Version",
794 cchVersion
, wzVersion
, pcchActual
);
797 static HRESULT WINAPI
BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo
*iface
, UINT cchSpecVersion
,
798 WCHAR
*wzSpecVersion
, UINT
*pcchActual
)
800 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
802 TRACE("(%p,%u,%p,%p)\n", iface
, cchSpecVersion
, wzSpecVersion
, pcchActual
);
804 return ComponentInfo_GetStringValue(This
->classkey
, L
"SpecVersion",
805 cchSpecVersion
, wzSpecVersion
, pcchActual
);
808 static HRESULT WINAPI
BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo
*iface
, UINT cchFriendlyName
,
809 WCHAR
*wzFriendlyName
, UINT
*pcchActual
)
811 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
813 TRACE("(%p,%u,%p,%p)\n", iface
, cchFriendlyName
, wzFriendlyName
, pcchActual
);
815 return ComponentInfo_GetStringValue(This
->classkey
, L
"FriendlyName",
816 cchFriendlyName
, wzFriendlyName
, pcchActual
);
819 static HRESULT WINAPI
BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo
*iface
,
820 GUID
*pguidContainerFormat
)
822 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
823 TRACE("(%p,%p)\n", iface
, pguidContainerFormat
);
824 return ComponentInfo_GetGUIDValue(This
->classkey
, L
"ContainerFormat", pguidContainerFormat
);
827 static HRESULT WINAPI
BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo
*iface
,
828 UINT cFormats
, GUID
*pguidPixelFormats
, UINT
*pcActual
)
830 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
831 TRACE("(%p,%u,%p,%p)\n", iface
, cFormats
, pguidPixelFormats
, pcActual
);
832 return ComponentInfo_GetGuidList(This
->classkey
, L
"Formats", cFormats
, pguidPixelFormats
, pcActual
);
835 static HRESULT WINAPI
BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo
*iface
,
836 UINT cchColorManagementVersion
, WCHAR
*wzColorManagementVersion
, UINT
*pcchActual
)
838 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchColorManagementVersion
, wzColorManagementVersion
, pcchActual
);
842 static HRESULT WINAPI
BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo
*iface
,
843 UINT cchDeviceManufacturer
, WCHAR
*wzDeviceManufacturer
, UINT
*pcchActual
)
845 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchDeviceManufacturer
, wzDeviceManufacturer
, pcchActual
);
849 static HRESULT WINAPI
BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo
*iface
,
850 UINT cchDeviceModels
, WCHAR
*wzDeviceModels
, UINT
*pcchActual
)
852 FIXME("(%p,%u,%p,%p): stub\n", iface
, cchDeviceModels
, wzDeviceModels
, pcchActual
);
856 static HRESULT WINAPI
BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo
*iface
,
857 UINT cchMimeTypes
, WCHAR
*wzMimeTypes
, UINT
*pcchActual
)
859 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
861 TRACE("(%p,%u,%p,%p)\n", iface
, cchMimeTypes
, wzMimeTypes
, pcchActual
);
863 return ComponentInfo_GetStringValue(This
->classkey
, L
"MimeTypes",
864 cchMimeTypes
, wzMimeTypes
, pcchActual
);
867 static HRESULT WINAPI
BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo
*iface
,
868 UINT cchFileExtensions
, WCHAR
*wzFileExtensions
, UINT
*pcchActual
)
870 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
872 TRACE("(%p,%u,%p,%p)\n", iface
, cchFileExtensions
, wzFileExtensions
, pcchActual
);
874 return ComponentInfo_GetStringValue(This
->classkey
, L
"FileExtensions",
875 cchFileExtensions
, wzFileExtensions
, pcchActual
);
878 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo
*iface
,
879 BOOL
*pfSupportAnimation
)
881 FIXME("(%p,%p): stub\n", iface
, pfSupportAnimation
);
885 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo
*iface
,
886 BOOL
*pfSupportChromaKey
)
888 FIXME("(%p,%p): stub\n", iface
, pfSupportChromaKey
);
892 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo
*iface
,
893 BOOL
*pfSupportLossless
)
895 FIXME("(%p,%p): stub\n", iface
, pfSupportLossless
);
899 static HRESULT WINAPI
BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo
*iface
,
900 BOOL
*pfSupportMultiframe
)
902 FIXME("(%p,%p): stub\n", iface
, pfSupportMultiframe
);
906 static HRESULT WINAPI
BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo
*iface
,
907 LPCWSTR wzMimeType
, BOOL
*pfMatches
)
909 FIXME("(%p,%s,%p): stub\n", iface
, debugstr_w(wzMimeType
), pfMatches
);
913 static HRESULT WINAPI
BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo
*iface
,
914 IWICBitmapEncoder
**ppIBitmapEncoder
)
916 BitmapEncoderInfo
*This
= impl_from_IWICBitmapEncoderInfo(iface
);
918 TRACE("(%p,%p)\n", iface
, ppIBitmapEncoder
);
920 return create_instance(&This
->base
.clsid
, &IID_IWICBitmapEncoder
, (void**)ppIBitmapEncoder
);
923 static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl
= {
924 BitmapEncoderInfo_QueryInterface
,
925 BitmapEncoderInfo_AddRef
,
926 BitmapEncoderInfo_Release
,
927 BitmapEncoderInfo_GetComponentType
,
928 BitmapEncoderInfo_GetCLSID
,
929 BitmapEncoderInfo_GetSigningStatus
,
930 BitmapEncoderInfo_GetAuthor
,
931 BitmapEncoderInfo_GetVendorGUID
,
932 BitmapEncoderInfo_GetVersion
,
933 BitmapEncoderInfo_GetSpecVersion
,
934 BitmapEncoderInfo_GetFriendlyName
,
935 BitmapEncoderInfo_GetContainerFormat
,
936 BitmapEncoderInfo_GetPixelFormats
,
937 BitmapEncoderInfo_GetColorManagementVersion
,
938 BitmapEncoderInfo_GetDeviceManufacturer
,
939 BitmapEncoderInfo_GetDeviceModels
,
940 BitmapEncoderInfo_GetMimeTypes
,
941 BitmapEncoderInfo_GetFileExtensions
,
942 BitmapEncoderInfo_DoesSupportAnimation
,
943 BitmapEncoderInfo_DoesSupportChromaKey
,
944 BitmapEncoderInfo_DoesSupportLossless
,
945 BitmapEncoderInfo_DoesSupportMultiframe
,
946 BitmapEncoderInfo_MatchesMimeType
,
947 BitmapEncoderInfo_CreateInstance
950 static HRESULT
BitmapEncoderInfo_Constructor(HKEY classkey
, REFCLSID clsid
, ComponentInfo
**ret
)
952 BitmapEncoderInfo
*This
;
954 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo
));
957 RegCloseKey(classkey
);
958 return E_OUTOFMEMORY
;
961 This
->base
.IWICComponentInfo_iface
.lpVtbl
= (const IWICComponentInfoVtbl
*)&BitmapEncoderInfo_Vtbl
;
963 This
->classkey
= classkey
;
964 This
->base
.clsid
= *clsid
;
973 } FormatConverterInfo
;
975 static inline FormatConverterInfo
*impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo
*iface
)
977 return CONTAINING_RECORD(iface
, FormatConverterInfo
, base
.IWICComponentInfo_iface
);
980 static HRESULT WINAPI
FormatConverterInfo_QueryInterface(IWICFormatConverterInfo
*iface
, REFIID iid
,
983 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
984 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
986 if (!ppv
) return E_INVALIDARG
;
988 if (IsEqualIID(&IID_IUnknown
, iid
) ||
989 IsEqualIID(&IID_IWICComponentInfo
, iid
) ||
990 IsEqualIID(&IID_IWICFormatConverterInfo
,iid
))
992 *ppv
= &This
->base
.IWICComponentInfo_iface
;
997 return E_NOINTERFACE
;
1000 IUnknown_AddRef((IUnknown
*)*ppv
);
1004 static ULONG WINAPI
FormatConverterInfo_AddRef(IWICFormatConverterInfo
*iface
)
1006 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1007 ULONG ref
= InterlockedIncrement(&This
->base
.ref
);
1009 TRACE("(%p) refcount=%lu\n", iface
, ref
);
1014 static ULONG WINAPI
FormatConverterInfo_Release(IWICFormatConverterInfo
*iface
)
1016 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1017 ULONG ref
= InterlockedDecrement(&This
->base
.ref
);
1019 TRACE("(%p) refcount=%lu\n", iface
, ref
);
1023 RegCloseKey(This
->classkey
);
1024 HeapFree(GetProcessHeap(), 0, This
);
1030 static HRESULT WINAPI
FormatConverterInfo_GetComponentType(IWICFormatConverterInfo
*iface
,
1031 WICComponentType
*pType
)
1033 TRACE("(%p,%p)\n", iface
, pType
);
1034 if (!pType
) return E_INVALIDARG
;
1035 *pType
= WICPixelFormatConverter
;
1039 static HRESULT WINAPI
FormatConverterInfo_GetCLSID(IWICFormatConverterInfo
*iface
, CLSID
*pclsid
)
1041 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1042 TRACE("(%p,%p)\n", iface
, pclsid
);
1045 return E_INVALIDARG
;
1047 *pclsid
= This
->base
.clsid
;
1051 static HRESULT WINAPI
FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo
*iface
, DWORD
*pStatus
)
1053 FIXME("(%p,%p): stub\n", iface
, pStatus
);
1057 static HRESULT WINAPI
FormatConverterInfo_GetAuthor(IWICFormatConverterInfo
*iface
, UINT cchAuthor
,
1058 WCHAR
*wzAuthor
, UINT
*pcchActual
)
1060 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1062 TRACE("(%p,%u,%p,%p)\n", iface
, cchAuthor
, wzAuthor
, pcchActual
);
1064 return ComponentInfo_GetStringValue(This
->classkey
, L
"Author", cchAuthor
, wzAuthor
, pcchActual
);
1067 static HRESULT WINAPI
FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo
*iface
, GUID
*pguidVendor
)
1069 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1071 TRACE("(%p,%p)\n", iface
, pguidVendor
);
1073 return ComponentInfo_GetGUIDValue(This
->classkey
, L
"Vendor", pguidVendor
);
1076 static HRESULT WINAPI
FormatConverterInfo_GetVersion(IWICFormatConverterInfo
*iface
, UINT cchVersion
,
1077 WCHAR
*wzVersion
, UINT
*pcchActual
)
1079 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1081 TRACE("(%p,%u,%p,%p)\n", iface
, cchVersion
, wzVersion
, pcchActual
);
1083 return ComponentInfo_GetStringValue(This
->classkey
, L
"Version",
1084 cchVersion
, wzVersion
, pcchActual
);
1087 static HRESULT WINAPI
FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo
*iface
, UINT cchSpecVersion
,
1088 WCHAR
*wzSpecVersion
, UINT
*pcchActual
)
1090 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1092 TRACE("(%p,%u,%p,%p)\n", iface
, cchSpecVersion
, wzSpecVersion
, pcchActual
);
1094 return ComponentInfo_GetStringValue(This
->classkey
, L
"SpecVersion",
1095 cchSpecVersion
, wzSpecVersion
, pcchActual
);
1098 static HRESULT WINAPI
FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo
*iface
, UINT cchFriendlyName
,
1099 WCHAR
*wzFriendlyName
, UINT
*pcchActual
)
1101 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1103 TRACE("(%p,%u,%p,%p)\n", iface
, cchFriendlyName
, wzFriendlyName
, pcchActual
);
1105 return ComponentInfo_GetStringValue(This
->classkey
, L
"FriendlyName",
1106 cchFriendlyName
, wzFriendlyName
, pcchActual
);
1109 static HRESULT WINAPI
FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo
*iface
,
1110 UINT cFormats
, GUID
*pguidPixelFormats
, UINT
*pcActual
)
1112 FIXME("(%p,%u,%p,%p): stub\n", iface
, cFormats
, pguidPixelFormats
, pcActual
);
1116 static HRESULT WINAPI
FormatConverterInfo_CreateInstance(IWICFormatConverterInfo
*iface
,
1117 IWICFormatConverter
**ppIFormatConverter
)
1119 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1121 TRACE("(%p,%p)\n", iface
, ppIFormatConverter
);
1123 return create_instance(&This
->base
.clsid
, &IID_IWICFormatConverter
,
1124 (void**)ppIFormatConverter
);
1127 static BOOL
ConverterSupportsFormat(IWICFormatConverterInfo
*iface
, const WCHAR
*formatguid
)
1130 FormatConverterInfo
*This
= impl_from_IWICFormatConverterInfo(iface
);
1131 HKEY formats_key
, guid_key
;
1133 /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
1134 would be O(n). A registry test should do better. */
1136 res
= RegOpenKeyExW(This
->classkey
, L
"PixelFormats", 0, KEY_READ
, &formats_key
);
1137 if (res
!= ERROR_SUCCESS
) return FALSE
;
1139 res
= RegOpenKeyExW(formats_key
, formatguid
, 0, KEY_READ
, &guid_key
);
1140 if (res
== ERROR_SUCCESS
) RegCloseKey(guid_key
);
1142 RegCloseKey(formats_key
);
1144 return (res
== ERROR_SUCCESS
);
1147 static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl
= {
1148 FormatConverterInfo_QueryInterface
,
1149 FormatConverterInfo_AddRef
,
1150 FormatConverterInfo_Release
,
1151 FormatConverterInfo_GetComponentType
,
1152 FormatConverterInfo_GetCLSID
,
1153 FormatConverterInfo_GetSigningStatus
,
1154 FormatConverterInfo_GetAuthor
,
1155 FormatConverterInfo_GetVendorGUID
,
1156 FormatConverterInfo_GetVersion
,
1157 FormatConverterInfo_GetSpecVersion
,
1158 FormatConverterInfo_GetFriendlyName
,
1159 FormatConverterInfo_GetPixelFormats
,
1160 FormatConverterInfo_CreateInstance
1163 static HRESULT
FormatConverterInfo_Constructor(HKEY classkey
, REFCLSID clsid
, ComponentInfo
**ret
)
1165 FormatConverterInfo
*This
;
1167 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo
));
1170 RegCloseKey(classkey
);
1171 return E_OUTOFMEMORY
;
1174 This
->base
.IWICComponentInfo_iface
.lpVtbl
= (const IWICComponentInfoVtbl
*)&FormatConverterInfo_Vtbl
;
1176 This
->classkey
= classkey
;
1177 This
->base
.clsid
= *clsid
;
1188 static inline PixelFormatInfo
*impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2
*iface
)
1190 return CONTAINING_RECORD(iface
, PixelFormatInfo
, base
.IWICComponentInfo_iface
);
1193 static HRESULT WINAPI
PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2
*iface
, REFIID iid
,
1196 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1197 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
1199 if (!ppv
) return E_INVALIDARG
;
1201 if (IsEqualIID(&IID_IUnknown
, iid
) ||
1202 IsEqualIID(&IID_IWICComponentInfo
, iid
) ||
1203 IsEqualIID(&IID_IWICPixelFormatInfo
, iid
) ||
1204 IsEqualIID(&IID_IWICPixelFormatInfo2
,iid
))
1206 *ppv
= &This
->base
.IWICComponentInfo_iface
;
1211 return E_NOINTERFACE
;
1214 IUnknown_AddRef((IUnknown
*)*ppv
);
1218 static ULONG WINAPI
PixelFormatInfo_AddRef(IWICPixelFormatInfo2
*iface
)
1220 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1221 ULONG ref
= InterlockedIncrement(&This
->base
.ref
);
1223 TRACE("(%p) refcount=%lu\n", iface
, ref
);
1228 static ULONG WINAPI
PixelFormatInfo_Release(IWICPixelFormatInfo2
*iface
)
1230 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1231 ULONG ref
= InterlockedDecrement(&This
->base
.ref
);
1233 TRACE("(%p) refcount=%lu\n", iface
, ref
);
1237 RegCloseKey(This
->classkey
);
1238 HeapFree(GetProcessHeap(), 0, This
);
1244 static HRESULT WINAPI
PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2
*iface
,
1245 WICComponentType
*pType
)
1247 TRACE("(%p,%p)\n", iface
, pType
);
1248 if (!pType
) return E_INVALIDARG
;
1249 *pType
= WICPixelFormat
;
1253 static HRESULT WINAPI
PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2
*iface
, CLSID
*pclsid
)
1255 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1256 TRACE("(%p,%p)\n", iface
, pclsid
);
1259 return E_INVALIDARG
;
1261 *pclsid
= This
->base
.clsid
;
1265 static HRESULT WINAPI
PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2
*iface
, DWORD
*pStatus
)
1267 TRACE("(%p,%p)\n", iface
, pStatus
);
1270 return E_INVALIDARG
;
1272 /* Pixel formats don't require code, so they are considered signed. */
1273 *pStatus
= WICComponentSigned
;
1278 static HRESULT WINAPI
PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2
*iface
, UINT cchAuthor
,
1279 WCHAR
*wzAuthor
, UINT
*pcchActual
)
1281 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1283 TRACE("(%p,%u,%p,%p)\n", iface
, cchAuthor
, wzAuthor
, pcchActual
);
1285 return ComponentInfo_GetStringValue(This
->classkey
, L
"Author", cchAuthor
, wzAuthor
, pcchActual
);
1288 static HRESULT WINAPI
PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2
*iface
, GUID
*pguidVendor
)
1290 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1292 TRACE("(%p,%p)\n", iface
, pguidVendor
);
1294 return ComponentInfo_GetGUIDValue(This
->classkey
, L
"Vendor", pguidVendor
);
1297 static HRESULT WINAPI
PixelFormatInfo_GetVersion(IWICPixelFormatInfo2
*iface
, UINT cchVersion
,
1298 WCHAR
*wzVersion
, UINT
*pcchActual
)
1300 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1302 TRACE("(%p,%u,%p,%p)\n", iface
, cchVersion
, wzVersion
, pcchActual
);
1304 return ComponentInfo_GetStringValue(This
->classkey
, L
"Version",
1305 cchVersion
, wzVersion
, pcchActual
);
1308 static HRESULT WINAPI
PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2
*iface
, UINT cchSpecVersion
,
1309 WCHAR
*wzSpecVersion
, UINT
*pcchActual
)
1311 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1313 TRACE("(%p,%u,%p,%p)\n", iface
, cchSpecVersion
, wzSpecVersion
, pcchActual
);
1315 return ComponentInfo_GetStringValue(This
->classkey
, L
"SpecVersion",
1316 cchSpecVersion
, wzSpecVersion
, pcchActual
);
1319 static HRESULT WINAPI
PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2
*iface
, UINT cchFriendlyName
,
1320 WCHAR
*wzFriendlyName
, UINT
*pcchActual
)
1322 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1324 TRACE("(%p,%u,%p,%p)\n", iface
, cchFriendlyName
, wzFriendlyName
, pcchActual
);
1326 return ComponentInfo_GetStringValue(This
->classkey
, L
"FriendlyName",
1327 cchFriendlyName
, wzFriendlyName
, pcchActual
);
1330 static HRESULT WINAPI
PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2
*iface
,
1333 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1334 TRACE("(%p,%p)\n", iface
, pFormat
);
1337 return E_INVALIDARG
;
1339 *pFormat
= This
->base
.clsid
;
1343 static HRESULT WINAPI
PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2
*iface
,
1344 IWICColorContext
**ppIColorContext
)
1346 FIXME("(%p,%p): stub\n", iface
, ppIColorContext
);
1350 static HRESULT WINAPI
PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2
*iface
,
1351 UINT
*puiBitsPerPixel
)
1353 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1355 TRACE("(%p,%p)\n", iface
, puiBitsPerPixel
);
1357 return ComponentInfo_GetUINTValue(This
->classkey
, L
"BitLength", puiBitsPerPixel
);
1360 static HRESULT WINAPI
PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2
*iface
,
1361 UINT
*puiChannelCount
)
1363 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1365 TRACE("(%p,%p)\n", iface
, puiChannelCount
);
1367 return ComponentInfo_GetUINTValue(This
->classkey
, L
"ChannelCount", puiChannelCount
);
1370 static HRESULT WINAPI
PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2
*iface
,
1371 UINT uiChannelIndex
, UINT cbMaskBuffer
, BYTE
*pbMaskBuffer
, UINT
*pcbActual
)
1373 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1377 WCHAR valuename
[11];
1380 TRACE("(%p,%u,%u,%p,%p)\n", iface
, uiChannelIndex
, cbMaskBuffer
, pbMaskBuffer
, pcbActual
);
1383 return E_INVALIDARG
;
1385 hr
= PixelFormatInfo_GetChannelCount(iface
, &channel_count
);
1387 if (SUCCEEDED(hr
) && uiChannelIndex
>= channel_count
)
1392 swprintf(valuename
, 11, L
"%u", uiChannelIndex
);
1394 cbData
= cbMaskBuffer
;
1396 ret
= RegGetValueW(This
->classkey
, L
"ChannelMasks", valuename
, RRF_RT_REG_BINARY
, NULL
, pbMaskBuffer
, &cbData
);
1398 if (ret
== ERROR_SUCCESS
|| ret
== ERROR_MORE_DATA
)
1399 *pcbActual
= cbData
;
1401 if (ret
== ERROR_MORE_DATA
)
1404 hr
= HRESULT_FROM_WIN32(ret
);
1410 static HRESULT WINAPI
PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2
*iface
,
1411 BOOL
*pfSupportsTransparency
)
1413 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1415 TRACE("(%p,%p)\n", iface
, pfSupportsTransparency
);
1417 return ComponentInfo_GetUINTValue(This
->classkey
, L
"SupportsTransparency", (UINT
*)pfSupportsTransparency
);
1420 static HRESULT WINAPI
PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2
*iface
,
1421 WICPixelFormatNumericRepresentation
*pNumericRepresentation
)
1423 PixelFormatInfo
*This
= impl_from_IWICPixelFormatInfo2(iface
);
1425 TRACE("(%p,%p)\n", iface
, pNumericRepresentation
);
1427 return ComponentInfo_GetUINTValue(This
->classkey
, L
"NumericRepresentation", pNumericRepresentation
);
1430 static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl
= {
1431 PixelFormatInfo_QueryInterface
,
1432 PixelFormatInfo_AddRef
,
1433 PixelFormatInfo_Release
,
1434 PixelFormatInfo_GetComponentType
,
1435 PixelFormatInfo_GetCLSID
,
1436 PixelFormatInfo_GetSigningStatus
,
1437 PixelFormatInfo_GetAuthor
,
1438 PixelFormatInfo_GetVendorGUID
,
1439 PixelFormatInfo_GetVersion
,
1440 PixelFormatInfo_GetSpecVersion
,
1441 PixelFormatInfo_GetFriendlyName
,
1442 PixelFormatInfo_GetFormatGUID
,
1443 PixelFormatInfo_GetColorContext
,
1444 PixelFormatInfo_GetBitsPerPixel
,
1445 PixelFormatInfo_GetChannelCount
,
1446 PixelFormatInfo_GetChannelMask
,
1447 PixelFormatInfo_SupportsTransparency
,
1448 PixelFormatInfo_GetNumericRepresentation
1451 static HRESULT
PixelFormatInfo_Constructor(HKEY classkey
, REFCLSID clsid
, ComponentInfo
**ret
)
1453 PixelFormatInfo
*This
;
1455 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo
));
1458 RegCloseKey(classkey
);
1459 return E_OUTOFMEMORY
;
1462 This
->base
.IWICComponentInfo_iface
.lpVtbl
= (const IWICComponentInfoVtbl
*)&PixelFormatInfo_Vtbl
;
1464 This
->classkey
= classkey
;
1465 This
->base
.clsid
= *clsid
;
1471 struct metadata_container
1473 WICMetadataPattern
*patterns
;
1482 GUID
*container_formats
;
1483 struct metadata_container
*containers
;
1484 UINT container_count
;
1485 } MetadataReaderInfo
;
1487 static struct metadata_container
*get_metadata_container(MetadataReaderInfo
*info
, const GUID
*guid
)
1491 for (i
= 0; i
< info
->container_count
; i
++)
1492 if (IsEqualGUID(info
->container_formats
+ i
, guid
))
1493 return info
->containers
+ i
;
1498 static inline MetadataReaderInfo
*impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo
*iface
)
1500 return CONTAINING_RECORD(iface
, MetadataReaderInfo
, base
.IWICComponentInfo_iface
);
1503 static HRESULT WINAPI
MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo
*iface
,
1504 REFIID riid
, void **ppv
)
1506 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1508 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppv
);
1510 if (!ppv
) return E_INVALIDARG
;
1512 if (IsEqualIID(&IID_IUnknown
, riid
) ||
1513 IsEqualIID(&IID_IWICComponentInfo
, riid
) ||
1514 IsEqualIID(&IID_IWICMetadataHandlerInfo
, riid
) ||
1515 IsEqualIID(&IID_IWICMetadataReaderInfo
, riid
))
1517 *ppv
= &This
->base
.IWICComponentInfo_iface
;
1522 return E_NOINTERFACE
;
1525 IUnknown_AddRef((IUnknown
*)*ppv
);
1529 static ULONG WINAPI
MetadataReaderInfo_AddRef(IWICMetadataReaderInfo
*iface
)
1531 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1532 ULONG ref
= InterlockedIncrement(&This
->base
.ref
);
1534 TRACE("(%p) refcount=%lu\n", iface
, ref
);
1538 static ULONG WINAPI
MetadataReaderInfo_Release(IWICMetadataReaderInfo
*iface
)
1540 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1541 ULONG ref
= InterlockedDecrement(&This
->base
.ref
);
1543 TRACE("(%p) refcount=%lu\n", iface
, ref
);
1548 RegCloseKey(This
->classkey
);
1549 for (i
= 0; i
< This
->container_count
; i
++)
1550 heap_free(This
->containers
[i
].patterns
);
1551 heap_free(This
->containers
);
1552 heap_free(This
->container_formats
);
1553 HeapFree(GetProcessHeap(), 0, This
);
1558 static HRESULT WINAPI
MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo
*iface
,
1559 WICComponentType
*type
)
1561 TRACE("(%p,%p)\n", iface
, type
);
1563 if (!type
) return E_INVALIDARG
;
1564 *type
= WICMetadataReader
;
1568 static HRESULT WINAPI
MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo
*iface
,
1571 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1573 TRACE("(%p,%p)\n", iface
, clsid
);
1575 if (!clsid
) return E_INVALIDARG
;
1576 *clsid
= This
->base
.clsid
;
1580 static HRESULT WINAPI
MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo
*iface
,
1583 FIXME("(%p,%p): stub\n", iface
, status
);
1587 static HRESULT WINAPI
MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo
*iface
,
1588 UINT length
, WCHAR
*author
, UINT
*actual_length
)
1590 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1592 TRACE("(%p,%u,%p,%p)\n", iface
, length
, author
, actual_length
);
1594 return ComponentInfo_GetStringValue(This
->classkey
, L
"Author", length
, author
, actual_length
);
1597 static HRESULT WINAPI
MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo
*iface
,
1600 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1602 TRACE("(%p,%p)\n", iface
, vendor
);
1604 return ComponentInfo_GetGUIDValue(This
->classkey
, L
"Vendor", vendor
);
1607 static HRESULT WINAPI
MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo
*iface
,
1608 UINT length
, WCHAR
*version
, UINT
*actual_length
)
1610 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1612 TRACE("(%p,%u,%p,%p)\n", iface
, length
, version
, actual_length
);
1614 return ComponentInfo_GetStringValue(This
->classkey
, L
"Version", length
, version
, actual_length
);
1617 static HRESULT WINAPI
MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo
*iface
,
1618 UINT length
, WCHAR
*version
, UINT
*actual_length
)
1620 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1622 TRACE("(%p,%u,%p,%p)\n", iface
, length
, version
, actual_length
);
1624 return ComponentInfo_GetStringValue(This
->classkey
, L
"SpecVersion",
1625 length
, version
, actual_length
);
1628 static HRESULT WINAPI
MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo
*iface
,
1629 UINT length
, WCHAR
*name
, UINT
*actual_length
)
1631 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1633 TRACE("(%p,%u,%p,%p)\n", iface
, length
, name
, actual_length
);
1635 return ComponentInfo_GetStringValue(This
->classkey
, L
"FriendlyName",
1636 length
, name
, actual_length
);
1639 static HRESULT WINAPI
MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo
*iface
,
1642 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1643 TRACE("(%p,%p)\n", iface
, format
);
1644 return ComponentInfo_GetGUIDValue(This
->classkey
, L
"MetadataFormat", format
);
1647 static HRESULT WINAPI
MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo
*iface
,
1648 UINT length
, GUID
*formats
, UINT
*actual_length
)
1650 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1652 TRACE("(%p,%u,%p,%p)\n", iface
, length
, formats
, actual_length
);
1655 return E_INVALIDARG
;
1657 *actual_length
= This
->container_count
;
1660 if (This
->container_count
&& length
< This
->container_count
)
1661 return WINCODEC_ERR_INSUFFICIENTBUFFER
;
1662 memcpy(formats
, This
->container_formats
, This
->container_count
* sizeof(*formats
));
1667 static HRESULT WINAPI
MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo
*iface
,
1668 UINT length
, WCHAR
*manufacturer
, UINT
*actual_length
)
1670 FIXME("(%p,%u,%p,%p): stub\n", iface
, length
, manufacturer
, actual_length
);
1674 static HRESULT WINAPI
MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo
*iface
,
1675 UINT length
, WCHAR
*models
, UINT
*actual_length
)
1677 FIXME("(%p,%u,%p,%p): stub\n", iface
, length
, models
, actual_length
);
1681 static HRESULT WINAPI
MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo
*iface
,
1684 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1685 TRACE("(%p,%p)\n", iface
, param
);
1686 return ComponentInfo_GetUINTValue(This
->classkey
, L
"RequiresFullStream", (UINT
*)param
);
1689 static HRESULT WINAPI
MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo
*iface
,
1692 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1693 TRACE("(%p,%p)\n", iface
, param
);
1694 return ComponentInfo_GetUINTValue(This
->classkey
, L
"SupportsPadding", (UINT
*)param
);
1697 static HRESULT WINAPI
MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo
*iface
,
1700 FIXME("(%p,%p): stub\n", iface
, param
);
1704 static HRESULT WINAPI
MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo
*iface
,
1705 REFGUID container_guid
, UINT length
, WICMetadataPattern
*patterns
, UINT
*count
, UINT
*actual_length
)
1707 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1708 struct metadata_container
*container
;
1710 TRACE("(%p,%s,%u,%p,%p,%p)\n", iface
, debugstr_guid(container_guid
), length
, patterns
, count
, actual_length
);
1712 if (!actual_length
|| !container_guid
) return E_INVALIDARG
;
1714 if (!(container
= get_metadata_container(This
, container_guid
)))
1715 return WINCODEC_ERR_COMPONENTNOTFOUND
;
1717 *count
= container
->pattern_count
;
1718 *actual_length
= container
->patterns_size
;
1721 if (container
->patterns_size
&& length
< container
->patterns_size
)
1722 return WINCODEC_ERR_INSUFFICIENTBUFFER
;
1723 memcpy(patterns
, container
->patterns
, container
->patterns_size
);
1728 static HRESULT WINAPI
MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo
*iface
,
1729 REFGUID container_guid
, IStream
*stream
, BOOL
*matches
)
1731 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1732 struct metadata_container
*container
;
1738 LARGE_INTEGER seekpos
;
1741 TRACE("(%p,%s,%p,%p)\n", iface
, debugstr_guid(container_guid
), stream
, matches
);
1743 if (!(container
= get_metadata_container(This
, container_guid
)))
1744 return WINCODEC_ERR_COMPONENTNOTFOUND
;
1746 for (i
=0; i
< container
->pattern_count
; i
++)
1748 if (datasize
< container
->patterns
[i
].Length
)
1750 HeapFree(GetProcessHeap(), 0, data
);
1751 datasize
= container
->patterns
[i
].Length
;
1752 data
= HeapAlloc(GetProcessHeap(), 0, container
->patterns
[i
].Length
);
1760 seekpos
.QuadPart
= container
->patterns
[i
].Position
.QuadPart
;
1761 hr
= IStream_Seek(stream
, seekpos
, STREAM_SEEK_SET
, NULL
);
1762 if (FAILED(hr
)) break;
1764 hr
= IStream_Read(stream
, data
, container
->patterns
[i
].Length
, &bytesread
);
1765 if (hr
== S_FALSE
|| (hr
== S_OK
&& bytesread
!= container
->patterns
[i
].Length
)) /* past end of stream */
1767 if (FAILED(hr
)) break;
1769 for (pos
=0; pos
< container
->patterns
[i
].Length
; pos
++)
1771 if ((data
[pos
] & container
->patterns
[i
].Mask
[pos
]) != container
->patterns
[i
].Pattern
[pos
])
1774 if (pos
== container
->patterns
[i
].Length
) /* matches pattern */
1782 if (i
== container
->pattern_count
) /* does not match any pattern */
1788 HeapFree(GetProcessHeap(), 0, data
);
1793 static HRESULT WINAPI
MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo
*iface
,
1794 IWICMetadataReader
**reader
)
1796 MetadataReaderInfo
*This
= impl_from_IWICMetadataReaderInfo(iface
);
1798 TRACE("(%p,%p)\n", iface
, reader
);
1800 return create_instance(&This
->base
.clsid
, &IID_IWICMetadataReader
, (void **)reader
);
1803 static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl
= {
1804 MetadataReaderInfo_QueryInterface
,
1805 MetadataReaderInfo_AddRef
,
1806 MetadataReaderInfo_Release
,
1807 MetadataReaderInfo_GetComponentType
,
1808 MetadataReaderInfo_GetCLSID
,
1809 MetadataReaderInfo_GetSigningStatus
,
1810 MetadataReaderInfo_GetAuthor
,
1811 MetadataReaderInfo_GetVendorGUID
,
1812 MetadataReaderInfo_GetVersion
,
1813 MetadataReaderInfo_GetSpecVersion
,
1814 MetadataReaderInfo_GetFriendlyName
,
1815 MetadataReaderInfo_GetMetadataFormat
,
1816 MetadataReaderInfo_GetContainerFormats
,
1817 MetadataReaderInfo_GetDeviceManufacturer
,
1818 MetadataReaderInfo_GetDeviceModels
,
1819 MetadataReaderInfo_DoesRequireFullStream
,
1820 MetadataReaderInfo_DoesSupportPadding
,
1821 MetadataReaderInfo_DoesRequireFixedSize
,
1822 MetadataReaderInfo_GetPatterns
,
1823 MetadataReaderInfo_MatchesPattern
,
1824 MetadataReaderInfo_CreateInstance
1827 static void read_metadata_patterns(MetadataReaderInfo
*info
, GUID
*container_guid
,
1828 struct metadata_container
*container
)
1830 DWORD pattern_count
=0;
1831 UINT patterns_size
=0;
1832 WCHAR subkeyname
[11], guidkeyname
[39];
1834 HKEY containers_key
, guid_key
, patternkey
;
1836 WICMetadataPattern
*patterns
;
1838 DWORD length
, valuesize
;
1840 res
= RegOpenKeyExW(info
->classkey
, L
"Containers", 0, KEY_READ
, &containers_key
);
1841 if (res
!= ERROR_SUCCESS
) return;
1843 StringFromGUID2(container_guid
, guidkeyname
, 39);
1844 res
= RegOpenKeyExW(containers_key
, guidkeyname
, 0, KEY_READ
, &guid_key
);
1845 RegCloseKey(containers_key
);
1846 if (res
!= ERROR_SUCCESS
) return;
1848 res
= RegQueryInfoKeyW(guid_key
, NULL
, NULL
, NULL
, &pattern_count
,
1849 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
1850 if (res
!= ERROR_SUCCESS
)
1852 RegCloseKey(guid_key
);
1856 patterns_size
= pattern_count
* sizeof(WICMetadataPattern
);
1857 patterns
= heap_alloc(patterns_size
);
1860 RegCloseKey(guid_key
);
1864 for (i
=0; res
== ERROR_SUCCESS
&& i
< pattern_count
; i
++)
1866 swprintf(subkeyname
, 11, L
"%u", i
);
1867 res
= RegOpenKeyExW(guid_key
, subkeyname
, 0, KEY_READ
, &patternkey
);
1868 if (res
!= ERROR_SUCCESS
) break;
1870 res
= RegGetValueW(patternkey
, NULL
, L
"Pattern", RRF_RT_REG_BINARY
, NULL
, NULL
, &length
);
1871 if (res
== ERROR_SUCCESS
)
1873 patterns_size
+= length
*2;
1874 patterns
[i
].Length
= length
;
1876 valuesize
= sizeof(DWORD64
);
1877 res
= RegGetValueW(patternkey
, NULL
, L
"DataOffset", RRF_RT_DWORD
|RRF_RT_QWORD
, NULL
,
1878 &patterns
[i
].DataOffset
, &valuesize
);
1879 if (res
) patterns
[i
].DataOffset
.QuadPart
= 0;
1881 patterns
[i
].Position
.QuadPart
= 0;
1882 valuesize
= sizeof(DWORD64
);
1883 res
= RegGetValueW(patternkey
, NULL
, L
"Position", RRF_RT_DWORD
|RRF_RT_QWORD
, NULL
,
1884 &patterns
[i
].Position
, &valuesize
);
1887 RegCloseKey(patternkey
);
1890 if (res
!= ERROR_SUCCESS
|| !(patterns_ptr
= heap_realloc(patterns
, patterns_size
)))
1892 heap_free(patterns
);
1893 RegCloseKey(guid_key
);
1896 patterns
= (WICMetadataPattern
*)patterns_ptr
;
1897 patterns_ptr
+= pattern_count
* sizeof(*patterns
);
1899 for (i
=0; res
== ERROR_SUCCESS
&& i
< pattern_count
; i
++)
1901 swprintf(subkeyname
, 11, L
"%u", i
);
1902 res
= RegOpenKeyExW(guid_key
, subkeyname
, 0, KEY_READ
, &patternkey
);
1903 if (res
!= ERROR_SUCCESS
) break;
1905 length
= patterns
[i
].Length
;
1906 patterns
[i
].Pattern
= patterns_ptr
;
1908 res
= RegGetValueW(patternkey
, NULL
, L
"Pattern", RRF_RT_REG_BINARY
, NULL
,
1909 patterns
[i
].Pattern
, &valuesize
);
1910 patterns_ptr
+= length
;
1912 if (res
== ERROR_SUCCESS
)
1914 patterns
[i
].Mask
= patterns_ptr
;
1916 res
= RegGetValueW(patternkey
, NULL
, L
"Mask", RRF_RT_REG_BINARY
, NULL
,
1917 patterns
[i
].Mask
, &valuesize
);
1918 patterns_ptr
+= length
;
1921 RegCloseKey(patternkey
);
1924 RegCloseKey(guid_key
);
1926 if (res
!= ERROR_SUCCESS
)
1928 heap_free(patterns
);
1932 container
->pattern_count
= pattern_count
;
1933 container
->patterns_size
= patterns_size
;
1934 container
->patterns
= patterns
;
1937 static BOOL
read_metadata_info(MetadataReaderInfo
*info
)
1943 hr
= ComponentInfo_GetGuidList(info
->classkey
, L
"Containers", 0, NULL
, &format_count
);
1944 if (FAILED(hr
)) return TRUE
;
1946 formats
= heap_calloc(format_count
, sizeof(*formats
));
1947 if (!formats
) return FALSE
;
1949 hr
= ComponentInfo_GetGuidList(info
->classkey
, L
"Containers", format_count
, formats
,
1957 info
->container_formats
= formats
;
1958 info
->container_count
= format_count
;
1964 info
->containers
= heap_calloc(format_count
, sizeof(*info
->containers
));
1965 if (!info
->containers
) return FALSE
;
1967 for (i
= 0; i
< format_count
; i
++)
1968 read_metadata_patterns(info
, info
->container_formats
+ i
, info
->containers
+ i
);
1974 static HRESULT
MetadataReaderInfo_Constructor(HKEY classkey
, REFCLSID clsid
, ComponentInfo
**info
)
1976 MetadataReaderInfo
*This
;
1978 This
= heap_alloc_zero(sizeof(*This
));
1981 RegCloseKey(classkey
);
1982 return E_OUTOFMEMORY
;
1985 This
->base
.IWICComponentInfo_iface
.lpVtbl
= (const IWICComponentInfoVtbl
*)&MetadataReaderInfo_Vtbl
;
1987 This
->classkey
= classkey
;
1988 This
->base
.clsid
= *clsid
;
1990 if (!read_metadata_info(This
))
1992 IWICComponentInfo_Release(&This
->base
.IWICComponentInfo_iface
);
1993 return WINCODEC_ERR_COMPONENTNOTFOUND
;
1996 *info
= &This
->base
;
2001 WICComponentType type
;
2003 HRESULT (*constructor
)(HKEY
,REFCLSID
,ComponentInfo
**);
2006 static const struct category categories
[] = {
2007 {WICDecoder
, &CATID_WICBitmapDecoders
, BitmapDecoderInfo_Constructor
},
2008 {WICEncoder
, &CATID_WICBitmapEncoders
, BitmapEncoderInfo_Constructor
},
2009 {WICPixelFormatConverter
, &CATID_WICFormatConverters
, FormatConverterInfo_Constructor
},
2010 {WICPixelFormat
, &CATID_WICPixelFormats
, PixelFormatInfo_Constructor
},
2011 {WICMetadataReader
, &CATID_WICMetadataReader
, MetadataReaderInfo_Constructor
},
2015 static int ComponentInfo_Compare(const void *key
, const struct wine_rb_entry
*entry
)
2017 ComponentInfo
*info
= WINE_RB_ENTRY_VALUE(entry
, ComponentInfo
, entry
);
2018 return memcmp(key
, &info
->clsid
, sizeof(info
->clsid
));
2021 static struct wine_rb_tree component_info_cache
= { ComponentInfo_Compare
};
2023 static CRITICAL_SECTION component_info_cache_cs
;
2024 static CRITICAL_SECTION_DEBUG component_info_cache_cs_dbg
=
2026 0, 0, &component_info_cache_cs
,
2027 { &component_info_cache_cs_dbg
.ProcessLocksList
, &component_info_cache_cs_dbg
.ProcessLocksList
},
2028 0, 0, { (DWORD_PTR
)(__FILE__
": component_info_cache") }
2030 static CRITICAL_SECTION component_info_cache_cs
= { &component_info_cache_cs_dbg
, -1, 0, 0, 0, 0 };
2032 HRESULT
CreateComponentInfo(REFCLSID clsid
, IWICComponentInfo
**ppIInfo
)
2034 struct wine_rb_entry
*cache_entry
;
2035 ComponentInfo
*info
;
2040 WCHAR guidstring
[39];
2042 const struct category
*category
;
2046 EnterCriticalSection(&component_info_cache_cs
);
2048 cache_entry
= wine_rb_get(&component_info_cache
, clsid
);
2051 info
= WINE_RB_ENTRY_VALUE(cache_entry
, ComponentInfo
, entry
);
2052 IWICComponentInfo_AddRef(*ppIInfo
= &info
->IWICComponentInfo_iface
);
2053 LeaveCriticalSection(&component_info_cache_cs
);
2057 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, L
"CLSID", 0, KEY_READ
, &clsidkey
);
2058 if (res
!= ERROR_SUCCESS
)
2060 LeaveCriticalSection(&component_info_cache_cs
);
2061 return HRESULT_FROM_WIN32(res
);
2064 for (category
=categories
; category
->type
; category
++)
2066 StringFromGUID2(category
->catid
, guidstring
, 39);
2067 res
= RegOpenKeyExW(clsidkey
, guidstring
, 0, KEY_READ
, &catidkey
);
2068 if (res
== ERROR_SUCCESS
)
2070 res
= RegOpenKeyExW(catidkey
, L
"Instance", 0, KEY_READ
, &instancekey
);
2071 if (res
== ERROR_SUCCESS
)
2073 StringFromGUID2(clsid
, guidstring
, 39);
2074 res
= RegOpenKeyExW(instancekey
, guidstring
, 0, KEY_READ
, &classkey
);
2075 if (res
== ERROR_SUCCESS
)
2077 RegCloseKey(classkey
);
2080 RegCloseKey(instancekey
);
2082 RegCloseKey(catidkey
);
2089 res
= RegOpenKeyExW(clsidkey
, guidstring
, 0, KEY_READ
, &classkey
);
2090 if (res
== ERROR_SUCCESS
)
2091 hr
= category
->constructor(classkey
, clsid
, &info
);
2093 hr
= HRESULT_FROM_WIN32(res
);
2097 FIXME("%s is not supported\n", wine_dbgstr_guid(clsid
));
2101 RegCloseKey(clsidkey
);
2105 wine_rb_put(&component_info_cache
, clsid
, &info
->entry
);
2106 IWICComponentInfo_AddRef(*ppIInfo
= &info
->IWICComponentInfo_iface
);
2108 LeaveCriticalSection(&component_info_cache_cs
);
2112 void ReleaseComponentInfos(void)
2114 ComponentInfo
*info
, *next_info
;
2115 WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(info
, next_info
, &component_info_cache
, ComponentInfo
, entry
)
2116 IWICComponentInfo_Release(&info
->IWICComponentInfo_iface
);
2119 HRESULT
get_decoder_info(REFCLSID clsid
, IWICBitmapDecoderInfo
**info
)
2121 IWICComponentInfo
*compinfo
;
2124 hr
= CreateComponentInfo(clsid
, &compinfo
);
2125 if (FAILED(hr
)) return hr
;
2127 hr
= IWICComponentInfo_QueryInterface(compinfo
, &IID_IWICBitmapDecoderInfo
,
2130 IWICComponentInfo_Release(compinfo
);
2136 IEnumUnknown IEnumUnknown_iface
;
2138 struct list objects
;
2139 struct list
*cursor
;
2140 CRITICAL_SECTION lock
; /* Must be held when reading or writing cursor */
2143 static inline ComponentEnum
*impl_from_IEnumUnknown(IEnumUnknown
*iface
)
2145 return CONTAINING_RECORD(iface
, ComponentEnum
, IEnumUnknown_iface
);
2151 } ComponentEnumItem
;
2153 static const IEnumUnknownVtbl ComponentEnumVtbl
;
2155 static HRESULT WINAPI
ComponentEnum_QueryInterface(IEnumUnknown
*iface
, REFIID iid
,
2158 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2159 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
2161 if (!ppv
) return E_INVALIDARG
;
2163 if (IsEqualIID(&IID_IUnknown
, iid
) ||
2164 IsEqualIID(&IID_IEnumUnknown
, iid
))
2166 *ppv
= &This
->IEnumUnknown_iface
;
2171 return E_NOINTERFACE
;
2174 IUnknown_AddRef((IUnknown
*)*ppv
);
2178 static ULONG WINAPI
ComponentEnum_AddRef(IEnumUnknown
*iface
)
2180 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2181 ULONG ref
= InterlockedIncrement(&This
->ref
);
2183 TRACE("(%p) refcount=%lu\n", iface
, ref
);
2188 static ULONG WINAPI
ComponentEnum_Release(IEnumUnknown
*iface
)
2190 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2191 ULONG ref
= InterlockedDecrement(&This
->ref
);
2192 ComponentEnumItem
*cursor
, *cursor2
;
2194 TRACE("(%p) refcount=%lu\n", iface
, ref
);
2198 LIST_FOR_EACH_ENTRY_SAFE(cursor
, cursor2
, &This
->objects
, ComponentEnumItem
, entry
)
2200 IUnknown_Release(cursor
->unk
);
2201 list_remove(&cursor
->entry
);
2202 HeapFree(GetProcessHeap(), 0, cursor
);
2204 This
->lock
.DebugInfo
->Spare
[0] = 0;
2205 DeleteCriticalSection(&This
->lock
);
2206 HeapFree(GetProcessHeap(), 0, This
);
2212 static HRESULT WINAPI
ComponentEnum_Next(IEnumUnknown
*iface
, ULONG celt
,
2213 IUnknown
**rgelt
, ULONG
*pceltFetched
)
2215 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2216 ULONG num_fetched
=0;
2217 ComponentEnumItem
*item
;
2220 TRACE("(%p,%lu,%p,%p)\n", iface
, celt
, rgelt
, pceltFetched
);
2222 EnterCriticalSection(&This
->lock
);
2223 while (num_fetched
<celt
)
2230 item
= LIST_ENTRY(This
->cursor
, ComponentEnumItem
, entry
);
2231 IUnknown_AddRef(item
->unk
);
2232 rgelt
[num_fetched
] = item
->unk
;
2234 This
->cursor
= list_next(&This
->objects
, This
->cursor
);
2236 LeaveCriticalSection(&This
->lock
);
2238 *pceltFetched
= num_fetched
;
2242 static HRESULT WINAPI
ComponentEnum_Skip(IEnumUnknown
*iface
, ULONG celt
)
2244 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2248 TRACE("(%p,%lu)\n", iface
, celt
);
2250 EnterCriticalSection(&This
->lock
);
2251 for (i
=0; i
<celt
; i
++)
2258 This
->cursor
= list_next(&This
->objects
, This
->cursor
);
2260 LeaveCriticalSection(&This
->lock
);
2264 static HRESULT WINAPI
ComponentEnum_Reset(IEnumUnknown
*iface
)
2266 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2268 TRACE("(%p)\n", iface
);
2270 EnterCriticalSection(&This
->lock
);
2271 This
->cursor
= list_head(&This
->objects
);
2272 LeaveCriticalSection(&This
->lock
);
2276 static HRESULT WINAPI
ComponentEnum_Clone(IEnumUnknown
*iface
, IEnumUnknown
**ppenum
)
2278 ComponentEnum
*This
= impl_from_IEnumUnknown(iface
);
2279 ComponentEnum
*new_enum
;
2280 ComponentEnumItem
*old_item
, *new_item
;
2282 struct list
*old_cursor
;
2284 new_enum
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum
));
2288 return E_OUTOFMEMORY
;
2291 new_enum
->IEnumUnknown_iface
.lpVtbl
= &ComponentEnumVtbl
;
2293 new_enum
->cursor
= NULL
;
2294 list_init(&new_enum
->objects
);
2295 InitializeCriticalSection(&new_enum
->lock
);
2296 new_enum
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": ComponentEnum.lock");
2298 EnterCriticalSection(&This
->lock
);
2299 old_cursor
= This
->cursor
;
2300 LeaveCriticalSection(&This
->lock
);
2302 LIST_FOR_EACH_ENTRY(old_item
, &This
->objects
, ComponentEnumItem
, entry
)
2304 new_item
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem
));
2307 ret
= E_OUTOFMEMORY
;
2310 new_item
->unk
= old_item
->unk
;
2311 list_add_tail(&new_enum
->objects
, &new_item
->entry
);
2312 IUnknown_AddRef(new_item
->unk
);
2313 if (&old_item
->entry
== old_cursor
) new_enum
->cursor
= &new_item
->entry
;
2318 IEnumUnknown_Release(&new_enum
->IEnumUnknown_iface
);
2322 *ppenum
= &new_enum
->IEnumUnknown_iface
;
2327 static const IEnumUnknownVtbl ComponentEnumVtbl
= {
2328 ComponentEnum_QueryInterface
,
2329 ComponentEnum_AddRef
,
2330 ComponentEnum_Release
,
2333 ComponentEnum_Reset
,
2337 HRESULT
CreateComponentEnumerator(DWORD componentTypes
, DWORD options
, IEnumUnknown
**ppIEnumUnknown
)
2339 ComponentEnum
*This
;
2340 ComponentEnumItem
*item
;
2341 const struct category
*category
;
2342 HKEY clsidkey
, catidkey
, instancekey
;
2343 WCHAR guidstring
[39];
2349 if (options
) FIXME("ignoring flags %lx\n", options
);
2351 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, L
"CLSID", 0, KEY_READ
, &clsidkey
);
2352 if (res
!= ERROR_SUCCESS
)
2353 return HRESULT_FROM_WIN32(res
);
2355 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum
));
2358 RegCloseKey(clsidkey
);
2359 return E_OUTOFMEMORY
;
2362 This
->IEnumUnknown_iface
.lpVtbl
= &ComponentEnumVtbl
;
2364 list_init(&This
->objects
);
2365 InitializeCriticalSection(&This
->lock
);
2366 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": ComponentEnum.lock");
2368 for (category
=categories
; category
->type
&& hr
== S_OK
; category
++)
2370 if ((category
->type
& componentTypes
) == 0) continue;
2371 StringFromGUID2(category
->catid
, guidstring
, 39);
2372 res
= RegOpenKeyExW(clsidkey
, guidstring
, 0, KEY_READ
, &catidkey
);
2373 if (res
== ERROR_SUCCESS
)
2375 res
= RegOpenKeyExW(catidkey
, L
"Instance", 0, KEY_READ
, &instancekey
);
2376 if (res
== ERROR_SUCCESS
)
2381 DWORD guidstring_size
= 39;
2382 res
= RegEnumKeyExW(instancekey
, i
, guidstring
, &guidstring_size
, NULL
, NULL
, NULL
, NULL
);
2383 if (res
!= ERROR_SUCCESS
) break;
2385 item
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem
));
2386 if (!item
) { hr
= E_OUTOFMEMORY
; break; }
2388 hr
= CLSIDFromString(guidstring
, &clsid
);
2391 hr
= CreateComponentInfo(&clsid
, (IWICComponentInfo
**)&item
->unk
);
2393 list_add_tail(&This
->objects
, &item
->entry
);
2398 HeapFree(GetProcessHeap(), 0, item
);
2402 RegCloseKey(instancekey
);
2404 RegCloseKey(catidkey
);
2406 if (res
!= ERROR_SUCCESS
&& res
!= ERROR_NO_MORE_ITEMS
)
2407 hr
= HRESULT_FROM_WIN32(res
);
2409 RegCloseKey(clsidkey
);
2413 IEnumUnknown_Reset(&This
->IEnumUnknown_iface
);
2414 *ppIEnumUnknown
= &This
->IEnumUnknown_iface
;
2418 *ppIEnumUnknown
= NULL
;
2419 IEnumUnknown_Release(&This
->IEnumUnknown_iface
);
2425 static BOOL
is_1bpp_format(const WICPixelFormatGUID
*format
)
2427 return IsEqualGUID(format
, &GUID_WICPixelFormatBlackWhite
) ||
2428 IsEqualGUID(format
, &GUID_WICPixelFormat1bppIndexed
);
2431 HRESULT WINAPI
WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat
, IWICBitmapSource
*pISrc
, IWICBitmapSource
**ppIDst
)
2434 IEnumUnknown
*enumconverters
;
2435 IUnknown
*unkconverterinfo
;
2436 IWICFormatConverterInfo
*converterinfo
=NULL
;
2437 IWICFormatConverter
*converter
=NULL
;
2439 WCHAR srcformatstr
[39], dstformatstr
[39];
2443 TRACE("%s,%p,%p\n", debugstr_guid(dstFormat
), pISrc
, ppIDst
);
2445 res
= IWICBitmapSource_GetPixelFormat(pISrc
, &srcFormat
);
2446 if (FAILED(res
)) return res
;
2448 if (IsEqualGUID(&srcFormat
, dstFormat
) || (is_1bpp_format(&srcFormat
) && is_1bpp_format(dstFormat
)))
2450 IWICBitmapSource_AddRef(pISrc
);
2455 StringFromGUID2(&srcFormat
, srcformatstr
, 39);
2456 StringFromGUID2(dstFormat
, dstformatstr
, 39);
2458 res
= CreateComponentEnumerator(WICPixelFormatConverter
, 0, &enumconverters
);
2459 if (FAILED(res
)) return res
;
2463 res
= IEnumUnknown_Next(enumconverters
, 1, &unkconverterinfo
, &num_fetched
);
2467 res
= IUnknown_QueryInterface(unkconverterinfo
, &IID_IWICFormatConverterInfo
, (void**)&converterinfo
);
2471 canconvert
= ConverterSupportsFormat(converterinfo
, srcformatstr
);
2474 canconvert
= ConverterSupportsFormat(converterinfo
, dstformatstr
);
2478 res
= IWICFormatConverterInfo_CreateInstance(converterinfo
, &converter
);
2481 res
= IWICFormatConverter_CanConvert(converter
, &srcFormat
, dstFormat
, &canconvert
);
2483 if (SUCCEEDED(res
) && canconvert
)
2484 res
= IWICFormatConverter_Initialize(converter
, pISrc
, dstFormat
, WICBitmapDitherTypeNone
,
2485 NULL
, 0.0, WICBitmapPaletteTypeMedianCut
);
2487 if (FAILED(res
) || !canconvert
)
2491 IWICFormatConverter_Release(converter
);
2497 IWICFormatConverterInfo_Release(converterinfo
);
2500 IUnknown_Release(unkconverterinfo
);
2506 IEnumUnknown_Release(enumconverters
);
2510 res
= IWICFormatConverter_QueryInterface(converter
, &IID_IWICBitmapSource
, (void **)ppIDst
);
2511 IWICFormatConverter_Release(converter
);
2516 FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat
), debugstr_guid(dstFormat
));
2518 return WINCODEC_ERR_COMPONENTNOTFOUND
;