cgohlke / imagecodecs

Image transformation, compression, and decompression codecs
https://pypi.org/project/imagecodecs
BSD 3-Clause "New" or "Revised" License
111 stars 21 forks source link

Consider changing the way `option_lossess` is set in `jpegxl_encode`? #30

Closed JackKelly closed 2 years ago

JackKelly commented 2 years ago

Thanks again for all your work on imagecodecs!

In jpegxl_encode, option_lossless is set to True if level is None or level < 0 (line 160 of _jpegxl.pyx).

The level argument to jpegxl_encode is passed to JxlEncoderOptionsSetDecodingSpeed which sets the decoding speed, not whether the image is lossless or not :slightly_smiling_face:. That is, level is somewhat orthogonal to whether lossless mode should be engaged or not.

An improvement might be to set option_lossless to True if distance is 0.0. (See the docs for distance)

(Also, would it be worth considering renaming level to decoding_speed or something like that?)

cgohlke commented 2 years ago

Right. This is mostly fixed in the development version, which introduces two additional parameters lossless, and decodingspeed

        JXL_BOOL option_lossless = lossless is None or bool(lossless)
        int option_tier = _default_value(decodingspeed, 0, 0, 4)

The level parameter is actually part of the imagecodecs encode API. Right now it is mapped to lossless and tier but maybe it's better mapped to effort or distance...

JackKelly commented 2 years ago

Awesome, thank you! Sorry for the silly question but how do I access the dev version of imagecodecs?

The level parameter is actually part of the imagecodecs encode API. Right now it is mapped to lossless and tier but maybe it's better mapped to effort or distance...

As you probably know, the cjxl utility has a quality setting (which takes a value between -inf and 100, where 100 is lossless). If the level param in the imagecodecs API is supposed to take a value up to 100 then maybe it's worth checking the cjxl code to see how it maps from quality to distance etc?

cgohlke commented 2 years ago

AFAICT, the cjxl quality setting maps to fields in a private C++ struct. Those can't be set from C using the public API.