107 lines
3.1 KiB
C
107 lines
3.1 KiB
C
#include <stdio.h>
|
|
#include <png.h>
|
|
|
|
#ifndef use_png_library
|
|
#define use_png_library
|
|
#endif
|
|
|
|
static void * png_image_import (const char * path, uint * width, uint * height) {
|
|
FILE * file;
|
|
uint * data;
|
|
uint index;
|
|
|
|
png_byte colour_type = 0;
|
|
png_byte bit_depth = 0;
|
|
png_bytep * row_pointers = null;
|
|
|
|
png_structp structure = null;
|
|
png_infop information = null;
|
|
|
|
fatal_failure (path == null, "png_image_import: File path is null pointer.");
|
|
fatal_failure (width == null, "png_image_import: Width is null pointer.");
|
|
fatal_failure (height == null, "png_image_import: Height is null pointer.");
|
|
|
|
file = fopen (path, "rb");
|
|
|
|
fatal_failure (file == null, path);
|
|
|
|
structure = png_create_read_struct (PNG_LIBPNG_VER_STRING, null, null, null);
|
|
information = png_create_info_struct (structure);
|
|
|
|
png_init_io (structure, file);
|
|
png_read_info (structure, information);
|
|
|
|
* width = png_get_image_width (structure, information);
|
|
* height = png_get_image_height (structure, information);
|
|
colour_type = png_get_color_type (structure, information);
|
|
bit_depth = png_get_bit_depth (structure, information);
|
|
|
|
if (bit_depth == 16) {
|
|
png_set_strip_16 (structure);
|
|
}
|
|
|
|
if (colour_type == PNG_COLOR_TYPE_PALETTE) {
|
|
png_set_palette_to_rgb (structure);
|
|
}
|
|
|
|
if ((colour_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8)) {
|
|
png_set_expand_gray_1_2_4_to_8 (structure);
|
|
}
|
|
|
|
if (png_get_valid (structure, information, PNG_INFO_tRNS)) {
|
|
png_set_tRNS_to_alpha (structure);
|
|
}
|
|
|
|
if ((colour_type == PNG_COLOR_TYPE_RGB) || (colour_type == PNG_COLOR_TYPE_GRAY) || (colour_type == PNG_COLOR_TYPE_PALETTE)) {
|
|
png_set_filler (structure, 0xff, PNG_FILLER_AFTER);
|
|
}
|
|
|
|
if ((colour_type == PNG_COLOR_TYPE_GRAY) || (colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)) {
|
|
png_set_gray_to_rgb (structure);
|
|
}
|
|
|
|
png_read_update_info (structure, information);
|
|
|
|
row_pointers = allocate ((* height) * sizeof (* row_pointers));
|
|
|
|
for (index = 0; index < (* height); ++index) {
|
|
row_pointers [index] = allocate (png_get_rowbytes (structure, information));
|
|
}
|
|
|
|
png_read_image (structure, row_pointers);
|
|
|
|
fclose (file);
|
|
|
|
data = allocate ((* width) * (* height) * sizeof (* data));
|
|
|
|
for (index = 0; index < (* height); ++index) {
|
|
memory_copy (& data [index * (* width)], row_pointers [index], (* width) * sizeof (* data));
|
|
|
|
row_pointers [index] = deallocate (row_pointers [index]);
|
|
}
|
|
|
|
row_pointers = deallocate (row_pointers);
|
|
|
|
png_destroy_read_struct (& structure, & information, null);
|
|
|
|
return (data);
|
|
}
|
|
|
|
static void png_image_export (const char * path, uint * data, uint width, uint height) {
|
|
png_image image = { 0 };
|
|
|
|
fatal_failure (path == null, "png_image_export: File path is null pointer.");
|
|
fatal_failure (data == null, "png_image_export: Data is null pointer.");
|
|
fatal_failure (width == 0, "png_image_export: Width is equal to zero.");
|
|
fatal_failure (height == 0, "png_image_export: Height is equal to zero.");
|
|
|
|
image.version = PNG_IMAGE_VERSION;
|
|
image.format = PNG_FORMAT_RGBA;
|
|
image.width = width;
|
|
image.height = height;
|
|
|
|
png_image_write_to_file (& image, path, 0, data, 0, null);
|
|
|
|
png_image_free (& image);
|
|
}
|