diff libgfx.c @ 460:0af039b6c0ae

Improve transparent color handling.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 04 Nov 2012 13:57:03 +0200
parents 349a2ff11531
children c7a3aacbd55e
line wrap: on
line diff
--- a/libgfx.c	Sun Nov 04 12:28:05 2012 +0200
+++ b/libgfx.c	Sun Nov 04 13:57:03 2012 +0200
@@ -48,22 +48,35 @@
 }
 
 
-BOOL dmPaletteAlloc(DMColor **ppal, int ncolors)
+BOOL dmPaletteAlloc(DMColor **ppal, int ncolors, int ctransp)
 {
+    int i;
+
     if (ppal == NULL)
         return FALSE;
 
-    return (*ppal = dmCalloc(ncolors, sizeof(DMColor))) != NULL;
+    // Allocate desired amount of palette
+    if ((*ppal = dmCalloc(ncolors, sizeof(DMColor))) == NULL)
+        return FALSE;
+
+    // Set alpha values to max, except for transparent color
+    for (i = 0; i < ncolors; i++)
+    {
+        (*ppal)[i].a = (i == ctransp) ? 0 : 255;
+    }
+
+    return TRUE;
 }
 
 
-BOOL dmImageAllocPalette(DMImage *img, int ncolors)
+BOOL dmImageAllocPalette(DMImage *img, int ncolors, int ctransp)
 {
     if (img == NULL)
         return FALSE;
     
     img->ncolors = ncolors;
-    return dmPaletteAlloc(&(img->pal), ncolors);
+    img->ctransp = ctransp;
+    return dmPaletteAlloc(&(img->pal), ncolors, ctransp);
 }
 
 
@@ -140,7 +153,7 @@
                     qr = img->pal[c].r;
                     qg = img->pal[c].g;
                     qb = img->pal[c].b;
-                    qa = (c == img->ctrans) ? 0 : 255;
+                    qa = img->pal[c].a;
                 
                     for (xscale = 0; xscale < spec->scale; xscale++)
                     {
@@ -401,6 +414,11 @@
         PNG_COMPRESSION_TYPE_DEFAULT,
         PNG_FILTER_TYPE_DEFAULT);
 
+    dmMsg(2, "PNG: %d x %d, depth=%d, type=%d\n",
+        img->width * spec->scale,
+        img->height * spec->scale,
+        8, fmt);
+
     // Palette
     if (spec->format == DM_IFMT_PALETTE)
     {
@@ -423,7 +441,7 @@
             palette[i].blue  = img->pal[i].b;
         }
 
-        png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
+        png_set_PLTE(png_ptr, info_ptr, palette, img->ncolors);
     }
 
 //    png_set_gAMA(png_ptr, info_ptr, 2.2);
@@ -472,8 +490,9 @@
     png_infop info_ptr = NULL;
     png_colorp palette = NULL;
     png_bytep *row_pointers = NULL;
+    png_bytep trans = NULL;
     png_uint_32 width, height;
-    int i, bit_depth, color_type, ncolors;
+    int i, bit_depth, color_type, ncolors, ntrans;
     int res = DMERR_OK;
     DMImage *img;
 
@@ -566,21 +585,13 @@
     png_read_end(png_ptr, NULL);
 
     // Create palette
-    palette = png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof(png_color));
-    if (palette == NULL)
-    {
-        dmError("PNG: Could not allocate palette structure.");
-        res = DMERR_MALLOC;
-        goto error;
-    }
-    
     switch (color_type)
     {
         case PNG_COLOR_TYPE_GRAY:
             ncolors = 256;
             dmMsg(2, "PNG: Generating %d color grayscale palette.\n", ncolors);
 
-            if (!dmImageAllocPalette(img, ncolors))
+            if (!dmImageAllocPalette(img, ncolors, -1))
             {
                 res = DMERR_MALLOC;
                 goto error;
@@ -598,7 +609,7 @@
             if (ncolors <= 0)
                 goto error;
 
-            if (!dmImageAllocPalette(img, ncolors))
+            if (!dmImageAllocPalette(img, ncolors, -1))
             {
                 res = DMERR_MALLOC;
                 goto error;
@@ -613,8 +624,18 @@
             break;
     }
 
+    if (color_type == PNG_COLOR_TYPE_PALETTE ||
+        color_type == PNG_COLOR_TYPE_GRAY)
+    {
+        png_get_tRNS(png_ptr, info_ptr, &trans, &ntrans, NULL);
+        for (i = 0; i < img->ncolors && i < ntrans; i++)
+        {
+            img->pal[i].a = trans[i];
+        }
+    }    
+
 error:
-    png_free(png_ptr, palette);
+//    png_free(png_ptr, palette);
 
     if (png_ptr && info_ptr)
         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
@@ -1075,7 +1096,7 @@
             ncolors = 256;
         }
 
-        if (!dmImageAllocPalette(img, ncolors))
+        if (!dmImageAllocPalette(img, ncolors, -1))
         {
             dmError("PCX: Could not allocate palette data!\n");
             res = DMERR_MALLOC;
@@ -1476,7 +1497,7 @@
                 // Read palette
                 if (iff.ncolors > 0)
                 {
-                    if (!dmPaletteAlloc(&iff.pal, iff.ncolors))
+                    if (!dmPaletteAlloc(&iff.pal, iff.ncolors, -1))
                     {
                         dmError("ILBM: Could not allocate palette data.\n");
                         return DMERR_MALLOC;