From 5e7fd9112e3056004f6c1e33ce43a141975dd538 Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Wed, 14 Nov 2018 01:29:53 -0500 Subject: Factor out png.h --- bin/Makefile | 2 ++ bin/png.h | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bin/psf2png.c | 51 +++++++-------------------------- bin/scheme.c | 68 +++++++++++-------------------------------- 4 files changed, 121 insertions(+), 92 deletions(-) create mode 100644 bin/png.h diff --git a/bin/Makefile b/bin/Makefile index d68d1cc5..6b6452aa 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -54,6 +54,8 @@ scheme.h: scheme open pbcopy pbpaste: pbd ln -f pbd $@ +psf2png.o scheme.o: png.h + scheme.png: scheme ./scheme -t -g > scheme.png diff --git a/bin/png.h b/bin/png.h new file mode 100644 index 00000000..05993f87 --- /dev/null +++ b/bin/png.h @@ -0,0 +1,92 @@ +/* Copyright (C) 2018 Curtis McEnroe + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +enum { + PNGGrayscale, + PNGTruecolor = 2, + PNGIndexed, + PNGAlpha, +}; + +enum { + PNGNone, + PNGSub, + PNGUp, + PNGAverage, + PNGPaeth, +}; + +static uint32_t pngCRC; +static inline void pngWrite(FILE *file, const void *ptr, size_t len) { + if (!fwrite(ptr, len, 1, file)) err(EX_IOERR, "pngWrite"); + pngCRC = crc32(pngCRC, ptr, len); +} +static inline void pngInt32(FILE *file, uint32_t n) { + n = htonl(n); + pngWrite(file, &n, 4); +} +static inline void pngChunk(FILE *file, char type[static 4], uint32_t len) { + pngInt32(file, len); + pngCRC = crc32(0, Z_NULL, 0); + pngWrite(file, type, 4); +} + +static inline void pngHead( + FILE *file, uint32_t width, uint32_t height, uint8_t depth, uint8_t color +) { + pngWrite(file, "\x89PNG\r\n\x1A\n", 8); + pngChunk(file, "IHDR", 13); + pngInt32(file, width); + pngInt32(file, height); + pngWrite(file, &depth, 1); + pngWrite(file, &color, 1); + pngWrite(file, "\0\0\0", 3); + pngInt32(file, pngCRC); +} + +static inline void pngPalette(FILE *file, const uint8_t *pal, uint32_t len) { + pngChunk(file, "PLTE", len); + pngWrite(file, pal, len); + pngInt32(file, pngCRC); +} + +static inline void pngData(FILE *file, const uint8_t *data, uint32_t len) { + uLong zlen = compressBound(len); + uint8_t *zdata = malloc(zlen); + if (!zlen) err(EX_OSERR, "malloc"); + + int error = compress(zdata, &zlen, data, len); + if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error); + + pngChunk(file, "IDAT", zlen); + pngWrite(file, zdata, zlen); + pngInt32(file, pngCRC); + + free(zdata); +} + +static inline void pngTail(FILE *file) { + pngChunk(file, "IEND", 0); + pngInt32(file, pngCRC); +} diff --git a/bin/psf2png.c b/bin/psf2png.c index 0ff3c9ac..eedda3b7 100644 --- a/bin/psf2png.c +++ b/bin/psf2png.c @@ -14,7 +14,6 @@ * along with this program. If not, see . */ -#include #include #include #include @@ -22,23 +21,8 @@ #include #include #include -#include -static uint32_t crc; -static void pngWrite(const void *ptr, size_t size) { - fwrite(ptr, size, 1, stdout); - if (ferror(stdout)) err(EX_IOERR, "(stdout)"); - crc = crc32(crc, ptr, size); -} -static void pngInt(uint32_t host) { - uint32_t net = htonl(host); - pngWrite(&net, 4); -} -static void pngChunk(const char *type, uint32_t size) { - pngInt(size); - crc = crc32(0, Z_NULL, 0); - pngWrite(type, 4); -} +#include "png.h" int main(int argc, char *argv[]) { uint32_t cols = 32; @@ -91,26 +75,20 @@ int main(int argc, char *argv[]) { } fclose(file); - pngWrite("\x89PNG\r\n\x1A\n", 8); - uint32_t count = (str ? strlen(str) : header.glyph.len); uint32_t width = header.glyph.width * cols; uint32_t rows = (count + cols - 1) / cols; uint32_t height = header.glyph.height * rows; - pngChunk("IHDR", 13); - pngInt(width); - pngInt(height); - pngWrite("\x08\x03\x00\x00\x00", 5); - pngInt(crc); - - pngChunk("PLTE", 6); - pngWrite((uint8_t[]) { bg >> 16, bg >> 8, bg }, 3); - pngWrite((uint8_t[]) { fg >> 16, fg >> 8, fg }, 3); - pngInt(crc); + pngHead(stdout, width, height, 8, PNGIndexed); + uint8_t pal[] = { + bg >> 16, bg >> 8, bg, + fg >> 16, fg >> 8, fg, + }; + pngPalette(stdout, pal, sizeof(pal)); uint8_t data[height][1 + width]; - memset(data, 0, sizeof(data)); + memset(data, PNGNone, sizeof(data)); for (uint32_t i = 0; i < count; ++i) { uint32_t row = header.glyph.height * (i / cols); @@ -124,15 +102,6 @@ int main(int argc, char *argv[]) { } } - uLong size = compressBound(sizeof(data)); - uint8_t deflate[size]; - int error = compress(deflate, &size, (Byte *)data, sizeof(data)); - if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error); - - pngChunk("IDAT", size); - pngWrite(deflate, size); - pngInt(crc); - - pngChunk("IEND", 0); - pngInt(crc); + pngData(stdout, (uint8_t *)data, sizeof(data)); + pngTail(stdout); } diff --git a/bin/scheme.c b/bin/scheme.c index f4ef180d..adcf7da8 100644 --- a/bin/scheme.c +++ b/bin/scheme.c @@ -14,16 +14,15 @@ * along with this program. If not, see . */ -#include #include #include -#include #include #include #include #include #include -#include + +#include "png.h" typedef unsigned uint; typedef unsigned char byte; @@ -188,53 +187,29 @@ static void printMintty(uint n) { printf("%s=%hhd,%hhd,%hhd\n", MinttyNames[n], rgb.r, rgb.g, rgb.b); } -static uint32_t crc; -static void pngWrite(const void *ptr, size_t size) { - fwrite(ptr, size, 1, stdout); - if (ferror(stdout)) err(EX_IOERR, "(stdout)"); - crc = crc32(crc, ptr, size); -} -static void pngInt(uint32_t host) { - uint32_t net = htonl(host); - pngWrite(&net, 4); -} -static void pngChunk(const char *type, uint32_t size) { - pngInt(size); - crc = crc32(0, Z_NULL, 0); - pngWrite(type, 4); -} - static void png(uint at, uint to) { if (to - at > 256) to = at + 256; - uint32_t len = to - at; - uint32_t swatchWidth = 64; - uint32_t swatchHeight = 64; - uint32_t cols = 8; - uint32_t rows = (len + cols - 1) / cols; - uint32_t width = swatchWidth * cols; - uint32_t height = swatchHeight * rows; + uint len = to - at; + uint swatchWidth = 64; + uint swatchHeight = 64; + uint cols = 8; + uint rows = (len + cols - 1) / cols; + uint width = swatchWidth * cols; + uint height = swatchHeight * rows; - pngWrite("\x89PNG\r\n\x1A\n", 8); + pngHead(stdout, width, height, 8, PNGIndexed); - pngChunk("IHDR", 13); - pngInt(width); - pngInt(height); - pngWrite("\x08\x03\x00\x00\x00", 5); - pngInt(crc); - - pngChunk("PLTE", 3 * len); - for (uint i = at; i < to; ++i) { - struct RGB rgb = toRGB(scheme[i]); - pngWrite(&rgb, 3); + struct RGB rgb[len]; + for (uint i = 0; i < len; ++i) { + rgb[i] = toRGB(scheme[at + i]); } - pngInt(crc); + pngPalette(stdout, (byte *)rgb, sizeof(rgb)); uint8_t data[height][1 + width]; memset(data, 0, sizeof(data)); for (uint32_t y = 0; y < height; ++y) { - enum { None, Sub, Up, Average, Paeth }; - data[y][0] = (y % swatchHeight) ? Up : Sub; + data[y][0] = (y % swatchHeight) ? PNGUp : PNGSub; } for (uint i = at; i < to; ++i) { uint p = i - at; @@ -243,17 +218,8 @@ static void png(uint at, uint to) { data[y][1 + x] = x ? 1 : p; } - uLong size = compressBound(sizeof(data)); - byte deflate[size]; - int error = compress(deflate, &size, (byte *)data, sizeof(data)); - if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error); - - pngChunk("IDAT", size); - pngWrite(deflate, size); - pngInt(crc); - - pngChunk("IEND", 0); - pngInt(crc); + pngData(stdout, (byte *)data, sizeof(data)); + pngTail(stdout); } static void print(void (*fn)(uint), uint at, uint to) { -- cgit 1.4.1