From b2bbfd7be69c1de91a06d922a9f7e09b45e59c1e Mon Sep 17 00:00:00 2001 From: xolatile Date: Sun, 20 Apr 2025 15:13:58 +0200 Subject: Hopefully finished Xarbon... --- xormat/png.h | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 xormat/png.h (limited to 'xormat') diff --git a/xormat/png.h b/xormat/png.h new file mode 100644 index 0000000..8c15c29 --- /dev/null +++ b/xormat/png.h @@ -0,0 +1,105 @@ +#include +#include + +#ifndef use_png_library +#define use_png_library +#endif + +static generic * png_image_import (character * path, natural * width, natural * height) { + FILE * file = null; + natural * data = null; + + 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 (natural 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 (natural 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 procedure png_image_export (character * path, natural * data, natural width, natural 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); +} -- cgit v1.2.3