2 "$Id: png.c 9193 2008-06-01 14:26:32Z anmaster $";
45 #include <gdk/gdkwin32.h>
47 #include <gdk/gdkkeysyms.h>
56 #define PNGX_OUTOFMEM 2
68 static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) {
83 static png_bytepp rows=NULL;
84 static int rows_byte=0;
88 int bit_depth, color_type, interlace_type, compression_type, y;
94 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
100 info_ptr = png_create_info_struct (png_ptr);
103 png_destroy_read_struct (&png_ptr, NULL, NULL);
108 if (setjmp (png_jmpbuf(png_ptr))) {
109 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
115 png_read_info (png_ptr, info_ptr);
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);
135 if (color_type == PNG_COLOR_TYPE_PALETTE &&
139 png_set_expand (png_ptr);
141 }
else if (color_type == PNG_COLOR_TYPE_GRAY &&
145 png_set_expand (png_ptr);
147 }
else if (png_get_valid (png_ptr,
148 info_ptr, PNG_INFO_tRNS)) {
152 png_set_expand(png_ptr);
154 }
else if (bit_depth < 8) {
157 png_set_expand(png_ptr);
165 if (bit_depth == 16) {
166 png_set_strip_16(png_ptr);
170 if (color_type == PNG_COLOR_TYPE_GRAY ||
171 color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
172 png_set_gray_to_rgb(png_ptr);
176 if (interlace_type != PNG_INTERLACE_NONE) {
177 png_set_interlace_handling(png_ptr);
181 if (!(color_type & PNG_COLOR_MASK_ALPHA))
182 png_set_filler(png_ptr, 255, PNG_FILLER_AFTER);
185 png_read_update_info(png_ptr, info_ptr);
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);
200 pixels = (
uint8*)malloc(*width * *height * 4);
203 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
209 if (rows_byte == 0) {
210 rows =(png_bytepp) malloc(
sizeof(
char*) * *
height);
212 }
else if (*height > rows_byte) {
213 rows =(png_bytepp) realloc(rows,
sizeof(
char*) * *
height);
217 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
222 rows[y] = pixels + y * *width * 4;
224 png_read_image(png_ptr, rows);
225 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
235 #define MAX_IMAGE_WIDTH 1024
236 #define MAX_IMAGE_HEIGHT 1024
273 int new_width = *width * scale /
RATIO, new_height = *height * scale /
RATIO;
275 int sourcerow=0, ytoleft, ytofill, xtoleft, xtofill, dest_column=0, source_column=0, needcol,
289 memset(yrow, 0,
sizeof(
int) * *height *
BPP);
291 ndata = (
uint8*)malloc(new_width * new_height * BPP);
293 for (y=0; y<new_height; y++)
294 nrows[y] = (png_bytep) (ndata + y * new_width *
BPP);
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) {
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;
315 if (data[(sourcerow * *width + x)*BPP+3] > yrow[x*BPP+3])
316 yrow[x*BPP+3] = data[(sourcerow * *width + x)*BPP+3];
320 if (sourcerow < *height)
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;
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;
338 if (sourcerow < *height)
349 for (x=0; x< *
width; x++) {
352 while (xtoleft >= xtofill) {
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;
363 if (xrow[3+source_column*BPP] > a)
364 a = xrow[3+source_column*
BPP];
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;
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;
387 if (xrow[3+source_column*BPP] > a)
388 a = xrow[3+source_column*
BPP];
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;
402 if (xrow[3+source_column*BPP] > a)
403 a = xrow[3+source_column*
BPP];
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;
420 *height = new_height;
442 GdkPixmap **pix, GdkBitmap **
mask, GdkColormap *
colormap)
444 GdkGC *gc, *gc_alpha;
445 int has_alpha=0, alpha;
449 *pix = gdk_pixmap_new(window, width, height, -1);
452 gdk_gc_set_function(gc, GDK_COPY);
454 *mask=gdk_pixmap_new(window, width, height,1);
455 gc_alpha=gdk_gc_new(*mask);
458 gdk_gc_set_foreground(gc_alpha, &scolor);
459 gdk_draw_rectangle(*mask, gc_alpha, 1, 0, 0, width, height);
462 gdk_gc_set_foreground(gc_alpha, &scolor);
468 for (y=0; y<
height; y++) {
469 for (x=0; x<
width; x++) {
470 alpha = data[(y * width + x) * 4 +3];
473 gdk_draw_point(*mask, gc_alpha, x, y);
479 gdk_draw_rgb_32_image(*pix, gc, 0, 0, width, height, GDK_RGB_DITHER_NONE, data, width*4);
481 gdk_pixmap_unref(*mask);
485 gdk_gc_destroy(gc_alpha);
510 *pix = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB,
511 TRUE, 8, width, height, width * 4, NULL, NULL);
515 *pix = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
TRUE, 8, width, height);
517 rowstride = gdk_pixbuf_get_rowstride(*pix);
518 pixels = gdk_pixbuf_get_pixels(*pix);
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 ];
545 GdkPixmap **pix, GdkBitmap **
mask, GdkColormap *
colormap)
547 static uint8 *pixels=NULL;
548 static int pixels_byte=0, rows_byte=0;
549 static png_bytepp rows=NULL;
553 int bit_depth, color_type, interlace_type, compression_type, filter_type,
554 bpp, x,y,has_alpha,i,alpha;
556 GdkGC *gc, *gc_alpha;
562 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
568 info_ptr = png_create_info_struct (png_ptr);
571 png_destroy_read_struct (&png_ptr, NULL, NULL);
574 if (setjmp (png_ptr->jmpbuf)) {
575 png_destroy_read_struct (&png_ptr, &info_ptr,NULL);
580 png_read_info (png_ptr, info_ptr);
582 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
583 &color_type, &interlace_type, &compression_type, &filter_type);
585 if (color_type == PNG_COLOR_TYPE_PALETTE &&
589 png_set_expand (png_ptr);
591 }
else if (color_type == PNG_COLOR_TYPE_GRAY &&
595 png_set_expand (png_ptr);
597 }
else if (png_get_valid (png_ptr,
598 info_ptr, PNG_INFO_tRNS)) {
602 png_set_expand(png_ptr);
604 }
else if (bit_depth < 8) {
607 png_set_expand(png_ptr);
615 if (bit_depth == 16) {
616 png_set_strip_16(png_ptr);
620 if (color_type == PNG_COLOR_TYPE_GRAY ||
621 color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
622 png_set_gray_to_rgb(png_ptr);
626 if (interlace_type != PNG_INTERLACE_NONE) {
627 png_set_interlace_handling(png_ptr);
631 png_read_update_info(png_ptr, info_ptr);
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)
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;
653 pixels= (
uint8*)malloc(pixels_byte);
657 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
661 if (rows_byte == 0) {
662 rows =(png_bytepp) malloc(
sizeof(
char*) *
height);
664 }
else if (height > rows_byte) {
665 rows =(png_bytepp) realloc(rows,
sizeof(
char*) *
height);
669 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
675 rows[y] = pixels + y * width * bpp;
677 png_read_image(png_ptr, rows);
679 fprintf(stderr,
"image is %d X %d, bpp=%d, color_type=%d\n",
680 width, height, bpp, color_type);
683 *pix = gdk_pixmap_new(window, width, height, -1);
687 gdk_gc_set_function(gc, GDK_COPY);
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);
695 gdk_gc_set_foreground(gc_alpha, &scolor);
696 gdk_draw_rectangle(*mask, gc_alpha, 1, 0, 0, width, height);
699 gdk_gc_set_foreground(gc_alpha, &scolor);
707 for (y=0; y<
height; y++) {
708 for (x=0; x<
width; x++) {
709 rgb[i++]=rows[y][x*bpp];
710 rgb[i++]=rows[y][x*bpp+1];
711 rgb[i++]=rows[y][x*bpp+2];
713 alpha = rows[y][x*bpp+3];
716 gdk_draw_point(*mask, gc_alpha, x, y);
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);
724 gdk_gc_destroy(gc_alpha);
int rgba_to_gdkpixmap(GdkWindow *window, uint8 *data, int width, int height, GdkPixmap **pix, GdkBitmap **mask, GdkColormap *colormap)
uint8 * png_to_data(uint8 *data, int len, uint32 *width, uint32 *height)
int rgba_to_gdkpixbuf(uint8 *data, int width, int height, GdkPixbuf **pix)
void LOG(LogLevel level, const char *origin, const char *format,...)
static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
uint8 * rescale_rgba_data(uint8 *data, int *width, int *height, int scale)
const char *const rcsid_gtk2_png_c
int png_to_gdkpixmap(GdkWindow *window, uint8 *data, int len, GdkPixmap **pix, GdkBitmap **mask, GdkColormap *colormap)