| | 1 | #include <stdlib.h> |
| | 2 | #include <stdint.h> |
| | 3 | #include <libpng/png.h> |
| | 4 | |
| | 5 | unsigned char *png_get_image_data(FILE *infile, uint32_t *image_width, uint32_t *image_height) |
| | 6 | { |
| | 7 | unsigned char buf[8], *image_data = NULL; |
| | 8 | png_structp png_ptr; |
| | 9 | |
| | 10 | fread(buf, 1, 8, infile); |
| | 11 | |
| | 12 | if((png_sig_cmp(buf, 0, 8)) |
| | 13 | || |
| | 14 | (NULL == (png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))) |
| | 15 | return NULL; |
| | 16 | |
| | 17 | png_infop info_ptr = png_create_info_struct(png_ptr); |
| | 18 | |
| | 19 | if (NULL != info_ptr) |
| | 20 | { |
| | 21 | if (setjmp(png_jmpbuf(png_ptr))) |
| | 22 | { |
| | 23 | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); |
| | 24 | free(image_data); |
| | 25 | return NULL; |
| | 26 | } |
| | 27 | |
| | 28 | png_init_io(png_ptr, infile); |
| | 29 | png_set_sig_bytes(png_ptr, 8); |
| | 30 | png_read_info(png_ptr, info_ptr); |
| | 31 | |
| | 32 | if(4 != png_get_channels(png_ptr, info_ptr)) |
| | 33 | { |
| | 34 | fprintf(stderr, "missing alpha channel\n"); |
| | 35 | return NULL; |
| | 36 | } |
| | 37 | else if (16 == png_get_bit_depth(png_ptr, info_ptr)) |
| | 38 | { |
| | 39 | png_set_strip_16(png_ptr); |
| | 40 | png_read_update_info(png_ptr, info_ptr); |
| | 41 | } |
| | 42 | |
| | 43 | *image_height = png_get_image_height(png_ptr, info_ptr); |
| | 44 | *image_width = png_get_image_width(png_ptr, info_ptr); |
| | 45 | image_data = calloc(*image_height, png_get_rowbytes(png_ptr, info_ptr)); |
| | 46 | |
| | 47 | if (NULL != image_data) |
| | 48 | { |
| | 49 | png_bytep rows[*image_height]; |
| | 50 | uint32_t y, offset = *image_width * 4; |
| | 51 | |
| | 52 | for (y=0; y < *image_height; y++) |
| | 53 | { |
| | 54 | rows[y] = image_data + (y * offset); |
| | 55 | } |
| | 56 | |
| | 57 | png_read_image(png_ptr, rows); |
| | 58 | } |
| | 59 | } |
| | 60 | |
| | 61 | png_destroy_read_struct(&png_ptr, &info_ptr, NULL); |
| | 62 | |
| | 63 | return image_data; |
| | 64 | } |