Show pngio.h syntax highlighted
// Helper functions for reading a writing PNG files.
// By Brendon Higgins: bh_doc@users.sf.net
// Released in Nov 2003 under GPL. See www.gnu.org if you don't know what that is.
#include <stdio.h>
#include <png.h>
typedef struct {
unsigned char red, green, blue, alpha;
} colour;
typedef struct {
FILE* fp;
png_structp png;
png_infop info;
png_infop end;
colour** rows;
} pngstuff;
int open_png(char *filename, pngstuff* ret) {
png_uint_32 width, height;
int y, bit_depth, colour_type, interlace_type;
ret->fp = fopen(filename, "rb");
if (!ret->fp) {
return 1;
}
ret->png = png_create_read_struct(
PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!ret->png) {
fclose(ret->fp);
return 2;
}
ret->info = png_create_info_struct(ret->png);
if (!ret->info) {
png_destroy_read_struct(&ret->png, NULL, NULL);
fclose(ret->fp);
return 3;
}
ret->end = png_create_info_struct(ret->png);
if (!ret->end) {
png_destroy_read_struct(&ret->png, &ret->info, NULL);
fclose(ret->fp);
return 4;
}
if (setjmp(png_jmpbuf(ret->png))) {
png_destroy_read_struct(&ret->png, &ret->info, &ret->end);
fclose(ret->fp);
return 5;
}
png_init_io(ret->png, ret->fp);
png_read_info(ret->png, ret->info);
png_get_IHDR(ret->png, ret->info, &width, &height, &bit_depth,
&colour_type, &interlace_type, NULL, NULL);
png_set_strip_16(ret->png);
png_set_packing(ret->png);
if (colour_type == PNG_COLOR_TYPE_PALETTE) {
png_set_palette_to_rgb(ret->png);
}
if (colour_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
png_set_gray_1_2_4_to_8(ret->png);
}
if (png_get_valid(ret->png, ret->info, PNG_INFO_tRNS)) {
png_set_tRNS_to_alpha(ret->png);
}
png_set_filler(ret->png, 0xff, PNG_FILLER_AFTER);
if (colour_type == PNG_COLOR_TYPE_GRAY ||
colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
png_set_gray_to_rgb(ret->png);
}
ret->rows = (colour**) malloc(height * sizeof(colour*));
for (y = 0; y < height; ++y) {
ret->rows[y] = (colour*) malloc(width * sizeof(colour));
}
png_read_image(ret->png, (png_bytepp) ret->rows);
png_read_end(ret->png, ret->info);
return 0;
}
void close_png(pngstuff* p) {
png_destroy_read_struct(&p->png, &p->info, &p->end);
fclose(p->fp);
p->fp = NULL;
}
int write_png(char* filename, colour** rows, int width, int height) {
FILE* fp_out;
png_structp ppng_out;
png_infop pinfo_out;
fp_out = fopen(filename, "wb");
if (!fp_out) {
return 1;
}
ppng_out = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!ppng_out) {
fclose(fp_out);
return 2;
}
pinfo_out = png_create_info_struct(ppng_out);
if (!pinfo_out) {
png_destroy_write_struct(&ppng_out, NULL);
fclose(fp_out);
return 3;
}
png_init_io(ppng_out, fp_out);
png_set_IHDR(ppng_out, pinfo_out, width, height, 8,
PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_set_rows(ppng_out, pinfo_out, (png_bytepp)rows);
if (setjmp(png_jmpbuf(ppng_out))) {
png_destroy_write_struct(&ppng_out, &pinfo_out);
fclose(fp_out);
return 4;
}
png_write_png(ppng_out, pinfo_out, PNG_TRANSFORM_IDENTITY, NULL);
png_destroy_write_struct(&ppng_out, &pinfo_out);
fclose(fp_out);
return 0;
}
See more files for this project here