diff options
| author | Mattias Andrée <m@maandree.se> | 2026-03-01 03:56:16 +0100 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-03-01 03:56:16 +0100 |
| commit | 948b23ca1fabfe65ab36d866031422e92840282f (patch) | |
| tree | 07ff00b4959f734f65761896d39920e27396feb7 /ppmtolss16.c | |
| parent | fix typos (diff) | |
| download | liblss16-948b23ca1fabfe65ab36d866031422e92840282f.tar.gz liblss16-948b23ca1fabfe65ab36d866031422e92840282f.tar.bz2 liblss16-948b23ca1fabfe65ab36d866031422e92840282f.tar.xz | |
Fix mistakes, and finish ppmtolss16
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'ppmtolss16.c')
| -rw-r--r-- | ppmtolss16.c | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/ppmtolss16.c b/ppmtolss16.c index 1f2ec1a..5db4a39 100644 --- a/ppmtolss16.c +++ b/ppmtolss16.c @@ -7,6 +7,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <libquanta.h> #if defined(__clang__) # pragma clang diagnostic ignored "-Wunsafe-buffer-usage" @@ -31,7 +32,7 @@ static int invert; static void -writeall(char *data, size_t n) +writeall(const char *data, size_t n) { ssize_t r; @@ -121,6 +122,7 @@ static size_t read_dimension(size_t p, size_t *value) { size_t digit; + *value = 0; for (;;) { if (p == len) { if (eof) @@ -437,6 +439,55 @@ read_image_bits(void) } +static void +quantise(struct liblss16_header *header, int coloured) +{ + size_t i, nchannels = coloured ? 3U : 1U; + struct libquanta_channel channels[3]; + struct libquanta_palette *palette; + struct libquanta_image *image; + + memset(channels, 0, sizeof(channels)); + + for (i = 0; i < nchannels; i++) { + channels[i].bits_in = 6; + channels[i].bits_out = 6; + channels[i].image_width = width; + channels[i].image_height = height; + channels[i].image_row_size = nchannels * width; + channels[i].image_cell_size = nchannels; + channels[i].image = &buf[i]; + } + + palette = libquanta_malloc_palette(16, nchannels); + if (!palette) { + fprintf(stderr, "%s: libquanta_malloc_palette: %s\n", argv0, strerror(errno)); + exit(3); + } + + image = libquanta_quantise(palette, &channels[0], coloured ? &channels[1] : NULL, &channels[2], NULL); + if (!image) { + fprintf(stderr, "%s: libquanta_quantise: %s\n", argv0, strerror(errno)); + exit(3); + } + + for (i = 0; i < len; i++) + buf[i] = (char)image->image[i]; + + for (i = 0; i < palette->size; i++) { + header->colour_map[i].r = (uint8_t)palette->palette[i * nchannels + (coloured ? 0U : 0U)]; + header->colour_map[i].g = (uint8_t)palette->palette[i * nchannels + (coloured ? 1U : 0U)]; + header->colour_map[i].b = (uint8_t)palette->palette[i * nchannels + (coloured ? 2U : 0U)]; + } + memset(&header->colour_map[palette->size], + header->colour_map[palette->size - 1U].b, + (16U - palette->size) * sizeof(*header->colour_map)); + + free(image); + free(palette); +} + + int main(int argc, char *argv[]) { @@ -541,19 +592,23 @@ main(int argc, char *argv[]) header.colour_map[!invert].g = 63U; header.colour_map[!invert].b = 63U; } else if (maptype == 2) { - /* TODO convert to 16 colours -- greyscale values [0, 63], quantize to 16 colours and map Y to (Y, Y, Y) */ + quantise(&header, 0); } else { - /* TODO convert to 16 colours -- [0, 63]-triplet values, quantize to 16 colours */ + if (len % 3) + not_pnm(); + len /= 3; + quantise(&header, 1); } liblss16_optimise(&header, (uint8_t *)buf); if (liblss16_encoder_init(&encoder, &header, 1, &error)) { - fprintf(stderr, "%s:liblss16_encoder_init: %s\n", argv0, liblss16_encode_strerror(error)); + fprintf(stderr, "%s: liblss16_encoder_init: %s\n", argv0, liblss16_encode_strerror(error)); exit(3); } off = 0; + do { - state = liblss16_encode_from_colour_index(&encoder, wbuf, sizeof(buf), &written, + state = liblss16_encode_from_colour_index(&encoder, wbuf, sizeof(wbuf), &written, (const uint8_t *)&buf[off], len - off, &consumed); off += consumed; writeall(wbuf, written); |
