These patches finish moving targa file handling into d3dx9.
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/surface.c | 38 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 8555464fefb..e7cc884bc59 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -596,20 +596,20 @@ static const struct tga_footer default_tga_footer = { { 'T', 'R', 'U', 'E', 'V', 'I', 'S', 'I', 'O', 'N', '-', 'X', 'F', 'I', 'L', 'E', '.', 0 } };
-#define check_tga_image_info(tga, tga_size, expected_width, expected_height, expected_format, expected_hr, todo_hr, todo_info) \ - check_tga_image_info_(__LINE__, tga, tga_size, expected_width, expected_height, expected_format, expected_hr, todo_hr, todo_info) +#define check_tga_image_info(tga, tga_size, expected_width, expected_height, expected_format, expected_hr) \ + check_tga_image_info_(__LINE__, tga, tga_size, expected_width, expected_height, expected_format, expected_hr) static void check_tga_image_info_(uint32_t line, const void *tga, uint32_t tga_size, uint32_t expected_width, - uint32_t expected_height, D3DFORMAT expected_format, HRESULT expected_hr, BOOL todo_hr, BOOL todo_info) + uint32_t expected_height, D3DFORMAT expected_format, HRESULT expected_hr) { D3DXIMAGE_INFO info = { 0 }; HRESULT hr;
hr = D3DXGetImageInfoFromFileInMemory(tga, tga_size, &info); - todo_wine_if(todo_hr) ok_(__FILE__, line)(hr == expected_hr, "Unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(hr == expected_hr, "Unexpected hr %#lx.\n", hr); if (SUCCEEDED(expected_hr) && SUCCEEDED(hr)) { check_image_info_(__FILE__, line, &info, expected_width, expected_height, 1, 1, expected_format, - D3DRTYPE_TEXTURE, D3DXIFF_TGA, todo_info); + D3DRTYPE_TEXTURE, D3DXIFF_TGA, FALSE); } }
@@ -693,18 +693,18 @@ static void test_tga_header_handling(void)
tga->header = info_tests[i].header; check_tga_image_info(tga, file_size, info_tests[i].expected.width, info_tests[i].expected.height, - info_tests[i].expected.format, info_tests[i].expected.hr, FALSE, FALSE); + info_tests[i].expected.format, info_tests[i].expected.hr);
/* X/Y origin fields are ignored. */ tga->header.xorigin = tga->header.width + 1; tga->header.yorigin = tga->header.height + 1; check_tga_image_info(tga, file_size, info_tests[i].expected.width, info_tests[i].expected.height, - info_tests[i].expected.format, info_tests[i].expected.hr, FALSE, FALSE); + info_tests[i].expected.format, info_tests[i].expected.hr);
/* Image descriptor field is ignored. */ tga->header.image_descriptor = 0xcf; check_tga_image_info(tga, file_size, info_tests[i].expected.width, info_tests[i].expected.height, - info_tests[i].expected.format, info_tests[i].expected.hr, FALSE, FALSE); + info_tests[i].expected.format, info_tests[i].expected.hr);
if (FAILED(info_tests[i].expected.hr)) goto next; @@ -717,12 +717,12 @@ static void test_tga_header_handling(void) tmp_footer.extension_area_offset = 65536; memcpy(&tga->data[info_tests[i].extra_header_size], &tmp_footer, sizeof(tmp_footer)); check_tga_image_info(tga, file_size + sizeof(tmp_footer), info_tests[i].expected.width, info_tests[i].expected.height, - info_tests[i].expected.format, info_tests[i].expected.hr, FALSE, FALSE); + info_tests[i].expected.format, info_tests[i].expected.hr);
/* Check RLE type. */ tga->header.image_type |= IMAGETYPE_RLE; check_tga_image_info(tga, file_size, info_tests[i].expected.width, info_tests[i].expected.height, - info_tests[i].expected.format, info_tests[i].expected.hr, FALSE, FALSE); + info_tests[i].expected.format, info_tests[i].expected.hr); tga->header.image_type &= ~IMAGETYPE_RLE;
if (tga->header.image_type == IMAGETYPE_COLORMAPPED) @@ -734,22 +734,22 @@ static void test_tga_header_handling(void) */ tga->header.color_map_length = 1; check_tga_image_info(tga, file_size, info_tests[i].expected.width, info_tests[i].expected.height, - info_tests[i].expected.format, info_tests[i].expected.hr, FALSE, FALSE); + info_tests[i].expected.format, info_tests[i].expected.hr);
tga->header.color_map_entrysize = 8; - check_tga_image_info(tga, file_size, 0, 0, D3DFMT_UNKNOWN, D3DXERR_INVALIDDATA, FALSE, FALSE); + check_tga_image_info(tga, file_size, 0, 0, D3DFMT_UNKNOWN, D3DXERR_INVALIDDATA);
/* Add a byte to file size to account for color map. */ check_tga_image_info(tga, file_size + 1, info_tests[i].expected.width, info_tests[i].expected.height, - info_tests[i].expected.format, info_tests[i].expected.hr, FALSE, FALSE); + info_tests[i].expected.format, info_tests[i].expected.hr);
/* ID length field is also considered. */ tga->header.id_length = 1; - check_tga_image_info(tga, file_size + 1, 0, 0, D3DFMT_UNKNOWN, D3DXERR_INVALIDDATA, FALSE, FALSE); + check_tga_image_info(tga, file_size + 1, 0, 0, D3DFMT_UNKNOWN, D3DXERR_INVALIDDATA);
/* Add another byte to file size to account for id length. */ check_tga_image_info(tga, file_size + 2, info_tests[i].expected.width, info_tests[i].expected.height, - info_tests[i].expected.format, info_tests[i].expected.hr, FALSE, FALSE); + info_tests[i].expected.format, info_tests[i].expected.hr);
/* * If the color map type field is set but the color map fields @@ -759,22 +759,22 @@ static void test_tga_header_handling(void) */ tga->header.id_length = tga->header.color_map_entrysize = tga->header.color_map_length = 0; tga->header.color_map_type = COLORMAP_TYPE_ONE; - check_tga_image_info(tga, file_size + 2, 0, 0, D3DFMT_UNKNOWN, D3DXERR_INVALIDDATA, FALSE, FALSE); + check_tga_image_info(tga, file_size + 2, 0, 0, D3DFMT_UNKNOWN, D3DXERR_INVALIDDATA);
/* 8 isn't a valid entry size. */ tga->header.color_map_entrysize = 8; tga->header.color_map_length = 1; - check_tga_image_info(tga, file_size + 1, 0, 0, D3DFMT_UNKNOWN, D3DXERR_INVALIDDATA, FALSE, FALSE); + check_tga_image_info(tga, file_size + 1, 0, 0, D3DFMT_UNKNOWN, D3DXERR_INVALIDDATA);
/* 16 is a valid entry size. */ tga->header.color_map_entrysize = 16; check_tga_image_info(tga, file_size + 2, info_tests[i].expected.width, info_tests[i].expected.height, - info_tests[i].expected.format, info_tests[i].expected.hr, FALSE, FALSE); + info_tests[i].expected.format, info_tests[i].expected.hr);
/* First entry doesn't factor into validation. */ tga->header.color_map_firstentry = 512; check_tga_image_info(tga, file_size + 2, info_tests[i].expected.width, info_tests[i].expected.height, - info_tests[i].expected.format, info_tests[i].expected.hr, FALSE, FALSE); + info_tests[i].expected.format, info_tests[i].expected.hr); next: winetest_pop_context(); }
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/surface.c | 626 ++++++++++++++++++++++++++++++++++ 1 file changed, 626 insertions(+)
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index e7cc884bc59..1bf8a18bafe 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -566,6 +566,9 @@ static void test_dds_header_handling(void) #define IMAGETYPE_GRAYSCALE 3 #define IMAGETYPE_RLE 8
+#define IMAGE_RIGHTTOLEFT 0x10 +#define IMAGE_TOPTOBOTTOM 0x20 + #include "pshpack1.h" struct tga_header { @@ -1276,15 +1279,22 @@ static uint32_t get_bpp_for_d3dformat(D3DFORMAT format) case D3DFMT_Q16W16V16U16: return 8;
+ case D3DFMT_A8B8G8R8: case D3DFMT_A8R8G8B8: case D3DFMT_V16U16: case D3DFMT_G16R16: return 4;
+ case D3DFMT_R8G8B8: + return 3; + + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: case D3DFMT_V8U8: case D3DFMT_A8P8: return 2;
+ case D3DFMT_L8: case D3DFMT_P8: return 1;
@@ -1525,6 +1535,621 @@ static void test_dxt_premultiplied_alpha(IDirect3DDevice9 *device) IDirect3DSurface9_Release(decomp_surf); }
+static const uint8_t test_tga_color_map_15bpp[] = +{ + 0x00,0x00,0x10,0x00,0x00,0x02,0x10,0x02,0x00,0x40,0x10,0x40,0x00,0x42,0x18,0x63, + 0x78,0x63,0x34,0x7b,0x88,0x00,0x8c,0x00,0x90,0x00,0x94,0x00,0x98,0x00,0x9c,0x00, + 0x00,0x01,0x04,0x01,0x08,0x01,0x0c,0x01,0x10,0x01,0x14,0x01,0x18,0x01,0x1c,0x01, + 0x80,0x01,0x84,0x01,0x88,0x01,0x8c,0x01,0x90,0x01,0x94,0x01,0x98,0x01,0x9c,0x01, + 0x00,0x02,0x04,0x02,0x08,0x02,0x0c,0x02,0x10,0x02,0x14,0x02,0x18,0x02,0x1c,0x02, + 0x80,0x02,0x84,0x02,0x88,0x02,0x8c,0x02,0x90,0x02,0x94,0x02,0x98,0x02,0x9c,0x02, + 0x00,0x03,0x04,0x03,0x08,0x03,0x0c,0x03,0x10,0x03,0x14,0x03,0x18,0x03,0x1c,0x03, + 0x80,0x03,0x84,0x03,0x88,0x03,0x8c,0x03,0x90,0x03,0x94,0x03,0x98,0x03,0x9c,0x03, + 0x00,0x20,0x04,0x20,0x08,0x20,0x0c,0x20,0x10,0x20,0x14,0x20,0x18,0x20,0x1c,0x20, + 0x80,0x20,0x84,0x20,0x88,0x20,0x8c,0x20,0x90,0x20,0x94,0x20,0x98,0x20,0x9c,0x20, + 0x00,0x21,0x04,0x21,0x08,0x21,0x0c,0x21,0x10,0x21,0x14,0x21,0x18,0x21,0x1c,0x21, + 0x80,0x21,0x84,0x21,0x88,0x21,0x8c,0x21,0x90,0x21,0x94,0x21,0x98,0x21,0x9c,0x21, + 0x00,0x22,0x04,0x22,0x08,0x22,0x0c,0x22,0x10,0x22,0x14,0x22,0x18,0x22,0x1c,0x22, + 0x80,0x22,0x84,0x22,0x88,0x22,0x8c,0x22,0x90,0x22,0x94,0x22,0x98,0x22,0x9c,0x22, + 0x00,0x23,0x04,0x23,0x08,0x23,0x0c,0x23,0x10,0x23,0x14,0x23,0x18,0x23,0x1c,0x23, + 0x80,0x23,0x84,0x23,0x88,0x23,0x8c,0x23,0x90,0x23,0x94,0x23,0x98,0x23,0x9c,0x23, + 0x00,0x40,0x04,0x40,0x08,0x40,0x0c,0x40,0x10,0x40,0x14,0x40,0x18,0x40,0x1c,0x40, + 0x80,0x40,0x84,0x40,0x88,0x40,0x8c,0x40,0x90,0x40,0x94,0x40,0x98,0x40,0x9c,0x40, + 0x00,0x41,0x04,0x41,0x08,0x41,0x0c,0x41,0x10,0x41,0x14,0x41,0x18,0x41,0x1c,0x41, + 0x80,0x41,0x84,0x41,0x88,0x41,0x8c,0x41,0x90,0x41,0x94,0x41,0x98,0x41,0x9c,0x41, + 0x00,0x42,0x04,0x42,0x08,0x42,0x0c,0x42,0x10,0x42,0x14,0x42,0x18,0x42,0x1c,0x42, + 0x80,0x42,0x84,0x42,0x88,0x42,0x8c,0x42,0x90,0x42,0x94,0x42,0x98,0x42,0x9c,0x42, + 0x00,0x43,0x04,0x43,0x08,0x43,0x0c,0x43,0x10,0x43,0x14,0x43,0x18,0x43,0x1c,0x43, + 0x80,0x43,0x84,0x43,0x88,0x43,0x8c,0x43,0x90,0x43,0x94,0x43,0x98,0x43,0x9c,0x43, + 0x00,0x60,0x04,0x60,0x08,0x60,0x0c,0x60,0x10,0x60,0x14,0x60,0x18,0x60,0x1c,0x60, + 0x80,0x60,0x84,0x60,0x88,0x60,0x8c,0x60,0x90,0x60,0x94,0x60,0x98,0x60,0x9c,0x60, + 0x00,0x61,0x04,0x61,0x08,0x61,0x0c,0x61,0x10,0x61,0x14,0x61,0x18,0x61,0x1c,0x61, + 0x80,0x61,0x84,0x61,0x88,0x61,0x8c,0x61,0x90,0x61,0x94,0x61,0x98,0x61,0x9c,0x61, + 0x00,0x62,0x04,0x62,0x08,0x62,0x0c,0x62,0x10,0x62,0x14,0x62,0x18,0x62,0x1c,0x62, + 0x80,0x62,0x84,0x62,0x88,0x62,0x8c,0x62,0x90,0x62,0x94,0x62,0x98,0x62,0x9c,0x62, + 0x00,0x63,0x04,0x63,0x08,0x63,0x0c,0x63,0x10,0x63,0x14,0x63,0xff,0x7b,0x94,0x52, + 0x10,0x42,0x1f,0x00,0xe0,0x03,0xff,0x03,0x00,0x7c,0x1f,0x7c,0xe0,0x7f,0xff,0x7f, +}; + +static const uint8_t test_tga_color_map_16bpp[] = +{ + 0x00,0x00,0x10,0x00,0x00,0x02,0x10,0x02,0x00,0x40,0x10,0x40,0x00,0x42,0x18,0x63, + 0x78,0x63,0x34,0x7b,0x88,0x00,0x8c,0x00,0x90,0x00,0x94,0x00,0x98,0x00,0x9c,0x00, + 0x00,0x01,0x04,0x01,0x08,0x01,0x0c,0x01,0x10,0x01,0x14,0x01,0x18,0x01,0x1c,0x01, + 0x80,0x01,0x84,0x01,0x88,0x01,0x8c,0x01,0x90,0x01,0x94,0x01,0x98,0x01,0x9c,0x01, + 0x00,0x02,0x04,0x02,0x08,0x02,0x0c,0x02,0x10,0x02,0x14,0x02,0x18,0x02,0x1c,0x02, + 0x80,0x02,0x84,0x02,0x88,0x02,0x8c,0x02,0x90,0x02,0x94,0x02,0x98,0x02,0x9c,0x02, + 0x00,0x03,0x04,0x03,0x08,0x03,0x0c,0x03,0x10,0x03,0x14,0x03,0x18,0x03,0x1c,0x03, + 0x80,0x03,0x84,0x03,0x88,0x03,0x8c,0x03,0x90,0x03,0x94,0x03,0x98,0x03,0x9c,0x03, + 0x00,0x20,0x04,0x20,0x08,0x20,0x0c,0x20,0x10,0x20,0x14,0x20,0x18,0x20,0x1c,0x20, + 0x80,0x20,0x84,0x20,0x88,0x20,0x8c,0x20,0x90,0x20,0x94,0x20,0x98,0x20,0x9c,0x20, + 0x00,0x21,0x04,0x21,0x08,0x21,0x0c,0x21,0x10,0x21,0x14,0x21,0x18,0x21,0x1c,0x21, + 0x80,0x21,0x84,0x21,0x88,0x21,0x8c,0x21,0x90,0x21,0x94,0x21,0x98,0x21,0x9c,0x21, + 0x00,0x22,0x04,0x22,0x08,0x22,0x0c,0x22,0x10,0x22,0x14,0x22,0x18,0x22,0x1c,0x22, + 0x80,0x22,0x84,0x22,0x88,0x22,0x8c,0x22,0x90,0x22,0x94,0x22,0x98,0x22,0x9c,0x22, + 0x00,0x23,0x04,0x23,0x08,0x23,0x0c,0x23,0x10,0x23,0x14,0x23,0x18,0x23,0x1c,0x23, + 0x80,0x23,0x84,0x23,0x88,0x23,0x8c,0x23,0x90,0x23,0x94,0x23,0x98,0x23,0x9c,0x23, + 0x00,0xc0,0x04,0xc0,0x08,0xc0,0x0c,0xc0,0x10,0xc0,0x14,0xc0,0x18,0xc0,0x1c,0xc0, + 0x80,0xc0,0x84,0xc0,0x88,0xc0,0x8c,0xc0,0x90,0xc0,0x94,0xc0,0x98,0xc0,0x9c,0xc0, + 0x00,0xc1,0x04,0xc1,0x08,0xc1,0x0c,0xc1,0x10,0xc1,0x14,0xc1,0x18,0xc1,0x1c,0xc1, + 0x80,0xc1,0x84,0xc1,0x88,0xc1,0x8c,0xc1,0x90,0xc1,0x94,0xc1,0x98,0xc1,0x9c,0xc1, + 0x00,0xc2,0x04,0xc2,0x08,0xc2,0x0c,0xc2,0x10,0xc2,0x14,0xc2,0x18,0xc2,0x1c,0xc2, + 0x80,0xc2,0x84,0xc2,0x88,0xc2,0x8c,0xc2,0x90,0xc2,0x94,0xc2,0x98,0xc2,0x9c,0xc2, + 0x00,0xc3,0x04,0xc3,0x08,0xc3,0x0c,0xc3,0x10,0xc3,0x14,0xc3,0x18,0xc3,0x1c,0xc3, + 0x80,0xc3,0x84,0xc3,0x88,0xc3,0x8c,0xc3,0x90,0xc3,0x94,0xc3,0x98,0xc3,0x9c,0xc3, + 0x00,0xe0,0x04,0xe0,0x08,0xe0,0x0c,0xe0,0x10,0xe0,0x14,0xe0,0x18,0xe0,0x1c,0xe0, + 0x80,0xe0,0x84,0xe0,0x88,0xe0,0x8c,0xe0,0x90,0xe0,0x94,0xe0,0x98,0xe0,0x9c,0xe0, + 0x00,0xe1,0x04,0xe1,0x08,0xe1,0x0c,0xe1,0x10,0xe1,0x14,0xe1,0x18,0xe1,0x1c,0xe1, + 0x80,0xe1,0x84,0xe1,0x88,0xe1,0x8c,0xe1,0x90,0xe1,0x94,0xe1,0x98,0xe1,0x9c,0xe1, + 0x00,0xe2,0x04,0xe2,0x08,0xe2,0x0c,0xe2,0x10,0xe2,0x14,0xe2,0x18,0xe2,0x1c,0xe2, + 0x80,0xe2,0x84,0xe2,0x88,0xe2,0x8c,0xe2,0x90,0xe2,0x94,0xe2,0x98,0xe2,0x9c,0xe2, + 0x00,0xe3,0x04,0xe3,0x08,0xe3,0x0c,0xe3,0x10,0xe3,0x14,0xe3,0xff,0xfb,0x94,0xd2, + 0x10,0xc2,0x1f,0x80,0xe0,0x83,0xff,0x83,0x00,0xfc,0x1f,0xfc,0xe0,0xff,0xff,0xff, +}; + +static const uint8_t test_tga_color_map_24bpp[] = +{ + 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0x80, + 0x00,0x80,0x00,0x80,0x80,0xc0,0xc0,0xc0,0xc0,0xdc,0xc0,0xa6,0xca,0xf0,0x40,0x20, + 0x00,0x60,0x20,0x00,0x80,0x20,0x00,0xa0,0x20,0x00,0xc0,0x20,0x00,0xe0,0x20,0x00, + 0x00,0x40,0x00,0x20,0x40,0x00,0x40,0x40,0x00,0x60,0x40,0x00,0x80,0x40,0x00,0xa0, + 0x40,0x00,0xc0,0x40,0x00,0xe0,0x40,0x00,0x00,0x60,0x00,0x20,0x60,0x00,0x40,0x60, + 0x00,0x60,0x60,0x00,0x80,0x60,0x00,0xa0,0x60,0x00,0xc0,0x60,0x00,0xe0,0x60,0x00, + 0x00,0x80,0x00,0x20,0x80,0x00,0x40,0x80,0x00,0x60,0x80,0x00,0x80,0x80,0x00,0xa0, + 0x80,0x00,0xc0,0x80,0x00,0xe0,0x80,0x00,0x00,0xa0,0x00,0x20,0xa0,0x00,0x40,0xa0, + 0x00,0x60,0xa0,0x00,0x80,0xa0,0x00,0xa0,0xa0,0x00,0xc0,0xa0,0x00,0xe0,0xa0,0x00, + 0x00,0xc0,0x00,0x20,0xc0,0x00,0x40,0xc0,0x00,0x60,0xc0,0x00,0x80,0xc0,0x00,0xa0, + 0xc0,0x00,0xc0,0xc0,0x00,0xe0,0xc0,0x00,0x00,0xe0,0x00,0x20,0xe0,0x00,0x40,0xe0, + 0x00,0x60,0xe0,0x00,0x80,0xe0,0x00,0xa0,0xe0,0x00,0xc0,0xe0,0x00,0xe0,0xe0,0x00, + 0x00,0x00,0x40,0x20,0x00,0x40,0x40,0x00,0x40,0x60,0x00,0x40,0x80,0x00,0x40,0xa0, + 0x00,0x40,0xc0,0x00,0x40,0xe0,0x00,0x40,0x00,0x20,0x40,0x20,0x20,0x40,0x40,0x20, + 0x40,0x60,0x20,0x40,0x80,0x20,0x40,0xa0,0x20,0x40,0xc0,0x20,0x40,0xe0,0x20,0x40, + 0x00,0x40,0x40,0x20,0x40,0x40,0x40,0x40,0x40,0x60,0x40,0x40,0x80,0x40,0x40,0xa0, + 0x40,0x40,0xc0,0x40,0x40,0xe0,0x40,0x40,0x00,0x60,0x40,0x20,0x60,0x40,0x40,0x60, + 0x40,0x60,0x60,0x40,0x80,0x60,0x40,0xa0,0x60,0x40,0xc0,0x60,0x40,0xe0,0x60,0x40, + 0x00,0x80,0x40,0x20,0x80,0x40,0x40,0x80,0x40,0x60,0x80,0x40,0x80,0x80,0x40,0xa0, + 0x80,0x40,0xc0,0x80,0x40,0xe0,0x80,0x40,0x00,0xa0,0x40,0x20,0xa0,0x40,0x40,0xa0, + 0x40,0x60,0xa0,0x40,0x80,0xa0,0x40,0xa0,0xa0,0x40,0xc0,0xa0,0x40,0xe0,0xa0,0x40, + 0x00,0xc0,0x40,0x20,0xc0,0x40,0x40,0xc0,0x40,0x60,0xc0,0x40,0x80,0xc0,0x40,0xa0, + 0xc0,0x40,0xc0,0xc0,0x40,0xe0,0xc0,0x40,0x00,0xe0,0x40,0x20,0xe0,0x40,0x40,0xe0, + 0x40,0x60,0xe0,0x40,0x80,0xe0,0x40,0xa0,0xe0,0x40,0xc0,0xe0,0x40,0xe0,0xe0,0x40, + 0x00,0x00,0x80,0x20,0x00,0x80,0x40,0x00,0x80,0x60,0x00,0x80,0x80,0x00,0x80,0xa0, + 0x00,0x80,0xc0,0x00,0x80,0xe0,0x00,0x80,0x00,0x20,0x80,0x20,0x20,0x80,0x40,0x20, + 0x80,0x60,0x20,0x80,0x80,0x20,0x80,0xa0,0x20,0x80,0xc0,0x20,0x80,0xe0,0x20,0x80, + 0x00,0x40,0x80,0x20,0x40,0x80,0x40,0x40,0x80,0x60,0x40,0x80,0x80,0x40,0x80,0xa0, + 0x40,0x80,0xc0,0x40,0x80,0xe0,0x40,0x80,0x00,0x60,0x80,0x20,0x60,0x80,0x40,0x60, + 0x80,0x60,0x60,0x80,0x80,0x60,0x80,0xa0,0x60,0x80,0xc0,0x60,0x80,0xe0,0x60,0x80, + 0x00,0x80,0x80,0x20,0x80,0x80,0x40,0x80,0x80,0x60,0x80,0x80,0x80,0x80,0x80,0xa0, + 0x80,0x80,0xc0,0x80,0x80,0xe0,0x80,0x80,0x00,0xa0,0x80,0x20,0xa0,0x80,0x40,0xa0, + 0x80,0x60,0xa0,0x80,0x80,0xa0,0x80,0xa0,0xa0,0x80,0xc0,0xa0,0x80,0xe0,0xa0,0x80, + 0x00,0xc0,0x80,0x20,0xc0,0x80,0x40,0xc0,0x80,0x60,0xc0,0x80,0x80,0xc0,0x80,0xa0, + 0xc0,0x80,0xc0,0xc0,0x80,0xe0,0xc0,0x80,0x00,0xe0,0x80,0x20,0xe0,0x80,0x40,0xe0, + 0x80,0x60,0xe0,0x80,0x80,0xe0,0x80,0xa0,0xe0,0x80,0xc0,0xe0,0x80,0xe0,0xe0,0x80, + 0x00,0x00,0xc0,0x20,0x00,0xc0,0x40,0x00,0xc0,0x60,0x00,0xc0,0x80,0x00,0xc0,0xa0, + 0x00,0xc0,0xc0,0x00,0xc0,0xe0,0x00,0xc0,0x00,0x20,0xc0,0x20,0x20,0xc0,0x40,0x20, + 0xc0,0x60,0x20,0xc0,0x80,0x20,0xc0,0xa0,0x20,0xc0,0xc0,0x20,0xc0,0xe0,0x20,0xc0, + 0x00,0x40,0xc0,0x20,0x40,0xc0,0x40,0x40,0xc0,0x60,0x40,0xc0,0x80,0x40,0xc0,0xa0, + 0x40,0xc0,0xc0,0x40,0xc0,0xe0,0x40,0xc0,0x00,0x60,0xc0,0x20,0x60,0xc0,0x40,0x60, + 0xc0,0x60,0x60,0xc0,0x80,0x60,0xc0,0xa0,0x60,0xc0,0xc0,0x60,0xc0,0xe0,0x60,0xc0, + 0x00,0x80,0xc0,0x20,0x80,0xc0,0x40,0x80,0xc0,0x60,0x80,0xc0,0x80,0x80,0xc0,0xa0, + 0x80,0xc0,0xc0,0x80,0xc0,0xe0,0x80,0xc0,0x00,0xa0,0xc0,0x20,0xa0,0xc0,0x40,0xa0, + 0xc0,0x60,0xa0,0xc0,0x80,0xa0,0xc0,0xa0,0xa0,0xc0,0xc0,0xa0,0xc0,0xe0,0xa0,0xc0, + 0x00,0xc0,0xc0,0x20,0xc0,0xc0,0x40,0xc0,0xc0,0x60,0xc0,0xc0,0x80,0xc0,0xc0,0xa0, + 0xc0,0xc0,0xff,0xfb,0xf0,0xa0,0xa0,0xa4,0x80,0x80,0x80,0xff,0x00,0x00,0x00,0xff, + 0x00,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0xff,0xff, +}; + +static const uint8_t test_tga_color_map_32bpp[] = +{ + 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x01,0x00,0x80,0x00,0x02,0x80,0x80,0x00,0x03, + 0x00,0x00,0x80,0x04,0x80,0x00,0x80,0x05,0x00,0x80,0x80,0x06,0xc0,0xc0,0xc0,0x07, + 0xc0,0xdc,0xc0,0x08,0xa6,0xca,0xf0,0x09,0x40,0x20,0x00,0x0a,0x60,0x20,0x00,0x0b, + 0x80,0x20,0x00,0x0c,0xa0,0x20,0x00,0x0d,0xc0,0x20,0x00,0x0e,0xe0,0x20,0x00,0x0f, + 0x00,0x40,0x00,0x10,0x20,0x40,0x00,0x11,0x40,0x40,0x00,0x12,0x60,0x40,0x00,0x13, + 0x80,0x40,0x00,0x14,0xa0,0x40,0x00,0x15,0xc0,0x40,0x00,0x16,0xe0,0x40,0x00,0x17, + 0x00,0x60,0x00,0x18,0x20,0x60,0x00,0x19,0x40,0x60,0x00,0x1a,0x60,0x60,0x00,0x1b, + 0x80,0x60,0x00,0x1c,0xa0,0x60,0x00,0x1d,0xc0,0x60,0x00,0x1e,0xe0,0x60,0x00,0x1f, + 0x00,0x80,0x00,0x20,0x20,0x80,0x00,0x21,0x40,0x80,0x00,0x22,0x60,0x80,0x00,0x23, + 0x80,0x80,0x00,0x24,0xa0,0x80,0x00,0x25,0xc0,0x80,0x00,0x26,0xe0,0x80,0x00,0x27, + 0x00,0xa0,0x00,0x28,0x20,0xa0,0x00,0x29,0x40,0xa0,0x00,0x2a,0x60,0xa0,0x00,0x2b, + 0x80,0xa0,0x00,0x2c,0xa0,0xa0,0x00,0x2d,0xc0,0xa0,0x00,0x2e,0xe0,0xa0,0x00,0x2f, + 0x00,0xc0,0x00,0x30,0x20,0xc0,0x00,0x31,0x40,0xc0,0x00,0x32,0x60,0xc0,0x00,0x33, + 0x80,0xc0,0x00,0x34,0xa0,0xc0,0x00,0x35,0xc0,0xc0,0x00,0x36,0xe0,0xc0,0x00,0x37, + 0x00,0xe0,0x00,0x38,0x20,0xe0,0x00,0x39,0x40,0xe0,0x00,0x3a,0x60,0xe0,0x00,0x3b, + 0x80,0xe0,0x00,0x3c,0xa0,0xe0,0x00,0x3d,0xc0,0xe0,0x00,0x3e,0xe0,0xe0,0x00,0x3f, + 0x00,0x00,0x40,0x40,0x20,0x00,0x40,0x41,0x40,0x00,0x40,0x42,0x60,0x00,0x40,0x43, + 0x80,0x00,0x40,0x44,0xa0,0x00,0x40,0x45,0xc0,0x00,0x40,0x46,0xe0,0x00,0x40,0x47, + 0x00,0x20,0x40,0x48,0x20,0x20,0x40,0x49,0x40,0x20,0x40,0x4a,0x60,0x20,0x40,0x4b, + 0x80,0x20,0x40,0x4c,0xa0,0x20,0x40,0x4d,0xc0,0x20,0x40,0x4e,0xe0,0x20,0x40,0x4f, + 0x00,0x40,0x40,0x50,0x20,0x40,0x40,0x51,0x40,0x40,0x40,0x52,0x60,0x40,0x40,0x53, + 0x80,0x40,0x40,0x54,0xa0,0x40,0x40,0x55,0xc0,0x40,0x40,0x56,0xe0,0x40,0x40,0x57, + 0x00,0x60,0x40,0x58,0x20,0x60,0x40,0x59,0x40,0x60,0x40,0x5a,0x60,0x60,0x40,0x5b, + 0x80,0x60,0x40,0x5c,0xa0,0x60,0x40,0x5d,0xc0,0x60,0x40,0x5e,0xe0,0x60,0x40,0x5f, + 0x00,0x80,0x40,0x60,0x20,0x80,0x40,0x61,0x40,0x80,0x40,0x62,0x60,0x80,0x40,0x63, + 0x80,0x80,0x40,0x64,0xa0,0x80,0x40,0x65,0xc0,0x80,0x40,0x66,0xe0,0x80,0x40,0x67, + 0x00,0xa0,0x40,0x68,0x20,0xa0,0x40,0x69,0x40,0xa0,0x40,0x6a,0x60,0xa0,0x40,0x6b, + 0x80,0xa0,0x40,0x6c,0xa0,0xa0,0x40,0x6d,0xc0,0xa0,0x40,0x6e,0xe0,0xa0,0x40,0x6f, + 0x00,0xc0,0x40,0x70,0x20,0xc0,0x40,0x71,0x40,0xc0,0x40,0x72,0x60,0xc0,0x40,0x73, + 0x80,0xc0,0x40,0x74,0xa0,0xc0,0x40,0x75,0xc0,0xc0,0x40,0x76,0xe0,0xc0,0x40,0x77, + 0x00,0xe0,0x40,0x78,0x20,0xe0,0x40,0x79,0x40,0xe0,0x40,0x7a,0x60,0xe0,0x40,0x7b, + 0x80,0xe0,0x40,0x7c,0xa0,0xe0,0x40,0x7d,0xc0,0xe0,0x40,0x7e,0xe0,0xe0,0x40,0x7f, + 0x00,0x00,0x80,0x80,0x20,0x00,0x80,0x81,0x40,0x00,0x80,0x82,0x60,0x00,0x80,0x83, + 0x80,0x00,0x80,0x84,0xa0,0x00,0x80,0x85,0xc0,0x00,0x80,0x86,0xe0,0x00,0x80,0x87, + 0x00,0x20,0x80,0x88,0x20,0x20,0x80,0x89,0x40,0x20,0x80,0x8a,0x60,0x20,0x80,0x8b, + 0x80,0x20,0x80,0x8c,0xa0,0x20,0x80,0x8d,0xc0,0x20,0x80,0x8e,0xe0,0x20,0x80,0x8f, + 0x00,0x40,0x80,0x90,0x20,0x40,0x80,0x91,0x40,0x40,0x80,0x92,0x60,0x40,0x80,0x93, + 0x80,0x40,0x80,0x94,0xa0,0x40,0x80,0x95,0xc0,0x40,0x80,0x96,0xe0,0x40,0x80,0x97, + 0x00,0x60,0x80,0x98,0x20,0x60,0x80,0x99,0x40,0x60,0x80,0x9a,0x60,0x60,0x80,0x9b, + 0x80,0x60,0x80,0x9c,0xa0,0x60,0x80,0x9d,0xc0,0x60,0x80,0x9e,0xe0,0x60,0x80,0x9f, + 0x00,0x80,0x80,0xa0,0x20,0x80,0x80,0xa1,0x40,0x80,0x80,0xa2,0x60,0x80,0x80,0xa3, + 0x80,0x80,0x80,0xa4,0xa0,0x80,0x80,0xa5,0xc0,0x80,0x80,0xa6,0xe0,0x80,0x80,0xa7, + 0x00,0xa0,0x80,0xa8,0x20,0xa0,0x80,0xa9,0x40,0xa0,0x80,0xaa,0x60,0xa0,0x80,0xab, + 0x80,0xa0,0x80,0xac,0xa0,0xa0,0x80,0xad,0xc0,0xa0,0x80,0xae,0xe0,0xa0,0x80,0xaf, + 0x00,0xc0,0x80,0xb0,0x20,0xc0,0x80,0xb1,0x40,0xc0,0x80,0xb2,0x60,0xc0,0x80,0xb3, + 0x80,0xc0,0x80,0xb4,0xa0,0xc0,0x80,0xb5,0xc0,0xc0,0x80,0xb6,0xe0,0xc0,0x80,0xb7, + 0x00,0xe0,0x80,0xb8,0x20,0xe0,0x80,0xb9,0x40,0xe0,0x80,0xba,0x60,0xe0,0x80,0xbb, + 0x80,0xe0,0x80,0xbc,0xa0,0xe0,0x80,0xbd,0xc0,0xe0,0x80,0xbe,0xe0,0xe0,0x80,0xbf, + 0x00,0x00,0xc0,0xc0,0x20,0x00,0xc0,0xc1,0x40,0x00,0xc0,0xc2,0x60,0x00,0xc0,0xc3, + 0x80,0x00,0xc0,0xc4,0xa0,0x00,0xc0,0xc5,0xc0,0x00,0xc0,0xc6,0xe0,0x00,0xc0,0xc7, + 0x00,0x20,0xc0,0xc8,0x20,0x20,0xc0,0xc9,0x40,0x20,0xc0,0xca,0x60,0x20,0xc0,0xcb, + 0x80,0x20,0xc0,0xcc,0xa0,0x20,0xc0,0xcd,0xc0,0x20,0xc0,0xce,0xe0,0x20,0xc0,0xcf, + 0x00,0x40,0xc0,0xd0,0x20,0x40,0xc0,0xd1,0x40,0x40,0xc0,0xd2,0x60,0x40,0xc0,0xd3, + 0x80,0x40,0xc0,0xd4,0xa0,0x40,0xc0,0xd5,0xc0,0x40,0xc0,0xd6,0xe0,0x40,0xc0,0xd7, + 0x00,0x60,0xc0,0xd8,0x20,0x60,0xc0,0xd9,0x40,0x60,0xc0,0xda,0x60,0x60,0xc0,0xdb, + 0x80,0x60,0xc0,0xdc,0xa0,0x60,0xc0,0xdd,0xc0,0x60,0xc0,0xde,0xe0,0x60,0xc0,0xdf, + 0x00,0x80,0xc0,0xe0,0x20,0x80,0xc0,0xe1,0x40,0x80,0xc0,0xe2,0x60,0x80,0xc0,0xe3, + 0x80,0x80,0xc0,0xe4,0xa0,0x80,0xc0,0xe5,0xc0,0x80,0xc0,0xe6,0xe0,0x80,0xc0,0xe7, + 0x00,0xa0,0xc0,0xe8,0x20,0xa0,0xc0,0xe9,0x40,0xa0,0xc0,0xea,0x60,0xa0,0xc0,0xeb, + 0x80,0xa0,0xc0,0xec,0xa0,0xa0,0xc0,0xed,0xc0,0xa0,0xc0,0xee,0xe0,0xa0,0xc0,0xef, + 0x00,0xc0,0xc0,0xf0,0x20,0xc0,0xc0,0xf1,0x40,0xc0,0xc0,0xf2,0x60,0xc0,0xc0,0xf3, + 0x80,0xc0,0xc0,0xf4,0xa0,0xc0,0xc0,0xf5,0xff,0xfb,0xf0,0xf6,0xa0,0xa0,0xa4,0xf7, + 0x80,0x80,0x80,0xf8,0xff,0x00,0x00,0xf9,0x00,0xff,0x00,0xfa,0xff,0xff,0x00,0xfb, + 0x00,0x00,0xff,0xfc,0xff,0x00,0xff,0xfd,0x00,0xff,0xff,0xfe,0xff,0xff,0xff,0xff, +}; + +static const uint8_t test_tga_color_map_index_4_4[] = +{ + 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xff, +}; + +static const uint8_t test_tga_color_map_index_4_4_rle[] = +{ + 0x83,0x10,0x83,0x20,0x03,0x80,0x90,0xa0,0xb0,0x03,0xc0,0xd0,0xe0,0xff, +}; + +static const uint8_t test_tga_true_color_15bpp_4_4[] = +{ + 0x00,0x04,0x42,0x0c,0x84,0x14,0xc6,0x1c,0x08,0x25,0x4a,0x2d,0x8c,0x35,0xce,0x3d, + 0x10,0x46,0x52,0x4e,0x94,0x56,0xd6,0x5e,0x18,0x67,0x5a,0x6f,0x9c,0x77,0xde,0x7f, +}; + +static const uint8_t test_tga_true_color_15bpp_4_4_rle[] = +{ + 0x03,0x00,0x04,0x42,0x0c,0x84,0x14,0xc6,0x1c,0x81,0x08,0x25,0x00,0x8c,0x35,0x00, + 0xce,0x3d,0x03,0x10,0x46,0x52,0x4e,0x94,0x56,0xd6,0x5e,0x03,0x18,0x67,0x5a,0x6f, + 0x9c,0x77,0xde,0x7f, +}; + +static const uint8_t test_tga_true_color_16bpp_4_4[] = +{ + 0x00,0x04,0x42,0x0c,0x84,0x14,0xc6,0x1c,0x08,0x25,0x4a,0x2d,0x8c,0x35,0xce,0x3d, + 0x10,0xc6,0x52,0xce,0x94,0xd6,0xd6,0xde,0x18,0xe7,0x5a,0xef,0x9c,0xf7,0xde,0xff, +}; + +static const uint8_t test_tga_true_color_16bpp_4_4_rle[] = +{ + 0x03,0x00,0x04,0x42,0x0c,0x84,0x14,0xc6,0x1c,0x81,0x08,0x25,0x00,0x8c,0x35,0x00, + 0xce,0x3d,0x03,0x10,0xc6,0x52,0xce,0x94,0xd6,0xd6,0xde,0x03,0x18,0xe7,0x5a,0xef, + 0x9c,0xf7,0xde,0xff, +}; + +static const uint8_t test_tga_true_color_24bpp_4_4[] = +{ + 0x00,0x04,0x08,0x10,0x14,0x18,0x20,0x24,0x28,0x30,0x34,0x38,0x40,0x44,0x48,0x50, + 0x54,0x58,0x60,0x64,0x68,0x70,0x74,0x78,0x80,0x84,0x88,0x90,0x94,0x98,0xa0,0xa4, + 0xa8,0xb0,0xb4,0xb8,0xc0,0xc4,0xc8,0xd0,0xd4,0xd8,0xe0,0xe4,0xe8,0xf0,0xf4,0xf8, +}; + +static const uint8_t test_tga_true_color_24bpp_4_4_rle[] = +{ + 0x03,0x00,0x04,0x08,0x10,0x14,0x18,0x20,0x24,0x28,0x30,0x34,0x38,0x81,0x40,0x44, + 0x48,0x00,0x60,0x64,0x68,0x00,0x70,0x74,0x78,0x03,0x80,0x84,0x88,0x90,0x94,0x98, + 0xa0,0xa4,0xa8,0xb0,0xb4,0xb8,0x03,0xc0,0xc4,0xc8,0xd0,0xd4,0xd8,0xe0,0xe4,0xe8, + 0xf0,0xf4,0xf8, +}; + +static const uint8_t test_tga_true_color_32bpp_4_4[] = +{ + 0x08,0x04,0x00,0x0c,0x18,0x14,0x10,0x1c,0x28,0x24,0x20,0x2c,0x38,0x34,0x30,0x3c, + 0x48,0x44,0x40,0x4c,0x58,0x54,0x50,0x5c,0x68,0x64,0x60,0x6c,0x78,0x74,0x70,0x7c, + 0x88,0x84,0x80,0x8c,0x98,0x94,0x90,0x9c,0xa8,0xa4,0xa0,0xac,0xb8,0xb4,0xb0,0xbc, + 0xc8,0xc4,0xc0,0xcc,0xd8,0xd4,0xd0,0xdc,0xe8,0xe4,0xe0,0xec,0xf8,0xf4,0xf0,0xfc, +}; + +static const uint8_t test_tga_true_color_32bpp_4_4_rle[] = +{ + 0x03,0x08,0x04,0x00,0x0c,0x18,0x14,0x10,0x1c,0x28,0x24,0x20,0x2c,0x38,0x34,0x30, + 0x3c,0x81,0x48,0x44,0x40,0x4c,0x00,0x68,0x64,0x60,0x6c,0x00,0x78,0x74,0x70,0x7c, + 0x03,0x88,0x84,0x80,0x8c,0x98,0x94,0x90,0x9c,0xa8,0xa4,0xa0,0xac,0xb8,0xb4,0xb0, + 0xbc,0x03,0xc8,0xc4,0xc0,0xcc,0xd8,0xd4,0xd0,0xdc,0xe8,0xe4,0xe0,0xec,0xf8,0xf4, + 0xf0,0xfc, +}; + +static const uint8_t test_tga_grayscale_8bpp_4_4[] = +{ + 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0, +}; + +static const uint8_t test_tga_grayscale_8bpp_4_4_rle[] = +{ + 0x03,0x00,0x10,0x20,0x30,0x82,0x40,0x00,0x70,0x03,0x80,0x90,0xa0,0xb0,0x03,0xc0, + 0xd0,0xe0,0xf0, +}; + +/* Expected is stored as bottom to top. */ +static const uint8_t test_tga_color_map_15bpp_expected[] = +{ + 0x00,0x00,0x00,0xff,0x00,0x42,0x00,0xff,0x00,0x84,0x00,0xff,0x00,0xc6,0x00,0xff, + 0x42,0x00,0x00,0xff,0x42,0x42,0x00,0xff,0x42,0x84,0x00,0xff,0x42,0xc6,0x00,0xff, + 0x84,0x00,0x00,0xff,0x84,0x42,0x00,0xff,0x84,0x84,0x00,0xff,0x84,0xc6,0x00,0xff, + 0xc6,0x00,0x00,0xff,0xc6,0x42,0x00,0xff,0xc6,0x84,0x00,0xff,0xff,0xff,0xff,0xff, +}; + +static const uint8_t test_tga_color_map_15bpp_rle_expected[] = +{ + 0x00,0x42,0x00,0xff,0x00,0x42,0x00,0xff,0x00,0x42,0x00,0xff,0x00,0x42,0x00,0xff, + 0x00,0x84,0x00,0xff,0x00,0x84,0x00,0xff,0x00,0x84,0x00,0xff,0x00,0x84,0x00,0xff, + 0x84,0x00,0x00,0xff,0x84,0x42,0x00,0xff,0x84,0x84,0x00,0xff,0x84,0xc6,0x00,0xff, + 0xc6,0x00,0x00,0xff,0xc6,0x42,0x00,0xff,0xc6,0x84,0x00,0xff,0xff,0xff,0xff,0xff, +}; + +static const uint8_t test_tga_color_map_16bpp_expected[] = +{ + 0x00,0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0xc6,0x00,0x00, + 0x42,0x00,0x00,0x00,0x42,0x42,0x00,0x00,0x42,0x84,0x00,0x00,0x42,0xc6,0x00,0x00, + 0x84,0x00,0x00,0xff,0x84,0x42,0x00,0xff,0x84,0x84,0x00,0xff,0x84,0xc6,0x00,0xff, + 0xc6,0x00,0x00,0xff,0xc6,0x42,0x00,0xff,0xc6,0x84,0x00,0xff,0xff,0xff,0xff,0xff, +}; + +static const uint8_t test_tga_color_map_24bpp_expected[] = +{ + 0x00,0x00,0x00,0xff,0x00,0x40,0x00,0xff,0x00,0x80,0x00,0xff,0x00,0xc0,0x00,0xff, + 0x40,0x00,0x00,0xff,0x40,0x40,0x00,0xff,0x40,0x80,0x00,0xff,0x40,0xc0,0x00,0xff, + 0x80,0x00,0x00,0xff,0x80,0x40,0x00,0xff,0x80,0x80,0x00,0xff,0x80,0xc0,0x00,0xff, + 0xc0,0x00,0x00,0xff,0xc0,0x40,0x00,0xff,0xc0,0x80,0x00,0xff,0xff,0xff,0xff,0xff, +}; + +static const uint8_t test_tga_color_map_32bpp_expected[] = +{ + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x10,0x00,0x80,0x00,0x20,0x00,0xc0,0x00,0x30, + 0x40,0x00,0x00,0x40,0x40,0x40,0x00,0x50,0x40,0x80,0x00,0x60,0x40,0xc0,0x00,0x70, + 0x80,0x00,0x00,0x80,0x80,0x40,0x00,0x90,0x80,0x80,0x00,0xa0,0x80,0xc0,0x00,0xb0, + 0xc0,0x00,0x00,0xc0,0xc0,0x40,0x00,0xd0,0xc0,0x80,0x00,0xe0,0xff,0xff,0xff,0xff, +}; + +static const uint8_t test_tga_color_map_half_32bpp_expected[] = +{ + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x10,0x00,0x80,0x00,0x20,0x00,0xc0,0x00,0x30, + 0x40,0x00,0x00,0x40,0x40,0x40,0x00,0x50,0x40,0x80,0x00,0x60,0x40,0xc0,0x00,0x70, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +}; + +static const uint8_t test_tga_true_color_15bpp_rle_expected[] = +{ + 0x00,0x04,0x42,0x0c,0x84,0x14,0xc6,0x1c,0x08,0x25,0x08,0x25,0x8c,0x35,0xce,0x3d, + 0x10,0x46,0x52,0x4e,0x94,0x56,0xd6,0x5e,0x18,0x67,0x5a,0x6f,0x9c,0x77,0xde,0x7f, +}; + +static const uint8_t test_tga_true_color_16bpp_rle_expected[] = +{ + 0x00,0x04,0x42,0x0c,0x84,0x14,0xc6,0x1c,0x08,0x25,0x08,0x25,0x8c,0x35,0xce,0x3d, + 0x10,0xc6,0x52,0xce,0x94,0xd6,0xd6,0xde,0x18,0xe7,0x5a,0xef,0x9c,0xf7,0xde,0xff, +}; + +static const uint8_t test_tga_true_color_24bpp_rle_expected[] = +{ + 0x00,0x04,0x08,0x10,0x14,0x18,0x20,0x24,0x28,0x30,0x34,0x38,0x40,0x44,0x48,0x40, + 0x44,0x48,0x60,0x64,0x68,0x70,0x74,0x78,0x80,0x84,0x88,0x90,0x94,0x98,0xa0,0xa4, + 0xa8,0xb0,0xb4,0xb8,0xc0,0xc4,0xc8,0xd0,0xd4,0xd8,0xe0,0xe4,0xe8,0xf0,0xf4,0xf8, +}; + +static const uint8_t test_tga_true_color_32bpp_rle_expected[] = +{ + 0x08,0x04,0x00,0x0c,0x18,0x14,0x10,0x1c,0x28,0x24,0x20,0x2c,0x38,0x34,0x30,0x3c, + 0x48,0x44,0x40,0x4c,0x48,0x44,0x40,0x4c,0x68,0x64,0x60,0x6c,0x78,0x74,0x70,0x7c, + 0x88,0x84,0x80,0x8c,0x98,0x94,0x90,0x9c,0xa8,0xa4,0xa0,0xac,0xb8,0xb4,0xb0,0xbc, + 0xc8,0xc4,0xc0,0xcc,0xd8,0xd4,0xd0,0xdc,0xe8,0xe4,0xe0,0xec,0xf8,0xf4,0xf0,0xfc, +}; + +static const uint8_t test_tga_grayscale_8bpp_rle_expected[] = +{ + 0x00,0x10,0x20,0x30,0x40,0x40,0x40,0x70,0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0, +}; + +#define check_tga_surface_load(surface, expected, right_to_left, bottom_to_top, todo) \ + check_tga_surface_load_(__LINE__, surface, expected, right_to_left, bottom_to_top, todo) +static void check_tga_surface_load_(uint32_t line, IDirect3DSurface9 *surface, const uint8_t *expected, BOOL right_to_left, + BOOL bottom_to_top, BOOL todo) +{ + uint32_t x, y, fmt_bpp, fmt_pitch, mismatch_count; + D3DLOCKED_RECT lock_rect; + D3DSURFACE_DESC desc; + HRESULT hr; + + hr = IDirect3DSurface9_GetDesc(surface, &desc); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + fmt_bpp = get_bpp_for_d3dformat(desc.Format); + fmt_pitch = fmt_bpp * desc.Width; + IDirect3DSurface9_LockRect(surface, &lock_rect, NULL, D3DLOCK_READONLY); + mismatch_count = 0; + for (y = 0; y < desc.Height; ++y) + { + const uint32_t expected_row_idx = bottom_to_top ? (desc.Height - y - 1) : y; + const uint8_t *row = ((uint8_t *)lock_rect.pBits) + (lock_rect.Pitch * y); + const uint8_t *expected_row = expected + (fmt_pitch * expected_row_idx); + + for (x = 0; x < desc.Width; ++x) + { + const uint32_t expected_pixel_idx = right_to_left ? (desc.Width - x - 1) : x; + const uint8_t *expected_pixel = expected_row + (fmt_bpp * expected_pixel_idx); + const uint8_t *pixel = row + (fmt_bpp * x); + BOOL pixel_match = !memcmp(pixel, expected_pixel, fmt_bpp); + + if (!pixel_match) + mismatch_count++; + } + } + todo_wine_if(todo) ok_(__FILE__, line)(!mismatch_count, "%u mismatched pixels.\n", mismatch_count); + IDirect3DSurface9_UnlockRect(surface); +} + +static void test_load_surface_from_tga(IDirect3DDevice9 *device) +{ + static const struct + { + struct tga_header header; + const uint8_t *color_map; + uint32_t color_map_size; + const uint8_t *pixels; + uint32_t pixels_size; + + const uint8_t *expected; + BOOL todo_hr; + BOOL todo_surface; + } tga_tests[] = + { + { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED, 0, 256, 15, 0, 0, 4, 4, 8, 0 }, + test_tga_color_map_15bpp, sizeof(test_tga_color_map_15bpp), + test_tga_color_map_index_4_4, sizeof(test_tga_color_map_index_4_4), + test_tga_color_map_15bpp_expected, + }, + { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED | IMAGETYPE_RLE, 0, 256, 15, 0, 0, 4, 4, 8, 0 }, + test_tga_color_map_15bpp, sizeof(test_tga_color_map_15bpp), + test_tga_color_map_index_4_4_rle, sizeof(test_tga_color_map_index_4_4_rle), + test_tga_color_map_15bpp_rle_expected + }, + { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED, 0, 256, 16, 0, 0, 4, 4, 8, 0 }, + test_tga_color_map_16bpp, sizeof(test_tga_color_map_16bpp), + test_tga_color_map_index_4_4, sizeof(test_tga_color_map_index_4_4), + test_tga_color_map_16bpp_expected, .todo_surface = TRUE + }, + { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED, 0, 256, 24, 0, 0, 4, 4, 8, 0 }, + test_tga_color_map_24bpp, sizeof(test_tga_color_map_24bpp), + test_tga_color_map_index_4_4, sizeof(test_tga_color_map_index_4_4), + test_tga_color_map_24bpp_expected, .todo_surface = TRUE + }, + { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED, 0, 256, 32, 0, 0, 4, 4, 8, 0 }, + test_tga_color_map_32bpp, sizeof(test_tga_color_map_32bpp), + test_tga_color_map_index_4_4, sizeof(test_tga_color_map_index_4_4), + test_tga_color_map_32bpp_expected, .todo_surface = TRUE + }, + { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED, 0, 128, 32, 0, 0, 4, 4, 8, 0 }, + test_tga_color_map_32bpp, sizeof(test_tga_color_map_32bpp) / 2, + test_tga_color_map_index_4_4, sizeof(test_tga_color_map_index_4_4), + test_tga_color_map_half_32bpp_expected, .todo_surface = TRUE + }, + { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR, 0, 0, 0, 0, 0, 4, 4, 15, 0 }, + NULL, 0, + test_tga_true_color_15bpp_4_4, sizeof(test_tga_true_color_15bpp_4_4), + test_tga_true_color_15bpp_4_4, .todo_hr = TRUE + }, + { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR | IMAGETYPE_RLE, 0, 0, 0, 0, 0, 4, 4, 15, 0 }, + NULL, 0, + test_tga_true_color_15bpp_4_4_rle, sizeof(test_tga_true_color_15bpp_4_4_rle), + test_tga_true_color_15bpp_rle_expected, .todo_hr = TRUE + }, + { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR, 0, 0, 0, 0, 0, 4, 4, 16, 0 }, + NULL, 0, + test_tga_true_color_16bpp_4_4, sizeof(test_tga_true_color_16bpp_4_4), + test_tga_true_color_16bpp_4_4, .todo_surface = TRUE + }, + { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR | IMAGETYPE_RLE, 0, 0, 0, 0, 0, 4, 4, 16, 0 }, + NULL, 0, + test_tga_true_color_16bpp_4_4_rle, sizeof(test_tga_true_color_16bpp_4_4_rle), + test_tga_true_color_16bpp_rle_expected, .todo_surface = TRUE + }, + { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR, 0, 0, 0, 0, 0, 4, 4, 24, 0 }, + NULL, 0, + test_tga_true_color_24bpp_4_4, sizeof(test_tga_true_color_24bpp_4_4), + test_tga_true_color_24bpp_4_4, + }, + { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR | IMAGETYPE_RLE, 0, 0, 0, 0, 0, 4, 4, 24, 0 }, + NULL, 0, + test_tga_true_color_24bpp_4_4_rle, sizeof(test_tga_true_color_24bpp_4_4_rle), + test_tga_true_color_24bpp_rle_expected + }, + { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR, 0, 0, 0, 0, 0, 4, 4, 32, 0 }, + NULL, 0, + test_tga_true_color_32bpp_4_4, sizeof(test_tga_true_color_32bpp_4_4), + test_tga_true_color_32bpp_4_4, + }, + { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR | IMAGETYPE_RLE, 0, 0, 0, 0, 0, 4, 4, 32, 0 }, + NULL, 0, + test_tga_true_color_32bpp_4_4_rle, sizeof(test_tga_true_color_32bpp_4_4_rle), + test_tga_true_color_32bpp_rle_expected + }, + { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_GRAYSCALE, 0, 0, 0, 0, 0, 4, 4, 8, 0 }, + NULL, 0, + test_tga_grayscale_8bpp_4_4, sizeof(test_tga_grayscale_8bpp_4_4), + test_tga_grayscale_8bpp_4_4 + }, + { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_GRAYSCALE | IMAGETYPE_RLE, 0, 0, 0, 0, 0, 4, 4, 8, 0 }, + NULL, 0, + test_tga_grayscale_8bpp_4_4_rle, sizeof(test_tga_grayscale_8bpp_4_4_rle), + test_tga_grayscale_8bpp_rle_expected + }, + }; + static const uint8_t rle_test_bits[] = { 15, 16, 24, 32 }; + struct + { + struct tga_header header; + uint8_t data[4096 * 1024]; + } *tga; + IDirect3DSurface9 *surface; + uint32_t i; + HRESULT hr; + + if (!(tga = calloc(1, sizeof(*tga)))) + { + skip("Failed to allocate memory.\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(tga_tests); ++i) + { + const uint32_t file_size = sizeof(tga->header) + tga_tests[i].color_map_size + tga_tests[i].pixels_size; + D3DFORMAT surface_fmt; + D3DXIMAGE_INFO info; + + winetest_push_context("Test %u", i); + + tga->header = tga_tests[i].header; + if (tga_tests[i].color_map) + memcpy(tga->data, tga_tests[i].color_map, tga_tests[i].color_map_size); + memcpy(tga->data + tga_tests[i].color_map_size, tga_tests[i].pixels, tga_tests[i].pixels_size); + + hr = D3DXGetImageInfoFromFileInMemory(tga, file_size, &info); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + surface_fmt = (info.Format == D3DFMT_P8) ? D3DFMT_A8B8G8R8 : info.Format; + + hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, info.Width, info.Height, surface_fmt, D3DPOOL_SCRATCH, + &surface, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + /* + * Unlike D3DXGetImageInfo(), file size must be valid when loading + * image data. + */ + hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size - 1, NULL, D3DX_FILTER_NONE, 0, NULL); + ok(hr == D3DXERR_INVALIDDATA, "Unexpected hr %#lx.\n", hr); + + /* Read as default, bottom to top, left to right. */ + hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); + todo_wine_if(tga_tests[i].todo_hr) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + check_tga_surface_load(surface, tga_tests[i].expected, FALSE, TRUE, tga_tests[i].todo_surface); + + /* Read as top to bottom, left to right. */ + tga->header.image_descriptor = IMAGE_TOPTOBOTTOM; + hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); + todo_wine_if(tga_tests[i].todo_hr) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + check_tga_surface_load(surface, tga_tests[i].expected, FALSE, FALSE, tga_tests[i].todo_surface); + + /* Read as bottom to top, right to left. */ + tga->header.image_descriptor = IMAGE_RIGHTTOLEFT; + hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); + todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + check_tga_surface_load(surface, tga_tests[i].expected, TRUE, TRUE, FALSE); + + /* Read as top to bottom, right to left. */ + tga->header.image_descriptor = IMAGE_TOPTOBOTTOM | IMAGE_RIGHTTOLEFT; + hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); + todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + check_tga_surface_load(surface, tga_tests[i].expected, TRUE, FALSE, FALSE); + + check_release((IUnknown *)surface, 0); + winetest_pop_context(); + } + + /* + * Test RLE behavior. RLE packets cannot cross row boundaries. + */ + for (i = 0; i < ARRAY_SIZE(rle_test_bits); ++i) + { + const struct tga_header rle_hdr = { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR | IMAGETYPE_RLE, 0, 0, 0, 0, 0, + 4, 2, rle_test_bits[i], IMAGE_TOPTOBOTTOM }; + const uint32_t packet_size = ((rle_test_bits[i] + 7) / 8) + 1; + uint32_t file_size = sizeof(tga->header); + D3DFORMAT surface_fmt; + D3DXIMAGE_INFO info; + + winetest_push_context("Test %u", i); + + memset(tga->data, 0, sizeof(tga->data)); + tga->header = rle_hdr; + + hr = D3DXGetImageInfoFromFileInMemory(tga, file_size, &info); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + surface_fmt = info.Format; + + hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, info.Width, info.Height, surface_fmt, D3DPOOL_SCRATCH, + &surface, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + /* + * This packet encodes 8 pixels, but the image has a width of 4. This + * should fail. + */ + tga->data[0] = 0x87; + file_size += packet_size; + hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); + todo_wine_if(rle_test_bits[i] != 15) ok(hr == D3DXERR_INVALIDDATA, "Unexpected hr %#lx.\n", hr); + + /* Two packets, each containing 4 pixels. This succeeds.*/ + tga->data[0] = 0x83; + tga->data[packet_size] = 0x83; + file_size += packet_size; + + hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); + todo_wine_if(rle_test_bits[i] == 15) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + /* Second packet with only 2 pixels, doesn't finish the final row. */ + tga->data[packet_size] = 0x82; + hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); + ok(hr == D3DXERR_INVALIDDATA, "Unexpected hr %#lx.\n", hr); + + check_release((IUnknown *)surface, 0); + winetest_pop_context(); + } + + free(tga); +} + static void test_D3DXLoadSurface(IDirect3DDevice9 *device) { HRESULT hr; @@ -2755,6 +3380,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
test_format_conversion(device); test_dxt_premultiplied_alpha(device); + test_load_surface_from_tga(device);
/* cleanup */ if(testdummy_ok) DeleteFileA("testdummy.bmp");
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 41 ++++++++++++++++++++++++++++++----- dlls/d3dx9_36/tests/surface.c | 8 +++---- 2 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index c56310982dc..cc2d2f22c17 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -1009,6 +1009,9 @@ static D3DFORMAT d3dx_get_tga_format_for_bpp(uint8_t bpp) #define IMAGETYPE_MASK 0x07 #define IMAGETYPE_RLE 8
+#define IMAGE_RIGHTTOLEFT 0x10 +#define IMAGE_TOPTOBOTTOM 0x20 + #include "pshpack1.h" struct tga_header { @@ -1027,7 +1030,32 @@ struct tga_header }; #include "poppack.h"
-static HRESULT d3dx_initialize_image_from_tga(const void *src_data, uint32_t src_data_size, struct d3dx_image *image) +static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_size, uint32_t src_header_size, + struct d3dx_image *image) +{ + const struct tga_header *header = (const struct tga_header *)src_data; + const BOOL right_to_left = !!(header->image_descriptor & IMAGE_RIGHTTOLEFT); + const BOOL bottom_to_top = !(header->image_descriptor & IMAGE_TOPTOBOTTOM); + const BOOL is_rle = !!(header->image_type & IMAGETYPE_RLE); + uint32_t row_pitch, slice_pitch; + HRESULT hr; + + if (image->format == D3DFMT_P8 || is_rle || bottom_to_top || right_to_left) + return E_NOTIMPL; + + hr = d3dx_calculate_pixels_size(image->format, image->size.width, image->size.height, &row_pitch, &slice_pitch); + if (FAILED(hr)) + return hr; + + /* File is too small. */ + if ((src_header_size + slice_pitch) > src_data_size) + return D3DXERR_INVALIDDATA; + + image->pixels = (uint8_t *)src_data + src_header_size; + return D3D_OK; +} + +static HRESULT d3dx_initialize_image_from_tga(const void *src_data, uint32_t src_data_size, struct d3dx_image *image, uint32_t flags) { const struct tga_header *header = (const struct tga_header *)src_data; uint32_t expected_header_size = sizeof(*header); @@ -1073,6 +1101,9 @@ static HRESULT d3dx_initialize_image_from_tga(const void *src_data, uint32_t src image->resource_type = D3DRTYPE_TEXTURE; image->image_file_format = D3DXIFF_TGA;
+ if (!(flags & D3DX_IMAGE_INFO_ONLY)) + return d3dx_image_tga_decode(src_data, src_data_size, expected_header_size, image); + return D3D_OK; }
@@ -1101,10 +1132,10 @@ HRESULT d3dx_image_init(const void *src_data, uint32_t src_data_size, struct d3d }
/* Last resort, try TGA. */ - if (flags & D3DX_IMAGE_INFO_ONLY) - return d3dx_initialize_image_from_tga(src_data, src_data_size, image); - - return d3dx_initialize_image_from_wic(src_data, src_data_size, image, D3DXIFF_TGA, flags); + hr = d3dx_initialize_image_from_tga(src_data, src_data_size, image, flags); + if (hr == E_NOTIMPL) + hr = d3dx_initialize_image_from_wic(src_data, src_data_size, image, D3DXIFF_TGA, flags); + return hr; }
switch (iff) diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 1bf8a18bafe..87627b86124 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -1973,7 +1973,7 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR, 0, 0, 0, 0, 0, 4, 4, 15, 0 }, NULL, 0, test_tga_true_color_15bpp_4_4, sizeof(test_tga_true_color_15bpp_4_4), - test_tga_true_color_15bpp_4_4, .todo_hr = TRUE + test_tga_true_color_15bpp_4_4 }, { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR | IMAGETYPE_RLE, 0, 0, 0, 0, 0, 4, 4, 15, 0 }, NULL, 0, @@ -1983,7 +1983,7 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR, 0, 0, 0, 0, 0, 4, 4, 16, 0 }, NULL, 0, test_tga_true_color_16bpp_4_4, sizeof(test_tga_true_color_16bpp_4_4), - test_tga_true_color_16bpp_4_4, .todo_surface = TRUE + test_tga_true_color_16bpp_4_4 }, { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR | IMAGETYPE_RLE, 0, 0, 0, 0, 0, 4, 4, 16, 0 }, NULL, 0, @@ -2067,9 +2067,9 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device)
/* Read as default, bottom to top, left to right. */ hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine_if(tga_tests[i].todo_hr) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + todo_wine_if(tga_tests[i].todo_hr || tga->header.depth == 15) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) - check_tga_surface_load(surface, tga_tests[i].expected, FALSE, TRUE, tga_tests[i].todo_surface); + check_tga_surface_load(surface, tga_tests[i].expected, FALSE, TRUE, tga_tests[i].todo_surface || tga->header.depth == 16);
/* Read as top to bottom, left to right. */ tga->header.image_descriptor = IMAGE_TOPTOBOTTOM;
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 45 ++++++++++++++++++++++++++++++++--- dlls/d3dx9_36/tests/surface.c | 8 +++---- 2 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index cc2d2f22c17..1797269eee2 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -1036,11 +1036,14 @@ static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_siz const struct tga_header *header = (const struct tga_header *)src_data; const BOOL right_to_left = !!(header->image_descriptor & IMAGE_RIGHTTOLEFT); const BOOL bottom_to_top = !(header->image_descriptor & IMAGE_TOPTOBOTTOM); + const struct pixel_format_desc *fmt_desc = get_format_info(image->format); const BOOL is_rle = !!(header->image_type & IMAGETYPE_RLE); - uint32_t row_pitch, slice_pitch; + uint32_t row_pitch, slice_pitch, i; + uint8_t *img_buf = NULL; + const uint8_t *src_row; HRESULT hr;
- if (image->format == D3DFMT_P8 || is_rle || bottom_to_top || right_to_left) + if (image->format == D3DFMT_P8 || is_rle) return E_NOTIMPL;
hr = d3dx_calculate_pixels_size(image->format, image->size.width, image->size.height, &row_pitch, &slice_pitch); @@ -1051,7 +1054,43 @@ static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_siz if ((src_header_size + slice_pitch) > src_data_size) return D3DXERR_INVALIDDATA;
- image->pixels = (uint8_t *)src_data + src_header_size; + if (!bottom_to_top && !right_to_left) + { + image->pixels = (uint8_t *)src_data + src_header_size; + return D3D_OK; + } + + if (!(img_buf = malloc(slice_pitch))) + return E_OUTOFMEMORY; + + src_row = (const uint8_t *)src_data + src_header_size; + for (i = 0; i < image->size.height; ++i) + { + const uint32_t dst_row_idx = bottom_to_top ? (image->size.height - i - 1) : i; + uint8_t *dst_row = img_buf + (dst_row_idx * row_pitch); + + if (right_to_left) + { + const uint8_t *src_pixel = &src_row[((image->size.width - 1)) * fmt_desc->bytes_per_pixel]; + uint8_t *dst_pixel = dst_row; + uint32_t j; + + for (j = 0; j < image->size.width; ++j) + { + memcpy(dst_pixel, src_pixel, fmt_desc->bytes_per_pixel); + src_pixel -= fmt_desc->bytes_per_pixel; + dst_pixel += fmt_desc->bytes_per_pixel; + } + } + else + { + memcpy(dst_row, src_row, row_pitch); + } + + src_row += row_pitch; + } + + image->image_buf = image->pixels = img_buf; return D3D_OK; }
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 87627b86124..43ff16efb45 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -2067,9 +2067,9 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device)
/* Read as default, bottom to top, left to right. */ hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine_if(tga_tests[i].todo_hr || tga->header.depth == 15) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + todo_wine_if(tga_tests[i].todo_hr) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) - check_tga_surface_load(surface, tga_tests[i].expected, FALSE, TRUE, tga_tests[i].todo_surface || tga->header.depth == 16); + check_tga_surface_load(surface, tga_tests[i].expected, FALSE, TRUE, tga_tests[i].todo_surface);
/* Read as top to bottom, left to right. */ tga->header.image_descriptor = IMAGE_TOPTOBOTTOM; @@ -2081,14 +2081,14 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) /* Read as bottom to top, right to left. */ tga->header.image_descriptor = IMAGE_RIGHTTOLEFT; hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + todo_wine_if(tga_tests[i].color_map || (tga->header.image_type & IMAGETYPE_RLE)) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) check_tga_surface_load(surface, tga_tests[i].expected, TRUE, TRUE, FALSE);
/* Read as top to bottom, right to left. */ tga->header.image_descriptor = IMAGE_TOPTOBOTTOM | IMAGE_RIGHTTOLEFT; hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + todo_wine_if(tga_tests[i].color_map || (tga->header.image_type & IMAGETYPE_RLE)) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) check_tga_surface_load(surface, tga_tests[i].expected, TRUE, FALSE, FALSE);
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 76 ++++++++++++++++++++++++++++++----- dlls/d3dx9_36/tests/surface.c | 12 +++--- 2 files changed, 72 insertions(+), 16 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 1797269eee2..cfe6e525bff 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -1030,6 +1030,44 @@ struct tga_header }; #include "poppack.h"
+static HRESULT d3dx_image_tga_rle_decode_row(const uint8_t **src, uint32_t src_bytes_left, uint32_t row_width, + uint32_t bytes_per_pixel, uint8_t *dst_row) +{ + const uint8_t *src_ptr = *src; + uint32_t pixel_count = 0; + + while (pixel_count != row_width) + { + uint32_t rle_count = (src_ptr[0] & 0x7f) + 1; + uint32_t rle_packet_size = 1; + + rle_packet_size += (src_ptr[0] & 0x80) ? bytes_per_pixel : (bytes_per_pixel * rle_count); + if ((rle_packet_size > src_bytes_left) || (pixel_count + rle_count) > row_width) + return D3DXERR_INVALIDDATA; + + if (src_ptr[0] & 0x80) + { + uint32_t i; + + for (i = 0; i < rle_count; ++i) + memcpy(&dst_row[(pixel_count + i) * bytes_per_pixel], src_ptr + 1, bytes_per_pixel); + } + else + { + memcpy(&dst_row[pixel_count * bytes_per_pixel], (src_ptr + 1), rle_packet_size - 1); + } + + src_ptr += rle_packet_size; + src_bytes_left -= rle_packet_size; + pixel_count += rle_count; + if (!src_bytes_left && pixel_count != row_width) + return D3DXERR_INVALIDDATA; + } + + *src = src_ptr; + return D3D_OK; +} + static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_size, uint32_t src_header_size, struct d3dx_image *image) { @@ -1039,11 +1077,11 @@ static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_siz const struct pixel_format_desc *fmt_desc = get_format_info(image->format); const BOOL is_rle = !!(header->image_type & IMAGETYPE_RLE); uint32_t row_pitch, slice_pitch, i; - uint8_t *img_buf = NULL; - const uint8_t *src_row; + uint8_t *img_buf = NULL, *src_row; + const uint8_t *src_pos; HRESULT hr;
- if (image->format == D3DFMT_P8 || is_rle) + if (image->format == D3DFMT_P8) return E_NOTIMPL;
hr = d3dx_calculate_pixels_size(image->format, image->size.width, image->size.height, &row_pitch, &slice_pitch); @@ -1051,24 +1089,39 @@ static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_siz return hr;
/* File is too small. */ - if ((src_header_size + slice_pitch) > src_data_size) + if (!is_rle && (src_header_size + slice_pitch) > src_data_size) return D3DXERR_INVALIDDATA;
- if (!bottom_to_top && !right_to_left) + if (!is_rle && !bottom_to_top && !right_to_left) { image->pixels = (uint8_t *)src_data + src_header_size; return D3D_OK; }
- if (!(img_buf = malloc(slice_pitch))) + /* Allocate an extra row to use as a temporary buffer. */ + if (!(img_buf = malloc(slice_pitch + row_pitch))) return E_OUTOFMEMORY;
- src_row = (const uint8_t *)src_data + src_header_size; + src_row = img_buf + slice_pitch; + src_pos = (const uint8_t *)src_data + src_header_size; for (i = 0; i < image->size.height; ++i) { const uint32_t dst_row_idx = bottom_to_top ? (image->size.height - i - 1) : i; uint8_t *dst_row = img_buf + (dst_row_idx * row_pitch);
+ if (is_rle) + { + hr = d3dx_image_tga_rle_decode_row(&src_pos, src_data_size - (src_pos - (const uint8_t *)src_data), + image->size.width, fmt_desc->bytes_per_pixel, src_row); + if (FAILED(hr)) + goto exit; + } + else + { + memcpy(src_row, src_pos, row_pitch); + src_pos += row_pitch; + } + if (right_to_left) { const uint8_t *src_pixel = &src_row[((image->size.width - 1)) * fmt_desc->bytes_per_pixel]; @@ -1086,12 +1139,15 @@ static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_siz { memcpy(dst_row, src_row, row_pitch); } - - src_row += row_pitch; }
image->image_buf = image->pixels = img_buf; - return D3D_OK; + +exit: + if (img_buf && (image->image_buf != img_buf)) + free(img_buf); + + return hr; }
static HRESULT d3dx_initialize_image_from_tga(const void *src_data, uint32_t src_data_size, struct d3dx_image *image, uint32_t flags) diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 43ff16efb45..011c5392460 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -1978,7 +1978,7 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR | IMAGETYPE_RLE, 0, 0, 0, 0, 0, 4, 4, 15, 0 }, NULL, 0, test_tga_true_color_15bpp_4_4_rle, sizeof(test_tga_true_color_15bpp_4_4_rle), - test_tga_true_color_15bpp_rle_expected, .todo_hr = TRUE + test_tga_true_color_15bpp_rle_expected }, { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR, 0, 0, 0, 0, 0, 4, 4, 16, 0 }, NULL, 0, @@ -1988,7 +1988,7 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR | IMAGETYPE_RLE, 0, 0, 0, 0, 0, 4, 4, 16, 0 }, NULL, 0, test_tga_true_color_16bpp_4_4_rle, sizeof(test_tga_true_color_16bpp_4_4_rle), - test_tga_true_color_16bpp_rle_expected, .todo_surface = TRUE + test_tga_true_color_16bpp_rle_expected }, { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR, 0, 0, 0, 0, 0, 4, 4, 24, 0 }, NULL, 0, @@ -2081,14 +2081,14 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) /* Read as bottom to top, right to left. */ tga->header.image_descriptor = IMAGE_RIGHTTOLEFT; hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine_if(tga_tests[i].color_map || (tga->header.image_type & IMAGETYPE_RLE)) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + todo_wine_if(tga_tests[i].color_map) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) check_tga_surface_load(surface, tga_tests[i].expected, TRUE, TRUE, FALSE);
/* Read as top to bottom, right to left. */ tga->header.image_descriptor = IMAGE_TOPTOBOTTOM | IMAGE_RIGHTTOLEFT; hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine_if(tga_tests[i].color_map || (tga->header.image_type & IMAGETYPE_RLE)) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + todo_wine_if(tga_tests[i].color_map) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) check_tga_surface_load(surface, tga_tests[i].expected, TRUE, FALSE, FALSE);
@@ -2128,7 +2128,7 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) tga->data[0] = 0x87; file_size += packet_size; hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine_if(rle_test_bits[i] != 15) ok(hr == D3DXERR_INVALIDDATA, "Unexpected hr %#lx.\n", hr); + ok(hr == D3DXERR_INVALIDDATA, "Unexpected hr %#lx.\n", hr);
/* Two packets, each containing 4 pixels. This succeeds.*/ tga->data[0] = 0x83; @@ -2136,7 +2136,7 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) file_size += packet_size;
hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine_if(rle_test_bits[i] == 15) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
/* Second packet with only 2 pixels, doesn't finish the final row. */ tga->data[packet_size] = 0x82;
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 54 ++++++++++++++++++++++++++--------- dlls/d3dx9_36/tests/surface.c | 43 +++++++++++----------------- 2 files changed, 57 insertions(+), 40 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index cfe6e525bff..e635d46a2b3 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -32,9 +32,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**);
-/* Wine-specific WIC GUIDs */ -DEFINE_GUID(GUID_WineContainerFormatTga, 0x0c44fda1,0xa5c5,0x4298,0x96,0x85,0x47,0x3f,0xc1,0x7c,0xd3,0x22); - static const struct { const GUID *wic_guid; @@ -755,8 +752,7 @@ static BOOL image_is_argb(IWICBitmapFrameDecode *frame, struct d3dx_image *image BYTE *buffer; HRESULT hr;
- if (image->format != D3DFMT_X8R8G8B8 || (image->image_file_format != D3DXIFF_BMP - && image->image_file_format != D3DXIFF_TGA)) + if (image->format != D3DFMT_X8R8G8B8 || image->image_file_format != D3DXIFF_BMP) return FALSE;
size = image->size.width * image->size.height * 4; @@ -794,7 +790,6 @@ static const GUID *d3dx_file_format_to_wic_container_guid(D3DXIMAGE_FILEFORMAT i switch (iff) { case D3DXIFF_BMP: return &GUID_ContainerFormatBmp; - case D3DXIFF_TGA: return &GUID_WineContainerFormatTga; case D3DXIFF_JPG: return &GUID_ContainerFormatJpeg; case D3DXIFF_PNG: return &GUID_ContainerFormatPng; default: @@ -1078,12 +1073,10 @@ static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_siz const BOOL is_rle = !!(header->image_type & IMAGETYPE_RLE); uint32_t row_pitch, slice_pitch, i; uint8_t *img_buf = NULL, *src_row; + PALETTEENTRY *palette = NULL; const uint8_t *src_pos; HRESULT hr;
- if (image->format == D3DFMT_P8) - return E_NOTIMPL; - hr = d3dx_calculate_pixels_size(image->format, image->size.width, image->size.height, &row_pitch, &slice_pitch); if (FAILED(hr)) return hr; @@ -1092,15 +1085,48 @@ static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_siz if (!is_rle && (src_header_size + slice_pitch) > src_data_size) return D3DXERR_INVALIDDATA;
+ if (image->format == D3DFMT_P8) + { + const uint8_t *src_palette = ((const uint8_t *)src_data) + sizeof(*header) + header->id_length; + const struct volume image_map_size = { header->color_map_length, 1, 1 }; + uint32_t src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; + const struct pixel_format_desc *src_desc, *dst_desc; + + if (!(palette = malloc(sizeof(*palette) * 256))) + return E_OUTOFMEMORY; + + /* + * Convert from a TGA colormap to PALETTEENTRY. TGA is BGRA, + * PALETTEENTRY is RGBA. + */ + src_desc = get_format_info(d3dx_get_tga_format_for_bpp(header->color_map_entrysize)); + hr = d3dx_calculate_pixels_size(src_desc->format, header->color_map_length, 1, &src_row_pitch, &src_slice_pitch); + if (FAILED(hr)) + goto exit; + + dst_desc = get_format_info(D3DFMT_A8B8G8R8); + d3dx_calculate_pixels_size(dst_desc->format, 256, 1, &dst_row_pitch, &dst_slice_pitch); + convert_argb_pixels(src_palette, src_row_pitch, src_slice_pitch, &image_map_size, src_desc, (BYTE *)palette, + dst_row_pitch, dst_slice_pitch, &image_map_size, dst_desc, 0, NULL); + + /* Initialize unused palette entries to 0xff. */ + if (header->color_map_length < 256) + memset(&palette[header->color_map_length], 0xff, sizeof(*palette) * (256 - header->color_map_length)); + } + if (!is_rle && !bottom_to_top && !right_to_left) { image->pixels = (uint8_t *)src_data + src_header_size; + image->image_palette = image->palette = palette; return D3D_OK; }
/* Allocate an extra row to use as a temporary buffer. */ if (!(img_buf = malloc(slice_pitch + row_pitch))) - return E_OUTOFMEMORY; + { + hr = E_OUTOFMEMORY; + goto exit; + }
src_row = img_buf + slice_pitch; src_pos = (const uint8_t *)src_data + src_header_size; @@ -1142,10 +1168,13 @@ static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_siz }
image->image_buf = image->pixels = img_buf; + image->image_palette = image->palette = palette;
exit: if (img_buf && (image->image_buf != img_buf)) free(img_buf); + if (palette && (image->image_palette != palette)) + free(palette);
return hr; } @@ -1227,10 +1256,7 @@ HRESULT d3dx_image_init(const void *src_data, uint32_t src_data_size, struct d3d }
/* Last resort, try TGA. */ - hr = d3dx_initialize_image_from_tga(src_data, src_data_size, image, flags); - if (hr == E_NOTIMPL) - hr = d3dx_initialize_image_from_wic(src_data, src_data_size, image, D3DXIFF_TGA, flags); - return hr; + return d3dx_initialize_image_from_tga(src_data, src_data_size, image, flags); }
switch (iff) diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 011c5392460..1b3f28dfd7a 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -1887,12 +1887,12 @@ static const uint8_t test_tga_grayscale_8bpp_rle_expected[] = 0x00,0x10,0x20,0x30,0x40,0x40,0x40,0x70,0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0, };
-#define check_tga_surface_load(surface, expected, right_to_left, bottom_to_top, todo) \ - check_tga_surface_load_(__LINE__, surface, expected, right_to_left, bottom_to_top, todo) +#define check_tga_surface_load(surface, expected, right_to_left, bottom_to_top) \ + check_tga_surface_load_(__LINE__, surface, expected, right_to_left, bottom_to_top) static void check_tga_surface_load_(uint32_t line, IDirect3DSurface9 *surface, const uint8_t *expected, BOOL right_to_left, - BOOL bottom_to_top, BOOL todo) + BOOL bottom_to_top) { - uint32_t x, y, fmt_bpp, fmt_pitch, mismatch_count; + uint32_t x, y, fmt_bpp, fmt_pitch; D3DLOCKED_RECT lock_rect; D3DSURFACE_DESC desc; HRESULT hr; @@ -1903,7 +1903,6 @@ static void check_tga_surface_load_(uint32_t line, IDirect3DSurface9 *surface, c fmt_bpp = get_bpp_for_d3dformat(desc.Format); fmt_pitch = fmt_bpp * desc.Width; IDirect3DSurface9_LockRect(surface, &lock_rect, NULL, D3DLOCK_READONLY); - mismatch_count = 0; for (y = 0; y < desc.Height; ++y) { const uint32_t expected_row_idx = bottom_to_top ? (desc.Height - y - 1) : y; @@ -1917,11 +1916,9 @@ static void check_tga_surface_load_(uint32_t line, IDirect3DSurface9 *surface, c const uint8_t *pixel = row + (fmt_bpp * x); BOOL pixel_match = !memcmp(pixel, expected_pixel, fmt_bpp);
- if (!pixel_match) - mismatch_count++; + ok_(__FILE__, line)(pixel_match, "Pixel mismatch at (%u,%u).\n", x, y); } } - todo_wine_if(todo) ok_(__FILE__, line)(!mismatch_count, "%u mismatched pixels.\n", mismatch_count); IDirect3DSurface9_UnlockRect(surface); }
@@ -1936,8 +1933,6 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) uint32_t pixels_size;
const uint8_t *expected; - BOOL todo_hr; - BOOL todo_surface; } tga_tests[] = { { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED, 0, 256, 15, 0, 0, 4, 4, 8, 0 }, @@ -1953,22 +1948,22 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device) { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED, 0, 256, 16, 0, 0, 4, 4, 8, 0 }, test_tga_color_map_16bpp, sizeof(test_tga_color_map_16bpp), test_tga_color_map_index_4_4, sizeof(test_tga_color_map_index_4_4), - test_tga_color_map_16bpp_expected, .todo_surface = TRUE + test_tga_color_map_16bpp_expected }, { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED, 0, 256, 24, 0, 0, 4, 4, 8, 0 }, test_tga_color_map_24bpp, sizeof(test_tga_color_map_24bpp), test_tga_color_map_index_4_4, sizeof(test_tga_color_map_index_4_4), - test_tga_color_map_24bpp_expected, .todo_surface = TRUE + test_tga_color_map_24bpp_expected }, { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED, 0, 256, 32, 0, 0, 4, 4, 8, 0 }, test_tga_color_map_32bpp, sizeof(test_tga_color_map_32bpp), test_tga_color_map_index_4_4, sizeof(test_tga_color_map_index_4_4), - test_tga_color_map_32bpp_expected, .todo_surface = TRUE + test_tga_color_map_32bpp_expected }, { { 0, COLORMAP_TYPE_ONE, IMAGETYPE_COLORMAPPED, 0, 128, 32, 0, 0, 4, 4, 8, 0 }, test_tga_color_map_32bpp, sizeof(test_tga_color_map_32bpp) / 2, test_tga_color_map_index_4_4, sizeof(test_tga_color_map_index_4_4), - test_tga_color_map_half_32bpp_expected, .todo_surface = TRUE + test_tga_color_map_half_32bpp_expected }, { { 0, COLORMAP_TYPE_NONE, IMAGETYPE_TRUECOLOR, 0, 0, 0, 0, 0, 4, 4, 15, 0 }, NULL, 0, @@ -2067,30 +2062,26 @@ static void test_load_surface_from_tga(IDirect3DDevice9 *device)
/* Read as default, bottom to top, left to right. */ hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine_if(tga_tests[i].todo_hr) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - check_tga_surface_load(surface, tga_tests[i].expected, FALSE, TRUE, tga_tests[i].todo_surface); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + check_tga_surface_load(surface, tga_tests[i].expected, FALSE, TRUE);
/* Read as top to bottom, left to right. */ tga->header.image_descriptor = IMAGE_TOPTOBOTTOM; hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine_if(tga_tests[i].todo_hr) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - check_tga_surface_load(surface, tga_tests[i].expected, FALSE, FALSE, tga_tests[i].todo_surface); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + check_tga_surface_load(surface, tga_tests[i].expected, FALSE, FALSE);
/* Read as bottom to top, right to left. */ tga->header.image_descriptor = IMAGE_RIGHTTOLEFT; hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine_if(tga_tests[i].color_map) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - check_tga_surface_load(surface, tga_tests[i].expected, TRUE, TRUE, FALSE); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + check_tga_surface_load(surface, tga_tests[i].expected, TRUE, TRUE);
/* Read as top to bottom, right to left. */ tga->header.image_descriptor = IMAGE_TOPTOBOTTOM | IMAGE_RIGHTTOLEFT; hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, tga, file_size, NULL, D3DX_FILTER_NONE, 0, NULL); - todo_wine_if(tga_tests[i].color_map) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - check_tga_surface_load(surface, tga_tests[i].expected, TRUE, FALSE, FALSE); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + check_tga_surface_load(surface, tga_tests[i].expected, TRUE, FALSE);
check_release((IUnknown *)surface, 0); winetest_pop_context();