Refactor invert.c in farbfeld.5 - farbfeld - suckless image format with convers… | |
git clone git://git.suckless.org/farbfeld | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 9fdfff98f15fb3f7a01d944aba5d75d9d34c66ed | |
parent 781cec031d8ebc40b36cf06e7c3bf1080745e1d2 | |
Author: Laslo Hunhold <[email protected]> | |
Date: Fri, 14 Apr 2017 21:40:20 +0200 | |
Refactor invert.c in farbfeld.5 | |
I noticed that it would be beneficial to release the invert.c code | |
listing under a very permissive license. | |
I like the style of the "Copy me if you can"-License, but thought | |
that 0BSD would make it even clearer that everyone can do whatever | |
he wants with this code. | |
The code itself was not bad beforehand, but lacked some elementary | |
features like checked flushing at the end and proper error messages. | |
I also reworked the data structures a bit to make it more appealing | |
and clearer where the "guts" of the code are (i.e. in invert()). | |
Diffstat: | |
M farbfeld.5 | 101 ++++++++++++++++++++++-------… | |
1 file changed, 73 insertions(+), 28 deletions(-) | |
--- | |
diff --git a/farbfeld.5 b/farbfeld.5 | |
@@ -52,72 +52,117 @@ and inherent complexity involved in handling common image … | |
(PNG, JPEG, GIF,...), having to rely on bloated libraries while not being | |
able to focus on the task at hand for a given image processing problem. | |
.Sh EXAMPLES | |
-Below is an example for a color inverter usable in a pipeline. No external | |
-libraries other than libc are needed to handle the image data: | |
+The following code listing | |
+.Em invert.c | |
+is a ready-to-use color inverter with all necessary error handling and | |
+reporting. This program can be integrated into a farbfeld pipeline as | |
+follows: | |
+.Pp | |
+$ png2ff < image.png | invert | ff2png > image-inverted.png | |
+.Pp | |
+It shall be noted here that due to the simplicity of the format no | |
+external libraries are needed to handle the farbfeld image data. The | |
+0BSD-License gives you the freedom to throw away the license block and | |
+just use the code as you wish. Happy hacking! | |
.Bd -literal -offset left | |
+/* | |
+ * 0BSD-License | |
+ * | |
+ * (c) 2017 Laslo Hunhold <[email protected]> | |
+ * | |
+ * Permission to use, copy, modify, and/or distribute this software for | |
+ * any purpose with or without fee is hereby granted. | |
+ * | |
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL | |
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED | |
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE | |
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | |
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
+ * PERFORMANCE OF THIS SOFTWARE. | |
+ */ | |
#include <arpa/inet.h> | |
+#include <errno.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
-#include <stdlib.h> | |
#include <string.h> | |
+#define LEN(x) (sizeof (x) / sizeof *(x)) | |
+ | |
+static void | |
+invert(uint16_t rgba[4]) | |
+{ | |
+ rgba[0] = UINT16_MAX - rgba[0]; | |
+ rgba[1] = UINT16_MAX - rgba[1]; | |
+ rgba[2] = UINT16_MAX - rgba[2]; | |
+} | |
+ | |
int | |
main(int argc, char *argv[]) | |
{ | |
- uint32_t width, height, i, j, k; | |
+ uint32_t hdr[4], width, height, i, j, k; | |
uint16_t rgba[4]; | |
- uint8_t hdr[strlen("farbfeld") + 2 * sizeof(uint32_t)]; | |
- if (argc > 1) { | |
+ /* arguments */ | |
+ if (argc != 1) { | |
fprintf(stderr, "usage: %s\\n", argv[0]); | |
return 1; | |
} | |
- if (fread(hdr, 1, sizeof(hdr), stdin) != sizeof(hdr)) { | |
- fprintf(stderr, "incomplete header\\n"); | |
- return 1; | |
+ /* read header */ | |
+ if (fread(hdr, sizeof(*hdr), LEN(hdr), stdin) != LEN(hdr)) { | |
+ goto readerr; | |
} | |
- if (memcmp("farbfeld", hdr, strlen("farbfeld"))) { | |
- fprintf(stderr, "invalid magic\\n"); | |
+ if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) { | |
+ fprintf(stderr, "%s: invalid magic value\\n", argv[0]); | |
return 1; | |
} | |
- width = ntohl(*((uint32_t *)(hdr + 8))); | |
- height = ntohl(*((uint32_t *)(hdr + 12))); | |
+ width = ntohl(hdr[2]); | |
+ height = ntohl(hdr[3]); | |
- if (fwrite(hdr, 1, sizeof(hdr), stdout) != sizeof(hdr)) { | |
- fprintf(stderr, "write error\\n"); | |
- return 1; | |
+ /* write data */ | |
+ if (fwrite(hdr, sizeof(*hdr), LEN(hdr), stdout) != 4) { | |
+ goto writerr; | |
} | |
for (i = 0; i < height; i++) { | |
for (j = 0; j < width; j++) { | |
- if (fread(rgba, sizeof(uint16_t), 4, | |
- stdin) != 4) { | |
- fprintf(stderr, "unexpected EOF\\n"); | |
- return 1; | |
+ if (fread(rgba, sizeof(*rgba), LEN(rgba), | |
+ stdin) != LEN(rgba)) { | |
+ goto readerr; | |
} | |
for (k = 0; k < 4; k++) { | |
rgba[k] = ntohs(rgba[k]); | |
} | |
- /* invert colors */ | |
- rgba[0] = 65535 - rgba[0]; | |
- rgba[1] = 65535 - rgba[1]; | |
- rgba[2] = 65535 - rgba[2]; | |
+ invert(rgba); | |
for (k = 0; k < 4; k++) { | |
rgba[k] = htons(rgba[k]); | |
} | |
- if (fwrite(rgba, sizeof(uint16_t), 4, | |
- stdout) != 4) { | |
- fprintf(stderr, "write error\\n"); | |
- return 1; | |
+ if (fwrite(rgba, sizeof(*rgba), LEN(rgba), | |
+ stdout) != LEN(rgba)) { | |
+ goto writerr; | |
} | |
} | |
} | |
+ /* clean up */ | |
+ if (fclose(stdout)) { | |
+ fprintf(stderr, "%s: fclose: %s\\n", argv[0], | |
+ strerror(errno)); | |
+ return 1; | |
+ } | |
+ | |
return 0; | |
+readerr: | |
+ fprintf(stderr, "%s: fread: Unexpected EOF\\n", argv[0]); | |
+ return 1; | |
+writerr: | |
+ fprintf(stderr, "%s: fwrite: %s\\n", argv[0], strerror(errno)); | |
+ return 1; | |
} | |
.Ed | |
.Sh SEE ALSO |