#include #include #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); }