Damjan Jovanovic : winemenubuilder: Generate .png even for paletted icons.

Alexandre Julliard julliard at winehq.org
Fri May 21 12:15:20 CDT 2010


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

Author: Damjan Jovanovic <damjan.jov at gmail.com>
Date:   Fri May 21 07:44:22 2010 +0200

winemenubuilder: Generate .png even for paletted icons.

---

 programs/winemenubuilder/winemenubuilder.c |  146 +++++++++++++++++++++++++++-
 1 files changed, 145 insertions(+), 1 deletions(-)

diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index 9f10fdb..eba21ef 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -242,7 +242,7 @@ static void user_warning_fn(png_structp png_ptr, png_const_charp warning_message
     WINE_WARN("PNG warning: %s\n", wine_dbgstr_an(warning_message, -1));
 }
 
-static BOOL SaveIconResAsPNG(const BITMAPINFO *pIcon, const char *png_filename, LPCWSTR commentW)
+static BOOL SaveTrueColorIconResAsPNG(const BITMAPINFO *pIcon, const char *png_filename, LPCWSTR commentW)
 {
     static const char comment_key[] = "Created from";
     FILE *fp;
@@ -373,6 +373,150 @@ static BOOL SaveIconResAsPNG(const BITMAPINFO *pIcon, const char *png_filename,
     HeapFree(GetProcessHeap(), 0, comment.text);
     return FALSE;
 }
+
+static BOOL SavePalettedIconResAsPNG(const BITMAPINFO *pIcon, const char *png_filename, LPCWSTR commentW)
+{
+    static const char comment_key[] = "Created from";
+    FILE *pngFile = NULL;
+    int i, j;
+    int nHeight;
+    int nXORWidthBytes;
+    int nANDWidthBytes;
+    BOOL b8BitColors;
+    int nColors;
+    const BYTE *pXOR;
+    const BYTE *pAND;
+    png_structp png_ptr;
+    png_infop info_ptr;
+    png_text comment;
+    jmp_buf jmpbuf;
+    unsigned char *row = NULL;
+    BOOL ret = FALSE;
+
+    comment.text = NULL;
+
+    if (!((pIcon->bmiHeader.biBitCount == 4) || (pIcon->bmiHeader.biBitCount == 8)))
+    {
+        WINE_FIXME("Unsupported color depth %d-bit\n", pIcon->bmiHeader.biBitCount);
+        goto done;
+    }
+
+    if (!(pngFile = fopen(png_filename, "w")))
+    {
+        WINE_TRACE("Unable to open '%s' for writing: %s\n", png_filename, strerror(errno));
+        goto done;
+    }
+
+    nHeight = pIcon->bmiHeader.biHeight / 2;
+    nXORWidthBytes = 4 * ((pIcon->bmiHeader.biWidth * pIcon->bmiHeader.biBitCount / 32)
+                          + ((pIcon->bmiHeader.biWidth * pIcon->bmiHeader.biBitCount % 32) > 0));
+    nANDWidthBytes = 4 * ((pIcon->bmiHeader.biWidth / 32)
+                          + ((pIcon->bmiHeader.biWidth % 32) > 0));
+    b8BitColors = pIcon->bmiHeader.biBitCount == 8;
+    nColors = pIcon->bmiHeader.biClrUsed ? pIcon->bmiHeader.biClrUsed
+        : 1 << pIcon->bmiHeader.biBitCount;
+    pXOR = (const BYTE*) pIcon + sizeof (BITMAPINFOHEADER) + (nColors * sizeof (RGBQUAD));
+    pAND = pXOR + nHeight * nXORWidthBytes;
+
+    row = HeapAlloc(GetProcessHeap(), 0, 4 * pIcon->bmiHeader.biWidth);
+    if (row == NULL)
+    {
+        WINE_ERR("out of memory\n");
+        goto done;
+    }
+
+    if (!libpng_handle && !load_libpng())
+    {
+        WINE_WARN("Unable to load libpng\n");
+        goto done;
+    }
+
+    if (!(png_ptr = ppng_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) ||
+        !(info_ptr = ppng_create_info_struct(png_ptr)))
+        goto done;
+
+    if (setjmp(jmpbuf))
+    {
+        /* All future errors jump here */
+        goto done;
+    }
+    ppng_set_error_fn(png_ptr, &jmpbuf, user_error_fn, user_warning_fn);
+
+    ppng_init_io(png_ptr, pngFile);
+    ppng_set_IHDR(png_ptr, info_ptr, pIcon->bmiHeader.biWidth, nHeight, 8,
+                  PNG_COLOR_TYPE_RGB_ALPHA,
+                  PNG_INTERLACE_NONE,
+                  PNG_COMPRESSION_TYPE_DEFAULT,
+                  PNG_FILTER_TYPE_DEFAULT);
+
+    /* Set comment */
+    comment.compression = PNG_TEXT_COMPRESSION_NONE;
+    comment.key = (png_charp)comment_key;
+    i = WideCharToMultiByte(CP_UNIXCP, 0, commentW, -1, NULL, 0, NULL, NULL);
+    comment.text = HeapAlloc(GetProcessHeap(), 0, i);
+    if (comment.text == NULL)
+    {
+        WINE_ERR("out of memory\n");
+        goto done;
+    }
+    WideCharToMultiByte(CP_UNIXCP, 0, commentW, -1, comment.text, i, NULL, NULL);
+    comment.text_length = i - 1;
+    ppng_set_text(png_ptr, info_ptr, &comment, 1);
+
+    ppng_write_info(png_ptr, info_ptr);
+    for (i = 0; i < nHeight; i++)
+    {
+        unsigned char *p = row;
+        for (j = 0; j < pIcon->bmiHeader.biWidth; j++)
+        {
+            if MASK(j,i)
+            {
+                *p++ = 0;
+                *p++ = 0;
+                *p++ = 0;
+                *p++ = 0;
+            }
+            else
+            {
+#define COLOR(x,y) (b8BitColors ? pXOR[(x) + (nHeight - (y) - 1) * nXORWidthBytes] : (x) % 2 ? pXOR[(x) / 2 + (nHeight - (y) - 1) * nXORWidthBytes] & 0xF : (pXOR[(x) / 2 + (nHeight - (y) - 1) * nXORWidthBytes] & 0xF0) >> 4)
+                *p++ = pIcon->bmiColors[COLOR(j,i)].rgbRed;
+                *p++ = pIcon->bmiColors[COLOR(j,i)].rgbGreen;
+                *p++ = pIcon->bmiColors[COLOR(j,i)].rgbBlue;
+                *p++ = 0xFF;
+#undef COLOR
+            }
+        }
+        ppng_write_row(png_ptr, (png_bytep)row);
+    }
+    ppng_write_end(png_ptr, info_ptr);
+    ret = TRUE;
+
+done:
+    ppng_destroy_write_struct(&png_ptr, &info_ptr);
+    if (pngFile != NULL)
+        fclose(pngFile);
+    HeapFree(GetProcessHeap(), 0, comment.text);
+    HeapFree(GetProcessHeap(), 0, row);
+    return ret;
+}
+
+static BOOL SaveIconResAsPNG(const BITMAPINFO *pIcon, const char *png_filename, LPCWSTR commentW)
+{
+    switch (pIcon->bmiHeader.biBitCount)
+    {
+    case 4:
+        return SavePalettedIconResAsPNG(pIcon, png_filename, commentW);
+    case 8:
+        return SavePalettedIconResAsPNG(pIcon, png_filename, commentW);
+    case 24:
+        return SaveTrueColorIconResAsPNG(pIcon, png_filename, commentW);
+    case 32:
+        return SaveTrueColorIconResAsPNG(pIcon, png_filename, commentW);
+    default:
+        WINE_FIXME("unsupported bpp %d, please report", pIcon->bmiHeader.biBitCount);
+        return FALSE;
+    }
+}
 #endif /* SONAME_LIBPNG */
 
 static BOOL SaveIconResAsXPM(const BITMAPINFO *pIcon, const char *szXPMFileName, LPCWSTR commentW)




More information about the wine-cvs mailing list