farbfeld

suckless image format with conversion tools
git clone git://git.suckless.org/farbfeld
Log | Files | Refs | README | LICENSE

commit 9fdfff98f15fb3f7a01d944aba5d75d9d34c66ed
parent 781cec031d8ebc40b36cf06e7c3bf1080745e1d2
Author: Laslo Hunhold <dev@frign.de>
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:
Mfarbfeld.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 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@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