[PATCH v2] windowscodecs: Correctly handle 8bpp custom conversions
Esme Povirk (she/they)
esme at codeweavers.com
Thu Feb 24 15:01:46 CST 2022
Can you change the other checks for bpp <= 8 in this file to also use
is_indexed_format?
On Wed, Feb 23, 2022 at 7:37 PM Alistair Leslie-Hughes
<leslie_alistair at hotmail.com> wrote:
>
> Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
> ---
> dlls/windowscodecs/converter.c | 29 +++---
> dlls/windowscodecs/tests/converter.c | 128 +++++++++++++++++++++++++++
> 2 files changed, 144 insertions(+), 13 deletions(-)
>
> diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c
> index a401d1cdc4a..ed0babc26f2 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},
> @@ -1689,6 +1690,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,7 +1711,10 @@ 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:
> @@ -1747,14 +1758,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