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]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] (PR#2340) more PNG for XAW
From: "Jason Short via RT" <rt@xxxxxxxxxxxxxx>
Date: Thu, 14 Nov 2002 13:53:06 -0800
Reply-to: rt@xxxxxxxxxxxxxx

-------- Original Message --------
Subject: Re: PNG and backwards compatability
Date: Thu, 14 Nov 2002 21:30:33 +0000 (WET)
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 had to protect the last ditch colour lookup with a XGrabServer, 
XUngrabServer pair. This should make that part a bit slower but it is 
necessary since we cannot allow some other program to mess up the 
palette while we are doing our job.

To compensate for this possible extra slowness I speed up the mask
building, reduced the number of malloc calls, made the raw image 
contents be adjacent to memory.
It even seems to be slightly faster loading now than it used to.

The patch is attached to this email.

---
Vasco Alexandre da Silva Costa @ Instituto Superior Tecnico, Lisboa


--- client/gui-xaw/graphics.c   13 Nov 2002 19:19:43 -0000      1.43
+++ client/gui-xaw/graphics.c   14 Nov 2002 21:23:17 -0000
@@ -306,22 +306,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)
@@ -330,8 +314,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;
@@ -349,15 +332,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;
   struct Sprite *mysprite;
   XImage *xi;
   int has_mask;
@@ -386,19 +369,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;
@@ -421,6 +403,9 @@
        for (j = 0; j < ncols; j++) {
          cols[j].pixel = j;
        }
+
+       XGrabServer(display);
+
        XQueryColors(display, cmap, cols, ncols);
 
        for (; i < npalette; i++) {
@@ -440,8 +425,12 @@
              pixel = j;
            }
          }
+
+         XAllocColor(display, cmap, &cols[pixel]);
          pcolorarray[i] = pixel;
        }
+
+       XUngrabServer(display);
        free(cols);
        break;
       }
@@ -451,31 +440,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);
+
+  {
+    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));
+
 
-  mysprite=fc_malloc(sizeof(struct Sprite));
-  mysprite->pixmap = 0;
-  mysprite->mask = 0;
-  
   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);
@@ -487,11 +498,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);
@@ -503,11 +515,8 @@
   mysprite->pcolorarray = pcolorarray;
   mysprite->ncols = npalette;
 
-  for (row = 0; row < height; row++) {
-    free(row_pointers[row]);
-  }
-  free(row_pointers);
-  png_destroy_read_struct(&pngp, &infop, NULL);
+  free(ptransarray);
+  free(buf);
   return mysprite;
 }
 
@@ -520,9 +529,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]