Browse Source

Factor out png.h

June 1 month ago
parent
commit
5e7fd9112e
Signed by: Curtis McEnroe <june@causal.agency> GPG Key ID: CEA2F97ADCFCD77C
4 changed files with 121 additions and 92 deletions
  1. 2
    0
      bin/Makefile
  2. 92
    0
      bin/png.h
  3. 10
    41
      bin/psf2png.c
  4. 17
    51
      bin/scheme.c

+ 2
- 0
bin/Makefile View File

@@ -54,6 +54,8 @@ scheme.h: scheme
54 54
 open pbcopy pbpaste: pbd
55 55
 	ln -f pbd $@
56 56
 
57
+psf2png.o scheme.o: png.h
58
+
57 59
 scheme.png: scheme
58 60
 	./scheme -t -g > scheme.png
59 61
 

+ 92
- 0
bin/png.h View File

@@ -0,0 +1,92 @@
1
+/* Copyright (C) 2018  Curtis McEnroe <june@causal.agency>
2
+ *
3
+ * This program is free software: you can redistribute it and/or modify
4
+ * it under the terms of the GNU Affero General Public License as published by
5
+ * the Free Software Foundation, either version 3 of the License, or
6
+ * (at your option) any later version.
7
+ *
8
+ * This program is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+ * GNU Affero General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
+ */
16
+
17
+#include <arpa/inet.h>
18
+#include <err.h>
19
+#include <stdint.h>
20
+#include <stdio.h>
21
+#include <stdlib.h>
22
+#include <sysexits.h>
23
+#include <zlib.h>
24
+
25
+enum {
26
+	PNGGrayscale,
27
+	PNGTruecolor = 2,
28
+	PNGIndexed,
29
+	PNGAlpha,
30
+};
31
+
32
+enum {
33
+	PNGNone,
34
+	PNGSub,
35
+	PNGUp,
36
+	PNGAverage,
37
+	PNGPaeth,
38
+};
39
+
40
+static uint32_t pngCRC;
41
+static inline void pngWrite(FILE *file, const void *ptr, size_t len) {
42
+	if (!fwrite(ptr, len, 1, file)) err(EX_IOERR, "pngWrite");
43
+	pngCRC = crc32(pngCRC, ptr, len);
44
+}
45
+static inline void pngInt32(FILE *file, uint32_t n) {
46
+	n = htonl(n);
47
+	pngWrite(file, &n, 4);
48
+}
49
+static inline void pngChunk(FILE *file, char type[static 4], uint32_t len) {
50
+	pngInt32(file, len);
51
+	pngCRC = crc32(0, Z_NULL, 0);
52
+	pngWrite(file, type, 4);
53
+}
54
+
55
+static inline void pngHead(
56
+	FILE *file, uint32_t width, uint32_t height, uint8_t depth, uint8_t color
57
+) {
58
+	pngWrite(file, "\x89PNG\r\n\x1A\n", 8);
59
+	pngChunk(file, "IHDR", 13);
60
+	pngInt32(file, width);
61
+	pngInt32(file, height);
62
+	pngWrite(file, &depth, 1);
63
+	pngWrite(file, &color, 1);
64
+	pngWrite(file, "\0\0\0", 3);
65
+	pngInt32(file, pngCRC);
66
+}
67
+
68
+static inline void pngPalette(FILE *file, const uint8_t *pal, uint32_t len) {
69
+	pngChunk(file, "PLTE", len);
70
+	pngWrite(file, pal, len);
71
+	pngInt32(file, pngCRC);
72
+}
73
+
74
+static inline void pngData(FILE *file, const uint8_t *data, uint32_t len) {
75
+	uLong zlen = compressBound(len);
76
+	uint8_t *zdata = malloc(zlen);
77
+	if (!zlen) err(EX_OSERR, "malloc");
78
+
79
+	int error = compress(zdata, &zlen, data, len);
80
+	if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error);
81
+
82
+	pngChunk(file, "IDAT", zlen);
83
+	pngWrite(file, zdata, zlen);
84
+	pngInt32(file, pngCRC);
85
+
86
+	free(zdata);
87
+}
88
+
89
+static inline void pngTail(FILE *file) {
90
+	pngChunk(file, "IEND", 0);
91
+	pngInt32(file, pngCRC);
92
+}

+ 10
- 41
bin/psf2png.c View File

@@ -14,7 +14,6 @@
14 14
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15 15
  */
16 16
 
17
-#include <arpa/inet.h>
18 17
 #include <err.h>
19 18
 #include <stdint.h>
20 19
 #include <stdio.h>
@@ -22,23 +21,8 @@
22 21
 #include <string.h>
23 22
 #include <sysexits.h>
24 23
 #include <unistd.h>
25
-#include <zlib.h>
26 24
 
27
-static uint32_t crc;
28
-static void pngWrite(const void *ptr, size_t size) {
29
-	fwrite(ptr, size, 1, stdout);
30
-	if (ferror(stdout)) err(EX_IOERR, "(stdout)");
31
-	crc = crc32(crc, ptr, size);
32
-}
33
-static void pngInt(uint32_t host) {
34
-	uint32_t net = htonl(host);
35
-	pngWrite(&net, 4);
36
-}
37
-static void pngChunk(const char *type, uint32_t size) {
38
-	pngInt(size);
39
-	crc = crc32(0, Z_NULL, 0);
40
-	pngWrite(type, 4);
41
-}
25
+#include "png.h"
42 26
 
43 27
 int main(int argc, char *argv[]) {
44 28
 	uint32_t cols = 32;
@@ -91,26 +75,20 @@ int main(int argc, char *argv[]) {
91 75
 	}
92 76
 	fclose(file);
93 77
 
94
-	pngWrite("\x89PNG\r\n\x1A\n", 8);
95
-
96 78
 	uint32_t count = (str ? strlen(str) : header.glyph.len);
97 79
 	uint32_t width = header.glyph.width * cols;
98 80
 	uint32_t rows = (count + cols - 1) / cols;
99 81
 	uint32_t height = header.glyph.height * rows;
100 82
 
101
-	pngChunk("IHDR", 13);
102
-	pngInt(width);
103
-	pngInt(height);
104
-	pngWrite("\x08\x03\x00\x00\x00", 5);
105
-	pngInt(crc);
106
-
107
-	pngChunk("PLTE", 6);
108
-	pngWrite((uint8_t[]) { bg >> 16, bg >> 8, bg }, 3);
109
-	pngWrite((uint8_t[]) { fg >> 16, fg >> 8, fg }, 3);
110
-	pngInt(crc);
83
+	pngHead(stdout, width, height, 8, PNGIndexed);
84
+	uint8_t pal[] = {
85
+		bg >> 16, bg >> 8, bg,
86
+		fg >> 16, fg >> 8, fg,
87
+	};
88
+	pngPalette(stdout, pal, sizeof(pal));
111 89
 
112 90
 	uint8_t data[height][1 + width];
113
-	memset(data, 0, sizeof(data));
91
+	memset(data, PNGNone, sizeof(data));
114 92
 
115 93
 	for (uint32_t i = 0; i < count; ++i) {
116 94
 		uint32_t row = header.glyph.height * (i / cols);
@@ -124,15 +102,6 @@ int main(int argc, char *argv[]) {
124 102
 		}
125 103
 	}
126 104
 
127
-	uLong size = compressBound(sizeof(data));
128
-	uint8_t deflate[size];
129
-	int error = compress(deflate, &size, (Byte *)data, sizeof(data));
130
-	if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error);
131
-
132
-	pngChunk("IDAT", size);
133
-	pngWrite(deflate, size);
134
-	pngInt(crc);
135
-
136
-	pngChunk("IEND", 0);
137
-	pngInt(crc);
105
+	pngData(stdout, (uint8_t *)data, sizeof(data));
106
+	pngTail(stdout);
138 107
 }

+ 17
- 51
bin/scheme.c View File

@@ -14,16 +14,15 @@
14 14
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15 15
  */
16 16
 
17
-#include <arpa/inet.h>
18 17
 #include <err.h>
19 18
 #include <math.h>
20
-#include <stdint.h>
21 19
 #include <stdio.h>
22 20
 #include <stdlib.h>
23 21
 #include <string.h>
24 22
 #include <sysexits.h>
25 23
 #include <unistd.h>
26
-#include <zlib.h>
24
+
25
+#include "png.h"
27 26
 
28 27
 typedef unsigned uint;
29 28
 typedef unsigned char byte;
@@ -188,53 +187,29 @@ static void printMintty(uint n) {
188 187
 	printf("%s=%hhd,%hhd,%hhd\n", MinttyNames[n], rgb.r, rgb.g, rgb.b);
189 188
 }
190 189
 
191
-static uint32_t crc;
192
-static void pngWrite(const void *ptr, size_t size) {
193
-	fwrite(ptr, size, 1, stdout);
194
-	if (ferror(stdout)) err(EX_IOERR, "(stdout)");
195
-	crc = crc32(crc, ptr, size);
196
-}
197
-static void pngInt(uint32_t host) {
198
-	uint32_t net = htonl(host);
199
-	pngWrite(&net, 4);
200
-}
201
-static void pngChunk(const char *type, uint32_t size) {
202
-	pngInt(size);
203
-	crc = crc32(0, Z_NULL, 0);
204
-	pngWrite(type, 4);
205
-}
206
-
207 190
 static void png(uint at, uint to) {
208 191
 	if (to - at > 256) to = at + 256;
209 192
 
210
-	uint32_t len = to - at;
211
-	uint32_t swatchWidth = 64;
212
-	uint32_t swatchHeight = 64;
213
-	uint32_t cols = 8;
214
-	uint32_t rows = (len + cols - 1) / cols;
215
-	uint32_t width = swatchWidth * cols;
216
-	uint32_t height = swatchHeight * rows;
193
+	uint len = to - at;
194
+	uint swatchWidth = 64;
195
+	uint swatchHeight = 64;
196
+	uint cols = 8;
197
+	uint rows = (len + cols - 1) / cols;
198
+	uint width = swatchWidth * cols;
199
+	uint height = swatchHeight * rows;
217 200
 
218
-	pngWrite("\x89PNG\r\n\x1A\n", 8);
201
+	pngHead(stdout, width, height, 8, PNGIndexed);
219 202
 
220
-	pngChunk("IHDR", 13);
221
-	pngInt(width);
222
-	pngInt(height);
223
-	pngWrite("\x08\x03\x00\x00\x00", 5);
224
-	pngInt(crc);
225
-
226
-	pngChunk("PLTE", 3 * len);
227
-	for (uint i = at; i < to; ++i) {
228
-		struct RGB rgb = toRGB(scheme[i]);
229
-		pngWrite(&rgb, 3);
203
+	struct RGB rgb[len];
204
+	for (uint i = 0; i < len; ++i) {
205
+		rgb[i] = toRGB(scheme[at + i]);
230 206
 	}
231
-	pngInt(crc);
207
+	pngPalette(stdout, (byte *)rgb, sizeof(rgb));
232 208
 
233 209
 	uint8_t data[height][1 + width];
234 210
 	memset(data, 0, sizeof(data));
235 211
 	for (uint32_t y = 0; y < height; ++y) {
236
-		enum { None, Sub, Up, Average, Paeth };
237
-		data[y][0] = (y % swatchHeight) ? Up : Sub;
212
+		data[y][0] = (y % swatchHeight) ? PNGUp : PNGSub;
238 213
 	}
239 214
 	for (uint i = at; i < to; ++i) {
240 215
 		uint p = i - at;
@@ -243,17 +218,8 @@ static void png(uint at, uint to) {
243 218
 		data[y][1 + x] = x ? 1 : p;
244 219
 	}
245 220
 
246
-	uLong size = compressBound(sizeof(data));
247
-	byte deflate[size];
248
-	int error = compress(deflate, &size, (byte *)data, sizeof(data));
249
-	if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error);
250
-
251
-	pngChunk("IDAT", size);
252
-	pngWrite(deflate, size);
253
-	pngInt(crc);
254
-
255
-	pngChunk("IEND", 0);
256
-	pngInt(crc);
221
+	pngData(stdout, (byte *)data, sizeof(data));
222
+	pngTail(stdout);
257 223
 }
258 224
 
259 225
 static void print(void (*fn)(uint), uint at, uint to) {

Loading…
Cancel
Save