aboutsummaryrefslogtreecommitdiffstats
path: root/ppmtolss16.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-03-01 03:56:16 +0100
committerMattias Andrée <m@maandree.se>2026-03-01 03:56:16 +0100
commit948b23ca1fabfe65ab36d866031422e92840282f (patch)
tree07ff00b4959f734f65761896d39920e27396feb7 /ppmtolss16.c
parentfix typos (diff)
downloadliblss16-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.c65
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);