Module: wine Branch: master Commit: 870b08b7fd59bd37dc66f7322019618e0e494595 URL: https://source.winehq.org/git/wine.git/?a=commit;h=870b08b7fd59bd37dc66f7322...
Author: Ziqing Hui zhui@codeweavers.com Date: Thu May 28 13:08:55 2020 +0800
windowscodecs: Implement DdsDecoder_Dds_GetFrame().
DdsDecoder_GetFrame() is implemented on top of DdsDecoder_Dds_GetFrame().
Signed-off-by: Ziqing Hui zhui@codeweavers.com Signed-off-by: Esme Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/windowscodecs/ddsformat.c | 80 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 8 deletions(-)
diff --git a/dlls/windowscodecs/ddsformat.c b/dlls/windowscodecs/ddsformat.c index 7341147245..333f015820 100644 --- a/dlls/windowscodecs/ddsformat.c +++ b/dlls/windowscodecs/ddsformat.c @@ -121,8 +121,12 @@ typedef struct DdsFrameDecode { IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; IWICDdsFrameDecode IWICDdsFrameDecode_iface; LONG ref; + UINT width; + UINT height; } DdsFrameDecode;
+static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *, UINT, UINT, UINT, IWICBitmapFrameDecode **); + static inline BOOL has_extended_header(DDS_HEADER *header) { return (header->ddspf.flags & DDPF_FOURCC) && @@ -643,15 +647,35 @@ static HRESULT WINAPI DdsDecoder_GetFrameCount(IWICBitmapDecoder *iface, static HRESULT WINAPI DdsDecoder_GetFrame(IWICBitmapDecoder *iface, UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) { - HRESULT hr; - DdsFrameDecode *frame_decode; + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + UINT frame_per_texture, array_index, mip_level, slice_index, depth;
- FIXME("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); + TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame);
- hr = DdsFrameDecode_CreateInstance(&frame_decode); - if (hr == S_OK) *ppIBitmapFrame = &frame_decode->IWICBitmapFrameDecode_iface; + if (!ppIBitmapFrame) return E_INVALIDARG;
- return hr; + EnterCriticalSection(&This->lock); + + if (!This->initialized) { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_WRONGSTATE; + } + + frame_per_texture = This->info.frame_count / This->info.array_size; + array_index = index / frame_per_texture; + slice_index = index % frame_per_texture; + depth = This->info.depth; + mip_level = 0; + while (slice_index >= depth) + { + slice_index -= depth; + mip_level++; + if (depth > 1) depth /= 2; + } + + LeaveCriticalSection(&This->lock); + + return DdsDecoder_Dds_GetFrame(&This->IWICDdsDecoder_iface, array_index, mip_level, slice_index, ppIBitmapFrame); }
static const IWICBitmapDecoderVtbl DdsDecoder_Vtbl = { @@ -730,9 +754,49 @@ static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *iface, UINT arrayIndex, UINT mipLevel, UINT sliceIndex, IWICBitmapFrameDecode **bitmapFrame) { - TRACE("(%p,%u,%u,%u,%p): Stub.\n", iface, arrayIndex, mipLevel, sliceIndex, bitmapFrame); + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + HRESULT hr; + UINT width = 0, height = 0; + int j; + DdsFrameDecode *frame_decode;
- return E_NOTIMPL; + TRACE("(%p,%u,%u,%u,%p)\n", iface, arrayIndex, mipLevel, sliceIndex, bitmapFrame); + + if (!bitmapFrame) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->initialized) { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + if (arrayIndex >= This->info.array_size || mipLevel >= This->info.mip_levels || sliceIndex >= This->info.depth) { + hr = E_INVALIDARG; + goto end; + } + + width = This->info.width; + height = This->info.height; + for (j = 0; j < mipLevel; j++) + { + if (width > 1) width /= 2; + if (height > 1) height /= 2; + } + + hr = DdsFrameDecode_CreateInstance(&frame_decode); + if (hr != S_OK) goto end; + + frame_decode->width = width; + frame_decode->height = height; + *bitmapFrame = &frame_decode->IWICBitmapFrameDecode_iface; + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + + return hr; }
static const IWICDdsDecoderVtbl DdsDecoder_Dds_Vtbl = {