2 "$Id: png.c 9190 2008-06-01 08:53:05Z anmaster $";
41 #include <gdk/gdkwin32.h>
43 #include <gdk/gdkkeysyms.h>
52 #define PNGX_OUTOFMEM 2
58 static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) {
66 static png_bytepp rows=NULL;
67 static int rows_byte=0;
71 int bit_depth, color_type, interlace_type, compression_type, y;
77 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
83 info_ptr = png_create_info_struct (png_ptr);
86 png_destroy_read_struct (&png_ptr, NULL, NULL);
89 if (setjmp (png_ptr->jmpbuf)) {
90 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
95 png_read_info (png_ptr, info_ptr);
107 *width = png_get_image_width(png_ptr, info_ptr);
108 * height = png_get_image_height(png_ptr, info_ptr);
109 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
110 color_type = png_get_color_type(png_ptr, info_ptr);
111 interlace_type = png_get_interlace_type(png_ptr, info_ptr);
112 compression_type = png_get_compression_type(png_ptr, info_ptr);
113 if (color_type == PNG_COLOR_TYPE_PALETTE &&
117 png_set_expand (png_ptr);
119 }
else if (color_type == PNG_COLOR_TYPE_GRAY &&
123 png_set_expand (png_ptr);
125 }
else if (png_get_valid (png_ptr,
126 info_ptr, PNG_INFO_tRNS)) {
130 png_set_expand(png_ptr);
132 }
else if (bit_depth < 8) {
135 png_set_expand(png_ptr);
143 if (bit_depth == 16) {
144 png_set_strip_16(png_ptr);
148 if (color_type == PNG_COLOR_TYPE_GRAY ||
149 color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
150 png_set_gray_to_rgb(png_ptr);
154 if (interlace_type != PNG_INTERLACE_NONE) {
155 png_set_interlace_handling(png_ptr);
159 if (!(color_type & PNG_COLOR_MASK_ALPHA))
160 png_set_filler(png_ptr, 255, PNG_FILLER_AFTER);
163 png_read_update_info(png_ptr, info_ptr);
170 *width = png_get_image_width(png_ptr, info_ptr);
171 *height = png_get_image_height(png_ptr, info_ptr);
172 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
173 color_type = png_get_color_type(png_ptr, info_ptr);
174 interlace_type = png_get_interlace_type(png_ptr, info_ptr);
175 compression_type = png_get_compression_type(png_ptr, info_ptr);
177 pixels = (
uint8*)malloc(*width * *height * 4);
180 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
186 if (rows_byte == 0) {
187 rows =(png_bytepp) malloc(
sizeof(
char*) * *
height);
189 }
else if (*height > rows_byte) {
190 rows =(png_bytepp) realloc(rows,
sizeof(
char*) * *
height);
194 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
199 rows[y] = pixels + y * *width * 4;
201 png_read_image(png_ptr, rows);
202 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
240 #define MAX_IMAGE_WIDTH 1024
241 #define MAX_IMAGE_HEIGHT 1024
250 int new_width = *width * scale /
RATIO, new_height = *height * scale /
RATIO;
252 int sourcerow=0, ytoleft, ytofill, xtoleft, xtofill, dest_column=0, source_column=0, needcol,
266 memset(yrow, 0,
sizeof(
int) * *height *
BPP);
268 ndata = (
uint8*)malloc(new_width * new_height * BPP);
270 for (y=0; y<new_height; y++)
271 nrows[y] = (png_bytep) (ndata + y * new_width *
BPP);
276 for (y=0,sourcerow=0; y < new_height; y++) {
277 memset(xrow, 0,
sizeof(
int) * *width * BPP);
278 while (ytoleft < ytofill) {
279 for (x=0; x< *
width; ++x) {
284 if (data[(sourcerow * *width + x)*BPP+3] > 0 ) {
285 yrow[x*
BPP] += ytoleft * data[(sourcerow * *width + x)*BPP]/
RATIO;
286 yrow[x*BPP+1] += ytoleft * data[(sourcerow * *width + x)*BPP+1]/
RATIO;
287 yrow[x*BPP+2] += ytoleft * data[(sourcerow * *width + x)*BPP+2]/
RATIO;
292 if (data[(sourcerow * *width + x)*BPP+3] > yrow[x*BPP+3])
293 yrow[x*BPP+3] = data[(sourcerow * *width + x)*BPP+3];
297 if (sourcerow < *height)
301 for (x=0; x < *
width; ++x) {
302 if (data[(sourcerow * *width + x)*BPP+3] > 0 ) {
303 xrow[x*
BPP] = yrow[x*
BPP] + ytofill * data[(sourcerow * *width + x)*BPP] /
RATIO;
304 xrow[x*BPP+1] = yrow[x*BPP+1] + ytofill * data[(sourcerow * *width + x)*BPP+1] /
RATIO;
305 xrow[x*BPP+2] = yrow[x*BPP+2] + ytofill * data[(sourcerow * *width + x)*BPP+2] /
RATIO;
307 if (data[(sourcerow * *width + x)*BPP+3] > xrow[x*BPP+3])
308 xrow[x*BPP+3] = data[(sourcerow * *width + x)*BPP+3];
309 yrow[x*
BPP]=0; yrow[x*BPP+1]=0; yrow[x*BPP+2]=0; yrow[x*BPP+3]=0;
315 if (sourcerow < *height)
326 for (x=0; x< *
width; x++) {
329 while (xtoleft >= xtofill) {
335 if (xrow[source_column*BPP+3] > 0) {
336 r += xtofill * xrow[source_column*
BPP] /
RATIO;
337 g += xtofill * xrow[1+source_column*
BPP] /
RATIO;
338 b += xtofill * xrow[2+source_column*
BPP] /
RATIO;
340 if (xrow[3+source_column*BPP] > a)
341 a = xrow[3+source_column*
BPP];
343 nrows[destrow][dest_column *
BPP] = r;
344 nrows[destrow][1+dest_column *
BPP] = g;
345 nrows[destrow][2+dest_column *
BPP] = b;
346 nrows[destrow][3+dest_column *
BPP] = a;
359 if (xrow[3+source_column*BPP] > 0) {
360 r += xtoleft * xrow[source_column*
BPP] /
RATIO;
361 g += xtoleft * xrow[1+source_column*
BPP] /
RATIO;
362 b += xtoleft * xrow[2+source_column*
BPP] /
RATIO;
364 if (xrow[3+source_column*BPP] > a)
365 a = xrow[3+source_column*
BPP];
374 if (xrow[3+source_column*BPP] > 0) {
375 r += xtofill * xrow[source_column*
BPP] /
RATIO;
376 g += xtofill * xrow[1+source_column*
BPP] /
RATIO;
377 b += xtofill * xrow[2+source_column*
BPP] /
RATIO;
379 if (xrow[3+source_column*BPP] > a)
380 a = xrow[3+source_column*
BPP];
388 if (!needcol && (dest_column < new_width)) {
389 nrows[destrow][dest_column *
BPP] = r;
390 nrows[destrow][1+dest_column *
BPP] = g;
391 nrows[destrow][2+dest_column *
BPP] = b;
392 nrows[destrow][3+dest_column *
BPP] = a;
397 *height = new_height;
408 GdkPixmap **pix, GdkBitmap **
mask, GdkColormap *
colormap)
410 GdkGC *gc, *gc_alpha;
411 int has_alpha=0, alpha;
415 *pix = gdk_pixmap_new(window, width, height, -1);
418 gdk_gc_set_function(gc, GDK_COPY);
420 *mask=gdk_pixmap_new(window, width, height,1);
421 gc_alpha=gdk_gc_new(*mask);
424 gdk_gc_set_foreground(gc_alpha, &scolor);
425 gdk_draw_rectangle(*mask, gc_alpha, 1, 0, 0, width, height);
428 gdk_gc_set_foreground(gc_alpha, &scolor);
434 for (y=0; y<
height; y++) {
435 for (x=0; x<
width; x++) {
436 alpha = data[(y * width + x) * 4 +3];
439 gdk_draw_point(*mask, gc_alpha, x, y);
445 gdk_draw_rgb_32_image(*pix, gc, 0, 0, width, height, GDK_RGB_DITHER_NONE, data, width*4);
447 gdk_pixmap_unref(*mask);
451 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)
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)
const char *const rcsid_gtk_png_c
uint8 * rescale_rgba_data(uint8 *data, int *width, int *height, int scale)