From d6351d1ebd892a031e9e645dbdeadf4c6cc1b1d2 Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Mon, 19 Feb 2018 00:06:56 -0500 Subject: Read and write palette in pngo --- bin/pngo.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'bin/pngo.c') diff --git a/bin/pngo.c b/bin/pngo.c index 14f86579..3522eb82 100644 --- a/bin/pngo.c +++ b/bin/pngo.c @@ -195,6 +195,42 @@ static void writeHeader(void) { header.height = ntohl(header.height); } +static struct { + uint32_t len; + struct PACKED { + uint8_t r, g, b; + } entries[256]; +} palette; + +static void readPalette(void) { + struct Chunk chunk; + for (;;) { + chunk = readChunk(); + if (0 == memcmp(chunk.type, "PLTE", 4)) { + break; + } else if (!(chunk.type[0] & 0x20)) { + errx( + EX_DATAERR, "%s: expected PLTE chunk, found %s", + path, typeStr(chunk) + ); + } + } + if (chunk.size % 3) { + errx(EX_DATAERR, "%s: PLTE size %u not divisible by 3", path, chunk.size); + } + + palette.len = chunk.size / 3; + readExpect(palette.entries, chunk.size, "palette data"); + readCrc(); +} + +static void writePalette(void) { + struct Chunk plte = { .size = 3 * palette.len, .type = { 'P', 'L', 'T', 'E' } }; + writeChunk(plte); + writeExpect(palette.entries, plte.size); + writeCrc(); +} + static uint8_t *data; static void readData(void) { @@ -392,7 +428,7 @@ static void discardAlpha(void) { } static void discardColor(void) { - if (!(header.color & TRUECOLOR)) return; + if (header.color != TRUECOLOR && header.color != TRUECOLOR_ALPHA) return; size_t sampleSize = header.depth / 8; size_t pixelSize = ((header.color & ALPHA) ? 4 : 3) * sampleSize; for (uint32_t y = 0; y < header.height; ++y) { @@ -455,6 +491,7 @@ static void optimize(const char *inPath, const char *outPath) { path, header.interlace ); } + if (header.color == INDEXED) readPalette(); readData(); int error = fclose(file); @@ -478,6 +515,7 @@ static void optimize(const char *inPath, const char *outPath) { writeSignature(); writeHeader(); + if (header.color == INDEXED) writePalette(); writeData(); writeEnd(); free(data); -- cgit 1.4.1