[PATCH 0/2] MR10412: windowscodecs/tests: Add conversion tests for Gray2, Gray4 and Gray16 pixel formats.
windowscodecs/tests: Add conversion tests for 2bppGray, 4bppGray and 16bppGray pixel formats. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10412
From: Robert Gerigk <Robert-Gerigk@online.de> Add test data for 2bppGray and 16bppGray expected conversion results. Add test_conversion() calls for 8bppGray -> 2bppGray, 8bppGray -> 4bppGray, and 8bppGray -> 16bppGray conversions. Update dst_todo_count values for BlackWhite, 2bppGray, 4bppGray and 16bppGray from 35 to 12 to match the actual number of missing CanConvert source formats after implementing copypixels handlers. Signed-off-by: Robert Gerigk <Robert-Gerigk@online.de> --- dlls/windowscodecs/tests/converter.c | 29 ++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/dlls/windowscodecs/tests/converter.c b/dlls/windowscodecs/tests/converter.c index d85ae579d3b..166e964e8b6 100644 --- a/dlls/windowscodecs/tests/converter.c +++ b/dlls/windowscodecs/tests/converter.c @@ -596,6 +596,12 @@ 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_2bppGray[] = { + 0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74, + 0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef}; +static const struct bitmap_data testdata_2bppGray = { + &GUID_WICPixelFormat2bppGray, 2, bits_2bppGray, 32, 2, 96.0, 96.0}; + 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}; @@ -624,6 +630,18 @@ static const BYTE bits_8bppGray[] = { static const struct bitmap_data testdata_8bppGray = { &GUID_WICPixelFormat8bppGray, 8, bits_8bppGray, 32, 2, 96.0, 96.0, &testdata_8bppGray_xp}; +static const BYTE bits_16bppGray[] = { + 0x4c,0x4c, 0xdc,0xdc, 0x7f,0x7f, 0x00,0x00, 0x4c,0x4c, 0xdc,0xdc, 0x7f,0x7f, 0x00,0x00, + 0x4c,0x4c, 0xdc,0xdc, 0x7f,0x7f, 0x00,0x00, 0x4c,0x4c, 0xdc,0xdc, 0x7f,0x7f, 0x00,0x00, + 0x4c,0x4c, 0xdc,0xdc, 0x7f,0x7f, 0x00,0x00, 0x4c,0x4c, 0xdc,0xdc, 0x7f,0x7f, 0x00,0x00, + 0x4c,0x4c, 0xdc,0xdc, 0x7f,0x7f, 0x00,0x00, 0x4c,0x4c, 0xdc,0xdc, 0x7f,0x7f, 0x00,0x00, + 0xf7,0xf7, 0x91,0x91, 0xe6,0xe6, 0xff,0xff, 0xf7,0xf7, 0x91,0x91, 0xe6,0xe6, 0xff,0xff, + 0xf7,0xf7, 0x91,0x91, 0xe6,0xe6, 0xff,0xff, 0xf7,0xf7, 0x91,0x91, 0xe6,0xe6, 0xff,0xff, + 0xf7,0xf7, 0x91,0x91, 0xe6,0xe6, 0xff,0xff, 0xf7,0xf7, 0x91,0x91, 0xe6,0xe6, 0xff,0xff, + 0xf7,0xf7, 0x91,0x91, 0xe6,0xe6, 0xff,0xff, 0xf7,0xf7, 0x91,0x91, 0xe6,0xe6, 0xff,0xff}; +static const struct bitmap_data testdata_16bppGray = { + &GUID_WICPixelFormat16bppGray, 16, bits_16bppGray, 32, 2, 96.0, 96.0}; + static const BYTE bits_24bppBGR_gray[] = { 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0, 76,76,76, 220,220,220, 127,127,127, 0,0,0, @@ -858,11 +876,11 @@ static void test_can_convert(void) {WIC_PIXEL_FORMAT(2bppIndexed), TRUE, TRUE, 35}, {WIC_PIXEL_FORMAT(4bppIndexed), TRUE, TRUE, 35}, {WIC_PIXEL_FORMAT(8bppIndexed), TRUE, TRUE, 12}, - {WIC_PIXEL_FORMAT(BlackWhite), TRUE, TRUE, 35}, - {WIC_PIXEL_FORMAT(2bppGray), TRUE, TRUE, 35}, - {WIC_PIXEL_FORMAT(4bppGray), TRUE, TRUE, 35}, + {WIC_PIXEL_FORMAT(BlackWhite), TRUE, TRUE, 12}, + {WIC_PIXEL_FORMAT(2bppGray), TRUE, TRUE, 12}, + {WIC_PIXEL_FORMAT(4bppGray), TRUE, TRUE, 12}, {WIC_PIXEL_FORMAT(8bppGray), TRUE, TRUE, 12}, - {WIC_PIXEL_FORMAT(16bppGray), TRUE, TRUE, 35}, + {WIC_PIXEL_FORMAT(16bppGray), TRUE, TRUE, 12}, {WIC_PIXEL_FORMAT(8bppAlpha), TRUE, TRUE, 35, TRUE}, @@ -2391,6 +2409,9 @@ START_TEST(converter) test_conversion(&testdata_24bppBGR, &testdata_8bppGray, "24bppBGR -> 8bppGray", FALSE); test_conversion(&testdata_32bppBGR, &testdata_8bppGray, "32bppBGR -> 8bppGray", FALSE); + test_conversion(&testdata_8bppGray, &testdata_2bppGray, "8bppGray -> 2bppGray", FALSE); + test_conversion(&testdata_8bppGray, &testdata_4bppGray, "8bppGray -> 4bppGray", FALSE); + test_conversion(&testdata_8bppGray, &testdata_16bppGray, "8bppGray -> 16bppGray", FALSE); test_conversion(&testdata_32bppGrayFloat, &testdata_24bppBGR_gray, "32bppGrayFloat -> 24bppBGR gray", FALSE); test_conversion(&testdata_32bppGrayFloat, &testdata_8bppGray, "32bppGrayFloat -> 8bppGray", FALSE); test_conversion(&testdata_32bppBGRA, &testdata_16bppBGRA5551, "32bppBGRA -> 16bppBGRA5551", FALSE); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10412
From: Robert Gerigk <Robert-Gerigk@online.de> The WIC format converter did not support 2bppGray, 4bppGray or 16bppGray as destination formats, returning WINCODEC_ERR_UNSUPPORTEDOPERATION. Implement copypixels_to_2bppGray(): - Identity copy for 2bppGray source - All other formats: convert via 8bppGray, quantize to 4 levels, bit-pack Implement copypixels_to_4bppGray(): - Identity copy for 4bppGray source - All other formats: convert via 8bppGray, quantize to 16 levels, nibble-pack Implement copypixels_to_16bppGray(): - Identity copy for 16bppGray source - All other formats: convert via 8bppGray, expand to 16-bit (val * 257) Signed-off-by: Robert Gerigk <Robert-Gerigk@online.de> --- dlls/windowscodecs/converter.c | 144 ++++++++++++++++++++++++++++++++- 1 file changed, 141 insertions(+), 3 deletions(-) diff --git a/dlls/windowscodecs/converter.c b/dlls/windowscodecs/converter.c index 1783e0eb7ac..a671b8a0a95 100644 --- a/dlls/windowscodecs/converter.c +++ b/dlls/windowscodecs/converter.c @@ -2040,6 +2040,144 @@ static HRESULT copypixels_to_BlackWhite(struct FormatConverter *This, const WICR } } +static HRESULT copypixels_to_2bppGray(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + BYTE *srcdata; + UINT srcstride, srcdatasize; + + if (source_format == format_2bppGray) + { + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + } + + if (!prc) + return copypixels_to_8bppGray(This, NULL, cbStride, cbBufferSize, pbBuffer, source_format); + + srcstride = prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = malloc(srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + hr = copypixels_to_8bppGray(This, prc, srcstride, srcdatasize, srcdata, source_format); + if (SUCCEEDED(hr)) + { + INT x, y; + BYTE *src = srcdata, *dst = pbBuffer; + + for (y = 0; y < prc->Height; y++) + { + memset(dst, 0, (prc->Width + 3) / 4); + for (x = 0; x < prc->Width; x++) + { + BYTE gray2 = src[x] >> 6; /* 256 levels -> 4 levels */ + dst[x >> 2] |= gray2 << (6 - (x & 3) * 2); + } + src += srcstride; + dst += cbStride; + } + } + + free(srcdata); + return hr; +} + +static HRESULT copypixels_to_4bppGray(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + BYTE *srcdata; + UINT srcstride, srcdatasize; + + if (source_format == format_4bppGray) + { + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + } + + if (!prc) + return copypixels_to_8bppGray(This, NULL, cbStride, cbBufferSize, pbBuffer, source_format); + + srcstride = prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = malloc(srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + hr = copypixels_to_8bppGray(This, prc, srcstride, srcdatasize, srcdata, source_format); + if (SUCCEEDED(hr)) + { + INT x, y; + BYTE *src = srcdata, *dst = pbBuffer; + + for (y = 0; y < prc->Height; y++) + { + memset(dst, 0, (prc->Width + 1) / 2); + for (x = 0; x < prc->Width; x++) + { + BYTE gray4 = src[x] >> 4; /* 256 levels -> 16 levels */ + if (x & 1) + dst[x >> 1] |= gray4; + else + dst[x >> 1] |= gray4 << 4; + } + src += srcstride; + dst += cbStride; + } + } + + free(srcdata); + return hr; +} + +static HRESULT copypixels_to_16bppGray(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + BYTE *srcdata; + UINT srcstride, srcdatasize; + + if (source_format == format_16bppGray) + { + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + } + + if (!prc) + return copypixels_to_8bppGray(This, NULL, cbStride, cbBufferSize, pbBuffer, source_format); + + srcstride = prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = malloc(srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + hr = copypixels_to_8bppGray(This, prc, srcstride, srcdatasize, srcdata, source_format); + if (SUCCEEDED(hr)) + { + INT x, y; + BYTE *src = srcdata, *dst = pbBuffer; + + for (y = 0; y < prc->Height; y++) + { + UINT16 *dst16 = (UINT16 *)dst; + for (x = 0; x < prc->Width; x++) + dst16[x] = src[x] * 257; /* 0xFF -> 0xFFFF */ + src += srcstride; + dst += cbStride; + } + } + + free(srcdata); + return hr; +} + static HRESULT copypixels_to_16bppBGRA5551(struct FormatConverter *This, const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) { @@ -2550,10 +2688,10 @@ static const struct pixelformatinfo supported_formats[] = { {format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL, TRUE}, {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed, TRUE}, {format_BlackWhite, &GUID_WICPixelFormatBlackWhite, copypixels_to_BlackWhite}, - {format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL}, - {format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL}, + {format_2bppGray, &GUID_WICPixelFormat2bppGray, copypixels_to_2bppGray}, + {format_4bppGray, &GUID_WICPixelFormat4bppGray, copypixels_to_4bppGray}, {format_8bppGray, &GUID_WICPixelFormat8bppGray, copypixels_to_8bppGray}, - {format_16bppGray, &GUID_WICPixelFormat16bppGray, NULL}, + {format_16bppGray, &GUID_WICPixelFormat16bppGray, copypixels_to_16bppGray}, {format_16bppGrayHalf, &GUID_WICPixelFormat16bppGrayHalf}, {format_16bppBGR555, &GUID_WICPixelFormat16bppBGR555, NULL}, {format_16bppBGR565, &GUID_WICPixelFormat16bppBGR565, NULL}, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10412
participants (2)
-
Jan Robert Gerigk (@RgSg86) -
Robert Gerigk