[PATCH v3] windowscodecs: Correctly handle 8bpp custom conversions
Alistair Leslie-Hughes
leslie_alistair at hotmail.com
Fri Feb 25 00:53:01 CST 2022
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
dlls/windowscodecs/converter.c | 40 ++++-----
dlls/windowscodecs/tests/converter.c | 128 +++++++++++++++++++++++++++
2 files changed, 147 insertions(+), 21 deletions(-)
diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c
index a401d1cdc4a..8abba2dec52 100644
--- a/dlls/windowscodecs/converter.c
+++ b/dlls/windowscodecs/converter.c
@@ -69,6 +69,7 @@ struct pixelformatinfo {
enum pixelformat format;
const WICPixelFormatGUID *guid;
copyfunc copy_function;
+ BOOL is_indexed_format;
};
typedef struct FormatConverter {
@@ -1493,10 +1494,10 @@ static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WIC
}
static const struct pixelformatinfo supported_formats[] = {
- {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL},
- {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL},
- {format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL},
- {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed},
+ {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL, TRUE},
+ {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL, TRUE},
+ {format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL, TRUE},
+ {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed, TRUE},
{format_BlackWhite, &GUID_WICPixelFormatBlackWhite, NULL},
{format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL},
{format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL},
@@ -1636,12 +1637,7 @@ static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface,
if (!This->palette)
{
- HRESULT hr;
- UINT bpp;
-
- hr = get_pixelformat_bpp(This->dst_format->guid, &bpp);
- if (hr != S_OK) return hr;
- if (bpp <= 8) return WINCODEC_ERR_WRONGSTATE;
+ if (This->dst_format->is_indexed_format) return WINCODEC_ERR_WRONGSTATE;
return IWICBitmapSource_CopyPalette(This->source, palette);
}
@@ -1689,6 +1685,13 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
TRACE("(%p,%p,%s,%u,%p,%0.3f,%u)\n", iface, source, debugstr_guid(dstFormat),
dither, palette, alpha_threshold, palette_type);
+ dstinfo = get_formatinfo(dstFormat);
+ if (!dstinfo)
+ {
+ FIXME("Unsupported destination format %s\n", debugstr_guid(dstFormat));
+ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
+ }
+
if (!palette)
{
UINT bpp;
@@ -1703,18 +1706,21 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
case WICBitmapPaletteTypeCustom:
IWICPalette_Release(palette);
palette = NULL;
- if (bpp <= 8) return E_INVALIDARG;
+
+ /* Indexed types require a palette */
+ if (dstinfo->is_indexed_format)
+ return E_INVALIDARG;
break;
case WICBitmapPaletteTypeMedianCut:
{
- if (bpp <= 8)
+ if (dstinfo->is_indexed_format)
res = IWICPalette_InitializeFromBitmap(palette, source, 1 << bpp, FALSE);
break;
}
default:
- if (bpp <= 8)
+ if (dstinfo->is_indexed_format)
res = IWICPalette_InitializePredefined(palette, palette_type, FALSE);
break;
}
@@ -1747,14 +1753,6 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
goto end;
}
- dstinfo = get_formatinfo(dstFormat);
- if (!dstinfo)
- {
- res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT;
- FIXME("Unsupported destination format %s\n", debugstr_guid(dstFormat));
- goto end;
- }
-
if (dstinfo->copy_function)
{
IWICBitmapSource_AddRef(source);
diff --git a/dlls/windowscodecs/tests/converter.c b/dlls/windowscodecs/tests/converter.c
index f0672fceaf8..ca26b5204bc 100644
--- a/dlls/windowscodecs/tests/converter.c
+++ b/dlls/windowscodecs/tests/converter.c
@@ -538,6 +538,18 @@ static const float bits_32bppGrayFloat[] = {
static const struct bitmap_data testdata_32bppGrayFloat = {
&GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat, 32, 2, 96.0, 96.0, &testdata_32bppGrayFloat_xp};
+static const BYTE bits_4bppGray_xp[] = {
+ 77,112,77,112,77,112,77,112,77,112,77,112,77,112,77,112,249,
+ 239,249,239,249,239,249,239,249,239,249,239,249,239,249,239};
+static const struct bitmap_data testdata_4bppGray_xp = {
+ &GUID_WICPixelFormat4bppGray, 4, bits_4bppGray_xp, 32, 2, 96.0, 96.0};
+
+static const BYTE bits_4bppGray[] = {
+ 77,112,77,112,77,112,77,112,77,112,77,112,77,112,77,112,249,
+ 239,249,239,249,239,249,239,249,239,249,239,249,239,249,239};
+static const struct bitmap_data testdata_4bppGray = {
+ &GUID_WICPixelFormat4bppGray, 4, bits_4bppGray, 32, 2, 96.0, 96.0, &testdata_4bppGray_xp};
+
static const BYTE bits_8bppGray_xp[] = {
29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0,
29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0,
@@ -637,6 +649,72 @@ static void test_default_converter(void)
DeleteTestBitmap(src_obj);
}
+static void test_converter_4bppGray(void)
+{
+ BitmapTestSrc *src_obj;
+ IWICFormatConverter *converter;
+ BOOL can_convert = TRUE;
+ HRESULT hr;
+
+ CreateTestBitmap(&testdata_32bppBGRA, &src_obj);
+
+ hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IWICFormatConverter, (void**)&converter);
+ ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA,
+ &GUID_WICPixelFormat4bppGray, &can_convert);
+ ok(SUCCEEDED(hr), "CanConvert returned %x\n", hr);
+ todo_wine ok(can_convert, "expected TRUE, got %i\n", can_convert);
+
+ hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
+ &GUID_WICPixelFormat4bppGray, WICBitmapDitherTypeNone, NULL, 0.0,
+ WICBitmapPaletteTypeCustom);
+ todo_wine ok(SUCCEEDED(hr), "Initialize returned %x\n", hr);
+
+ if (SUCCEEDED(hr))
+ compare_bitmap_data(&testdata_32bppBGRA, &testdata_4bppGray, (IWICBitmapSource*)converter, "4bppGray converter");
+
+ IWICFormatConverter_Release(converter);
+ }
+
+ DeleteTestBitmap(src_obj);
+}
+
+static void test_converter_8bppGray(void)
+{
+ BitmapTestSrc *src_obj;
+ IWICFormatConverter *converter;
+ BOOL can_convert = TRUE;
+ HRESULT hr;
+
+ CreateTestBitmap(&testdata_32bppBGRA, &src_obj);
+
+ hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IWICFormatConverter, (void**)&converter);
+ ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA,
+ &GUID_WICPixelFormat8bppGray, &can_convert);
+ ok(SUCCEEDED(hr), "CanConvert returned %x\n", hr);
+ ok(can_convert, "expected TRUE, got %i\n", can_convert);
+
+ hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
+ &GUID_WICPixelFormat8bppGray, WICBitmapDitherTypeNone, NULL, 0.0,
+ WICBitmapPaletteTypeCustom);
+ ok(SUCCEEDED(hr), "Initialize returned %x\n", hr);
+
+ if (SUCCEEDED(hr))
+ compare_bitmap_data(&testdata_32bppBGRA, &testdata_8bppGray, (IWICBitmapSource*)converter, "8bppGray converter");
+
+ IWICFormatConverter_Release(converter);
+ }
+
+ DeleteTestBitmap(src_obj);
+}
+
typedef struct property_opt_test_data
{
LPCOLESTR name;
@@ -1736,6 +1814,54 @@ static void test_converter_8bppIndexed(void)
ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr);
IWICFormatConverter_Release(converter);
+ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
+ ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
+ hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
+ &GUID_WICPixelFormat4bppIndexed, WICBitmapDitherTypeNone,
+ NULL, 0.0, WICBitmapPaletteTypeCustom);
+ ok(hr == E_INVALIDARG, "unexpected error %#x\n", hr);
+ IWICFormatConverter_Release(converter);
+
+ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
+ ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
+ hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
+ &GUID_WICPixelFormat2bppIndexed, WICBitmapDitherTypeNone,
+ NULL, 0.0, WICBitmapPaletteTypeCustom);
+ ok(hr == E_INVALIDARG, "unexpected error %#x\n", hr);
+ IWICFormatConverter_Release(converter);
+
+ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
+ ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
+ hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
+ &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone,
+ NULL, 0.0, WICBitmapPaletteTypeCustom);
+ ok(hr == E_INVALIDARG, "unexpected error %#x\n", hr);
+ IWICFormatConverter_Release(converter);
+
+ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
+ ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
+ hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
+ &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone,
+ NULL, 0.0, WICBitmapPaletteTypeMedianCut);
+ todo_wine ok(hr == S_OK, "unexpected error %#x\n", hr);
+ IWICFormatConverter_Release(converter);
+
+ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
+ ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
+ hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
+ &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone,
+ NULL, 0.0, WICBitmapPaletteTypeFixedBW);
+ todo_wine ok(hr == S_OK, "unexpected error %#x\n", hr);
+ IWICFormatConverter_Release(converter);
+
+ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
+ ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
+ hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface,
+ &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone,
+ NULL, 0.0, WICBitmapPaletteTypeFixedHalftone8);
+ todo_wine ok(hr == E_INVALIDARG, "unexpected error %#x\n", hr);
+ IWICFormatConverter_Release(converter);
+
/* empty palette + Custom type */
hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
@@ -1906,6 +2032,8 @@ START_TEST(converter)
test_invalid_conversion();
test_default_converter();
+ test_converter_4bppGray();
+ test_converter_8bppGray();
test_converter_8bppIndexed();
test_encoder(&testdata_8bppIndexed, &CLSID_WICGifEncoder,
--
2.34.1
More information about the wine-devel
mailing list