int imageLoadPng(const char *path, int *outWidth, int *outHeight, unsigned char **pixels) {
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
png_infop info = png ? png_create_info_struct(png) : NULL;
if (!png) {
fprintf(stderr, "Cannot initialize PNG library\n");
fflush(stderr);
return FALSE;
}
FILE *f = fopen(path, "rb");
if (!f) {
fprintf(stderr, "Cannot open for read: %s\n", path);
fflush(stderr);
return FALSE;
}
unsigned char header[8];
fread(header, sizeof(header), 1, f);
if (png_sig_cmp(header, 0, sizeof(header))) {
fclose(f);
fprintf(stderr, "Seems it is not PNG image: %s\n", path);
fflush(stderr);
return FALSE;
}
png_init_io(png, f);
png_set_sig_bytes(png, sizeof(header));
png_read_info(png, info);
unsigned int width, height;
int bitdepth, colortype;
png_get_IHDR(png,info, &width, &height, &bitdepth, &colortype, 0, 0, 0);
if (colortype == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png);
if (colortype == PNG_COLOR_TYPE_GRAY && bitdepth < 8)
png_set_expand_gray_1_2_4_to_8(png);
if (colortype == PNG_COLOR_TYPE_GRAY || colortype == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png);
if (png_get_valid(png, info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png);
if (colortype == PNG_COLOR_TYPE_RGB)
png_set_filler(png, 0xff, PNG_FILLER_AFTER);
if (bitdepth == 16)
png_set_strip_16(png);
if (bitdepth < 8)
png_set_packing(png);
png_read_update_info(png, info);
png_get_IHDR(png, info, &width, &height, 0, 0, 0, 0, 0);
unsigned char *data = (unsigned char*)calloc(1, 4*width*height);
png_bytep *rows = (png_bytep*)malloc(height*sizeof(png_bytep));
for(unsigned int i = 0; i < height; i++)
rows[i] = data + i*4*width;
png_read_image(png, rows);
png_read_end(png, 0);
free(rows);
png_destroy_read_struct(&png, &info, 0);
fclose(f);
*outWidth = (int)width;
*outHeight = (int)height;
*pixels = data;
return TRUE;
}
int imageSavePng(const char *path, int width, int height, const unsigned char *pixels) {
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
png_infop info = png ? png_create_info_struct(png) : NULL;
if (!png) {
fprintf(stderr, "Cannot initialize PNG library\n");
fflush(stderr);
return FALSE;
}
FILE *f = fopen(path, "wb");
if (!f) {
fprintf(stderr, "Cannot open for write: %s\n", path);
fflush(stderr);
return FALSE;
}
png_init_io(png, f);
png_set_IHDR( png, info, width, height, 8, PNG_COLOR_TYPE_RGBA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE );
png_write_info(png, info);
png_set_packing(png);
png_bytep *rows = (png_bytep*)malloc(height*sizeof(png_bytep));
for(int i = 0; i < height; i++)
rows[i] = (png_bytep)(pixels + i*4*width);
png_write_image(png, rows);
png_write_end(png, info);
free(rows);
png_destroy_write_struct(&png, &info);
fclose(f);
return TRUE;
}