Fork me on GitHub

FLIF by Example

Here is an example that illustrates some of the strengths of FLIF. Consider the following image from pngimg.com. It is a 1969x1307 image with four 8-bit channels (three for RGB color and one for alpha/transparency).

Example image of a fish

Lossless compression

Here are the sizes of this image in various image file formats:

OK, so in lossless compression, FLIF wins (though BPG and WebP are not far behind).

Lossy compression

What about lossy compression?

Let us compare the compression artifacts of the different formats. We'll look at partial FLIF and PNG files, and compare with lossy WebP, lossy JPEG 2000, lossy BPG, and the older standard formats GIF and JPEG.

Note that what we will be doing is not a fair comparison. It heavily disadvantages FLIF and PNG, because we are looking at different-sized first parts of one file (the one that eventually leads to a lossless image), while for the other formats, we look at multiple files, each optimized for a specific quality setting.

To make it easier to compare the image quality, only part of the images are shown here. You can click on the image to see the full image.

The smallest possible file I could produce with existing image formats, was a 16,977 bytes JPEG file (encoded using the lowest possible quality setting). Obviously, this is extremely lossy: JPEG does not support transparency at all, quantization is extreme, etc. Here are the resulting images at this size:

Original (lossless) Partially loaded FLIF (16,977 first bytes of a 299,643 byte file) Partially loaded PNG (16,977 first bytes of a 657,022 byte file) Partially loaded lossy GIF (16,977 first bytes of a 219,377 byte file) Lossy BPG (15,411 bytes) Lossy WebP Lossy JPEG 2000 (16,962 bytes) Lossy JPEG (16,977 bytes)
Example image of a fish Example image of a fish Example image of a fish Example image of a fish Example image of a fish no WebP at this size Example image of a fish Example image of a fish

The winner? In my opinion, BPG looks best here. But keep in mind that this is a completely different BPG file than the lossless BPG file. Also, the BPG encoder is very slow.

The smallest WebP file I could produce (using cwebp -q 1 -alpha_q 1 -m 6) has a size of 22,702 bytes. Let's take a look:

Original (lossless) Partially loaded FLIF (22,702 first bytes of a 299,643 byte file) Partially loaded PNG (22,702 first bytes of a 657,022 byte file) Partially loaded lossy GIF (22,702 first bytes of a 219,377 byte file) Lossy BPG (22,024 bytes) Lossy WebP (22,702 bytes) Lossy JPEG 2000 (22,676 bytes) Lossy JPEG (22,749 bytes)
Example image of a fish Example image of a fish Example image of a fish Example image of a fish Example image of a fish Example image of a fish Example image of a fish Example image of a fish

Again, the BPG file looks best. I would say FLIF is second best. Now, let's give WebP some more bytes to work with. With cwebp -q 20 -alpha_q 20 -m 6) I got a .webp file with a size of 40,100 bytes.

Original (lossless) Partially loaded FLIF (40,100 first bytes of a 299,643 byte file) Partially loaded PNG (40,100 first bytes of a 657,022 byte file) Partially loaded lossy GIF (40,100 first bytes of a 219,377 byte file) Lossy BPG (38,590 bytes) Lossy WebP (40,100 bytes) Lossy JPEG 2000 (40,024 bytes) Lossy JPEG (40,442 bytes)
Example image of a fish Example image of a fish Example image of a fish Example image of a fish Example image of a fish Example image of a fish Example image of a fish Example image of a fish

Progressive decoding

What about progressive decoding of the other lossless formats?

BPG is very good at lossy compression, but its lossless files cannot be progressively decoded very well. In this example, bpgdec only wanted to decode the lossless BPG file after about 90,000 bytes were downloaded, and then still only the alpha channel seems to be OK:

Partially loaded FLIF (90,000 first bytes of a 299,643 byte file) Partially loaded BPG (90,000 first bytes of a 334,889 byte file)
Example image of a fish Example image of a fish

Even after 200,000 bytes, the lossless BPG file still looks pretty bad:

Partially loaded FLIF (200,000 first bytes of a 299,643 byte file) Partially loaded BPG (200,000 first bytes of a 334,889 byte file)
Example image of a fish Example image of a fish

WebP does not support progressive decoding at all. JPEG 2000 supposedly does, but I couldn't find any program that can handle partial JPEG 2000 files. So besides FLIF, the only real choice for a progressively downloading lossless format would be PNG with Adam7 interlacing. But in this example, that would be a file that is twice as large. In general, FLIF files are about 39% smaller than PNG files with Adam7 interlacing (even after pngcrushing them).

Responsive images

The original image is 1969x1307 pixels, which is quite big. Most likely your browser has to scale the image down so it fits the available space:

Example image of a fish

As said before, the above image can be encoded in FLIF using 299,643 bytes. However, using flif -d -s 2, a downscaled image can be decoded at scale 1:2, which results in the following 653x985 image after reading only the first 80,389 bytes of the file:

Example image of a fish

If scale 1:4 is good enough (e.g. you're viewing the image on a smartphone), then you can get the following 492x326 image from the first 37,014 bytes of the FLIF file:

Example image of a fish