Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2002:
[Freeciv-Dev] (PR#2340) more PNG for XAW
Home

[Freeciv-Dev] (PR#2340) more PNG for XAW

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#2340) more PNG for XAW
From: "Jason Short via RT" <rt@xxxxxxxxxxxxxx>
Date: Tue, 19 Nov 2002 19:38:07 -0800
Reply-to: rt@xxxxxxxxxxxxxx


> From: Vasco Alexandre Da Silva Costa <vasc@xxxxxxxxxxxxxx>
> 
> I cleaned up the Xaw PNG loading code a bit.
> I removed some useless libpng library calls.
> I also fixed some colour allocation issues.

I'm committing this with one small change - ptransarray is only freed if
has_mask is set.

Patch attached.

jason

? client/gui-xaw/diff
Index: client/gui-xaw/graphics.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/graphics.c,v
retrieving revision 1.44
diff -u -r1.44 graphics.c
--- client/gui-xaw/graphics.c   2002/11/14 09:15:00     1.44
+++ client/gui-xaw/graphics.c   2002/11/20 03:37:30
@@ -307,22 +307,6 @@
 }
 
 /***************************************************************************
-  Return true iff the given pixel is transparent.  The 'trans' and
-  'ntrans' parameters provide an array of transparent colors.
-***************************************************************************/
-static bool is_transparent(png_byte index, png_bytep trans, int ntrans)
-{
-  int i;
-
-  for (i = 0; i < ntrans; i++) {
-    if (index == trans[i]) {
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-
-/***************************************************************************
   Converts an image to a pixmap...
 ***************************************************************************/
 static Pixmap image2pixmap(XImage *xi)
@@ -331,8 +315,7 @@
   XGCValues values;
   GC gc;
   
-  ret = XCreatePixmap(display, root_window,
-                     xi->width, xi->height, xi->depth);
+  ret = XCreatePixmap(display, root_window, xi->width, xi->height, xi->depth);
 
   values.foreground = 1;
   values.background = 0;
@@ -350,15 +333,15 @@
 {
   png_structp pngp;
   png_infop infop;
-  png_uint_32 sig_read = 0;
-  png_int_32 width, height, row, col;
-  int bit_depth, color_type, interlace_type;
+  png_int_32 width, height, x, y;
   FILE *fp;
   int npalette, ntrans;
   png_colorp palette;
   png_bytep trans;
+  png_bytep buf, pb;
+  png_uint_32 stride;
   unsigned long *pcolorarray;
-  png_bytep *row_pointers;
+  bool *ptransarray = NULL;
   struct Sprite *mysprite;
   XImage *xi;
   int has_mask;
@@ -387,19 +370,18 @@
   }
 
   png_init_io(pngp, fp);
-  png_set_sig_bytes(pngp, sig_read);
 
-  png_read_info(pngp, infop);
-  png_get_IHDR(pngp, infop, &width, &height, &bit_depth, &color_type,
-              &interlace_type, NULL, NULL);
-
   png_set_strip_16(pngp);
   png_set_packing(pngp);
 
+  png_read_info(pngp, infop);
+  width = png_get_image_width(pngp, infop);
+  height = png_get_image_height(pngp, infop);
+
   if (png_get_PLTE(pngp, infop, &palette, &npalette)) {
     int i;
 
-    pcolorarray = fc_malloc(npalette * sizeof(unsigned long));
+    pcolorarray = fc_malloc(npalette * sizeof(*pcolorarray));
 
     for (i = 0; i < npalette; i++) {
       XColor mycolor;
@@ -422,6 +404,9 @@
        for (j = 0; j < ncols; j++) {
          cols[j].pixel = j;
        }
+
+       XGrabServer(display);
+
        XQueryColors(display, cmap, cols, ncols);
 
        for (; i < npalette; i++) {
@@ -441,8 +426,12 @@
              pixel = j;
            }
          }
+
+         XAllocColor(display, cmap, &cols[pixel]);
          pcolorarray[i] = pixel;
        }
+
+       XUngrabServer(display);
        free(cols);
        break;
       }
@@ -452,31 +441,53 @@
     exit(EXIT_FAILURE);
   }
 
-  png_read_update_info(pngp, infop);
   has_mask = png_get_tRNS(pngp, infop, &trans, &ntrans, NULL);
 
-  row_pointers = fc_malloc(sizeof(png_bytep) * height);
+  if (has_mask) {
+    int i;
+
+    ptransarray = fc_calloc(npalette, sizeof(*ptransarray));
 
-  for (row = 0; row < height; row++) {
-    row_pointers[row] = fc_malloc(png_get_rowbytes(pngp, infop));
+    for (i = 0; i < ntrans; i++) {
+      ptransarray[trans[i]] = TRUE;
+    }
   }
 
-  png_read_image(pngp, row_pointers);
-  png_read_end(pngp, infop);
-  fclose(fp);
+  png_read_update_info(pngp, infop);
 
-  mysprite=fc_malloc(sizeof(struct Sprite));
-  mysprite->pixmap = 0;
-  mysprite->mask = 0;
-  
+  {
+    png_bytep *row_pointers;
+
+    stride = png_get_rowbytes(pngp, infop);
+    buf = fc_malloc(stride * height);
+
+    row_pointers = fc_malloc(height * sizeof(png_bytep));
+
+    for (y = 0, pb = buf; y < height; y++, pb += stride) {
+      row_pointers[y] = pb;
+    }
+
+    png_read_image(pngp, row_pointers);
+    png_read_end(pngp, infop);
+    fclose(fp);
+
+    free(row_pointers);
+    png_destroy_read_struct(&pngp, &infop, NULL);
+  }
+
+  mysprite = fc_malloc(sizeof(*mysprite));
+
+
   xi = XCreateImage(display, DefaultVisual(display, screen_number),
                    display_depth, ZPixmap, 0, NULL, width, height, 32, 0);
   xi->data = fc_calloc(xi->bytes_per_line * xi->height, 1);
 
-  for (row = 0; row < height; row++) {
-    for (col = 0; col < width; col++) {
-      XPutPixel(xi, col, row, pcolorarray[row_pointers[row][col]]);
+  pb = buf;
+  for (y = 0; y < height; y++) {
+    for (x = 0; x < width; x++) {
+      XPutPixel(xi, x, y, pcolorarray[pb[x]]);
     }
+    pb += stride;
   }
   mysprite->pixmap = image2pixmap(xi);
   XDestroyImage(xi);
@@ -488,11 +499,12 @@
                      1, XYBitmap, 0, NULL, width, height, 8, 0);
     xm->data = fc_calloc(xm->bytes_per_line * xm->height, 1);
 
-    for (row = 0; row < height; row++) {
-      for (col = 0; col < width; col++) {
-       XPutPixel(xm, col, row,
-                 !is_transparent(row_pointers[row][col], trans, ntrans));
+    pb = buf;
+    for (y = 0; y < height; y++) {
+      for (x = 0; x < width; x++) {
+       XPutPixel(xm, x, y, !ptransarray[pb[x]]);
       }
+      pb += stride;
     }
     mysprite->mask = image2pixmap(xm);
     XDestroyImage(xm);
@@ -504,11 +516,10 @@
   mysprite->pcolorarray = pcolorarray;
   mysprite->ncols = npalette;
 
-  for (row = 0; row < height; row++) {
-    free(row_pointers[row]);
+  if (has_mask) {
+    free(ptransarray);
   }
-  free(row_pointers);
-  png_destroy_read_struct(&pngp, &infop, NULL);
+  free(buf);
   return mysprite;
 }
 
@@ -521,9 +532,7 @@
   if (s->has_mask) {
     XFreePixmap(display, s->mask);
   }
-#if 0
-  free_colors(s->pcolorarray, s->ncols);
-#endif
+  XFreeColors(display, cmap, s->pcolorarray, s->ncols, 0);
   free(s->pcolorarray);
   free(s);
 }

[Prev in Thread] Current Thread [Next in Thread]