Crossfire Client, Branches  R11627
png.c
Go to the documentation of this file.
1 const char * const rcsid_gtk2_png_c =
2  "$Id: png.c 9193 2008-06-01 14:26:32Z anmaster $";
3 /*
4  Crossfire client, a client program for the crossfire program.
5 
6  Copyright (C) 2005 Mark Wedel & Crossfire Development Team
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 
22  The author can be reached via e-mail to crossfire@metalforge.org
23 */
24 
30 #include <config.h>
31 #include <stdlib.h>
32 #include <sys/stat.h>
33 #ifndef WIN32
34 #include <unistd.h>
35 #endif
36 #include <png.h>
37 #include <client-types.h>
38 #include <client.h>
39 
40 /* Pick up the gtk headers we need */
41 #include <gtk/gtk.h>
42 #ifndef WIN32
43 #include <gdk/gdkx.h>
44 #else
45 #include <gdk/gdkwin32.h>
46 #endif
47 #include <gdk/gdkkeysyms.h>
48 
49 
50 /* Defines for PNG return values */
51 /* These should be in a header file, but currently our calling functions
52  * routines just check for nonzero return status and don't really care
53  * why the load failed.
54  */
55 #define PNGX_NOFILE 1
56 #define PNGX_OUTOFMEM 2
57 #define PNGX_DATA 3
58 
59 static uint8 *data_cp;
60 static int data_len, data_start;
61 
68 static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) {
69  memcpy(data, data_cp + data_start, length);
70  data_start += length;
71 }
72 
81 {
82  uint8 *pixels=NULL;
83  static png_bytepp rows=NULL;
84  static int rows_byte=0;
85 
86  png_structp png_ptr;
87  png_infop info_ptr;
88  int bit_depth, color_type, interlace_type, compression_type, y;
89 
90  data_len=len;
91  data_cp = data;
92  data_start=0;
93 
94  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
95  NULL, NULL, NULL);
96 
97  if (!png_ptr) {
98  return NULL;
99  }
100  info_ptr = png_create_info_struct (png_ptr);
101 
102  if (!info_ptr) {
103  png_destroy_read_struct (&png_ptr, NULL, NULL);
104  return NULL;
105  }
106 
107 
108  if (setjmp (png_jmpbuf(png_ptr))) {
109  png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
110  return NULL;
111  }
112 
113 
114  png_set_read_fn(png_ptr, NULL, user_read_data);
115  png_read_info (png_ptr, info_ptr);
116 
117  /*
118  * This seems to bug on at least one system (other than mine)
119  * http://www.metalforge.net/cfmb/viewtopic.php?t=1085
120  *
121  * I think its actually a bug in libpng. This function dies with an
122  * error based on image width. However I've produced a work around
123  * using the indivial functions. Repeated below.
124  *
125  png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)width, (png_unit_32*)height, &bit_depth,
126  &color_type, &interlace_type, &compression_type, &filter_type);
127  */
128  *width = png_get_image_width(png_ptr, info_ptr);
129  *height = png_get_image_height(png_ptr, info_ptr);
130  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
131  color_type = png_get_color_type(png_ptr, info_ptr);
132  interlace_type = png_get_interlace_type(png_ptr, info_ptr);
133  compression_type = png_get_compression_type(png_ptr, info_ptr);
134 
135  if (color_type == PNG_COLOR_TYPE_PALETTE &&
136  bit_depth <= 8) {
137 
138  /* Convert indexed images to RGB */
139  png_set_expand (png_ptr);
140 
141  } else if (color_type == PNG_COLOR_TYPE_GRAY &&
142  bit_depth < 8) {
143 
144  /* Convert grayscale to RGB */
145  png_set_expand (png_ptr);
146 
147  } else if (png_get_valid (png_ptr,
148  info_ptr, PNG_INFO_tRNS)) {
149 
150  /* If we have transparency header, convert it to alpha
151  channel */
152  png_set_expand(png_ptr);
153 
154  } else if (bit_depth < 8) {
155 
156  /* If we have < 8 scale it up to 8 */
157  png_set_expand(png_ptr);
158 
159 
160  /* Conceivably, png_set_packing() is a better idea;
161  * God only knows how libpng works
162  */
163  }
164  /* If we are 16-bit, convert to 8-bit */
165  if (bit_depth == 16) {
166  png_set_strip_16(png_ptr);
167  }
168 
169  /* If gray scale, convert to RGB */
170  if (color_type == PNG_COLOR_TYPE_GRAY ||
171  color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
172  png_set_gray_to_rgb(png_ptr);
173  }
174 
175  /* If interlaced, handle that */
176  if (interlace_type != PNG_INTERLACE_NONE) {
177  png_set_interlace_handling(png_ptr);
178  }
179 
180  /* pad it to 4 bytes to make processing easier */
181  if (!(color_type & PNG_COLOR_MASK_ALPHA))
182  png_set_filler(png_ptr, 255, PNG_FILLER_AFTER);
183 
184  /* Update the info the reflect our transformations */
185  png_read_update_info(png_ptr, info_ptr);
186  /* re-read due to transformations just made */
187  /*
188  * See above for error description
189  png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)width, (png_uint_32*)height, &bit_depth,
190  &color_type, &interlace_type, &compression_type, &filter_type);
191  */
192  *width = png_get_image_width(png_ptr, info_ptr);
193  *height = png_get_image_height(png_ptr, info_ptr);
194  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
195  color_type = png_get_color_type(png_ptr, info_ptr);
196  interlace_type = png_get_interlace_type(png_ptr, info_ptr);
197  compression_type = png_get_compression_type(png_ptr, info_ptr);
198 
199 
200  pixels = (uint8*)malloc(*width * *height * 4);
201 
202  if (!pixels) {
203  png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
204  LOG(LOG_CRITICAL,"gtk::png_to_data","Out of memory - exiting");
205  exit(1);
206  }
207 
208  /* the png library needs the rows, but we will just return the raw data */
209  if (rows_byte == 0) {
210  rows =(png_bytepp) malloc(sizeof(char*) * *height);
211  rows_byte=*height;
212  } else if (*height > rows_byte) {
213  rows =(png_bytepp) realloc(rows, sizeof(char*) * *height);
214  rows_byte=*height;
215  }
216  if (!rows) {
217  png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
218  return NULL;
219  }
220 
221  for (y=0; y<*height; y++)
222  rows[y] = pixels + y * *width * 4;
223 
224  png_read_image(png_ptr, rows);
225  png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
226 
227  return pixels;
228 }
229 
230 /* RATIO is used to know what units scale is - in this case, a percentage, so
231  * it is set to 100
232  */
233 #define RATIO 100
234 
235 #define MAX_IMAGE_WIDTH 1024
236 #define MAX_IMAGE_HEIGHT 1024
237 #define BPP 4
238 
267 uint8 *rescale_rgba_data(uint8 *data, int *width, int *height, int scale)
268 {
269  static int xrow[BPP * MAX_IMAGE_WIDTH], yrow[BPP*MAX_IMAGE_HEIGHT];
270  static uint8 *nrows[MAX_IMAGE_HEIGHT];
271 
272  /* Figure out new height/width */
273  int new_width = *width * scale / RATIO, new_height = *height * scale / RATIO;
274 
275  int sourcerow=0, ytoleft, ytofill, xtoleft, xtofill, dest_column=0, source_column=0, needcol,
276  destrow=0;
277  int x,y;
278  uint8 *ndata;
279  uint8 r,g,b,a;
280 
281  if (*width > MAX_IMAGE_WIDTH || new_width > MAX_IMAGE_WIDTH
282  || *height > MAX_IMAGE_HEIGHT || new_height > MAX_IMAGE_HEIGHT)
283  {
284  LOG(LOG_CRITICAL,"gtk::rescale_rgba_data","Image too big");
285  exit(0);
286  }
287 
288  /* clear old values these may have */
289  memset(yrow, 0, sizeof(int) * *height * BPP);
290 
291  ndata = (uint8*)malloc(new_width * new_height * BPP);
292 
293  for (y=0; y<new_height; y++)
294  nrows[y] = (png_bytep) (ndata + y * new_width * BPP);
295 
296  ytoleft = scale;
297  ytofill = RATIO;
298 
299  for (y=0,sourcerow=0; y < new_height; y++) {
300  memset(xrow, 0, sizeof(int) * *width * BPP);
301  while (ytoleft < ytofill) {
302  for (x=0; x< *width; ++x) {
303  /* Only want to copy the data if this is not a transperent pixel.
304  * If it is transparent, the color information is has is probably
305  * bogus, and blending that makes the results look worse.
306  */
307  if (data[(sourcerow * *width + x)*BPP+3] > 0 ) {
308  yrow[x*BPP] += ytoleft * data[(sourcerow * *width + x)*BPP]/RATIO;
309  yrow[x*BPP+1] += ytoleft * data[(sourcerow * *width + x)*BPP+1]/RATIO;
310  yrow[x*BPP+2] += ytoleft * data[(sourcerow * *width + x)*BPP+2]/RATIO;
311  }
312  /* Alpha is a bit special - we don't want to blend it -
313  * we want to take whatever is the more opaque value.
314  */
315  if (data[(sourcerow * *width + x)*BPP+3] > yrow[x*BPP+3])
316  yrow[x*BPP+3] = data[(sourcerow * *width + x)*BPP+3];
317  }
318  ytofill -= ytoleft;
319  ytoleft = scale;
320  if (sourcerow < *height)
321  sourcerow++;
322  }
323 
324  for (x=0; x < *width; ++x) {
325  if (data[(sourcerow * *width + x)*BPP+3] > 0 ) {
326  xrow[x*BPP] = yrow[x*BPP] + ytofill * data[(sourcerow * *width + x)*BPP] / RATIO;
327  xrow[x*BPP+1] = yrow[x*BPP+1] + ytofill * data[(sourcerow * *width + x)*BPP+1] / RATIO;
328  xrow[x*BPP+2] = yrow[x*BPP+2] + ytofill * data[(sourcerow * *width + x)*BPP+2] / RATIO;
329  }
330  if (data[(sourcerow * *width + x)*BPP+3] > xrow[x*BPP+3])
331  xrow[x*BPP+3] = data[(sourcerow * *width + x)*BPP+3];
332  yrow[x*BPP]=0; yrow[x*BPP+1]=0; yrow[x*BPP+2]=0; yrow[x*BPP+3]=0;
333  }
334 
335  ytoleft -= ytofill;
336  if (ytoleft <= 0) {
337  ytoleft = scale;
338  if (sourcerow < *height)
339  sourcerow++;
340  }
341 
342  ytofill = RATIO;
343  xtofill = RATIO;
344  dest_column = 0;
345  source_column=0;
346  needcol=0;
347  r=0; g=0; b=0; a=0;
348 
349  for (x=0; x< *width; x++) {
350  xtoleft = scale;
351 
352  while (xtoleft >= xtofill) {
353  if (needcol) {
354  dest_column++;
355  r=0; g=0; b=0; a=0;
356  }
357 
358  if (xrow[source_column*BPP+3] > 0) {
359  r += xtofill * xrow[source_column*BPP] / RATIO;
360  g += xtofill * xrow[1+source_column*BPP] / RATIO;
361  b += xtofill * xrow[2+source_column*BPP] / RATIO;
362  }
363  if (xrow[3+source_column*BPP] > a)
364  a = xrow[3+source_column*BPP];
365 
366  nrows[destrow][dest_column * BPP] = r;
367  nrows[destrow][1+dest_column * BPP] = g;
368  nrows[destrow][2+dest_column * BPP] = b;
369  nrows[destrow][3+dest_column * BPP] = a;
370  xtoleft -= xtofill;
371  xtofill = RATIO;
372  needcol=1;
373  }
374 
375  if (xtoleft > 0 ){
376  if (needcol) {
377  dest_column++;
378  r=0; g=0; b=0; a=0;
379  needcol=0;
380  }
381 
382  if (xrow[3+source_column*BPP] > 0) {
383  r += xtoleft * xrow[source_column*BPP] / RATIO;
384  g += xtoleft * xrow[1+source_column*BPP] / RATIO;
385  b += xtoleft * xrow[2+source_column*BPP] / RATIO;
386  }
387  if (xrow[3+source_column*BPP] > a)
388  a = xrow[3+source_column*BPP];
389 
390  xtofill -= xtoleft;
391  }
392  source_column++;
393  }
394 
395  if (xtofill > 0 ) {
396  source_column--;
397  if (xrow[3+source_column*BPP] > 0) {
398  r += xtofill * xrow[source_column*BPP] / RATIO;
399  g += xtofill * xrow[1+source_column*BPP] / RATIO;
400  b += xtofill * xrow[2+source_column*BPP] / RATIO;
401  }
402  if (xrow[3+source_column*BPP] > a)
403  a = xrow[3+source_column*BPP];
404  }
405 
406  /* Not positve, but without the bound checking for dest_column,
407  * we were overrunning the buffer. My guess is this only really
408  * showed up if when the images are being scaled - there is probably
409  * something like half a pixel left over.
410  */
411  if (!needcol && (dest_column < new_width)) {
412  nrows[destrow][dest_column * BPP] = r;
413  nrows[destrow][1+dest_column * BPP] = g;
414  nrows[destrow][2+dest_column * BPP] = b;
415  nrows[destrow][3+dest_column * BPP] = a;
416  }
417  destrow++;
418  }
419  *width = new_width;
420  *height = new_height;
421  return ndata;
422 }
423 
424 
425 guchar rgb[512*512*3];
441 int rgba_to_gdkpixmap(GdkWindow *window, uint8 *data,int width, int height,
442  GdkPixmap **pix, GdkBitmap **mask, GdkColormap *colormap)
443 {
444  GdkGC *gc, *gc_alpha;
445  int has_alpha=0, alpha;
446  GdkColor scolor;
447  int x,y;
448 
449  *pix = gdk_pixmap_new(window, width, height, -1);
450 
451  gc=gdk_gc_new(*pix);
452  gdk_gc_set_function(gc, GDK_COPY);
453 
454  *mask=gdk_pixmap_new(window, width, height,1);
455  gc_alpha=gdk_gc_new(*mask);
456 
457  scolor.pixel=1;
458  gdk_gc_set_foreground(gc_alpha, &scolor);
459  gdk_draw_rectangle(*mask, gc_alpha, 1, 0, 0, width, height);
460 
461  scolor.pixel=0;
462  gdk_gc_set_foreground(gc_alpha, &scolor);
463 
464  /* we need to draw the alpha channel. The image may not in fact
465  * have alpha, but no way to know at this point other than to try
466  * and draw it.
467  */
468  for (y=0; y<height; y++) {
469  for (x=0; x<width; x++) {
470  alpha = data[(y * width + x) * 4 +3];
471  /* Transparent bit */
472  if (alpha==0) {
473  gdk_draw_point(*mask, gc_alpha, x, y);
474  has_alpha=1;
475  }
476  }
477  }
478 
479  gdk_draw_rgb_32_image(*pix, gc, 0, 0, width, height, GDK_RGB_DITHER_NONE, data, width*4);
480  if (!has_alpha) {
481  gdk_pixmap_unref(*mask);
482  *mask = NULL;
483  }
484 
485  gdk_gc_destroy(gc_alpha);
486  gdk_gc_destroy(gc);
487  return 0;
488 }
489 
500 int rgba_to_gdkpixbuf(uint8 *data,int width, int height,GdkPixbuf **pix)
501 {
502  int rowstride;
503  guchar *pixels, *p;
504  int x,y;
505 
506 #if 0
507  /* I'm not sure why this doesn't work, since it seems
508  * the data should be in the right format, but it doesn't.
509  */
510  *pix = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB,
511  TRUE, 8, width, height, width * 4, NULL, NULL);
512  return 0;
513 
514 #else
515  *pix = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
516 
517  rowstride = gdk_pixbuf_get_rowstride(*pix);
518  pixels = gdk_pixbuf_get_pixels(*pix);
519 
520  for (y=0; y<height; y++) {
521  for (x=0; x<width; x++) {
522  p = pixels + y * rowstride + x * 4;
523  p[0] = data[4*(x + y * width)];
524  p[1] = data[4*(x + y * width) + 1 ];
525  p[2] = data[4*(x + y * width) + 2 ];
526  p[3] = data[4*(x + y * width) + 3 ];
527 
528  }
529  }
530 
531  return 0;
532 #endif
533 }
534 
544 int png_to_gdkpixmap(GdkWindow *window, uint8 *data, int len,
545  GdkPixmap **pix, GdkBitmap **mask, GdkColormap *colormap)
546 {
547  static uint8 *pixels=NULL;
548  static int pixels_byte=0, rows_byte=0;
549  static png_bytepp rows=NULL;
550  unsigned long width, height;
551  png_structp png_ptr;
552  png_infop info_ptr;
553  int bit_depth, color_type, interlace_type, compression_type, filter_type,
554  bpp, x,y,has_alpha,i,alpha;
555  GdkColor scolor;
556  GdkGC *gc, *gc_alpha;
557 
558  data_len=len;
559  data_cp = data;
560  data_start=0;
561 
562  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
563  NULL, NULL, NULL);
564 
565  if (!png_ptr) {
566  return PNGX_OUTOFMEM;
567  }
568  info_ptr = png_create_info_struct (png_ptr);
569 
570  if (!info_ptr) {
571  png_destroy_read_struct (&png_ptr, NULL, NULL);
572  return PNGX_OUTOFMEM;
573  }
574  if (setjmp (png_ptr->jmpbuf)) {
575  png_destroy_read_struct (&png_ptr, &info_ptr,NULL);
576  return PNGX_DATA;
577  }
578  has_alpha=0;
579  png_set_read_fn(png_ptr, NULL, user_read_data);
580  png_read_info (png_ptr, info_ptr);
581 
582  png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
583  &color_type, &interlace_type, &compression_type, &filter_type);
584 
585  if (color_type == PNG_COLOR_TYPE_PALETTE &&
586  bit_depth <= 8) {
587 
588  /* Convert indexed images to RGB */
589  png_set_expand (png_ptr);
590 
591  } else if (color_type == PNG_COLOR_TYPE_GRAY &&
592  bit_depth < 8) {
593 
594  /* Convert grayscale to RGB */
595  png_set_expand (png_ptr);
596 
597  } else if (png_get_valid (png_ptr,
598  info_ptr, PNG_INFO_tRNS)) {
599 
600  /* If we have transparency header, convert it to alpha
601  channel */
602  png_set_expand(png_ptr);
603 
604  } else if (bit_depth < 8) {
605 
606  /* If we have < 8 scale it up to 8 */
607  png_set_expand(png_ptr);
608 
609 
610  /* Conceivably, png_set_packing() is a better idea;
611  * God only knows how libpng works
612  */
613  }
614  /* If we are 16-bit, convert to 8-bit */
615  if (bit_depth == 16) {
616  png_set_strip_16(png_ptr);
617  }
618 
619  /* If gray scale, convert to RGB */
620  if (color_type == PNG_COLOR_TYPE_GRAY ||
621  color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
622  png_set_gray_to_rgb(png_ptr);
623  }
624 
625  /* If interlaced, handle that */
626  if (interlace_type != PNG_INTERLACE_NONE) {
627  png_set_interlace_handling(png_ptr);
628  }
629 
630  /* Update the info the reflect our transformations */
631  png_read_update_info(png_ptr, info_ptr);
632  /* re-read due to transformations just made */
633  png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
634  &color_type, &interlace_type, &compression_type, &filter_type);
635  if (color_type & PNG_COLOR_MASK_ALPHA)
636  bpp = 4;
637  else
638  bpp = 3;
639 
640  /* Allocate the memory we need once, and increase it if necessary.
641  * This is more efficient the allocating this block of memory every time.
642  */
643  if (pixels_byte==0) {
644  pixels_byte = width * height * bpp;
645  pixels = (uint8*)malloc(pixels_byte);
646  } else if ((width * height * bpp) > pixels_byte) {
647  pixels_byte =width * height * bpp;
648  /* Doing a free/malloc is probably more efficient -
649  * we don't care about the old data in this
650  * buffer.
651  */
652  free(pixels);
653  pixels= (uint8*)malloc(pixels_byte);
654  }
655 
656  if (!pixels) {
657  png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
658  pixels_byte=0;
659  return PNGX_OUTOFMEM;
660  }
661  if (rows_byte == 0) {
662  rows =(png_bytepp) malloc(sizeof(char*) * height);
663  rows_byte=height;
664  } else if (height > rows_byte) {
665  rows =(png_bytepp) realloc(rows, sizeof(char*) * height);
666  rows_byte=height;
667  }
668  if (!rows) {
669  png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
670  pixels_byte=0;
671  return PNGX_OUTOFMEM;
672  }
673 
674  for (y=0; y<height; y++)
675  rows[y] = pixels + y * width * bpp;
676 
677  png_read_image(png_ptr, rows);
678 #if 0
679  fprintf(stderr,"image is %d X %d, bpp=%d, color_type=%d\n",
680  width, height, bpp, color_type);
681 #endif
682 
683  *pix = gdk_pixmap_new(window, width, height, -1);
684 
685 
686  gc=gdk_gc_new(*pix);
687  gdk_gc_set_function(gc, GDK_COPY);
688 
689  if (color_type & PNG_COLOR_MASK_ALPHA) {
690  *mask=gdk_pixmap_new(window, width, height,1);
691  gc_alpha=gdk_gc_new(*mask);
692  gdk_gc_set_function(gc_alpha, GDK_COPY);
693 
694  scolor.pixel=1;
695  gdk_gc_set_foreground(gc_alpha, &scolor);
696  gdk_draw_rectangle(*mask, gc_alpha, 1, 0, 0, width, height);
697 
698  scolor.pixel=0;
699  gdk_gc_set_foreground(gc_alpha, &scolor);
700  has_alpha=1;
701  }
702  else {
703  *mask = NULL;
704  gc_alpha = NULL; /* Prevent compile warnings */
705  }
706  i=0;
707  for (y=0; y<height; y++) {
708  for (x=0; x<width; x++) {
709  rgb[i++]=rows[y][x*bpp]; /* red */
710  rgb[i++]=rows[y][x*bpp+1]; /* green */
711  rgb[i++]=rows[y][x*bpp+2]; /* blue */
712  if (has_alpha) {
713  alpha = rows[y][x*bpp+3];
714  /* Transparent bit */
715  if (alpha==0) {
716  gdk_draw_point(*mask, gc_alpha, x, y);
717  }
718  }
719  }
720  }
721  gdk_draw_rgb_image(*pix, gc, 0, 0, 32, 32, GDK_RGB_DITHER_NONE, rgb, 32*3);
722  png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
723  if (has_alpha)
724  gdk_gc_destroy(gc_alpha);
725  gdk_gc_destroy(gc);
726  return 0;
727 }
int rgba_to_gdkpixmap(GdkWindow *window, uint8 *data, int width, int height, GdkPixmap **pix, GdkBitmap **mask, GdkColormap *colormap)
Definition: png.c:407
static int height
Definition: mapdata.c:104
#define MAX_IMAGE_HEIGHT
Definition: png.c:236
uint8 * png_to_data(uint8 *data, int len, uint32 *width, uint32 *height)
Definition: png.c:63
guchar rgb[512 *512 *3]
Definition: png.c:425
int rgba_to_gdkpixbuf(uint8 *data, int width, int height, GdkPixbuf **pix)
Definition: png.c:500
static int data_len
Definition: png.c:60
static int width
Definition: mapdata.c:104
void LOG(LogLevel level, const char *origin, const char *format,...)
Definition: misc.c:178
#define TRUE
Definition: client-types.h:71
#define PNGX_DATA
Definition: png.c:57
Pixmap mask
Definition: xutil.c:67
static int data_start
Definition: png.c:60
static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
Definition: png.c:68
#define MAX_IMAGE_WIDTH
Definition: png.c:235
uint8 * rescale_rgba_data(uint8 *data, int *width, int *height, int scale)
Definition: png.c:244
static uint8 * data_cp
Definition: png.c:59
unsigned int uint32
Definition: client-types.h:77
const char *const rcsid_gtk2_png_c
Definition: png.c:1
int png_to_gdkpixmap(GdkWindow *window, uint8 *data, int len, GdkPixmap **pix, GdkBitmap **mask, GdkColormap *colormap)
Definition: png.c:544
unsigned char uint8
Definition: client-types.h:81
Colormap colormap
Definition: x11.c:190
#define BPP
Definition: png.c:237
#define RATIO
Definition: png.c:233
#define PNGX_OUTOFMEM
Definition: png.c:56