Module: wine Branch: master Commit: fa398d6ec0b2f9b7d4b6ed272b83bf2ee1c06a5a URL: https://source.winehq.org/git/wine.git/?a=commit;h=fa398d6ec0b2f9b7d4b6ed272...
Author: Ziqing Hui zhui@codeweavers.com Date: Thu Aug 27 13:36:47 2020 +0800
windowscodecs: Fix DdsFrameDecode_Dds_CopyBlocks().
Signed-off-by: Ziqing Hui zhui@codeweavers.com Signed-off-by: Esme Povirk esme@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/windowscodecs/ddsformat.c | 42 ++++++++++++++---------------------- dlls/windowscodecs/tests/ddsformat.c | 1 - 2 files changed, 16 insertions(+), 27 deletions(-)
diff --git a/dlls/windowscodecs/ddsformat.c b/dlls/windowscodecs/ddsformat.c index 72c884b0ed..7e3bd44bd8 100644 --- a/dlls/windowscodecs/ddsformat.c +++ b/dlls/windowscodecs/ddsformat.c @@ -891,8 +891,7 @@ static HRESULT WINAPI DdsFrameDecode_Dds_CopyBlocks(IWICDdsFrameDecode *iface, { DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); int x, y, width, height; - UINT bytes_per_block, frame_stride, frame_size, i; - BYTE *data, *dst_buffer; + UINT bytes_per_block, frame_stride, frame_size;
TRACE("(%p,%p,%u,%u,%p)\n", iface, boundsInBlocks, stride, bufferSize, buffer);
@@ -901,35 +900,26 @@ static HRESULT WINAPI DdsFrameDecode_Dds_CopyBlocks(IWICDdsFrameDecode *iface, bytes_per_block = This->info.bytes_per_block; frame_stride = This->info.width_in_blocks * bytes_per_block; frame_size = frame_stride * This->info.height_in_blocks; + if (!boundsInBlocks) { if (stride < frame_stride) return E_INVALIDARG; if (bufferSize < frame_size) return E_INVALIDARG; - memcpy(buffer, This->block_data, frame_size); - return S_OK; - } - - x = boundsInBlocks->X; - y = boundsInBlocks->Y; - width = boundsInBlocks->Width; - height = boundsInBlocks->Height; - if (x < 0 || y < 0 || width <= 0 || height <= 0 || - x + width > This->info.width_in_blocks || - y + height > This->info.height_in_blocks) { - return E_INVALIDARG; - } - if (stride < width * bytes_per_block) return E_INVALIDARG; - if (bufferSize < stride * height) return E_INVALIDARG; - - data = This->block_data + (x + y * This->info.width_in_blocks) * bytes_per_block; - dst_buffer = buffer; - for (i = 0; i < height; i++) - { - memcpy(dst_buffer, data, (size_t)width * bytes_per_block); - data += This->info.width_in_blocks * bytes_per_block; - dst_buffer += stride; + } else { + x = boundsInBlocks->X; + y = boundsInBlocks->Y; + width = boundsInBlocks->Width; + height = boundsInBlocks->Height; + if (x < 0 || y < 0 || width <= 0 || height <= 0 || + x + width > This->info.width_in_blocks || + y + height > This->info.height_in_blocks) { + return E_INVALIDARG; + } + if (stride < width * bytes_per_block) return E_INVALIDARG; + if (bufferSize < stride * height) return E_INVALIDARG; }
- return S_OK; + return copy_pixels(This->info.bytes_per_block * 8, This->block_data, This->info.width_in_blocks, + This->info.height_in_blocks, frame_stride, boundsInBlocks, stride, bufferSize, buffer); }
static const IWICDdsFrameDecodeVtbl DdsFrameDecode_Dds_Vtbl = { diff --git a/dlls/windowscodecs/tests/ddsformat.c b/dlls/windowscodecs/tests/ddsformat.c index 1ce249c4b4..37ed17bd79 100644 --- a/dlls/windowscodecs/tests/ddsformat.c +++ b/dlls/windowscodecs/tests/ddsformat.c @@ -1064,7 +1064,6 @@ static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFra hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride * 2, sizeof(buffer), buffer); ok(hr == S_OK, "Test %u, frame %u: CopyBlocks failed, hr %#x\n", i, frame_index, hr); if (hr != S_OK) return; - todo_wine_if(width_in_blocks > 1) ok(!memcmp(pixels, buffer, frame_size), "Test %u, frame %u: Block data mismatch\n", i, frame_index);