aboutsummaryrefslogtreecommitdiff
path: root/xormat/png.h
diff options
context:
space:
mode:
authorxolatile2025-04-29 15:06:12 +0200
committerxolatile2025-04-29 15:06:12 +0200
commit563677d05001ac082721746db79aa915b10968ea (patch)
treed3aa65b164f1260841877f659d7897603174a4aa /xormat/png.h
downloadxolatile-xuxuxu-563677d05001ac082721746db79aa915b10968ea.tar.xz
xolatile-xuxuxu-563677d05001ac082721746db79aa915b10968ea.tar.zst
Added this for Anon...
Diffstat (limited to 'xormat/png.h')
-rw-r--r--xormat/png.h105
1 files changed, 105 insertions, 0 deletions
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 <stdio.h>
+#include <png.h>
+
+#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);
+}