diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index e9b0b087af9..ccfa165013f 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -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 diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index ca7874771b0..41ec4dcaa6c 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -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 },