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.
-- v2: d3dx9: Add support for saving DIB files in d3dx_save_pixels_to_memory(). d3dx9: Add support for saving paletted pixel formats in d3dx_pixels_save_wic(). d3dx9: Add support for saving BMP files in d3dx_save_pixels_to_memory(). d3dx9: Add support for saving JPG files in d3dx_save_pixels_to_memory(). d3dx9: Add support for saving PNG files in d3dx_save_pixels_to_memory().
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 | 236 ++++++++++++++++++++++++++++------ dlls/d3dx9_36/tests/surface.c | 80 ++++++------ 2 files changed, 235 insertions(+), 81 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index da8ab19a4dc..060aa76bd76 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; + + wic_pixel_format = *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,66 @@ 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) + { + FIXME("Returning empty buffer for size 0 image.\n"); + 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 +1197,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 +1300,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 +2766,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 +3268,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 060aa76bd76..e6ee986dace 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 @@ -3268,12 +3279,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 e6ee986dace..a091de45467 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); + wic_pixel_format = *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 @@ -3275,7 +3332,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; @@ -3283,6 +3339,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..887c1a793cb 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 at least + * one 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 a091de45467..b1d688e3208 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 887c1a793cb..160bf0d0ead 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 b1d688e3208..6b986055b06 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 @@ -991,75 +989,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 }; @@ -3337,214 +3266,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 160bf0d0ead..2b24555c8c8 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);
On Mon Mar 3 23:19:38 2025 +0000, Matteo Bruni wrote:
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".
I wrote some tests for this awhile ago and forgot how it behaved on native :)
I just tested it again, it's format dependent. BMP/TGA/PPM/HDR/PFM/DDS all encode a header with width/height fields set to 0. JPG and PNG just return a buffer with a size of 0. I've added a `FIXME` now to indicate that we're returning an empty buffer.
On Tue Mar 4 15:15:24 2025 +0000, Connor McAdams wrote:
I wrote some tests for this awhile ago and forgot how it behaved on native :) I just tested it again, it's format dependent. BMP/TGA/PPM/HDR/PFM/DDS all encode a header with width/height fields set to 0. JPG and PNG just return a buffer with a size of 0. I've added a `FIXME` now to indicate that we're returning an empty buffer.
Ah, good to know, thanks!