JPEG XL

Info

rules 58
github 38692
reddit 688

JPEG XL

jxl-rs 0
tools 4270
website 1813
adoption 22069
image-compression-forum 0
glitch-art 1071

General chat

welcome 3957
introduce-yourself 294
color 1687
photography 3532
other-codecs 25116
on-topic 26652
off-topic 23987

Voice Channels

General 2578

Archived

bot-spam 4577

libjxl

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
2026-01-29 11:00:05
oh
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
2026-03-06 09:40:20
😭
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