Zip compression in OpenEXR is just the standard DEFLATE algorithm
as used by Zip, gzip, PNG and others. That got me thinking - the compression has different “compression levels” that
control ratio vs. performance. Which one is OpenEXR using, and would changing them affect anything?
OpenEXR seems to be mostly using the default zlib compression level (6). It uses level 9 in several places (within the lossy DWAA/DWAB compression), we’ll ignore those for now.
Let’s try all the zlib compression levels, 1 to 9 (click for an interactive chart):
- The Zip compression level used in current OpenEXR is level 6, marked with the triangle shape point on the graph.
- Compression ratio is not affected much by the level settings - fastest level (1) compresses data 2.344x; slowest (9) compresses at 2.473x.
- Levels don’t affect decompression performance much.
- Maybe level 4 should be the default (marked with a star shape point on the graph)? It’s a tiny compression ratio drop
(2.452x -> 2.421x), but compression is over 2x faster (206 -> 437 MB/s)! At level 4, writing a Zip-compressed EXR
file becomes faster than writing an uncompressed one.
- Just a tiny 4 line change in OpenEXR library source code would be enough for this.
- A huge advantage is that this does not change the compression format at all. All the existing EXR decoding software can still decode the files just fine; it’s still exactly the same compression algorithm.
With a bit more changes, it should be possible to make the Zip compression level be configurable, like so:
Header header(width, height); header.compression() = ZIP_COMPRESSION; addZipCompressionLevel(header, level); // <-- new! RgbaOutputFile output(filePath, header);
So that’s it. I think switching OpenEXR from Zip compression level 6 to level 4 by default should be a no-brainer. Let’s make a PR and see what happens!
In the next post I’ll try adding a new lossless compression algorithm to OpenEXR and see what happens.