Update of /cvsroot/pure-data/externals/pdp/system/png In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6756/system/png
Added Files: Makefile pdp_png.c Log Message: checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz
--- NEW FILE: pdp_png.c ---
/* * Pure Data Packet system module. - png glue code * Copyright (c) by Tom Schouten pdp@zzz.kotnet.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */
#include "pdp_packet.h" #include "pdp_mem.h" #include "pdp_post.h" #include "pdp_debug.h"
// this is an optional module #include "pdp_config.h"
#ifdef HAVE_PDP_PNG //if 0
#include <png.h>
#define READING 1 #define WRITING 2 #define SIG_BYTES 8
#define D if(0)
typedef struct { FILE *x_fp;
int x_kindof; //READING or WRITING png_structp x_png; png_infop x_info; png_infop x_end_info;
png_uint_32 x_width; png_uint_32 x_height; int x_bit_depth; int x_color_type; int x_interlace_type; int x_compression_type; int x_filter_type;
int x_pdp_bitmap_type; int x_packet;
} t_png_image;
static t_png_image *_init(t_png_image *x) { x->x_png = 0; x->x_info = 0; x->x_end_info = 0; x->x_fp = 0; x->x_packet = -1; return x; }
static int _cleanup(t_png_image *x) { #define INTERNAL_ERROR 1 if (!x) return 1; pdp_packet_mark_unused(x->x_packet); if (x->x_png) switch(x->x_kindof){ case READING: png_destroy_read_struct(&x->x_png, &x->x_info, &x->x_end_info); break; case WRITING: png_destroy_write_struct(&x->x_png, &x->x_info); break; default: PDP_ASSERT(INTERNAL_ERROR); } if (x->x_fp) fclose(x->x_fp); return 1; }
static int _open_read(t_png_image* x, char *file) { char header[SIG_BYTES]; int is_png;
x->x_fp = fopen(file, "r"); if (!x->x_fp) { D pdp_post("can't open %s for reading", file); return 0; } fread(header, 1, SIG_BYTES, x->x_fp); is_png = !png_sig_cmp(header, 0, SIG_BYTES);
D pdp_post("%s is %s png file", file, is_png ? "a" : "not a");
return is_png; }
static int _open_write(t_png_image* x, char *file) { char header[SIG_BYTES]; int is_png;
x->x_fp = fopen(file, "w"); if (!x->x_fp) { D pdp_post("can't open %s for writing", file); return 0; }
return 1; }
/* progress callback */
static void _row_callback(png_structp p, png_uint_32 row, int pass) { fprintf(stderr, "."); }
static int _initio_read(t_png_image *x) { png_init_io(x->x_png, x->x_fp); png_set_sig_bytes(x->x_png, SIG_BYTES); D png_set_read_status_fn(x->x_png, _row_callback); return 1;
}
static int _initio_write(t_png_image *x) { png_init_io(x->x_png, x->x_fp); D png_set_write_status_fn(x->x_png, _row_callback);
return 1;
}
static int _checkimagetype(t_png_image *x) { png_read_info(x->x_png, x->x_info); png_get_IHDR(x->x_png, x->x_info, &x->x_width, &x->x_height, &x->x_bit_depth, &x->x_color_type, &x->x_interlace_type, &x->x_compression_type, &x->x_filter_type);
D pdp_post("image info: w=%d, h=%d, depth=%d, type=%d", (int)x->x_width, (int)x->x_height, (int)x->x_bit_depth, (int)x->x_color_type);
/* handle paletted images: convert to 8 bit RGB(A) */ if (x->x_color_type == PNG_COLOR_TYPE_PALETTE && x->x_bit_depth <= 8) { png_set_expand(x->x_png); D pdp_post("convert palette");
/* check if there's an alpha channel and set PDP_BITMAP type */ x->x_pdp_bitmap_type = (png_get_valid(x->x_png, x->x_info, PNG_INFO_tRNS)) ? PDP_BITMAP_RGBA : PDP_BITMAP_RGB;
return 1; }
/* handle bitdepth */ if (x->x_bit_depth < 8) { png_set_expand(x->x_png); D pdp_post("convert greyscale to 8 bit"); } if (x->x_bit_depth == 16){ D pdp_post("stripping 16 bit to 8 bit"); png_set_strip_16(x->x_png); }
/* handle greyscale images */ if (x->x_color_type == PNG_COLOR_TYPE_GRAY){ x->x_pdp_bitmap_type = PDP_BITMAP_GREY; if (png_get_valid(x->x_png, x->x_info, PNG_INFO_tRNS)){ D pdp_post("no support for greyscale images with alpha info"); return 0; } return 1; }
/* handle RGB imges */ if (x->x_color_type = PNG_COLOR_TYPE_RGB){ x->x_pdp_bitmap_type = PDP_BITMAP_RGB; return 1; }
/* handle RGBA imges */ if (x->x_color_type = PNG_COLOR_TYPE_RGBA){ x->x_pdp_bitmap_type = PDP_BITMAP_RGBA; return 1; }
/* can't handle image type */ D pdp_post("image type not supported"); return 0;
}
#define user_error_ptr NULL #define user_error_fn NULL #define user_warning_fn NULL
static int _buildstruct_read(t_png_image *x) { x->x_kindof = READING;
if (!(x->x_png = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn))) return 0;
if (!(x->x_info = png_create_info_struct(x->x_png))) return 0; if (!(x->x_end_info = png_create_info_struct(x->x_png))) return 0;
return 1; }
static int _buildstruct_write(t_png_image *x) { x->x_kindof = WRITING;
if (!(x->x_png = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn))) return 0;
if (!(x->x_info = png_create_info_struct(x->x_png))) return 0;
return 1; }
static int _getimagedata(t_png_image *x) { int nbchans = 0; char *image_data; png_bytep row_pointers[x->x_height]; png_uint_32 i;
D pdp_post("reading %d rows ", (int)x->x_height);
switch (x->x_pdp_bitmap_type){ case PDP_BITMAP_GREY: nbchans = 1; break; case PDP_BITMAP_RGB: nbchans = 3; break; case PDP_BITMAP_RGBA: nbchans = 4; break; default: return 0; }
x->x_packet = pdp_packet_new_bitmap(x->x_pdp_bitmap_type, x->x_width, x->x_height); if (!(image_data = pdp_packet_data(x->x_packet))) return 0;
for(i=0; i<x->x_height; i++) row_pointers[i] = image_data + nbchans * i * x->x_width;
png_read_image(x->x_png, row_pointers);
D pdp_post("DONE");
return 1; }
static int _saveimagedata(t_png_image *x, int packet) { png_bytep *row_pointers; png_uint_32 i; int nbchans; t_pdp *h = pdp_packet_header(packet); char *image_data = (char *)pdp_packet_data(packet);
if (!h) return 0; if (PDP_BITMAP != h->type) return 0; if (!image_data) return 0;
x->x_width = h->info.bitmap.width; x->x_height = h->info.bitmap.height;
switch(h->info.image.encoding){ case PDP_BITMAP_GREY: x->x_color_type = PNG_COLOR_TYPE_GRAY; nbchans = 1; break; case PDP_BITMAP_RGB: x->x_color_type = PNG_COLOR_TYPE_RGB; nbchans = 3; break; case PDP_BITMAP_RGBA: x->x_color_type = PNG_COLOR_TYPE_RGBA; nbchans = 4; break; default: return 0; } png_set_IHDR(x->x_png, x->x_info, x->x_width, x->x_height, 8, x->x_color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(x->x_png, x->x_info);
D pdp_post("writing %d rows ", (int)x->x_height);
row_pointers = (png_bytep *)pdp_alloc(sizeof(png_bytep) * x->x_height); for(i=0; i<x->x_height; i++) row_pointers[i] = image_data + nbchans * i * x->x_width;
png_write_image(x->x_png, row_pointers); png_write_end(x->x_png, x->x_info); pdp_dealloc(row_pointers);
D pdp_post("DONE");
return 1; }
/* simple functions to load and save png images */
int pdp_packet_bitmap_from_png_file(char *filename) { int packet = -1; t_png_image _x; t_png_image *x = &_x;
if (!_init(x)) goto exit; if (!_open_read(x, filename)) goto exit; if (!_buildstruct_read(x)) goto exit; if (!_initio_read(x)) goto exit; if (!_checkimagetype(x)) goto exit; if (!_getimagedata(x)) goto exit;
packet = x->x_packet; x->x_packet = -1; _cleanup(x); return packet; exit: _cleanup(x); return -1;
}
int pdp_packet_bitmap_save_png_file(int packet, char *filename) {
t_png_image _x; t_png_image *x = &_x;
if (!_init(x)) goto exit; if (!_open_write(x, filename)) goto exit; if (!_buildstruct_write(x)) goto exit; if (!_initio_write(x)) goto exit; if (!_saveimagedata(x, packet)) goto exit;
_cleanup(x); return 1; exit: _cleanup(x); return 0;
}
#else //PDP_HAVE_PNG int pdp_packet_bitmap_save_png_file(int packet, char *filename) { pdp_post("WARNING: no png support, can't save png file %s", filename); return 0; }
int pdp_packet_bitmap_from_png_file(char *filename) { pdp_post("WARNING: no png support, can't load png file %s", filename); return -1; }
#endif //PDP_HAVE_PNG
#if 0 int main(int argc, char **argv) { char *image = 0;
if (argc != 2) pdp_post("usage: %s <png file>", argv[0]); else image = load_png(argv[1]);
pdp_post ("%s", image ? "OK" : "ERROR");
} #endif
--- NEW FILE: Makefile ---
OBJECTS = pdp_png.o
include ../../Makefile.config
all: $(OBJECTS)
clean: rm -f *~ rm -f *.o