aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.gitignore1
-rw-r--r--Makefile6
-rw-r--r--demo.c158
3 files changed, 164 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index a071ed4..9e13a6f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@
*.gcov
*.gcno
*.gcda
+/demo
diff --git a/Makefile b/Makefile
index 9bf77c2..3464de0 100644
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,7 @@ MAN3 =\
MAN7 = libquanta.7
-all: libquanta.a libquanta.$(LIBEXT)
+all: libquanta.a libquanta.$(LIBEXT) demo
$(OBJ): $(HDR)
$(LOBJ): $(HDR)
@@ -57,6 +57,9 @@ libquanta.a: $(OBJ)
libquanta.$(LIBEXT): $(LOBJ)
$(CC) $(LIBFLAGS) -o $@ $(LOBJ) $(LDFLAGS)
+demo: demo.o libquanta.a
+ $(CC) -o $@ demo.o libquanta.a $(LDFLAGS)
+
install: libquanta.a libquanta.$(LIBEXT)
mkdir -p -- "$(DESTDIR)$(PREFIX)/lib"
mkdir -p -- "$(DESTDIR)$(PREFIX)/include"
@@ -85,6 +88,7 @@ uninstall:
clean:
-rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib
-rm -f -- *.gch *.gcov *.gcno *.gcda *.$(LIBEXT)
+ -rm -f -- demo
.SUFFIXES:
.SUFFIXES: .lo .o .c
diff --git a/demo.c b/demo.c
new file mode 100644
index 0000000..75c0c7d
--- /dev/null
+++ b/demo.c
@@ -0,0 +1,158 @@
+/* See LICENSE file for copyright and license details. */
+#include <arpa/inet.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libquanta.h"
+
+
+static void
+die(const char *msg)
+{
+ perror(msg);
+ exit(1);
+}
+
+
+static void
+xfread(void *ptr, size_t size, size_t n)
+{
+ if (fread(ptr, size, n, stdin) != n) {
+ if (feof(stdin))
+ fprintf(stderr, "Unexpected EOF\n");
+ else
+ perror("fread");
+ exit(1);
+ }
+}
+
+static uint32_t
+read_be32(void)
+{
+ uint32_t be;
+ xfread(&be, 1, sizeof(be));
+ return ntohl(be);
+}
+
+
+static uint16_t
+read_be16(void)
+{
+ uint16_t be;
+ xfread(&be, 1, sizeof(be));
+ return ntohs(be);
+}
+
+
+static void
+xfwrite(const void *ptr, size_t size, size_t n)
+{
+ if (fwrite(ptr, size, n, stdout) != n)
+ die("fwrite");
+}
+
+
+static void
+write_be32(uint32_t v)
+{
+ uint32_t be = htonl(v);
+ xfwrite(&be, 1, sizeof(be));
+}
+
+static void
+write_be16(uint16_t v)
+{
+ uint16_t be = htons(v);
+ xfwrite(&be, 1, sizeof(be));
+}
+
+
+static size_t
+parse_opt_zu(const char *s, size_t def)
+{
+ char *end = NULL;
+ unsigned long int v;
+ if (!s || !*s)
+ return def;
+ errno = 0;
+ v = strtoul(s, &end, 10);
+ if (errno || end == s || *end || v == 0)
+ return def;
+ return (size_t)v;
+}
+
+
+int
+main(void)
+{
+ size_t max_colours = parse_opt_zu(getenv("QUANTA_COLOURS"), 16);
+ char magic[8];
+ size_t w, h, size, i, j;
+ uint16_t *chimgs[4];
+ struct libquanta_channel chs[4];
+ struct libquanta_palette *pal;
+ struct libquanta_image *img;
+
+ xfread(magic, 1, 8);
+ if (memcmp(magic, "farbfeld", 8)) {
+ fprintf(stderr, "Input is not farbfeld\n");
+ return 1;
+ }
+
+ w = (size_t)read_be32();
+ h = (size_t)read_be32();
+ if (!w || !h) {
+ fprintf(stderr, "Empty image\n");
+ return 1;
+ }
+ if (w > SIZE_MAX / h) {
+ fprintf(stderr, "Image too large\n");
+ return 1;
+ }
+ size = w * h;
+
+ memset(chs, 0, sizeof(chs));
+
+ for (i = 0; i < 4; i++) {
+ chimgs[i] = calloc(size, sizeof(**chimgs));
+ if (!chimgs[i])
+ die("calloc");
+ chs[i].bits_in = 16;
+ chs[i].bits_out = 16;
+ chs[i].image_width = w;
+ chs[i].image_height = h;
+ chs[i].image_row_size = w * sizeof(uint16_t);
+ chs[i].image_cell_size = sizeof(uint16_t);
+ chs[i].image = chimgs[i];
+ }
+
+ for (j = 0; j < size; j++)
+ for (i = 0; i < 4; i++)
+ chimgs[i][j] = read_be16();
+
+ pal = libquanta_malloc_palette(max_colours, 4);
+ if (!pal)
+ die("libquanta_malloc_palette");
+
+ img = libquanta_quantise(pal, &chs[0], &chs[1], &chs[2], &chs[3], NULL);
+ if (!img)
+ die("libquanta_quantise");
+
+ xfwrite("farbfeld", 1, 8);
+ write_be32((uint32_t)w);
+ write_be32((uint32_t)h);
+
+ for (j = 0; j < size; j++)
+ for (i = 0; i < 4; i++)
+ write_be16((uint16_t)pal->palette[img->image[j] * 4 + i]);
+
+ free(img);
+ free(pal);
+ for (i = 4; i--;)
+ free(chimgs[i]);
+
+ fflush(stdout);
+ return 0;
+}