Ziqing Hui : windowscodecs: Add tests and initial implementation for DdsFrameDecode_CopyPixels().

Alexandre Julliard julliard at winehq.org
Tue Aug 18 16:34:23 CDT 2020


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

Author: Ziqing Hui <zhui at codeweavers.com>
Date:   Mon Aug 17 10:23:47 2020 +0800

windowscodecs: Add tests and initial implementation for DdsFrameDecode_CopyPixels().

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

---

 dlls/windowscodecs/ddsformat.c       | 31 +++++++++++-
 dlls/windowscodecs/tests/ddsformat.c | 91 ++++++++++++++++++++++++++++++++++--
 2 files changed, 115 insertions(+), 7 deletions(-)

diff --git a/dlls/windowscodecs/ddsformat.c b/dlls/windowscodecs/ddsformat.c
index 9f6aab4e91..12b6c42f64 100644
--- a/dlls/windowscodecs/ddsformat.c
+++ b/dlls/windowscodecs/ddsformat.c
@@ -589,9 +589,36 @@ static HRESULT WINAPI DdsFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
 static HRESULT WINAPI DdsFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
                                                 const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer)
 {
-    FIXME("(%p,%s,%u,%u,%p): stub.\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer);
+    DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface);
+    UINT bpp, frame_stride, frame_size;
+    INT x, y, width, height;
 
-    return E_NOTIMPL;
+    TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer);
+
+    if (!pbBuffer) return E_INVALIDARG;
+
+    bpp = This->info.pixel_format_bpp;
+    frame_stride = This->info.width * bpp / 8;
+    frame_size = frame_stride * This->info.height;
+    if (!prc) {
+        if (cbStride < frame_stride) return E_INVALIDARG;
+        if (cbBufferSize < frame_size) return WINCODEC_ERR_INSUFFICIENTBUFFER;
+        return S_OK;
+    }
+
+    x = prc->X;
+    y = prc->Y;
+    width = prc->Width;
+    height = prc->Height;
+    if (x < 0 || y < 0 || width <= 0 || height <= 0 ||
+        x + width > This->info.width ||
+        y + height > This->info.height) {
+        return E_INVALIDARG;
+    }
+    if (cbStride < width * bpp / 8) return E_INVALIDARG;
+    if (cbBufferSize < cbStride * height) return WINCODEC_ERR_INSUFFICIENTBUFFER;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI DdsFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface,
diff --git a/dlls/windowscodecs/tests/ddsformat.c b/dlls/windowscodecs/tests/ddsformat.c
index 49de7e566e..2d5afa8e6e 100644
--- a/dlls/windowscodecs/tests/ddsformat.c
+++ b/dlls/windowscodecs/tests/ddsformat.c
@@ -506,6 +506,29 @@ static BOOL has_extended_header(const BYTE *data)
     return data[84] == 'D' && data[85] == 'X' && data[86] == '1' && data[87] == '0';
 }
 
+static UINT get_pixel_format_bpp(GUID *pixel_format)
+{
+    HRESULT hr;
+    UINT bpp = 0;
+    IWICComponentInfo *info = NULL;
+    IWICPixelFormatInfo* format_info = NULL;
+
+    hr = IWICImagingFactory_CreateComponentInfo(factory, pixel_format, &info);
+    ok(hr == S_OK, "CreateComponentInfo failed, hr %#x\n", hr);
+    if (hr != S_OK) goto end;
+    hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void **)&format_info);
+    ok(hr == S_OK, "QueryInterface failed, hr %#x\n", hr);
+    if (hr != S_OK) goto end;
+    hr = IWICPixelFormatInfo_GetBitsPerPixel(format_info, &bpp);
+    ok(hr == S_OK, "GetBitsPerPixel failed, hr %#x\n", hr);
+
+end:
+    if (format_info) IWICPixelFormatInfo_Release(format_info);
+    if (info) IWICComponentInfo_Release(info);
+
+    return bpp;
+}
+
 static void test_dds_decoder_initialize(void)
 {
     int i;
@@ -767,19 +790,26 @@ static void test_dds_decoder_frame_properties(IWICBitmapFrameDecode *frame_decod
        i, frame_index, debugstr_guid(test_data[i].expected_pixel_format), debugstr_guid(&pixel_format));
 }
 
-static void test_dds_decoder_frame_data(IWICDdsFrameDecode *dds_frame, UINT frame_count, WICDdsParameters *params,
-                                        int i, int frame_index)
+static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFrameDecode *dds_frame, UINT frame_count,
+                                        WICDdsParameters *params, int i, int frame_index)
 {
     HRESULT hr;
+    GUID pixel_format;
     WICDdsFormatInfo format_info;
     WICRect rect = { 0, 0, 1, 1 }, rect_test_a = { 0, 0, 0, 0 }, rect_test_b = { 0, 0, 0xdeadbeaf, 0xdeadbeaf };
     WICRect rect_test_c = { -0xdeadbeaf, -0xdeadbeaf, 1, 1 }, rect_test_d = { 0xdeadbeaf, 0xdeadbeaf, 1, 1 };
-    BYTE buffer[256];
-    UINT stride, frame_stride, frame_size, width_in_blocks, height_in_blocks;
+    BYTE buffer[2048];
+    UINT stride, frame_stride, frame_size, frame_width, frame_height, width_in_blocks, height_in_blocks, bpp;
     UINT width, height, depth, array_index;
     UINT block_offset;
     int slice_index;
 
+    hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &pixel_format);
+    ok(hr == S_OK, "Test %u, frame %u: GetPixelFormat failed, hr %#x\n", i, frame_index, hr);
+    if (hr != S_OK) return;
+    hr = IWICBitmapFrameDecode_GetSize(frame, &frame_width, &frame_height);
+    ok(hr == S_OK, "Test %u, frame %u: GetSize failed, hr %#x\n", i, frame_index, hr);
+    if (hr != S_OK) return;
     hr = IWICDdsFrameDecode_GetFormatInfo(dds_frame, &format_info);
     ok(hr == S_OK, "Test %u, frame %u: GetFormatInfo failed, hr %#x\n", i, frame_index, hr);
     if (hr != S_OK) return;
@@ -790,6 +820,8 @@ static void test_dds_decoder_frame_data(IWICDdsFrameDecode *dds_frame, UINT fram
     frame_stride = width_in_blocks * format_info.BytesPerBlock;
     frame_size = frame_stride * height_in_blocks;
 
+    /* CopyBlocks tests */
+
     hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, 0, 0, NULL);
     ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyBlocks got unexpected hr %#x\n", i, frame_index, hr);
 
@@ -871,6 +903,55 @@ static void test_dds_decoder_frame_data(IWICDdsFrameDecode *dds_frame, UINT fram
     if (hr != S_OK) return;
     ok(!strncmp((const char *)test_data[i].data + block_offset, (const char *)buffer, frame_size),
        "Test %u, frame %u: Block data mismatch\n", i, frame_index);
+
+    /* CopyPixels tests */
+
+    bpp = get_pixel_format_bpp(&pixel_format);
+    stride = rect.Width * bpp / 8;
+    frame_stride = frame_width * bpp / 8;
+
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 0, 0, NULL);
+    ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_a, stride, sizeof(buffer), buffer);
+    ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_b, stride, sizeof(buffer), buffer);
+    ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_c, stride, sizeof(buffer), buffer);
+    ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_d, stride, sizeof(buffer), buffer);
+    ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride - 1, sizeof(buffer), buffer);
+    ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride * 2, sizeof(buffer), buffer);
+    ok(hr == S_OK, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, sizeof(buffer), buffer);
+    ok(hr == S_OK, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, frame_stride * frame_height - 1, buffer);
+    ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, frame_stride * frame_height, buffer);
+    ok(hr == S_OK, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, 0, sizeof(buffer), buffer);
+    ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride - 1, sizeof(buffer), buffer);
+    ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride * 2, sizeof(buffer), buffer);
+    ok(hr == S_OK, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, 0, buffer);
+    ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, 1, buffer);
+    ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER || (hr == S_OK && test_data[i].expected_bytes_per_block == 1),
+       "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, stride * rect.Height - 1, buffer);
+    ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, stride * rect.Height, buffer);
+    ok(hr == S_OK, "Test %u, frame %u: CopyPixels got unexpected hr %#x\n", i, frame_index, hr);
+
+    hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, sizeof(buffer), NULL);
+    ok(hr == E_INVALIDARG, "Test %u, frame %u: CopyBlocks got unexpected hr %#x\n", i, frame_index, hr);
 }
 
 static void test_dds_decoder_frame(IWICBitmapDecoder *decoder, int i)
@@ -905,7 +986,7 @@ static void test_dds_decoder_frame(IWICBitmapDecoder *decoder, int i)
         if (hr != S_OK) goto next;
 
         test_dds_decoder_frame_properties(frame_decode, dds_frame, frame_count, &params, i, j);
-        test_dds_decoder_frame_data(dds_frame, frame_count, &params, i, j);
+        test_dds_decoder_frame_data(frame_decode, dds_frame, frame_count, &params, i, j);
 
     next:
         if (frame_decode) IWICBitmapFrameDecode_Release(frame_decode);




More information about the wine-cvs mailing list