#include "config.h" #ifdef FBV_SUPPORT_PNG #include "fbv.h" #include #include #include #include #include #include #include #define PNG_BYTES_TO_CHECK 4 #ifndef min #define min(x,y) ((x) < (y) ? (x) : (y)) #endif int fh_png_id(char *name) { int fd; char id[4]; fd = open(name, O_RDONLY); if(fd==-1) return(0); read(fd, id, 4); close(fd); if(id[1]=='P' && id[2]=='N' && id[3]=='G') return(1); return(0); } int fh_png_load(char *name, unsigned char *buffer, unsigned char ** alpha,int x,int y) { png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; png_uint_32 i; int bit_depth, color_type, interlace_type; int number_passes,pass, trans = 0; png_bytep rptr[2]; unsigned char *rp; unsigned char *fbptr; FILE *fh; if(!(fh = fopen(name,"rb"))) return(FH_ERROR_FILE); png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); if (png_ptr == NULL) return(FH_ERROR_FORMAT); info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); fclose(fh); return(FH_ERROR_FORMAT); } rp = 0; if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); if(rp) free(rp); fclose(fh); return(FH_ERROR_FORMAT); } png_init_io(png_ptr,fh); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); if (bit_depth < 8) png_set_packing(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type== PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { trans = 1; png_set_tRNS_to_alpha(png_ptr); } if(bit_depth == 16) png_set_strip_16(png_ptr); number_passes = png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA || color_type == PNG_COLOR_TYPE_RGB_ALPHA || trans) { unsigned char * alpha_buffer = (unsigned char*) malloc(width * height); unsigned char * aptr; rp = (unsigned char*)malloc(width * 4); rptr[0] = (png_bytep) rp; *alpha = alpha_buffer; for (pass = 0; pass < number_passes; pass++) { fbptr = buffer; aptr = alpha_buffer; for(i=0; i