openexr icon indicating copy to clipboard operation
openexr copied to clipboard

Per-channel DWA compression scheme / custom clasifiers

Open vmsrc opened this issue 1 year ago • 3 comments

Currently DWA compressed images use different compression schemes - LOSSY_DCT, RLE. Compresson scheme upon EXR writing is determined using hard-coded classifiers - sDefaultChannelRules[]. Would it be possible to add ability for per-channel compression scheme selection? Probably - by using custom channel classifiers? This would make it possible to use lossless compression for the "Y" channel. And this would make it possible to store coordinates or vector normals. For example - storing "Normal.X", "Normal.Y", "Normal.Z", "WorldPosition.X", "WorldPosition.Y", etc. Using lossy DCT does not work fine for such values, that could be negative values.

vmsrc avatar Dec 16 '24 10:12 vmsrc

The ChannelList attribute does have space that future versions of OpenEXR could use to store flags that are per-channel hints to lossy compression algorithms.

An approach that's already possible is to use multipart files: store the RGB channels in one part using DWA compression, and all the XYZ in another part using a lossless compression type. That way you can pick the optimal lossless compressor to use.

peterhillman avatar Dec 16 '24 19:12 peterhillman

This is doable without the need of new ChannelList attribute. For some reason, channel rules (aka channel classifiers) are stored at the beginning of each DWA chunk using the following codepath: exr_compress_chunk() -> DwaCompressor_compress(0 -> DwaCompressor_writeRelevantChannelRules() -> Classifier_write().

By just commenting-out the "Y" classifiers in the "static Classifier sDefaultChannelRules[]", the problem is fixed – and the produced single-part EXR files use RLE for channels named "normals.Y", etc. And the produced files are readable using unmodified OpenEXR library.

It would be nice if we have control over these classifiers using the public API though.

vmsrc avatar Jan 06 '25 13:01 vmsrc

Yes, that could be a possibility. The API could also support querying the rules that a file was written with from the DWA chunks, so a file could be read in and written out again with the same rules.

All that said, The technical specification says Y means luminance. The newer default/non-legacy rules for DWA types will encode x,y, and z as lossless. If it's possible to name your normals channels with lower case letters, then you'll get the result you need and also write a file that conforms with OpenEXR channel naming conventions.

peterhillman avatar Jan 08 '25 02:01 peterhillman