farbfeld

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

farbfeld.5 (4301B)


      1 .Dd 2018-04-11
      2 .Dt FARBFELD 5
      3 .Os suckless.org
      4 .Sh NAME
      5 .Nm farbfeld
      6 .Nd suckless image format
      7 .Sh DESCRIPTION
      8 .Nm
      9 is a
     10 .Em lossless
     11 image format which is easy to parse, pipe and compress.
     12 It has the following format:
     13 .Bd -literal -offset left
     14 BYTES    DESCRIPTION
     15 8        "farbfeld" magic value
     16 4        32-Bit BE unsigned integer (width)
     17 4        32-Bit BE unsigned integer (height)
     18 [2222]   4*16-Bit BE unsigned integers [RGBA] / pixel, row-major
     19 .Ed
     20 .Pp
     21 The RGB-data should be sRGB for best interoperability and not
     22 alpha-premultiplied.
     23 .Sh USAGE
     24 .Nm
     25 provides the tools
     26 .Xr 2ff 1 ,
     27 .Xr jpg2ff 1 ,
     28 .Xr png2ff 1
     29 and
     30 .Xr ff2jpg 1 ,
     31 .Xr ff2pam 1 ,
     32 .Xr ff2png 1 ,
     33 .Xr ff2ppm 1
     34 to
     35 .Em convert
     36 to and from farbfeld images respectively.
     37 .Pp
     38 .Xr bzip2 1
     39 is recommended for
     40 .Em compression ,
     41 giving results comparable with PNG for photographs and much better results
     42 for other image types.
     43 .sp
     44 The
     45 .Em file extension
     46 is ".ff" and compression extensions shall be
     47 appended (e.g. ".ff.bz2").
     48 .Sh MOTIVATION
     49 .Nm
     50 was created because the author was not satisfied with the boilerplate
     51 and inherent complexity involved in handling common image formats
     52 (PNG, JPEG, GIF,...), having to rely on bloated libraries while not being
     53 able to focus on the task at hand for a given image processing problem.
     54 .Sh EXAMPLES
     55 The following code listing
     56 .Em invert.c
     57 is a ready-to-use color inverter with all necessary error handling and
     58 reporting. This program can be integrated into a farbfeld pipeline as
     59 follows:
     60 .Pp
     61 $ png2ff < image.png | invert | ff2png > image-inverted.png
     62 .Pp
     63 It shall be noted here that due to the simplicity of the format no
     64 external libraries are needed to handle the farbfeld image data. The
     65 0BSD-License gives you the freedom to throw away the license block and
     66 just use the code as you wish. Happy hacking!
     67 .Bd -literal -offset left
     68 /*
     69  * 0BSD-License
     70  *
     71  * (c) 2017 Laslo Hunhold <dev@frign.de>
     72  *
     73  * Permission to use, copy, modify, and/or distribute this software for
     74  * any purpose with or without fee is hereby granted.
     75  *
     76  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
     77  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
     78  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
     79  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
     80  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
     81  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     82  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     83  * PERFORMANCE OF THIS SOFTWARE.
     84  */
     85 #include <arpa/inet.h>
     86 
     87 #include <errno.h>
     88 #include <stdint.h>
     89 #include <stdio.h>
     90 #include <string.h>
     91 
     92 #define LEN(x) (sizeof (x) / sizeof *(x))
     93 
     94 static void
     95 invert(uint16_t rgba[4])
     96 {
     97 	rgba[0] = UINT16_MAX - rgba[0];
     98 	rgba[1] = UINT16_MAX - rgba[1];
     99 	rgba[2] = UINT16_MAX - rgba[2];
    100 }
    101 
    102 int
    103 main(int argc, char *argv[])
    104 {
    105 	uint32_t hdr[4], width, height, i, j, k;
    106 	uint16_t rgba[4];
    107 
    108 	/* arguments */
    109 	if (argc != 1) {
    110 		fprintf(stderr, "usage: %s\\n", argv[0]);
    111 		return 1;
    112 	}
    113 
    114 	/* read header */
    115 	if (fread(hdr, sizeof(*hdr), LEN(hdr), stdin) != LEN(hdr)) {
    116 		goto readerr;
    117 	}
    118 	if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) {
    119 		fprintf(stderr, "%s: invalid magic value\\n", argv[0]);
    120 		return 1;
    121 	}
    122 	width = ntohl(hdr[2]);
    123 	height = ntohl(hdr[3]);
    124 
    125 	/* write data */
    126 	if (fwrite(hdr, sizeof(*hdr), LEN(hdr), stdout) != 4) {
    127 		goto writerr;
    128 	}
    129 
    130 	for (i = 0; i < height; i++) {
    131 		for (j = 0; j < width; j++) {
    132 			if (fread(rgba, sizeof(*rgba), LEN(rgba),
    133 			          stdin) != LEN(rgba)) {
    134 				goto readerr;
    135 			}
    136 			for (k = 0; k < 4; k++) {
    137 				rgba[k] = ntohs(rgba[k]);
    138 			}
    139 
    140 			invert(rgba);
    141 
    142 			for (k = 0; k < 4; k++) {
    143 				rgba[k] = htons(rgba[k]);
    144 			}
    145 			if (fwrite(rgba, sizeof(*rgba), LEN(rgba),
    146 			           stdout) != LEN(rgba)) {
    147 				goto writerr;
    148 			}
    149 		}
    150 	}
    151 
    152 	/* clean up */
    153 	if (fclose(stdout)) {
    154 		fprintf(stderr, "%s: fclose: %s\\n", argv[0],
    155 		        strerror(errno));
    156 		return 1;
    157 	}
    158 
    159 	return 0;
    160 readerr:
    161 	fprintf(stderr, "%s: fread: Unexpected EOF\\n", argv[0]);
    162 	return 1;
    163 writerr:
    164 	fprintf(stderr, "%s: fwrite: %s\\n", argv[0], strerror(errno));
    165 	return 1;
    166 }
    167 .Ed
    168 .Sh SEE ALSO
    169 .Xr 2ff 1 ,
    170 .Xr ff2jpg 1 ,
    171 .Xr ff2pam 1 ,
    172 .Xr ff2png 1 ,
    173 .Xr ff2ppm 1 ,
    174 .Xr jpg2ff 1 ,
    175 .Xr png2ff 1
    176 .Sh AUTHORS
    177 .An Laslo Hunhold Aq Mt dev@frign.de