[v2 PATCH 3/3] windowscodecs: Add support for palette image formats to PNG encoder.

Nikolay Sivov nsivov at codeweavers.com
Fri Jan 27 00:22:19 CST 2017


From: Dmitry Timoshkov <dmitry at baikal.ru>

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/windowscodecs/pngformat.c | 45 ++++++++++++++++++++++++++++++++++++++++++
 dlls/windowscodecs/regsvr.c    |  4 ++++
 2 files changed, 49 insertions(+)

diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index 990dcf6ecf..b13377a4bd 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009 Vincent Povirk for CodeWeavers
+ * Copyright 2016 Dmitry Timoshkov
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -330,8 +331,10 @@ MAKE_FUNCPTR(png_set_gray_to_rgb);
 MAKE_FUNCPTR(png_set_interlace_handling);
 MAKE_FUNCPTR(png_set_IHDR);
 MAKE_FUNCPTR(png_set_pHYs);
+MAKE_FUNCPTR(png_set_PLTE);
 MAKE_FUNCPTR(png_set_read_fn);
 MAKE_FUNCPTR(png_set_strip_16);
+MAKE_FUNCPTR(png_set_tRNS);
 MAKE_FUNCPTR(png_set_tRNS_to_alpha);
 MAKE_FUNCPTR(png_set_write_fn);
 MAKE_FUNCPTR(png_read_end);
@@ -399,8 +402,10 @@ static void *load_libpng(void)
         LOAD_FUNCPTR(png_set_interlace_handling);
         LOAD_FUNCPTR(png_set_IHDR);
         LOAD_FUNCPTR(png_set_pHYs);
+        LOAD_FUNCPTR(png_set_PLTE);
         LOAD_FUNCPTR(png_set_read_fn);
         LOAD_FUNCPTR(png_set_strip_16);
+        LOAD_FUNCPTR(png_set_tRNS);
         LOAD_FUNCPTR(png_set_tRNS_to_alpha);
         LOAD_FUNCPTR(png_set_write_fn);
         LOAD_FUNCPTR(png_read_end);
@@ -1338,6 +1343,10 @@ static const struct png_pixelformat formats[] = {
     {&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1},
     {&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0},
     {&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0},
+    {&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0},
+    {&GUID_WICPixelFormat2bppIndexed, 2, 2, PNG_COLOR_TYPE_PALETTE, 0, 0},
+    {&GUID_WICPixelFormat4bppIndexed, 4, 4, PNG_COLOR_TYPE_PALETTE, 0, 0},
+    {&GUID_WICPixelFormat8bppIndexed, 8, 8, PNG_COLOR_TYPE_PALETTE, 0, 0},
     {NULL},
 };
 
@@ -1640,6 +1649,42 @@ static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface,
                 (This->yres+0.0127) / 0.0254, PNG_RESOLUTION_METER);
         }
 
+        if (This->format->color_type == PNG_COLOR_TYPE_PALETTE && This->colors)
+        {
+            png_color png_palette[256];
+            png_byte trans[256];
+            UINT i, num_trans = 0, colors;
+
+            /* Newer libpng versions don't accept larger palettes than the declared
+             * bit depth, so we need to generate the palette of the correct length.
+             */
+            colors = 1 << This->format->bit_depth;
+
+            for (i = 0; i < colors; i++)
+            {
+                if (i < This->colors)
+                {
+                    png_palette[i].red = (This->palette[i] >> 16) & 0xff;
+                    png_palette[i].green = (This->palette[i] >> 8) & 0xff;
+                    png_palette[i].blue = This->palette[i] & 0xff;
+                    trans[i] = (This->palette[i] >> 24) & 0xff;
+                    if (trans[i] != 0xff)
+                        num_trans++;
+                }
+                else
+                {
+                    png_palette[i].red = 0;
+                    png_palette[i].green = 0;
+                    png_palette[i].blue = 0;
+                }
+            }
+
+            ppng_set_PLTE(This->png_ptr, This->info_ptr, png_palette, colors);
+
+            if (num_trans)
+                ppng_set_tRNS(This->png_ptr, This->info_ptr, trans, colors, NULL);
+        }
+
         ppng_write_info(This->png_ptr, This->info_ptr);
 
         if (This->format->remove_filler)
diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c
index 10a6c03d9b..b011d71645 100644
--- a/dlls/windowscodecs/regsvr.c
+++ b/dlls/windowscodecs/regsvr.c
@@ -1359,6 +1359,10 @@ static GUID const * const png_encode_formats[] = {
     &GUID_WICPixelFormat32bppBGRA,
     &GUID_WICPixelFormat48bppRGB,
     &GUID_WICPixelFormat64bppRGBA,
+    &GUID_WICPixelFormat1bppIndexed,
+    &GUID_WICPixelFormat2bppIndexed,
+    &GUID_WICPixelFormat4bppIndexed,
+    &GUID_WICPixelFormat8bppIndexed,
     NULL
 };
 
-- 
2.11.0




More information about the wine-patches mailing list