JPEG XL

Info

rules 57
github 35276
reddit 647

JPEG XL

tools 4225
website 1655
adoption 20712
image-compression-forum 0

General chat

welcome 3810
introduce-yourself 291
color 1414
photography 3435
other-codecs 23765
on-topic 24923
off-topic 22701

Voice Channels

General 2147

Archived

bot-spam 4380

jxl

Anything JPEG XL related

fab
2023-01-14 11:00:37
E9 doesn't satisfies me
diskorduser
2023-01-14 11:40:54
Avm?
VcSaJen
2023-01-14 11:41:09
So patches are outdated? Mozilla might reject them using that as an excuse.
_wb_
2023-01-14 11:41:12
Tbh I don't really get why e10 is _that_ much slower than e9. How many combinations does it try?
veluca
2023-01-14 12:28:06
_many_
2023-01-14 12:29:20
432
2023-01-14 12:29:46
we could probably be smarter and skip a few
_wb_
2023-01-14 01:15:07
432 is a big number to multiply with something that is already pretty slow πŸ™‚
veluca
2023-01-14 01:43:04
Indeed
Tirr
2023-01-14 03:26:47
I finally managed to write a decoder that successfully decodes simple ~e6 modular image https://github.com/tirr-c/jxl-oxide
2023-01-14 03:27:18
self-correcting predictor was *really* tough to implement
veluca
2023-01-14 03:35:34
Yup, that thing is a bit of a nightmare to get right...
2023-01-14 03:37:32
I'm very impressed that you managed to write the header stuff with non-procedural macros btw πŸ˜„
Tirr
2023-01-14 03:39:46
header struct got a little bit bigger but yeah πŸ˜‰
veluca
2023-01-14 03:40:06
Does it also do decoding?
2023-01-14 03:40:14
Sorry, encoding
Tirr
2023-01-14 03:40:25
nope
veluca
2023-01-14 03:41:09
Being able to do both was the main reason I went with procedural macros IIRC, although that was so long ago that I have no idea if I'd make the same decision today
Tirr
2023-01-14 03:49:44
maybe I'll go with handwritten ones if I also need to write encoders
2023-01-14 03:50:08
with full potential of rust type system
2023-01-15 08:12:58
tested my decoder with lossy modular and it panicked
2023-01-15 08:13:21
maybe I got squeeze wrong
_wb_
2023-01-15 08:26:31
Did you implement xyb?
Tirr
2023-01-15 08:26:45
nope, not yet
_wb_
2023-01-15 08:27:24
Lossy modular uses xyb by default
2023-01-15 08:28:08
Does progressive lossless work? That also uses squeeze, but without xyb
Tirr
2023-01-15 08:28:25
it panics at global modular so I guess squeeze is the problem
_wb_
2023-01-15 08:29:52
Global modular is where the first squeezed channels go, the ones not larger than kGroupDim
Tirr
2023-01-15 08:30:46
do we count channel index with only filtered ones?
_wb_
2023-01-15 08:32:10
yes
Tirr
2023-01-15 08:32:46
then that would be the problem
2023-01-15 08:32:55
I changed that part when debugging
2023-01-15 08:37:02
the other problem was residual channel dimensions
Demiurge
2023-01-15 08:37:08
Could future JXL encoders be tuned similar to present-day AVIF encoders, for extremely-low-bitrate, low-fidelity, high "glamour" output?
2023-01-15 08:39:51
I notice that rav1e default settings will produce output that looks noticeably worse than JXL -d1 by a noticeable-but-small margin, and yet will take up a quarter of the filesize.
2023-01-15 08:41:10
That's not a bad tradeoff for extremely low bitrate compression of images that don't contain any fine pixel-size details that require preservation.
2023-01-15 08:48:43
There's still a lot of room for improvement in regards to potential perceptual performance at low bitrates and increasing the perceptual uniformity of compression, right? Another thing I noticed is that there is noticeably increased ringing and blurring around black text set on a dark purple background compared to text set on a higher-contrast background.
_wb_
2023-01-15 08:53:44
I think we're only scratching the surface of what jxl encoders can potentially do. It's basically a swiss army knife and we're currently carving wood with it using only the screwdriver and can opener.
Demiurge
2023-01-15 08:56:45
I notice all AV1 encoders have similar-looking artifacts that are very distinctly different compared to libjxl
_wb_
2023-01-15 08:56:49
I mean we're not even using all coding tools, and the ones we do use, we only use in relatively specific and limited ways. We're not even really doing bitrate-distortion optimization at this point.
Demiurge
2023-01-15 08:59:01
I know that one of JXL's goals is perceptual uniformity, and having set-it-and-forget-it quality settings that have a good model of human vision so that quality can be regulated in a perceptually uniform way according to what our eyes notice. RDO is a big part of achieving perceptual uniformity right?
2023-01-15 09:01:07
Basically all parts of the image should visually look to be the same level of quality, without some parts of the image looking much higher or lower fidelity than other parts of the same image
_wb_
2023-01-15 09:01:54
AV1 is imo inherently limited by its coding tools that are rather like using a hammer as a screwdriver: you can get the screw in with it, but it won't look pretty. The deblocking filters it has are quite aggressive and have only coarse-grained control, which is good to hide artifacts at low bitrates but for higher fidelities it means encoders have to choose between ringing artifacts (disabling the filters) and smoothing too much (which is what they're currently doing).
Demiurge
2023-01-15 09:02:38
It should all be perceptually uniform so that I can specify a quality setting I want and know that it will look consistent across a broad variety of images and image types and across the image.
2023-01-15 09:04:03
That's a good explanation. All current AV1 encoders love to completely delete pixel-size details.
2023-01-15 09:04:30
Like fine lines
_wb_
Demiurge I know that one of JXL's goals is perceptual uniformity, and having set-it-and-forget-it quality settings that have a good model of human vision so that quality can be regulated in a perceptually uniform way according to what our eyes notice. RDO is a big part of achieving perceptual uniformity right?
2023-01-15 09:04:30
Yeah but at lower qualities, you shouldn't try to just uniformly produce a low quality image, you should rather let it depend on what the actual compression gain is from lowering the quality, and be smart about it: if lowering the quality only saves a few bits, it's better not to do it and to take those bits in areas where lowering the quality saves lots of bits. Libjxl is not currently doing that kind of thing.
Demiurge
2023-01-15 09:08:20
I really hope that many lossy JXL encoders are written from scratch that try out all different kinds of ideas. Like computing a noise model for an image during encoding, and other fancy and exotic clever tricks to make lossy encoding extremely efficient.
2023-01-15 09:09:07
There are a lot of clever ways to do lossy, countless clever tricks that can be used and most of them can be applied to JXL
2023-01-15 09:09:21
including a lot of the tricks that were applied to GIF
_wb_
2023-01-15 09:18:41
absolutely. Also some of the tricks mozjpeg is using could be 'ported' to jxl
Demiurge
2023-01-15 09:24:43
mozjpeg is still doing some unique tricks of its own eh?
_wb_
2023-01-15 09:31:16
yes, e.g. it does this trick where it avoids ringing with black-on-white text by pretending the black is darker than black
2023-01-15 09:32:12
(relying on the decoder clamping of negative pixel values to zero)
Tirr
Tirr it panics at global modular so I guess squeeze is the problem
2023-01-15 02:28:49
problem solved! I got the GlobalModular spec wrong, decoding should stop on the first channel larger than group_dim, while I was checking it for *all* channels
pshufb
Tirr I finally managed to write a decoder that successfully decodes simple ~e6 modular image https://github.com/tirr-c/jxl-oxide
2023-01-15 03:47:30
Congrats! This is an awesome project.
Tirr
2023-01-15 03:50:53
thanks πŸ™‚ there are lots of work left though, vardct implementation isn't even started yet
_wb_
2023-01-15 05:15:38
If you can already do modular, a lot of work has been done already. VarDCT is still a lot of stuff but it uses the same entropy coding and lots of modular sub-bitstreams, so it's more about implementing the various transforms and piecing everything together, which may be easier than getting the weighted predictor right and the whole entropy decoder, which are both pretty complicated things to get right.
2023-01-15 05:16:20
Are you using the spec or are you starting from other code like j40 or jxlatte?
Tirr
2023-01-15 05:22:53
I started from the spec, with libjxl as reference
2023-01-15 05:23:59
I read the relevant part of libjxl when debugging
_wb_
2023-01-15 05:26:13
Nice β€” j40 and jxlatte already found most spec bugs I imagine, but if you encountered more spec bugs or unclear parts of the spec, please report them in <#1021189485960114198> β€” we only have a few days left to update the committee draft of the 2nd edition before we'll approve it and submit it to ISO...
Tirr
2023-01-15 07:55:40
oh wow, partial decoding works
2023-01-15 07:56:17
I can see blurry artifact of partially decoded area
_wb_
2023-01-15 08:08:32
with lossy modular? are you simply using zero values for the not-yet-decoded channels?
afed
2023-01-15 11:31:15
does vardct have anything for bruteforce or even heavier settings than e9 (for e10)? or does it make sense to have something faster than -e 3, like -e 3 without ANS? or it will be the same as jpegli-xyb but in a jxl container, without any advantages, or at least better multithreading?
veluca
2023-01-15 11:43:55
I suspect you can make e3 faster and/or better
_wb_
2023-01-16 12:12:53
Using the fast huffman coder of fjxl might be possible in VarDCT too, maybe?
2023-01-16 12:16:30
Also I suppose in principle we could make an e1 vardct that is basically libjpeg-turbo with tiling and slightly improved compression. So using YCbCr and doing the color and dct transforms in int16 instead of in float.
veluca
_wb_ Using the fast huffman coder of fjxl might be possible in VarDCT too, maybe?
2023-01-16 12:25:09
probably? although huffman does lose ~7% in vardct last I checked
2023-01-16 12:25:52
although perhaps doing RLE will recover that, IDK
_wb_ Also I suppose in principle we could make an e1 vardct that is basically libjpeg-turbo with tiling and slightly improved compression. So using YCbCr and doing the color and dct transforms in int16 instead of in float.
2023-01-16 12:26:17
that we can do, but for that matter I am pretty sure we could also do it in XYB and we wouldn't lose much
2023-01-16 12:26:28
(for speed)
_wb_
2023-01-16 12:50:43
I doubt rle would make much difference for AC, we already have num_zeroes which covers the main runs. For DC it might help a bit if there are large enough areas that are perfectly predicted by ClampedGradient...
veluca
2023-01-16 12:52:42
not with ans, but with huffman it might
Demiurge
_wb_ Using the fast huffman coder of fjxl might be possible in VarDCT too, maybe?
2023-01-16 02:16:30
Why would ycbcr be faster? Avoiding the colorspace transformation would make much of a difference?
2023-01-16 02:16:59
Also I imagine on some platforms float might actually be faster than int
2023-01-16 02:22:43
Also I was thinking a bit about DCT and macroblocking, and I was thinking, since the coefficients basically describe the amplitude of waves in particular frequencies, can't those waves be interpolated across block boundaries by making each block aware of the values of neighboring blocks so it can be smoothly interpolated across block boundaries rather than have a hard edge?
2023-01-16 02:27:35
So if the amplitude of a particular DCT coefficient is high in one block and zero in the space to the right of it, instead of having a hard edge there, couldn't the wave be interpolated and predicted somehow across the block boundaries?
Tirr
_wb_ with lossy modular? are you simply using zero values for the not-yet-decoded channels?
2023-01-16 02:47:52
with progressive modular, using zeroes yeah
_wb_
Demiurge Also I was thinking a bit about DCT and macroblocking, and I was thinking, since the coefficients basically describe the amplitude of waves in particular frequencies, can't those waves be interpolated across block boundaries by making each block aware of the values of neighboring blocks so it can be smoothly interpolated across block boundaries rather than have a hard edge?
2023-01-16 03:41:33
Yes, that's how some 'smooth' jpeg decoders work β€” instead of dequantizing in the naive way (just multiplying), adjust the value within the quantization bucket based on the neighboring blocks.
Demiurge Also I imagine on some platforms float might actually be faster than int
2023-01-16 03:43:15
I think int16_t multiply/adds should be faster than float32 on pretty much any platform, in particular when memory bandwidth is a bottleneck.
OkyDooky
2023-01-16 05:01:09
Smol question, does progressive mode use var DCT?
2023-01-16 05:02:40
There isn't a fixed number of dcts in vardct, isn't it tricky to order them for progressive?
yurume
2023-01-16 05:03:09
there is no single progressive mode in JPEG XL, you can organize the input so that it can be progressively decoded
2023-01-16 05:03:19
and this organization doesn't depend on whether VarDCT is being used or not
2023-01-16 05:03:52
the first layer would be a smaller image that is downscaled by 8x8, which is always present regardless of the mode
2023-01-16 05:04:58
for VarDCT each varblock has its transformation fixed early in the decoding process, but its coefficients can be progressively delivered
2023-01-16 05:05:38
let me phrase this differently:
2023-01-16 05:08:03
the image can be decomposed to multiple ways, and can be ordered so that the prefix sum is progressively reaching the desired output
2023-01-16 05:10:06
common to both modes, this decomposition always includes 8x8 downscaled image ("low-frequency image" aka LF), which will be (but not required to be) placed before everything else
2023-01-16 05:10:48
(sorry, I deleted one message from Discord and I realized you will still see it from Matrix, please disregard the first one following "let me phrase this differently" πŸ˜‰
2023-01-16 05:11:07
for the modular mode further decomposition can be done via Squeeze transformation
2023-01-16 05:11:48
for the VarDCT mode, once transformed varblock-wise, coefficients can be freely decomposed because they are still additive
2023-01-16 05:12:42
if you have coefficients (3, 10, -7, 5), this can be decomposed to (3, 10, 0, 0) + (0, 0, -7, 5) or (3, 10, 0, 5) + (0, 0, -7, 0) or even (5, 10, -5, 5) + (2, 0, -2, 0)
2023-01-16 05:13:10
encoders have much freedom in choosing how to decompose those coefficients
2023-01-16 05:14:01
AFAIK it is even possible to show some image and then progressively overwrite to the final image, as you are allowed to add values to already decoded coefficients
2023-01-16 05:14:45
it would be no longer "progressive" per se (poor man's animation? lol) but still
Demiurge
2023-01-16 07:04:36
For enormous images the LF image can itself be progressively encoded, too.
sklwmp
2023-01-16 07:06:40
progressive inception
yurume
2023-01-16 07:07:09
I should note that unlike other progressiveness the LF image is mandatory in JPEG XL, i.e. you always have some level of progressiveness available
2023-01-16 07:07:46
but otherwise you have tons of options available, the current encoder only makes use of a small number of combinations
Tirr
2023-01-16 11:06:01
jxl-oxide can now do cropped decoding (at least with my test images)
2023-01-16 11:06:46
with some exceptions: using delta-palette forces full decoding, using squeeze makes the cropped region expand to top-left corner
_wb_
2023-01-16 11:09:19
Nice!
2023-01-16 11:11:46
For delta-palette there's no way to avoid decoding all rows above, but I'm curious what happens with squeeze when you don't decode groups outside the crop...
Tirr
2023-01-16 11:12:39
tendency computation might be messed up if we don't decode previous rows or columns
2023-01-16 11:13:31
but I didn't check it visually
_wb_
2023-01-16 11:14:24
Obviously squeeze does have data dependencies for the tendencies, but we never did the math to check if there's a bound to how far those dependencies can reach β€” can it go arbitrary distances, or is there some bound to how many extra pixels are needed before it's guaranteed that the error cannot propagate further?
veluca
2023-01-16 11:15:50
I never did the math either but I think I can say with 90% confidence that you'll get at least off by 1 errors at arbitrary radius in patological cases
_wb_
2023-01-16 11:16:13
If there's some bound like a border of 16 pixels around the crop, then that's not too bad, in general crop coords will not be aligned with groups anyway so you'll decode an extra border of 128 pixels on average anyway
2023-01-16 11:18:10
It would be interesting to see what happens in a non-pathological case, and then maybe to try to construct a pathological case where the error does propagate arbitrarily far.
2023-01-16 11:19:21
(unless of course the non-pathological case already looks like garbage)
Tirr
2023-01-16 11:34:58
I did a quick test with a Minecraft screenshot, it does contain errors around group border (crop region is aligned)
2023-01-16 11:35:13
but it's not that severe
2023-01-16 11:36:59
(note the broken colors around the left border)
_wb_
2023-01-16 11:40:47
That purple is error right? And probably there's also some smaller error that's just hard to see
Tirr
2023-01-16 11:43:59
yeah that is visible one, I agree that there are more errors
_wb_
2023-01-16 11:48:20
I suspect either there are (probably only pathological but possibly also real) cases where errors can propagate arbitrarily far from the decoded border, or some kind of bound can be proven that the error cannot propagate farther than something like [some constant like 1 or 2] times bitdepth pixels away from the border.
2023-01-16 11:51:09
Or like constant * bitdepth * nb_squeeze_steps or something
retr0id
2023-01-16 06:42:21
how do I encode a lossless jxl from the imagemagick command line?
2023-01-16 06:42:31
i.e. `convert foo.png bar.jxl`
2023-01-16 06:43:40
(but lossless)
2023-01-16 06:45:33
seems like the answer is `-quality 100` :)
Demiurge
2023-01-16 07:18:48
why do people use imagemagick instead of graphicsmagick?
Demiurge Also I was thinking a bit about DCT and macroblocking, and I was thinking, since the coefficients basically describe the amplitude of waves in particular frequencies, can't those waves be interpolated across block boundaries by making each block aware of the values of neighboring blocks so it can be smoothly interpolated across block boundaries rather than have a hard edge?
2023-01-16 07:21:27
A good way to visualize what I'm saying here is take for example this image: https://commons.wikimedia.org/wiki/File:DCT-8x8.png If you look at the 4th pattern, where it's "dark-bright-dark-bright," with dark on one border and bright on the opposing border, if you imagine that pattern repeated next to eachother by taking copies of those block and putting them side by side, you'll see obvious block boundaries, it won't look like a smooth transition at all, at least going by that image.
2023-01-16 07:23:40
Even though each coefficient is supposed to be describing a smooth sine wave, it doesn't look smooth. It looks like a chunk of the sine wave was cut off where one sample it's absolute high and the next sample it's absolute low, with no transition in between.
2023-01-16 07:31:11
If this was a good visualization of the frequencies, then you should be able to stack the same square side by side with itself and it should look like a smooth wave.
2023-01-16 07:35:50
Hmm, but there's probably more too it as well. It just feels like there's something better that could be done with the coefficients to avoid macroblocking. Because macroblocking is basically aliasing.
2023-01-16 07:36:07
It's high frequency data that isn't in the coefficients, but is added during decoding.
2023-01-16 07:36:39
There's nothing inherent in the way the information is being stored that causes macroblocking, just how it's decoded
sklwmp
Demiurge why do people use imagemagick instead of graphicsmagick?
2023-01-17 01:09:57
or the inverse, why use graphicsmagick?
Demiurge
2023-01-17 03:49:12
idk if imagemagick is just more well known or something, or if there's some other reason, but graphicsmagick has a lot of advantages over imagemagick that are listed on the website. Mainly, cleaner code, and it doesn't pollute your PATH with a bunch of really vague and generic sounding binaries like `import` and `stream` and `identify` and `display` and `convert` and all of the other tools that are part of imagemagick as separate binaries to clutter your PATH. Also, greater stability of the API if you're a programmer using these tools in another project.
Peter Samuels
2023-01-17 04:02:33
outdated it is all magick now
2023-01-17 04:02:38
magick convert etc.
Demiurge
2023-01-17 04:07:34
News to me. On Arch Linux it's still like this:
Traneptora
2023-01-17 04:08:49
it's an optional build option for backwards compat
Demiurge
2023-01-17 04:09:59
also that's still more to type than `gm convert`
Traneptora
2023-01-17 04:10:28
"magick" being a longer string than "gm" is really irrelevant
Demiurge
2023-01-17 04:11:22
Also the code really does seem to be more organized.
2023-01-17 04:11:31
Here's an example
2023-01-17 04:11:48
https://sourceforge.net/p/graphicsmagick/code/ci/default/tree/coders/jxl.c https://github.com/ImageMagick/ImageMagick/blob/main/coders/jxl.c
Traneptora
2023-01-17 04:11:52
I don't doubt that, but an end user tends not to care about that
Demiurge
2023-01-17 04:13:01
Knowing little about the two projects aside from my initial impressions, gm makes a better impression
Traneptora
2023-01-17 04:13:25
graphicsmagick is notably missing a few very convenient features that imagemagick has
Demiurge
2023-01-17 04:14:58
Which features?
2023-01-17 04:15:15
I know they both added JXL support at around the same time.
Traneptora
2023-01-17 04:16:56
here's a list I found from a quick google search
2023-01-17 04:16:57
https://stackoverflow.com/a/56220630
2023-01-17 04:17:07
Personally, I've used the combination operations
2023-01-17 04:17:26
parenthesized processing that is
sklwmp
Demiurge Knowing little about the two projects aside from my initial impressions, gm makes a better impression
2023-01-17 04:23:16
From a very superficial point of view, ImageMagick's website is a lot nicer than GraphicsMagick's, which, while probably irrational, doesn't help to convince me that GM is really better. It does sound very interesting though.
Demiurge
2023-01-17 04:37:42
I wasn't looking so much at how the website looks, but how the project source superficially looks, plus the fact that they had all tools merged into one tool from the beginning, plus the emphasis on their website of code quality and correctness that makes a good impression on me.
2023-01-17 05:00:53
Another nice thing is that the gm website explains how to use an alternate memory allocator and explains why this might be desired because of the memory allocation pattern of gm. It gives the impression that a lot more thought and care and love has been put into making gm.
2023-01-17 05:01:15
IM on the other hand seems more hastily thrown together.
2023-01-17 05:02:19
And has less detailed information, and a lot more information is from the perspective of Windows users.
diskorduser
2023-01-17 01:17:36
Imagemagick good.
2023-01-17 01:19:31
Good enough
zamfofex
Peter Samuels magick convert etc.
2023-01-17 02:26:40
You shouldn’t use `magick convert` but rather just `magick`. `magick convert` will use the outdated argument parser, much like `convert`, whereas just `magick` won’t.
2023-01-17 02:29:26
(See: <https://stackoverflow.com/a/61208844>)
joppuyo
You shouldn’t use `magick convert` but rather just `magick`. `magick convert` will use the outdated argument parser, much like `convert`, whereas just `magick` won’t.
2023-01-17 04:33:40
Is there like a tutorial or something that lists all the new commands? It’s hard to find any resources about the new syntax compared to the old one because it’s so established throughout the years
sklwmp
2023-01-17 04:39:02
I think we're getting a bit <#806898911091753051>, might be best to move to that or to <#803663417881395200> (?)
Demiurge
joppuyo Is there like a tutorial or something that lists all the new commands? It’s hard to find any resources about the new syntax compared to the old one because it’s so established throughout the years
2023-01-17 05:20:07
`man magick`
Peter Samuels
You shouldn’t use `magick convert` but rather just `magick`. `magick convert` will use the outdated argument parser, much like `convert`, whereas just `magick` won’t.
2023-01-17 05:32:08
sorry I wasn't thinking very hard and just used one of the examples given without thinking
fab
2023-01-18 03:49:50
16:49
2023-01-18 03:49:55
Updated wikidata
2023-01-18 03:50:02
With the new release
2023-01-18 03:50:22
Wikipedia will index it in all language in a thirty minutes
2023-01-18 03:51:02
I did on phone hopefully is not tracked
2023-01-18 03:51:12
frial456
2023-01-18 03:59:16
Wikipedia is not updating
2023-01-18 05:12:44
Ok done all language it en es
Traneptora
2023-01-18 09:12:52
does anyone know where I can find the original JPEG specification?
2023-01-18 09:13:03
the one from the 1990s
_wb_
2023-01-18 09:49:58
https://www.w3.org/Graphics/JPEG/itu-t81.pdf
Orum
2023-01-19 11:56:58
did target size get removed from cjxl?
Demiurge
2023-01-20 12:27:11
I don't remember that being a feature
_wb_
2023-01-20 12:48:36
it's not a very useful feature, it's only useful for testing when you want to align things on bitrate (but I would argue this is generally not the best way to evaluate image codecs, since in practice, encoding with a bitrate target rather than a quality target is rather rare)
afed
Traneptora `screenshot-high-bit-depth=yes` saving screenshots tagged as 16-bit for 8-bit video depends a bit on the other options
2023-01-20 02:29:36
I wonder if it's possible to use something other than 8 or 16-bit to save screenshots for JXL, like 10-bit, because people are making very bloated screenshots with `screenshot-high-bit-depth=yes`, I don't think 8 or even 10-bit videos really needs 16 bpc or is that how render pipeline works if any shader/upscaler is used? I understand why this is made for png because it's either 8 or 16 bpc, but for jxl it would make a lot of sense
Traneptora
afed I wonder if it's possible to use something other than 8 or 16-bit to save screenshots for JXL, like 10-bit, because people are making very bloated screenshots with `screenshot-high-bit-depth=yes`, I don't think 8 or even 10-bit videos really needs 16 bpc or is that how render pipeline works if any shader/upscaler is used? I understand why this is made for png because it's either 8 or 16 bpc, but for jxl it would make a lot of sense
2023-01-20 02:32:27
it's not possible because libjxl only accepts 8 and 16 bit buffers
afed
2023-01-20 02:36:27
sad, and if using `--override_bitdepth=10`, I think there might be some quality losses <:Thonk:805904896879493180> https://discord.com/channels/794206087879852103/848189884614705192/1065816541590978700
_wb_ it's not a very useful feature, it's only useful for testing when you want to align things on bitrate (but I would argue this is generally not the best way to evaluate image codecs, since in practice, encoding with a bitrate target rather than a quality target is rather rare)
2023-01-20 02:52:55
it might be useful for visual comparison, for example one format encodes multiple images with different qualities, then for jxl (or other formats) for each of these images is encoded similar images with exactly the same sizes and then they are compared visually there could be bd-rate plots or metric comparisons, but these methods also have problems because there are no perfect metrics
_wb_
2023-01-20 02:54:26
Yes, if you want to do subjective evaluation with a limited amount of images, aligning on a few bitrate points is the way to do it.
improver
2023-01-20 07:00:48
is 16bit as opposed to 10bit really that much worse if relevant bits are not set?
afed
2023-01-20 07:07:02
yes, it is much worse for compression, at least for images from mpv/fffmpeg
Demiurge
2023-01-20 07:07:47
probably the least significant bits are not zeroed
_wb_
2023-01-20 07:11:53
At e2+ it shouldn't matter since it will do channel palette if there are only 10-bit worth of values in a 16-bit image, regardless of how the padding bits were set.
2023-01-20 07:12:24
At e1 it will be worse for both speed and compression.
2023-01-20 07:33:05
So the CDs of the 2nd editions of 18181-1 and 18181-2 are approved, and also the white paper on the jpeg website will be updated.
2023-01-20 07:33:28
πŸ₯³
Orum
_wb_ it's not a very useful feature, it's only useful for testing when you want to align things on bitrate (but I would argue this is generally not the best way to evaluate image codecs, since in practice, encoding with a bitrate target rather than a quality target is rather rare)
2023-01-20 10:18:54
sure but the only practical way to compare two different encoders at the same BPP is to have at least one of them support a target size option, no matter how it's implemented
_wb_
2023-01-20 10:21:49
Yes. It's a pretty niche use case though (I mean not for me or other people working on image compression, but for the population in general). We can manage with just some binary search scripts or whatever.
2023-01-20 10:25:18
Also I like to assess encoder consistency (what's the variance of visual results for a given q setting), and for that you need to align things on encoder settings and sample the quality space densily enough to get accurate full curves, not just 3-4 bitrate points per codec.
joppuyo
Orum sure but the only practical way to compare two different encoders at the same BPP is to have at least one of them support a target size option, no matter how it's implemented
2023-01-20 11:33:44
can't you just run the encoder in a loop with different quality settings? πŸ˜…
2023-01-20 11:33:59
you could even use binary search
Traneptora
joppuyo can't you just run the encoder in a loop with different quality settings? πŸ˜…
2023-01-20 01:41:11
that's very slow, but yes it would work
veluca
Traneptora that's very slow, but yes it would work
2023-01-20 01:41:49
it's also pretty much how target-size was implemented
2023-01-20 01:42:27
but cjxl_bisect_bpp exists (so does cjxl_bisect_size)
Orum
joppuyo can't you just run the encoder in a loop with different quality settings? πŸ˜…
2023-01-20 02:23:05
yeah, it's just more work on my end, which is why I was wondering why the option disappeared
_wb_
2023-01-21 01:54:19
It disappeared when we simplified cjxl to use libjxl instead of directly calling stuff without using the api, I guess
Demiurge
Orum yeah, it's just more work on my end, which is why I was wondering why the option disappeared
2023-01-21 08:29:41
Oh that's right. cjxl was rewritten from scratch and the old cjxl was chucked in the trash. That's why.
_wb_
2023-01-21 12:38:05
That makes it sound more dramatic than it is. Both old and new are using the libjxl code for all of the actual encoding. It's just that now it calls the encoder through the api, and before it called it directly.
afed
veluca but cjxl_bisect_bpp exists (so does cjxl_bisect_size)
2023-01-21 12:56:43
sadly this is not a cross-platform tool and does not work under windows (needs shell compatibility and etc)
DZgas Π–
2023-01-23 12:40:56
well
2023-01-23 12:41:17
me again.
2023-01-23 12:41:25
2023-01-23 12:53:36
Oh no. the "bug" was fixed in the latest builds. I don't seem to have anything to work on here <:AngryCry:805396146322145301>
2023-01-23 12:55:49
Demiurge
2023-01-23 04:57:01
I think lossy mode leaves a lot to be desired personally still. Still a lot of strange ringing and color bleeding compared to other codecs
DZgas Π–
Demiurge I think lossy mode leaves a lot to be desired personally still. Still a lot of strange ringing and color bleeding compared to other codecs
2023-01-24 07:10:21
It seems to you. other codecs have the same problems, especially webp.
Demiurge
2023-01-24 07:16:46
Well I'm mostly comparing to rav1e avif
DZgas Π–
2023-01-24 07:21:27
avif have the power for compression low quality
Demiurge
2023-01-24 09:02:35
Indeed. But I am pretty sure libjxl just isn't tuned for lower bitrates.
2023-01-24 09:03:08
And that it's not a limitation in the format itself
Traneptora
2023-01-24 01:55:23
how smooth are the increase in efforts between vardct e3 and e7?
2023-01-24 01:55:44
is it fairly linear, or is it something like e4 being a major increase over e3?
veluca
2023-01-24 02:01:16
it's by far not linear
2023-01-24 02:01:35
e6 is pretty close to e7 for most content
2023-01-24 02:02:04
e3 is much worse than e4
_wb_
2023-01-24 02:40:23
In terms of quality, I see big jumps going from e3 to e4 and from e4 to e5, then e5,6,7 are quite similar (at least for photo), then e8 is somewhat better, and e9 is pretty much the same as e8
2023-01-24 02:44:20
in terms of speed, I see e3 is not much faster than e4, then there's a big gap, then e5,6,7 are quite similar in speed too, then a very big gap to e8 and e9.
afed
2023-01-24 07:16:39
yeah, I also noticed that e3 and e4 encoding speeds are not much different, that's why I suggested to use at least e4 for lossy screenshots by default
DZgas Π–
2023-01-24 08:20:46
I use e6 if lot of photos
Jyrki Alakuijala
yurume there is no single progressive mode in JPEG XL, you can organize the input so that it can be progressively decoded
2023-01-25 09:57:48
I wasn't able to follow this concern -- could you rephrase it with different words?
yurume
2023-01-25 09:58:41
did my wording sound like a concern? I think I tried to articulate the flexibility of the JPEG XL bitstream at that time.
Jyrki Alakuijala
DZgas Π– Oh no. the "bug" was fixed in the latest builds. I don't seem to have anything to work on here <:AngryCry:805396146322145301>
2023-01-25 09:58:46
You are fixing them with us by bringing up these examples. πŸ™‚ Thank you for your kind guidance.
There isn't a fixed number of dcts in vardct, isn't it tricky to order them for progressive?
2023-01-25 10:03:58
The 8x8 dc field is used as a method to reconstuct values in larger dct. For example, a 32x32 dct would get its 4x4 corner of dct coefficients synthesized from the 8x8 dc value through running an dct on them. The other coefficients would come later in the stream, building a full 32x32 dct, which would then be idct'ed into pixels. I came up with this idea (which was easy) and Luca implemented it (which was not easy).
yurume did my wording sound like a concern? I think I tried to articulate the flexibility of the JPEG XL bitstream at that time.
2023-01-25 10:05:16
aah, now I understand it πŸ™‚ Thank you!!
2023-01-25 11:57:12
I'm still interested in quality opinions between 0.7 and 0.8 -- I'm super interested if it got worse, but also happy to hear if it is better I took some risk in adjusting the adaptive quantization and integral transform selection as well as adjusting the chromacity/luma-balance in quantization
Traneptora
afed yeah, I also noticed that e3 and e4 encoding speeds are not much different, that's why I suggested to use at least e4 for lossy screenshots by default
2023-01-25 02:16:57
that's what I'm considering, changing the default to e4
2023-01-25 02:26:55
but before I do so I want to investigate the 8bit videos being saved as 16bit
2023-01-25 02:27:13
which shouldn't happen even with screenshot-high-bit-depth=yes
JendaLinda
2023-01-25 09:13:26
Lossy with alpha needs some improvement. Would be great to allow setting the distance for alpha channel. RGBA image, size 19590 bytes, used cjxl -e 9 RGB and alpha encoded separately: RGB image, 14861 bytes, used cjxl -e 9 alpha (gray image), 1197 bytes, used cjxl -d 0 -e 9 VarDCT + alpha is about 20% bigger than VarDCT image and lossless alpha encoded separately.
Traneptora
2023-01-25 09:39:28
I know some people reported this bug, idr who
2023-01-25 09:39:29
https://github.com/mpv-player/mpv/pull/11207
2023-01-25 09:39:35
but I got a fix in review
afed
2023-01-25 10:09:02
is this pr contains a similar fix, but also with a rewriting of many other things? <https://github.com/mpv-player/mpv/pull/10998>
2023-01-25 10:16:04
but, for some reason, not accepted yet, because there are still some issues?
DZgas Π–
2023-01-25 10:35:17
-q 100 -e 9 works only one thread?
_wb_
2023-01-25 10:40:04
some stuff will be using more threads, but I suppose the bulk of the stuff done at lossless e9 is not yet parallelized
DZgas Π–
_wb_ some stuff will be using more threads, but I suppose the bulk of the stuff done at lossless e9 is not yet parallelized
2023-01-25 10:52:49
wait, what with multithreading encode when coding in Modular mode?
2023-01-25 10:54:35
Is there some kind of parallelizability degree table?
2023-01-25 10:55:31
I've never watched it, but I'm trying -e5, the first second the load is on 2-3 of the 4 cores, and then the stable load is only on 1 core
2023-01-25 10:57:47
Although I would like something else - is there a parallelization mode with the possibility of physically dividing the image into parts? for example, on 4 identical paralepiped, when encoding the paralepipeds part on all cores
2023-01-25 10:59:12
it does not matter how they will be located. vertically like VP9, horizontally like HEVC, or block-grid like AV1, is there such a function at all?
_wb_
2023-01-25 11:23:59
Atm only e1 really encodes tiles independently (after checking palette and sampling huffman)
2023-01-25 11:25:10
At e2+, the tokens are gathered in parallel but the histogram clustering (and MA tree learning at e4+) is single threaded.
DZgas Π–
2023-01-26 07:45:08
<:Thonk:805904896879493180> πŸ‘Œ
2023-01-26 07:49:07
I didn't expect that encoding -e 5+ for a 3840x2160 image would be so long, and at the same time only on one thread, at first I started -e9, but half an hour later I realized that something was wrong...
2023-01-26 07:50:41
when I made -e5 I realized that the file size was too much... in fact, at that moment I realized that using Loseless on an image with 16 bits of color was a bad idea, and I just compress everything into -q 95
JendaLinda
JendaLinda Lossy with alpha needs some improvement. Would be great to allow setting the distance for alpha channel. RGBA image, size 19590 bytes, used cjxl -e 9 RGB and alpha encoded separately: RGB image, 14861 bytes, used cjxl -e 9 alpha (gray image), 1197 bytes, used cjxl -d 0 -e 9 VarDCT + alpha is about 20% bigger than VarDCT image and lossless alpha encoded separately.
2023-01-26 09:29:01
The first test was juts a simple circle cutout from a photo. For the next test, I've tried something more organic, with lots of details around the edges. VarDCT (RGB + alpha): 531574 bytes VarDCT (only the RGB part): 313223 bytes Lossless (only the alpha as grayscale): 118784 bytes Again, in VarDCT, alpha is encoded about 20% less efficiently. AFAIK VarDCT can only work with 3 channels, so modular has to be used for the remaining channels. And lossy modular on its own is not that good. WebP can do lossy RGB with lossless alpha so why couldn't JXL do as well?
_wb_
2023-01-26 10:17:40
It can. But we need to expose it in the API, currently alpha quality is tied to color quality and that's not always a good idea.
2023-01-26 10:18:18
(especially since lossy modular can in some cases be larger than lossless)
JendaLinda
2023-01-26 10:44:10
Yes, lossy modular is even larger than png.
2023-01-26 10:59:11
At least in the case of circle cutout. Now I've tried to encode the more complex alpha channel as grayscale jxl with lossy modular and it's actually smaller. What's going on here?
2023-01-26 11:03:36
The same grayscale bitmap, as alpha channel it's approximately 208351 bytes, as a separate gray image, it's 92895 bytes. Both should be modular with distance 1.0, right?
_wb_
2023-01-26 11:23:41
No, it uses a higher quality for alpha than for the color image, to be on the safe side. Maybe we should lower the default alpha quality...
JendaLinda
2023-01-26 11:32:30
I'd rather see lossless alpha. Loweing alpha quality doesn't seem to be a good idea.
2023-01-26 11:41:22
Let's add the option to set alpha quality in the API. There are many options in the API, that are not very useful for general use. This one would be actually useful.
Demiurge
2023-01-26 11:45:11
Literally everyone and their mom (and their pet goldfish) exposes the completely useless option to force modular mode when it hurts quality and compression, even ffmpeg
OkyDooky
2023-01-26 11:49:50
well if it is an option in the API then applications are obviously going to expose it one way or another
Jyrki Alakuijala
JendaLinda Lossy with alpha needs some improvement. Would be great to allow setting the distance for alpha channel. RGBA image, size 19590 bytes, used cjxl -e 9 RGB and alpha encoded separately: RGB image, 14861 bytes, used cjxl -e 9 alpha (gray image), 1197 bytes, used cjxl -d 0 -e 9 VarDCT + alpha is about 20% bigger than VarDCT image and lossless alpha encoded separately.
2023-01-26 01:22:05
Sounds perfectly reasonable. Would you file a bug for this if we don't have it already?
Traneptora
afed is this pr contains a similar fix, but also with a rewriting of many other things? <https://github.com/mpv-player/mpv/pull/10998>
2023-01-26 03:07:58
that's a good question, and I don't know the answer
Demiurge Literally everyone and their mom (and their pet goldfish) exposes the completely useless option to force modular mode when it hurts quality and compression, even ffmpeg
2023-01-26 03:09:52
do you have any suggestions on more important options to expose in the ffmpeg encoder wrapper?
DZgas Π–
2023-01-26 05:58:11
lately I haven't noticed any artifacts at all, I need to go back to my test image
2023-01-26 06:00:04
new bug on e 7
2023-01-26 06:00:32
for the first time I see such an artifact, a white halo
2023-01-26 06:01:41
the borders of the blocks still have completely incomprehensible artifacts
2023-01-26 06:03:32
The e 3 mode still does the job perfectlyThe e 3 mode still does the job perfectly
2023-01-26 06:12:40
```benchmark_xl.exe --input=12.png --codec=jxl:7:d1.0 --debug_image_dir=. benchmark_xl.cc:144: JXL_CHECK: speed_stats.GetSummary(&summary)``` I can't create the jxl block map using Windows after half of year
Yari-nyan
2023-01-26 07:32:30
fast_lossless is really neat. it takes around 4 seconds (JXL) vs 6 seconds (QOI) to encode the "Cosmic Cliffs" image, while using 125.1 MB (JXL) instead of 159.3 MB (QOI) decoding also seems much faster with the JXL, although `magick convert`ing to `farbfeld:-` is a pretty shoddy benchmark.
2023-01-26 07:33:27
JPEG XL too slow? fear not mortals
2023-01-26 07:34:36
i forgot <#803645746661425173> existed, oh well, this isn't very scientific
Traneptora
DZgas Π– for the first time I see such an artifact, a white halo
2023-01-26 09:28:15
try disabling gaborish and see if that fixes the white halo
2023-01-26 09:28:34
if so, then the libjxl encoder isn't correctly detecting when it shouldn't be used
_wb_
2023-01-26 09:57:59
Or maybe the encode side gaborish needs more precision...
DZgas Π–
Traneptora try disabling gaborish and see if that fixes the white halo
2023-01-26 09:58:43
gaborish is what
Traneptora
DZgas Π– gaborish is what
2023-01-26 09:59:40
gaborish is an invertible blurring filter, where the inverse is run before encode, and then the blurring happens on decode
2023-01-26 10:00:02
which has an effect of smoothing out varblock boundaries
2023-01-26 10:00:19
`--gaborish 0` is the option in cjxl to disable it, try that and see if it helps
DZgas Π–
2023-01-26 10:02:36
aww..... is this deblocking. ... which technically always blure the picture ????
2023-01-26 10:03:48
I didn't know IT was there... I always thought that the boundaries between blocks are smoothed out by the residual bytes of values between blocks, passing into the gardients as necessary, as if mixing
2023-01-26 10:09:47
disabling this feature fixed ALL the artifacts
2023-01-26 10:10:38
does Jpeg XL have a quality parameter after which **gaborish **is not used?
2023-01-26 10:12:18
No. it used for 99 same. disable gaborish reduces the image weight by 5 times
2023-01-26 10:13:45
But now I saw another big problem
2023-01-26 10:14:26
this is an e3 image if you fill it with black
2023-01-26 10:14:48
and this is e7
2023-01-26 10:16:03
the colors just don't match the colors that they should be, they are floating, it's very bad
2023-01-26 10:18:07
this happens even on q99
Traneptora
2023-01-26 11:48:37
looks like gaborish is at fault
2023-01-26 11:48:42
should probably open an issue about that
afed
2023-01-27 02:19:42
yeah, I think gaborish needs to be significantly decreased or disabled at higher qualities (but needs testing for typical images/photos how much better/worse this will be)
2023-01-27 08:40:02
<https://www.reddit.com/r/jpegxl/comments/10lsb1y/jpegcompatible_encoding_options/> having an option for cjxl to transcode jpegli into jxl would be cool <:Stonks:806137886726553651>
DZgas Π–
Traneptora looks like gaborish is at fault
2023-01-27 08:43:09
gaborish is OFF
Traneptora should probably open an issue about that
2023-01-27 08:43:50
meh
2023-01-27 08:44:57
<@532010383041363969>
Demiurge
Traneptora do you have any suggestions on more important options to expose in the ffmpeg encoder wrapper?
2023-01-27 09:23:28
Yeah, probably filtering options that affect generational resilience like gaborish.
2023-01-27 09:23:38
Or the progressive encoding option
2023-01-27 09:26:39
Lossy modular has a lot of potential though, I wouldn't be surprised if it's better than the current state of vardct in the future.
Traneptora
2023-01-27 09:27:14
isn't progressive the default? or you mean the option that enables multiple passes
Demiurge
2023-01-27 09:28:05
the current state of vardct is pretty ugly too. I notice that for a lot of synthetic images vardct creates a lot of weird and extremely ugly, colorful fringes around edges.
2023-01-27 09:28:50
Yeah, the -p option. Maybe also the options that allow specifying the "center" too, for ROI middle-out decoding
Traneptora
2023-01-27 09:30:11
I'm not sure how the `-p` option maps to libjxl settings
2023-01-27 09:30:24
2023-01-27 09:30:36
as there's four of them
DZgas Π–
2023-01-27 10:08:26
new test image only for this case
2023-01-27 10:10:30
e7 q50 gaborish on gaborish off (brightness correction in order to see the boundaries of gradient transitions)
2023-01-27 10:11:22
(the correction is identical but the overall color is still not determined normally)
2023-01-27 10:12:50
original color FF9375 gaborish on q50 FE9476 gaborish off q50 FF9276
2023-01-27 10:12:57
in center
2023-01-27 10:13:05
2023-01-27 10:14:19
e3 q50 is FF9470 but there are absolutely no artifacts, there are only 2 colors in the image
2023-01-27 10:16:44
map of the color differences original and e7 q50 gaborish on
2023-01-27 10:17:42
e7 q50 gaborish off
2023-01-27 10:18:15
e3 q50
2023-01-27 10:20:10
Of course I have question about the color transmission accuracy; What's going on here? is the same problem as the original JPEG? jpeg simply can not save the identical color of the image if you create the 1 color picture
joppuyo
2023-01-27 10:25:39
well if it's lossy compression at 50% quality, don't you kinda expect there to be artifacts?
2023-01-27 10:26:06
here's a test I did with a 50% quality webp and photoshop paintbucket
2023-01-27 10:26:20
32% quality avif
DZgas Π–
DZgas Π– Of course I have question about the color transmission accuracy; What's going on here? is the same problem as the original JPEG? jpeg simply can not save the identical color of the image if you create the 1 color picture
2023-01-27 10:26:33
Experimentally, I found out that e3 save the color identical of the original only with **quality 97** and higher
DZgas Π– this happens even on q99
2023-01-27 10:27:35
e4-e7 they can't save identical color, they float, gradient transitions even at 99 quality
Demiurge
joppuyo well if it's lossy compression at 50% quality, don't you kinda expect there to be artifacts?
2023-01-27 10:29:38
Not really. I find this to be a poor argument since other modern encoders can compress extremely simple line-art style images much more cleanly at smaller bitrates and the encoder could be improved to be more competitive. Creating weird colorful fringes of colors that did not even exist in the original image is not good even at low bitrates.
joppuyo
2023-01-27 10:31:36
well if you really wanna preserve all the details why not use lossless compression or high-quality lossy compression?
DZgas Π–
joppuyo 32% quality avif
2023-01-27 10:31:37
what? how did you save it?
2023-01-27 10:32:03
of course AVIF only has problems with color accuracy
joppuyo
DZgas Π– what? how did you save it?
2023-01-27 10:32:29
I used the squoosh tool to do the AVIF conversion
DZgas Π–
2023-01-27 10:33:12
There should be no problems with blocks or transitions, I created this image exactly so that any BLOCK should be on one side of the color
Demiurge
2023-01-27 10:34:28
I think it would be better to use a more realistic test image like a colorful flowchart or some other form of line art
DZgas Π–
2023-01-27 10:34:44
it's really funny, but for WEBP, this is a problem exclusively in the deblock filter
joppuyo
2023-01-27 10:34:56
if this kind of color shifting happens as high quality, I think it would definitely to be bug but isn't the point of lossy compression that it will change the image by discarding some of the detail in order to make it smaller? if you use 50% quality, you are basically saying that you want a small image even if it is different from the original
DZgas Π–
2023-01-27 10:35:06
i just off deblock
Demiurge
2023-01-27 10:35:08
use avif.io, squoosh is weird.
DZgas Π–
2023-01-27 10:35:13
webp
joppuyo
2023-01-27 10:35:15
this is like using JPEG quality 50 and then complaining that the image is super blocky
Demiurge
2023-01-27 10:35:49
Yeah except we aren't using JPEG quality 50, we're using the state of the art next gen codec that will destroy JPEG
Traneptora
2023-01-27 10:36:34
I mean the quality settings were designed specifically to be similar to jpeg quality
2023-01-27 10:36:40
so the UI would translate over
Demiurge
2023-01-27 10:36:42
You can always make that argument but in this case I think that JXL is capable of a lot better than what the encoder is currently doing
2023-01-27 10:36:53
So you could say it's a bug in the encoder
DZgas Π–
DZgas Π– i just off deblock
2023-01-27 10:36:58
something interesting is happening at the border. perhaps WEBP algorithms take into account the colors of neighboring blocks and do coding depending on them
Demiurge
2023-01-27 10:37:02
Not the format itself
Traneptora
2023-01-27 10:37:13
it's really not an encoder bug that q50 produces low-quality images
2023-01-27 10:37:16
you should expect that
Demiurge
2023-01-27 10:37:43
The problem is a lot worse if you use a realistic test image rather than these images.
2023-01-27 10:37:53
Bad enough that it should be considered a bug
DZgas Π–
Traneptora it's really not an encoder bug that q50 produces low-quality images
2023-01-27 10:38:04
There is nothing in my image that can be compressed by reducing or increasing the quality.
Traneptora
2023-01-27 10:38:15
that said, I do think libjxl could be better about detecting when gaborish is not a good idea
DZgas Π–
2023-01-27 10:38:51
IDEALLY, at any quality from 1 to 99, the encoder should produce a Single result for my images
2023-01-27 10:39:05
AVIF do it.
Demiurge
2023-01-27 10:39:12
If you use a more realistic test image consisting of some colorful synthetic images with clearly-defined color borders, there are extremely noisy and colorful, bizarre fringes around them.
2023-01-27 10:40:18
Consisting of rainbow colors that are not in the original image
joppuyo
2023-01-27 10:40:19
I'm not against test cases to demonstrate a bug. Still, I don't think you can make a codec that performs perfectly on every kind of image in the world. also JXL already has a mode that compresses that image way better, it's modular
Demiurge
2023-01-27 10:40:29
That is not acceptable or expected behavior at all
DZgas Π–
2023-01-27 10:40:54
AVIF just do 634 byte on q0 and 6**43** byte on q99
Demiurge
2023-01-27 10:42:16
Yes, I have noticed lossy modular mode actually perform better than vardct in that situation, to my surprise, despite the lack of tuning, although I really think something is very wrong with vardct mode for it to be doing that. I don't think that is normal at all
DZgas Π–
2023-01-27 10:42:18
the difference between using gaborish+e7 and just e3 in image size is 20-50 times
Traneptora
2023-01-27 10:42:46
well you shouldn't expect e3 to be as good at e7
2023-01-27 10:42:58
e3 is a very dumb mode, it essentially is just a glorified xyb jpeg with ans
2023-01-27 10:43:05
only 8x8 blocks for example
DZgas Π–
Traneptora well you shouldn't expect e3 to be as good at e7
2023-01-27 10:43:11
I'm saying this is totally not normal
Traneptora
2023-01-27 10:43:23
idk I think e3 and e7 producing different results to be totally normal
DZgas Π–
Traneptora e3 is a very dumb mode, it essentially is just a glorified xyb jpeg with ans
2023-01-27 10:44:06
which at the same time works perfectly
2023-01-27 10:44:55
there are no artifacts, there are no gradients where there should not be, there is no filter that does not work correctly in this case
2023-01-27 10:45:29
but again, the question is - what about the accuracy of color transfer?
2023-01-27 10:45:43
and this problem concerns all the quality options and encoding parameters, even e3
2023-01-27 10:46:53
now I can ask harder - what 38 bits per color can we talk about if the encoder cannot Save correct color even for 8 bits per color image??
2023-01-27 10:50:35
I think I'll ask about it in contact-devs
Demiurge
2023-01-27 11:09:18
Later on I will post some examples of colorful graphics that develop strange rainbow fringes when compressed with JXL. With some AVIF comparison. I'm testing at -q 75 but even at -q 90 you can faintly see weird hallucinatory colors that are not supposed to be there.
DZgas Π–
Demiurge Later on I will post some examples of colorful graphics that develop strange rainbow fringes when compressed with JXL. With some AVIF comparison. I'm testing at -q 75 but even at -q 90 you can faintly see weird hallucinatory colors that are not supposed to be there.
2023-01-27 11:09:54
are you using the latest build?
Demiurge
2023-01-27 11:10:30
It's not the kind of thing that can be easily brushed away as "oh well, what do you expect, it's lossy"
DZgas Π–
DZgas Π–
2023-01-27 11:10:33
some problems with colors have already been solved
Demiurge
2023-01-27 11:10:56
Not nightly, no. Just 0.8
DZgas Π–
Demiurge Not nightly, no. Just 0.8
2023-01-27 11:11:26
https://artifacts.lucaversari.it/libjxl/libjxl/
2023-01-27 11:11:54
you have to use the latest build that is here
2023-01-27 11:12:07
must
Demiurge
2023-01-27 11:12:15
Nice, static builds :)
2023-01-27 11:12:58
ok, I will try this next time.
JendaLinda
2023-01-27 02:29:42
I know it's not the main focus of JXL but "retro" PC graphics can take advantage of low bit depths. CGA/EGA graphics can be losslessly stored using 2 bit samples. VGA graphics can be losslessly stored using 6 bit samples. The original VGA design used 6 bit DAC and palette registers rather than 8 bit. So most of the graphics in PC DOS games will perfectly fit into 2 bit or 6 bit JXL.
_wb_
2023-01-27 02:32:34
for lossless that's fine, palettes will be detected and will be encoded efficiently
Demiurge
2023-01-27 02:34:02
Just no fancy palette ordering optimization
JendaLinda
2023-01-27 02:35:32
The nature of such graphics is that lossless will be usually more efficient than lossy. VGA graphics uses max 256 colors on screen at the same time.
2023-01-27 02:39:01
CGA and EGA uses max 16 colors at the same time. JXL will just reduce it to palette.
2023-01-27 02:54:41
However, this is the area, where PNG is pretty good too, so it can beat current JXL encoder.
BillyL’Bob✨
2023-01-27 07:41:14
is the brotil special for jxl or is it the as the git version?
_wb_
2023-01-27 07:54:40
Nothing special, you can also just use a system brotli
BillyL’Bob✨
2023-01-27 07:59:50
<@794205442175402004> Did you ever considered using Zstandard, from my personal experience things using Pea zip I noticed that it tends to have a better compression ratio, for the same time compared to time then broil. Obviously, the JPEG XL bitstream is frozen now but we might be able to adapt Zstandard’s method of entropy coding for a faster decoding and encoding. I believe zed standard had also some kind of preprocessing might be good for effort level 9.
veluca
2023-01-27 08:01:34
the entropy coder in jxl is not the one in brotli, and is more flexible than what zstd uses πŸ˜‰
2023-01-27 08:02:00
also image and text compression are completely different beasts
BillyL’Bob✨
2023-01-27 08:04:02
<@179701849576833024> what is brotli use for in jpeg xl? Thank for helping me
Fraetor
BillyL’Bob✨ <@179701849576833024> what is brotli use for in jpeg xl? Thank for helping me
2023-01-27 08:10:16
Brotli is used for compressing metadata boxes, such as EXIF or ~~ICC profiles~~. Due the form this data takes (often a lot of XML), brotli is actually very good at compressing it. While zstd may be faster than brotli, this metadata is usually small so decodes fast enough.
_wb_
2023-01-27 08:17:32
The main image data is not using Brotli at all. You can render jxl images without needing brotli. Brotli is indeed only used for compressed metadata, and also the non-image-data stuff needed to do lossless jpeg recompression.
DZgas Π–
2023-01-27 08:50:56
technically, to compress the gradient of an image in JPEG XL, is it possible to take only 2 colors components gradients and thereby create transitional values? and it can also be done with large blocks of 64x64 or more. or does it **already **work that way?
_wb_
2023-01-27 08:52:45
Using DCT, such a gradient is basically just one DC coeff (for the average value) and two low frequency AC coeffs, and everything else is zeroes.
Traneptora
2023-01-28 04:08:56
does anybody have sample PNGs with sBIT set?
Fraetor Brotli is used for compressing metadata boxes, such as EXIF or ~~ICC profiles~~. Due the form this data takes (often a lot of XML), brotli is actually very good at compressing it. While zstd may be faster than brotli, this metadata is usually small so decodes fast enough.
2023-01-28 04:10:03
brotli isn't used for ICC btw, the standard entropy coding used for JXL itself
_wb_
2023-01-28 04:14:10
Also generally you can use the enum to signal colorspaces, icc should only really be needed for cmyk and exotic profiles...
Demiurge
2023-01-28 04:26:14
Shouldn't alien colorspaces just be converted to one of the enum colorspaces if possible during conversion?
2023-01-28 04:29:03
Also, unrelated question, but I've wondered... does JXL have any reversible color transforms it can use for more efficient lossless?
Fraetor
Demiurge Shouldn't alien colorspaces just be converted to one of the enum colorspaces if possible during conversion?
2023-01-28 04:38:07
Can't do that for lossless. And certain kinds of end to end processes (especially around print) make a lot more sense to keep the original colour space.
Demiurge
2023-01-28 04:39:44
Yeah, I was thinking in the context of lossy encoding. If you're doing lossy, wouldn't it make sense to convert an exotic colorspace into a standard one?
_wb_
Demiurge Yeah, I was thinking in the context of lossy encoding. If you're doing lossy, wouldn't it make sense to convert an exotic colorspace into a standard one?
2023-01-28 04:42:02
Yes, in my opinion that would usually make sense. Normalize to a standard space with a large enough gamut...
Demiurge
2023-01-28 04:45:40
I guess it would also depend on the intent of the encoder, like if it's optimizing for display on an HDR or non-HDR screen, for zoomed in or for zoomed out viewing, for printing, etc.
2023-01-28 04:46:13
Maybe it's possible to optimize for all of those things at the same time without conflict
Traneptora
Demiurge Also, unrelated question, but I've wondered... does JXL have any reversible color transforms it can use for more efficient lossless?
2023-01-29 01:29:17
42 of them
_wb_
2023-01-29 01:49:12
They're all variations of subtracting one channel (e.g. G) from the others, subtracting the average of two channels from another, and YCoCg-R (7 transforms in total), combined with all 6 permutations of RGB. And they can be chained, e.g. if there are more than 3 channels it might make sense to apply multiple RCTs (current encoder is not doing that, but e.g. CMYKA images could first do an RCT on CMY, to get something like CoCgYKA, then some other RCT on YKA since those channels might also benefit from that...
mothmoon
2023-01-30 05:50:59
hey, i remember someone posting something about like. being able to pick what parts of the image get more/less compression (or like, block sizes?? not sure..) a while back, but i can’t find it again sorry this is vague , but if anyone has a clue what i’m referring to, i’d really appreciate a link to it n_n
Jyrki Alakuijala
_wb_ Using DCT, such a gradient is basically just one DC coeff (for the average value) and two low frequency AC coeffs, and everything else is zeroes.
2023-01-30 12:53:08
if you use 16x16 or bigger transforms, the 8x8 dc will automatically fill the coefficients of the dct with the idct of the dc field filling the NxN upper-left-hand corner of the dcts. For example, for 32x32 DCT, the 4x4 corner would be filled -- this gives okeyish interpolation of the values where the remaining quantization error can be blurred with epf
2023-01-30 12:54:41
for the dc itself, you can use predictors with constant residual to create pretty much any direction/slope
Demiurge
2023-01-30 01:39:59
So then, the current lossless encoder uses RCTs to reduce correlation in color channels?
_wb_
2023-01-30 03:41:51
yes, only for the first 3 channels though (RGB), for any extra channels it's not trying to use RCTs
Demiurge
2023-01-30 11:00:26
And not for losslessly-recompressed JPEG right?
_wb_
2023-01-31 07:02:13
No. It could in principle (for DC only, AC has its own encoding). But it currently doesn't.
Demiurge
2023-01-31 07:46:27
I wonder if there will ever be a good enough impetus to have a low complexity profile for JXL.
2023-01-31 07:48:16
My instinct tells me probably not, but I wonder if there is a low complexity subset that captures 99% of the performance of JXL while having orders of magnitude better worst-case complexity.
2023-01-31 07:49:00
And if that is something that's even important to begin with for an image decoder.
_wb_
2023-01-31 08:14:54
it's too early now, but if/when hardware implementations are available, we'll likely define such a profile. Limited block size, no splines or patches, simple modular stuff only.
2023-01-31 08:15:59
For software implementations, I don't think it is worth it to have a low complexity profile. Sure, you could perhaps make a decoder in 30 kb instead of 100 kb, but who really cares?
Demiurge
_wb_ For software implementations, I don't think it is worth it to have a low complexity profile. Sure, you could perhaps make a decoder in 30 kb instead of 100 kb, but who really cares?
2023-01-31 08:26:02
the people writing alternate decoders...
2023-01-31 08:28:28
If you ever do start thinking about a constrained profile, I hope that it doesn't sacrifice hardly any compression efficiency. Otherwise I don't think it will catch on.
2023-01-31 08:28:43
It would have to be literally invisible and unnoticeable.
2023-01-31 08:29:03
or it would just get ignored
2023-01-31 08:29:53
Like around ~1% loss
2023-01-31 08:30:13
Or less
2023-01-31 08:31:20
But I think that's pretty realistic if the goal is only to improve the worst-case complexity
_wb_
2023-01-31 08:31:27
a hardware profile would mostly just be a limitation in functionality (e.g. only RGB, no alpha, no layers, no patches, no splines, no multiple progressive scans, etc), and then also some restrictions that will reduce compression performance, but not by much.
2023-01-31 08:32:00
basically something like what libjxl-tiny is doing
Demiurge
2023-01-31 08:33:55
Well that sounds like a very specialized and internal use of the codec that isn't meant to be shared outside of its own embedded environment. There wouldn't be any need to standardize something like that.
2023-01-31 08:35:03
A lot of the compression advantage of JXL comes from the color transforms alone.
2023-01-31 08:36:14
put too many restrictions on and you're back to basically using JPEG
yurume
_wb_ For software implementations, I don't think it is worth it to have a low complexity profile. Sure, you could perhaps make a decoder in 30 kb instead of 100 kb, but who really cares?
2023-01-31 08:36:19
technically speaking there had been enough interest in making decoders for general compression formats (specifically DEFLATE); but I do think that's mostly because those formats are too ubiquitous to ignore even in embedded settings.
_wb_
Demiurge Well that sounds like a very specialized and internal use of the codec that isn't meant to be shared outside of its own embedded environment. There wouldn't be any need to standardize something like that.
2023-01-31 08:40:37
it could be nice if you can take pictures on one camera and view them on another, but yes, generally hw encoding is more important for still images than decoding and encoders don't require standardization/profiles...
afed
DZgas Π– this is an e3 image if you fill it with black
2023-01-31 09:25:55
weird, on this image for benchmark_xl jpegli I also get this error: `tools\benchmark\benchmark_xl.cc:144: JXL_CHECK: speed_stats.GetSummary(&summary)` but jxl encodes fine or if I optimize or resave png then jpegli will also work fine <@794205442175402004> could it be some specific color conversion for jpegli?
_wb_
2023-01-31 09:28:47
no idea, I haven't played much with jpegli yet
afed
2023-01-31 09:39:05
and about unexpected distortions that are clearly visible, I only found a color shift for jpejli-xyb, even at higher quality
2023-01-31 09:39:40
here https://i.imgur.com/a8uoopA.png
2023-01-31 09:39:57
DZgas Π–
2023-01-31 09:50:11
<@1028567873007927297> What is EPF?
Demiurge
2023-01-31 09:50:41
Edge Preserving Filter, you can set it to zero to disable.
2023-01-31 09:50:49
Same with gaborish
2023-01-31 09:51:31
idk if there are other pre/post processing filter options, I think just those two
DZgas Π–
afed weird, on this image for benchmark_xl jpegli I also get this error: `tools\benchmark\benchmark_xl.cc:144: JXL_CHECK: speed_stats.GetSummary(&summary)` but jxl encodes fine or if I optimize or resave png then jpegli will also work fine <@794205442175402004> could it be some specific color conversion for jpegli?
2023-01-31 09:57:34
what commands do you enter? are you using windows?
afed
2023-01-31 10:01:20
any for jpegli and for the example this is a fixed png, for which the encoding works fine
DZgas Π–
afed any for jpegli and for the example this is a fixed png, for which the encoding works fine
2023-01-31 10:03:54
why are you using this particular image? I showed by the example of him that e5+ has big problems with color fluctuations everywhere
2023-01-31 10:04:15
<@1034873369314730065> my original for test
Demiurge Edge Preserving Filter, you can set it to zero to disable.
2023-01-31 10:06:19
well well
afed
DZgas Π– why are you using this particular image? I showed by the example of him that e5+ has big problems with color fluctuations everywhere
2023-01-31 10:07:50
just randomly testing
DZgas Π–
Demiurge idk if there are other pre/post processing filter options, I think just those two
2023-01-31 10:08:10
pre/post shit that damage my gold pixels <:AngryCry:805396146322145301>
Demiurge
2023-01-31 10:08:53
I think that stuff is probably disabled at d=1 and high fidelity/bitrate in general?
DZgas Π–
2023-01-31 10:21:41
--epf=-1|0|1|2|3 Edge preserving filter level, -1 to 3. Value -1 means: default (encoder chooses), 0 to 3 set a strength. --gaborish=0|1 Force disable/enable the gaborish filter. (not provided = default, 0 = disable, 1 = enable).
2023-01-31 10:21:59
epf=default (encoder chooses) -- **based on what?**
2023-01-31 10:28:39
the new test image, it perfectly shows the artifacts that I observe
2023-01-31 10:30:12
standard jxl q60 e7
2023-01-31 10:31:42
--epf=0 --gaborish=1
_wb_
DZgas Π– epf=default (encoder chooses) -- **based on what?**
2023-01-31 10:33:53
currently iirc it enables epf (and sets its strength) based on the quality setting: lower quality, more epf (highest qualities, no epf)
DZgas Π–
2023-01-31 10:35:39
epf=0 epf=3 difference. judging by the observations, it does not affect anything at all in these tests, artifacts leave their blocks
2023-01-31 10:36:49
epf 3 epf 0
2023-01-31 10:37:41
I see that the artifacts have become, as it were, smoothed by a filter, from this they have become more tortuous. And nothing else
2023-01-31 10:38:11
but yes, it would be better to conduct such tests when epf 0
_wb_
2023-01-31 10:41:01
what do you mean with "artifacts leave their blocks"?
DZgas Π–
_wb_ what do you mean with "artifacts leave their blocks"?
2023-01-31 10:42:09
literally that's what it means. He wakes up in the morning, goes to the train station and leaves for another block
2023-01-31 10:42:44
https://discord.com/channels/794206087879852103/848189884614705192/1068656120018771998
DZgas Π– https://discord.com/channels/794206087879852103/848189884614705192/1068656120018771998
2023-01-31 10:44:36
although the white blocks are part of the image, the strength of their wave does not block the artifacts from the color block, and therefore the artefact from the color block goes further through several more white blocks
2023-01-31 10:52:18
really interesting
_wb_
2023-01-31 10:52:52
2023-01-31 10:54:16
this the block selection I'm getting
2023-01-31 10:56:08
I don't see any artifacts
DZgas Π–
2023-01-31 10:56:35
also an interesting observation is the asymmetry of all the artifacts, they have a slope to the lower right corner, although they are still in all directions for some distance
_wb_ I don't see any artifacts
2023-01-31 10:59:25
and yet they are there, ever on an 8-bit image, although in this case it is not visible to the eye
_wb_ this the block selection I'm getting
2023-01-31 11:00:41
Of course I have a question - what is it? what does it mean? is this a incomprehensible structure - for what reason are there 8x4 blocks on a completely empty white 8x8 block???
_wb_
2023-01-31 11:02:40
no idea β€” I don't understand the ac block selection heuristics and they're likely doing suboptimal things (especially on artificial images like this)
DZgas Π–
_wb_
2023-01-31 11:03:45
But by the way, in your case, the 2 most noticeable artifacts in terms of color occur at the connection of the blocks (white on white)
_wb_
2023-01-31 11:04:46
the asymmetry of the artifacts (and the spread beyond blocks) could be caused by DC being encoded in a particular way (which in a way has a bottom-right direction)
DZgas Π–
_wb_ this the block selection I'm getting
2023-01-31 11:06:47
apropos when will benchmark_xl be repaired for windows? to create a jxl block map
_wb_ no idea β€” I don't understand the ac block selection heuristics and they're likely doing suboptimal things (especially on artificial images like this)
2023-01-31 11:09:58
*the essence of these artifacts for some reason looks like quantum effects, but from practical types it looks like waves that when they crash into the barrier (the end of the block) give part of their kinetic energy, which can be transmitted to waves located in another block*
_wb_
2023-01-31 11:10:55
the way DC gets encoded in libjxl is not just quantizing the colors, but rather quantizing the prediction residuals
DZgas Π–
2023-01-31 11:12:08
I collect bugs and give them to <@532010383041363969>
_wb_
2023-01-31 11:14:28
this gives better results in general, less banding etc, but it does cause dc to have some kind of diagonal blurring artifacts (which should be generally too small to notice but using low quality settings on artificial images these kind of dc artifacts can become visible)
2023-01-31 11:16:01
I don't think an off-by-one error in 8-bit rgb is very problematic for a q60 encode, so I don't think that should really be treated as a bug
2023-01-31 11:16:48
the ac selection is a bit weird though, it would make more sense to use only 8x16 and 16x8 here (and one 8x8 in the center)
2023-01-31 11:18:33
or even just only 8x8, since that will actually compress better than switching up the block types (all AC coeffs are zeroes anyway)
DZgas Π–
2023-01-31 11:18:51
briefly Creating a block VarDCT structure works poorly. ~~Gaborish works poorly.~~ The transmission of exact colors works poorly. With e4+ block artifacts go beyond the boundaries of their blocks and can do it 10 times more than the blocks themselves, artifacts are also noticed at the junction of blocks & they are moving towards the lower right corner. e3 continues to have no problems at all πŸ‘
_wb_ I don't think an off-by-one error in 8-bit rgb is very problematic for a q60 encode, so I don't think that should really be treated as a bug
2023-01-31 11:21:09
-q 90 -e 7 --epf=0 --gaborish=0
_wb_
2023-01-31 11:21:22
gaborish is not designed for artificial images like this...
DZgas Π–
DZgas Π– -q 90 -e 7 --epf=0 --gaborish=0
2023-01-31 11:21:58
of course I unscrewed the colors of the image. but you <@794205442175402004> , as a JPEG XL developer, can tell what the red stuff is on the side
2023-01-31 11:22:23
_wb_ gaborish is not designed for artificial images like this...
2023-01-31 11:23:52
But of course there is no mechanism that would determine this.
2023-01-31 11:25:17
I don't really understand what "epf" does, are there any pages with its tests? maybe documents?
_wb_
2023-01-31 11:25:48
not yet β€” maybe at some point we'll do something like this https://github.com/libjxl/libjxl/pull/1395 and avoid doing gaborish and dct in areas where that's counterproductive
DZgas Π–
_wb_ not yet β€” maybe at some point we'll do something like this https://github.com/libjxl/libjxl/pull/1395 and avoid doing gaborish and dct in areas where that's counterproductive
2023-01-31 11:28:01
I hope I will live to see the moment when the jpeg xl encoder will be able to determine for itself whether is an image for Modular or for VarDCT
_wb_
DZgas Π– of course I unscrewed the colors of the image. but you <@794205442175402004> , as a JPEG XL developer, can tell what the red stuff is on the side
2023-01-31 11:28:04
I don't see red stuff in the jxl file, but i'm looking at an 8-bit decoded image. what is the amplitude of the error there?
DZgas Π–
_wb_ I don't see red stuff in the jxl file, but i'm looking at an 8-bit decoded image. what is the amplitude of the error there?
2023-01-31 11:29:49
FFFFFF -> FFFEFE
2023-01-31 11:30:48
I would not be surprised by such an error, but I am worried that it occurred at a distance of 2 blocks from the red color
_wb_
2023-01-31 11:31:40
ah I see it now
DZgas Π–
2023-01-31 11:36:55
32 bit
_wb_
2023-01-31 11:38:10
I'm assuming this is caused by DC being encoded using quantized prediction residuals rather than just quantizing the DC values themselves. In principle we can do both, this is just an encoder choice. Quantizing DC values themselves results in a bigger quantization error, but it is the same everywhere (the error does not depend on blocks to the left and top) so for solid color areas it may be better. Quantizing residuals makes it possible to do way smoother gradients and avoid banding in very slow gradients, but it does lead to a bit of weirdness since errors are not quite the same everywhere but depend on blocks in the rows above and to the left of the current block.
DZgas Π–
2023-01-31 11:39:11
Very Thonk
_wb_
2023-01-31 11:41:49
basically the way we do it now, the effective precision of DC is much better in smooth regions than it is when colors are changing drastically. For photographic images, this is a good thing. For artificial images like the ones you're looking at here, this leads to some weirdness.
DZgas Π–
_wb_ basically the way we do it now, the effective precision of DC is much better in smooth regions than it is when colors are changing drastically. For photographic images, this is a good thing. For artificial images like the ones you're looking at here, this leads to some weirdness.
2023-01-31 11:43:42
I would like to solve the problem that for some reason the artifact may be outside its block - this is bad > better in smooth just need the encoder to create Bigger blocks smarter
DZgas Π– But by the way, in your case, the 2 most noticeable artifacts in terms of color occur at the connection of the blocks (white on white)
2023-01-31 03:39:21
<@532010383041363969> do you know why the structure of blocks is so bad in this case?