From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 62 ++++++++++++++++++----------------- dlls/d3dx9_36/tests/surface.c | 8 ++--- 2 files changed, 36 insertions(+), 34 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 33ed11b662a..0f692023809 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -1876,8 +1876,8 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic }
static HRESULT d3dx_image_decompress(const void *memory, UINT row_pitch, const RECT *rect, - const struct volume *size, const struct pixel_format_desc *desc, void **out_memory, - UINT *out_row_pitch, RECT *out_rect, const struct pixel_format_desc **out_desc) + const RECT *exclude_rect, const struct volume *size, const struct pixel_format_desc *desc, + void **out_memory, UINT *out_row_pitch, RECT *out_rect, const struct pixel_format_desc **out_desc) { void (*fetch_dxt_texel)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel); const struct pixel_format_desc *uncompressed_desc = NULL; @@ -1909,6 +1909,9 @@ static HRESULT d3dx_image_decompress(const void *memory, UINT row_pitch, const R if (!(uncompressed_mem = malloc(size->width * size->height * size->depth * uncompressed_desc->bytes_per_pixel))) return E_OUTOFMEMORY;
+ if (exclude_rect && EqualRect(rect, exclude_rect)) + goto exit; + TRACE("Decompressing image.\n"); tmp_pitch = row_pitch * desc->block_width / desc->block_byte_count; for (y = 0; y < size->height; ++y) @@ -1916,14 +1919,21 @@ static HRESULT d3dx_image_decompress(const void *memory, UINT row_pitch, const R BYTE *ptr = &uncompressed_mem[y * size->width * uncompressed_desc->bytes_per_pixel]; for (x = 0; x < size->width; ++x) { - fetch_dxt_texel(tmp_pitch, (BYTE *)memory, x + rect->left, y + rect->top, ptr); + const POINT pt = { x, y }; + + if (!PtInRect(exclude_rect, pt)) + fetch_dxt_texel(tmp_pitch, (BYTE *)memory, x + rect->left, y + rect->top, ptr); ptr += uncompressed_desc->bytes_per_pixel; } }
+exit: *out_memory = uncompressed_mem; *out_row_pitch = size->width * uncompressed_desc->bytes_per_pixel; - SetRect(out_rect, 0, 0, size->width, size->height); + if (exclude_rect) + *out_rect = *exclude_rect; + else + SetRect(out_rect, 0, 0, size->width, size->height); *out_desc = uncompressed_desc;
return S_OK; @@ -1992,7 +2002,7 @@ static HRESULT d3dx_load_image_from_memory(void *dst_memory, int32_t dst_row_pit UINT uncompressed_row_pitch; RECT uncompressed_rect;
- hr = d3dx_image_decompress(src_memory, src_row_pitch, src_rect, &src_size, src_desc, + hr = d3dx_image_decompress(src_memory, src_row_pitch, src_rect, NULL, &src_size, src_desc, &uncompressed_mem, &uncompressed_row_pitch, &uncompressed_rect, &uncompressed_desc); if (SUCCEEDED(hr)) { @@ -2007,29 +2017,21 @@ static HRESULT d3dx_load_image_from_memory(void *dst_memory, int32_t dst_row_pit /* Same as the above, need to decompress the destination prior to modifying. */ if (dst_desc->type == FORMAT_DXT) { - size_t dst_uncompressed_size = dst_size_aligned.width * dst_size_aligned.height * sizeof(DWORD); - BOOL dst_misaligned = dst_rect->left != dst_rect_aligned->left - || dst_rect->top != dst_rect_aligned->top - || dst_rect->right != dst_rect_aligned->right - || dst_rect->bottom != dst_rect_aligned->bottom; - const struct pixel_format_desc *dst_uncompressed_desc; - BYTE *dst_uncompressed, *dst_uncompressed_aligned; - UINT dst_uncompressed_row_pitch; - RECT dst_uncompressed_rect; - - dst_uncompressed_aligned = malloc(dst_uncompressed_size); - if (!dst_uncompressed_aligned) - return E_OUTOFMEMORY; - - if (dst_misaligned) memset(dst_uncompressed_aligned, 0, dst_uncompressed_size); - dst_uncompressed_row_pitch = dst_size_aligned.width * sizeof(DWORD); - dst_uncompressed_desc = get_format_info(D3DFMT_A8B8G8R8); - dst_uncompressed = dst_uncompressed_aligned + (dst_rect->top - dst_rect_aligned->top) * dst_uncompressed_row_pitch - + (dst_rect->left - dst_rect_aligned->left) * sizeof(DWORD); - - SetRect(&dst_uncompressed_rect, 0, 0, dst_size.width, dst_size.height); - hr = d3dx_load_image_from_memory(dst_uncompressed, dst_uncompressed_row_pitch, dst_uncompressed_desc, dst_palette, - &dst_uncompressed_rect, &dst_uncompressed_rect, src_memory_offset, src_row_pitch, src_desc, src_palette, + const struct pixel_format_desc *uncompressed_desc; + void *uncompressed_mem = NULL; + BYTE *uncompressed_mem_offset; + UINT uncompressed_row_pitch; + RECT uncompressed_rect; + + hr = d3dx_image_decompress(dst_memory, dst_row_pitch, dst_rect_aligned, dst_rect, &dst_size_aligned, dst_desc, + &uncompressed_mem, &uncompressed_row_pitch, &uncompressed_rect, &uncompressed_desc); + if (FAILED(hr)) + return hr; + + uncompressed_mem_offset = (BYTE *)uncompressed_mem + (dst_rect->top - dst_rect_aligned->top) * uncompressed_row_pitch + + (dst_rect->left - dst_rect_aligned->left) * uncompressed_desc->bytes_per_pixel; + hr = d3dx_load_image_from_memory(uncompressed_mem_offset, uncompressed_row_pitch, uncompressed_desc, dst_palette, + &uncompressed_rect, &uncompressed_rect, src_memory, src_row_pitch, src_desc, src_palette, src_rect, filter_flags, color_key); if (SUCCEEDED(hr)) { @@ -2053,10 +2055,10 @@ static HRESULT d3dx_load_image_from_memory(void *dst_memory, int32_t dst_row_pit ERR("Unexpected destination compressed format %u.\n", dst_desc->format); } TRACE("Compressing DXTn surface.\n"); - tx_compress_dxtn(4, dst_size_aligned.width, dst_size_aligned.height, dst_uncompressed_aligned, gl_format, + tx_compress_dxtn(4, dst_size_aligned.width, dst_size_aligned.height, uncompressed_mem, gl_format, dst_memory, dst_row_pitch); } - free(dst_uncompressed_aligned); + free(uncompressed_mem); return hr; }
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 8823c4e0b52..de2253fa6af 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -1600,14 +1600,14 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) D3DFMT_DXT5, 16 * 2, NULL, &rect, D3DX_FILTER_NONE, 0); ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
- check_dxt_pixel_4bpp(device, newsurf, 8, 8, 0, 0, 0xff0000ff, TRUE); /* Blue block, top left. */ + check_dxt_pixel_4bpp(device, newsurf, 8, 8, 0, 0, 0xff0000ff, FALSE); /* Blue block, top left. */ check_dxt_pixel_4bpp(device, newsurf, 8, 8, 3, 3, 0x000000ff, FALSE); /* Blue block, bottom right. */ - check_dxt_pixel_4bpp(device, newsurf, 8, 8, 7, 0, 0x00ff00ff, TRUE); /* Green block, top right. */ + check_dxt_pixel_4bpp(device, newsurf, 8, 8, 7, 0, 0x00ff00ff, FALSE); /* Green block, top right. */ check_dxt_pixel_4bpp(device, newsurf, 8, 8, 4, 3, 0x000000ff, FALSE); /* Green block, bottom left. */ check_dxt_pixel_4bpp(device, newsurf, 8, 8, 3, 4, 0x000000ff, FALSE); /* Red block, top right. */ - check_dxt_pixel_4bpp(device, newsurf, 8, 8, 0, 7, 0x0000ffff, TRUE); /* Red block, bottom left. */ + check_dxt_pixel_4bpp(device, newsurf, 8, 8, 0, 7, 0x0000ffff, FALSE); /* Red block, bottom left. */ check_dxt_pixel_4bpp(device, newsurf, 8, 8, 4, 4, 0x000000ff, FALSE); /* Black block, top left. */ - check_dxt_pixel_4bpp(device, newsurf, 8, 8, 7, 7, 0x000000ff, TRUE); /* Black block, bottom right. */ + check_dxt_pixel_4bpp(device, newsurf, 8, 8, 7, 7, 0x000000ff, FALSE); /* Black block, bottom right. */
check_release((IUnknown *)newsurf, 1); check_release((IUnknown *)tex, 0);