add ff2ppm(1) - farbfeld - suckless image format with conversion tools | |
git clone git://git.suckless.org/farbfeld | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit dc512d040c7d081ed96b1919420aebd646968879 | |
parent e637aae67ededf6a4a0b4d490d02f3294f297b71 | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Mon, 21 Mar 2016 21:06:06 +0100 | |
add ff2ppm(1) | |
ff2ppm can convert farbfeld images to PPM (P6 binary format, 24-bit RGB). | |
ff2ppm has an option -b to set the background color, for example for png files: | |
png2ff < test.png | ff2ppm -b '#00ff00' > test.ppm | |
Diffstat: | |
M Makefile | 7 ++++--- | |
A ff2ppm.1 | 48 +++++++++++++++++++++++++++++… | |
A ff2ppm.c | 125 +++++++++++++++++++++++++++++… | |
3 files changed, 177 insertions(+), 3 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
@@ -2,12 +2,13 @@ | |
# See LICENSE file for copyright and license details | |
include config.mk | |
-BIN = png2ff ff2png jpg2ff | |
+BIN = png2ff ff2png jpg2ff ff2ppm | |
SRC = ${BIN:=.c} | |
+HDR = arg.h | |
MAN1 = 2ff.1 ${BIN:=.1} | |
MAN5 = farbfeld.5 | |
-all: png2ff ff2png jpg2ff | |
+all: png2ff ff2png jpg2ff ff2ppm | |
.c: | |
@echo CC $< | |
@@ -21,7 +22,7 @@ dist: clean | |
@echo creating dist tarball | |
@mkdir -p farbfeld-${VERSION} | |
@cp -R FORMAT LICENSE Makefile README TODO config.mk \ | |
- 2ff ${SRC} ${MAN1} ${MAN5} farbfeld-${VERSION} | |
+ 2ff ${HDR} ${SRC} ${MAN1} ${MAN5} farbfeld-${VERSION} | |
@tar -cf farbfeld-${VERSION}.tar farbfeld-${VERSION} | |
@gzip farbfeld-${VERSION}.tar | |
@rm -rf farbfeld-${VERSION} | |
diff --git a/ff2ppm.1 b/ff2ppm.1 | |
@@ -0,0 +1,48 @@ | |
+.Dd 2016-03-21 | |
+.Dt FF2PPM 1 | |
+.Os suckless.org | |
+.Sh NAME | |
+.Nm ff2ppm | |
+.Nd convert farbfeld to PPM (binary) | |
+.Sh SYNOPSIS | |
+.Nm | |
+.Op Fl b Ar color | |
+.Sh DESCRIPTION | |
+.Nm | |
+reads a | |
+.Xr farbfeld 5 | |
+image from stdin, converts it to a PPM image (P6 binary format, RGB) and | |
+writes the result to stdout. | |
+.Pp | |
+In case of an error | |
+.Nm | |
+writes a diagnostic message to stderr. | |
+.Sh OPTIONS | |
+.Bl -tag -width Ds | |
+.It Fl b Ar color | |
+.Ar color | |
+to mix with the background alpha channel, the default is white. | |
+.Pp | |
+The following formats are supported: | |
+"#rrggbb", "#rrrrggggbbbb" and the short-form "#rgb" which expands to "#rrggbb… | |
+.El | |
+.Sh EXIT STATUS | |
+.Bl -tag -width Ds | |
+.It 0 | |
+Image processed successfully. | |
+.It 1 | |
+An error occurred. | |
+.El | |
+.Sh EXAMPLES | |
+$ | |
+png2ff < test.png | | |
+.Nm | |
+-b '#00ff00' > test.ppm | |
+.Sh SEE ALSO | |
+.Xr 2ff 1 , | |
+.Xr bunzip2 1 , | |
+.Xr bzip2 1 , | |
+.Xr png2ff 1 , | |
+.Xr farbfeld 5 | |
+.Sh AUTHORS | |
+.An Hiltjo Posthuma Aq Mt [email protected] | |
diff --git a/ff2ppm.c b/ff2ppm.c | |
@@ -0,0 +1,125 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include <arpa/inet.h> | |
+ | |
+#include <errno.h> | |
+#include <inttypes.h> | |
+#include <stdint.h> | |
+#include <stdio.h> | |
+#include <stdlib.h> | |
+#include <string.h> | |
+ | |
+#include "arg.h" | |
+ | |
+char *argv0; | |
+ | |
+static void | |
+usage(void) | |
+{ | |
+ fprintf(stderr, "usage: %s [-b #rrggbb]\n", argv0); | |
+ exit(1); | |
+} | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ size_t rowlen; | |
+ uint32_t hdr[4], width, height, i, j, k; | |
+ uint16_t *row, mr = 0xffff, mg = 0xffff, mb = 0xffff; | |
+ uint8_t *rowout; | |
+ char *color; | |
+ unsigned int r = 0xff, g = 0xff, b = 0xff; | |
+ float a; | |
+ | |
+ argv0 = argv[0]; | |
+ ARGBEGIN { | |
+ case 'b': | |
+ for (color = EARGF(usage()); *color && *color == '#'; color++) | |
+ ; | |
+ | |
+ switch (strlen(color)) { | |
+ case 3: | |
+ if (sscanf(color, "%1x%1x%1x", &r, &g, &b) != 3) | |
+ usage(); | |
+ mr = (r | r << 4) * 257; | |
+ mg = (g | g << 4) * 257; | |
+ mb = (b | b << 4) * 257; | |
+ break; | |
+ case 6: | |
+ if (sscanf(color, "%2x%2x%2x", &r, &g, &b) != 3) | |
+ usage(); | |
+ mr = r * 257; | |
+ mg = g * 257; | |
+ mb = b * 257; | |
+ break; | |
+ case 12: | |
+ if (sscanf(color, "%4x%4x%4x", &r, &g, &b) != 3) | |
+ usage(); | |
+ mr = r; | |
+ mg = g; | |
+ mb = b; | |
+ break; | |
+ default: | |
+ usage(); | |
+ } | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND | |
+ | |
+ if (argc) | |
+ usage(); | |
+ | |
+ /* header */ | |
+ if (fread(hdr, sizeof(*hdr), 4, stdin) != 4) { | |
+ fprintf(stderr, "%s: fread: %s\n", argv0, strerror(errno)); | |
+ return 1; | |
+ } | |
+ if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) { | |
+ fprintf(stderr, "%s: invalid magic value\n", argv0); | |
+ return 1; | |
+ } | |
+ if (!(width = ntohl(hdr[2]))) { | |
+ fprintf(stderr, "%s: invalid width: zero\n", argv0); | |
+ return 1; | |
+ } | |
+ if (!(height = ntohl(hdr[3]))) { | |
+ fprintf(stderr, "%s: invalid height: zero\n", argv0); | |
+ return 1; | |
+ } | |
+ if (width > SIZE_MAX / ((sizeof("RGBA") - 1) * sizeof(uint16_t))) { | |
+ fprintf(stderr, "%s: row length integer overflow\n", argv0); | |
+ return 1; | |
+ } | |
+ | |
+ rowlen = width * (sizeof("RGBA") - 1); | |
+ if (!(row = malloc(rowlen * sizeof(uint16_t)))) { | |
+ fprintf(stderr, "%s: malloc: %s\n", argv0, strerror(errno)); | |
+ return 1; | |
+ } | |
+ if (!(rowout = malloc(width * sizeof("RGB") - 1))) { | |
+ fprintf(stderr, "%s: malloc: %s\n", argv0, strerror(errno)); | |
+ return 1; | |
+ } | |
+ | |
+ /* PPM binary */ | |
+ printf("P6\n%" PRIu32 " %" PRIu32 "\n255\n", width, height); | |
+ | |
+ /* write rows */ | |
+ for (i = 0; i < height; ++i) { | |
+ if (fread(row, sizeof(uint16_t), rowlen, stdin) != rowlen) { | |
+ fprintf(stderr, "%s: fread: %s\n", argv0, strerror(err… | |
+ return 1; | |
+ } | |
+ for (j = 0, k = 0; j < rowlen; j += 4, k += 3) { | |
+ a = ntohs(row[j + 3]) / 65535.0f; | |
+ rowout[k] = ((ntohs(row[j]) * a) + (mr * (1 - … | |
+ rowout[k + 1] = ((ntohs(row[j + 1]) * a) + (mg * (1 - … | |
+ rowout[k + 2] = ((ntohs(row[j + 2]) * a) + (mb * (1 - … | |
+ } | |
+ if (fwrite(rowout, 3, width, stdout) != width) { | |
+ fprintf(stderr, "%s: fwrite: %s\n", argv0, strerror(er… | |
+ return 1; | |
+ } | |
+ } | |
+ return 0; | |
+} |