Image file formats and compression

Obsolete

While the information contained here may have some value, note that it is obsolete. RawTherapee 5.4 uses an efficient and fast compression strategy for both TIFF and PNG, and both formats support metadata.

Intermediate format

An intermediate file is one you use just to pass the image data around between programs while working on it, e.g. from RawTherapee to GIMP or Photoshop.

The ideal intermediate format is one which loses no image data or metadata and is quick to read and write. This pretty much means you should always use uncompressed 16-bit TIFF as your intermediate format. Period.

Final format

Some things to consider when deciding which format to use for storing non-intermediate files, e.g. final processed images, scanned film, high dynamic range images, and so forth:

  • JPEG is the most widely supported but is lossy and in most implementations limited to 8 bits per channel, 24 bits per pixel.
  • TIFF and JPEG support metadata, PNG generally does not.
  • TIFF can use various compression methods (including the one PNG uses: DEFLATE, also known as Zip). Zip is the most efficient compression method for real-world photos supported by TIFF.
  • PNG is slow and inefficient.
  • The images can be converted externally to other more efficient formats, such as 16-bit JPEG-2000 or OpenEXR.

Lossless compression comparison

The input file is a 16-bit 10000x5000 pixel real-world panorama.

To convert the formats I used ImageMagick-6.8.8.10 on an x86_64 Intel(R) Core(TM) i7 CPU Q 820 @ 1.73GHz, and I scripted the steps in Bash.

TIFF 16-bit

for c in RLE None LZW Zip; do time convert foo.tif[0] -monitor -depth 16 -compress "$c" "${c}_16.tif"; ls -lh "${c}_16.tif"; done

FormatCompressionSize [MB]Time [s]
TIFF 16-bitNone3825
TIFF 16-bitRLE3855
TIFF 16-bitLZW2938
TIFF 16-bitZip24361

Yes, the result using RLE was bigger than the uncompressed image.

TIFF 12-bit

for c in None LZW Zip; do time convert foo.tif[0] -monitor -depth 12 -compress "$c" "${c}_12.tif"; ls -lh "${c}_12.tif"; done

FormatCompressionSize [MB]Time [s]
TIFF 12-bitNone2874
TIFF 12-bitLZW2489
TIFF 12-bitZip21044

GIMP-2.9 and RawTherapee-4.2 do not read 12-bit TIFF files.

TIFF 8-bit

for c in None LZW Zip; do time convert foo.tif[0] -monitor -depth 8 -compress "$c" "${c}_8.tif"; ls -lh "${c}_8.tif"; done

FormatCompressionSize [MB]Time [s]
TIFF 8-bitNone1913
TIFF 8-bitLZW514
TIFF 8-bitZip4941

TIFF 16-bit floating-point

for c in None LZW Zip; do time convert foo.tif[0] -monitor -define quantum:format=floating-point -compress "$c" "${c}_fp.tif"; ls -lh "${c}_fp.tif"; done

FormatCompressionSize [MB]Time [s]
TIFF 16-bit floating-pointNone3826
TIFF 16-bit floating-pointLZW1538
TIFF 16-bit floating-pointZip13372

TIFF 64-bit double-precision floating-point

for c in None LZW Zip; do time convert foo.tif[0] -monitor -depth 64 -define quantum:format=floating-point -compress "$c" "${c}_64fp.tif"; ls -lh "${c}_64fp.tif"; done

FormatCompressionSize [MB]Time [s]
TIFF 64-bit floating-point doubleNone152521
TIFF 64-bit floating-point doubleLZW101636
TIFF 64-bit floating-point doubleZip551104

OpenEXR 16-bit floating-point

OpenEXR is a good option; it’s modern, efficient and widely supported.

for c in None Zip PIZ; do time convert foo.tif[0] -monitor -depth 16 -compress "$c" "${c}_16.exr"; ls -lh "${c}_16.exr"; done

FormatCompressionSize [MB]Time [s]
EXR 16-bitNone38213
EXR 16-bitZip10621
EXR 16-bitPIZ1117

To convert the EXR to a 16-bit TIFF you need to set the colorspace to sRGB (set it, not transform it):

convert Zip_16.exr -depth 16 -set colorspace sRGB suchwow.tif

PNG 16-bit

Finally, PNG. ImageMagick lets you set the zlib compression level 1-9, or uses Huffman compression if you set the first value to 0. The second value sets date encoding filtering, where 5=Adaptive, best for real-world photos.

for l in 0 6 9; do time foo.tif[0] -monitor -depth 16 -quality "${l}5" "${l}5_16.png"; ls -lh "${l}5_16.png"; done

FormatCompressionSize [MB]Time [s]
PNG 16-bitlevel 03109
PNG 16-bitlevel 623387
PNG 16-bitlevel 9233351

Notice the same file size of level 6 and 9 despite taking 4 times as long.

PNG 8-bit

for l in 0 6 9; do time foo.tif[0] -monitor -depth 8 -quality "${l}5" "${l}5_8.png"; ls -lh "${l}5_8.png"; done

FormatCompressionSize [MB]Time [s]
PNG 8-bitlevel 013710
PNG 8-bitlevel 64940
PNG 8-bitlevel 946341

Translations