Hello, after literally dozens of mails discussing a new suckless image-format, I sat down last week to reflect on what could be the best of all proposed format-specifications. As a result I came up with the first implementation, the if-tools[0], capable of easily converting between png and imagefiles. In this mail, I'll give you a small overview on the format itself and how it behaves in real situations.
1) FORMAT Bytes Description 9 "imagefile" 4 32-bit BE - width 4 32-bit BE - height [1111] RGBA 2) FILE-EXTENSIONS [if, if.bz2] The latter is used for bzipped imagefiles. Explanation follows. 3) CODING EXAMPLES The examples intentionally leave out error-checks. 3.1) Writing an imagefile-header uint32_t tmp, width = x, height = y; fprintf(fd, "imagefile"); tmp = htonl(width); fwrite(&tmp, sizeof(uint32_t), 1, fd); tmp = htonl(height); fwrite(&tmp, sizeof(uint32_t), 1, fd); 3.2) Reading an imagefile-header Every header is 17 bytes long (9 + 4 + 4). uint8_t hdr[17]; uint32_t width, height; fread(hdr, 1, 17, fd); width = ntohl((hdr[9] << 0) | (hdr[10] << 8) | (hdr[11] << 16) | (hdr[12] << 24)); height = ntohl((hdr[13] << 0) | (hdr[14] << 8) | (hdr[15] << 16) | (hdr[16] << 24)); 3.3) Reading data After the header has been read, reading the corresponding data segments is trivial. 4) USING THE IMAGEFILE-TOOLS The imagefile[0]-tools provide a way to convert between png and if using pipes. 4.1) Trivial conversions $ png2if < image.png > image.if $ if2png < image.if > image.png $ if2png < image.if | feh - (...) 4.2) Bzipped conversions $ png2if < image.png | bzip2 > image.if.bz2 $ bzcat image.if.bz2 | if2png > image.png 5) Why BZIP2? Basically all lossless image-formats implement their compression inside the format itself. This is the reason why it's not trivial to write a png-parser, given you have to know the compression-method to extract the pixels again. The idea behind bzipping an imagefile is combining a transparent interface with the advantages of file compression, and in many cases, this beats png by far! Even normal photographs reach comparable results to png, but the real strength lies in line-drawings. png if if.bz2 waterfall.png[1] 649K 1.4M 718K bio_hazard.png[2] 21K 588K 9.2K This is due to the fact that png takes an analytical approach to lossless compression and applies a pre-filter, which however doesn't allow the secondary deflate-algorithm to catch up large chunks of similar blocks. The imagefile-format is 100% transparent and thus, if your image has large chunks of similar data, or is greyscale (R = G = B), or only has one or two color-channels (R = 0 || G = 0 || B = 0), bzip will take care of that. What even surprised me is the fact bzip2 is so efficient with photographs, which apparently also have the necessary patterns allowing lossless compression. 6) CURRENT IMPLEMENTATIONS - if-tools [0] - xscreenshot [4] - academics (Schlieren Photography Data) 7) WHY USE IT? The UNIX-philosophy strongly encourages to write software which does one thing and does it well. Basically, a developer shouldn't have to worry about the intrinsics of a given image-format, but instead should focus on working on keeping his software as lean as possible. Porting the xscreenshot-tool to imagefile cut almost half the LOC and dramatically improved readability. The conversion to png can now be done using if2png and using pipes. That's the way to go! Moreover, imagefile is a great way to store images. It may not be as good as png when it comes to photographs, but it sure as hell beats it in regard to all kinds of line art, greyscale and other off-scale photography if you use bzip2 to compress it. Join the cause to spread this suckless image-format! Cheers FRIGN [0]: http://git.2f30.org/imagefile/ [1]: http://frign.de/static/imagefile/waterfall.png [2]: http://frign.de/static/imagefile/bio_hazard.png [3]: http://git.2f30.org/xscreenshot/ -- FRIGN <d...@frign.de>