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