-
Notifications
You must be signed in to change notification settings - Fork 332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Idea: Allow use of libjpegli for jpeg import/export #7125
Comments
No longer true since 3.x, it supports multiple sample bit depths OOTB. Code using it does have to be adapted though. However, I don't think you can ask for a higher bit-depth sample to what was encoded...
Not sure I get this part - isn't RT pipeline float already? Are you saying that, independent of RT, these are different: 8-bit jpeg -> libjpeg(-turbo) decode -> cast to float (w/ 1/255.f scale) and the latter is somehow "better"? Any demos of this improvement? |
I'll look into it more. Has RawTherapee already been adapted?
jpeg is nominally 8-bits, but because of the transformation, rounding, quantization, etc, fewer bits are used. Then when the process is reversed, there's more rounding, etc to make it fit back into 8-bits. But if more bits are allowed in the process, the gaps between the 8-bit values (converted to float) can be filled in. It can be seen with GIMP. Open a jpeg photo. Convert to 16-bit. Then look at the histogram. Convert the same photo to 16-bit pnm with This works because the transformations are based on sums of smooth curves. |
I doubt it, because there are virtually no 12-bit or 16-bit JPEGs out there.... Thanks for the histograms, I get the quantization issues. I guess what I'm saying is - since the plain old JPEG was already heavily quantized, do you really gain anything in terms of noticeable image quality with theoretically more levels when decoding? I suppose it might only become apparent when doing some considerable level stretching when editing... |
jpeg is quantized in a different domain, after transformation. The transformation is based on smooth curves, so when the process is reversed, the gaps are filled back in. They're not the exact same values, but it's better than a bunch of spikes. It's noticeable in GIMP with curve and level adjustments. If RawTherapee has some tricks to improve the image, it may not matter as much. Depends on the users' needs. |
It's kind of like the raw vs jpeg debate. Don't need raw if someone nails exposure every time. So why does anyone need a raw processor? (So people who bought into the jpeg side before realizing their mistake have a collection of jpegs they wish were raws... This might help them get a bit more out of them.) |
Sure. Just wondering how much is that "bit" 😉 |
Suppose it's 2-4 extra bits. I don't really know what that means. How much does each bit allow to increase exposure or any other setting? |
Might get interesting w/ Ultra HDRs (JPEG + gain map). (see also https://github.com/google/libultrahdr) |
Well, it's simple to test. Save an underexposed image as a jpeg. Open it the standard way and with higher precision. Correct the exposure for both versions and compare. |
On the JXL Discord server it was said to be roughly 10.5 bits in a standard 8 bit Jpeg, when encoded and decoded with jpegli from a 16 bit source. |
Just remembered about this issue and realised I have some tests results to share using SSIMULACRA2 against an 'original' PNG created from a DNG and downsized to reduce noise. (With bonus JXL transcode results)
This is using an 8-bit PNG as input for a most-common example, but I can re-run with 16-bit to gain the benefits of jpegli encoding too |
Those are good results. I would also like to see the results of high bit depth encoding with 8 bit decoding, which would be the scenario when a JPEG produced by RawTherapee is viewed in an application that only does 8 bit decoding. Do you know why the first libjpegli encoded and decoded image is smaller than the others? The image appears softer too. |
8-bit decoding is shown in the second to last image I uploaded, the last being the same file decoded with jpegli. If you mean the PNG files that I uploaded, the lower quality jpeg encoding and decoding means the final result is more quantized, and easier to compress as a PNG. |
The second to last image is encoded with higher quality settings than the first series of JPEGs so they can't be compared. The smaller and softer image I'm referring to is "Jpegli Encoded and Decoded JPEG 2.31 MB 62.45". |
I can make more comparisons tomorrow if I have time, currently away from home. The smaller image is because jpegli uses perceptual based encoding, so filesize is smaller at the same visual quality. Though, Adaptive Quantization has been noted to be worse when above quality 90, I'll have to double check when I'm home. |
It seems like the high bit depth decoding is responsible for the majority of the improvement. Encoding and decoding in high bit depth still has a noticeable improvement, but once 8-bit decoding is used, it doesn't look much better than 8-bit encoding and decoding. Is this what you notice as well? |
If I understand you correctly, yes. The improvements here are from jpegli's higher effective bitdepth. Other improvements such as quality are better compared at the original exposure. The high bit depth encoding has graceful fallback to standard 8bit decoding without jpegli, also loosing the higher bitdepth. Standard JPEG with jpegli decoding: Higher quality output |
Another though crossed my mind. Is the libjpegli compression different from libjpeg-turbo? If so and if libjpeg-turbo supports high bit-depth encoding/decoding, then it would be interesting to see if there is any difference between the libraries. If libjpegli offers better compression at the same quality, then it could be worthwhile to switch. Otherwise, it would be much simpler to use libjpeg-turbo's high bit-depth feature. |
My not-at-all accurate mental model is that compression is similar to drawing with a French curve. If the French curve is "good enough", a few points can be rendered into a reasonable approximation of a "16-bit" curve, even if the original was only "8-bit". I wonder whether a jpeg that shows banding at 8-bits would still do so when decompressed to higher bit depths with jpegli. Based on #7125 (comment), libjpeg-turbo may not be able to decode to higher bit-depth than what was originally encoded? If that is (still) the case, libjpegli would still be needed (for bit depth expansion). A potential feature aside from importing jpegs is bit-depth expansion of other 8-bit images (hinted at by tests using 8-bit png originals). Although some distros include cjpegli/djpegli with the libjxl package, as far as I'm aware, they do not provide the libjpegli library. So packagers would need to compile it separately or it would have to be included as a subproject. Another option is to call the command-line program if available. |
Does anyone know what happens if an 8-bit image is transformed with DCT to a higher bit-depth array. Then maybe add some noise, instead of quantizing, before transforming into a 16- or 32-bit image? Would the results be any better than trying to convert image data directly from 8-bit to 16-bit? |
There are two things that need to be distinguished:
Effectively 8-bit jpegs have 12-bit precision for the DC coefficients, and in slow gradients you only need the lowest frequency AC coefficients so you can still get around 10-11 bits of precision for those parts of the image — provided your pipeline does not do any intermediate quantization. So the banding/blocking that you would expect when doing HDR in only 8-bit can be avoided since the effective precision is higher. |
libjpegli was formerly part of the libjxl project. Images are processed in 32-bit float representation, similarly to jxl. This would be useful to expand editing latitude of imported images. libjpeg-turbo also appears to have an option for expanded bit depth,
but it must be enabled during build and is disabled by default.The new library would need to be built statically, to prevent conflict with system libjpeg-turbo.
Workflows that already build libjxl may work with adjusted build options. For others, libjpegli sources can be separated from the rest of libjxl and built as a subproject. Which jpeg library to use could be selected during configure for conditional compilation.I have
tested separating libjpegli from libjxl and compiling it as a submodule ofa test project that uses it to convert jpegs to and from other formats. This code could be adapted to RawTherapee. (libjpegli is no longer part of libjxl and no longer any need to manually separate it.)Thoughts? Opinions?
The text was updated successfully, but these errors were encountered: