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, ¶ms, i, j);
- test_dds_decoder_frame_data(dds_frame, frame_count, ¶ms, i, j);
+ test_dds_decoder_frame_data(frame_decode, dds_frame, frame_count, ¶ms, i, j);
next:
if (frame_decode) IWICBitmapFrameDecode_Release(frame_decode);
More information about the wine-cvs
mailing list