diff options
Diffstat (limited to '')
-rw-r--r-- | bin/.gitignore | 2 | ||||
-rw-r--r-- | bin/Makefile | 2 | ||||
-rw-r--r-- | bin/gfxx.c | 34 | ||||
-rw-r--r-- | bin/pngs.c | 75 |
4 files changed, 25 insertions, 88 deletions
diff --git a/bin/.gitignore b/bin/.gitignore index cb1d47f3..1a3b29fa 100644 --- a/bin/.gitignore +++ b/bin/.gitignore @@ -7,12 +7,10 @@ hnel pbcopy pbd pbpaste -pngs wake xx jrp klon -typo watch bri fbatt diff --git a/bin/Makefile b/bin/Makefile index 9834dac6..9835cb57 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -1,4 +1,4 @@ -ANY_BINS = atch dtch gfxx hnel pbcopy pbd pbpaste pngs wake xx +ANY_BINS = atch dtch gfxx hnel pbcopy pbd pbpaste wake xx BSD_BINS = jrp klon watch LIN_BINS = bri fbatt fbclock ALL_BINS = $(ANY_BINS) $(BSD_BINS) $(LIN_BINS) diff --git a/bin/gfxx.c b/bin/gfxx.c index 1138c696..50de64c9 100644 --- a/bin/gfxx.c +++ b/bin/gfxx.c @@ -57,6 +57,8 @@ static bool flip; static bool mirror; static size_t scale = 1; +static const char *prefix = "gfxx"; + static size_t size; static uint8_t *data; @@ -65,7 +67,7 @@ int init(int argc, char *argv[]) { const char *path = NULL; int opt; - while (0 < (opt = getopt(argc, argv, "c:p:b:e:E:n:fmw:z:"))) { + while (0 < (opt = getopt(argc, argv, "c:p:b:e:E:n:fmw:z:o:"))) { switch (opt) { case 'c': switch (optarg[0]) { case 'i': space = COLOR_INDEXED; break; @@ -95,6 +97,7 @@ int init(int argc, char *argv[]) { case 'm': mirror ^= true; break; case 'w': width = strtoul(optarg, NULL, 0); break; case 'z': scale = strtoul(optarg, NULL, 0); break; + case 'o': prefix = optarg; break; default: return EX_USAGE; } } @@ -285,25 +288,29 @@ static void drawBytes(struct Iter *it) { } } +static unsigned counter = 1; +static char pngPath[FILENAME_MAX]; +static FILE *png; + static uint32_t crc; static void pngWrite(const void *data, size_t size) { crc = crc32(crc, data, size); - size_t count = fwrite(data, 1, size, stdout); - if (count < size) err(EX_IOERR, "stdout"); + size_t count = fwrite(data, 1, size, png); + if (count < size) err(EX_IOERR, "%s", pngPath); } - static void pngUint32(uint32_t data) { uint32_t net = htonl(data); pngWrite(&net, 4); } - static void pngChunk(const char *type, uint32_t size) { pngUint32(size); crc = crc32(0, Z_NULL, 0); pngWrite(type, 4); } -static void pngEncode(uint32_t *src, size_t srcWidth, size_t srcHeight) { +static void pngDump(uint32_t *src, size_t srcWidth, size_t srcHeight) { + int error; + size_t scanline = 1 + 3 * srcWidth; uint8_t filt[scanline * srcHeight]; for (size_t y = 0; y < srcHeight; ++y) { @@ -319,15 +326,19 @@ static void pngEncode(uint32_t *src, size_t srcWidth, size_t srcHeight) { size_t dataSize = compressBound(sizeof(filt)); uint8_t data[dataSize]; - int error = compress(data, &dataSize, filt, sizeof(filt)); + error = compress(data, &dataSize, filt, sizeof(filt)); if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error); + snprintf(pngPath, sizeof(pngPath), "%s%04u.png", prefix, counter++); + png = fopen(pngPath, "wx"); + if (!png) err(EX_CANTCREAT, "%s", pngPath); + const uint8_t SIGNATURE[] = { 0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n' }; const uint8_t HEADER[] = { 8, 2, 0, 0, 0 }; // 8-bit RGB const char SOFTWARE[] = "Software"; - size_t count = fwrite(SIGNATURE, sizeof(SIGNATURE), 1, stdout); - if (count < 1) err(EX_IOERR, "stdout"); + size_t count = fwrite(SIGNATURE, sizeof(SIGNATURE), 1, png); + if (count < 1) err(EX_IOERR, "%s", pngPath); pngChunk("IHDR", 4 + 4 + sizeof(HEADER)); pngUint32(srcWidth); @@ -351,6 +362,9 @@ static void pngEncode(uint32_t *src, size_t srcWidth, size_t srcHeight) { pngChunk("IEND", 0); pngUint32(crc); + + error = fclose(png); + if (error) err(EX_IOERR, "%s", pngPath); } static bool dump; @@ -363,7 +377,7 @@ void draw(uint32_t *buf, size_t bufWidth, size_t bufHeight) { } else { drawBits(&it); } - if (dump) pngEncode(buf, bufWidth, bufHeight); + if (dump) pngDump(buf, bufWidth, bufHeight); dump = false; } diff --git a/bin/pngs.c b/bin/pngs.c deleted file mode 100644 index b0768d64..00000000 --- a/bin/pngs.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2018, Curtis McEnroe <programble@gmail.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <err.h> -#include <fcntl.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sysexits.h> -#include <unistd.h> - -static const uint8_t SIGNATURE[] = { 0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n' }; -static const uint8_t IEND[] = { 'I', 'E', 'N', 'D' }; - -static unsigned counter; -static char path[FILENAME_MAX]; -static int fd; - -static void next(const char *prefix) { - if (counter++) { - int error = close(fd); - if (error) err(EX_IOERR, "%s", path); - } - snprintf(path, sizeof(path), "%s%04u.png", prefix, counter); - fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0644); - if (fd < 0) err(EX_CANTCREAT, "%s", path); - printf("%s\n", path); -} - -static void writeAll(const uint8_t *buf, size_t size) { - while (size) { - ssize_t writeSize = write(fd, buf, size); - if (writeSize < 0) err(EX_IOERR, "%s", path); - buf += writeSize; - size -= writeSize; - } -} - -int main(int argc, char *argv[]) { - const char *prefix = (argc > 1) ? argv[1] : ""; - - for (;;) { - uint8_t buf[4096]; - ssize_t size = read(STDIN_FILENO, buf, sizeof(buf)); - if (size < 0) err(EX_IOERR, "read"); - if (!size) return EX_OK; - - const uint8_t *signature = memmem(buf, size, SIGNATURE, sizeof(SIGNATURE)); - if (signature) { - writeAll(buf, signature - buf); - next(prefix); - writeAll(signature, size - (signature - buf)); - } else { - const uint8_t *iend = memmem(buf, size, IEND, sizeof(IEND)); - if (iend && iend - buf < size - 8) { - warnx("trailing data, a PNG may be skipped"); - } - writeAll(buf, size); - } - } -} |