Ziqing Hui : windowscodecs: Implement DdsDecoder_GetFrameCount().

Alexandre Julliard julliard at winehq.org
Thu Apr 23 14:54:32 CDT 2020


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

Author: Ziqing Hui <zhui at codeweavers.com>
Date:   Thu Apr 23 17:29:49 2020 +0800

windowscodecs: Implement DdsDecoder_GetFrameCount().

The added tests code is to test the return value of
DdsDecoder_GetFrameCount() when decoder is not initialized or
parameter is NULL.

Signed-off-by: Ziqing Hui <zhui at codeweavers.com>
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/windowscodecs/ddsformat.c       | 40 ++++++++++++++++++++++++++++++++----
 dlls/windowscodecs/tests/ddsformat.c | 11 +++++++---
 2 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/dlls/windowscodecs/ddsformat.c b/dlls/windowscodecs/ddsformat.c
index 04914ead3a..19d5dd5a3f 100644
--- a/dlls/windowscodecs/ddsformat.c
+++ b/dlls/windowscodecs/ddsformat.c
@@ -94,6 +94,12 @@ typedef struct DdsDecoder {
     DDS_HEADER_DXT10 header_dxt10;
 } DdsDecoder;
 
+static inline BOOL has_extended_header(DDS_HEADER *header)
+{
+    return (header->ddspf.flags & DDPF_FOURCC) &&
+           (header->ddspf.fourCC == MAKEFOURCC('D', 'X', '1', '0'));
+}
+
 static inline DdsDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface)
 {
     return CONTAINING_RECORD(iface, DdsDecoder, IWICBitmapDecoder_iface);
@@ -202,8 +208,7 @@ static HRESULT WINAPI DdsDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
         goto end;
     }
 
-    if (This->header.ddspf.flags & DDPF_FOURCC &&
-        This->header.ddspf.fourCC == MAKEFOURCC('D', 'X', '1', '0')) {
+    if (has_extended_header(&This->header)) {
         hr = IStream_Read(pIStream, &This->header_dxt10, sizeof(This->header_dxt10), &bytesread);
         if (FAILED(hr)) goto end;
         if (bytesread != sizeof(This->header_dxt10)) {
@@ -285,9 +290,36 @@ static HRESULT WINAPI DdsDecoder_GetThumbnail(IWICBitmapDecoder *iface,
 static HRESULT WINAPI DdsDecoder_GetFrameCount(IWICBitmapDecoder *iface,
                                                UINT *pCount)
 {
-    FIXME("(%p) <-- %d: stub.\n", iface, *pCount);
+    DdsDecoder *This = impl_from_IWICBitmapDecoder(iface);
+    UINT arraySize = 1, mipMapCount = 1, depth = 1;
+    int i;
 
-    return E_NOTIMPL;
+    if (!pCount) return E_INVALIDARG;
+    if (!This->initialized) return WINCODEC_ERR_WRONGSTATE;
+
+    EnterCriticalSection(&This->lock);
+
+    if (This->header.mipMapCount) mipMapCount = This->header.mipMapCount;
+    if (This->header.depth) depth = This->header.depth;
+    if (has_extended_header(&This->header) && This->header_dxt10.arraySize) arraySize = This->header_dxt10.arraySize;
+
+    if (depth == 1) {
+        *pCount = arraySize * mipMapCount;
+    } else {
+        *pCount = 0;
+        for (i = 0; i < mipMapCount; i++)
+        {
+            *pCount += depth;
+            if (depth > 1) depth /= 2;
+        }
+        *pCount *= arraySize;
+    }
+
+    LeaveCriticalSection(&This->lock);
+
+    TRACE("(%p) <-- %d\n", iface, *pCount);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI DdsDecoder_GetFrame(IWICBitmapDecoder *iface,
diff --git a/dlls/windowscodecs/tests/ddsformat.c b/dlls/windowscodecs/tests/ddsformat.c
index 99f19eb175..e548ee9655 100644
--- a/dlls/windowscodecs/tests/ddsformat.c
+++ b/dlls/windowscodecs/tests/ddsformat.c
@@ -304,17 +304,22 @@ static void test_dds_decoder_frame_count(void)
         decoder = create_decoder();
         if (!decoder) goto next;
 
+        hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
+        ok (hr == WINCODEC_ERR_WRONGSTATE, "%d: Expected hr=WINCODEC_ERR_WRONGSTATE, got %x\n", i, hr);
+        hr = IWICBitmapDecoder_GetFrameCount(decoder, NULL);
+        ok (hr == E_INVALIDARG, "%d: Expected hr=E_INVALIDARG, got %x\n", i, hr);
+
         hr = init_decoder(decoder, stream, S_OK, -1);
         if (hr != S_OK) goto next;
 
-        todo_wine {
         hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
-        ok (hr == S_OK, "GetFrameCount failed, hr=%x\n", hr);
+        ok (hr == S_OK, "%d: GetFrameCount failed, hr=%x\n", i, hr);
         if (hr == S_OK) {
             ok (frame_count == test_data[i].expected, "%d: expected frame count %d, got %d\n",
                 i, test_data[i].expected, frame_count);
         }
-        };
+        hr = IWICBitmapDecoder_GetFrameCount(decoder, NULL);
+        ok (hr == E_INVALIDARG, "%d: Expected hr=S_OK, got %x\n", i, hr);
 
     next:
         if (decoder) IWICBitmapDecoder_Release(decoder);




More information about the wine-cvs mailing list