From 1b3c340d73f81f2df36eba72d9a0c7810f68ac83 Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Wed, 14 Feb 2018 14:52:53 -0500 Subject: Replace pngChunk with glorious C metaprogramming --- bin/gfxx.c | 57 ++++++++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) (limited to 'bin/gfxx.c') diff --git a/bin/gfxx.c b/bin/gfxx.c index 50de64c9..4674c82f 100644 --- a/bin/gfxx.c +++ b/bin/gfxx.c @@ -28,9 +28,9 @@ #include #include -#define RGB(r,g,b) ((uint32_t)(r) << 16 | (uint32_t)(g) << 8 | (uint32_t)(b)) -#define GRAY(n) RGB(n, n, n) -#define MASK(b) ((1 << (b)) - 1) +#define RGB(r, g, b) ((uint32_t)(r) << 16 | (uint32_t)(g) << 8 | (uint32_t)(b)) +#define GRAY(n) RGB(n, n, n) +#define MASK(b) ((1 << (b)) - 1) static enum { COLOR_INDEXED, @@ -302,11 +302,12 @@ 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); -} + +#define ONCE(before, after) for (int _once = ((before), 1); _once; (after), --_once) +#define PNG_CHUNK(type, size) ONCE( \ + (pngUint32((size)), crc = crc32(0, Z_NULL, 0), pngWrite((type), 4)), \ + pngUint32(crc) \ +) static void pngDump(uint32_t *src, size_t srcWidth, size_t srcHeight) { int error; @@ -337,31 +338,25 @@ static void pngDump(uint32_t *src, size_t srcWidth, size_t srcHeight) { const uint8_t HEADER[] = { 8, 2, 0, 0, 0 }; // 8-bit RGB const char SOFTWARE[] = "Software"; - 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); - pngUint32(srcHeight); - pngWrite(HEADER, sizeof(HEADER)); - pngUint32(crc); - formatOptions(); - pngChunk("tEXt", sizeof(SOFTWARE) + strlen(options)); - pngWrite(SOFTWARE, sizeof(SOFTWARE)); - pngWrite(options, strlen(options)); - pngUint32(crc); - - pngChunk("sBIT", 3); - pngWrite(&bits[R], 3); - pngUint32(crc); - pngChunk("IDAT", dataSize); - pngWrite(data, dataSize); - pngUint32(crc); - - pngChunk("IEND", 0); - pngUint32(crc); + pngWrite(SIGNATURE, sizeof(SIGNATURE)); + PNG_CHUNK("IHDR", 4 + 4 + sizeof(HEADER)) { + pngUint32(srcWidth); + pngUint32(srcHeight); + pngWrite(HEADER, sizeof(HEADER)); + } + PNG_CHUNK("tEXt", sizeof(SOFTWARE) + strlen(options)) { + pngWrite(SOFTWARE, sizeof(SOFTWARE)); + pngWrite(options, strlen(options)); + } + PNG_CHUNK("sBIT", 3) { + pngWrite(&bits[R], 3); + } + PNG_CHUNK("IDAT", dataSize) { + pngWrite(data, dataSize); + } + PNG_CHUNK("IEND", 0); error = fclose(png); if (error) err(EX_IOERR, "%s", pngPath); -- cgit 1.4.1