[hackers] [farbfeld] Refactor invert.c in farbfeld.5 || Laslo Hunhold

From: <git_AT_suckless.org>
Date: Fri, 14 Apr 2017 21:43:50 +0200 (CEST)

commit 9fdfff98f15fb3f7a01d944aba5d75d9d34c66ed
Author: Laslo Hunhold <dev_AT_frign.de>
AuthorDate: Fri Apr 14 21:40:20 2017 +0200
Commit: Laslo Hunhold <dev_AT_frign.de>
CommitDate: Fri Apr 14 21:42:43 2017 +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()).

diff --git a/farbfeld.5 b/farbfeld.5
index accae57..664075d 100644
--- a/farbfeld.5
+++ b/farbfeld.5
_AT_@ -52,72 +52,117 @@ and inherent complexity involved in handling common image formats
 (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 <dev_AT_frign.de>
+ *
+ * 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
Received on Fri Apr 14 2017 - 21:43:50 CEST

This archive was generated by hypermail 2.3.0 : Fri Apr 14 2017 - 21:48:17 CEST