summaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/image.c b/src/image.c
new file mode 100644
index 0000000..4cf7905
--- /dev/null
+++ b/src/image.c
@@ -0,0 +1,91 @@
+#include "image.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <png.h>
+
+#include "i18n.h"
+
+#define BIT_DEPTH 4
+#define PALETTE_SIZE (1 << BIT_DEPTH)
+#define PIXEL_SIZE ((BIT_DEPTH + 7) / 8)
+
+struct image {
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_bytepp rows;
+};
+
+static png_color palette[PALETTE_SIZE];
+
+struct image *
+image_new(const char *file_name)
+{
+ struct image *image;
+ FILE *fp;
+ size_t i;
+ size_t width = 32;
+ size_t height = 32;
+
+ image = calloc(1, sizeof(*image));
+ if (!image) {
+ return NULL;
+ }
+
+ fp = fopen(file_name, "wb");
+ if (!fp) {
+ printf(_("Error: Cannot open \"%s\" for writing\n"), file_name);
+ return image_destroy(&image);
+ }
+
+ image->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
+ NULL, NULL, NULL);
+ if (!image->png_ptr) {
+ return image_destroy(&image);
+ }
+
+ image->info_ptr = png_create_info_struct(image->png_ptr);
+ if (!image->info_ptr) {
+ return image_destroy(&image);
+ }
+
+ png_init_io(image->png_ptr, fp);
+
+ png_set_IHDR(image->png_ptr, image->info_ptr, width, height,
+ BIT_DEPTH, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ png_set_PLTE(image->png_ptr, image->info_ptr, palette, PALETTE_SIZE);
+
+ image->rows = png_malloc(image->png_ptr, height * sizeof(*image->rows));
+ for (i = 0; i < height; ++i) {
+ image->rows[i] = png_malloc(image->png_ptr, width * PIXEL_SIZE);
+ }
+ png_set_rows(image->png_ptr, image->info_ptr, image->rows);
+
+ return image;
+}
+
+void
+image_render(struct image *image)
+{
+ png_write_png(image->png_ptr, image->info_ptr, PNG_TRANSFORM_IDENTITY,
+ NULL);
+}
+
+struct image *
+image_destroy(struct image **image_p)
+{
+ struct image *image;
+ size_t i;
+
+ image = *image_p;
+
+ for (i = 0; i < 32; ++i) {
+ png_free(image->png_ptr, image->rows[i]);
+ }
+ png_free(image->png_ptr, image->rows);
+ png_destroy_write_struct(&image->png_ptr, &image->info_ptr);
+ free(image);
+ return image = NULL;
+}