Skip to content
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

Enhancement: add support for jpegli as jpeg encoder #4018

Open
kurtextrem opened this issue Mar 1, 2024 · 12 comments
Open

Enhancement: add support for jpegli as jpeg encoder #4018

kurtextrem opened this issue Mar 1, 2024 · 12 comments

Comments

@kurtextrem
Copy link

kurtextrem commented Mar 1, 2024

Feature request

What are you trying to achieve?

The JPEG XL team at Google has built yet another JPEG encoder, jpegli, which is both faster and better than even mozjpeg. It is based on lessons learned from guetzli and libjxl, and offers a very attractive trade-off: it is very fast, compresses better than WebP and even high-speed AVIF, while still producing good old JPEG files that are supported everywhere. - source: https://cloudinary.com/blog/jpeg-xl-and-the-pareto-front.

Why is it worth adding

Google did a visual study using jpegli, made public in 2024: https://github.com/google-research/google-research/tree/master/mucped23

jpegli likely lifts jpeg to the WebP quality, and far above in high quality - https://twitter.com/jyzg/status/1758436289181859995

There is no bait. Jpegli is a huge upside, 30–35 % more compression without decode slowdown, without compatibility nightmare. It just wörks. It continues on the trajectory of mozjpeg and guetzli but goes further in speed and density. - https://twitter.com/jyzg/status/1762239776667685361

The second and third deficiencies are not a big issues at high quality (libjpeg q85+), but reduces Jpegli's ability to compete in the lowest quality class, like q75-.
Overall I believe jpegli is in its own class of jpeg codecs, combining the quality of guetzli while being faster than mozjpeg and allowing 10+ bits of dynamics for "8 bit" jpegs.
I believe Jpegli and jpeg xl lead in the highest quality category (5 BPP). In mid quality (1.5 BPP) jpeg xl and AVIF are the leaders, Jpegli likely better than WebP. In low quality (0.5 BPP) AVIF will be great for graphics and indoor photos while JPEG XL can still outperform AVIF in nature photos. In low quality WebP can be better than jpegli. - https://news.ycombinator.com/item?id=36429397

Jpegli will lift traditional JPEG compression density by 25–30% and support 10+ bit HDR within the backward compatible 8 bit formalism. Jpegli is based on porting jpeg xl encoding strategies back to old jpeg. It is a whole new reimplementation, instead of tweaking old libs such as libjpeg, libjpeg-turbo or mozjpeg. Jpegli is API and ABI compatible with its usual alternatives like three mentioned before. - https://news.ycombinator.com/item?id=38644005

Further blog posts (from last year, could be that jpegli advanced by now):

How to integrate

Jpegli is included in the JXL repo: https://github.com/libjxl/libjxl/blob/main/lib/jpegli/README.md:

When building the parent libjxl project, two binaries, tools/cjpegli and tools/djpegli will be built, as well as a lib/jpegli/libjpeg.so.62.3.0 shared library that can be used as a drop-in replacement for the system library with the same name.

libvips discussion: libvips/libvips#3871

When you searched for similar feature requests, what did you find that might be related?

#2731

What would you expect the API to look like?

Probably an option like [options.mozjpeg] -> [options.jpegli].

What alternatives have you considered?

see above; jpegli is an alternative to mozjpeg, while being faster and achieving better quality.

@lovell
Copy link
Owner

lovell commented Mar 1, 2024

My understanding is that the jpegli encoder discards more data from the blue part of the visual spectrum to achieve smaller files. To achieve this it uses a somewhat non-standard approach, converting RGB pixel values to a custom colour space (XYB) and storing them as if they were YCbCr, attaching an ICC profile with the relevant curves for a decoder to convert back again.

This means all decoders given such images would need to properly support ICC profiles, something that is still not the case today. This would also preclude the use of wider gamut RGB profiles such as P3.

as well as a lib/jpegli/libjpeg.so.62.3.0 shared library that can be used as a drop-in replacement for the system library

Those wishing to use this should be able to do so today with a globally-installed libvips, although I cannot provide any help or support.

If the prebuilt binaries were ever to include this, it would be instead of mozjpeg rather than in addition to. This means it would require that the upstream jpegli library have a "switch" to use standard libjpeg YCbCr colour encoding, a feature I don't see today.

@kurtextrem
Copy link
Author

I got the info that Jpegli only uses XYB optionally nowadays, and all comparisons that Google has done were without the XYB ICC color space. jpegli does the same as other encoders, just quantized differently. i.e., no decoding compatibility burned.

Jyrki will also reply here as soon as he has the time.

@lovell
Copy link
Owner

lovell commented Mar 1, 2024

Ah OK, happy to stand corrected, the documentation for jpegli is rather sparse and I might be mixing it up with bits of JPEG-XL.

@georges-gomes
Copy link

georges-gomes commented Apr 5, 2024

@kurtextrem
Copy link
Author

For people following this issue, as far as I can tell, if you build your own libvips and replace the jpeg libs during building of libvips, you can make sharp use jpegli already (implicitly).

@adityapatadia
Copy link

How to replace JPEG lib? Can you give command to give while building libvips?

@kurtextrem
Copy link
Author

I think something like this should do it:

sudo cp ./libjpeg.so.62.3.0 /usr/lib/ # make sure libjpeg.so.62.3.0 is the one from the jpegli build
sudo ldconfig

and then build libvips. not 100% sure though (and make sure to make a backup of the current libjpeg in case you try it outside of a docker container or so)

@jyrkialakuijala
Copy link

Jpegli is not using XYB by default. Most of the substantial savings are by variable dead zone quantization and more precise intermediate computations. Using XYB will give an additional ~10 % savings in mid-to-high quality.

@lovell
Copy link
Owner

lovell commented Apr 14, 2024

@jyrkialakuijala Thanks for the info. Given jpegli is intended as a "drop-in replacement" for libjpeg(-turbo), is there any plan to add support for the jpeg_c_*_param_supported() extensibility framework functions, as provided by mozjpeg via mozilla/mozjpeg#118? This would allow libvips and therefore sharp to switch jpegli features on/off in an ABI-compatible manner in the same way that we can currently switch mozjpeg features on/off.

@szabadka
Copy link

Jpegli features can currently be switched on/off with individual jpegli_* API functions, like jpegli_enable_adaptive_quantization. We are currently in the process of migrating Jpegli from the libjxl/libjxl repository to the google/jpegli repository and will not change the API until this is completed.

Please consider adding an issue to the google/jpegli repository so that we can consider this in the future.

@kurtextrem
Copy link
Author

@lovell you probably have more context on what you'd need, could you open the issue there? (or if you don't have time, please lmk which features sharp would need, and then I'll happily open it)

@lovell
Copy link
Owner

lovell commented Oct 27, 2024

I've opened google/jpegli#45 to discuss this upstream in the jpegli repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants