windowscodecs: Correctly handle 8bpp custom conversions.
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair@hotmail.com> Signed-off-by: Esme Povirk <esme@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
15a3864f4d
commit
950f3c08ce
|
@ -69,6 +69,7 @@ struct pixelformatinfo {
|
||||||
enum pixelformat format;
|
enum pixelformat format;
|
||||||
const WICPixelFormatGUID *guid;
|
const WICPixelFormatGUID *guid;
|
||||||
copyfunc copy_function;
|
copyfunc copy_function;
|
||||||
|
BOOL is_indexed_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct FormatConverter {
|
typedef struct FormatConverter {
|
||||||
|
@ -1493,10 +1494,10 @@ static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WIC
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pixelformatinfo supported_formats[] = {
|
static const struct pixelformatinfo supported_formats[] = {
|
||||||
{format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL},
|
{format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL, TRUE},
|
||||||
{format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL},
|
{format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL, TRUE},
|
||||||
{format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL},
|
{format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL, TRUE},
|
||||||
{format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed},
|
{format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed, TRUE},
|
||||||
{format_BlackWhite, &GUID_WICPixelFormatBlackWhite, NULL},
|
{format_BlackWhite, &GUID_WICPixelFormatBlackWhite, NULL},
|
||||||
{format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL},
|
{format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL},
|
||||||
{format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL},
|
{format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL},
|
||||||
|
@ -1636,12 +1637,7 @@ static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface,
|
||||||
|
|
||||||
if (!This->palette)
|
if (!This->palette)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
if (This->dst_format->is_indexed_format) return WINCODEC_ERR_WRONGSTATE;
|
||||||
UINT bpp;
|
|
||||||
|
|
||||||
hr = get_pixelformat_bpp(This->dst_format->guid, &bpp);
|
|
||||||
if (hr != S_OK) return hr;
|
|
||||||
if (bpp <= 8) return WINCODEC_ERR_WRONGSTATE;
|
|
||||||
return IWICBitmapSource_CopyPalette(This->source, palette);
|
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),
|
TRACE("(%p,%p,%s,%u,%p,%0.3f,%u)\n", iface, source, debugstr_guid(dstFormat),
|
||||||
dither, palette, alpha_threshold, palette_type);
|
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)
|
if (!palette)
|
||||||
{
|
{
|
||||||
UINT bpp;
|
UINT bpp;
|
||||||
|
@ -1703,18 +1706,21 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
|
||||||
case WICBitmapPaletteTypeCustom:
|
case WICBitmapPaletteTypeCustom:
|
||||||
IWICPalette_Release(palette);
|
IWICPalette_Release(palette);
|
||||||
palette = NULL;
|
palette = NULL;
|
||||||
if (bpp <= 8) return E_INVALIDARG;
|
|
||||||
|
/* Indexed types require a palette */
|
||||||
|
if (dstinfo->is_indexed_format)
|
||||||
|
return E_INVALIDARG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WICBitmapPaletteTypeMedianCut:
|
case WICBitmapPaletteTypeMedianCut:
|
||||||
{
|
{
|
||||||
if (bpp <= 8)
|
if (dstinfo->is_indexed_format)
|
||||||
res = IWICPalette_InitializeFromBitmap(palette, source, 1 << bpp, FALSE);
|
res = IWICPalette_InitializeFromBitmap(palette, source, 1 << bpp, FALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (bpp <= 8)
|
if (dstinfo->is_indexed_format)
|
||||||
res = IWICPalette_InitializePredefined(palette, palette_type, FALSE);
|
res = IWICPalette_InitializePredefined(palette, palette_type, FALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1747,14 +1753,6 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface,
|
||||||
goto end;
|
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)
|
if (dstinfo->copy_function)
|
||||||
{
|
{
|
||||||
IWICBitmapSource_AddRef(source);
|
IWICBitmapSource_AddRef(source);
|
||||||
|
|
|
@ -538,6 +538,18 @@ static const float bits_32bppGrayFloat[] = {
|
||||||
static const struct bitmap_data testdata_32bppGrayFloat = {
|
static const struct bitmap_data testdata_32bppGrayFloat = {
|
||||||
&GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat, 32, 2, 96.0, 96.0, &testdata_32bppGrayFloat_xp};
|
&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[] = {
|
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,
|
||||||
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);
|
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
|
typedef struct property_opt_test_data
|
||||||
{
|
{
|
||||||
LPCOLESTR name;
|
LPCOLESTR name;
|
||||||
|
@ -1736,6 +1814,54 @@ static void test_converter_8bppIndexed(void)
|
||||||
ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr);
|
ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr);
|
||||||
IWICFormatConverter_Release(converter);
|
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 */
|
/* empty palette + Custom type */
|
||||||
hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
|
hr = IWICImagingFactory_CreateFormatConverter(factory, &converter);
|
||||||
ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
|
ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr);
|
||||||
|
@ -1906,6 +2032,8 @@ START_TEST(converter)
|
||||||
|
|
||||||
test_invalid_conversion();
|
test_invalid_conversion();
|
||||||
test_default_converter();
|
test_default_converter();
|
||||||
|
test_converter_4bppGray();
|
||||||
|
test_converter_8bppGray();
|
||||||
test_converter_8bppIndexed();
|
test_converter_8bppIndexed();
|
||||||
|
|
||||||
test_encoder(&testdata_8bppIndexed, &CLSID_WICGifEncoder,
|
test_encoder(&testdata_8bppIndexed, &CLSID_WICGifEncoder,
|
||||||
|
|
Loading…
Reference in New Issue