summary refs log tree commit diff
path: root/bin/pngo.c
diff options
context:
space:
mode:
authorJune McEnroe <programble@gmail.com>2018-02-19 01:01:35 -0500
committerJune McEnroe <programble@gmail.com>2018-02-19 01:01:35 -0500
commit192d17390f5c82a7fa2c9b9eb4a71f412f012e3b (patch)
tree035764ad3516b23556a74190e6868db673eb09af /bin/pngo.c
parentRead and write palette in pngo (diff)
downloadsrc-192d17390f5c82a7fa2c9b9eb4a71f412f012e3b.tar.gz
src-192d17390f5c82a7fa2c9b9eb4a71f412f012e3b.zip
Index color if possible in pngo
Diffstat (limited to 'bin/pngo.c')
-rw-r--r--bin/pngo.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/bin/pngo.c b/bin/pngo.c
index 3522eb82..95252fff 100644
--- a/bin/pngo.c
+++ b/bin/pngo.c
@@ -197,9 +197,7 @@ static void writeHeader(void) {
 
 static struct {
     uint32_t len;
-    struct PACKED {
-        uint8_t r, g, b;
-    } entries[256];
+    uint8_t entries[256][3];
 } palette;
 
 static void readPalette(void) {
@@ -473,6 +471,43 @@ static void discardColor(void) {
     header.color &= ~TRUECOLOR;
 }
 
+static void indexColor(void) {
+    if (header.color != TRUECOLOR || header.depth != 8) return;
+    for (uint32_t y = 0; y < header.height; ++y) {
+        for (uint32_t x = 0; x < header.width; ++x) {
+            uint32_t i;
+            for (i = 0; i < palette.len; ++i) {
+                if (0 == memcmp(palette.entries[i], &lines[y].data[x * 3], 3)) {
+                    break;
+                }
+            }
+            if (i < palette.len) continue;
+            if (palette.len == 256) return;
+            memcpy(palette.entries[i], &lines[y].data[x * 3], 3);
+            palette.len++;
+        }
+    }
+
+    uint8_t *ptr = data;
+    for (uint32_t y = 0; y < header.height; ++y) {
+        uint8_t *type = ptr++;
+        uint8_t *data = ptr;
+        *type = *lines[y].type;
+        for (uint32_t x = 0; x < header.width; ++x) {
+            uint32_t i;
+            for (i = 0; i < palette.len; ++i) {
+                if (0 == memcmp(palette.entries[i], &lines[y].data[x * 3], 3)) {
+                    break;
+                }
+            }
+            *ptr++ = i;
+        }
+        lines[y].type = type;
+        lines[y].data = data;
+    }
+    header.color = INDEXED;
+}
+
 static void optimize(const char *inPath, const char *outPath) {
     if (inPath) {
         path = inPath;
@@ -501,6 +536,7 @@ static void optimize(const char *inPath, const char *outPath) {
     reconData();
     discardAlpha();
     discardColor();
+    indexColor();
     filterData();
     free(lines);