gdiplus: Convert to 32bppARGB when PNG image with transparency chunk is loaded. (rebased).

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44409
Signed-off-by: Akihiro Sagawa <sagawa.aki@gmail.com>
Signed-off-by: Vincent Povirk <vincent@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Akihiro Sagawa 2018-11-08 22:17:04 +09:00 committed by Alexandre Julliard
parent 5855ff7846
commit 748a246a8d
2 changed files with 46 additions and 5 deletions

View File

@ -3949,6 +3949,39 @@ static GpStatus decode_image_jpeg(IStream* stream, GpImage **image)
return decode_image_wic(stream, &GUID_ContainerFormatJpeg, NULL, image);
}
static BOOL has_png_transparency_chunk(IStream *pIStream)
{
LARGE_INTEGER seek;
BOOL has_tRNS = FALSE;
HRESULT hr;
BYTE header[8];
seek.QuadPart = 8;
do
{
ULARGE_INTEGER chunk_start;
ULONG bytesread, chunk_size;
hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, &chunk_start);
if (FAILED(hr)) break;
hr = IStream_Read(pIStream, header, 8, &bytesread);
if (FAILED(hr) || bytesread < 8) break;
chunk_size = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3];
if (!memcmp(&header[4], "tRNS", 4))
{
has_tRNS = TRUE;
break;
}
seek.QuadPart = chunk_start.QuadPart + chunk_size + 12; /* skip data and CRC */
} while (memcmp(&header[4], "IDAT", 4) && memcmp(&header[4], "IEND", 4));
TRACE("has_tRNS = %d\n", has_tRNS);
return has_tRNS;
}
static GpStatus decode_image_png(IStream* stream, GpImage **image)
{
IWICBitmapDecoder *decoder;
@ -3970,6 +4003,14 @@ static GpStatus decode_image_png(IStream* stream, GpImage **image)
{
if (IsEqualGUID(&format, &GUID_WICPixelFormat8bppGray))
force_conversion = TRUE;
else if ((IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed) ||
IsEqualGUID(&format, &GUID_WICPixelFormat4bppIndexed) ||
IsEqualGUID(&format, &GUID_WICPixelFormat2bppIndexed) ||
IsEqualGUID(&format, &GUID_WICPixelFormat1bppIndexed) ||
IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR)) &&
has_png_transparency_chunk(stream))
force_conversion = TRUE;
status = decode_frame_wic(decoder, force_conversion, 0, png_metadata_reader, image);
}
else

View File

@ -5168,7 +5168,7 @@ static void test_png_color_formats(void)
{ 2, PNG_COLOR_TYPE_RGB },
{ 4, PNG_COLOR_TYPE_RGB },
{ 8, PNG_COLOR_TYPE_RGB,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE },
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ PixelFormat24bppRGB, ImageFlagsColorSpaceRGB },
{ PixelFormat24bppRGB, ImageFlagsColorSpaceRGB }}},
/* libpng refuses to load our test image complaining about extra compressed data,
@ -5182,7 +5182,7 @@ static void test_png_color_formats(void)
/* 5 */
{ 1, PNG_COLOR_TYPE_GRAY,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE },
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ PixelFormat1bppIndexed, ImageFlagsColorSpaceRGB },
{ PixelFormat1bppIndexed, ImageFlagsColorSpaceRGB }}},
{ 2, PNG_COLOR_TYPE_GRAY,
@ -5194,7 +5194,7 @@ static void test_png_color_formats(void)
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY }}},
{ 8, PNG_COLOR_TYPE_GRAY,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE },
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY }}},
{ 16, PNG_COLOR_TYPE_GRAY,
@ -5204,7 +5204,7 @@ static void test_png_color_formats(void)
/* 10 */
{ 1, PNG_COLOR_TYPE_PALETTE,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE },
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ PixelFormat1bppIndexed, ImageFlagsColorSpaceRGB },
{ 0, 0 }}},
{ 2, PNG_COLOR_TYPE_PALETTE,
@ -5216,7 +5216,7 @@ static void test_png_color_formats(void)
{ PixelFormat4bppIndexed, ImageFlagsColorSpaceRGB, TRUE },
{ 0, 0 }}},
{ 8, PNG_COLOR_TYPE_PALETTE,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE },
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ PixelFormat8bppIndexed, ImageFlagsColorSpaceRGB },
{ 0, 0 }}},
{ 16, PNG_COLOR_TYPE_PALETTE },