libjxl
libjxl copied to clipboard
Suggest to switch to default effort 3
I bench-marked about 2k of my private digital cam pictures with d=1.0 and different efforts using "JPEG XL encoder v0.7.0 ab775e2".
First I checked some hundreds in an effort range from 2 to 8 and found that the resulting BPP for 3 is almost same as with effort 4. Effort 5 is near effort 6 in resulting BPP. Effort 2 is significant 'bad' in resulting compression size and 8 takes too long time. Therefore I skipped 2, 5, 6 and 8 for later tests (means using only 3, 5, 7).
I counted how often which effort results in lowest BPP and over all always -e 3 won. (e.g. a folder with 1714 jpg-files effort 3 won 1310 times. 5 with 373 and effort 7 with only 31). So I calculated the optimal lowest file size using for each file the best effort, setting this to 100%. Recompressing jpg-files with only the same effort: Effort 7 results in 106.7% -- effort 5 in 105,5% -- effort 3 in 101,3% in relation to optimum. So even I choose only effort 3 for all files I'm very near to the optimum. An other set (about 500 files) results in: e7=107,3% -- e5=104,9% -- e3 =101,7%
Question (has not to be answered but be considered in future development): Why the effort 7 which is more complex and should outperform lower efforts, is so bad?
With effort 8 it's a bit different. It wins more often against e 3 but not as much as I thought. It depends on selected jpg-files. I tried about 50 pictures. Effort 3 results in an over all file size of only 100.6% related to using effort 8.
I also switched for my set of 1714 files to "-d 0.5". Resulting in: e7=103.1% -- e5=103.2% -- e3 = 101.3% (like before comparing optimum to using only one effort). Now e7 is a bit better than e5 but still e3 wins.
I suggest to switch to default effort=3.
Best regards Andreas
Well, I just a guess, but the higher efforts may be tailored to check for image features which are not present in your photos, like dots, high noise, repeating sections, areas with (nearly) the same colors etc.
@A-Conrath I'm wondering if -e9 would lead to "always the best" compression, and if not, why not :)
@A-Conrath just to make sure, you're converting jpgs I guess, so you need to use the --jpeg_transcode flag to not just do a lossless jpg conversion of your files, which can be fully reverted.
I tried (granted with just one image) but I don't see any effect you're seeing with my file:
- e9: 1016806 bytes (1.006 bpp)
- e8: 1017526 bytes (1.007 bpp)
- e7: 1101571 bytes (1.090 bpp)
- e6: 1092293 bytes (1.081 bpp)
- e5: 1081313 bytes (1.070 bpp)
- e4: 1362793 bytes (1.349 bpp)
- e3: 1368776 bytes (1.355 bpp)
- e2: 1597923 bytes (1.582 bpp)
- e1: 1598482 bytes (1.582 bpp)
While the encoding times are the following:
- e9: 18.445s
- e8: 11.041s
- e7: 1.299s
- e6: 0.695s
- e5: 0.671s
- e4: 0.472s
- e3: 0.456s
- e2: 0.448s
- e1: 0.439s
So from my observation the jump from 4 to 5 is definitely worth the additionally processing time, while 7 tries a bit harder but doesn't seem to find anything worth compressing better for all the effort. 8/9 try even harder but find something worth compressing.
Overall, 3 looks like a bad choice as default for me, as most files are saved once and read and transferred many times.
@A-Conrath I'm wondering if -e9 would lead to "always the best" compression, and if not, why not :)
I tried to figure out a practicable way to convert (if encoder has version 1.0) all my pics. 9 is taking a way to much time. So I didn't tried.
@A-Conrath just to make sure, you're converting jpgs I guess, so you need to use the
--jpeg_transcodeflag to not just do a lossless jpg conversion of your files, which can be fully reverted.
In my opinion "-j" is only needed if you not use the "-d" command. But the jxl-files are so much smaller than the original jpg-files, I have no doubt they are transcoded and not only recompressed. Additional the encoder always says "VarDCT".
Some of my files have also a straight behavior. I think you should benchmark some more. And also in your one file e5 is the best by taking only about half the time e7 does.
A file size regression with higher effort should be considered a bug - the man page states "That is to say, all other parameters being equal, a higher effort should yield a file that is at least as dense and possibly denser, and with at least as high and possibly higher quality." https://github.com/libjxl/libjxl/blob/main/doc/man/cjxl.txt
Your dataset is original high resolution, low compression jpeg picture from camera? (with so many noise per pixel)
It's not at all representative to the real diversity of image and size encoded with an encoder, gain could be much higher. Do the same test in -d 2 and resized denoised picture, you will see a bigger difference. Also if you want to store your picture, time encoding is not a big deal.
Secondly, I can say that comparing file size without using the butteraugli benchmark is not good at all. Encoder is not doint an EXACT quality. You can have a two file @ -d 0.5 with different visual quality. Use benchmark_xl.exe tool to compare compression efficiency.
Many people do tests on the discord, it's a best place to speak about tunning encoder.
After I have dealt a little more with this topic, I can understand the objection from the technical side. From the user side, however, this is completely useless. When I select a quality (d-Value), as a user I want to have exactly this quality and without the influence of the encoder effort.
So my original point should actually be "Effort-independent quality setting". In addition, my pictures are a cross-section of various (possibly not so good) digital cameras and smartphone shots. So they are quite representative (especially due to the noise that may be present).
If you want all efforts to make the same quality-affecting choices, then that leaves only room for differences in the entropy coding, not all the other encoder heuristics.
I don't think it works like that in any other modern encoder. They will all produce different pixels for the same quality setting at different effort settings.
The man page for cjxl is wrong: there is no guarantee that higher effort means smaller filesize. The only real guarantee is that it is slower. Generally it should also result in better consistency (less variance in visual quality for a given d setting, both within an image and across a corpus), and also in better overall (corpus-wide) compression in the 'bang for buck' sense (quality per bit). You can get better bang for buck by reducing bucks (bits) or by increasing bang (quality). It can certainly happen that lower effort results in a lower filesize and a lower quality. Whether that means it's "compressing better" depends on how much lower the filesize is and how much lower the quality is. The answer should typically be "no" though.
The man page for cjxl is wrong: there is no guarantee that higher effort means smaller filesize.
Thanks for the explanation (and your great work, again).
I have one last nitpick to add because I was one of those confused by how modern encoders work:
From users' perspective it would be nice if at least the "slowest" effort would be very likly, if not even guaranteed, to result in the best compression (aka smallest file size, speaking as a simple user).
It's reaonable that different efforts enable different encoder heuristics, but there could-should be a "best compression, no matter the cost" setting to get a baseline or to be on the safe side.
-
Looking at how slow effort 9 currently is that might be already covered though?
-
If not, maybe cjxl deserves a setting like optipng that tries all strategies and returns the most favorable result (again, looking at optipng no matter the cost).
For lossless compression, I think it's reasonable to have this expectation, and while we don't currently have this guarantee, if you find a counterexample we will treat it as a bug.
For lossy compression, it is much less clear what "best compression" means. You can always make a file smaller by reducing quality. But the point is not only to make the smallest possible file no matter what, it is also to make a file that looks 'good enough' according to the fidelity target the user chose. If the file is smaller, but it also looks worse than what you wanted to get, then I wouldn't call that "better compression".
Lower effort settings get much of their speed by using simpler/faster heuristics to make choices regarding quality. This means there will be more fluctuations in the actual quality you get: say for a d1 target, at e3 you will sometimes actually get d1.2, sometimes d0.9, sometimes d1.5, etc. At higher effort the amount of fluctuation is lower (thanks to spending more effort on 'getting it right'), so maybe those images now will be d1.05, d0.98, d1.07 instead at e8. In other words, the consistency of the results improves. But that means that for some images, the actual quality will be a bit lower and for others, it will be a bit higher. In the cases where it's higher, the file size will generally also be larger.
So the confusing thing is that most of the effort actually goes to improving consistency (which can lead to both smaller and larger files), not to improving compression itself (making files smaller for every single image).