2 * Copyright 2020 Esme Povirk
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define NONAMELESSUNION
28 #include "wincodecs_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
35 IWICBitmapDecoder IWICBitmapDecoder_iface
;
37 CRITICAL_SECTION lock
; /* must be held when stream or decoder is accessed */
39 struct decoder
*decoder
;
40 struct decoder_info decoder_info
;
41 struct decoder_stat file_info
;
42 WICDecodeOptions cache_options
;
45 static inline CommonDecoder
*impl_from_IWICBitmapDecoder(IWICBitmapDecoder
*iface
)
47 return CONTAINING_RECORD(iface
, CommonDecoder
, IWICBitmapDecoder_iface
);
50 static HRESULT WINAPI
CommonDecoder_QueryInterface(IWICBitmapDecoder
*iface
, REFIID iid
,
53 CommonDecoder
*This
= impl_from_IWICBitmapDecoder(iface
);
54 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
56 if (!ppv
) return E_INVALIDARG
;
58 if (IsEqualIID(&IID_IUnknown
, iid
) || IsEqualIID(&IID_IWICBitmapDecoder
, iid
))
60 *ppv
= &This
->IWICBitmapDecoder_iface
;
68 IUnknown_AddRef((IUnknown
*)*ppv
);
72 static ULONG WINAPI
CommonDecoder_AddRef(IWICBitmapDecoder
*iface
)
74 CommonDecoder
*This
= impl_from_IWICBitmapDecoder(iface
);
75 ULONG ref
= InterlockedIncrement(&This
->ref
);
77 TRACE("(%p) refcount=%u\n", iface
, ref
);
82 static ULONG WINAPI
CommonDecoder_Release(IWICBitmapDecoder
*iface
)
84 CommonDecoder
*This
= impl_from_IWICBitmapDecoder(iface
);
85 ULONG ref
= InterlockedDecrement(&This
->ref
);
87 TRACE("(%p) refcount=%u\n", iface
, ref
);
92 IStream_Release(This
->stream
);
93 This
->lock
.DebugInfo
->Spare
[0] = 0;
94 DeleteCriticalSection(&This
->lock
);
95 decoder_destroy(This
->decoder
);
96 HeapFree(GetProcessHeap(), 0, This
);
102 static HRESULT WINAPI
CommonDecoder_QueryCapability(IWICBitmapDecoder
*iface
, IStream
*stream
,
105 CommonDecoder
*This
= impl_from_IWICBitmapDecoder(iface
);
108 TRACE("(%p,%p,%p)\n", iface
, stream
, capability
);
110 if (!stream
|| !capability
) return E_INVALIDARG
;
112 hr
= IWICBitmapDecoder_Initialize(iface
, stream
, WICDecodeMetadataCacheOnDemand
);
113 if (hr
!= S_OK
) return hr
;
115 *capability
= (This
->file_info
.flags
& DECODER_FLAGS_CAPABILITY_MASK
);
119 static HRESULT WINAPI
CommonDecoder_Initialize(IWICBitmapDecoder
*iface
, IStream
*pIStream
,
120 WICDecodeOptions cacheOptions
)
122 CommonDecoder
*This
= impl_from_IWICBitmapDecoder(iface
);
125 TRACE("(%p,%p,%x)\n", iface
, pIStream
, cacheOptions
);
127 EnterCriticalSection(&This
->lock
);
130 hr
= WINCODEC_ERR_WRONGSTATE
;
133 hr
= decoder_initialize(This
->decoder
, pIStream
, &This
->file_info
);
137 This
->cache_options
= cacheOptions
;
138 This
->stream
= pIStream
;
139 IStream_AddRef(This
->stream
);
142 LeaveCriticalSection(&This
->lock
);
147 static HRESULT WINAPI
CommonDecoder_GetContainerFormat(IWICBitmapDecoder
*iface
,
148 GUID
*pguidContainerFormat
)
150 CommonDecoder
*This
= impl_from_IWICBitmapDecoder(iface
);
151 memcpy(pguidContainerFormat
, &This
->decoder_info
.container_format
, sizeof(GUID
));
155 static HRESULT WINAPI
CommonDecoder_GetDecoderInfo(IWICBitmapDecoder
*iface
,
156 IWICBitmapDecoderInfo
**ppIDecoderInfo
)
158 CommonDecoder
*This
= impl_from_IWICBitmapDecoder(iface
);
159 TRACE("(%p,%p)\n", iface
, ppIDecoderInfo
);
161 return get_decoder_info(&This
->decoder_info
.clsid
, ppIDecoderInfo
);
164 static HRESULT WINAPI
CommonDecoder_CopyPalette(IWICBitmapDecoder
*iface
,
165 IWICPalette
*palette
)
167 TRACE("(%p,%p)\n", iface
, palette
);
168 return WINCODEC_ERR_PALETTEUNAVAILABLE
;
171 static HRESULT WINAPI
CommonDecoder_GetMetadataQueryReader(IWICBitmapDecoder
*iface
,
172 IWICMetadataQueryReader
**reader
)
174 TRACE("(%p,%p)\n", iface
, reader
);
176 if (!reader
) return E_INVALIDARG
;
179 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
182 static HRESULT WINAPI
CommonDecoder_GetPreview(IWICBitmapDecoder
*iface
,
183 IWICBitmapSource
**ppIBitmapSource
)
185 TRACE("(%p,%p)\n", iface
, ppIBitmapSource
);
187 if (!ppIBitmapSource
) return E_INVALIDARG
;
189 *ppIBitmapSource
= NULL
;
190 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
193 static HRESULT WINAPI
CommonDecoder_GetColorContexts(IWICBitmapDecoder
*iface
,
194 UINT cCount
, IWICColorContext
**ppIColorContexts
, UINT
*pcActualCount
)
196 TRACE("(%p,%u,%p,%p)\n", iface
, cCount
, ppIColorContexts
, pcActualCount
);
197 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
200 static HRESULT WINAPI
CommonDecoder_GetThumbnail(IWICBitmapDecoder
*iface
,
201 IWICBitmapSource
**ppIThumbnail
)
203 TRACE("(%p,%p)\n", iface
, ppIThumbnail
);
205 if (!ppIThumbnail
) return E_INVALIDARG
;
207 *ppIThumbnail
= NULL
;
208 return WINCODEC_ERR_CODECNOTHUMBNAIL
;
211 static HRESULT WINAPI
CommonDecoder_GetFrameCount(IWICBitmapDecoder
*iface
,
214 CommonDecoder
*This
= impl_from_IWICBitmapDecoder(iface
);
215 if (!pCount
) return E_INVALIDARG
;
218 *pCount
= This
->file_info
.frame_count
;
225 static HRESULT WINAPI
CommonDecoder_GetFrame(IWICBitmapDecoder
*iface
,
226 UINT index
, IWICBitmapFrameDecode
**ppIBitmapFrame
);
228 static const IWICBitmapDecoderVtbl CommonDecoder_Vtbl
= {
229 CommonDecoder_QueryInterface
,
230 CommonDecoder_AddRef
,
231 CommonDecoder_Release
,
232 CommonDecoder_QueryCapability
,
233 CommonDecoder_Initialize
,
234 CommonDecoder_GetContainerFormat
,
235 CommonDecoder_GetDecoderInfo
,
236 CommonDecoder_CopyPalette
,
237 CommonDecoder_GetMetadataQueryReader
,
238 CommonDecoder_GetPreview
,
239 CommonDecoder_GetColorContexts
,
240 CommonDecoder_GetThumbnail
,
241 CommonDecoder_GetFrameCount
,
242 CommonDecoder_GetFrame
246 IWICBitmapFrameDecode IWICBitmapFrameDecode_iface
;
247 IWICMetadataBlockReader IWICMetadataBlockReader_iface
;
249 CommonDecoder
*parent
;
251 struct decoder_frame decoder_frame
;
252 BOOL metadata_initialized
;
253 ULONG metadata_count
;
254 struct decoder_block
* metadata_blocks
;
255 } CommonDecoderFrame
;
257 static inline CommonDecoderFrame
*impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode
*iface
)
259 return CONTAINING_RECORD(iface
, CommonDecoderFrame
, IWICBitmapFrameDecode_iface
);
262 static inline CommonDecoderFrame
*impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader
*iface
)
264 return CONTAINING_RECORD(iface
, CommonDecoderFrame
, IWICMetadataBlockReader_iface
);
267 static HRESULT WINAPI
CommonDecoderFrame_QueryInterface(IWICBitmapFrameDecode
*iface
, REFIID iid
,
270 CommonDecoderFrame
*This
= impl_from_IWICBitmapFrameDecode(iface
);
271 if (!ppv
) return E_INVALIDARG
;
273 if (IsEqualIID(&IID_IUnknown
, iid
) ||
274 IsEqualIID(&IID_IWICBitmapSource
, iid
) ||
275 IsEqualIID(&IID_IWICBitmapFrameDecode
, iid
))
277 *ppv
= &This
->IWICBitmapFrameDecode_iface
;
279 else if (IsEqualIID(&IID_IWICMetadataBlockReader
, iid
) &&
280 (This
->parent
->file_info
.flags
& WICBitmapDecoderCapabilityCanEnumerateMetadata
))
282 *ppv
= &This
->IWICMetadataBlockReader_iface
;
287 return E_NOINTERFACE
;
290 IUnknown_AddRef((IUnknown
*)*ppv
);
294 static ULONG WINAPI
CommonDecoderFrame_AddRef(IWICBitmapFrameDecode
*iface
)
296 CommonDecoderFrame
*This
= impl_from_IWICBitmapFrameDecode(iface
);
297 ULONG ref
= InterlockedIncrement(&This
->ref
);
299 TRACE("(%p) refcount=%u\n", iface
, ref
);
304 static ULONG WINAPI
CommonDecoderFrame_Release(IWICBitmapFrameDecode
*iface
)
306 CommonDecoderFrame
*This
= impl_from_IWICBitmapFrameDecode(iface
);
307 ULONG ref
= InterlockedDecrement(&This
->ref
);
309 TRACE("(%p) refcount=%u\n", iface
, ref
);
313 IWICBitmapDecoder_Release(&This
->parent
->IWICBitmapDecoder_iface
);
314 HeapFree(GetProcessHeap(), 0, This
->metadata_blocks
);
315 HeapFree(GetProcessHeap(), 0, This
);
321 static HRESULT WINAPI
CommonDecoderFrame_GetSize(IWICBitmapFrameDecode
*iface
,
322 UINT
*puiWidth
, UINT
*puiHeight
)
324 CommonDecoderFrame
*This
= impl_from_IWICBitmapFrameDecode(iface
);
326 TRACE("(%p,%p,%p)\n", This
, puiWidth
, puiHeight
);
328 if (!puiWidth
|| !puiHeight
)
331 *puiWidth
= This
->decoder_frame
.width
;
332 *puiHeight
= This
->decoder_frame
.height
;
336 static HRESULT WINAPI
CommonDecoderFrame_GetPixelFormat(IWICBitmapFrameDecode
*iface
,
337 WICPixelFormatGUID
*pPixelFormat
)
339 CommonDecoderFrame
*This
= impl_from_IWICBitmapFrameDecode(iface
);
341 TRACE("(%p,%p)\n", This
, pPixelFormat
);
346 *pPixelFormat
= This
->decoder_frame
.pixel_format
;
350 static HRESULT WINAPI
CommonDecoderFrame_GetResolution(IWICBitmapFrameDecode
*iface
,
351 double *pDpiX
, double *pDpiY
)
353 CommonDecoderFrame
*This
= impl_from_IWICBitmapFrameDecode(iface
);
355 TRACE("(%p,%p,%p)\n", This
, pDpiX
, pDpiY
);
357 if (!pDpiX
|| !pDpiY
)
360 *pDpiX
= This
->decoder_frame
.dpix
;
361 *pDpiY
= This
->decoder_frame
.dpiy
;
365 static HRESULT WINAPI
CommonDecoderFrame_CopyPalette(IWICBitmapFrameDecode
*iface
,
366 IWICPalette
*pIPalette
)
368 CommonDecoderFrame
*This
= impl_from_IWICBitmapFrameDecode(iface
);
371 TRACE("(%p,%p)\n", iface
, pIPalette
);
373 if (This
->decoder_frame
.num_colors
)
375 hr
= IWICPalette_InitializeCustom(pIPalette
, This
->decoder_frame
.palette
, This
->decoder_frame
.num_colors
);
379 hr
= WINCODEC_ERR_PALETTEUNAVAILABLE
;
385 static HRESULT WINAPI
CommonDecoderFrame_CopyPixels(IWICBitmapFrameDecode
*iface
,
386 const WICRect
*prc
, UINT cbStride
, UINT cbBufferSize
, BYTE
*pbBuffer
)
388 CommonDecoderFrame
*This
= impl_from_IWICBitmapFrameDecode(iface
);
393 TRACE("(%p,%s,%u,%u,%p)\n", iface
, debug_wic_rect(prc
), cbStride
, cbBufferSize
, pbBuffer
);
402 rect
.Width
= This
->decoder_frame
.width
;
403 rect
.Height
= This
->decoder_frame
.height
;
408 if (prc
->X
< 0 || prc
->Y
< 0 ||
409 prc
->X
+prc
->Width
> This
->decoder_frame
.width
||
410 prc
->Y
+prc
->Height
> This
->decoder_frame
.height
)
414 bytesperrow
= ((This
->decoder_frame
.bpp
* prc
->Width
)+7)/8;
416 if (cbStride
< bytesperrow
)
419 if ((cbStride
* (prc
->Height
-1)) + bytesperrow
> cbBufferSize
)
422 EnterCriticalSection(&This
->parent
->lock
);
424 hr
= decoder_copy_pixels(This
->parent
->decoder
, This
->frame
,
425 prc
, cbStride
, cbBufferSize
, pbBuffer
);
427 LeaveCriticalSection(&This
->parent
->lock
);
432 static HRESULT WINAPI
CommonDecoderFrame_GetMetadataQueryReader(IWICBitmapFrameDecode
*iface
,
433 IWICMetadataQueryReader
**ppIMetadataQueryReader
)
435 CommonDecoderFrame
*This
= impl_from_IWICBitmapFrameDecode(iface
);
436 IWICComponentFactory
* factory
;
439 TRACE("(%p,%p)\n", iface
, ppIMetadataQueryReader
);
441 if (!ppIMetadataQueryReader
)
444 if (!(This
->parent
->file_info
.flags
& WICBitmapDecoderCapabilityCanEnumerateMetadata
))
445 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
447 hr
= create_instance(&CLSID_WICImagingFactory
, &IID_IWICComponentFactory
, (void**)&factory
);
451 hr
= IWICComponentFactory_CreateQueryReaderFromBlockReader(factory
, &This
->IWICMetadataBlockReader_iface
, ppIMetadataQueryReader
);
452 IWICComponentFactory_Release(factory
);
456 *ppIMetadataQueryReader
= NULL
;
461 static HRESULT WINAPI
CommonDecoderFrame_GetColorContexts(IWICBitmapFrameDecode
*iface
,
462 UINT cCount
, IWICColorContext
**ppIColorContexts
, UINT
*pcActualCount
)
464 CommonDecoderFrame
*This
= impl_from_IWICBitmapFrameDecode(iface
);
470 TRACE("(%p,%u,%p,%p)\n", iface
, cCount
, ppIColorContexts
, pcActualCount
);
472 if (!pcActualCount
) return E_INVALIDARG
;
474 if (This
->parent
->file_info
.flags
& DECODER_FLAGS_UNSUPPORTED_COLOR_CONTEXT
)
476 FIXME("not supported for %s\n", wine_dbgstr_guid(&This
->parent
->decoder_info
.clsid
));
478 return WINCODEC_ERR_UNSUPPORTEDOPERATION
;
481 *pcActualCount
= This
->decoder_frame
.num_color_contexts
;
483 if (This
->decoder_frame
.num_color_contexts
&& cCount
&& ppIColorContexts
)
485 if (cCount
>= This
->decoder_frame
.num_color_contexts
)
487 EnterCriticalSection(&This
->parent
->lock
);
489 for (i
=0; i
<This
->decoder_frame
.num_color_contexts
; i
++)
491 hr
= decoder_get_color_context(This
->parent
->decoder
, This
->frame
, i
,
492 &profile
, &profile_len
);
495 hr
= IWICColorContext_InitializeFromMemory(ppIColorContexts
[i
], profile
, profile_len
);
497 HeapFree(GetProcessHeap(), 0, profile
);
504 LeaveCriticalSection(&This
->parent
->lock
);
515 static HRESULT WINAPI
CommonDecoderFrame_GetThumbnail(IWICBitmapFrameDecode
*iface
,
516 IWICBitmapSource
**ppIThumbnail
)
518 TRACE("(%p,%p)\n", iface
, ppIThumbnail
);
520 if (!ppIThumbnail
) return E_INVALIDARG
;
522 *ppIThumbnail
= NULL
;
523 return WINCODEC_ERR_CODECNOTHUMBNAIL
;
526 static const IWICBitmapFrameDecodeVtbl CommonDecoderFrameVtbl
= {
527 CommonDecoderFrame_QueryInterface
,
528 CommonDecoderFrame_AddRef
,
529 CommonDecoderFrame_Release
,
530 CommonDecoderFrame_GetSize
,
531 CommonDecoderFrame_GetPixelFormat
,
532 CommonDecoderFrame_GetResolution
,
533 CommonDecoderFrame_CopyPalette
,
534 CommonDecoderFrame_CopyPixels
,
535 CommonDecoderFrame_GetMetadataQueryReader
,
536 CommonDecoderFrame_GetColorContexts
,
537 CommonDecoderFrame_GetThumbnail
540 static HRESULT WINAPI
CommonDecoderFrame_Block_QueryInterface(IWICMetadataBlockReader
*iface
, REFIID iid
,
543 CommonDecoderFrame
*This
= impl_from_IWICMetadataBlockReader(iface
);
544 return IWICBitmapFrameDecode_QueryInterface(&This
->IWICBitmapFrameDecode_iface
, iid
, ppv
);
547 static ULONG WINAPI
CommonDecoderFrame_Block_AddRef(IWICMetadataBlockReader
*iface
)
549 CommonDecoderFrame
*This
= impl_from_IWICMetadataBlockReader(iface
);
550 return IWICBitmapFrameDecode_AddRef(&This
->IWICBitmapFrameDecode_iface
);
553 static ULONG WINAPI
CommonDecoderFrame_Block_Release(IWICMetadataBlockReader
*iface
)
555 CommonDecoderFrame
*This
= impl_from_IWICMetadataBlockReader(iface
);
556 return IWICBitmapFrameDecode_Release(&This
->IWICBitmapFrameDecode_iface
);
559 static HRESULT WINAPI
CommonDecoderFrame_Block_GetContainerFormat(IWICMetadataBlockReader
*iface
,
560 GUID
*pguidContainerFormat
)
562 CommonDecoderFrame
*This
= impl_from_IWICMetadataBlockReader(iface
);
563 if (!pguidContainerFormat
) return E_INVALIDARG
;
564 *pguidContainerFormat
= This
->parent
->decoder_info
.block_format
;
568 static HRESULT WINAPI
CommonDecoderFrame_InitializeMetadata(CommonDecoderFrame
*This
)
572 if (This
->metadata_initialized
)
575 EnterCriticalSection(&This
->parent
->lock
);
577 if (!This
->metadata_initialized
)
579 hr
= decoder_get_metadata_blocks(This
->parent
->decoder
, This
->frame
, &This
->metadata_count
, &This
->metadata_blocks
);
581 This
->metadata_initialized
= TRUE
;
584 LeaveCriticalSection(&This
->parent
->lock
);
589 static HRESULT WINAPI
CommonDecoderFrame_Block_GetCount(IWICMetadataBlockReader
*iface
,
592 CommonDecoderFrame
*This
= impl_from_IWICMetadataBlockReader(iface
);
595 TRACE("%p,%p\n", iface
, pcCount
);
597 if (!pcCount
) return E_INVALIDARG
;
599 hr
= CommonDecoderFrame_InitializeMetadata(This
);
601 *pcCount
= This
->metadata_count
;
606 static HRESULT WINAPI
CommonDecoderFrame_Block_GetReaderByIndex(IWICMetadataBlockReader
*iface
,
607 UINT nIndex
, IWICMetadataReader
**ppIMetadataReader
)
609 CommonDecoderFrame
*This
= impl_from_IWICMetadataBlockReader(iface
);
611 IWICComponentFactory
* factory
= NULL
;
614 TRACE("%p,%d,%p\n", iface
, nIndex
, ppIMetadataReader
);
616 if (!ppIMetadataReader
)
619 hr
= CommonDecoderFrame_InitializeMetadata(This
);
621 if (SUCCEEDED(hr
) && nIndex
>= This
->metadata_count
)
625 hr
= create_instance(&CLSID_WICImagingFactory
, &IID_IWICComponentFactory
, (void**)&factory
);
628 hr
= IWICComponentFactory_CreateStream(factory
, &stream
);
632 if (This
->metadata_blocks
[nIndex
].options
& DECODER_BLOCK_FULL_STREAM
)
634 LARGE_INTEGER offset
;
635 offset
.QuadPart
= This
->metadata_blocks
[nIndex
].offset
;
637 hr
= IWICStream_InitializeFromIStream(stream
, This
->parent
->stream
);
640 hr
= IWICStream_Seek(stream
, offset
, STREAM_SEEK_SET
, NULL
);
644 ULARGE_INTEGER offset
, length
;
646 offset
.QuadPart
= This
->metadata_blocks
[nIndex
].offset
;
647 length
.QuadPart
= This
->metadata_blocks
[nIndex
].length
;
649 hr
= IWICStream_InitializeFromIStreamRegion(stream
, This
->parent
->stream
,
653 if (This
->metadata_blocks
[nIndex
].options
& DECODER_BLOCK_READER_CLSID
)
655 IWICMetadataReader
*reader
;
656 IWICPersistStream
*persist
;
659 hr
= create_instance(&This
->metadata_blocks
[nIndex
].reader_clsid
,
660 &IID_IWICMetadataReader
, (void**)&reader
);
665 hr
= IWICMetadataReader_QueryInterface(reader
, &IID_IWICPersistStream
, (void**)&persist
);
669 hr
= IWICPersistStream_LoadEx(persist
, (IStream
*)stream
, NULL
,
670 This
->metadata_blocks
[nIndex
].options
& DECODER_BLOCK_OPTION_MASK
);
672 IWICPersistStream_Release(persist
);
676 *ppIMetadataReader
= reader
;
678 IWICMetadataReader_Release(reader
);
683 hr
= IWICComponentFactory_CreateMetadataReaderFromContainer(factory
,
684 &This
->parent
->decoder_info
.block_format
, NULL
,
685 This
->metadata_blocks
[nIndex
].options
& DECODER_BLOCK_OPTION_MASK
,
686 (IStream
*)stream
, ppIMetadataReader
);
689 IWICStream_Release(stream
);
692 if (factory
) IWICComponentFactory_Release(factory
);
695 *ppIMetadataReader
= NULL
;
700 static HRESULT WINAPI
CommonDecoderFrame_Block_GetEnumerator(IWICMetadataBlockReader
*iface
,
701 IEnumUnknown
**ppIEnumMetadata
)
703 FIXME("%p,%p\n", iface
, ppIEnumMetadata
);
707 static const IWICMetadataBlockReaderVtbl CommonDecoderFrame_BlockVtbl
= {
708 CommonDecoderFrame_Block_QueryInterface
,
709 CommonDecoderFrame_Block_AddRef
,
710 CommonDecoderFrame_Block_Release
,
711 CommonDecoderFrame_Block_GetContainerFormat
,
712 CommonDecoderFrame_Block_GetCount
,
713 CommonDecoderFrame_Block_GetReaderByIndex
,
714 CommonDecoderFrame_Block_GetEnumerator
,
717 static HRESULT WINAPI
CommonDecoder_GetFrame(IWICBitmapDecoder
*iface
,
718 UINT index
, IWICBitmapFrameDecode
**ppIBitmapFrame
)
720 CommonDecoder
*This
= impl_from_IWICBitmapDecoder(iface
);
722 CommonDecoderFrame
*result
;
724 TRACE("(%p,%u,%p)\n", iface
, index
, ppIBitmapFrame
);
729 EnterCriticalSection(&This
->lock
);
731 if (!This
->stream
|| index
>= This
->file_info
.frame_count
)
732 hr
= WINCODEC_ERR_FRAMEMISSING
;
736 result
= HeapAlloc(GetProcessHeap(), 0, sizeof(*result
));
743 result
->IWICBitmapFrameDecode_iface
.lpVtbl
= &CommonDecoderFrameVtbl
;
744 result
->IWICMetadataBlockReader_iface
.lpVtbl
= &CommonDecoderFrame_BlockVtbl
;
746 result
->parent
= This
;
747 result
->frame
= index
;
748 result
->metadata_initialized
= FALSE
;
749 result
->metadata_count
= 0;
750 result
->metadata_blocks
= NULL
;
752 hr
= decoder_get_frame_info(This
->decoder
, index
, &result
->decoder_frame
);
754 if (SUCCEEDED(hr
) && This
->cache_options
== WICDecodeMetadataCacheOnLoad
)
755 hr
= CommonDecoderFrame_InitializeMetadata(result
);
758 HeapFree(GetProcessHeap(), 0, result
);
761 LeaveCriticalSection(&This
->lock
);
765 TRACE("-> %ux%u, %u-bit pixelformat=%s res=%f,%f colors=%u contexts=%u\n",
766 result
->decoder_frame
.width
, result
->decoder_frame
.height
,
767 result
->decoder_frame
.bpp
, wine_dbgstr_guid(&result
->decoder_frame
.pixel_format
),
768 result
->decoder_frame
.dpix
, result
->decoder_frame
.dpiy
,
769 result
->decoder_frame
.num_colors
, result
->decoder_frame
.num_color_contexts
);
770 IWICBitmapDecoder_AddRef(&This
->IWICBitmapDecoder_iface
);
771 *ppIBitmapFrame
= &result
->IWICBitmapFrameDecode_iface
;
775 *ppIBitmapFrame
= NULL
;
781 HRESULT
CommonDecoder_CreateInstance(struct decoder
*decoder
,
782 const struct decoder_info
*decoder_info
, REFIID iid
, void** ppv
)
787 TRACE("(%s,%s,%p)\n", debugstr_guid(&decoder_info
->clsid
), debugstr_guid(iid
), ppv
);
789 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
792 decoder_destroy(decoder
);
793 return E_OUTOFMEMORY
;
796 This
->IWICBitmapDecoder_iface
.lpVtbl
= &CommonDecoder_Vtbl
;
799 This
->decoder
= decoder
;
800 This
->decoder_info
= *decoder_info
;
801 InitializeCriticalSection(&This
->lock
);
802 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": CommonDecoder.lock");
804 hr
= IWICBitmapDecoder_QueryInterface(&This
->IWICBitmapDecoder_iface
, iid
, ppv
);
805 IWICBitmapDecoder_Release(&This
->IWICBitmapDecoder_iface
);