diff options
| author | Mattias Andrée <m@maandree.se> | 2026-02-25 22:28:36 +0100 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-02-25 22:28:36 +0100 |
| commit | 0db08b388ff8ee277b554accf6d43ce31c7d97a8 (patch) | |
| tree | 9f76bb0bcdbc3d55f07c6ce0863807d37d11147d /demo.c | |
| parent | Fix bug (incorrect update to histogram) (diff) | |
| download | libquanta-6de8730b9ef6c6972962db3108853fcd5fbfc3a1.tar.gz libquanta-6de8730b9ef6c6972962db3108853fcd5fbfc3a1.tar.bz2 libquanta-6de8730b9ef6c6972962db3108853fcd5fbfc3a1.tar.xz | |
Add demo1.0
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'demo.c')
| -rw-r--r-- | demo.c | 158 |
1 files changed, 158 insertions, 0 deletions
@@ -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; +} |
