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

Signed-off-by: Ziqing Hui <zhui@codeweavers.com>
Signed-off-by: Esme Povirk <esme@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Ziqing Hui 2020-08-17 10:23:47 +08:00 committed by Alexandre Julliard
parent bec58b5e9c
commit f178907850
2 changed files with 115 additions and 7 deletions

View File

@ -589,9 +589,36 @@ static HRESULT WINAPI DdsFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface,
static HRESULT WINAPI DdsFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, static HRESULT WINAPI DdsFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface,
const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) 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, static HRESULT WINAPI DdsFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface,

View File

@ -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'; 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) static void test_dds_decoder_initialize(void)
{ {
int i; 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)); 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, static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFrameDecode *dds_frame, UINT frame_count,
int i, int frame_index) WICDdsParameters *params, int i, int frame_index)
{ {
HRESULT hr; HRESULT hr;
GUID pixel_format;
WICDdsFormatInfo format_info; 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 = { 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 }; WICRect rect_test_c = { -0xdeadbeaf, -0xdeadbeaf, 1, 1 }, rect_test_d = { 0xdeadbeaf, 0xdeadbeaf, 1, 1 };
BYTE buffer[256]; BYTE buffer[2048];
UINT stride, frame_stride, frame_size, width_in_blocks, height_in_blocks; UINT stride, frame_stride, frame_size, frame_width, frame_height, width_in_blocks, height_in_blocks, bpp;
UINT width, height, depth, array_index; UINT width, height, depth, array_index;
UINT block_offset; UINT block_offset;
int slice_index; 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); hr = IWICDdsFrameDecode_GetFormatInfo(dds_frame, &format_info);
ok(hr == S_OK, "Test %u, frame %u: GetFormatInfo failed, hr %#x\n", i, frame_index, hr); ok(hr == S_OK, "Test %u, frame %u: GetFormatInfo failed, hr %#x\n", i, frame_index, hr);
if (hr != S_OK) return; 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_stride = width_in_blocks * format_info.BytesPerBlock;
frame_size = frame_stride * height_in_blocks; frame_size = frame_stride * height_in_blocks;
/* CopyBlocks tests */
hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, 0, 0, NULL); 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); 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; if (hr != S_OK) return;
ok(!strncmp((const char *)test_data[i].data + block_offset, (const char *)buffer, frame_size), 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); "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) 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; if (hr != S_OK) goto next;
test_dds_decoder_frame_properties(frame_decode, dds_frame, frame_count, &params, i, j); 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: next:
if (frame_decode) IWICBitmapFrameDecode_Release(frame_decode); if (frame_decode) IWICBitmapFrameDecode_Release(frame_decode);