diff options
Diffstat (limited to 'src/png.c')
-rw-r--r-- | src/png.c | 103 |
1 files changed, 62 insertions, 41 deletions
@@ -1,65 +1,86 @@ +#include <stdlib.h> #include <png.h> #include "meh.h" -unsigned char *loadpng(FILE *infile, int *bufwidth, int *bufheight){ + +struct png_t{ + struct image img; + FILE *f; png_structp png_ptr; png_infop info_ptr; png_infop end_info; - int numpasses = 1; - unsigned char *buf; - - if((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL) + int numpasses; +}; + +struct image *png_open(FILE *f){ + struct png_t *p = malloc(sizeof(struct png_t)); + if((p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL){ + free(p); return NULL; - if((info_ptr = png_create_info_struct(png_ptr)) == NULL){ - png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + } + if((p->info_ptr = png_create_info_struct(p->png_ptr)) == NULL){ + png_destroy_read_struct(&p->png_ptr, (png_infopp)NULL, (png_infopp)NULL); + free(p); return NULL; } - if((end_info = png_create_info_struct(png_ptr)) == NULL){ - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + if((p->end_info = png_create_info_struct(p->png_ptr)) == NULL){ + png_destroy_read_struct(&p->png_ptr, &p->info_ptr, (png_infopp)NULL); + free(p); return NULL; } - if(setjmp(png_jmpbuf(png_ptr))){ - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + if(setjmp(png_jmpbuf(p->png_ptr))){ + png_destroy_read_struct(&p->png_ptr, &p->info_ptr, &p->end_info); + free(p); return NULL; } - png_init_io(png_ptr, infile); + p->f = f; + rewind(f); + png_init_io(p->png_ptr, f); - /* Start reading */ - png_read_info(png_ptr, info_ptr); - buf = malloc(100); + png_read_info(p->png_ptr, p->info_ptr); { - png_byte color_type = png_get_color_type(png_ptr, info_ptr); + png_byte color_type = png_get_color_type(p->png_ptr, p->info_ptr); if(color_type == PNG_COLOR_TYPE_PALETTE) - png_set_palette_to_rgb(png_ptr); - if(color_type == PNG_COLOR_TYPE_GRAY && png_get_bit_depth(png_ptr, info_ptr) < 8) - png_set_gray_1_2_4_to_8(png_ptr); - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) - png_set_tRNS_to_alpha(png_ptr); - if (png_get_bit_depth(png_ptr, info_ptr) == 16) - png_set_strip_16(png_ptr); + png_set_palette_to_rgb(p->png_ptr); + if(color_type == PNG_COLOR_TYPE_GRAY && png_get_bit_depth(p->png_ptr, p->info_ptr) < 8) + png_set_gray_1_2_4_to_8(p->png_ptr); + if (png_get_valid(p->png_ptr, p->info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(p->png_ptr); + if (png_get_bit_depth(p->png_ptr, p->info_ptr) == 16) + png_set_strip_16(p->png_ptr); if(color_type & PNG_COLOR_MASK_ALPHA) - png_set_strip_alpha(png_ptr); + png_set_strip_alpha(p->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_interlace_type(png_ptr, info_ptr) == PNG_INTERLACE_ADAM7) - numpasses = png_set_interlace_handling(png_ptr); - png_read_update_info(png_ptr, info_ptr); - } - { - int y; - *bufwidth = png_get_image_width(png_ptr, info_ptr); - *bufheight = png_get_image_height(png_ptr, info_ptr); - buf = malloc((*bufwidth) * (*bufheight) * 3); - printf("%ix%i\n", *bufwidth, *bufheight); - while(numpasses--){ - for(y = 0; y < *bufheight; y++) - png_read_row(png_ptr, &buf[y * (*bufwidth) * 3], NULL); - } + png_set_gray_to_rgb(p->png_ptr); + if(png_get_interlace_type(p->png_ptr, p->info_ptr) == PNG_INTERLACE_ADAM7) + p->numpasses = png_set_interlace_handling(p->png_ptr); + else + p->numpasses = 1; + png_read_update_info(p->png_ptr, p->info_ptr); } - printf("reached end\n"); - return buf; + p->img.width = png_get_image_width(p->png_ptr, p->info_ptr); + p->img.height = png_get_image_height(p->png_ptr, p->info_ptr); + + return (struct image *)p; } +int png_read(struct image *img){ + struct png_t *p = (struct png_t *)img; + int y; + while(p->numpasses--){ + for(y = 0; y < img->height; y++) + png_read_row(p->png_ptr, &img->buf[y * (img->width) * 3], NULL); + } + png_destroy_read_struct(&p->png_ptr, &p->info_ptr, &p->end_info); + return 0; +} + +struct imageformat libpng = { + png_open, + png_read +}; + + |