Vincent Povirk : windowscodecs: Generate a palette for color-keyed grayscale PNG's.

Alexandre Julliard julliard at winehq.org
Fri Sep 8 15:03:21 CDT 2017


Module: wine
Branch: master
Commit: 66b126b67539d23c61645e1dcff2191d42fc0249
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=66b126b67539d23c61645e1dcff2191d42fc0249

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Thu Sep  7 15:52:05 2017 -0500

windowscodecs: Generate a palette for color-keyed grayscale PNG's.

Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 configure                            |  16 -----
 configure.ac                         |   4 +-
 dlls/windowscodecs/pngformat.c       | 124 +++++++++++++++++++----------------
 dlls/windowscodecs/tests/pngformat.c |   8 +--
 include/config.h.in                  |   3 -
 5 files changed, 73 insertions(+), 82 deletions(-)

diff --git a/configure b/configure
index 5138198..47a41cd 100755
--- a/configure
+++ b/configure
@@ -13890,23 +13890,7 @@ cat >>confdefs.h <<_ACEOF
 #define SONAME_LIBPNG "$ac_cv_lib_soname_png"
 _ACEOF
 
-       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <png.h>
-int
-main ()
-{
-typeof(png_set_expand_gray_1_2_4_to_8) *p
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
 
-$as_echo "#define HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8 1" >>confdefs.h
-
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
         else
             PNG_CFLAGS=""
diff --git a/configure.ac b/configure.ac
index a2ef1b4..cd5a50b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1647,9 +1647,7 @@ then
         [AC_CHECK_HEADERS([png.h])
         if test "$ac_cv_header_png_h" = "yes"
         then
-            WINE_CHECK_SONAME(png,png_create_read_struct,
-                [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <png.h>]],[[typeof(png_set_expand_gray_1_2_4_to_8) *p]])],
-                    [AC_DEFINE(HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8,1,[Define to 1 if libpng has the png_set_expand_gray_1_2_4_to_8 function.])])],
+            WINE_CHECK_SONAME(png,png_create_read_struct,,
                 [PNG_CFLAGS=""],[$PNG_LIBS -lm -lz],[[libpng[[0-9]]*]])
         else
             PNG_CFLAGS=""
diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index b4fd346..9e837ca 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -319,11 +319,6 @@ MAKE_FUNCPTR(png_get_tRNS);
 MAKE_FUNCPTR(png_set_bgr);
 MAKE_FUNCPTR(png_set_crc_action);
 MAKE_FUNCPTR(png_set_error_fn);
-#ifdef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
-MAKE_FUNCPTR(png_set_expand_gray_1_2_4_to_8);
-#else
-MAKE_FUNCPTR(png_set_gray_1_2_4_to_8);
-#endif
 MAKE_FUNCPTR(png_set_filler);
 MAKE_FUNCPTR(png_set_filter);
 MAKE_FUNCPTR(png_set_gray_to_rgb);
@@ -388,11 +383,6 @@ static void *load_libpng(void)
         LOAD_FUNCPTR(png_set_bgr);
         LOAD_FUNCPTR(png_set_crc_action);
         LOAD_FUNCPTR(png_set_error_fn);
-#ifdef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
-        LOAD_FUNCPTR(png_set_expand_gray_1_2_4_to_8);
-#else
-        LOAD_FUNCPTR(png_set_gray_1_2_4_to_8);
-#endif
         LOAD_FUNCPTR(png_set_filler);
         LOAD_FUNCPTR(png_set_filter);
         LOAD_FUNCPTR(png_set_gray_to_rgb);
@@ -651,43 +641,18 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
     /* check for color-keyed alpha */
     transparency = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans, &num_trans, &trans_values);
 
-    if (transparency && color_type != PNG_COLOR_TYPE_PALETTE)
+    if (transparency && (color_type == PNG_COLOR_TYPE_RGB ||
+        (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16)))
     {
         /* expand to RGBA */
         if (color_type == PNG_COLOR_TYPE_GRAY)
-        {
-            if (bit_depth < 8)
-            {
-#ifdef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
-                ppng_set_expand_gray_1_2_4_to_8(This->png_ptr);
-#else
-                ppng_set_gray_1_2_4_to_8(This->png_ptr);
-#endif
-                bit_depth = 8;
-            }
             ppng_set_gray_to_rgb(This->png_ptr);
-        }
         ppng_set_tRNS_to_alpha(This->png_ptr);
         color_type = PNG_COLOR_TYPE_RGB_ALPHA;
     }
 
     switch (color_type)
     {
-    case PNG_COLOR_TYPE_GRAY:
-        This->bpp = bit_depth;
-        switch (bit_depth)
-        {
-        case 1: This->format = &GUID_WICPixelFormatBlackWhite; break;
-        case 2: This->format = &GUID_WICPixelFormat2bppGray; break;
-        case 4: This->format = &GUID_WICPixelFormat4bppGray; break;
-        case 8: This->format = &GUID_WICPixelFormat8bppGray; break;
-        case 16: This->format = &GUID_WICPixelFormat16bppGray; break;
-        default:
-            ERR("invalid grayscale bit depth: %i\n", bit_depth);
-            hr = E_FAIL;
-            goto end;
-        }
-        break;
     case PNG_COLOR_TYPE_GRAY_ALPHA:
         /* WIC does not support grayscale alpha formats so use RGBA */
         ppng_set_gray_to_rgb(This->png_ptr);
@@ -707,6 +672,25 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
             goto end;
         }
         break;
+    case PNG_COLOR_TYPE_GRAY:
+        This->bpp = bit_depth;
+        if (!transparency)
+        {
+            switch (bit_depth)
+            {
+            case 1: This->format = &GUID_WICPixelFormatBlackWhite; break;
+            case 2: This->format = &GUID_WICPixelFormat2bppGray; break;
+            case 4: This->format = &GUID_WICPixelFormat4bppGray; break;
+            case 8: This->format = &GUID_WICPixelFormat8bppGray; break;
+            case 16: This->format = &GUID_WICPixelFormat16bppGray; break;
+            default:
+                ERR("invalid grayscale bit depth: %i\n", bit_depth);
+                hr = E_FAIL;
+                goto end;
+            }
+            break;
+        }
+        /* else fall through */
     case PNG_COLOR_TYPE_PALETTE:
         This->bpp = bit_depth;
         switch (bit_depth)
@@ -1034,7 +1018,7 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
     IWICPalette *pIPalette)
 {
     PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
-    png_uint_32 ret;
+    png_uint_32 ret, color_type, bit_depth;
     png_colorp png_palette;
     int num_palette;
     WICColor palette[256];
@@ -1048,30 +1032,58 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
 
     EnterCriticalSection(&This->lock);
 
-    ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette);
-    if (!ret)
-    {
-        hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
-        goto end;
-    }
+    color_type = ppng_get_color_type(This->png_ptr, This->info_ptr);
+    bit_depth = ppng_get_bit_depth(This->png_ptr, This->info_ptr);
 
-    if (num_palette > 256)
+    if (color_type == PNG_COLOR_TYPE_PALETTE)
     {
-        ERR("palette has %i colors?!\n", num_palette);
-        hr = E_FAIL;
-        goto end;
+        ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette);
+        if (!ret)
+        {
+            hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
+            goto end;
+        }
+
+        if (num_palette > 256)
+        {
+            ERR("palette has %i colors?!\n", num_palette);
+            hr = E_FAIL;
+            goto end;
+        }
+
+        ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values);
+        if (!ret) num_trans = 0;
+
+        for (i=0; i<num_palette; i++)
+        {
+            BYTE alpha = (i < num_trans) ? trans_alpha[i] : 0xff;
+            palette[i] = (alpha << 24 |
+                          png_palette[i].red << 16|
+                          png_palette[i].green << 8|
+                          png_palette[i].blue);
+        }
     }
+    else if (color_type == PNG_COLOR_TYPE_GRAY) {
+        ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values);
 
-    ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values);
-    if (!ret) num_trans = 0;
+        if (!ret)
+        {
+            hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
+            goto end;
+        }
 
-    for (i=0; i<num_palette; i++)
+        num_palette = 1 << bit_depth;
+
+        for (i=0; i<num_palette; i++)
+        {
+            BYTE alpha = (i == trans_values[0].gray) ? 0 : 0xff;
+            BYTE val = i * 255 / (num_palette - 1);
+            palette[i] = (alpha << 24 | val << 16 | val << 8 | val);
+        }
+    }
+    else
     {
-        BYTE alpha = (i < num_trans) ? trans_alpha[i] : 0xff;
-        palette[i] = (alpha << 24 |
-                      png_palette[i].red << 16|
-                      png_palette[i].green << 8|
-                      png_palette[i].blue);
+        hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
     }
 
 end:
diff --git a/dlls/windowscodecs/tests/pngformat.c b/dlls/windowscodecs/tests/pngformat.c
index f34711d..4b84cce 100644
--- a/dlls/windowscodecs/tests/pngformat.c
+++ b/dlls/windowscodecs/tests/pngformat.c
@@ -674,10 +674,10 @@ static void test_color_formats(void)
         { 24, 2, NULL, NULL, NULL },
         { 32, 2, NULL, NULL, NULL },
         /* 0 - PNG_COLOR_TYPE_GRAY */
-        { 1, 0, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormat1bppIndexed, TRUE },
-        { 2, 0, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppIndexed, TRUE },
-        { 4, 0, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppIndexed, TRUE },
-        { 8, 0, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppIndexed, TRUE },
+        { 1, 0, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormat1bppIndexed },
+        { 2, 0, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppIndexed },
+        { 4, 0, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppIndexed },
+        { 8, 0, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppIndexed },
         { 16, 0, &GUID_WICPixelFormat16bppGray, &GUID_WICPixelFormat16bppGray, &GUID_WICPixelFormat64bppRGBA },
         { 24, 0, NULL, NULL, NULL },
         { 32, 0, NULL, NULL, NULL },
diff --git a/include/config.h.in b/include/config.h.in
index b0b5925..dd7a3a2 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -711,9 +711,6 @@
 /* Define to 1 if you have the <png.h> header file. */
 #undef HAVE_PNG_H
 
-/* Define to 1 if libpng has the png_set_expand_gray_1_2_4_to_8 function. */
-#undef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
-
 /* Define to 1 if you have the `poll' function. */
 #undef HAVE_POLL
 




More information about the wine-cvs mailing list