libjxl / libjxl

JPEG XL image format reference implementation
BSD 3-Clause "New" or "Revised" License
2.71k stars 260 forks source link

jpegli 10+ bit documentation #3464

Open RieGo opened 7 months ago

RieGo commented 7 months ago

I'm doing some experiments with converting my processed images to jpg using jpegli instead of mozjpeg. Now the option to encode more than 8 bits sounds great to me, as it might make the images very futureproof. I just can't find any documentation on it.

Here are a few questions:

any info very much appreciated, thanks

niutech commented 7 months ago

From Chromium issue::

This time, there are no format extensions. The data is stored just slightly more carefully into the existing 8-bit formalism, into the usual DCT coefficients -- making some of the improvements available for all users, regardless which encoder or decoder they use, as long some of the encoding or decoding is being done with jpegli, regardless of it being in 8-bit or 10+ bit mode.

If you use the 16 bit framebuffer API at encoding and decoding, you get about 10.5 bits of dynamics in smooth gradients. The resulting image is more like the original with no observable 8-bit banding.

If you use the 16 bit framebuffer API at encoding and but a usual 8-bit framebuffer jpeg decoder for decoding, you get marginally better results (more density, more quality) than if also the encoding had been done with 8 bit framebuffer. But in the end you will have an 8 bit frame buffer.

If you use an 8 bit framebuffer API with jpegli for encoding, or another JPEG encoder such as libjpeg-turbo or MozJPEG, and only decode with jpegli to 16 bits, you will get marginally better results at lower quality but substantially (almost 12 %, didn't measure, guesswork number) better results at higher quality settings (95+).

If you use 8-bits for both encoding (MozJPEG/libjpeg-turbo/jpegli) and then 8-bit framebuffer decoding, you will still get better results if you decode to 8-bits with jpegli rather than with libjpeg-turbo/MozJPEG. The improvement for using Jpegli for decoding is 7 % in the highest quality, quickly dropping to zero at lower quality.

RieGo commented 7 months ago

Thanks, I think I got it now

PNG16 -> Jpegli means internal bit depth of ~10bits. - djpegli to PNG16 means I can use the extra bits, right?

so if i would losslessy recode this jpegli to JPEGXL I would loose that extra precision because it's probably defined as 8 bit JPEGXL and would always be decoded as 8 bit. in this case I would have to reencode.

Is this right or am I missing something?

lonjil commented 7 months ago

Bit depth isn't really "real" in VarDCT (aka the JPEG-like mode) JXL. The full bit depth is always available. The JXL file will identify itself as "8-bit" in the metadata, which might unfortunately lead to some applications decoding with less precision, but libjxl itself will happily decode it to whatever precision you want.