summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bin/pngo.c63
1 files changed, 53 insertions, 10 deletions
diff --git a/bin/pngo.c b/bin/pngo.c
index 8f279e8a..4db0d11d 100644
--- a/bin/pngo.c
+++ b/bin/pngo.c
@@ -366,15 +366,12 @@ static void filterData(void) {
 
 static void eliminateAlpha(void) {
     if (!(header.color & ALPHA)) return;
-
-    size_t pixelSize = lineSize() / header.width;
-    size_t alphaSize = header.depth / 8;
-    size_t colorSize = pixelSize - alphaSize;
-
+    size_t sampleSize = header.depth / 8;
+    size_t pixelSize = 4 * sampleSize;
     for (uint32_t y = 0; y < header.height; ++y) {
         for (uint32_t x = 0; x < header.width; ++x) {
-            for (size_t i = 0; i < alphaSize; ++i) {
-                if (lines[y].data[x * pixelSize + colorSize + i] != 0xFF) return;
+            for (size_t i = 0; i < sampleSize; ++i) {
+                if (lines[y].data[x * pixelSize + 3 * sampleSize + i] != 0xFF) return;
             }
         }
     }
@@ -385,16 +382,61 @@ static void eliminateAlpha(void) {
         uint8_t *data = ptr;
         *type = *lines[y].type;
         for (uint32_t x = 0; x < header.width; ++x) {
-            memcpy(ptr, &lines[y].data[x * pixelSize], colorSize);
-            ptr += colorSize;
+            memcpy(ptr, &lines[y].data[x * pixelSize], 3 * sampleSize);
+            ptr += 3 * sampleSize;
         }
         lines[y].type = type;
         lines[y].data = data;
     }
-
     header.color &= ~ALPHA;
 }
 
+static void eliminateColor(void) {
+    if (!(header.color & TRUECOLOR)) 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) {
+        for (uint32_t x = 0; x < header.width; ++x) {
+            if (
+                0 != memcmp(
+                    &lines[y].data[x * pixelSize],
+                    &lines[y].data[x * pixelSize + 1 * sampleSize],
+                    sampleSize
+                )
+            ) return;
+            if (
+                0 != memcmp(
+                    &lines[y].data[x * pixelSize + 1 * sampleSize],
+                    &lines[y].data[x * pixelSize + 2 * sampleSize],
+                    sampleSize
+                )
+            ) return;
+        }
+    }
+
+    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) {
+            memcpy(ptr, &lines[y].data[x * pixelSize], sampleSize);
+            ptr += sampleSize;
+            if (header.color & ALPHA) {
+                memcpy(
+                    ptr,
+                    &lines[y].data[x * pixelSize + 3 * sampleSize],
+                    sampleSize
+                );
+                ptr += sampleSize;
+            }
+        }
+        lines[y].type = type;
+        lines[y].data = data;
+    }
+    header.color &= ~TRUECOLOR;
+}
+
 static void optimize(const char *inPath, const char *outPath) {
     if (inPath) {
         path = inPath;
@@ -421,6 +463,7 @@ static void optimize(const char *inPath, const char *outPath) {
     scanlines();
     reconData();
     eliminateAlpha();
+    eliminateColor();
     filterData();
     free(lines);
 
ne McEnroe 2021-09-21Recalculate various lengths only as neededJune McEnroe This actually speeds things up quite a bit, saving roughly a second on a big PNG screenshot. Almost all the remaining time is spent in deflate. 2021-09-21Rewrite pngo, add explicit optionsJune McEnroe Interesting to see how my code habits have changed. 2021-09-16Fix /* **/ comment matchingJune McEnroe 2021-09-15Remove typer, add downgrade to READMEJune McEnroe 2021-09-15Set bot mode on downgradeJune McEnroe 2021-09-15Enter capsicum in downgradeJune McEnroe 2021-09-15Factor out common parts of downgrade messagesJune McEnroe Also bump the message cap to 1024 because that is ostensibly useful for replying to older messages. 2021-09-14Add downgrade IRC botJune McEnroe 2021-09-14Sort by title if authors matchJune McEnroe There are probably better things to sort by but title definitely always exists. 2021-09-13Swap-remove tags as they're foundJune McEnroe This makes it even faster. From ~1s on a sqlite3.c amalgamation to ~0.85s. 2021-09-12Replace htagml regex with strncmpJune McEnroe Since ctags only ever produces regular expressions of the form /^re$/ or /^re/ with no other special characters, instead unescape the pattern and simply use strncmp. Running on a sqlite3.c amalgamation, the regex version takes ~37s while the strncmp version takes ~1s, producing identical output. Big win! 2021-09-11Also defer printing comment for lone close-parensJune McEnroe 2021-09-10Publish "git-comment"June McEnroe 2021-09-10Add git comment --pretty optionJune McEnroe 2021-09-08Defer printing comment if line is blank or closing braceJune McEnroe This fixes badly indented comments. 2021-09-08Up default min-repeat to 30 linesJune McEnroe 2021-09-08Handle dirty lines in git-commentJune McEnroe 2021-09-08Document and install git-commentJune McEnroe 2021-09-08Add repeat and all options to git-commentJune McEnroe 2021-09-08Add group threshold to git-commentJune McEnroe