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

Alexandre Julliard julliard at winehq.org
Thu Nov 8 14:47:26 CST 2018


Module: wine
Branch: master
Commit: 748a246a8de172678a6e8b779b9378cf5fd0aca1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=748a246a8de172678a6e8b779b9378cf5fd0aca1

Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date:   Thu Nov  8 22:17:04 2018 +0900

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 at gmail.com>
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdiplus/image.c       | 41 +++++++++++++++++++++++++++++++++++++++++
 dlls/gdiplus/tests/image.c | 10 +++++-----
 2 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index e9b0b08..ccfa165 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 ca78747..41ec4dc 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 },




More information about the wine-cvs mailing list