[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