This patch series reworks `D3DXSaveSurfaceToFileInMemory()` to use the new `d3dx_save_pixels_to_memory()` function.
It also adds support for selecting a replacement pixel format when the image file format being saved to doesn't have direct support for the pixel format being saved. The code for calculating the best replacement format was inspired by the code in `check_texture_requirements()` in `d3dx9_36/texture.c`. This should fix WineHQ bug 51584, but I haven't tested that.
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 112 +++++++++++++++++++++++++++++++--- dlls/d3dx9_36/tests/surface.c | 84 ++++++++++++------------- 2 files changed, 145 insertions(+), 51 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 638bddf39ca..da8ab19a4dc 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -517,6 +517,91 @@ static HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE r return D3D_OK; }
+static const enum d3dx_pixel_format_id tga_save_pixel_formats[] = +{ + D3DX_PIXEL_FORMAT_B8G8R8_UNORM, + D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM +}; + +static enum d3dx_pixel_format_id d3dx_get_closest_d3dx_pixel_format_id(const enum d3dx_pixel_format_id *format_ids, + uint32_t format_ids_size, enum d3dx_pixel_format_id format_id) +{ + const struct pixel_format_desc *fmt, *curfmt, *bestfmt = NULL; + int bestscore = INT_MIN, rgb_channels, a_channel, i, j; + BOOL alpha_only, rgb_only; + + for (i = 0; i < format_ids_size; ++i) + { + if (format_ids[i] == format_id) + return format_id; + } + + TRACE("Requested format is not directly supported, looking for the best alternative.\n"); + switch (format_id) + { + case D3DX_PIXEL_FORMAT_P8_UINT: + case D3DX_PIXEL_FORMAT_P8_UINT_A8_UNORM: + case D3DX_PIXEL_FORMAT_DXT1_UNORM: + case D3DX_PIXEL_FORMAT_DXT2_UNORM: + case D3DX_PIXEL_FORMAT_DXT3_UNORM: + case D3DX_PIXEL_FORMAT_DXT4_UNORM: + case D3DX_PIXEL_FORMAT_DXT5_UNORM: + fmt = get_d3dx_pixel_format_info(D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM); + break; + + default: + fmt = get_d3dx_pixel_format_info(format_id); + break; + } + + alpha_only = rgb_only = FALSE; + if (fmt->a_type != CTYPE_EMPTY && fmt->rgb_type == CTYPE_EMPTY) + alpha_only = TRUE; + else if (fmt->a_type == CTYPE_EMPTY && fmt->rgb_type != CTYPE_EMPTY) + rgb_only = TRUE; + + if (fmt->rgb_type == CTYPE_LUMA) + rgb_channels = 3; + else + rgb_channels = !!fmt->bits[1] + !!fmt->bits[2] + !!fmt->bits[3]; + a_channel = !!fmt->bits[0]; + for (i = 0; i < format_ids_size; ++i) + { + int cur_rgb_channels, cur_a_channel, score; + + curfmt = get_d3dx_pixel_format_info(format_ids[i]); + if (!is_conversion_to_supported(curfmt)) + continue; + if (alpha_only && curfmt->a_type == CTYPE_EMPTY) + continue; + if (rgb_only && curfmt->rgb_type == CTYPE_EMPTY) + continue; + if (fmt->rgb_type == CTYPE_SNORM && curfmt->rgb_type != CTYPE_SNORM) + continue; + + cur_rgb_channels = !!curfmt->bits[1] + !!curfmt->bits[2] + !!curfmt->bits[3]; + cur_a_channel = !!curfmt->bits[0]; + /* Calculate a score for this format. */ + score = 512 * (format_types_match(curfmt, fmt)); + score -= 32 * abs(cur_a_channel - a_channel); + score -= 32 * abs(cur_rgb_channels - rgb_channels); + for (j = 0; j < 4; ++j) + { + int diff = curfmt->bits[j] - fmt->bits[j]; + + score -= (diff < 0 ? -diff * 8 : diff) * (j == 0 ? 1 : 2); + } + + if (score > bestscore) + { + bestscore = score; + bestfmt = curfmt; + } + } + + return (bestfmt) ? bestfmt->format : D3DX_PIXEL_FORMAT_COUNT; +} + static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, D3DXIMAGE_FILEFORMAT file_format, ID3DXBuffer **dst_buffer) { @@ -538,9 +623,17 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const break;
case D3DXIFF_TGA: - if ((dst_format != D3DX_PIXEL_FORMAT_B8G8R8_UNORM) && (dst_format != D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM)) + dst_format = d3dx_get_closest_d3dx_pixel_format_id(tga_save_pixel_formats, ARRAY_SIZE(tga_save_pixel_formats), + dst_format); + if (dst_format == D3DX_PIXEL_FORMAT_COUNT) + { + WARN("Failed to find adequate replacement format for saving.\n"); + return D3DERR_INVALIDCALL; + } + + if (dst_format != src_fmt_desc->format && !is_conversion_from_supported(src_fmt_desc)) { - FIXME("Format replacement for TGA files is currently unimplemented.\n"); + FIXME("Cannot convert d3dx pixel format %d, can't save.\n", src_fmt_desc->format); return E_NOTIMPL; } break; @@ -607,9 +700,10 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const
if (src_pixels->size.width != 0 && src_pixels->size.height != 0) { + const PALETTEENTRY *dst_palette = is_index_format(dst_fmt_desc) ? src_pixels->palette : NULL; const RECT dst_rect = { 0, 0, src_pixels->size.width, src_pixels->size.height };
- set_d3dx_pixels(&dst_pixels, pixels, dst_row_pitch, dst_slice_pitch, src_pixels->palette, src_pixels->size.width, + set_d3dx_pixels(&dst_pixels, pixels, dst_row_pitch, dst_slice_pitch, dst_palette, src_pixels->size.width, src_pixels->size.height, src_pixels->size.depth, &dst_rect);
hr = d3dx_load_pixels_from_pixels(&dst_pixels, dst_fmt_desc, src_pixels, src_fmt_desc, D3DX_FILTER_NONE, 0); @@ -3012,12 +3106,6 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE if (!dst_buffer || !src_surface) return D3DERR_INVALIDCALL;
IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc); - if (file_format != D3DXIFF_DDS && (src_palette || is_index_format(get_format_info(src_surface_desc.Format)))) - { - FIXME("Saving surfaces with palettized pixel formats to non-DDS files is not implemented yet.\n"); - return D3DERR_INVALIDCALL; - } - switch (file_format) { case D3DXIFF_BMP: @@ -3042,6 +3130,12 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE return D3DERR_INVALIDCALL; }
+ if (src_palette || is_index_format(get_format_info(src_surface_desc.Format))) + { + FIXME("Saving surfaces with palettized pixel formats via WIC is not implemented yet.\n"); + return D3DERR_INVALIDCALL; + } + if (src_rect) { if (src_rect->left == src_rect->right || src_rect->top == src_rect->bottom) diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 25152fc6a74..cf07cd5d84a 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -3868,7 +3868,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_P8, test_palette, 0x00, { { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, @@ -3879,7 +3879,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A8P8, test_palette, 0x00, { { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, @@ -3965,7 +3965,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_X8R8G8B8, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, }, { D3D_OK, D3DFMT_X8R8G8B8 }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, }, @@ -3981,7 +3981,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A8B8G8R8, NULL, 0x00, { { D3D_OK, D3DFMT_A8B8G8R8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8B8G8R8, .todo_hr = TRUE }, @@ -3992,7 +3992,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_X8B8G8R8, NULL, 0x00, { { D3D_OK, D3DFMT_X8B8G8R8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8B8G8R8, .todo_hr = TRUE }, @@ -4003,7 +4003,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_R5G6B5, NULL, 0x00, { { D3D_OK, D3DFMT_R5G6B5, }, { D3D_OK, D3DFMT_X8R8G8B8 }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R5G6B5, }, @@ -4014,7 +4014,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_X1R5G5B5, NULL, 0x00, { { D3D_OK, D3DFMT_X1R5G5B5, }, { D3D_OK, D3DFMT_X8R8G8B8 }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X1R5G5B5, }, @@ -4025,7 +4025,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A1R5G5B5, NULL, 0x00, { { D3D_OK, D3DFMT_A1R5G5B5, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A1R5G5B5, .todo_hr = TRUE }, @@ -4036,7 +4036,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_R3G3B2, NULL, 0x00, { { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, @@ -4047,7 +4047,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A8R3G3B2, NULL, 0x00, { { D3D_OK, D3DFMT_A8R3G3B2, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R3G3B2, .todo_hr = TRUE }, @@ -4058,7 +4058,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A4R4G4B4, NULL, 0x00, { { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, @@ -4069,7 +4069,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_X4R4G4B4, NULL, 0x00, { { D3D_OK, D3DFMT_X4R4G4B4, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X4R4G4B4, .todo_hr = TRUE }, @@ -4080,7 +4080,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A2R10G10B10, NULL, 0x00, { { D3D_OK, D3DFMT_A2R10G10B10, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A2R10G10B10, .todo_hr = TRUE }, @@ -4091,7 +4091,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A2B10G10R10, NULL, 0x00, { { D3D_OK, D3DFMT_A2B10G10R10, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A2B10G10R10, .todo_hr = TRUE }, @@ -4102,7 +4102,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A16B16G16R16, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, @@ -4113,7 +4113,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_G16R16, NULL, 0x00, { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, @@ -4124,7 +4124,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A8, NULL, 0x00, { { D3D_OK, D3DFMT_A8R3G3B2, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R3G3B2, .todo_hr = TRUE }, @@ -4135,7 +4135,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A8L8, NULL, 0x00, { { D3D_OK, D3DFMT_A8L8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8L8, .todo_hr = TRUE }, @@ -4146,7 +4146,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A4L4, NULL, 0x00, { { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, @@ -4163,7 +4163,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_L8, NULL, 0x00, { { D3D_OK, D3DFMT_P8, .todo_format = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_P8, .todo_format = TRUE }, @@ -4174,7 +4174,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_L16, NULL, 0x00, { { D3D_OK, D3DFMT_L16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_L16, .todo_hr = TRUE }, @@ -4185,7 +4185,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_DXT1, NULL, 0x00, { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, @@ -4196,7 +4196,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_DXT2, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4207,7 +4207,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_DXT2, NULL, 0xff, { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, @@ -4218,7 +4218,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_DXT3, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4229,7 +4229,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_DXT3, NULL, 0xff, { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, @@ -4240,7 +4240,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_DXT4, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4251,7 +4251,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_DXT4, NULL, 0xff, { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, @@ -4262,7 +4262,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_DXT5, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4273,7 +4273,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_DXT5, NULL, 0xff, { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, @@ -4284,7 +4284,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_R16F, NULL, 0x00, { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, @@ -4295,7 +4295,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_G16R16F, NULL, 0x00, { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, @@ -4306,7 +4306,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A16B16G16R16F, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4317,7 +4317,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_R32F, NULL, 0x00, { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, @@ -4328,7 +4328,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_G32R32F, NULL, 0x00, { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, @@ -4339,7 +4339,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A32B32G32R32F, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4350,7 +4350,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_Q8W8V8U8, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4361,7 +4361,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_V8U8, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4372,7 +4372,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_V16U16, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4383,7 +4383,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_X8L8V8U8, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4394,7 +4394,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_A2W10V10U10, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4405,7 +4405,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DFMT_Q16W16V16U16, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE },
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 235 ++++++++++++++++++++++++++++------ dlls/d3dx9_36/tests/surface.c | 80 ++++++------ 2 files changed, 234 insertions(+), 81 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index da8ab19a4dc..800bb53dd0f 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -65,9 +65,8 @@ static enum d3dx_pixel_format_id d3dx_pixel_format_id_from_wic_pixel_format(cons
}
-static const GUID *wic_guid_from_d3dformat(D3DFORMAT format) +static const GUID *wic_guid_from_d3dx_pixel_format_id(enum d3dx_pixel_format_id d3dx_pixel_format) { - enum d3dx_pixel_format_id d3dx_pixel_format = d3dx_pixel_format_id_from_d3dformat(format); unsigned int i;
for (i = 0; i < ARRAY_SIZE(wic_pixel_formats); i++) @@ -79,6 +78,11 @@ static const GUID *wic_guid_from_d3dformat(D3DFORMAT format) return NULL; }
+static const GUID *wic_guid_from_d3dformat(D3DFORMAT format) +{ + return wic_guid_from_d3dx_pixel_format_id(d3dx_pixel_format_id_from_d3dformat(format)); +} + #define DDS_PALETTE_SIZE (sizeof(PALETTEENTRY) * 256)
/* dds_header.flags */ @@ -517,12 +521,133 @@ static HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE r return D3D_OK; }
+static const GUID *wic_container_guid_from_d3dx_file_format(D3DXIMAGE_FILEFORMAT iff) +{ + switch (iff) + { + case D3DXIFF_BMP: return &GUID_ContainerFormatBmp; + case D3DXIFF_JPG: return &GUID_ContainerFormatJpeg; + case D3DXIFF_PNG: return &GUID_ContainerFormatPng; + default: + assert(0 && "Unexpected file format."); + return NULL; + } +} + +static HRESULT d3dx_pixels_save_wic(struct d3dx_pixels *pixels, const struct pixel_format_desc *fmt_desc, + D3DXIMAGE_FILEFORMAT image_file_format, IStream **wic_file, uint32_t *wic_file_size) +{ + const GUID *container_format = wic_container_guid_from_d3dx_file_format(image_file_format); + const GUID *pixel_format_guid = wic_guid_from_d3dx_pixel_format_id(fmt_desc->format); + IWICBitmapFrameEncode *wic_frame = NULL; + IPropertyBag2 *encoder_options = NULL; + IWICBitmapEncoder *wic_encoder = NULL; + WICPixelFormatGUID wic_pixel_format; + const LARGE_INTEGER seek = { 0 }; + IWICImagingFactory *wic_factory; + IStream *stream = NULL; + STATSTG stream_stats; + HRESULT hr; + + assert(container_format && pixel_format_guid); + hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &wic_factory); + if (FAILED(hr)) + return D3DERR_INVALIDCALL; + + hr = IWICImagingFactory_CreateEncoder(wic_factory, container_format, NULL, &wic_encoder); + IWICImagingFactory_Release(wic_factory); + if (FAILED(hr)) + return D3DERR_INVALIDCALL; + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + if (FAILED(hr)) + goto exit; + + hr = IWICBitmapEncoder_Initialize(wic_encoder, stream, WICBitmapEncoderNoCache); + if (FAILED(hr)) + goto exit; + + hr = IWICBitmapEncoder_CreateNewFrame(wic_encoder, &wic_frame, &encoder_options); + if (FAILED(hr)) + goto exit; + + hr = IWICBitmapFrameEncode_Initialize(wic_frame, encoder_options); + if (FAILED(hr)) + goto exit; + + hr = IWICBitmapFrameEncode_SetSize(wic_frame, pixels->size.width, pixels->size.height); + if (FAILED(hr)) + goto exit; + + memcpy(&wic_pixel_format, pixel_format_guid, sizeof(*pixel_format_guid)); + hr = IWICBitmapFrameEncode_SetPixelFormat(wic_frame, &wic_pixel_format); + if (FAILED(hr)) + goto exit; + + if (!IsEqualGUID(pixel_format_guid, &wic_pixel_format)) + { + ERR("SetPixelFormat returned a different pixel format.\n"); + hr = E_FAIL; + goto exit; + } + + hr = IWICBitmapFrameEncode_WritePixels(wic_frame, pixels->size.height, pixels->row_pitch, pixels->slice_pitch, + (BYTE *)pixels->data); + if (FAILED(hr)) + goto exit; + + hr = IWICBitmapFrameEncode_Commit(wic_frame); + if (FAILED(hr)) + goto exit; + + hr = IWICBitmapEncoder_Commit(wic_encoder); + if (FAILED(hr)) + goto exit; + + hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, NULL); + if (FAILED(hr)) + goto exit; + + hr = IStream_Stat(stream, &stream_stats, STATFLAG_NONAME); + if (FAILED(hr)) + goto exit; + + if (!stream_stats.cbSize.u.HighPart && !!stream_stats.cbSize.u.LowPart) + { + *wic_file = stream; + *wic_file_size = stream_stats.cbSize.u.LowPart; + } + else + { + hr = D3DXERR_INVALIDDATA; + } + +exit: + if (stream && (*wic_file != stream)) + IStream_Release(stream); + if (wic_frame) + IWICBitmapFrameEncode_Release(wic_frame); + if (encoder_options) + IPropertyBag2_Release(encoder_options); + if (wic_encoder) + IWICBitmapEncoder_Release(wic_encoder); + + return hr; +} + static const enum d3dx_pixel_format_id tga_save_pixel_formats[] = { D3DX_PIXEL_FORMAT_B8G8R8_UNORM, D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM };
+static const enum d3dx_pixel_format_id png_save_pixel_formats[] = +{ + D3DX_PIXEL_FORMAT_B8G8R8_UNORM, + D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM, + D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM +}; + static enum d3dx_pixel_format_id d3dx_get_closest_d3dx_pixel_format_id(const enum d3dx_pixel_format_id *format_ids, uint32_t format_ids_size, enum d3dx_pixel_format_id format_id) { @@ -609,11 +734,12 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const const struct pixel_format_desc *dst_fmt_desc; uint32_t dst_row_pitch, dst_slice_pitch; struct d3dx_pixels dst_pixels; + uint8_t *pixels, *tmp_buf; ID3DXBuffer *buffer; - uint8_t *pixels; HRESULT hr;
*dst_buffer = buffer = NULL; + pixels = tmp_buf = NULL; switch (file_format) { case D3DXIFF_DDS: @@ -625,17 +751,11 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const case D3DXIFF_TGA: dst_format = d3dx_get_closest_d3dx_pixel_format_id(tga_save_pixel_formats, ARRAY_SIZE(tga_save_pixel_formats), dst_format); - if (dst_format == D3DX_PIXEL_FORMAT_COUNT) - { - WARN("Failed to find adequate replacement format for saving.\n"); - return D3DERR_INVALIDCALL; - } + break;
- if (dst_format != src_fmt_desc->format && !is_conversion_from_supported(src_fmt_desc)) - { - FIXME("Cannot convert d3dx pixel format %d, can't save.\n", src_fmt_desc->format); - return E_NOTIMPL; - } + case D3DXIFF_PNG: + dst_format = d3dx_get_closest_d3dx_pixel_format_id(png_save_pixel_formats, ARRAY_SIZE(png_save_pixel_formats), + dst_format); break;
default: @@ -643,6 +763,18 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const return E_FAIL; }
+ if (dst_format == D3DX_PIXEL_FORMAT_COUNT) + { + WARN("Failed to find adequate replacement format for saving.\n"); + return D3DERR_INVALIDCALL; + } + + if (dst_format != src_fmt_desc->format && !is_conversion_from_supported(src_fmt_desc)) + { + FIXME("Cannot convert d3dx pixel format %d, can't save.\n", src_fmt_desc->format); + return E_NOTIMPL; + } + dst_fmt_desc = get_d3dx_pixel_format_info(dst_format); hr = d3dx_calculate_pixels_size(dst_format, src_pixels->size.width, src_pixels->size.height, &dst_row_pitch, &dst_slice_pitch); @@ -694,25 +826,65 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const break; }
+ case D3DXIFF_PNG: + if (src_fmt_desc == dst_fmt_desc) + dst_pixels = *src_pixels; + else + pixels = tmp_buf = malloc(dst_slice_pitch); + break; + default: break; }
if (src_pixels->size.width != 0 && src_pixels->size.height != 0) { - const PALETTEENTRY *dst_palette = is_index_format(dst_fmt_desc) ? src_pixels->palette : NULL; - const RECT dst_rect = { 0, 0, src_pixels->size.width, src_pixels->size.height }; + if (pixels) + { + const PALETTEENTRY *dst_palette = is_index_format(dst_fmt_desc) ? src_pixels->palette : NULL; + const RECT dst_rect = { 0, 0, src_pixels->size.width, src_pixels->size.height };
- set_d3dx_pixels(&dst_pixels, pixels, dst_row_pitch, dst_slice_pitch, dst_palette, src_pixels->size.width, - src_pixels->size.height, src_pixels->size.depth, &dst_rect); + set_d3dx_pixels(&dst_pixels, pixels, dst_row_pitch, dst_slice_pitch, dst_palette, + src_pixels->size.width, src_pixels->size.height, src_pixels->size.depth, &dst_rect);
- hr = d3dx_load_pixels_from_pixels(&dst_pixels, dst_fmt_desc, src_pixels, src_fmt_desc, D3DX_FILTER_NONE, 0); + hr = d3dx_load_pixels_from_pixels(&dst_pixels, dst_fmt_desc, src_pixels, src_fmt_desc, D3DX_FILTER_NONE, 0); + if (FAILED(hr)) + goto exit; + } + + /* WIC path, encode the image. */ + if (!buffer) + { + IStream *wic_file = NULL; + uint32_t buf_size = 0; + + hr = d3dx_pixels_save_wic(&dst_pixels, dst_fmt_desc, file_format, &wic_file, &buf_size); + if (FAILED(hr)) + goto exit; + hr = D3DXCreateBuffer(buf_size, &buffer); + if (FAILED(hr)) + { + IStream_Release(wic_file); + goto exit; + } + + hr = IStream_Read(wic_file, ID3DXBuffer_GetBufferPointer(buffer), buf_size, NULL); + IStream_Release(wic_file); + if (FAILED(hr)) + goto exit; + } + } + /* Return an empty buffer for size 0 images via WIC. */ + else if (!buffer) + { + hr = D3DXCreateBuffer(64, &buffer); if (FAILED(hr)) goto exit; }
*dst_buffer = buffer; exit: + free(tmp_buf); if (*dst_buffer != buffer) ID3DXBuffer_Release(buffer); return hr; @@ -1024,25 +1196,6 @@ static BOOL image_is_argb(IWICBitmapFrameDecode *frame, struct d3dx_image *image return FALSE; }
-struct d3dx_wic_file_format -{ - const GUID *wic_container_guid; - D3DXIMAGE_FILEFORMAT d3dx_file_format; -}; - -static const GUID *d3dx_file_format_to_wic_container_guid(D3DXIMAGE_FILEFORMAT iff) -{ - switch (iff) - { - case D3DXIFF_BMP: return &GUID_ContainerFormatBmp; - case D3DXIFF_JPG: return &GUID_ContainerFormatJpeg; - case D3DXIFF_PNG: return &GUID_ContainerFormatPng; - default: - assert(0); /* Shouldn't happen. */ - return NULL; - } -} - static const char *debug_d3dx_image_file_format(D3DXIMAGE_FILEFORMAT format) { switch (format) @@ -1146,7 +1299,7 @@ exit: static HRESULT d3dx_initialize_image_from_wic(const void *src_data, uint32_t src_data_size, struct d3dx_image *image, D3DXIMAGE_FILEFORMAT d3dx_file_format, uint32_t flags) { - const GUID *container_format_guid = d3dx_file_format_to_wic_container_guid(d3dx_file_format); + const GUID *container_format_guid = wic_container_guid_from_d3dx_file_format(d3dx_file_format); IWICBitmapFrameDecode *bitmap_frame = NULL; IWICBitmapDecoder *bitmap_decoder = NULL; IWICImagingFactory *wic_factory; @@ -2612,6 +2765,8 @@ HRESULT d3dx_pixels_init(const void *data, uint32_t row_pitch, uint32_t slice_pi SetRect(&unaligned_rect, 0, 0, (right - left), (bottom - top)); }
+ if (!slice_pitch) + slice_pitch = row_pitch * (bottom - top); set_d3dx_pixels(pixels, ptr, row_pitch, slice_pitch, palette, (right - left), (bottom - top), (back - front), &unaligned_rect);
@@ -3112,14 +3267,12 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE case D3DXIFF_DIB: container_format = &GUID_ContainerFormatBmp; break; - case D3DXIFF_PNG: - container_format = &GUID_ContainerFormatPng; - break; case D3DXIFF_JPG: container_format = &GUID_ContainerFormatJpeg; break; case D3DXIFF_DDS: case D3DXIFF_TGA: + case D3DXIFF_PNG: return save_surface_to_memory(dst_buffer, src_surface, src_palette, src_rect, file_format); case D3DXIFF_HDR: case D3DXIFF_PFM: diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index cf07cd5d84a..0abac129502 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -3869,7 +3869,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -3880,7 +3880,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -3982,7 +3982,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A8B8G8R8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8B8G8R8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -3993,7 +3993,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_X8B8G8R8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8B8G8R8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4004,7 +4004,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_R5G6B5, }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R5G6B5, }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4015,7 +4015,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_X1R5G5B5, }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X1R5G5B5, }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4026,7 +4026,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A1R5G5B5, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A1R5G5B5, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4037,7 +4037,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4048,7 +4048,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A8R3G3B2, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R3G3B2, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4059,7 +4059,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4070,7 +4070,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_X4R4G4B4, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X4R4G4B4, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4081,7 +4081,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A2R10G10B10, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A2R10G10B10, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4092,7 +4092,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A2B10G10R10, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A2B10G10R10, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4114,7 +4114,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4125,7 +4125,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A8R3G3B2, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R3G3B2, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4136,7 +4136,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A8L8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8L8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4147,7 +4147,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4164,7 +4164,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_P8, .todo_format = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_P8, .todo_format = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4175,7 +4175,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_L16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_L16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4186,7 +4186,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4197,7 +4197,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4208,7 +4208,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4219,7 +4219,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4230,7 +4230,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4241,7 +4241,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4252,7 +4252,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4263,7 +4263,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4274,7 +4274,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4285,7 +4285,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4296,7 +4296,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4307,7 +4307,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4318,7 +4318,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4329,7 +4329,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_R8G8B8 }, - { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4340,7 +4340,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A8R8G8B8 }, - { D3D_OK, D3DFMT_A16B16G16R16, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, @@ -4351,7 +4351,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4362,7 +4362,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4373,7 +4373,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4384,7 +4384,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4395,7 +4395,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4406,7 +4406,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE },
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 15 +++++-- dlls/d3dx9_36/tests/surface.c | 76 +++++++++++++++++------------------ 2 files changed, 50 insertions(+), 41 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 800bb53dd0f..3146d09123a 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -648,6 +648,11 @@ static const enum d3dx_pixel_format_id png_save_pixel_formats[] = D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM };
+static const enum d3dx_pixel_format_id jpg_save_pixel_formats[] = +{ + D3DX_PIXEL_FORMAT_B8G8R8_UNORM, +}; + static enum d3dx_pixel_format_id d3dx_get_closest_d3dx_pixel_format_id(const enum d3dx_pixel_format_id *format_ids, uint32_t format_ids_size, enum d3dx_pixel_format_id format_id) { @@ -758,6 +763,11 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const dst_format); break;
+ case D3DXIFF_JPG: + dst_format = d3dx_get_closest_d3dx_pixel_format_id(jpg_save_pixel_formats, ARRAY_SIZE(jpg_save_pixel_formats), + dst_format); + break; + default: assert(0 && "Unexpected file format."); return E_FAIL; @@ -827,6 +837,7 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const }
case D3DXIFF_PNG: + case D3DXIFF_JPG: if (src_fmt_desc == dst_fmt_desc) dst_pixels = *src_pixels; else @@ -3267,12 +3278,10 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE case D3DXIFF_DIB: container_format = &GUID_ContainerFormatBmp; break; - case D3DXIFF_JPG: - container_format = &GUID_ContainerFormatJpeg; - break; case D3DXIFF_DDS: case D3DXIFF_TGA: case D3DXIFF_PNG: + case D3DXIFF_JPG: return save_surface_to_memory(dst_buffer, src_surface, src_palette, src_rect, file_format); case D3DXIFF_HDR: case D3DXIFF_PFM: diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 0abac129502..7a92d01ec50 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -3867,7 +3867,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { { D3DFMT_P8, test_palette, 0x00, { { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -3878,7 +3878,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A8P8, test_palette, 0x00, { { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -3980,7 +3980,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) */ { D3DFMT_A8B8G8R8, NULL, 0x00, { { D3D_OK, D3DFMT_A8B8G8R8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -3991,7 +3991,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_X8B8G8R8, NULL, 0x00, { { D3D_OK, D3DFMT_X8B8G8R8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4024,7 +4024,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A1R5G5B5, NULL, 0x00, { { D3D_OK, D3DFMT_A1R5G5B5, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4035,7 +4035,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_R3G3B2, NULL, 0x00, { { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4046,7 +4046,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A8R3G3B2, NULL, 0x00, { { D3D_OK, D3DFMT_A8R3G3B2, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4057,7 +4057,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A4R4G4B4, NULL, 0x00, { { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4068,7 +4068,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_X4R4G4B4, NULL, 0x00, { { D3D_OK, D3DFMT_X4R4G4B4, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4079,7 +4079,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A2R10G10B10, NULL, 0x00, { { D3D_OK, D3DFMT_A2R10G10B10, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4090,7 +4090,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A2B10G10R10, NULL, 0x00, { { D3D_OK, D3DFMT_A2B10G10R10, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4112,7 +4112,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_G16R16, NULL, 0x00, { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4123,7 +4123,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A8, NULL, 0x00, { { D3D_OK, D3DFMT_A8R3G3B2, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4134,7 +4134,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A8L8, NULL, 0x00, { { D3D_OK, D3DFMT_A8L8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4145,7 +4145,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A4L4, NULL, 0x00, { { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4162,7 +4162,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) */ { D3DFMT_L8, NULL, 0x00, { { D3D_OK, D3DFMT_P8, .todo_format = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4173,7 +4173,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_L16, NULL, 0x00, { { D3D_OK, D3DFMT_L16, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4184,7 +4184,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_DXT1, NULL, 0x00, { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4195,7 +4195,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_DXT2, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4206,7 +4206,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_DXT2, NULL, 0xff, { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4217,7 +4217,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_DXT3, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4228,7 +4228,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_DXT3, NULL, 0xff, { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4239,7 +4239,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_DXT4, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4250,7 +4250,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_DXT4, NULL, 0xff, { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4261,7 +4261,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_DXT5, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4272,7 +4272,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_DXT5, NULL, 0xff, { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4283,7 +4283,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_R16F, NULL, 0x00, { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4294,7 +4294,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_G16R16F, NULL, 0x00, { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4305,7 +4305,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A16B16G16R16F, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4316,7 +4316,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_R32F, NULL, 0x00, { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4327,7 +4327,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_G32R32F, NULL, 0x00, { { D3D_OK, D3DFMT_G16R16, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4338,7 +4338,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A32B32G32R32F, NULL, 0x00, { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, @@ -4349,7 +4349,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_Q8W8V8U8, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4360,7 +4360,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_V8U8, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4371,7 +4371,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_V16U16, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4382,7 +4382,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_X8L8V8U8, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4393,7 +4393,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_A2W10V10U10, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, @@ -4404,7 +4404,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, { D3DFMT_Q16W16V16U16, NULL, 0x00, { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE },
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 59 ++++++++++++++++++++++++++++++++++- dlls/d3dx9_36/tests/surface.c | 49 +++++++++++++---------------- 2 files changed, 80 insertions(+), 28 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 3146d09123a..65b40cd38d5 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -579,6 +579,13 @@ static HRESULT d3dx_pixels_save_wic(struct d3dx_pixels *pixels, const struct pix if (FAILED(hr)) goto exit;
+ /* + * Encode 32bpp BGRA format surfaces as 32bpp BGRX for BMP. + * This matches the behavior of native. + */ + if (IsEqualGUID(&GUID_ContainerFormatBmp, container_format) && (fmt_desc->format == D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM)) + pixel_format_guid = wic_guid_from_d3dx_pixel_format_id(D3DX_PIXEL_FORMAT_B8G8R8X8_UNORM); + memcpy(&wic_pixel_format, pixel_format_guid, sizeof(*pixel_format_guid)); hr = IWICBitmapFrameEncode_SetPixelFormat(wic_frame, &wic_pixel_format); if (FAILED(hr)) @@ -653,6 +660,38 @@ static const enum d3dx_pixel_format_id jpg_save_pixel_formats[] = D3DX_PIXEL_FORMAT_B8G8R8_UNORM, };
+static const enum d3dx_pixel_format_id bmp_save_pixel_formats[] = +{ + D3DX_PIXEL_FORMAT_B5G5R5X1_UNORM, + D3DX_PIXEL_FORMAT_B5G6R5_UNORM, + D3DX_PIXEL_FORMAT_B8G8R8_UNORM, + D3DX_PIXEL_FORMAT_B8G8R8X8_UNORM, + D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM, +}; + +static const enum d3dx_pixel_format_id unimplemented_bmp_save_pixel_formats[] = +{ + D3DX_PIXEL_FORMAT_P8_UINT, + D3DX_PIXEL_FORMAT_A8_UNORM, + D3DX_PIXEL_FORMAT_P8_UINT_A8_UNORM, + D3DX_PIXEL_FORMAT_L8A8_UNORM, + D3DX_PIXEL_FORMAT_L16_UNORM, + D3DX_PIXEL_FORMAT_B2G3R3_UNORM, + D3DX_PIXEL_FORMAT_R16_FLOAT, + D3DX_PIXEL_FORMAT_R16G16_FLOAT, + D3DX_PIXEL_FORMAT_R16G16_UNORM, + D3DX_PIXEL_FORMAT_R32_FLOAT, + D3DX_PIXEL_FORMAT_R32G32_FLOAT, + D3DX_PIXEL_FORMAT_B4G4R4X4_UNORM, + D3DX_PIXEL_FORMAT_B4G4R4A4_UNORM, + D3DX_PIXEL_FORMAT_B2G3R3A8_UNORM, + D3DX_PIXEL_FORMAT_B5G5R5A1_UNORM, + D3DX_PIXEL_FORMAT_R8G8B8X8_UNORM, + D3DX_PIXEL_FORMAT_R8G8B8A8_UNORM, + D3DX_PIXEL_FORMAT_B10G10R10A2_UNORM, + D3DX_PIXEL_FORMAT_R10G10B10A2_UNORM, +}; + static enum d3dx_pixel_format_id d3dx_get_closest_d3dx_pixel_format_id(const enum d3dx_pixel_format_id *format_ids, uint32_t format_ids_size, enum d3dx_pixel_format_id format_id) { @@ -768,6 +807,23 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const dst_format); break;
+ case D3DXIFF_BMP: + { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(unimplemented_bmp_save_pixel_formats); ++i) + { + if (unimplemented_bmp_save_pixel_formats[i] == dst_format) + { + FIXME("Saving pixel format %d to BMP files is currently unsupported.\n", dst_format); + return E_NOTIMPL; + } + } + dst_format = d3dx_get_closest_d3dx_pixel_format_id(bmp_save_pixel_formats, ARRAY_SIZE(bmp_save_pixel_formats), + dst_format); + break; + } + default: assert(0 && "Unexpected file format."); return E_FAIL; @@ -838,6 +894,7 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const
case D3DXIFF_PNG: case D3DXIFF_JPG: + case D3DXIFF_BMP: if (src_fmt_desc == dst_fmt_desc) dst_pixels = *src_pixels; else @@ -3274,7 +3331,6 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc); switch (file_format) { - case D3DXIFF_BMP: case D3DXIFF_DIB: container_format = &GUID_ContainerFormatBmp; break; @@ -3282,6 +3338,7 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE case D3DXIFF_TGA: case D3DXIFF_PNG: case D3DXIFF_JPG: + case D3DXIFF_BMP: return save_surface_to_memory(dst_buffer, src_surface, src_palette, src_rect, file_format); case D3DXIFF_HDR: case D3DXIFF_PFM: diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 7a92d01ec50..66a521ef99e 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -3932,16 +3932,11 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, /* - * We don't match formats here because we encode our BMP headers - * differently. Native encodes with the same header as - * D3DFMT_X8R8G8B8, it just sets the values in the alpha channel. The - * format is distinguished by checking the image. We encode a bitmap - * V4 header with a dedicated alpha mask, so we'll always report - * D3DFMT_A8R8G8B8, regardless of whether or not any alpha channel - * values are non-zero. + * For BMP/DIB, these encode as D3DFMT_X8R8G8B8. If there's a single + * pixel with a non-zero alpha channel, it reports as D3DFMT_A8R8G8B8. */ { D3DFMT_A8R8G8B8, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, }, @@ -4100,7 +4095,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_A16B16G16R16, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, @@ -4144,7 +4139,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_A4L4, NULL, 0x00, - { { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A4R4G4B4, .todo_format = TRUE }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4183,7 +4178,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT1, NULL, 0x00, - { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4194,7 +4189,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT2, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4205,7 +4200,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT2, NULL, 0xff, - { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4216,7 +4211,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT3, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4227,7 +4222,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT3, NULL, 0xff, - { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4238,7 +4233,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT4, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4249,7 +4244,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT4, NULL, 0xff, - { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4260,7 +4255,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT5, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4271,7 +4266,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_DXT5, NULL, 0xff, - { { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, @@ -4304,7 +4299,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_A16B16G16R16F, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, @@ -4337,7 +4332,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_A32B32G32R32F, NULL, 0x00, - { { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, @@ -4348,7 +4343,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_Q8W8V8U8, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, @@ -4359,7 +4354,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_V8U8, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, @@ -4370,7 +4365,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_V16U16, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, @@ -4381,7 +4376,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_X8L8V8U8, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, @@ -4392,7 +4387,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_A2W10V10U10, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, @@ -4403,7 +4398,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) }, }, { D3DFMT_Q16W16V16U16, NULL, 0x00, - { { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL },
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 38 ++++++++++++++++++++++++++++++++--- dlls/d3dx9_36/tests/surface.c | 2 +- 2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 65b40cd38d5..d538ed3f3fd 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -545,6 +545,7 @@ static HRESULT d3dx_pixels_save_wic(struct d3dx_pixels *pixels, const struct pix WICPixelFormatGUID wic_pixel_format; const LARGE_INTEGER seek = { 0 }; IWICImagingFactory *wic_factory; + IWICPalette *wic_palette = NULL; IStream *stream = NULL; STATSTG stream_stats; HRESULT hr; @@ -555,9 +556,11 @@ static HRESULT d3dx_pixels_save_wic(struct d3dx_pixels *pixels, const struct pix return D3DERR_INVALIDCALL;
hr = IWICImagingFactory_CreateEncoder(wic_factory, container_format, NULL, &wic_encoder); - IWICImagingFactory_Release(wic_factory); if (FAILED(hr)) - return D3DERR_INVALIDCALL; + { + hr = D3DERR_INVALIDCALL; + goto exit; + }
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); if (FAILED(hr)) @@ -579,6 +582,31 @@ static HRESULT d3dx_pixels_save_wic(struct d3dx_pixels *pixels, const struct pix if (FAILED(hr)) goto exit;
+ if (pixels->palette) + { + WICColor tmp_palette[256]; + unsigned int i; + + hr = IWICImagingFactory_CreatePalette(wic_factory, &wic_palette); + if (FAILED(hr)) + goto exit; + + for (i = 0; i < ARRAY_SIZE(tmp_palette); ++i) + { + const PALETTEENTRY *pe = &pixels->palette[i]; + + tmp_palette[i] = (pe->peFlags << 24) | (pe->peRed << 16) | (pe->peGreen << 8) | (pe->peBlue); + } + + hr = IWICPalette_InitializeCustom(wic_palette, tmp_palette, ARRAY_SIZE(tmp_palette)); + if (FAILED(hr)) + goto exit; + + hr = IWICBitmapFrameEncode_SetPalette(wic_frame, wic_palette); + if (FAILED(hr)) + goto exit; + } + /* * Encode 32bpp BGRA format surfaces as 32bpp BGRX for BMP. * This matches the behavior of native. @@ -630,10 +658,14 @@ static HRESULT d3dx_pixels_save_wic(struct d3dx_pixels *pixels, const struct pix }
exit: + if (wic_factory) + IWICImagingFactory_Release(wic_factory); if (stream && (*wic_file != stream)) IStream_Release(stream); if (wic_frame) IWICBitmapFrameEncode_Release(wic_frame); + if (wic_palette) + IWICPalette_Release(wic_palette); if (encoder_options) IPropertyBag2_Release(encoder_options); if (wic_encoder) @@ -667,11 +699,11 @@ static const enum d3dx_pixel_format_id bmp_save_pixel_formats[] = D3DX_PIXEL_FORMAT_B8G8R8_UNORM, D3DX_PIXEL_FORMAT_B8G8R8X8_UNORM, D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM, + D3DX_PIXEL_FORMAT_P8_UINT, };
static const enum d3dx_pixel_format_id unimplemented_bmp_save_pixel_formats[] = { - D3DX_PIXEL_FORMAT_P8_UINT, D3DX_PIXEL_FORMAT_A8_UNORM, D3DX_PIXEL_FORMAT_P8_UINT_A8_UNORM, D3DX_PIXEL_FORMAT_L8A8_UNORM, diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 66a521ef99e..4e09313bc32 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -3866,7 +3866,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) iff_tests[] = { { D3DFMT_P8, test_palette, 0x00, - { { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, + { { D3D_OK, D3DFMT_P8 }, { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 },
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/surface.c | 289 ++++++---------------------------- dlls/d3dx9_36/tests/surface.c | 53 +++---- 2 files changed, 70 insertions(+), 272 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index d538ed3f3fd..c6bc7db7484 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -78,11 +78,6 @@ static const GUID *wic_guid_from_d3dx_pixel_format_id(enum d3dx_pixel_format_id return NULL; }
-static const GUID *wic_guid_from_d3dformat(D3DFORMAT format) -{ - return wic_guid_from_d3dx_pixel_format_id(d3dx_pixel_format_id_from_d3dformat(format)); -} - #define DDS_PALETTE_SIZE (sizeof(PALETTEENTRY) * 256)
/* dds_header.flags */ @@ -525,6 +520,7 @@ static const GUID *wic_container_guid_from_d3dx_file_format(D3DXIMAGE_FILEFORMAT { switch (iff) { + case D3DXIFF_DIB: case D3DXIFF_BMP: return &GUID_ContainerFormatBmp; case D3DXIFF_JPG: return &GUID_ContainerFormatJpeg; case D3DXIFF_PNG: return &GUID_ContainerFormatPng; @@ -840,6 +836,7 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const break;
case D3DXIFF_BMP: + case D3DXIFF_DIB: { unsigned int i;
@@ -927,6 +924,7 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const case D3DXIFF_PNG: case D3DXIFF_JPG: case D3DXIFF_BMP: + case D3DXIFF_DIB: if (src_fmt_desc == dst_fmt_desc) dst_pixels = *src_pixels; else @@ -990,75 +988,6 @@ exit: return hr; }
-static HRESULT save_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSurface9 *src_surface, - const PALETTEENTRY *src_palette, const RECT *src_rect, D3DXIMAGE_FILEFORMAT file_format) -{ - const struct pixel_format_desc *src_fmt_desc; - D3DSURFACE_DESC src_surface_desc; - IDirect3DSurface9 *temp_surface; - struct d3dx_pixels src_pixels; - D3DLOCKED_RECT locked_rect; - ID3DXBuffer *buffer; - RECT src_rect_temp; - HRESULT hr; - - IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc); - src_fmt_desc = get_format_info(src_surface_desc.Format); - if (is_unknown_format(src_fmt_desc)) - return E_NOTIMPL; - - if (!src_palette && is_index_format(src_fmt_desc)) - { - FIXME("Default palette unimplemented.\n"); - return E_NOTIMPL; - } - - if (src_rect) - { - if (src_rect->left > src_rect->right || src_rect->right > src_surface_desc.Width - || src_rect->top > src_rect->bottom || src_rect->bottom > src_surface_desc.Height - || src_rect->left < 0 || src_rect->top < 0) - { - WARN("Invalid src_rect specified.\n"); - return D3DERR_INVALIDCALL; - } - } - else - { - SetRect(&src_rect_temp, 0, 0, src_surface_desc.Width, src_surface_desc.Height); - src_rect = &src_rect_temp; - } - - hr = lock_surface(src_surface, NULL, &locked_rect, &temp_surface, FALSE); - if (FAILED(hr)) - return hr; - - hr = d3dx_pixels_init(locked_rect.pBits, locked_rect.Pitch, 0, src_palette, src_fmt_desc->format, - src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1, &src_pixels); - if (FAILED(hr)) - { - unlock_surface(src_surface, NULL, temp_surface, FALSE); - return hr; - } - - hr = d3dx_save_pixels_to_memory(&src_pixels, src_fmt_desc, file_format, &buffer); - if (FAILED(hr)) - { - unlock_surface(src_surface, NULL, temp_surface, FALSE); - return hr; - } - - hr = unlock_surface(src_surface, NULL, temp_surface, FALSE); - if (FAILED(hr)) - { - ID3DXBuffer_Release(buffer); - return hr; - } - - *dst_buffer = buffer; - return D3D_OK; -} - static const uint8_t bmp_file_signature[] = { 'B', 'M' }; static const uint8_t jpg_file_signature[] = { 0xff, 0xd8 }; static const uint8_t png_file_signature[] = { 0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a }; @@ -3336,214 +3265,86 @@ HRESULT WINAPI D3DXSaveSurfaceToFileW(const WCHAR *dst_filename, D3DXIMAGE_FILEF HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_FILEFORMAT file_format, IDirect3DSurface9 *src_surface, const PALETTEENTRY *src_palette, const RECT *src_rect) { - IWICBitmapEncoder *encoder = NULL; - IWICBitmapFrameEncode *frame = NULL; - IPropertyBag2 *encoder_options = NULL; - IStream *stream = NULL; - HRESULT hr; - const GUID *container_format; - const GUID *pixel_format_guid; - WICPixelFormatGUID wic_pixel_format; - IWICImagingFactory *factory; - D3DFORMAT d3d_pixel_format; + const struct pixel_format_desc *src_fmt_desc; D3DSURFACE_DESC src_surface_desc; IDirect3DSurface9 *temp_surface; + struct d3dx_pixels src_pixels; D3DLOCKED_RECT locked_rect; - int width, height; - STATSTG stream_stats; - HGLOBAL stream_hglobal; ID3DXBuffer *buffer; - DWORD size; + RECT src_rect_temp; + HRESULT hr;
TRACE("dst_buffer %p, file_format %#x, src_surface %p, src_palette %p, src_rect %s.\n", dst_buffer, file_format, src_surface, src_palette, wine_dbgstr_rect(src_rect));
- if (!dst_buffer || !src_surface) return D3DERR_INVALIDCALL; + if (!dst_buffer || !src_surface || file_format > D3DXIFF_PFM) + return D3DERR_INVALIDCALL;
- IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc); switch (file_format) { - case D3DXIFF_DIB: - container_format = &GUID_ContainerFormatBmp; - break; - case D3DXIFF_DDS: - case D3DXIFF_TGA: - case D3DXIFF_PNG: - case D3DXIFF_JPG: - case D3DXIFF_BMP: - return save_surface_to_memory(dst_buffer, src_surface, src_palette, src_rect, file_format); case D3DXIFF_HDR: case D3DXIFF_PFM: case D3DXIFF_PPM: - FIXME("File format %#x is not supported yet\n", file_format); + FIXME("File format %#x is not supported yet.\n", file_format); return E_NOTIMPL; + default: - return D3DERR_INVALIDCALL; + break; }
- if (src_palette || is_index_format(get_format_info(src_surface_desc.Format))) + IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc); + src_fmt_desc = get_format_info(src_surface_desc.Format); + if (is_unknown_format(src_fmt_desc)) + return E_NOTIMPL; + + if (!src_palette && is_index_format(src_fmt_desc)) { - FIXME("Saving surfaces with palettized pixel formats via WIC is not implemented yet.\n"); - return D3DERR_INVALIDCALL; + FIXME("Default palette unimplemented.\n"); + return E_NOTIMPL; }
if (src_rect) { - if (src_rect->left == src_rect->right || src_rect->top == src_rect->bottom) + if (src_rect->left > src_rect->right || src_rect->right > src_surface_desc.Width + || src_rect->top > src_rect->bottom || src_rect->bottom > src_surface_desc.Height + || src_rect->left < 0 || src_rect->top < 0) { - WARN("Invalid rectangle with 0 area\n"); - return D3DXCreateBuffer(64, dst_buffer); - } - if (src_rect->left < 0 || src_rect->top < 0) - return D3DERR_INVALIDCALL; - if (src_rect->left > src_rect->right || src_rect->top > src_rect->bottom) - return D3DERR_INVALIDCALL; - if (src_rect->right > src_surface_desc.Width || src_rect->bottom > src_surface_desc.Height) + WARN("Invalid src_rect specified.\n"); return D3DERR_INVALIDCALL; - - width = src_rect->right - src_rect->left; - height = src_rect->bottom - src_rect->top; + } } else { - width = src_surface_desc.Width; - height = src_surface_desc.Height; + SetRect(&src_rect_temp, 0, 0, src_surface_desc.Width, src_surface_desc.Height); + src_rect = &src_rect_temp; }
- hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); - if (FAILED(hr)) goto cleanup_err; - - hr = IWICImagingFactory_CreateEncoder(factory, container_format, NULL, &encoder); - IWICImagingFactory_Release(factory); - if (FAILED(hr)) goto cleanup_err; - - hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); - if (FAILED(hr)) goto cleanup_err; - - hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); - if (FAILED(hr)) goto cleanup_err; - - hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame, &encoder_options); - if (FAILED(hr)) goto cleanup_err; - - hr = IWICBitmapFrameEncode_Initialize(frame, encoder_options); - if (FAILED(hr)) goto cleanup_err; - - hr = IWICBitmapFrameEncode_SetSize(frame, width, height); - if (FAILED(hr)) goto cleanup_err; - - pixel_format_guid = wic_guid_from_d3dformat(src_surface_desc.Format); - if (!pixel_format_guid) - { - FIXME("Pixel format %#x is not supported yet\n", src_surface_desc.Format); - hr = E_NOTIMPL; - goto cleanup; - } + hr = lock_surface(src_surface, NULL, &locked_rect, &temp_surface, FALSE); + if (FAILED(hr)) + return hr;
- memcpy(&wic_pixel_format, pixel_format_guid, sizeof(GUID)); - hr = IWICBitmapFrameEncode_SetPixelFormat(frame, &wic_pixel_format); - d3d_pixel_format = d3dformat_from_d3dx_pixel_format_id(d3dx_pixel_format_id_from_wic_pixel_format(&wic_pixel_format)); - if (SUCCEEDED(hr) && d3d_pixel_format != D3DFMT_UNKNOWN) + hr = d3dx_pixels_init(locked_rect.pBits, locked_rect.Pitch, 0, src_palette, src_fmt_desc->format, + src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1, &src_pixels); + if (FAILED(hr)) { - TRACE("Using pixel format %s %#x\n", debugstr_guid(&wic_pixel_format), d3d_pixel_format); - if (src_surface_desc.Format == d3d_pixel_format) /* Simple copy */ - { - if (FAILED(hr = lock_surface(src_surface, src_rect, &locked_rect, &temp_surface, FALSE))) - goto cleanup; - - IWICBitmapFrameEncode_WritePixels(frame, height, - locked_rect.Pitch, height * locked_rect.Pitch, locked_rect.pBits); - unlock_surface(src_surface, src_rect, temp_surface, FALSE); - } - else /* Pixel format conversion */ - { - const struct pixel_format_desc *src_format_desc, *dst_format_desc; - struct volume size; - DWORD dst_pitch; - void *dst_data; - - src_format_desc = get_format_info(src_surface_desc.Format); - dst_format_desc = get_format_info(d3d_pixel_format); - if (!is_conversion_from_supported(src_format_desc) - || !is_conversion_to_supported(dst_format_desc)) - { - FIXME("Unsupported format conversion %#x -> %#x.\n", - src_surface_desc.Format, d3d_pixel_format); - hr = E_NOTIMPL; - goto cleanup; - } - - size.width = width; - size.height = height; - size.depth = 1; - dst_pitch = width * dst_format_desc->bytes_per_pixel; - dst_data = malloc(dst_pitch * height); - if (!dst_data) - { - hr = E_OUTOFMEMORY; - goto cleanup; - } - if (FAILED(hr = lock_surface(src_surface, src_rect, &locked_rect, &temp_surface, FALSE))) - { - free(dst_data); - goto cleanup; - } - convert_argb_pixels(locked_rect.pBits, locked_rect.Pitch, 0, &size, src_format_desc, - dst_data, dst_pitch, 0, &size, dst_format_desc, 0, NULL); - unlock_surface(src_surface, src_rect, temp_surface, FALSE); - - IWICBitmapFrameEncode_WritePixels(frame, height, dst_pitch, dst_pitch * height, dst_data); - free(dst_data); - } - - hr = IWICBitmapFrameEncode_Commit(frame); - if (SUCCEEDED(hr)) hr = IWICBitmapEncoder_Commit(encoder); + unlock_surface(src_surface, NULL, temp_surface, FALSE); + return hr; } - else WARN("Unsupported pixel format %#x\n", src_surface_desc.Format); - - /* copy data from stream to ID3DXBuffer */ - hr = IStream_Stat(stream, &stream_stats, STATFLAG_NONAME); - if (FAILED(hr)) goto cleanup_err;
- if (stream_stats.cbSize.u.HighPart != 0) + hr = d3dx_save_pixels_to_memory(&src_pixels, src_fmt_desc, file_format, &buffer); + if (FAILED(hr)) { - hr = D3DXERR_INVALIDDATA; - goto cleanup; + unlock_surface(src_surface, NULL, temp_surface, FALSE); + return hr; } - size = stream_stats.cbSize.u.LowPart;
- /* Remove BMP header for DIB */ - if (file_format == D3DXIFF_DIB) - size -= sizeof(BITMAPFILEHEADER); - - hr = D3DXCreateBuffer(size, &buffer); - if (FAILED(hr)) goto cleanup; - - hr = GetHGlobalFromStream(stream, &stream_hglobal); - if (SUCCEEDED(hr)) + hr = unlock_surface(src_surface, NULL, temp_surface, FALSE); + if (FAILED(hr)) { - void *buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer); - void *stream_data = GlobalLock(stream_hglobal); - /* Remove BMP header for DIB */ - if (file_format == D3DXIFF_DIB) - stream_data = (void*)((BYTE*)stream_data + sizeof(BITMAPFILEHEADER)); - memcpy(buffer_pointer, stream_data, size); - GlobalUnlock(stream_hglobal); - *dst_buffer = buffer; + ID3DXBuffer_Release(buffer); + return hr; } - else ID3DXBuffer_Release(buffer); - -cleanup_err: - if (FAILED(hr) && hr != E_OUTOFMEMORY) - hr = D3DERR_INVALIDCALL; - -cleanup: - if (stream) IStream_Release(stream);
- if (frame) IWICBitmapFrameEncode_Release(frame); - if (encoder_options) IPropertyBag2_Release(encoder_options); - - if (encoder) IWICBitmapEncoder_Release(encoder); - - return hr; + *dst_buffer = buffer; + return D3D_OK; } diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 4e09313bc32..32c748a730d 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -3871,7 +3871,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_P8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_P8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -3941,7 +3941,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8, }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4100,7 +4100,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_format = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4144,7 +4144,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A4R4G4B4, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A4R4G4B4, .todo_format = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4183,7 +4183,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4194,7 +4194,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4205,7 +4205,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4216,7 +4216,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4227,7 +4227,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4238,7 +4238,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4249,7 +4249,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4260,7 +4260,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4271,7 +4271,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_A8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4304,7 +4304,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4337,7 +4337,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3D_OK, D3DFMT_A8R8G8B8 }, { D3D_OK, D3DFMT_A16B16G16R16 }, { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, - { D3D_OK, D3DFMT_X8R8G8B8, .todo_hr = TRUE }, + { D3D_OK, D3DFMT_X8R8G8B8 }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, { D3D_OK, D3DFMT_A32B32G32R32F, .todo_hr = TRUE }, }, @@ -4348,7 +4348,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, }, @@ -4359,7 +4359,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, }, @@ -4370,7 +4370,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, }, @@ -4381,7 +4381,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, }, @@ -4392,7 +4392,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, }, @@ -4403,7 +4403,7 @@ static void test_save_surface_iffs(IDirect3DDevice9 *device) { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, - { D3DERR_INVALIDCALL, .todo_hr = TRUE }, + { D3DERR_INVALIDCALL }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, { D3DERR_INVALIDCALL, .todo_hr = TRUE }, }, @@ -4664,13 +4664,10 @@ static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device)
hr = D3DXGetImageInfoFromFileInMemory(ID3DXBuffer_GetBufferPointer(buffer), ID3DXBuffer_GetBufferSize(buffer), &info); ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine ok(info.ImageFileFormat == D3DXIFF_BMP, "Unexpected ImageFileFormat %d.\n", info.ImageFileFormat); - todo_wine ok(ID3DXBuffer_GetBufferSize(buffer) == ID3DXBuffer_GetBufferSize(buffer2), "Unexpected buffer size.\n"); - if (ID3DXBuffer_GetBufferSize(buffer) == ID3DXBuffer_GetBufferSize(buffer2)) - { - ok(!memcmp(ID3DXBuffer_GetBufferPointer(buffer), ID3DXBuffer_GetBufferPointer(buffer2), ID3DXBuffer_GetBufferSize(buffer)), - "Files do not match.\n"); - } + ok(info.ImageFileFormat == D3DXIFF_BMP, "Unexpected ImageFileFormat %d.\n", info.ImageFileFormat); + ok(ID3DXBuffer_GetBufferSize(buffer) == ID3DXBuffer_GetBufferSize(buffer2), "Unexpected buffer size.\n"); + ok(!memcmp(ID3DXBuffer_GetBufferPointer(buffer), ID3DXBuffer_GetBufferPointer(buffer2), ID3DXBuffer_GetBufferSize(buffer)), + "Files do not match.\n");
ID3DXBuffer_Release(buffer); ID3DXBuffer_Release(buffer2);
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/surface.c:
- if (FAILED(hr))
goto exit;
- hr = IWICBitmapEncoder_CreateNewFrame(wic_encoder, &wic_frame, &encoder_options);
- if (FAILED(hr))
goto exit;
- hr = IWICBitmapFrameEncode_Initialize(wic_frame, encoder_options);
- if (FAILED(hr))
goto exit;
- hr = IWICBitmapFrameEncode_SetSize(wic_frame, pixels->size.width, pixels->size.height);
- if (FAILED(hr))
goto exit;
- memcpy(&wic_pixel_format, pixel_format_guid, sizeof(*pixel_format_guid));
This could also be written as: ```suggestion:-0+0 wic_pixel_format = *pixel_format_guid; ```
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/surface.c:
if (FAILED(hr))
{
IStream_Release(wic_file);
goto exit;
}
hr = IStream_Read(wic_file, ID3DXBuffer_GetBufferPointer(buffer), buf_size, NULL);
IStream_Release(wic_file);
if (FAILED(hr))
goto exit;
}
- }
- /* Return an empty buffer for size 0 images via WIC. */
- else if (!buffer)
- {
hr = D3DXCreateBuffer(64, &buffer);
This is copying existing code from `D3DXSaveSurfaceToFileInMemory()`, so nothing really about the patch itself, just an excuse to discuss this bit.
We're returning a zero-initialized buffer for size-0 images for WIC file formats. Do we know what does native do for these (assuming there is consistent behavior in the first place)? I'd expect some kind of "empty" image but with a normal file header (at least with the retail d3d version, I see the test mentions a `D3DERR_INVALIDCALL` return with the debug runtime).
It doesn't seem like a big deal in any case, but it might be worthwhile to give it a look and possibly add a `FIXME` if this isn't exactly "compliant".
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/surface.c:
}, }, /*
* We don't match formats here because we encode our BMP headers
* differently. Native encodes with the same header as
* D3DFMT_X8R8G8B8, it just sets the values in the alpha channel. The
* format is distinguished by checking the image. We encode a bitmap
* V4 header with a dedicated alpha mask, so we'll always report
* D3DFMT_A8R8G8B8, regardless of whether or not any alpha channel
* values are non-zero.
* For BMP/DIB, these encode as D3DFMT_X8R8G8B8. If there's a single
* pixel with a non-zero alpha channel, it reports as D3DFMT_A8R8G8B8.
Nitpick, "If there's at least one pixel..."
This merge request was approved by Matteo Bruni.
MR looks good to me. I left a few comments for very minor details / followups.