From e74d39c32d4f49d9b983811772f3324bcbe3ce55 Mon Sep 17 00:00:00 2001 From: Ziqing Hui Date: Sat, 18 Jul 2020 11:15:38 +0800 Subject: [PATCH] windowscodecs: Introduce is_compressed(). And fix some format checks. Signed-off-by: Ziqing Hui Signed-off-by: Esme Povirk Signed-off-by: Alexandre Julliard --- dlls/windowscodecs/ddsformat.c | 37 ++++++++++++++++++++++------ dlls/windowscodecs/tests/ddsformat.c | 5 ++-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/dlls/windowscodecs/ddsformat.c b/dlls/windowscodecs/ddsformat.c index 41e92a2b482..5de3759527a 100644 --- a/dlls/windowscodecs/ddsformat.c +++ b/dlls/windowscodecs/ddsformat.c @@ -105,7 +105,6 @@ typedef struct dds_info { UINT frame_count; UINT data_offset; UINT bytes_per_block; - BOOL compressed; DXGI_FORMAT format; WICDdsDimension dimension; WICDdsAlphaMode alpha_mode; @@ -187,6 +186,16 @@ static struct dds_format { { { sizeof(DDS_PIXELFORMAT), DDPF_LUMINANCE, 0, 8, 0xFF,0,0,0 }, DXGI_FORMAT_R8_UNORM } }; +static DXGI_FORMAT compressed_formats[] = { + DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_BC4_TYPELESS, DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_SNORM, + DXGI_FORMAT_BC5_TYPELESS, DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_SNORM, + DXGI_FORMAT_BC6H_TYPELESS, DXGI_FORMAT_BC6H_UF16, DXGI_FORMAT_BC6H_SF16, + DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB +}; + static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *, UINT, UINT, UINT, IWICBitmapFrameDecode **); static inline BOOL has_extended_header(DDS_HEADER *header) @@ -273,13 +282,22 @@ static UINT get_bytes_per_block_from_format(DXGI_FORMAT format) } } +static BOOL is_compressed(DXGI_FORMAT format) +{ + UINT i; + + for (i = 0; i < ARRAY_SIZE(compressed_formats); i++) + { + if (format == compressed_formats[i]) return TRUE; + } + return FALSE; +} + static void get_dds_info(dds_info* info, DDS_HEADER *header, DDS_HEADER_DXT10 *header_dxt10) { int i; UINT depth; - info->compressed = !(header->ddspf.flags & (DDPF_RGB | DDPF_LUMINANCE)); - info->width = header->width; info->height = header->height; info->depth = 1; @@ -303,10 +321,10 @@ static void get_dds_info(dds_info* info, DDS_HEADER *header, DDS_HEADER_DXT10 *h info->pixel_format = (info->alpha_mode == WICDdsAlphaModePremultiplied) ? &GUID_WICPixelFormat32bppPBGRA : &GUID_WICPixelFormat32bppBGRA; - if (info->compressed) { - info->bytes_per_block = get_bytes_per_block_from_format(info->format); - } else { + if (header->ddspf.flags & (DDPF_RGB | DDPF_ALPHA | DDPF_LUMINANCE)) { info->bytes_per_block = header->ddspf.rgbBitCount / 8; + } else { + info->bytes_per_block = get_bytes_per_block_from_format(info->format); } /* get frame count */ @@ -685,7 +703,10 @@ static HRESULT WINAPI DdsDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p hr = IWICWineDecoder_Initialize(&This->IWICWineDecoder_iface, pIStream, cacheOptions); if (FAILED(hr)) goto end; - if (!This->info.compressed || This->info.dimension == WICDdsTextureCube) { + if (This->info.dimension == WICDdsTextureCube || + (This->info.format != DXGI_FORMAT_BC1_UNORM && + This->info.format != DXGI_FORMAT_BC2_UNORM && + This->info.format != DXGI_FORMAT_BC3_UNORM)) { IStream_Release(pIStream); This->stream = NULL; This->initialized = FALSE; @@ -911,7 +932,7 @@ static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *iface, } bytes_per_block = This->info.bytes_per_block; - if (This->info.compressed) { + if (is_compressed(This->info.format)) { block_width = DDS_BLOCK_WIDTH; block_height = DDS_BLOCK_HEIGHT; } else { diff --git a/dlls/windowscodecs/tests/ddsformat.c b/dlls/windowscodecs/tests/ddsformat.c index f1141c15a01..c5147c33278 100644 --- a/dlls/windowscodecs/tests/ddsformat.c +++ b/dlls/windowscodecs/tests/ddsformat.c @@ -331,7 +331,6 @@ static HRESULT init_decoder(IWICBitmapDecoder *decoder, IWICStream *stream, HRES if (index == -1) { ok(hr == S_OK || wine_init, "Decoder initialize failed, hr %#x\n", hr); } else { - todo_wine_if(index == 9 || index == 10 || index == 11) ok(hr == expected, "Test %u: Expected hr %#x, got %#x\n", index, expected, hr); } @@ -608,7 +607,7 @@ static void test_dds_decoder_frame_properties(IWICBitmapFrameDecode *frame_decod ok(format_info.DxgiFormat == test_data[i].expected_parameters.DxgiFormat, "Test %u, frame %u: Expected DXGI format %#x, got %#x\n", i, frame_index, test_data[i].expected_parameters.DxgiFormat, format_info.DxgiFormat); - todo_wine_if(i == 4 || i == 5 || i == 6) { + todo_wine_if(i == 4 || i == 5 || i == 6) ok(format_info.BytesPerBlock == test_data[i].expected_bytes_per_block, "Test %u, frame %u: Expected bytes per block %u, got %u\n", i, frame_index, test_data[i].expected_bytes_per_block, format_info.BytesPerBlock); @@ -618,7 +617,7 @@ static void test_dds_decoder_frame_properties(IWICBitmapFrameDecode *frame_decod ok(format_info.BlockHeight == expected_block_height, "Test %u, frame %u: Expected block height %u, got %u\n", i, frame_index, expected_block_height, format_info.BlockHeight); - } + /* size in blocks tests */