Ziqing Hui : windowscodecs: Implement DdsDecoder_Dds_GetFrame().

Alexandre Julliard julliard at winehq.org
Fri May 29 15:22:54 CDT 2020


Module: wine
Branch: master
Commit: 870b08b7fd59bd37dc66f7322019618e0e494595
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=870b08b7fd59bd37dc66f7322019618e0e494595

Author: Ziqing Hui <zhui at 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 at codeweavers.com>
Signed-off-by: Esme Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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 = {




More information about the wine-cvs mailing list