|
MissBehavior
|
2026-01-21 04:53:45
|
good to know
|
|
|
monad
|
2026-01-21 05:19:59
|
the stable release is stable though
|
|
|
username
|
|
_wb_
Whenever we have found a good way to dither, it would be good to make jxl-rs do something similar, and also to make as many viewers as possible also do this if possible whenever they downscale images. E.g. it would be nice if Chrome would also apply this when showing downscaled images.
|
|
2026-01-21 05:55:01
|
quality wise it seems like it's in a really good position once the current PR gets merged. Probably the only stuff to look into further would be optimization related such as if the size of the LUT could be reduced while still being acceptable visually and what veluca was suggesting with trying a low memory integer representation
|
|
|
Quackdoc
|
2026-01-21 06:10:13
|
whats the conditions needed for djxl's `display_nits` to work? this image for instance has zero difference `--display_nits=40` vs `--display_nits=4000` with ver 0.11.1
```
jxlinfo /tmp/test.jxl
JPEG XL file format container (ISO/IEC 18181-2)
JPEG XL image, 2560x1440, lossy, 32-bit float (8 exponent bits) RGB
intensity_target: 1012.500000 nits
min_nits: 0.000000
relative_to_max_display: 0
linear_below: 0.000000
Color space: RGB, D65, sRGB primaries, Linear transfer function, rendering intent: Relative
```
|
|
|
spider-mario
|
2026-01-21 07:58:28
|
it’s possible that it relies on the signalled transfer function being PQ (for Rec. 2390 tonemapping) or HLG (-> OOTF)
|
|
2026-01-21 07:58:54
|
with linear, you might just be getting the “scale 0-`intensity_target` to 0-1” behaviour
|
|
|
Quackdoc
|
2026-01-21 08:13:52
|
that would make sense, right now im just pointing people to use jxl-oxide,
|
|
|
|
runr855
|
2026-01-21 09:12:34
|
Does anyone know why this PNG fails to encode with cjxl? cjxl outputs `Getting pixel data failed.` and nothing more.
|
|
|
TheBigBadBoy - 𝙸𝚛
|
|
runr855
Does anyone know why this PNG fails to encode with cjxl? cjxl outputs `Getting pixel data failed.` and nothing more.
|
|
2026-01-21 09:31:28
|
> Warning : [minor] Trailer data after PNG IEND chunk
could it be because of that ?
|
|
|
Quackdoc
|
2026-01-21 09:34:09
|
probably, last I checked it hard crashes on that
|
|
|
TheBigBadBoy - 𝙸𝚛
|
2026-01-21 09:36:06
|
at least I get that with v0.11
|
|
|
A homosapien
|
2026-01-21 09:42:43
|
Yeah, stripping out trailing data should make it work with libjxl
|
|
|
|
runr855
|
2026-01-21 10:42:43
|
Makes sense, reading that data could probably increase chance of vulnerabilities?
|
|
|
AccessViolation_
|
2026-01-21 10:47:54
|
I can't imagine it's a deliberate choice. if it was, the sensible thing would be to ignore trailing data, rather than crash
|
|
2026-01-21 10:51:41
|
or at least error with a message that says the PNG contains errors, mentioning the trailing data
(I'd prefer that actually, because allowing slight non-compliant-ness in your input, like allowing trailing data, seems great on the surface, but the bigger picture is that the more software does that, the lesser people are discouraged from outputting incorrect PNGs)
|
|
|
jonnyawsom3
|
|
Quackdoc
whats the conditions needed for djxl's `display_nits` to work? this image for instance has zero difference `--display_nits=40` vs `--display_nits=4000` with ver 0.11.1
```
jxlinfo /tmp/test.jxl
JPEG XL file format container (ISO/IEC 18181-2)
JPEG XL image, 2560x1440, lossy, 32-bit float (8 exponent bits) RGB
intensity_target: 1012.500000 nits
min_nits: 0.000000
relative_to_max_display: 0
linear_below: 0.000000
Color space: RGB, D65, sRGB primaries, Linear transfer function, rendering intent: Relative
```
|
|
2026-01-21 11:26:19
|
https://github.com/libjxl/libjxl/issues/4085
|
|
2026-01-21 11:27:26
|
Huh, the embed didn't fill in the issue info. But display_nits is broken and has been for a while
|
|
|
runr855
Does anyone know why this PNG fails to encode with cjxl? cjxl outputs `Getting pixel data failed.` and nothing more.
|
|
2026-01-21 11:29:50
|
https://github.com/libjxl/libjxl/issues/4383
|
|
2026-01-21 11:30:10
|
I could probably look into making that a warning only
|
|
|
|
runr855
|
2026-01-22 12:18:17
|
Does cjxl parse data after IEND tag and then fail, or does it instantly stop parsing any more data? Or is it actually libpng which refuses to decode the pixels thus libjxl/cjxl never gets any actual pixels? The printed error would make perfect sense in that case
|
|
|
Quackdoc
|
|
Huh, the embed didn't fill in the issue info. But display_nits is broken and has been for a while
|
|
2026-01-22 12:41:16
|
interesting
|
|
|
Jyrki Alakuijala
|
|
AccessViolation_
speaking of, I wonder if that's also why JXL has color-bleeding artifacts rather than pure luma artifacts like some other codecs: this might be because the three color channels have different quantization tables
|
|
2026-01-22 10:29:42
|
my only contribution to the AV1 (and consequently to the AVIF) format was to get per channel quantization tables, there, too :-D, it has them
|
|
|
AccessViolation_
I remember being surprised the artifacts in AVIF were mostly luma-based. there was no color bleeding, just darkening/brightening
|
|
2026-01-22 10:32:50
|
Big difference and possibly a design mistake (or at least a feature) in JPEG XL is that the AC Strategy is the same for luma and chromacity. This makes it rather expensive to model sharper changes in chromacity through smaller transforms, because then those smaller transforms will increase the cost of the inherently more expensive luma information ((it was my decision back in the day, it has plusses and minuses))
|
|
|
jonnyawsom3
|
2026-01-22 10:34:46
|
Oh, you mean seperate DCT sizes for Luma vs Chroma?
|
|
|
Jyrki Alakuijala
|
2026-01-22 10:34:57
|
yes, AVIF has it
|
|
2026-01-22 10:35:24
|
it makes encoding much easier
|
|
2026-01-22 10:36:40
|
Also, I consider the JPEG XL images are most often viewed at a distance of more than 1000 pixels -- and this allows for psychovisual optimizations that relate to chromacity. When zooming in more, those optimizations fall apart and color transitions look funky. The same can happen with pixelized textures or even in highly noisy images.
|
|
|
A homosapien
|
2026-01-22 10:39:48
|
The Dithering Saga Continues...
|
|
|
jonnyawsom3
|
2026-01-22 10:40:46
|
I should get back to tuning the AC strategy again, but I think it makes more sense to target accepable quality instead of smaller size. Distance can always be increased and quality lowered, but raising quality also 'wastes' bits on the areas which already looked fine
|
|
|
AccessViolation_
|
|
Jyrki Alakuijala
Big difference and possibly a design mistake (or at least a feature) in JPEG XL is that the AC Strategy is the same for luma and chromacity. This makes it rather expensive to model sharper changes in chromacity through smaller transforms, because then those smaller transforms will increase the cost of the inherently more expensive luma information ((it was my decision back in the day, it has plusses and minuses))
|
|
2026-01-22 10:43:00
|
could you elaborate on what AC Strategy means here? you can signal different quant tables per component, right? so that's not it
|
|
|
|
veluca
|
2026-01-22 10:43:56
|
you can always compose two frames, one with just the luma and the other one with just the chroma 😛
|
|
|
Jyrki Alakuijala
|
|
AccessViolation_
could you elaborate on what AC Strategy means here? you can signal different quant tables per component, right? so that's not it
|
|
2026-01-22 10:43:58
|
when an area is 8x8 or 32x32, it is that for all components, cannot be 8x8 for luma and 32x32 for X and B
|
|
|
AccessViolation_
|
2026-01-22 10:44:29
|
ohh
|
|
2026-01-22 10:44:31
|
fascinating
|
|
2026-01-22 10:45:40
|
so it's "blocks have channels" rather than "channels have blocks" basically
|
|
2026-01-22 10:45:57
|
I can see why that's a lot faster
|
|
|
Jyrki Alakuijala
|
|
AccessViolation_
fascinating
|
|
2026-01-22 10:45:58
|
the same integral transform selection decision affecting X, Y and B, where Y and B are masked by Y, makes an interesting world for the encoder developer -- heuristics will be very close to minimizing maximum error, but not quite, often 8th power of 16th power or similar works the best
|
|
|
AccessViolation_
I can see why that's a lot faster
|
|
2026-01-22 10:46:58
|
I thought it could be made faster and simpler, but that was likely a fantasy that doesn't realize in real life given the 256x256 buffering is needed for threading in any case
|
|
|
AccessViolation_
|
2026-01-22 10:47:36
|
ah dang, that's unfortunate
|
|
2026-01-22 10:47:45
|
well, it's hindsight, what can ya do
|
|
2026-01-22 10:48:14
|
aside from quietly making an itty bitty change to the bitstream :3c
|
|
|
jonnyawsom3
|
2026-01-22 10:48:29
|
AVIF moment
|
|
|
Jyrki Alakuijala
|
2026-01-22 10:49:35
|
when JPEG XL matures, it is possible that we will mostly be using various kinds of 8x8s (perhaps 2x2, 8x8 with some 16x8s added into the pool), and this question is not that important -- I don't think the future world will use low quality images
|
|
2026-01-22 10:50:05
|
about half the transforms (by transform type) are 8x8 sized, so JPEG XL is well prepared for the world with smaller transforms
|
|
2026-01-22 10:51:19
|
libjxl tiny only uses dct8x8 and dct8x16
|
|
|
jonnyawsom3
|
2026-01-22 10:51:33
|
Obligatory block diagram
|
|
|
AccessViolation_
|
2026-01-22 10:51:48
|
we love the block diagram ✨
|
|
|
jonnyawsom3
|
2026-01-22 10:52:35
|
128 and 256 aren't used at all yet, I think even 64 only got 'enabled' in v0.9 so still lots of room in both the high and low quality range
|
|
|
Jyrki Alakuijala
|
2026-01-22 10:53:28
|
AFV-transform, I like to call it the corner-cutting-transform
|
|
|
AccessViolation_
|
2026-01-22 10:55:01
|
related. so I've been thinking... you can represent slow gradients fairly cheaply with a few lower frequency HF coefficients. but does the encoder consider that it's possible having just that single LF component in combination with adaptive LF smoothing, could result in a gradient that's about equally correct, while saving on having to encode the gradient explicitly?
|
|
|
Jyrki Alakuijala
|
2026-01-22 10:55:45
|
it is complicated
|
|
2026-01-22 10:56:40
|
the cosine waves are 'wavy', and LF doesn't get spatially interpolated in the 8x8 transforms, to get proper interpolated we need 16x16 at least, and then it is in that cosine-interpolation mode that is not so good
|
|
2026-01-22 10:57:23
|
in Pik we were able to solve it better because only 8x8 DCTs, we could solve the frequency lifting much more thoroughly
|
|
|
|
veluca
|
2026-01-22 03:51:51
|
I do sometimes wish we'd have specified some form of smooth interpolation of DC values, and figured out what that would do to DCT coefficients on the decoder side, but I suspect it'd be quite slow
|
|
|
_wb_
|
2026-01-22 05:13:02
|
We do have adaptive LF smoothing in the spec...
|
|
|
jonnyawsom3
|
2026-01-22 05:15:46
|
Honestly, I'm surprised it's the HF that gets hit in the quant table so hard when LF is so resilient with the adaptive smoothing. I think we could get away with a lot more there and use the spare bits to stop the HF bleed/saturation issues. Not sure how hard that'd be to do though...
|
|
|
|
veluca
|
|
_wb_
We do have adaptive LF smoothing in the spec...
|
|
2026-01-22 07:42:15
|
not going nearly as far as "upsample the DC 8x by some fancy upsampling algo and code the residuals with DCT" 😛
|
|
2026-01-22 07:42:27
|
(although I guess that can be emulated with two layers)
|
|
|
jonnyawsom3
|
2026-01-22 07:51:30
|
Couldn't a theoretical encoder do that already? Do the non-seperable upsampling and subtract it from the original image, then hand the residuals to the DCT pass
|
|
|
_wb_
|
2026-01-22 08:26:31
|
yes, with multi-frame you can do a lot in principle, not sure if it's a good idea though for decode speed
|
|
2026-01-22 08:30:02
|
changing the ratio spent on LF/HF could make sense, probably we are being too conservative on LF (but "better safe than sorry" does apply to LF imo)
|
|
|
Traneptora
|
2026-01-22 09:25:42
|
hydrium just encodes LF losslessly using gradient
|
|
2026-01-22 09:26:01
|
it was much simpler than trying to quantize
|
|
2026-01-22 09:26:24
|
plus squeeze is awful for memory
|
|
|
|
veluca
|
|
Traneptora
plus squeeze is awful for memory
|
|
2026-01-22 09:27:38
|
doesn't *need* to be
|
|
|
Traneptora
|
|
veluca
doesn't *need* to be
|
|
2026-01-22 09:35:28
|
doesn't it require you to buffer all the blocks to the top and left
|
|
2026-01-22 09:36:05
|
hydrium doesn't buffer more than a single LF tile at once
|
|
|
|
veluca
|
2026-01-22 09:36:45
|
IIRC no, just the one exactly on top or exactly on left (and even there just the last row/column thereof)
|
|
|
jonnyawsom3
|
2026-01-23 08:55:03
|
A random thought, I wonder if using 128x128 groups instead of the default 256x256 for fast lossless would give a speed bump and a bit lower memory usage
|
|
|
juliobbv
|
|
Jyrki Alakuijala
my only contribution to the AV1 (and consequently to the AVIF) format was to get per channel quantization tables, there, too :-D, it has them
|
|
2026-01-23 04:35:45
|
thanks for doing this 🙏🏻
|
|
2026-01-23 04:36:04
|
this is super useful for 4:4:4 stuff
|
|
2026-01-23 04:41:57
|
I tried to add more QM goodness to AV2, but parts of the proposal had to be reverted due to `[redacted]`
|
|
|
|
veluca
|
|
juliobbv
I tried to add more QM goodness to AV2, but parts of the proposal had to be reverted due to `[redacted]`
|
|
2026-01-23 04:42:43
|
knowing nothing, I am going to bet that `[redacted]` is related to some hardware vendor 😛
|
|
|
juliobbv
|
|
AccessViolation_
I remember being surprised the artifacts in AVIF were mostly luma-based. there was no color bleeding, just darkening/brightening
|
|
2026-01-23 04:44:10
|
this makes sense... AV1 uses flat QMs by default, so encoders overspend bits in chroma for 4:4:4 content
|
|
|
|
veluca
|
2026-01-23 04:44:20
|
btw <@297955493698076672> any thoughts about trying to do whatever magic you did to AVIF heuristics with JXL? 😛
|
|
|
juliobbv
|
|
veluca
knowing nothing, I am going to bet that `[redacted]` is related to some hardware vendor 😛
|
|
2026-01-23 04:46:04
|
very good guess, but it wasn't hardware this time... the teams were shockingly very enthusiastic with the proposal
|
|
|
AccessViolation_
|
2026-01-23 04:46:09
|
> flat QMs
hm not sure what that means
|
|
|
|
veluca
|
|
juliobbv
very good guess, but it wasn't hardware this time... the teams were shockingly very enthusiastic with the proposal
|
|
2026-01-23 04:46:43
|
you have no idea how surprising this is for me 😛 (and the next guess is some patent)
|
|
|
AccessViolation_
|
2026-01-23 04:47:37
|
oh, quantization matrices
|
|
|
juliobbv
|
|
AccessViolation_
oh, quantization matrices
|
|
2026-01-23 04:47:44
|
yeah
|
|
|
veluca
you have no idea how surprising this is for me 😛 (and the next guess is some patent)
|
|
2026-01-23 04:48:00
|
you might be onto something here 😉
|
|
2026-01-23 04:48:33
|
and it was actually not due to our proposal even
|
|
2026-01-23 04:48:47
|
but an integration issue
|
|
|
AccessViolation_
|
|
juliobbv
yeah
|
|
2026-01-23 04:48:58
|
so it's using the same matrices for chroma as it does for luma, you mean? and that's why there's no color bleeding?
|
|
|
|
veluca
|
2026-01-23 04:49:28
|
"flat" here means "same quantization factor for all the AC coefficients"
|
|
2026-01-23 04:49:35
|
(both for chroma and for luma)
|
|
2026-01-23 04:49:42
|
IIRC that (used to be) the default
|
|
|
juliobbv
|
|
veluca
btw <@297955493698076672> any thoughts about trying to do whatever magic you did to AVIF heuristics with JXL? 😛
|
|
2026-01-23 04:50:12
|
well, JXL is already doing the right things
|
|
2026-01-23 04:50:33
|
it was AVIF was actually so PSNR-maxxed that they didn't even enable basic coding tools for still image coding
|
|
2026-01-23 04:51:06
|
but certain heuristics related to screen content coding in AV1 can definitely be translated to JXL
|
|
|
AccessViolation_
|
2026-01-23 04:51:09
|
<:Thonk:805904896879493180> so it's like: every square here as the same number? all coefficients are quantized by the same amount?
|
|
|
juliobbv
|
|
AccessViolation_
<:Thonk:805904896879493180> so it's like: every square here as the same number? all coefficients are quantized by the same amount?
|
|
2026-01-23 04:51:18
|
correct
|
|
|
AccessViolation_
|
2026-01-23 04:51:35
|
oh what, I never considered that that would result in anything good
|
|
2026-01-23 04:51:55
|
fascinating
|
|
|
juliobbv
|
|
AccessViolation_
oh what, I never considered that that would result in anything good
|
|
2026-01-23 04:52:02
|
it's good in a sense that your chroma will look *really* good relative to luma
|
|
|
|
veluca
|
|
juliobbv
well, JXL is already doing the right things
|
|
2026-01-23 04:52:52
|
I figured, but too bad that there aren't easyish free wins 😛
|
|
|
juliobbv
|
|
veluca
I figured, but too bad that there aren't easyish free wins 😛
|
|
2026-01-23 04:53:46
|
IMO, if JXL can make 203 intensity the default that'd be awesome
|
|
2026-01-23 04:54:12
|
the current defaults are crushing blacks too much
|
|
|
Quackdoc
|
2026-01-23 04:54:42
|
[Hmm](https://cdn.discordapp.com/emojis/1113499891314991275.webp?size=48&name=Hmm&lossless=true)
|
|
2026-01-23 04:55:37
|
~~make it 80~~
|
|
|
AccessViolation_
|
2026-01-23 04:55:46
|
I noticed that too and brought it up, unfortunately upping the intensity target doesn't just improve compression in dark areas, it actually makes the image brighter in PQ for example
|
|
|
|
veluca
|
2026-01-23 04:56:06
|
what's the current default?
|
|
|
Quackdoc
|
|
AccessViolation_
I noticed that too and brought it up, unfortunately upping the intensity target doesn't just improve compression in dark areas, it actually makes the image brighter in PQ for example
|
|
2026-01-23 04:56:13
|
thats to be expected no?
|
|
|
AccessViolation_
|
2026-01-23 04:57:22
|
|
|
|
Quackdoc
thats to be expected no?
|
|
2026-01-23 04:58:34
|
I assumed it didn't, because in sRGB the intensity doens't change
|
|
|
jonnyawsom3
|
|
juliobbv
well, JXL is already doing the right things
|
|
2026-01-23 04:59:07
|
If you go back to v0.8 then yeah, but right now there's still a lot of work to do between re-weighting the block selection and figuring out new quant tables without desaturation
|
|
|
Quackdoc
|
|
AccessViolation_
I assumed it didn't, because in sRGB the intensity doens't change
|
|
2026-01-23 04:59:57
|
when encoding a file you are telling jxl what luminance 1.0 is, so jxl would map that to PQ
|
|
|
juliobbv
|
|
If you go back to v0.8 then yeah, but right now there's still a lot of work to do between re-weighting the block selection and figuring out new quant tables without desaturation
|
|
2026-01-23 05:00:06
|
yeah, I'd say fixing these two regressions is important, so y'all are doing the right thing
|
|
|
jonnyawsom3
|
|
juliobbv
IMO, if JXL can make 203 intensity the default that'd be awesome
|
|
2026-01-23 05:00:12
|
The current default is 255...
|
|
|
juliobbv
|
|
The current default is 255...
|
|
2026-01-23 05:00:19
|
huh
|
|
|
Quackdoc
|
2026-01-23 05:00:21
|
I would say the inverse is a bug then
|
|
|
AccessViolation_
|
|
veluca
what's the current default?
|
|
2026-01-23 05:00:25
|
255
|
|
2026-01-23 05:00:36
|
|
|
|
Quackdoc
|
2026-01-23 05:00:54
|
maybe an --luminance-bias might make sense
|
|
2026-01-23 05:01:26
|
~~though never forget mastering nits for sRGB is 80~~
|
|
|
juliobbv
|
|
AccessViolation_
255
|
|
2026-01-23 05:01:30
|
so it sounds like there might be a regression with the underlying AQ heuristic that takes in the brightness number?
|
|
2026-01-23 05:03:10
|
there's *something* going on that's causing libjxl not spend as many bits as it should in dark areas
|
|
|
jonnyawsom3
|
|
juliobbv
yeah, I'd say fixing these two regressions is important, so y'all are doing the right thing
|
|
2026-01-23 05:03:29
|
Right now "y'all" is just me unfortunately, and I've been busy the past few months with holidays and health so haven't made any progress. I'm a lot better at finding problems and suggesting solutions than I am actually fixing them 😅
|
|
2026-01-23 05:04:26
|
Fixing blue noise the other day was a very nice surprise though, silky smooth dithering for all
|
|
|
AccessViolation_
|
2026-01-23 05:04:35
|
the "all modern infrastructure" xkcd but it's JXL encoding quality and you're one of the blocks
|
|
|
juliobbv
|
|
Right now "y'all" is just me unfortunately, and I've been busy the past few months with holidays and health so haven't made any progress. I'm a lot better at finding problems and suggesting solutions than I am actually fixing them 😅
|
|
2026-01-23 05:05:27
|
yeah, fixing nontrivial issues usually takes longer, unless you're like the author of the software in question
|
|
2026-01-23 05:06:51
|
but even trying is super commendable, because making changes to codecs isn't easy
|
|
|
AccessViolation_
|
|
veluca
I figured, but too bad that there aren't easyish free wins 😛
|
|
2026-01-23 05:11:26
|
we do have the paper proposing better block merging heuristics for JXL that we haven't implemented yet. that's probably a low hanging fruit one, given that the logic is already there. they just didn't contribute the code back
|
|
|
|
veluca
|
2026-01-23 05:12:19
|
I do want $eventually to write an encoder in jxl-rs and have fun with heuristics
|
|
2026-01-23 05:12:29
|
but who knows when xD
|
|
|
jonnyawsom3
|
|
juliobbv
yeah, fixing nontrivial issues usually takes longer, unless you're like the author of the software in question
|
|
2026-01-23 05:12:39
|
It mostly takes ages because I still don't know how to code fully. Most of the fixes/improvements the past year have been me finding something via cjxl, reading the code to find what went wrong, then asking <@207980494892040194> to help me try various ideas until 5am. The spaghetti code is a blessing and a curse, because generally I can just reference the surrounding code to eg, force a predictor or enable LZ77. Libjxl is surprisingly modular but very brittle.
|
|
|
username
|
|
AccessViolation_
we do have the paper proposing better block merging heuristics for JXL that we haven't implemented yet. that's probably a low hanging fruit one, given that the logic is already there. they just didn't contribute the code back
|
|
2026-01-23 05:12:42
|
AFAIK it seems to have been done for a paid product and I don't know if it's patented or not
|
|
|
AccessViolation_
|
2026-01-23 05:12:57
|
[Improvement of JPEG XL Lossy Image Coding Using Region Adaptive DCT Block Partitioning Structure](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=9505599)
|
|
|
jonnyawsom3
|
|
AccessViolation_
we do have the paper proposing better block merging heuristics for JXL that we haven't implemented yet. that's probably a low hanging fruit one, given that the logic is already there. they just didn't contribute the code back
|
|
2026-01-23 05:13:31
|
Some papers display psuedo-code or even have the example code in a repo, but AFAIK they only gave a very high level explanation
|
|
|
AccessViolation_
|
|
AccessViolation_
[Improvement of JPEG XL Lossy Image Coding Using Region Adaptive DCT Block Partitioning Structure](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=9505599)
|
|
2026-01-23 05:13:33
|
we later found out this was implemented in a commercial JPEG XL encoder, but iirc there was nothing preventing us from implementing it too
|
|
|
|
veluca
|
|
AccessViolation_
we later found out this was implemented in a commercial JPEG XL encoder, but iirc there was nothing preventing us from implementing it too
|
|
2026-01-23 05:14:40
|
... there are commercial jpeg xl encoders?
|
|
|
AccessViolation_
|
2026-01-23 05:15:27
|
there is at least one... that one
|
|
|
username
|
2026-01-23 05:16:02
|
I remember finding the website for the product/encoder but I don't remember the URL
|
|
|
AccessViolation_
|
2026-01-23 05:16:12
|
last time I mentioned this paper, Jon mentioned that they remembered seeing one of the authors at a JPEG conference. we dug deeper, and found the encoder that uses this algorithm
|
|
|
username
I remember finding the website for the product/encoder but I don't remember the URL
|
|
2026-01-23 05:17:05
|
ahh that was you, yeah
|
|
2026-01-23 05:17:36
|
iirc they actually advertised this better quality per byte over libjxl on that page
|
|
|
username
|
2026-01-23 05:17:50
|
it might have been jonny who found it? my memory is a bit rough
|
|
|
jonnyawsom3
|
|
veluca
... there are commercial jpeg xl encoders?
|
|
2026-01-23 05:18:22
|
https://doublebench.com/doublebench-software/#db-software-tabs|0
|
|
|
username
|
2026-01-23 05:19:54
|
there are patents listed on the site, should probably check them against the paper just in case
|
|
2026-01-23 05:26:28
|
also semi surprisingly the paper and encoder are seemingly from 2021
|
|
|
_wb_
|
2026-01-23 08:47:57
|
https://sejong.elsevierpure.com/en/persons/oh-jin-kwon/ <@179701849576833024> I think you may have been at the meeting where Oh Jin or one of his students were presenting their block segmentation approach, or was it Jan back then? It's from quite a while ago
|
|
|
|
veluca
|
2026-01-23 08:49:36
|
I have some vague memories of this
|
|
|
_wb_
|
2026-01-23 09:04:46
|
it seemed to be just some master thesis project or something back then, didn't know they were going to try to sell that stuff
|
|
2026-01-23 09:05:26
|
I doubt there's a market for commercial jxl implementations tbh, except in hw
|
|
|
AccessViolation_
|
2026-01-23 09:10:11
|
> Our $500 Evaluation License allows you to evaluate DoubleBench for up to 6 months
wew
|
|
2026-01-23 09:11:22
|
I was gonna say we could try it out and see if it's actually any good, but...
|
|
|
Traneptora
|
|
AccessViolation_
I was gonna say we could try it out and see if it's actually any good, but...
|
|
2026-01-23 09:55:59
|
> DoubleBench’s JPEG XL software partly uses JPEG XL reference software (https://gitlab.com/wg1/jpeg-xl/) under Apache License 2.0 (http://www.apache.org/licenses/).
|
|
2026-01-23 09:56:25
|
their legal page makes me think it's probably violating the libjxl license
|
|
2026-01-23 09:56:51
|
it's probably a derivative work of libjxl rather than a client
|
|
2026-01-23 09:57:40
|
It says it's apache but it's actually BSD 3clause
|
|
|
|
veluca
|
2026-01-23 11:59:14
|
```
thread 'api::decoder::tests::compare_pipelines_alpha_premultiplied' (260492) panicked at jxl/src/util/test.rs:125:9:
assertion failed @(2311, 41), c 0: `(left ≈ right)`
left: `0.030203538`,
right: `0.0302206`,
abs error: `1.7061829566955566e-5`
max_abs_error: `1e-5`
```
_sigh_
|
|
2026-01-24 12:13:58
|
... should we have a jxl-rs channel?
|
|
|
Quackdoc
|
|
veluca
... should we have a jxl-rs channel?
|
|
2026-01-24 12:30:18
|
<:YEP:808828808127971399>
|
|
|
|
veluca
|
|
veluca
```
thread 'api::decoder::tests::compare_pipelines_alpha_premultiplied' (260492) panicked at jxl/src/util/test.rs:125:9:
assertion failed @(2311, 41), c 0: `(left ≈ right)`
left: `0.030203538`,
right: `0.0302206`,
abs error: `1.7061829566955566e-5`
max_abs_error: `1e-5`
```
_sigh_
|
|
2026-01-24 12:31:44
|
(that was literally an off-by-one)
|
|
|
VcSaJen
|
2026-01-26 02:45:08
|
When batch encoding pictures, is it faster to just encode several pictures at once using single-threaded encode, or one picture at the time using multi-threaded encode?..
|
|
|
jonnyawsom3
|
2026-01-26 02:48:51
|
Singlethreaded. The multithreaded overhead shouldn't be much, but if you're not limited by memory usage then running in parallel should be fine
(And you could run effort 10 without the singlethreaded penalty, since you already are. Though maybe add `--patches 0` if they don't have text)
|
|
|
monad
|
2026-01-27 01:48:35
|
multiple pictures using multi-threaded encode
|
|
2026-01-27 01:49:30
|
but surely a test on a sample in your environment would inform best about details
|
|
|
username
|
2026-01-27 02:04:35
|
is there anything stopping the following PRs from getting merged?
https://github.com/libjxl/libjxl/pull/4559
https://github.com/libjxl/libjxl/pull/4561
|
|
2026-01-27 02:05:32
|
it seems like they are ready to get merged but either haven't been fully accepted yet or are maybe getting stopped from the failed Bazel test that's unrelated to them
|
|
|
|
runr855
|
2026-01-27 04:52:28
|
Is this extreme banding in the works of being fixed? Both 0.11.1 and a pretty new main build shows this. I find this impacting quite a lot of my screenshots with dark gradients to the point of being a showstopper currently. `-d 0.7 -e 7`
|
|
|
username
|
|
runr855
Is this extreme banding in the works of being fixed? Both 0.11.1 and a pretty new main build shows this. I find this impacting quite a lot of my screenshots with dark gradients to the point of being a showstopper currently. `-d 0.7 -e 7`
|
|
2026-01-27 05:12:31
|
could you send the source file/image you are encoding from and also a sample of the JXL you are getting out as well?
|
|
|
jonnyawsom3
|
|
runr855
Is this extreme banding in the works of being fixed? Both 0.11.1 and a pretty new main build shows this. I find this impacting quite a lot of my screenshots with dark gradients to the point of being a showstopper currently. `-d 0.7 -e 7`
|
|
2026-01-27 08:31:47
|
Assuming the screenshots are 8bit, the banding is baked into the image, so JXL will try to preserve it
|
|
|
username
it seems like they are ready to get merged but either haven't been fully accepted yet or are maybe getting stopped from the failed Bazel test that's unrelated to them
|
|
2026-01-27 10:49:14
|
Forgot to enable auto-merge
|
|
|
monad
|
2026-01-27 10:58:26
|
"forgot"
|
|
|
jonnyawsom3
|
2026-01-27 11:00:43
|
Well it got approved a few days ago
|
|
|
monad
|
2026-01-27 11:04:21
|
libjxl maintainers are professionals, it is more likely intentional than unintentional
|
|
|
|
veluca
|
2026-01-27 11:05:03
|
hm? auto-merge is enabled
|
|
2026-01-27 11:05:13
|
I imagine it's blocked by the bazel issue
|
|
|
jonnyawsom3
|
2026-01-27 11:12:04
|
Only checks marked as `Required` block merging, and auto-merge has to be enabled per-PR
One of them you approved but didn't set to merge, the other Eustas set to merge but didn't approve
|
|
|
_wb_
|
|
runr855
Is this extreme banding in the works of being fixed? Both 0.11.1 and a pretty new main build shows this. I find this impacting quite a lot of my screenshots with dark gradients to the point of being a showstopper currently. `-d 0.7 -e 7`
|
|
2026-01-27 11:20:53
|
Looks like a nice test image, can you share the original so we can play with it?
|
|
|
|
runr855
|
2026-01-27 04:30:10
|
I should've checked with more software, the banding only appears in Affinity and not in ImageGlass. I can only get the banding to appear when opening the JXL, no problems with the PNG. Affinity recognizes the PNG as `RGBA/8 - sRGB IEC61966-2.1` (the original document setup) while it loads the JPEG XL as `RGBA/8 - RGB_D65_SRG_Per_SRG`. I don't know if this could be a hint to the cause? As said ImageGlass has no problems with displaying the file. I can paste `jxlinfo` output below
|
|
2026-01-27 04:30:34
|
```JPEG XL image, 2000x3143, lossy, 8-bit RGB
Color space: RGB, D65, sRGB primaries, sRGB transfer function, rendering intent: Perceptual
Brotli-compressed xml metadata: 563 compressed bytes```
|
|
2026-01-27 04:33:06
|
I also ran into a memory usage problem with some screenshots and the original test image I created and sent here, but that's a side note. The JXL seems to use an enormous amount of memory to load compared to the PNG
|
|
2026-01-27 04:33:14
|
I can still provide the sample images if it's relevant
|
|
|
username
|
|
runr855
I also ran into a memory usage problem with some screenshots and the original test image I created and sent here, but that's a side note. The JXL seems to use an enormous amount of memory to load compared to the PNG
|
|
2026-01-27 04:34:43
|
I thought the image you sent yesterday was a screenshot of the JXL since I can see noticeable banding in the dark?
|
|
|
runr855
I can still provide the sample images if it's relevant
|
|
2026-01-27 04:35:03
|
yes this would be helpful so others can test this as well
|
|
|
|
runr855
|
2026-01-27 04:35:47
|
It's a screenshot of the image open in Affinity 3
|
|
2026-01-27 04:37:33
|
The original PNG is huge as I thought the problem might've been resolution dependent as I only noticed the problem on huge images, but I think this was a coincidence
|
|
2026-01-27 05:19:12
|
I needed to split up the archives because of Discord upload size limits
|
|
2026-01-27 05:20:41
|
The JPEG XL images are made with cjxl v0.11.1 and parameters -d 0.7 -e 7
|
|
|
AccessViolation_
|
2026-01-27 05:34:18
|
out of curiosity did you create the source PNG yourself or did you find it somewhere? if you created it yourself, I'd also be interested in a 16 bit per channel PNG of the high-res one. given that these gradients are so slow, it might even compress a bit better with JXL which I'm curious about
|
|
2026-01-27 05:43:45
|
> a 16 bit per channel PNG of the high-res one
or a lossless JXL, since then it might actually be small enough to send on Discord :p
|
|
|
username
|
2026-01-27 05:48:10
|
I'm comparing the PNG and JXL and they look almost exactly identical
|
|
2026-01-27 05:48:30
|
I guess some software is just handling JXL incorrectly
|
|
|
_wb_
|
2026-01-27 05:49:48
|
That kind of banding looks like it went through 8-bit linear RGB
|
|
|
|
runr855
|
2026-01-27 06:23:12
|
The 16bit variants become huge, but I can upload the .af file? Affinity 3 is free, but only for Windows and macOS
|
|
2026-01-27 06:23:56
|
It's just a simple gradient I made on a fill layer with mesh type fill
|
|
|
AccessViolation_
|
2026-01-27 06:24:33
|
huh, are they huge in lossless JXL as well? I thought for images like these a higher bit depth would lead to better compression because the predictors would be more effective
|
|
2026-01-27 06:24:41
|
thanks though!
|
|
|
|
veluca
|
2026-01-28 11:16:53
|
from a discussion in <#1464417869470371912> -- any thoughts about making cjxl by default buffer the _output_ in memory (at least by default)? that's most often not a lot of data, and lets one do the more "usual" group order
|
|
|
username
|
|
veluca
from a discussion in <#1464417869470371912> -- any thoughts about making cjxl by default buffer the _output_ in memory (at least by default)? that's most often not a lot of data, and lets one do the more "usual" group order
|
|
2026-01-29 12:00:00
|
If this fixes chucked encoding ordering groups in a way that doesn't work well with progressive then yes. currently when adding `-p` to encode a image with extra/full progressiveness it disables chunked encoding in the main branch as a workaround and in 0.11 it uses chunked encoding and results in a file that can barely be progressively decoded
|
|
|
|
runr855
|
2026-01-29 12:05:15
|
https://discord.com/channels/794206087879852103/1464417869470371912/1466221239856271719 Is there a resolution limit for when the non-progressive images go from loading fuzzy groups to blank groups? From my limited testing smaller images seem to load almost in a progressive manner even when not encoded progressively, but at some size that changes and complete chunks/groups are instead loaded one-by-one
|
|
|
A homosapien
|
2026-01-29 10:58:15
|
Windows users rejoice! Libjxl is finally using clang! Roughly a 50% performance improvement over MSVC.
|
|
|
username
|
|
A homosapien
Windows users rejoice! Libjxl is finally using clang! Roughly a 50% performance improvement over MSVC.
|
|
2026-01-29 10:59:15
|
where?
|
|
|
A homosapien
|
2026-01-29 10:59:47
|
https://github.com/libjxl/libjxl/commit/8ce9537c989cfc7adff034556c8a4b9469e874d6
|
|
|
username
|
|
A homosapien
|
2026-01-29 11:00:15
|
We're going to have to wait for v0.12 of course
|
|
|
jonnyawsom3
|
2026-01-29 11:12:57
|
Well, now https://artifacts.lucaversari.it/libjxl/libjxl/latest/ will have the speedup too
|
|
2026-01-29 11:13:17
|
To jxl-rs' dismay
|
|
|
runr855
https://discord.com/channels/794206087879852103/1464417869470371912/1466221239856271719 Is there a resolution limit for when the non-progressive images go from loading fuzzy groups to blank groups? From my limited testing smaller images seem to load almost in a progressive manner even when not encoded progressively, but at some size that changes and complete chunks/groups are instead loaded one-by-one
|
|
2026-01-29 11:14:08
|
Sorry for the late reply, that'll be 2048 pixels in either dimension
|
|
|
|
runr855
|
2026-01-30 03:22:14
|
Thanks
|
|
|
Traneptora
|
|
veluca
from a discussion in <#1464417869470371912> -- any thoughts about making cjxl by default buffer the _output_ in memory (at least by default)? that's most often not a lot of data, and lets one do the more "usual" group order
|
|
2026-01-30 05:30:38
|
Isn't this this required to write jxl to nonseekable media without using hydrium-style frame tiling
|
|
|
|
veluca
|
2026-01-30 07:36:49
|
Yes, I think so
|
|
|
jonnyawsom3
|
2026-01-30 01:57:37
|
Moving from https://discord.com/channels/794206087879852103/1464417869470371912/1466609238183776462
So on very large images, it does have a *slight* memory impact `PeakWorkingSetSize: 1.974 GiB` vs `PeakWorkingSetSize: 2.532 GiB`
The actual JXL was 70MB, so I think buffering the output and reordering there would be a lot more flexible and efficient
|
|
2026-01-30 02:07:14
|
Hmm, that image might've been an edge case, it didn't load progressively either
|
|
2026-01-30 02:10:04
|
`444.6 MiB` vs `457 MiB` on another image, only a 3% increase to get the LF at 20% instead of 99% loaded
|
|
|
|
veluca
|
|
Moving from https://discord.com/channels/794206087879852103/1464417869470371912/1466609238183776462
So on very large images, it does have a *slight* memory impact `PeakWorkingSetSize: 1.974 GiB` vs `PeakWorkingSetSize: 2.532 GiB`
The actual JXL was 70MB, so I think buffering the output and reordering there would be a lot more flexible and efficient
|
|
2026-01-30 02:26:32
|
... 500mb?
|
|
2026-01-30 02:26:37
|
what's that image xD
|
|
2026-01-30 02:27:14
|
I'd expect something between 70 and 150mb of usage, not 500mb, from buffering in memory
|
|
|
Hmm, that image might've been an edge case, it didn't load progressively either
|
|
2026-01-30 02:27:33
|
suspicious
|
|
|
jonnyawsom3
|
|
veluca
what's that image xD
|
|
2026-01-30 03:20:54
|
It's a Minecraft map screenshot, so pretty much all HF, but... It should still *have* an LF right? It's 83MP so definitely not patches
|
|
|
|
veluca
|
2026-01-30 03:22:06
|
I imagine that's not full resolution
|
|
|
jonnyawsom3
|
|
veluca
I imagine that's not full resolution
|
|
2026-01-30 03:24:55
|
Here's the full res
|
|
|
|
veluca
|
2026-01-30 03:26:38
|
nice, and how did you compress it?
|
|
|
jonnyawsom3
|
2026-01-30 03:27:02
|
`cjxl -e 5` to save a bit of time
|
|
|
|
veluca
|
2026-01-30 03:39:06
|
with `--num_threads=0`?
|
|
|
jonnyawsom3
|
2026-01-30 03:39:31
|
No, just default settings
|
|
|
|
veluca
|
2026-01-30 03:39:49
|
I get ~1.5gb of memory with 0 threads
|
|
|
No, just default settings
|
|
2026-01-30 03:40:07
|
the memory increase _could_ be due to the multithreading
|
|
2026-01-30 03:40:27
|
as in, MT can make memory usage significantly less deterministic
|
|
|
jonnyawsom3
|
2026-01-30 03:40:47
|
In my experience threading didn't impact memory usage noticeably. I did try with 4 threads instead of 16 but nothing changed
|
|
|
|
veluca
|
2026-01-30 03:41:54
|
interesting
|
|
2026-01-30 03:42:03
|
wonder why you're using 400 to 1000 more mb
|
|
|
jonnyawsom3
|
|
veluca
wonder why you're using 400 to 1000 more mb
|
|
2026-01-30 03:55:58
|
Figured it out, there was a second map image in the same folder and I picked the wrong one xP
Here's the *actual* image, though both have the same behaviour. Using the same amount of memory single or multithreaded and use a few hundred megs more with your PR
|
|
|
|
veluca
|
2026-01-30 04:13:53
|
ahhh I think I see why
|
|
2026-01-30 04:24:42
|
<@238552565619359744> try again now 🙂
|
|
|
jonnyawsom3
|
2026-01-30 04:51:56
|
That minecraft map actually uses 2MB less than main now, and other images are nearly identical, so if we don't find any issues I think it'd be fine to merge
|
|
|
|
veluca
|
2026-01-30 05:28:28
|
Eh, I still would prefer the flag to be wired up to keep the old behaviour in case you need it for some really huge image
|
|
2026-01-30 05:33:46
|
and for that matter, another thing that could use some improvement is the documentation of the "BUFFERING" setting xD
|
|
|
qdwang
|
2026-02-04 03:38:43
|
Is there anything I can do during encoding to reduce decoding memory usage for large resolution jxl files?
|
|
|
VcSaJen
|
2026-02-04 04:03:51
|
There's `JXL_ENC_FRAME_SETTING_DECODING_SPEED`, but it controls speed, not memory.
|
|
|
qdwang
|
2026-02-04 04:04:10
|
I've already set it to 4
|
|
2026-02-04 04:05:47
|
The reason why i need this is that iOS seems to have memory issue during saving high res JXL. When my app uses over 400mb memory, saving high res JXL by using `PHPhotoLibrary.shared().performChanges` will fail.
When the app take less than 100mb, it can save the high res jxl.
There's no problem with high res JPG and high res AVIF.
|
|
|
VcSaJen
|
2026-02-04 04:07:10
|
I also assume that streaming encode would result in streaming decode, but I'm not sure on that front
|
|
|
qdwang
|
2026-02-04 04:07:34
|
Thank you for giving the idea, i'll have a try
|
|
2026-02-04 04:11:19
|
I tried to enable `progressive_dc` but the encoding process using too much memory with this mode which cannot work on ios
|
|
2026-02-04 04:48:06
|
it doesn't work, by changing `JXL_ENC_FRAME_SETTING_BUFFERING` to 2, it still fails to save the high res jxl
|
|
|
jonnyawsom3
|
2026-02-04 04:54:45
|
That's because 2 doesn't do anything https://discord.com/channels/794206087879852103/1464417869470371912/1468282242974486692
|
|
|
qdwang
|
|
That's because 2 doesn't do anything https://discord.com/channels/794206087879852103/1464417869470371912/1468282242974486692
|
|
2026-02-04 05:08:24
|
Thank you for metioning that. It seems there is no way to prevent the failure.
|
|
|
jonnyawsom3
|
2026-02-04 05:08:47
|
I assume you're doing lossy encoding?
|
|
|
qdwang
|
2026-02-04 05:08:57
|
yes
|
|
2026-02-04 05:09:37
|
There is no memory problem during the encoding part, the issue is caused during saving the JXL to Photos on iOS.
|
|
|
jonnyawsom3
|
2026-02-04 05:10:27
|
Strange....
|
|
|
qdwang
|
2026-02-04 05:11:22
|
I don't know how Apple deals with the decoding process...
|
|
2026-02-04 05:19:39
|
With high res AVIF(same resolution), it even works up to 1.5G memory consumed. Maybe Apple has optimized the AVIF decoder a lot.
|
|
|
jonnyawsom3
|
2026-02-04 05:37:30
|
What resolution crashes for example?
|
|
|
qdwang
|
2026-02-04 05:42:12
|
48M, it won't crash, it just returns the error said, failed to save the JXL
|
|
2026-02-04 05:42:40
|
PHPhotosErrorDomain 3301
|
|
|
awxkee
|
2026-02-04 06:40:46
|
curious could you share code snippet? AFAIK saving jxl to photos is not supported and should fail returning something like this ```findWriterForTypeAndAlternateType:132: *** ERROR: unsupported output file format 'public.jpeg-xl'
CGImageDestinationCreateWithData:5573: *** ERROR: CGImageDestinationCreateWithData: failed to create 'CGImageDestinationRef'```
|
|
|
qdwang
|
2026-02-04 07:04:10
|
I save the jxl binary by using `PHPhotoLibrary.shared().performChanges`
|
|
2026-02-04 07:05:32
|
```
PHPhotoLibrary.shared().performChanges({
let creationRequest = PHAssetCreationRequest.forAsset()
let options = PHAssetResourceCreationOptions()
options.originalFilename = name + ".jxl"
creationRequest.addResource(with: .photo, data: data, options: options)
}) { success, error in
print(success)
}
```
|
|
2026-02-04 07:05:46
|
the `data` is JXL binary
|
|
2026-02-04 07:05:55
|
so nothing special
|
|
|
awxkee
|
2026-02-04 07:20:48
|
I didn't know this way it would work 🙂 I'm getting the same though. It seems photos service just panics ```Connection to assetsd was interrupted - assetsd exited, died, or closed the photo library
Error getting remote object proxy for -[PLNonBindingAssetsdPhotoKitAddClient sendChangesRequest:reply:]_block_invoke: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.photos.service" UserInfo={NSDebugDescription=connection to service named com.apple.photos.service}``
|
|
|
_wb_
|
2026-02-04 08:11:14
|
I wouldn't be surprised if Apple just decodes jxl to full buffers in float32 and then takes it from there, while for other formats it probably decodes to uint8 or uint16 buffers, or maybe even something like 10-bit yuv or whatever.
|
|
|
intelfx
|
2026-02-04 11:10:42
|
I hope I chose the right channel.
Does anyone have an idea why the libjxl perceptual metrics tools cannot open PNGs round-tripped through AVIF via `avifenc` + `avifdec`?
```
+++
+++ While converting /home/intelfx/tmp/big/sync/{jxl-images-phoronix-2/800x534/source.png -> jxl-images-phoronix-2.svtav1:tune3.L0.q30.s4.out/800x534/source.temp.avif}:
+++ Decoded pair /home/intelfx/tmp/big/sync/jxl-images-phoronix-2/800x534/source.png -> /tmp/decoded.JDbudi.png:
+++ Metric tool ssimulacra exited with 1
+++ JPEGXL_TOOLS_CHECK: jxl::SetFromBytes(jxl::Bytes(encoded), jxl::extras::ColorHints(), io[i])
+++
+++ While converting /home/intelfx/tmp/big/sync/{jxl-images-phoronix-2/800x534/source.png -> jxl-images-phoronix-2.svtav1:tune3.L0.q10.s4.out/800x534/source.temp.avif}:
+++ Decoded pair /home/intelfx/tmp/big/sync/jxl-images-phoronix-2/800x534/source.png -> /tmp/decoded.908ZuM.png:
+++ Metric tool ssimulacra exited with 1
+++ JPEGXL_TOOLS_CHECK: jxl::SetFromBytes(jxl::Bytes(encoded), jxl::extras::ColorHints(), io[i])
+++
+++ While converting /home/intelfx/tmp/big/sync/{jxl-images-phoronix-2/800x534/source.png -> jxl-images-phoronix-2.svtav1:tune3.L0.q30.s4.out/800x534/source.temp.avif}:
+++ Decoded pair /home/intelfx/tmp/big/sync/jxl-images-phoronix-2/800x534/source.png -> /tmp/decoded.JDbudi.png:
+++ Metric tool ssimulacra2 exited with 1
+++ Could not decode distorted image: /tmp/decoded.JDbudi.png
+++
+++ While converting /home/intelfx/tmp/big/sync/{jxl-images-phoronix-2/800x534/source.png -> jxl-images-phoronix-2.svtav1:tune3.L0.q10.s4.out/800x534/source.temp.avif}:
+++ Decoded pair /home/intelfx/tmp/big/sync/jxl-images-phoronix-2/800x534/source.png -> /tmp/decoded.908ZuM.png:
+++ Metric tool ssimulacra2 exited with 1
+++ Could not decode distorted image: /tmp/decoded.908ZuM.png
+++
+++ While converting /home/intelfx/tmp/big/sync/{jxl-images-phoronix-2/800x534/source.png -> jxl-images-phoronix-2.svtav1:tune3.L0.q30.s4.out/800x534/source.temp.avif}:
+++ Decoded pair /home/intelfx/tmp/big/sync/jxl-images-phoronix-2/800x534/source.png -> /tmp/decoded.JDbudi.png:
+++ Metric tool butteraugli exited with 1
+++ Failed to decode image from /tmp/decoded.JDbudi.png
```
(avifenc parameters are encoded into file names in the log above)
|
|
|
A homosapien
|
2026-02-04 11:39:33
|
It's got something to do with the metadata, I got ssimulacra2 to read the PNG when stripping it all out. Not ideal.
|
|
|
jonnyawsom3
|
2026-02-04 11:41:24
|
Metadata after IEND?
|
|
|
A homosapien
|
2026-02-04 11:43:13
|
Nope, seems like the color metadata is throwing it off. Still fails after `oxipng -s output.png`, `--strip all` works.
|
|
|
intelfx
|
|
Metadata after IEND?
|
|
2026-02-04 11:43:21
|
OK, I built libjxl with debug and this is enlightening:
```
$ build/tools/butteraugli_main ~/tmp/big/sync/jxl-tests/in.png ~/tmp/big/sync/jxl-tests/out.libaom:iq.L0.q30.s6.png
../lib/extras/dec/apng.cc:222: Unsupported transfer function specified in cICP chunk: 2
../lib/extras/dec/apng.cc:1074: JXL_RETURN_IF_ERROR code=1: DecodeCicpChunk(payload, &ppf->color_encoding)
../lib/extras/dec/decode.cc:178: JXL_FAILURE: Codecs failed to decode
../lib/extras/codec.cc:48: JXL_FAILURE: Codecs failed to decode
Failed to decode image from /home/intelfx/tmp/big/sync/jxl-tests/out.libaom:iq.L0.q30.s6.png
```
|
|
2026-02-04 11:43:47
|
judging by H.273, 2 is "unspecified"
|
|
2026-02-04 11:44:21
|
not entirely incorrect, I guess, but how do I make stuff work?
|
|
|
A homosapien
|
2026-02-04 11:45:22
|
Well, if it's an sRGB image, stripping the metadata will make ssimulacra2/butter treat the PNG as sRGB by default.
|
|
|
intelfx
|
2026-02-04 11:49:39
|
Looks that way — the original PNG image has no cICP chunk, only cHRM, but photographic metadata says sRGB, so I guess avifenc is just not smart enough to figure it out
|
|
|
Traneptora
|
|
intelfx
I hope I chose the right channel.
Does anyone have an idea why the libjxl perceptual metrics tools cannot open PNGs round-tripped through AVIF via `avifenc` + `avifdec`?
```
+++
+++ While converting /home/intelfx/tmp/big/sync/{jxl-images-phoronix-2/800x534/source.png -> jxl-images-phoronix-2.svtav1:tune3.L0.q30.s4.out/800x534/source.temp.avif}:
+++ Decoded pair /home/intelfx/tmp/big/sync/jxl-images-phoronix-2/800x534/source.png -> /tmp/decoded.JDbudi.png:
+++ Metric tool ssimulacra exited with 1
+++ JPEGXL_TOOLS_CHECK: jxl::SetFromBytes(jxl::Bytes(encoded), jxl::extras::ColorHints(), io[i])
+++
+++ While converting /home/intelfx/tmp/big/sync/{jxl-images-phoronix-2/800x534/source.png -> jxl-images-phoronix-2.svtav1:tune3.L0.q10.s4.out/800x534/source.temp.avif}:
+++ Decoded pair /home/intelfx/tmp/big/sync/jxl-images-phoronix-2/800x534/source.png -> /tmp/decoded.908ZuM.png:
+++ Metric tool ssimulacra exited with 1
+++ JPEGXL_TOOLS_CHECK: jxl::SetFromBytes(jxl::Bytes(encoded), jxl::extras::ColorHints(), io[i])
+++
+++ While converting /home/intelfx/tmp/big/sync/{jxl-images-phoronix-2/800x534/source.png -> jxl-images-phoronix-2.svtav1:tune3.L0.q30.s4.out/800x534/source.temp.avif}:
+++ Decoded pair /home/intelfx/tmp/big/sync/jxl-images-phoronix-2/800x534/source.png -> /tmp/decoded.JDbudi.png:
+++ Metric tool ssimulacra2 exited with 1
+++ Could not decode distorted image: /tmp/decoded.JDbudi.png
+++
+++ While converting /home/intelfx/tmp/big/sync/{jxl-images-phoronix-2/800x534/source.png -> jxl-images-phoronix-2.svtav1:tune3.L0.q10.s4.out/800x534/source.temp.avif}:
+++ Decoded pair /home/intelfx/tmp/big/sync/jxl-images-phoronix-2/800x534/source.png -> /tmp/decoded.908ZuM.png:
+++ Metric tool ssimulacra2 exited with 1
+++ Could not decode distorted image: /tmp/decoded.908ZuM.png
+++
+++ While converting /home/intelfx/tmp/big/sync/{jxl-images-phoronix-2/800x534/source.png -> jxl-images-phoronix-2.svtav1:tune3.L0.q30.s4.out/800x534/source.temp.avif}:
+++ Decoded pair /home/intelfx/tmp/big/sync/jxl-images-phoronix-2/800x534/source.png -> /tmp/decoded.JDbudi.png:
+++ Metric tool butteraugli exited with 1
+++ Failed to decode image from /tmp/decoded.JDbudi.png
```
(avifenc parameters are encoded into file names in the log above)
|
|
2026-02-05 04:58:03
|
Avifdec is tagging the file with illegal color metadata. You can override it with a tool like umbrielpng without stripping all
|
|
|
intelfx
|
|
Traneptora
Avifdec is tagging the file with illegal color metadata. You can override it with a tool like umbrielpng without stripping all
|
|
2026-02-05 05:22:32
|
Yeah, I just locally patched libjxl's PNG loader to ignore a partially "unspecified" cICP when other colorimetry chunks exist
|
|
|
Traneptora
|
2026-02-05 05:24:00
|
Ye, tho check out umbrielpng in the future. It is a png filterer that doesn't touch the IDAT chunks unlike most of them
|
|
2026-02-05 05:24:11
|
(which means it's very fast)
|
|
|
whatsurname
|
|
Traneptora
Avifdec is tagging the file with illegal color metadata. You can override it with a tool like umbrielpng without stripping all
|
|
2026-02-05 05:39:40
|
It is legal, it's just that libjxl doesn't support it
Should file a bug on the libjxl repo
|
|
|
intelfx
Yeah, I just locally patched libjxl's PNG loader to ignore a partially "unspecified" cICP when other colorimetry chunks exist
|
|
2026-02-05 05:43:46
|
cICP chunk should take precedence per PNG spec, so that may not be a good solution
|
|
|
intelfx
|
|
whatsurname
cICP chunk should take precedence per PNG spec, so that may not be a good solution
|
|
2026-02-05 05:45:40
|
It should, but if it contains an "unspecified" in one of the fields, then what is the proper semantics of such a file?
|
|
|
whatsurname
|
2026-02-05 05:46:27
|
Just use sRGB and ignore other chunks I guess
|
|
|
jonnyawsom3
|
2026-02-05 05:46:58
|
I wouldn't call "unspecified" legal....
|
|
|
intelfx
|
|
whatsurname
Just use sRGB and ignore other chunks I guess
|
|
2026-02-05 05:48:57
|
Isn't that strictly worse than using the best fully unambiguous colorimetry chunk? Like, cICP is optional, so it should be valid (internally consistent, at least) to cosplay as a decoder that just is not capable of parsing that chunk, otherwise what's even the point of the precedence rules in the standard?
|
|
|
whatsurname
|
|
intelfx
Isn't that strictly worse than using the best fully unambiguous colorimetry chunk? Like, cICP is optional, so it should be valid (internally consistent, at least) to cosplay as a decoder that just is not capable of parsing that chunk, otherwise what's even the point of the precedence rules in the standard?
|
|
2026-02-05 06:39:58
|
It's the encoder's responsibility to keep color chunks consistent, but that's not guaranteed (or not feasible in some cases).
Actually I'm surprised you get an unspecified cICP and a valid cHRM, what's the CICP of the AVIF?
|
|
|
|
veluca
|
2026-02-05 07:48:12
|
is the "unspecified" in the matrix coefficients and/or tv range field?
|
|
|
A homosapien
|
2026-02-05 09:01:26
|
just the transfer curve I think
|
|
|
|
veluca
|
2026-02-05 09:15:40
|
well, then kinda hard to do anything with that CICP...
|
|
|
_wb_
|
2026-02-05 10:23:35
|
I'd say we should interpret "unspecified" as being some crazy tf, say some extreme gamma that will make the image very bright, and if someone complains we just say "well you didn't bother to specify so we picked something"
|
|
2026-02-05 10:24:20
|
bonus points if chrome also does that
|
|
|
VcSaJen
|
2026-02-05 12:18:08
|
When converting PNG to JXL via libjxl's API, which things I should be aware of? There's a color profile, but there's also gamma, color space, white point and stuff separately?.. Is that even exposed in image loading libraries?
|
|
|
_wb_
|
2026-02-05 12:38:10
|
depends on the image loading library, but I think many don't fully get it right, e.g. only supporting ICC profiles but not the various other ways to signal colorspace in PNG.
|
|
2026-02-05 12:42:18
|
to load a PNG in something like PIL or whatever with an actual correct colorspace, you need to manually check for the various chunks and implement the precedence logic of the PNG spec, i.e. first check cICP, then ICC, then sRGB, then cHRM/gAMA, iirc. And you need to manually interpret all those chunks. So it's basically pretty messy and not very surprising that many applications get it wrong.
|
|
2026-02-05 12:44:27
|
Things would be a lot more straightforward if png decoders would do the libjxl/jxl-rs thing and have a function that just always gives you an ICC profile that corresponds to the colorspace of the decoded data, regardless of how that colorspace was signaled in the file (i.e. it produces an ICC profile from more compact representations if needed).
|
|
|
jonnyawsom3
|
|
veluca
suspicious
|
|
2026-02-05 06:45:31
|
I figured out why it still wasn't progressive, Alpha delays the LF from loading. Setting it to lossy Alpha lets the LF load, so I *think* we could re-order the lossless frame before the VarDCT data, would give a nicer progressive image too as the edges would be sharp while color data loads in
|
|
2026-02-05 06:50:05
|
I suppose we were going to interlace Alpha with Color for jxl-rs to display `-p` progressive images anyway, but it would bring back the 'inherent' progressiveness too if it's not too hard
|
|
|
AccessViolation_
|
|
_wb_
I'd say we should interpret "unspecified" as being some crazy tf, say some extreme gamma that will make the image very bright, and if someone complains we just say "well you didn't bother to specify so we picked something"
|
|
2026-02-05 07:20:46
|
I've been thinking of doing something like this for unspecified pixel data in jxl files, e.g. from overlapping a bunch of splines
like slow flashing between fully transparent and red or something
|
|
|
jonnyawsom3
|
2026-02-05 07:21:50
|
Gmod Error as JXL art embedded as a background frame
|
|
|
AccessViolation_
|
2026-02-05 07:21:59
|
lmao
|
|
2026-02-05 07:22:02
|
the freaking 3d model
|
|
|
|
veluca
|
|
I figured out why it still wasn't progressive, Alpha delays the LF from loading. Setting it to lossy Alpha lets the LF load, so I *think* we could re-order the lossless frame before the VarDCT data, would give a nicer progressive image too as the edges would be sharp while color data loads in
|
|
2026-02-05 07:59:10
|
Give me more context please? It's all out of cache 🤣
|
|
|
|
runr855
|
2026-02-09 09:56:30
|
Is the buffer overflow which is getting fixed in past versions too seen as a security problem, or is it a "safe" crash?
|
|
|
jonnyawsom3
|
2026-02-10 01:47:07
|
I'm taking a crack at improving the buffering settings, namely adding the logic so `JXL_ENC_FRAME_SETTING_BUFFERING` actually does something, and defaulting to group buffering so there isn't a discrepancy between 1080p and 1440p images. Also trying to add an option to cjxl to control the level, but getting a little bit overwhelmed.
|
|
|
|
veluca
|
2026-02-10 06:10:21
|
will give that a look eventually
|
|
2026-02-10 06:10:38
|
probably not this week, I'm quite busy
|
|
|
jonnyawsom3
|
2026-02-10 11:02:06
|
<@811568887577444363> I noticed you're doing a new minor release, I don't suppose this is worth including too? https://github.com/libjxl/libjxl/pull/4027
|
|
2026-02-10 11:02:46
|
It fixes a bug that caused effort 1 lossless images to not actually be lossless, which while not a security issue, definitely is quite severe https://github.com/libjxl/libjxl/issues/4026
|
|
|
|
veluca
|
2026-02-10 04:17:03
|
let's put it this way: not including it incentivizes us to make a 0.12 sooner 😛
|
|
|
username
|
2026-02-10 04:20:16
|
0.12 has been a looong time coming although tbh there's still some nice improvements that haven't been finished to be merged in yet...
|
|
2026-02-10 04:21:14
|
for example I wonder what the failing testcase on this is? https://github.com/libjxl/libjxl/pull/4296
|
|
2026-02-10 04:21:29
|
the runs are so old that the logs got deleted
|
|
2026-02-10 04:22:57
|
would anyone be willing to re-run/re-trigger the Conformance tests on this PR?
|
|
|
spider-mario
|
2026-02-10 04:51:06
|
I think I might need to rebase first; trying that
|
|
2026-02-10 04:55:21
|
my rebase drops a slight change to `jxlinfo` (it was changed more extensively in the meantime), so just to be safe, I’ll push the rebased version as a separate PR
|
|
2026-02-10 04:57:54
|
https://github.com/libjxl/libjxl/pull/4619
|
|
|
username
|
|
spider-mario
https://github.com/libjxl/libjxl/pull/4619
|
|
2026-02-11 12:25:30
|
thanks! after doing some looking around with <@207980494892040194> for a while I think I might have found the culprit for the failing case. It seems like there aren't any decoded pixel values getting changed for the lossless test, I think it's calculating the error between two ICC **files** that are slightly out of sync metadata wise (profile description and profile id) but otherwise have all the exact same color transformations and curves.
I *think* to fix this the hash on this line in this file for "reference.icc" https://github.com/libjxl/conformance/blob/4bf053529c7cefd2951be453475bb3dccc7e7be8/testcases/lossless_pfm/test.json#L21 would have to be changed to `87948CDB39DC5FE2044FA8A340B09B27AD06A3A0795F6EED5B8EF4CBCF6EA051` and the icc file attached to this message needs to be uploaded to replace the old one on the Google storage server (however that's done): https://storage.googleapis.com/storage/v1/b/jxl-conformance/o
also going to ping <@794205442175402004> for this.
|
|
2026-02-11 12:26:28
|
sorry for the possibly poor formatting of my message I have been awake for a bit too long
|
|
|
whatsurname
|
2026-02-11 04:16:37
|
`ColorEncodingDescriptionImpl` used to take rendering intent into account, that icc has a relative (instead of perceptual) rendering intent so it didn't get the sort name before
|
|
|
_wb_
|
2026-02-11 07:13:35
|
The conformance tests checking ICC profiles are too strict: we should only require bit-exact ICC profiles in case of have_icc instead of also requiring that in case of synthesized profiles.
|
|
|
spider-mario
|
|
_wb_
The conformance tests checking ICC profiles are too strict: we should only require bit-exact ICC profiles in case of have_icc instead of also requiring that in case of synthesized profiles.
|
|
2026-02-11 08:09:45
|
I’m not sure it’s actually checking the ICC profiles bit-exactly here; I think it’s just failing to skip the CMS so there are small numerical errors in what should be an identity transform
|
|
|
whatsurname
|
2026-02-11 08:17:26
|
There are https://github.com/libjxl/libjxl/tree/main/tools/conformance and https://github.com/libjxl/conformance, which should be the source of truth?
|
|
|
spider-mario
|
|
spider-mario
I’m not sure it’s actually checking the ICC profiles bit-exactly here; I think it’s just failing to skip the CMS so there are small numerical errors in what should be an identity transform
|
|
2026-02-11 08:21:52
|
ah, wait, we already have https://github.com/libjxl/conformance/commit/4bf053529c7cefd2951be453475bb3dccc7e7be8 for this (and the ProPhoto pull request updates to this)
|
|
|
whatsurname
There are https://github.com/libjxl/libjxl/tree/main/tools/conformance and https://github.com/libjxl/conformance, which should be the source of truth?
|
|
2026-02-11 08:23:05
|
I don’t think we use the former much
|
|
|
whatsurname
|
2026-02-11 08:23:39
|
Isn't that what used in CI
|
|
|
spider-mario
|
2026-02-11 08:24:03
|
as far as I’m aware, no, it’s the latter
|
|
|
whatsurname
|
2026-02-11 08:24:21
|
https://github.com/libjxl/libjxl/blob/4867d7bb0853a557dbc53659c0485e6b7c856947/.github/workflows/conformance.yml#L148
|
|
|
spider-mario
|
2026-02-11 08:25:34
|
that doesn’t seem to actually be used for much
|
|
2026-02-11 08:25:36
|
as opposed to https://github.com/libjxl/libjxl/blob/4867d7bb0853a557dbc53659c0485e6b7c856947/.github/workflows/conformance.yml#L43-L48
|
|
|
whatsurname
|
2026-02-11 08:30:16
|
I think it will download that later in https://github.com/libjxl/libjxl/blob/4867d7bb0853a557dbc53659c0485e6b7c856947/.github/workflows/conformance.yml#L227 and https://github.com/libjxl/libjxl/blob/4867d7bb0853a557dbc53659c0485e6b7c856947/.github/workflows/conformance.yml#L262 runs the conformance.py from the base dir?
|
|
|
spider-mario
|
2026-02-11 08:32:02
|
… oh
|
|
2026-02-11 08:32:21
|
that would certainly explain why “skip color transform when expectation is lossless” didn’t fix it
|
|
|
whatsurname
|
2026-02-11 08:34:30
|
Also it should just error out if it was using the fixed conformance.py
https://github.com/libjxl/conformance/pull/47
|
|
|
DZgas Ж
|
2026-02-11 01:25:05
|
Why aren't libjxl libraries included in the Windows build on GitHub?
|
|
2026-02-11 01:52:32
|
oh meh
|
|
|
whatsurname
|
2026-02-11 02:44:45
|
It seems the release assets failed to upload due to expired PAT
|
|
|
DZgas Ж
|
|
DZgas Ж
Why aren't libjxl libraries included in the Windows build on GitHub?
|
|
2026-02-11 03:26:52
|
For some reason, I was completely unable to unbind brotli libraries when compiling use msys2 (They weren't compiled natively from the source code of the downloaded Brotli itself, but were taken from the msys2 bin), but I will still send this for myself from the future (possibly)
libjxl.dll v0.11.2
|
|
2026-02-11 03:43:56
|
https://github.com/libjxl/libjxl/blob/main/doc/developing_in_windows_msys.md ?
git clone https://github.com/libjxl/libjxl.git libjxl-clean
cd libjxl-clean
git submodule update --init --recursive
mkdir build
cd build
bash nuclear_build.sh (It does **rm rf in the folder where it is located, don't screw up all the files**, it was more convenient for me to just clean up build with it)
|
|
|
username
|
|
spider-mario
… oh
|
|
2026-02-11 04:46:49
|
would it be better to try removing the local copy of the testing scripts and have it use the actual ones from the conformance repo that gets downloaded? or for now is it just fine to update the local copy and hope it doesn't cause issues again in the future?
|
|
|
𝐆𝐀 𝐀𝐦𝐞𝐫𝐢𝐜𝐚
|
2026-02-11 07:05:09
|
Quick question, every release of jxl i've found says the release is for evaluation purposes. Is there a version meant for actual use or will that not be a thing until version 1.0?
|
|
|
DZgas Ж
|
|
𝐆𝐀 𝐀𝐦𝐞𝐫𝐢𝐜𝐚
Quick question, every release of jxl i've found says the release is for evaluation purposes. Is there a version meant for actual use or will that not be a thing until version 1.0?
|
|
2026-02-11 07:08:04
|
Yes, JPEG XL isn't fully ready, it has artifacts that shouldn't be there. They're small, but they're definitely there. In some scenarios or archiving, this may be unacceptable. BUT there's good news: it's only about the lossy VarDCT codec. If you're only interested in lossless Modular compression, you can safely use JPEG XL now.
|
|
|
𝐆𝐀 𝐀𝐦𝐞𝐫𝐢𝐜𝐚
|
2026-02-11 07:08:38
|
Great to hear! Thank you!
|
|
|
monad
|
2026-02-11 07:10:38
|
as long as you do usual verification, since libjxl can fail to produce files or produce files which decoders refuse to decode
|
|
|
VcSaJen
|
2026-02-13 05:38:56
|
I'm thinking of converting GIF and APNG to JXL with libjxl losslessly. I don't want to rely on optimization of initial files (they could be unoptimized), so I should do optimization manually. Looking at API, bounding box of changes seems easy enough, but I want to encode only differences (including alpha differences). Initially I wanted to do it with XOR, but it seems like only ancient formats from Amiga era support that blend mode. Subtraction is the next best thing, but:
1) Would JXL_BLEND_ADD support negative values if JxlBlendInfo.clamp is False? How do I even input negative values if it usually accepts only unsigned integers?
2) I don't see any way to blend Alpha independently, how do I encode Alpha differences in this case?..
|
|
2026-02-14 05:53:54
|
Any way to interrupt encoding? I know I can just stop feeding frames when encoding animation, but what about static images?..
Also, any way to keep track of the progress (percentage)?
|
|
2026-02-15 12:15:21
|
One idea I have is to have chunking encoding and feed squares filled with black pixels into it when I want encoding to be interrupted, but I heard that effort 10 disables chunking, so...
|
|
|
novomesk
|
2026-02-16 03:58:45
|
Is it something to worry about?
https://issues.oss-fuzz.com/issues/461519874
|
|
|
Laserhosen
|
|
VcSaJen
I'm thinking of converting GIF and APNG to JXL with libjxl losslessly. I don't want to rely on optimization of initial files (they could be unoptimized), so I should do optimization manually. Looking at API, bounding box of changes seems easy enough, but I want to encode only differences (including alpha differences). Initially I wanted to do it with XOR, but it seems like only ancient formats from Amiga era support that blend mode. Subtraction is the next best thing, but:
1) Would JXL_BLEND_ADD support negative values if JxlBlendInfo.clamp is False? How do I even input negative values if it usually accepts only unsigned integers?
2) I don't see any way to blend Alpha independently, how do I encode Alpha differences in this case?..
|
|
2026-02-17 08:04:30
|
I've been through the same struggles. You can provide negative samples to the encoder, and it behaves how you would expect, but you have to use a floating point data type in the `JxlPixelFormat`. You can still set the image header bit depth to your original bit depth, and it will roundtrip losslessly at that bit depth.
|
|
2026-02-17 08:05:47
|
Every extra channel, including alpha, can have its own blend mode/source (`JxlEncoderSetExtraChannelBlendInfo`). I think if you don't set it, it defaults to the blend mode used by the color channels.
|
|
2026-02-17 08:16:16
|
What I found wild was the fact you can losslessly store the result of subtracting two 8-bit frames as an 8-bit JXL, even though there's an extra ~1 bit of information due to the range being [-1,1]... which I assume is because the header bit depth defines the *precision* but doesn't put hard limits on the actual range.
|
|
|
_wb_
|
2026-02-17 09:02:05
|
Correct.
|
|
|
|
AWM
|
|
Laserhosen
What I found wild was the fact you can losslessly store the result of subtracting two 8-bit frames as an 8-bit JXL, even though there's an extra ~1 bit of information due to the range being [-1,1]... which I assume is because the header bit depth defines the *precision* but doesn't put hard limits on the actual range.
|
|
2026-02-18 11:41:45
|
Isn't that just modular arithmetic?
|
|
|
_wb_
|
2026-02-18 12:46:10
|
One thing that is pretty different between jxl and other image formats is that jxl doesn't require byte-aligned or even bit-aligned sample ranges; as long as it fits in float32 (or in case of Level 5, also in int16), it can be represented.
|
|
2026-02-18 12:48:12
|
PNG, WebP, TIFF etc are all byte-based so if it's 8-bit, you literally get 8 bits and that's it. While in jxl, "8-bit" means the nominal [0,1] interval gets quantized to 256 values but you can still go outside that interval if you like.
|
|
2026-02-18 12:49:15
|
And you can just as effectively do 7-bit or 9-bit if you prefer that, while that's awkward and inefficient in most other formats.
|
|
|
Laserhosen
|
|
AWM
Isn't that just modular arithmetic?
|
|
2026-02-18 06:40:01
|
There's no wrap-around, so it doesn't really behave like modular arithmetic. It was just a slight mental gear shift coming from other image formats, to realize that an (uncompressed) sample can require more bits to represent it than the nominal bit depth of the channel it belongs to.
|
|
|
jonnyawsom3
|
2026-02-20 07:27:07
|
Does libjxl do any global pallete detection/color counting when chunked encoding is enabled? Was thinking of switching to LZ77 only when the amount of colors/bitdepth is very low (This could probably be done per-group too, but group/channel level compression parameters aren't implemented yet)
|
|
2026-02-23 06:09:30
|
https://github.com/libjxl/libjxl/pull/4634
|
|
2026-02-23 06:15:21
|
Lossless scales near-linearly with groups and threads, but I can't remember how VarDCT scales. Would it make sense to switch between 4 and 8 groups for lossless and lossy respectively? Then lossless still gets at least a 4x speedup for larger group sizes and density is sometimes better with chunked too
|
|
2026-02-23 06:39:58
|
Currently common screen resolutions fall below thresholds too due to not being perfect powers of 2. For example, 8 groups with a 1080p image at 2,073,600 pixels
256x256: 524,288 pixels - Chunked
512x512: 2,097,152 pixels - Not-chunked
8 groups at 8K with 8,294,400 pixels
512x512: 2,097,152 pixels - Chunked
1024x1024: 8,388,608 pixels - Not-chunked
Nevermind all of that, I forgot groups can be partially filled at the edges too, it should all work fine 😅
|
|
|
username
|
2026-02-24 04:16:39
|
<@604964375924834314> if you get the time could you try replacing [conformance.py](https://github.com/libjxl/libjxl/blob/main/tools/conformance/conformance.py) within the [prophoto test run PR](https://github.com/libjxl/libjxl/pull/4619)~~ with the one from [here](https://github.com/libjxl/conformance/pull/47)~~ to see if doing so fixes the failing testcase?
|
|
2026-02-24 04:18:58
|
If it does then IMO it might be worth it to just do that for the prophoto changes in the short term even if it doesn't fix the core issue of the libjxl repo not fully/properly using the files from the conformance repo
|
|
2026-02-24 04:29:09
|
err wait it seems like the copy of conformance.py within the libjxl repo is quite different from the one in the conformance repo and I'm not sure if the libjxl repo one was changed away from the conformance repo one or if the one in libjxl is just that old
|
|
|
username
err wait it seems like the copy of conformance.py within the libjxl repo is quite different from the one in the conformance repo and I'm not sure if the libjxl repo one was changed away from the conformance repo one or if the one in libjxl is just that old
|
|
2026-02-24 04:45:04
|
might be a combo of both.?
|
|
2026-02-24 04:54:07
|
how about just this instead then:
```patch
--- conformance.py
+++ conformance.py
@@ -35,12 +35,14 @@
return Failure(f'Expected shape {ref.shape} but found {dec.shape}')
ref_frame = ref[frame_idx]
dec_frame = dec[frame_idx]
num_channels = ref_frame.shape[2]
- if ref_icc != dec_icc:
+ if ref_icc != dec_icc and peak_error > 0:
# Transform colors before comparison.
+ # Skip this if we expect fully lossless, since it introduces tiny errors
+ # (even in the case where ref_icc and dec_icc are equivalent so it's a no-op)
if num_channels < 3:
return Failure(f"Only RGB images are supported")
dec_clr = dec_frame[:, :, 0:3]
dec_frame[:, :, 0:3] = lcms2.convert_pixels(dec_icc, ref_icc, dec_clr)
```
|
|
|
jonnyawsom3
|
2026-02-27 08:30:25
|
``` /** Enables or disables preserving color of invisible pixels. Use -1 for the
* default (1 if lossless, 0 if lossy), 0 to disable, 1 to enable.
*/
JXL_ENC_FRAME_SETTING_KEEP_INVISIBLE = 12,```
What if we extended it to also handle redundant alpha? Level 0 to remove empty alpha or overwrite invisible pixel color, 1 to only remove redundant alpha and 2 to always keep alpha
|
|
|
_wb_
|
2026-02-27 08:33:17
|
The thing is that you can have multi-frame images (layered or animation) where the first frame is fully opaque but the rest isn't. If you want to remove alpha completely, you need an image header that doesn't signal that extrachannel, but you need all frames to know if it's redundant, and the current API design is frame-by-frame...
|
|
|
jonnyawsom3
|
2026-02-27 08:35:26
|
Hmm, right...
|
|
|
username
|
2026-02-27 08:41:33
|
hmm maybe redundant alpha removal/detection could just be handed/done by cjxl and maybe restricted to non-multi-frame images as well depending on how the input file type is handled/buffered?
|
|
|
|
veluca
|
2026-02-27 09:20:52
|
we _could_ in theory do the "remove alpha" thing for single frame images
|
|
2026-02-27 09:21:00
|
not sure how well the current code can deal with that
|
|
|
jonnyawsom3
|
2026-02-27 09:30:50
|
If we could get it working and enabled by default, it would mean a free bump to density, encode and decode speed along with better progressive loading
|
|
2026-02-27 12:13:08
|
I just noticed a one-line edit that should significantly speed up progressive lossy encoding of images with transparency. Will test it in a bit
|
|
2026-02-27 01:15:55
|
Around 30% faster with a first test, but going to investigate some more
|
|
2026-02-27 05:31:35
|
A few hours of staring at an if statement later and I still can't get it working properly. It *should* be as simple as changing this to `ModularPartIsLossless` <https://github.com/libjxl/libjxl/blob/main/lib/jxl/enc_frame.cc#L1672>, but the `buffering < 3` check messes it up as it will always be true by default. Regardless of how I arranged it, tests would always fail if I linked the two together
`(!(cparams.responsive && cparams.ModularPartIsLossless()) && cparams.buffering < 3)` Broke
`if (!enc_state.streaming_mode && (!(cparams.responsive && cparams.ModularPartIsLossless()))) {` Broke even harder
It's not a huge deal, as it only impacts progressive VarDCT images with a lossless alpha, but it is still a free 30% encoding speed boost ripe for the taking if we can figure out the conditional nightmare
|
|
|
|
ignaloidas
|
2026-02-27 06:25:48
|
create a table with every condition and desired outcome, it's usually easier to encode the if statement from that
|
|
|
jonnyawsom3
|
2026-02-27 06:32:37
|
The problem is it also depends on other encoder choices, so it's easier to rerun the tests in the background than try to backtrack the heuristics fully.
It *should* have worked with both examples above, but something was causing it to fail
|
|
|
monad
|
2026-02-28 01:41:13
|
Is this what you are trying to do?
|
|
|
jonnyawsom3
|
2026-02-28 02:02:14
|
I think I tried something like that and tests still failed. I might keep trying another day
|
|
|
monad
|
2026-02-28 07:23:02
|
Well, it is mirroring your "Broke even harder" example (the others I could not interpret), but ensuring responsive is set. In this case there are no test failures, which were all size constraints without. It does allow speed ups, but not freely as there are size tradeoffs.
|
|
|
jonnyawsom3
|
2026-02-28 07:24:48
|
Hmm, interesting. I'll take another look when I'm on my computer, it's hard to read on mobile. I was seeing around a 0.1% size increase on my test file
|
|
|
monad
|
2026-02-28 08:57:20
|
It captures progressive lossless, which can get much larger and faster (e.g. >5% larger, >3x faster with 4 threads). Avoiding that, progressive VarDCT can still get both larger and slower.
|
|
|
jonnyawsom3
|
2026-02-28 09:06:45
|
Progressive lossless was already working, progressive VarDCT with Alpha was the target since it defaults to lossless
|
|
|
monad
|
2026-02-28 09:36:53
|
Yep, this is why I point it out. To target more specifically, you'd need to check against the lossless parameter and alpha information.
|
|
|
username
|
2026-03-01 09:58:43
|
|
|
2026-03-01 09:58:44
|
<@794205442175402004> I was thinking and had an idea for how crude preview frame generation could work with chunked encoding. no clue how bad or good of an idea this is or what the quality of the outputs would look like but here it is:
What if when working on each chunk a downscaled version is generated and then kept around in memory until the end where each downscaled chunk is then recombined/restitched into a full image and inserted as a preview frame? would the output of this introduce unacceptable visuals/artifacts and does it even seem sound from a implementation perspective?
|
|
2026-03-01 10:00:43
|
this is somewhat assuming that the intended resolution(s) of preview frames would be pretty low like an LQIP
|
|
|
jonnyawsom3
|
2026-03-01 10:25:39
|
I mean, lossy needs the LF anyway, so you already have a 1:8 downscale of RGB and 2048 x 2048 pixels in memory. Could just downscale it further
|
|
|
username
|
2026-03-01 10:28:28
|
I was thinking mostly about lossless since well AFAIU you don't really get any progressiveness with it unless you use squeeze which would require the full image in memory
|
|
|
jonnyawsom3
|
2026-03-01 10:28:38
|
One fancy thing jxl-rs could do is switch to the main image when it's progressive resolution exceeds the preview resolution
|
|
|
username
I was thinking mostly about lossless since well AFAIU you don't really get any progressiveness with it unless you use squeeze which would require the full image in memory
|
|
2026-03-01 10:32:18
|
Assuming you mean streamed input and not just chunked encode, per-group downsampling should work, since it's not defined anywhere and it should only be a preview anyway
|
|
|
_Broken s̸y̴m̴m̵̿e̴͌͆t̸r̵̉̿y̴͆͠
|
2026-03-04 08:29:00
|
10000 iterations of -e 5 compression at -d 1
In between decoded it with 16 bit per sample, and brought it back down to 8-bit per pixel with imagemagicks -depth option
He's apparently trying to escape, can't blame him.
-# (and yes, it do by one of my own drawings)
|
|
|
_wb_
|
2026-03-04 08:39:05
|
interesting, I wonder why the top survived but the bottom didn't
|
|
|
_Broken s̸y̴m̴m̵̿e̴͌͆t̸r̵̉̿y̴͆͠
|
2026-03-04 08:50:39
|
I'm not sure sure either, but the bottom part did got stronger variance in chroma sooner than the top part-
Thing is, the background down there is basically as calm as on the top, but over iterations the artifacts spread-
|
|
2026-03-04 08:53:44
|
|
|
2026-03-04 08:53:51
|
Iteration 6561
|
|
|
monad
|
2026-03-04 09:50:20
|
the new web
|
|
|
jonnyawsom3
|
2026-03-04 10:06:59
|
Hmmm... I wonder if boosting the blue channel would also help generation loss. It's definitely noticeable in the last image
|
|
|
_Broken s̸y̴m̴m̵̿e̴͌͆t̸r̵̉̿y̴͆͠
|
|
Hmmm... I wonder if boosting the blue channel would also help generation loss. It's definitely noticeable in the last image
|
|
2026-03-04 10:07:36
|
You mean like saturating the blue channel a bit more?
|
|
|
jonnyawsom3
|
2026-03-04 10:08:51
|
I mean increasing the accuracy of it during the encode. It's why the chroma error is almost entirely yellow and blue
|
|
|
_Broken s̸y̴m̴m̵̿e̴͌͆t̸r̵̉̿y̴͆͠
|
2026-03-04 10:09:31
|
ahhh.
I'd not know how to do that, lol
|
|
|
jonnyawsom3
|
2026-03-04 10:10:34
|
Unfortunately if we could do it easily, we already would have
|
|
|
_Broken s̸y̴m̴m̵̿e̴͌͆t̸r̵̉̿y̴͆͠
|
2026-03-04 10:13:15
|
I know-
I mostly wonder if there was a way to circumvent the spread.
But hey, non of this shows up at 10k iteration using `-e 7`
At least not in this image.
There was another one that did develop such black and white waves earlier- at 1000 iterations-
but I need to find an alternative image so I could share.
|
|
|
jonnyawsom3
|
2026-03-04 10:15:56
|
Huh, interesting. I can't think of anything specific that would make e7 any better
|
|
|
_Broken s̸y̴m̴m̵̿e̴͌͆t̸r̵̉̿y̴͆͠
|
|
Huh, interesting. I can't think of anything specific that would make e7 any better
|
|
2026-03-04 10:18:20
|
You mean why e7 would perform better?
|
|
|
VcSaJen
|
|
_Broken s̸y̴m̴m̵̿e̴͌͆t̸r̵̉̿y̴͆͠
|
|
2026-03-04 10:37:07
|
Do you have pics for all iterations? You can use ffmpeg to glue them into a video
|
|
|
_Broken s̸y̴m̴m̵̿e̴͌͆t̸r̵̉̿y̴͆͠
|
|
VcSaJen
Do you have pics for all iterations? You can use ffmpeg to glue them into a video
|
|
2026-03-04 10:41:55
|
I do not as of now-
I'd want to make my script more asynchronous or use a thread to store the images-
as right now it is kinda slowest part of the whole thing-
How ever, I do export images in (I think) logarithmic intervals-
currently 3^x, so `[1, 3, 9, 27, 81, 243, 729, 2187, 6561]`
I probably want to do a clip with 1.5 as a base.
Right now, I'm doing tho another run to 10k, using e1 and --gaborish=1;
Holds up very well so far- But I assume that is because there is nothing that changes in-between iterations.
Okay, between iteration 3 and 729 are changes, but between 729 and 2187 there are none.
Gonna do an e5 run with base 1.5 now and stich it together-
|
|
|
jonnyawsom3
|
2026-03-04 11:35:36
|
I know generation loss used to be a lot better years ago, but I can't remember if it was just Gaborish that regressed or the lossy quality itself
|
|
|
_Broken s̸y̴m̴m̵̿e̴͌͆t̸r̵̉̿y̴͆͠
|
|
I know generation loss used to be a lot better years ago, but I can't remember if it was just Gaborish that regressed or the lossy quality itself
|
|
2026-03-04 11:38:25
|
I mean Gaborish seems to not make it worse-
e1 does not seem to use it, iIrk, but I turned it on and it stood steady there.
So probably is something else.
I mean, I can test e5 and force Gaborish off later and see how it differs.
|
|
2026-03-04 12:37:30
|
Yeah, Gaborish forced off did do something-
Both at the same iteration of 7481-
First is encoder chooses (default), second is Gaborish forced to off-.
Does the encoder choose to enable and disable Gaborish per 'Tile' / 'Chunk' / Area?
Or is it still a hard on off for the whole image, when the encoder chooses?
|
|
|
|
ignaloidas
|
2026-03-04 12:57:18
|
gaborish should be per whole image AFAIK
|
|
2026-03-04 12:58:24
|
weird that it makes that area so much worse, I wonder what is about that area specifically that makes the encoder stumble
|
|
|
_Broken s̸y̴m̴m̵̿e̴͌͆t̸r̵̉̿y̴͆͠
|
|
ignaloidas
weird that it makes that area so much worse, I wonder what is about that area specifically that makes the encoder stumble
|
|
2026-03-04 01:11:55
|
I know that in the other image, which I can not share completely, the encoder stumbled over a 2.5-3 pix thick line with some soft sharpening applied to it-
Which it seems to amplify again and again.
-# I gotta touch some grass for a second
|
|
|
jonnyawsom3
|
2026-03-04 02:01:11
|
Gaborish is on for lossy above distance 0.5, so usually always
|
|
2026-03-06 04:40:50
|
Well that isn't good... Just had cjxl make a file that fails to decode on main
|
|
|
monad
|
|
monad
as long as you do usual verification, since libjxl can fail to produce files or produce files which decoders refuse to decode
|
|
2026-03-06 05:13:33
|
it's a thing
|
|
2026-03-06 05:15:53
|
worse, it can produce out-of-spec files
|
|
2026-03-06 05:16:19
|
(for some definition 'worse')
|
|
|
jonnyawsom3
|
|
Well that isn't good... Just had cjxl make a file that fails to decode on main
|
|
2026-03-06 05:40:47
|
Not exactly a common use case, but strange it fails regardless https://github.com/libjxl/libjxl/issues/4653
|
|
|
monad
|
2026-03-06 07:47:18
|
it is invalid?
|
|
|
jonnyawsom3
|
2026-03-06 08:06:45
|
Fails to decode in libjxl, jxl-rs and Oxide
|
|
|
|
veluca
|
|
Demez
|
2026-03-10 07:38:52
|
|
|
2026-03-10 07:39:05
|
https://tenor.com/view/bro-hell-sus-gif-4640953859587921843
|
|
2026-03-10 07:39:59
|
of course i manage to get the library to crash lol, trying to save downscaled thumbnails to disk for an image viewer im making, though it works just fine when i disable downscaling the image lol
|
|
2026-03-10 07:52:28
|
apparently my app was getting the jxl functions i used from the FreeImageRe dll lmao, no wonder why it didn't want to step into it for debugging lol, but it didn't fix that crash
|
|
2026-03-10 08:00:25
|
ok i got it lol, i never updated the frame_size argument i had for the size of the frame after downscaling lol
|
|
|
AccessViolation_
|
2026-03-10 09:58:21
|
is that JPEG XL with a hyphen in your profile <:CatBlobPolice:805388337862279198>
|
|
|
Demez
|
2026-03-10 11:06:59
|
oops i guess i never changed that lol
|
|
|
jonnyawsom3
|
2026-03-10 03:07:11
|
I can't find the code, but are you using the built-in 1:8 downsample in libjxl too? (though it tends to only work for lossy)
|
|
|
Demez
|
|
I can't find the code, but are you using the built-in 1:8 downsample in libjxl too? (though it tends to only work for lossy)
|
|
2026-03-10 05:55:14
|
if it's not the default, then probably not, i took the code from the encode_oneshot example and modified it for my use case, disabled multithreading, as it's called from a multi threaded thumbnail generator, and set effort of 6 and distance of 3 for now
|
|
2026-03-10 05:55:29
|
not sure how jxl's downsampling works though
|
|
|
jonnyawsom3
|
2026-03-10 05:56:45
|
Ohh right, you're making thumbnails *as* JXLs, not thumbnails *of* JXLs
|
|
|
Demez
|
2026-03-10 05:56:54
|
yeah
|
|
2026-03-10 05:57:16
|
i imagined using lossy jxl here would be a good use case for it
|
|
2026-03-10 05:59:29
|
tiny file size, great quality, and hopefully fast enough encode and decode time, haven't set up loading them back yet still lol
plus if i feel like it later on, i may experiment with animated thumbnails, so i can use animation in jxl too
|
|
2026-03-10 06:00:52
|
though alpha is messed up here in my thumbnails still, it's like 1 bit alpha or something
|
|
|
dogelition
|
2026-03-16 09:55:33
|
i know nothing about openexr, is decoding this file expected to fail using the `exr_to_pq` tool from libjxl?
```sh
$ ./exr_to_pq.exe --luminance 'white=203' screenshot.exr screenshot.png
JPEGXL_TOOLS_CHECK: jxl::extras::DecodeBytes(jxl::Bytes(input_bytes), jxl::extras::ColorHints(), &ppf)
```
```sh
$ file screenshot.exr
screenshot.exr: OpenEXR image data, version 2, storage: scanline, compression: piz, dataWindow: (0 0)-(1919 1079), displayWindow: (0 0)-(1919 1079), lineOrder: increasing y
```
|
|
2026-03-16 09:56:35
|
imagemagick can convert it so the file isn't broken at least
|
|
2026-03-16 10:08:08
|
```sh
$ cjxl screenshot.exr screenshot.jxl
JPEG XL encoder v0.11.1 0.11.1-4 [AVX2,SSE4,SSE2]
Encoding [VarDCT, d1.000, effort: 7]
Compressed to 343.9 kB (1.327 bpp).
1920 x 1080, 4.457 MP/s [4.46, 4.46], , 1 reps, 12 threads.
```
```sh
$ ./cjxl screenshot.exr screenshot.jxl
JPEG XL encoder v0.11.2 332feb1 [AVX2,SSE2]
Getting pixel data failed.
```
seems to be a dependency issue with the windows build from github? guess that should say i'm missing a dll or that it's built without exr support instead of just failing with a generic error
|
|
|
hana
|
2026-03-21 09:37:17
|
i noticed there isn't `cjpegli.exe` build on `<https://artifacts.lucaversari.it/libjxl/libjxl/latest/jxl-x64-windows-static.zip>`
|
|
|
jonnyawsom3
|
2026-03-21 09:42:29
|
https://github.com/libjxl/libjxl/pull/4657
|
|
|
Kleis Auke
|
|
hana
i noticed there isn't `cjpegli.exe` build on `<https://artifacts.lucaversari.it/libjxl/libjxl/latest/jxl-x64-windows-static.zip>`
|
|
2026-03-21 09:42:30
|
This is likely due to <https://github.com/libjxl/libjxl/pull/4657>. See also: https://discord.com/channels/794206087879852103/805176455658733570/1481390243939745874.
|
|
|
Iwritepoems
|
2026-03-21 11:58:55
|
hey i need some help, i am writting a proposal for GSOC "Adding JPEG XL import support in libreoffice" i am not an expert but i wanna know more and learn hooping to find someone who will mentor me
|
|
|
VcSaJen
|
|
https://github.com/libjxl/libjxl/pull/4657
|
|
2026-03-23 07:21:50
|
Was the separate repo updated with changes from this? I heard there was desync issue
|
|
|
jonnyawsom3
|
2026-03-23 07:24:14
|
I think so, but PRs still aren't merged
|
|
2026-03-28 05:48:15
|
Hmm, seems like something might've broken with the butteraugli AQ? Filesize went up massively while visual quality got much worse https://github.com/libjxl/libjxl/issues/4689#issuecomment-4137194862
|
|
|
A homosapien
|
2026-03-28 08:49:18
|
I noticed the same with all screenshot content
|
|
|
Demiurge
|
2026-03-28 12:09:56
|
Effort >7 is not recommended for lossy
|
|
2026-03-28 12:10:49
|
It's been bad as long as I can remember
|
|