|
username
|
2025-01-01 05:38:59
|
not even just libjxl it's also the format itself correct?
|
|
|
VcSaJen
|
|
Demiurge
|
|
0xC0000054
That was the issue, thanks. I think the origin of the bug was my misunderstanding of how `uses_original_profile` interacts with ICC profiles, I had thought that `uses_original_profile` was required for embedding ICC profiles.
|
|
2025-01-01 06:18:05
|
Ohhh, I see... so it should never be set to true when lossy. You can still embed whatever color profile you want, though, in the jxl file. It won't affect how the binary image data itself is encoded though
|
|
2025-01-01 06:18:35
|
It will just be there in case someone wants to know what the original or intended profile is
|
|
|
Quackdoc
|
2025-01-02 07:58:22
|
I have a question regarding the jxl-rs BT.709 PR, it looks like it is using oetf and the inverse oetf when going to linear. As far as I know according to BT.2087 one should use either 2.4 power or a 2 power for doing conversion. Is there any reason why jxl-rs should have the inverse function? or even the encoding function considering it's use is supposedly purely for a "source" capacity?
|
|
|
Demiurge
|
2025-01-02 09:32:29
|
It makes sense to add encoding to jxl-rs later down the line
|
|
2025-01-02 09:33:07
|
It may be beyond the scope right now, but that might not hold true in the future
|
|
2025-01-02 09:34:32
|
It will almost certainly outclass libjxl at decoding and might become the preferred jxl support library
|
|
2025-01-02 09:35:49
|
Once it's complete it's possible many projects that don't need encode will stop using libjxl entirely
|
|
2025-01-02 09:38:18
|
It's likely to be much cleaner and simpler for outside developers to read and start hacking on too, since it's written from scratch.
|
|
|
Quackdoc
|
2025-01-02 09:39:07
|
even then, I can understand maybe having the encode function for an encoder since maybe some sensor wants to be able to pipe data directly to libjxl/jxl-rs if it does get encode support, but I don't believe there is a lot of sense in having the inverse function
|
|
|
dogelition
|
2025-01-02 09:40:39
|
agree, the oetf has nothing to do with how images should be displayed, so 2.4 would make way more sense
|
|
|
Demiurge
|
2025-01-02 09:58:51
|
What about in the case of decoding an arbitrary lossless image with an arbitrary colorspace, to an arbitrary output colorspace
|
|
|
Quackdoc
|
2025-01-02 10:06:52
|
in that case the chances that you want the inverse oetf is extremely slim [av1_dogelol](https://cdn.discordapp.com/emojis/867794291652558888.webp?size=48&name=av1_dogelol)
|
|
|
Tirr
|
2025-01-02 10:15:14
|
it's copied from jxl-oxide. oetf is used when decoding xyb encoded images, because xyb-to-rgb procedure returns linear samples. inverse oetf is used when the input is lossless and some other color encoding is requested. lossless samples are already encoded with a specific transfer function, so it needs to be converted back to linear.
|
|
2025-01-02 10:16:53
|
(of course the result won't be lossless in that case ๐, but jxl-oxide allows requesting other color encoding)
|
|
|
Demiurge
|
2025-01-02 10:18:18
|
It won't be lossless but sometimes you want to decode to whatever it's going to be displayed as
|
|
|
dogelition
|
2025-01-02 10:20:16
|
right, but the bt.709 oetf exists to achieve a certain non-unity end-to-end gamma, and really shouldn't be used for anything other than encoding scene light
and for image colorimetry, you always (?) want to work with display light instead
|
|
|
Quackdoc
|
2025-01-02 10:21:18
|
doing inverse oetf -> xyb -> some other format will result in a wrong image. Like wise, any processing done may also result in the wrong image assuming the processing is supposed to take into account the stuffs.
|
|
|
dogelition
|
|
dogelition
right, but the bt.709 oetf exists to achieve a certain non-unity end-to-end gamma, and really shouldn't be used for anything other than encoding scene light
and for image colorimetry, you always (?) want to work with display light instead
|
|
2025-01-02 10:21:30
|
(and the only use for the inverse oetf that i'm aware of is making certain adjustments like exposure in scene light)
|
|
|
Quackdoc
|
2025-01-02 10:24:12
|
also likewise, going from XYB -> "rec 709" should almost certainly be done using BT.1886 unless you are dumping raw camera info into an xyb encode without doing the pre-requisite processing
|
|
2025-01-02 10:24:48
|
There is a case to be had for that granted, but im just not sure how that pipeline would look and if the oetf would be valid there.
|
|
|
|
veluca
|
2025-01-02 10:27:52
|
pretty sure libjxl does the same, fwiw
|
|
|
Tirr
|
2025-01-02 10:28:00
|
well the spec says "As specified in ITU-R BT.709-6" for `k709` transfer function kind, so I think we should follow that. if BT.1886 is intended then it can still be signalled as gamma 2.4
|
|
|
veluca
pretty sure libjxl does the same, fwiw
|
|
2025-01-02 10:28:27
|
I was also going to say that ๐
|
|
2025-01-02 10:29:10
|
uh well it seems that bt.709 refers to bt.1886
|
|
2025-01-02 10:30:03
|
maybe not, color specifications are such a mess
|
|
|
|
veluca
|
2025-01-02 10:30:57
|
I usually invoke <@604964375924834314> whenever I have doubts about this stuff
|
|
|
Demiurge
|
2025-01-02 10:31:01
|
Just one tiny nitpick. It's < 0.018 not <=
|
|
2025-01-02 10:32:03
|
Likewise for 0.081
|
|
2025-01-02 10:32:31
|
At least according to wikipedia
|
|
|
|
veluca
|
2025-01-02 10:33:01
|
doesn't really make a difference ๐
|
|
|
Tirr
|
2025-01-02 10:33:14
|
it's supposed to be continuous so it shouldn't matter so much
|
|
|
Demiurge
|
2025-01-02 10:36:24
|
The difference is arguably infinitesimally small even
|
|
|
Quackdoc
|
2025-01-02 10:37:14
|
in the end, as far as I know, bt.1886 is intended to be the "accurate as possible" way to decode rec.709 footage while taking into consideration issues that CRT's "generally had" as for the hard "it should be decoded using a pure 2.4 or 2.0 power" comes from https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2087-0-201510-I!!PDF-E.pdf page 3 (of the document, page 5 of the pdf)
|
|
|
Demiurge
|
2025-01-02 10:37:22
|
But it does save you 2 less characters
|
|
|
Quackdoc
|
2025-01-02 10:38:27
|
```
Non-linear to linear conversion from normalized RโฒGโฒBโฒ colour signals EโฒREโฒGEโฒB (Rec. 709) to linearly represented, normalized RGB colour signals EREGEB (Rec. 709) is accomplished by one of two equations which produce slightly different colours from each other:
Case #1: In the case where the goal is to preserve colours seen on a Rec. 709 display1 when displayed on a Rec. 2020 display2, an approximation of the electro-optical transfer function (EOTF) from
Recommendation ITU-R BT.1886 (Rec. 1886) is used:
๐ธ = (๐ธโฒ)2.40, 0 โค ๐ธโฒ โค 1
Case #2: In the case where the source is a direct camera output and the goal is to match the colours of a direct Rec. 2020 camera output, an approximation of the Rec. 709 inverse opto-electronic transfer
function (OETF) is used (see Annex 2):
๐ธ = (๐ธโฒ)2, 0 โค ๐ธโฒ โค 1
```
|
|
2025-01-02 10:38:52
|
well I was hoping copy and paste would format that a bit better, dunno why, it never does.
|
|
|
dogelition
|
2025-01-02 10:40:46
|
note: 2.4 gamma isn't just an approximation, but it's exactly what you get on a display with 0 black levels (e.g. oled)
|
|
|
Quackdoc
|
2025-01-02 10:41:37
|
it's not that 2.4 is an approximation, it's that 0 black levels is an approximation [av1_dogelol](https://cdn.discordapp.com/emojis/867794291652558888.webp?size=48&name=av1_dogelol)
|
|
|
Tirr
|
2025-01-04 07:13:51
|
so it seems that bt.709 basically says, use bt.1886 eotf when decoding to display
|
|
2025-01-04 07:15:36
|
and jxl decodes xyb to display-referred linear (this is why we need hlg ootf when encoding back to hlg signal) so we need bt.1886 inverse eotf
|
|
|
Quackdoc
|
2025-01-04 07:31:40
|
not only when decoding to display, but also when decoding to linear for the purposes of color conversion, since jxl want's to keep the intent of any color, decoding and encoding using 2.4 is prefered
|
|
|
Traneptora
|
|
Tirr
so it seems that bt.709 basically says, use bt.1886 eotf when decoding to display
|
|
2025-01-04 05:04:58
|
yes, though it gets complicated, since TRC and EOTF/OETF aren't quite teh same thing
|
|
2025-01-04 05:05:17
|
if the TRC is tagged as BT.709, by spec, if you're linearizing for the purpose of presentation you should use BT.1886
|
|
2025-01-04 05:05:48
|
If you're linearizing *not* for the purpose of presentation (e.g. if you're scaling in linear light) then you use the inverse of the TRC of BT.709 specified in H.273, and then you use the forward on the way back
|
|
|
Quackdoc
|
|
Traneptora
If you're linearizing *not* for the purpose of presentation (e.g. if you're scaling in linear light) then you use the inverse of the TRC of BT.709 specified in H.273, and then you use the forward on the way back
|
|
2025-01-04 06:38:22
|
really? I've always used 2.4 as per rec.2087 even while doing things like colorwork, while rec is specifically about rec 709 -> rec 2020 I have found that to be the optimal results.
|
|
|
dogelition
|
|
Traneptora
If you're linearizing *not* for the purpose of presentation (e.g. if you're scaling in linear light) then you use the inverse of the TRC of BT.709 specified in H.273, and then you use the forward on the way back
|
|
2025-01-04 07:53:22
|
but if you use the bt.709 oetf (+ its inverse), you're specifically scaling in scene light and not display light. which is almost never what you want
|
|
2025-01-04 07:54:05
|
unless you're specifically trying to simulate something like an exposure adjustment in a camera that uses the oetf
|
|
|
Quackdoc
|
|
dogelition
but if you use the bt.709 oetf (+ its inverse), you're specifically scaling in scene light and not display light. which is almost never what you want
|
|
2025-01-04 08:01:10
|
I think you might be confused? scene light, or more accurately referred to as scene referred or scene linear, *is* linear light. Linear is the direct energy values of light. Display light is the signal when the oetf is applied.
you typically, not always but usually, want to scale in linear colorspace.
|
|
|
dogelition
|
2025-01-04 08:01:49
|
not sure if i'm using the terms right, but what i meant by those is:
scene light: the linear light in the real world that goes into a camera
display light: the linear light that's emitted by a display when showing the picture
|
|
|
Quackdoc
|
2025-01-04 08:03:36
|
Yes, Display light is light that has been modified by an OETF and Scene light is the linear representation of light in essence, it can get a bit more complicated but in the end, "scene light" is what most scalers typically will prefer to work
|
|
2025-01-04 08:21:33
|
the issue with the rec709 transform is that it was in essence "a transform to make content look OK on a CRT" which means it had to be both computationally simple and "generic".
Rec.709 is *Not* a hard spec, it is a recommendation for cameras to use, and camera's almost always modified the spec to make it look good, because not all cameras look the same, and not all displays looked the same. However we *do* know that regardless of source image, rec709 encodes are designed to do one of two things, Look good on a CRT, or look good on BT.1886, which is a result of trying to emulate CRT displays.
If the intended destination of your encode is a 2.4, or at least, can be most reliably represented with 2.4, then using the inverse oetf is wrong. while in **some** cases you may better preserve the source data, you do not preserve the *intended data* from the artist or device.
Using the inverse rec 709 oetf to me only make sense in an authoring workflow and only when you know the source data is encoded in an actual 709 oetf, which as I stated before, is not always the case, and for context I will leave a quote from jack holm
https://community.acescentral.com/t/where-exact-numbers-of-rec709-formula-came-from-and-a-question-about-p3/3940/5
```
Itโs all about what results in a pleasing image on the display!
...
The Rec 709 OETF is a โreferenceโ OETF โ a reference for camera makers and for conversions of scene-referred colorimetry to the Rec 709 encoding. In practice, camera makers may use slightly different OETFs to optimize results for specific camera characteristics and to produce their desired default looks for their cameras.
...
It is not reliable to assume that the Rec 709 OETF has actually been used, unless this is known to be the case.
...
A far better reference for the desired colorimetry is the Rec 1886 EOTF, and even in this case one is assuming the content was mastered for the Rec 1886 reference display and viewing conditions.
```
|
|
2025-01-04 08:26:00
|
the reason why this doesn't really apply to sRGB is because
A) the "collection of official and unofficial sRGB specs" have a long history of contradictory information that has caused both displays and produces to encode and display sRGB content in a wide variety of wrong ways.
B) It is generally safe to assume that content that has been produced via a linear -> display transform would have been done using the sRGB oetf, however when doing color work, this discrepancy in how the author likely wanted it to be displayed needs to be taken into consideration and compensation needs to be done
C) no one cares about sRGB, everyone just kinda agrees that sRGB will never really be consistent so we can only do a "best guess"
|
|
|
Traneptora
|
|
Quackdoc
the issue with the rec709 transform is that it was in essence "a transform to make content look OK on a CRT" which means it had to be both computationally simple and "generic".
Rec.709 is *Not* a hard spec, it is a recommendation for cameras to use, and camera's almost always modified the spec to make it look good, because not all cameras look the same, and not all displays looked the same. However we *do* know that regardless of source image, rec709 encodes are designed to do one of two things, Look good on a CRT, or look good on BT.1886, which is a result of trying to emulate CRT displays.
If the intended destination of your encode is a 2.4, or at least, can be most reliably represented with 2.4, then using the inverse oetf is wrong. while in **some** cases you may better preserve the source data, you do not preserve the *intended data* from the artist or device.
Using the inverse rec 709 oetf to me only make sense in an authoring workflow and only when you know the source data is encoded in an actual 709 oetf, which as I stated before, is not always the case, and for context I will leave a quote from jack holm
https://community.acescentral.com/t/where-exact-numbers-of-rec709-formula-came-from-and-a-question-about-p3/3940/5
```
Itโs all about what results in a pleasing image on the display!
...
The Rec 709 OETF is a โreferenceโ OETF โ a reference for camera makers and for conversions of scene-referred colorimetry to the Rec 709 encoding. In practice, camera makers may use slightly different OETFs to optimize results for specific camera characteristics and to produce their desired default looks for their cameras.
...
It is not reliable to assume that the Rec 709 OETF has actually been used, unless this is known to be the case.
...
A far better reference for the desired colorimetry is the Rec 1886 EOTF, and even in this case one is assuming the content was mastered for the Rec 1886 reference display and viewing conditions.
```
|
|
2025-01-05 12:23:06
|
tbf if the input is tagged as rec709 with cicp or similar, you have nothing else to work with other than the assumption of reference
|
|
2025-01-05 12:23:31
|
so if your goal is to do some sort of image processing (e.g. scaling) in linear light, then roundtripping through the function defined in H.273 (and its inverse) is kinda the best you got
|
|
2025-01-05 12:24:31
|
also, for sRGB, it's not fair to say that you never know. if, for example, libjxl receives an image tagged as sRGB (without an icc profile, just tagged, e.g. sRGB chunk png) then it will use a specific linearization when converting to XYB, so if you're decoding a lossy JXL, it's safe to assume that the formula in H.273 is the correct one if you want to produce a PNG file tagged as sRGB
|
|
2025-01-05 12:25:00
|
since all current JXL encoders use that formula to linearize before applying the Opsin matrix, then any decoder can reasonably use it after applying the Opsin Inverse Matrix
|
|
|
Demiurge
|
2025-01-05 05:51:54
|
It's just a transfer curve...
|
|
|
Quackdoc
|
|
Traneptora
tbf if the input is tagged as rec709 with cicp or similar, you have nothing else to work with other than the assumption of reference
|
|
2025-01-05 07:19:18
|
thats not really true though. We can reliably assume the destination is going to be either BT.1886, a CRT, or a display that roughly mimics a CRT's characteristics.
also for sRGB while what JXL does is reliable, it's not reliable to assume how the png itself was crafted. we don't know if the host monitor was a pure 2.2 decode, or an inverse sRGB oetf, nor do we know if the source application used a pure 2.2. The best thing we can do is guess in that case.
sRGB will always be a mess lol. even if jxl's solution is perfect, garbage in garbage out
|
|
|
Traneptora
|
|
Quackdoc
thats not really true though. We can reliably assume the destination is going to be either BT.1886, a CRT, or a display that roughly mimics a CRT's characteristics.
also for sRGB while what JXL does is reliable, it's not reliable to assume how the png itself was crafted. we don't know if the host monitor was a pure 2.2 decode, or an inverse sRGB oetf, nor do we know if the source application used a pure 2.2. The best thing we can do is guess in that case.
sRGB will always be a mess lol. even if jxl's solution is perfect, garbage in garbage out
|
|
2025-01-05 07:24:31
|
in that case, we should roundtrip with the bt.709 curve defined in H.273
|
|
|
Quackdoc
|
2025-01-05 07:36:41
|
I don't really see the benefits of that. since we know that a pure 2.4 power curve is the most accurate for decoding rec709 as bt.1886 establishes, doing work in a 2.4 linearization seems to be the most accurate when it comes to doing processing.
rec 2087 also concurrs that when doing rec 708 -> rec 2020, you should do linearization utilizing the the approximation of the bt.1886, the pure 2.4 power curve.
It does also explicitly acknowledges that when the source is a direct camera output, and the goal is to match the colors of a "rec 2020 camera output" that you should use an approximation of the inverse 709, which they use a 2 power for.
In nearly all cases that we would care about, the goal should be to preserve the colors as seen on a rec 709 display, and only in the cases were we know for sure that this isn't the goal, should we use the inverse 709 oetf, or an approximation of it
|
|
2025-01-05 07:40:29
|
ofc that's not to say the inverse oetf should never be used, if I am recording footage and importing said footage into a video editor, I will often default to using the inverse oetf, but that's simply because the color is better to work with, and im using it to craft ofter things. If you are taking already mastered content, the 2.4 should be used.
|
|
|
jonnyawsom3
|
2025-01-05 08:45:40
|
Perhaps <#1288790874016190505> so people can find this more easily later?
|
|
|
Tirr
|
2025-01-05 09:14:30
|
uh maybe https://github.com/tirr-c/jxl-oxide/issues/318 is actually related to this
|
|
2025-01-05 09:20:34
|
yeah, it seems to preserve colors if I modify libjxl to use gamma2.4 on BT.709 input
|
|
2025-01-05 09:27:42
|
nevermind, I was comparing with wrong image
|
|
2025-01-05 09:39:00
|
I forgot to modify ICC profile generation part; when I modify it to generate gamma2.4 trc, it does preserve colors
|
|
|
Quackdoc
|
2025-01-05 09:53:35
|
the discrepancy between offsets wouldn't cause such a harsh difference in general, though it would cause some
|
|
|
Tirr
|
2025-01-05 10:06:19
|
like, without the fix, bt709 to jxl-xyb to srgb doesn't roundtrip visually
|
|
2025-01-05 10:08:49
|
srgb-decoded version looks too bright on dark areas
|
|
|
Quackdoc
|
2025-01-05 10:15:25
|
im not sure im following
|
|
2025-01-05 10:15:31
|
ill try to re-read the issue
|
|
|
Tirr
|
2025-01-05 10:26:35
|
Encode an image tagged as BT.709 to jxl. Then decode the jxl to BT.709 (no options) and sRGB (`--color_space=RGB_D65_SRG_Rel_SRG`). I expect those two decoded images should look identical, but with current libjxl the sRGB one looks too bright.
|
|
2025-01-05 10:27:24
|
(yeah, now I think this isn't a roundtrip)
|
|
2025-01-05 10:28:56
|
when I modify libjxl to use gamma2.4 on BT.709, two decoded images look identical
|
|
|
Quackdoc
|
2025-01-05 10:32:11
|
ah I see. sorry, had a hard time following.
|
|
|
Tirr
|
2025-01-05 10:34:42
|
so libjxl is currently applying inverse OETF to encode a BT.709 image so it's encoding in scene light. libjxl also applies OETF when decoding so it works okay when decoding to BT.709, but it breaks when sRGB is requested, because sRGB inverse EOTF works on display light (if I'm getting this right)
|
|
|
spider-mario
|
2025-01-05 10:36:15
|
thatโs oddย โ in an ICC workflow, they should look identical regardless of the curve, because the curve thatโs used in decoding should match the one in the ICC profile that is attached to the file
|
|
2025-01-05 10:36:37
|
are you maybe viewing them in Chrome and itโs giving precedence to the CICP chunk?
|
|
|
Tirr
|
2025-01-05 10:37:55
|
because libjxl doesn't use ICC workflow when decoding XYB image? I guess it's just FromLinear stage that ignores tagged transfer curve
|
|
|
spider-mario
|
2025-01-05 10:38:13
|
I meant in viewing the image
|
|
|
Tirr
|
2025-01-05 10:38:49
|
well macOS Preview, Chrome and Firefox all agree that sRGB one is brighter than BT.709 one
|
|
|
Quackdoc
|
2025-01-05 10:38:52
|
im a little confused, ill try to break this down.
jxl gets image - applies inverse oetf - converts to xyb - converts to linear sRGB - applies rec 709 oetf - rec709.png
jxl gets image - applies inverse oetf - converts to xyb - converts to linear sRGB - applies srgb inverse oetf - srgb.png
?
the first one will look fine since it is undoing the transfer effectively, but as far as I am aware, the latter will look wrong.
|
|
|
spider-mario
|
2025-01-05 10:39:06
|
libjxl will ignore the tagged curve when requesting a specific output colorspace, but which one is requested shouldnโt affect how the decoded image looks, because libjxl should attach an ICC profile to it that matches the curve it effectively used
|
|
2025-01-05 10:39:51
|
if the โoriginal image -> xybโ part is wrong, it should be wrong equally for both of them
|
|
2025-01-05 10:41:11
|
that the original image happened to be in BT.709 should be relevant only to whether the decoded image looks like the original
|
|
2025-01-05 10:41:19
|
not whether the two decoded images look the same
|
|
2025-01-05 10:41:44
|
at least as far as I can tell
|
|
|
Tirr
|
2025-01-05 10:42:20
|
ah I think I got what you mean, yeah they seem to give precedence to cicp tag then
|
|
|
Quackdoc
im a little confused, ill try to break this down.
jxl gets image - applies inverse oetf - converts to xyb - converts to linear sRGB - applies rec 709 oetf - rec709.png
jxl gets image - applies inverse oetf - converts to xyb - converts to linear sRGB - applies srgb inverse oetf - srgb.png
?
the first one will look fine since it is undoing the transfer effectively, but as far as I am aware, the latter will look wrong.
|
|
2025-01-05 10:47:34
|
that's what I think libjxl is doing, yeah
|
|
2025-01-05 10:53:12
|
Chrome shows images look identical if I remove cicp tag from the ICC profile, but in a way that looks too bright
|
|
|
Quackdoc
|
2025-01-05 02:36:30
|
in general the top one is fine since you are just reversing the change, the real issue comes when you apply the inverse oetf and go to different spaces. It may not be so bad in many cases, but in others it might be a rather different result
|
|
|
|
anonymguy
|
2025-01-05 09:20:35
|
Hey, I extracted the zip file jxl-x64-windows-static and added it to my PATH, but I still cant use it. (I am on windows 10)
|
|
|
jonnyawsom3
|
|
anonymguy
Hey, I extracted the zip file jxl-x64-windows-static and added it to my PATH, but I still cant use it. (I am on windows 10)
|
|
2025-01-05 09:21:18
|
What command are you trying to run?
|
|
|
|
anonymguy
|
2025-01-05 09:21:34
|
djxl --version
|
|
|
jonnyawsom3
|
2025-01-05 09:22:32
|
Hmm
|
|
2025-01-06 09:57:59
|
https://github.com/google/jpegli
|
|
|
HCrikki
|
2025-01-06 11:24:17
|
any nightly binaries that are also accessible publicly ?
|
|
|
Waterpicker
|
2025-01-06 06:22:52
|
is there ready avaialble simple package for a .dll .so and .dylib builds of libjxl?
|
|
|
jonnyawsom3
|
2025-01-07 09:14:10
|
I originally discounted this as 'higher effort is higher quality' or patches being used, but twice the file size in an image where no patches should be found...
It might be worth looking into as a bug, especially as it's a 16bit image https://www.reddit.com/r/jpegxl/comments/1htswuo/comment/m5unvcc/
|
|
2025-01-07 09:14:39
|
> The reference image is a blender rendering for GNOME wallpapers (this particular image is this). I got the original blender assets and re-rendered myself to a higher quality and preserve noise, which is what I'm encoding in the screenshot. The image has some unpredictable noise, but the results seemed pretty good for the file size. It is a reduction from ~400MB (5000x5000x16bit) to some megabytes. I simply found strage the file increase the better the effort.
|
|
|
A homosapien
|
|
> The reference image is a blender rendering for GNOME wallpapers (this particular image is this). I got the original blender assets and re-rendered myself to a higher quality and preserve noise, which is what I'm encoding in the screenshot. The image has some unpredictable noise, but the results seemed pretty good for the file size. It is a reduction from ~400MB (5000x5000x16bit) to some megabytes. I simply found strage the file increase the better the effort.
|
|
2025-01-07 11:57:00
|
I don't think its a bug. For images with a large flat areas, the more context libjxl has the better it can achieve its target quality. It seems to detect that it's wildly under shooting the desired butteraugli score and increases the bitrate to compensate.```
cjxl glass-chip-d.jxl glass-chip-compressed.jxl -d 0.5 -e 9
Compressed to 2669.4 kB (1.273 bpp).
SSIM2 Score = 84.56
butteraugli = 1.36
cjxl glass-chip-d.jxl glass-chip-compressed.jxl -d 0.5 -e 10
Compressed to 4550.3 kB (2.170 bpp).
SSIM2 Score = 88.63
butteraugli = 0.72
```
|
|
2025-01-07 11:58:00
|
A ssimulacra2 score of 84 is quite low for a distance of 0.5.
|
|
2025-01-08 01:40:12
|
Granted I'm working with the lossy image from the reddit post but I'm gonna retest with a clean source.
|
|
|
Traneptora
|
2025-01-08 03:27:46
|
higher file size for higher effort usually means that the lower efforts are undershooting the quality target
|
|
|
jonnyawsom3
|
|
A homosapien
Granted I'm working with the lossy image from the reddit post but I'm gonna retest with a clean source.
|
|
2025-01-08 04:06:55
|
His image source is 16bit and 5K instead of 4K, and with real rendering noise instead of photon noise. Though, the results you've posted do match rather well
|
|
2025-01-08 04:07:54
|
I doubt you can relay the find as a comment on Reddit?
|
|
|
A homosapien
|
2025-01-08 04:12:53
|
I do have a reddit, lemme dust off my old account and get to it.
|
|
|
jonnyawsom3
|
2025-01-08 09:40:56
|
Still thinking about this... I wonder how much tweaking and tuning it'll take to be as good as the old method. It seemed to make encoding slower and result in worse Ssimulacra2 scores, which our eyes have been agreeing with ever since https://github.com/libjxl/libjxl/pull/2836
|
|
|
_wb_
|
2025-01-08 09:49:24
|
It would be nice to have multiple completely different approaches for encoder heuristics, either with multiple settings of libjxl or by having more alternative encoders.
|
|
|
jonnyawsom3
|
2025-01-08 09:53:19
|
It'd be nice, but the use would be limited to those who know what setting fits that particular image best. Back to `-tune`...
Since this regression was caused by the metrics giving different results, and only Ssimulacra2 was right, it could even hurt performance
|
|
|
_wb_
|
2025-01-08 10:07:06
|
I am not in favor of manual per-image tuning, but having some healthy competition between encoders (all aiming to be good general-purpose encoders) could be a good thing that over time leads to improvements.
|
|
2025-01-08 10:12:29
|
Currently with only one good encoder, we're a bit suffering from the problem that only small incremental changes are made at this point since doing big changes is too scary. That would be less of an issue if there are multiple experimental encoders around...
|
|
|
jonnyawsom3
|
2025-01-08 10:18:14
|
Yeah. Looking at the Hydrium encode I just made, it's even using the same block decisions as `-e 7 -d 0.6`. So we haven't seen any other strategies past using cjxl 0.8
|
|
2025-01-13 03:22:29
|
Looking forward to trying this https://github.com/libjxl/libjxl/pull/4062
|
|
2025-01-13 03:23:25
|
Though is the corrupt DC setting the output black, or only the DC so the AC can still show?
|
|
|
_wb_
|
2025-01-13 04:41:42
|
The thing is that AC metadata is sent together in the same section with DC groups so if DC is corrupt, the AC metadata will also be corrupt.
|
|
2025-01-13 04:42:13
|
So you cannot really decode or show AC if something is wrong with the corresponding DC group
|
|
|
jonnyawsom3
|
2025-01-13 04:52:27
|
Ahh right
|
|
|
Demiurge
|
|
_wb_
Currently with only one good encoder, we're a bit suffering from the problem that only small incremental changes are made at this point since doing big changes is too scary. That would be less of an issue if there are multiple experimental encoders around...
|
|
2025-01-13 05:12:01
|
Someone should fork libjxl-ng
|
|
2025-01-13 05:12:16
|
Maybe those psy tuning avif guys...
|
|
2025-01-13 05:12:49
|
But it really just needs a massive code cleanup more than anything
|
|
2025-01-13 05:13:59
|
Simplifying the directory tree and separating out the main library code from the tool code
|
|
2025-01-13 05:14:44
|
That would make it way easier for newcomers to hack on it
|
|
|
AccessViolation_
|
|
_wb_
Currently with only one good encoder, we're a bit suffering from the problem that only small incremental changes are made at this point since doing big changes is too scary. That would be less of an issue if there are multiple experimental encoders around...
|
|
2025-01-13 05:50:18
|
why not an `experiments` branch for the encoder, or specific branches for specific experiments?
|
|
|
A homosapien
|
2025-01-13 06:43:56
|
I've been talking to the psy av1 guys and they have been working on a psy fork for jxl
|
|
|
Demiurge
|
2025-01-13 09:27:13
|
Currently libjxl has multiple different very distinct encoders or encoding modes. It's more accurate to call it a single common frontend to multiple different encoders than to pretend that it's just a single encoder.
|
|
2025-01-13 09:29:56
|
The vardct stuff is pretty separate and contained and so is fjxl
|
|
2025-01-13 09:31:57
|
Also the Squeeze mode has incredible, insane potential considering how it looks better than vardct despite vardct getting all the tuning
|
|
2025-01-13 09:35:03
|
Also I heard there's another interesting palette based encode mode that seems super promising too especially for near-lossless coding
|
|
2025-01-13 09:35:29
|
I forgot the name though
|
|
2025-01-13 09:36:05
|
Honestly all these different encoders could be split into separate folders or something and fjxl can be the default
|
|
2025-01-13 09:37:18
|
Since the speed will instantly knock peoples' socks off and you can never go wrong with lossless
|
|
|
spider-mario
|
|
Demiurge
I forgot the name though
|
|
2025-01-13 10:06:43
|
ฮ palette?
|
|
|
Demiurge
|
2025-01-13 10:07:00
|
Yeah, lossy palette or delta palette
|
|
2025-01-13 10:07:05
|
Something like that
|
|
2025-01-13 10:07:53
|
Seems like a promising and underused/underrated option
|
|
|
AccessViolation_
|
2025-01-13 10:10:14
|
With this many coding tools which can be combined in interesting ways, I wonder if we're going to see encoders tuned for every specific purposes. Like one specifically for screenshots that might eagerly use patches for text, a frame with most of the rest of the image in Modular mode and a VarDCT frame for photographic sections that happen to be in the screenshot, like a wallpaper photo
|
|
2025-01-13 10:13:56
|
Maybe JPEG XL could do with an encoder *engine*(?). A library which gives you the low level building blocks a JXL encoder would need, and allows you to create an encoder tuned for a specific purpose yourself. In a similar sense to Smithay, which is not a Wayland compositor but provides the things you need to build a Wayland compositor, which several compositors are using
|
|
2025-01-13 10:15:17
|
But I'm just thinking aloud
|
|
2025-01-13 10:23:06
|
If you wanted to create an encoder that makes use of a specific combination of coding tools that seem useful for your purpose, you bind to the library and write relatively little code to define the logic of your encoder. Though maybe this can already be achieved with the libjxl API, I just remembered that's a thing and I'm not familiar with it
|
|
|
Cesar
|
2025-01-13 10:35:51
|
I have tested `webp` `libx264` `libx265` `AVIF`
`AVIF` produces smallest size but biggest CPU usage
then `x265`
`x264` was the smallest cpu usage with a medium size
`webp` good quality and size but also high cpu
My software will encode images constantly send them through a websocket and decode them on the server side
What about libjxl
|
|
|
AccessViolation_
|
2025-01-13 10:42:33
|
I haven't compared them, but with cjxl you can fairly easily change the CPU usage of the encoding process using the effort flag `-e`
|
|
|
spider-mario
|
|
Cesar
I have tested `webp` `libx264` `libx265` `AVIF`
`AVIF` produces smallest size but biggest CPU usage
then `x265`
`x264` was the smallest cpu usage with a medium size
`webp` good quality and size but also high cpu
My software will encode images constantly send them through a websocket and decode them on the server side
What about libjxl
|
|
2025-01-13 10:44:20
|
webp and libjxl both have a range of possible speeds, but at any given speed, libjxl compresses better
https://cloudinary.com/blog/jpeg-xl-and-the-pareto-front#the_pareto_front
|
|
|
AccessViolation_
|
2025-01-13 10:44:27
|
you can experiment with `-d` or `-q` for quality and `-e` for encoding effort (how hard it'll try) to strike a balance that fits your purpose
|
|
|
spider-mario
|
2025-01-13 10:44:49
|
here is lossless compression
|
|
|
AccessViolation_
|
2025-01-13 10:44:50
|
unlike avif encoders which I wouldn't personally even attempt to configure
|
|
|
Cesar
|
|
spider-mario
here is lossless compression
|
|
2025-01-13 10:45:25
|
Cool, i'll try the c lib
|
|
2025-01-13 10:46:05
|
I'm encoding images of size 960x540, while trying to maintain a quality of around 60%
|
|
2025-01-13 10:48:00
|
The graphic you shared doesnt include `libjpeg-turbo`, have you ever tested it?
|
|
|
spider-mario
|
2025-01-13 10:48:41
|
this graphic is for lossless, which libjpeg-turbo doesnโt do
|
|
2025-01-13 10:48:45
|
see further down in the article for lossy
|
|
2025-01-13 10:48:52
|
(where libjpeg-turbo is featured)
|
|
|
Cesar
|
2025-01-13 10:55:49
|
There's a package on vcpkg listed as `libjxl:x64-windows` but its not mentioned in the [documentation](https://github.com/libjxl/libjxl/blob/main/doc/developing_in_windows_vcpkg.md), is it "official"?
|
|
|
RaveSteel
|
2025-01-13 11:25:44
|
libjpeg-turbo actually does do lossless, but it is pretty much always worse than PNG
|
|
|
CrushedAsian255
|
|
AccessViolation_
With this many coding tools which can be combined in interesting ways, I wonder if we're going to see encoders tuned for every specific purposes. Like one specifically for screenshots that might eagerly use patches for text, a frame with most of the rest of the image in Modular mode and a VarDCT frame for photographic sections that happen to be in the screenshot, like a wallpaper photo
|
|
2025-01-13 11:34:07
|
So libjxl could be a common front end and have some way of selecting the best backend encoder for each image (or even section of image)?
|
|
|
Cesar
|
2025-01-13 11:44:34
|
Is it not possible to cache the encoder, frame and frame settings?
|
|
|
CrushedAsian255
|
2025-01-14 12:42:18
|
Cache the encoder?
|
|
2025-01-14 12:42:24
|
Like CPU cache?
|
|
2025-01-14 12:42:34
|
Or like if an image is being re encoded ?
|
|
|
Cesar
|
2025-01-14 12:49:43
|
```c++
class Jxl
{
public:
struct Data
{
int width = 0;
int height = 0;
int stride = 0;
BYTE* Scan0 = nullptr;
using client = websocketpp::client<websocketpp::config::asio_client>;
client* wsClient;
websocketpp::connection_hdl* connection;
} _;
std::vector<uint8_t> _compressedData;
JxlEncoderPtr _enc;
JxlBasicInfo _basicInfo;
JxlPixelFormat _format = { 3, JXL_TYPE_UINT8, JXL_NATIVE_ENDIAN, 0 };
JxlEncoderFrameSettings* _frameSettings;
Jxl(const Data&& data) : _(data)
{
_compressedData.resize(223887);
JxlEncoderInitBasicInfo(&_basicInfo);
_basicInfo.xsize = _.width;
_basicInfo.ysize = _.height;
_basicInfo.num_color_channels = 3;
_basicInfo.bits_per_sample = 8;
init();
}
bool init()
{
_enc = JxlEncoderMake(nullptr);
if (!_enc)
throw std::runtime_error("JXL encoder initialization failed");
JxlEncoderSetBasicInfo(_enc.get(), &_basicInfo);
if (_frameSettings)
{
JxlEncoderFrameSettingsCreate(_enc.get(), _frameSettings);
//_enc.get()->encoder_options.emplace_back(_frameSettings);
}
else
{
_frameSettings = JxlEncoderFrameSettingsCreate(_enc.get(), nullptr);
// Testing encoding settings similar to WebP
JxlEncoderSetFrameLossless(_frameSettings, false);
JxlEncoderSetFrameDistance(_frameSettings, 13);
JxlEncoderFrameSettingsSetOption(_frameSettings, JXL_ENC_FRAME_SETTING_EFFORT, 1);
}
return true;
}
bool encode()
{
if (!init())
throw std::runtime_error("JXL encoder initialization failed");
if (JxlEncoderAddImageFrame(
_frameSettings,
&_format,
static_cast<void*>(_.Scan0),
_.stride * _.height)
!= JXL_ENC_SUCCESS)
{
return false;
}
JxlEncoderCloseFrames(_enc.get());
uint8_t* next_out = _compressedData.data();
size_t avail_out = _compressedData.size();
JxlEncoderStatus processResult;
do
{
processResult = JxlEncoderProcessOutput(_enc.get(), &next_out, &avail_out);
if (processResult == JXL_ENC_NEED_MORE_OUTPUT)
{
size_t offset = next_out - _compressedData.data();
_compressedData.resize(_compressedData.size() * 2);
next_out = _compressedData.data() + offset;
avail_out = _compressedData.size() - offset;
}
} while (processResult == JXL_ENC_NEED_MORE_OUTPUT);
if (processResult != JXL_ENC_SUCCESS)
return false;
_compressedData.resize(_compressedData.size() - avail_out);
websocketpp::lib::error_code ec;
_.wsClient->send(*_.connection,
_compressedData.data(),
_compressedData.size(),
websocketpp::frame::opcode::binary);
//_compressedData.clear();
return true;
}
};
```
|
|
2025-01-14 12:55:31
|
```c++
class Webp
{
public:
WebPConfig _config;
WebPPicture _pic;
WebPMemoryWriter _writer;
struct Data
{
int width = 0;
int height = 0;
int stride = 0;
BYTE* Scan0 = nullptr;
using client = websocketpp::client<websocketpp::config::asio_client>;
client* wsClient;
websocketpp::connection_hdl* connection;
} _;
Webp(const Data&& data) : _(data)
{
WebPConfigInit(&_config);
_config.quality = 60; // 0-100, lower = smaller file
_config.method = 0; // 0-6, higher = better compression but slower
_config.lossless = 0; // Use lossy compression
_config.pass = 1; // Number of encoder passes
_config.thread_level = 0; // Enable multi-threading
//config.near_lossless = 90;
WebPPictureInit(&_pic);
_pic.width = _.width;
_pic.height = _.height;
_pic.use_argb = 0;
WebPPictureAlloc(&_pic);
WebPMemoryWriterInit(&_writer);
_pic.custom_ptr = &_writer;
_pic.writer = WebPMemoryWrite;
}
bool encode()
{
if (!WebPPictureImportRGB(&_pic, _.Scan0, _.stride))
{
WebPPictureFree(&_pic);
return false;
}
if (!WebPEncode(&_config, &_pic))
{
WebPPictureFree(&_pic);
return false;
}
websocketpp::lib::error_code ec;
_.wsClient->send(*_.connection, _writer.mem, _writer.size, websocketpp::frame::opcode::binary);
WebPPictureFree(&_pic);
WebPMemoryWriterClear(&_writer);
return true;
}
};
```
|
|
2025-01-14 12:56:10
|
I'm asking if its possible to "cache" the encoder, create it and its settings only once and reuse to encode next images.
I'm more constrained by CPU usage.
|
|
|
Demiurge
|
2025-01-14 04:36:31
|
Can you use the same context to encode multiple images?
|
|
|
AccessViolation_
With this many coding tools which can be combined in interesting ways, I wonder if we're going to see encoders tuned for every specific purposes. Like one specifically for screenshots that might eagerly use patches for text, a frame with most of the rest of the image in Modular mode and a VarDCT frame for photographic sections that happen to be in the screenshot, like a wallpaper photo
|
|
2025-01-14 04:42:47
|
You shouldn't need to... I think the best possible approach is to optimize each encoding tool as much as possible, even if some tools like patch detection need to be run in their own separate pass, and then make it easier for the individual tools to be combined in effective ways, depending on the effort level.
|
|
2025-01-14 04:44:08
|
Like with more effective image decomposition and layering techniques than just patches
|
|
2025-01-14 04:45:57
|
Grain detection, spline detection, cartoon layer decomposition even
|
|
2025-01-14 04:49:02
|
Imagine if the encoder could automatically tell when DCT is ineffective
|
|
2025-01-14 04:49:36
|
So you don't have to manually specify different options for different types of images
|
|
2025-01-14 04:49:54
|
That's the dream
|
|
2025-01-14 04:50:58
|
Then you don't have to worry about those cases where lossless is actually smaller than dct
|
|
|
A homosapien
|
2025-01-14 04:53:30
|
These are plans for the far future though, the major milestone this year is the completion of the rust decoder and (hopefully) its adoption by Mozilla.
|
|
|
AccessViolation_
|
|
Demiurge
You shouldn't need to... I think the best possible approach is to optimize each encoding tool as much as possible, even if some tools like patch detection need to be run in their own separate pass, and then make it easier for the individual tools to be combined in effective ways, depending on the effort level.
|
|
2025-01-14 08:21:48
|
Yeah this would be good, but heuristics will always be hard to get right. So if you know you're only going to be encoding certain types of images you can specifically tune your encoder for those, instead of hoping the one true encoder makes the right guesses. For example a scanner in 'document mode' would spend more effort on patch detection, and using splines for lines like borders of tables and pen strokes like signatures, while in 'photo mode' it might just spend a lot of effort on the VarDCT stuff
|
|
|
A homosapien
|
2025-01-14 08:44:51
|
Just because it's hard doesn't mean we shouldn't pursue it. I don't believe adding tunes is the right direction for libjxl. It's certainly the easy way out but I think it would make things more complicated later on.
There is *so much* that can be done to make the encoder smarter. I believe with good heuristics the codec can make good decisions 99% of the time. It's hard to imagine a "dumb codec" existing in the far future.
|
|
|
AccessViolation_
|
2025-01-14 09:04:57
|
To be clear I wasn't suggesting these domain specific encoders be made a part of libjxl or developed by the core devs. Rather just existing on their own where they would be useful. I agree that a smarter encoder should be what the effort is poured into for libjxl. It's just that I could see some use cases where you basically know what your data will generally look like ahead of time, and then you could save massively on encode time if it's not trying really hard to figure out things that you already know
|
|
|
jonnyawsom3
|
|
Cesar
I'm asking if its possible to "cache" the encoder, create it and its settings only once and reuse to encode next images.
I'm more constrained by CPU usage.
|
|
2025-01-14 09:15:55
|
At such low effort settings, libjxl essentially works as a JPEG encoder <https://github.com/libjxl/libjxl/blob/main/doc/encode_effort.md>
I'd maybe suggest looking at jpegli if not checking what version libjxl you're using and that hardware instructions (SSE, AVX, ect) are enabled properly. On my tests cjxl is working at identical speeds to cwebp following your settings above (Though the webp is 70KB and much higher quality than the 19KB JXL I got...)
|
|
|
Cesar
|
|
At such low effort settings, libjxl essentially works as a JPEG encoder <https://github.com/libjxl/libjxl/blob/main/doc/encode_effort.md>
I'd maybe suggest looking at jpegli if not checking what version libjxl you're using and that hardware instructions (SSE, AVX, ect) are enabled properly. On my tests cjxl is working at identical speeds to cwebp following your settings above (Though the webp is 70KB and much higher quality than the 19KB JXL I got...)
|
|
2025-01-14 09:26:10
|
I didn't test `jpegli` ill try it, do you?
I also tested turbojpeg and from all libs i have tested until now, it was the one with lowest CPU usage.
|
|
|
jonnyawsom3
|
|
Demiurge
Yeah, lossy palette or delta palette
|
|
2025-01-14 10:08:16
|
Finally got round to checking if it's working in Krita, and yep. A lot of settings seem to have no effect on it, but it scores 5 lower in ssimulacra while preserving more texture to my eyes at a similar bpp to VarDCT (Around distance 0.5)
Original, VarDCT, Delta
|
|
2025-01-14 10:08:41
|
|
|
2025-01-14 10:11:45
|
Also <@274048677851430913> the EPF setting in Krita's export dialogue can't be set to -1 to let the encoder choose. Group ordering wasn't working either but you already fixed that for the next release IIRC
|
|
|
Demiurge
|
2025-01-14 10:38:16
|
Metrics are guiding people into blindly (literally) making really bad decisions
|
|
|
A homosapien
|
2025-01-14 10:48:00
|
I kinda agree with ssimulacra2 here. Lining up the images side-by-side, I could see that delta palette has a somewhat fuzzier look compared to the original even at 1x zoom. VarDCT was a tiny bit smoother but I had to zoom in 2-3x with a flicker test to see it.
|
|
|
Demiurge
|
2025-01-14 10:56:27
|
I'm on a phone atm and can't compare them
|
|
2025-01-14 10:58:07
|
Those shadows look ridiculously bad though
|
|
2025-01-14 10:59:05
|
I don't understand why Unreal engine is so ugly and bad these days
|
|
|
Oleksii Matiash
|
|
|
|
2025-01-14 11:25:43
|
DeltaDoggo is sharpened a bit comparing to the original or vardct
|
|
|
jonnyawsom3
|
|
A homosapien
I kinda agree with ssimulacra2 here. Lining up the images side-by-side, I could see that delta palette has a somewhat fuzzier look compared to the original even at 1x zoom. VarDCT was a tiny bit smoother but I had to zoom in 2-3x with a flicker test to see it.
|
|
2025-01-14 11:33:39
|
I was on Irfanview so it resampled at 'full' size, then I went to 500% to spot the differences. Delta has more noise, as expected with reduced colors essentially dithering to compensate, but to me it was preferable to the slight smoothing. In the end, both are good enough and it's surprising how well Delta Palette holds up for not being tweaked in years
|
|
|
Demiurge
I don't understand why Unreal engine is so ugly and bad these days
|
|
2025-01-14 11:33:45
|
That was actually over 2 years ago
|
|
2025-01-14 11:40:29
|
At 100% I can't see any difference to the original, 200% I start noticing the noise around high contrast edges, 500% I can see the pallete reduction affecting gradients and the edges are obvious, but ignoring areas like the mouth, I could still think it's the original
|
|
|
Demiurge
|
|
A homosapien
These are plans for the far future though, the major milestone this year is the completion of the rust decoder and (hopefully) its adoption by Mozilla.
|
|
2025-01-14 11:58:54
|
Mozilla hardly matters at all anymore, hardly anyone uses firefox now that it's essentially in maintenance mode aka life support
|
|
2025-01-14 11:59:26
|
What matters is reversing the decision to remove it from chromium
|
|
2025-01-14 12:01:32
|
Maybe Firefox support would be the tipping point for that? But that is kinda silly considering Safari has way more users
|
|
|
A homosapien
|
2025-01-14 12:01:52
|
I think the rust decoder has more leverage than people think
|
|
2025-01-14 12:02:04
|
Maybe I'm being a bit naive
|
|
|
Demiurge
|
2025-01-14 12:03:53
|
Maybe I'm being a bit naive in underestimating the influence mozilla has because of their history and (former) reputation despite having almost no users anymore
|
|
|
HCrikki
|
2025-01-14 12:05:55
|
imo it has pull power. sites with a proper jxl strategy could end up more lightweight than on other browsers - saving money, becoming profitable instead of not breaking even, having more room for instantly loading ads that dont slow site
|
|
2025-01-14 12:07:53
|
just making usable good code isnt everything though, there should still be militant adoption lobbying for important services like image hosts, cdns
|
|
|
Demiurge
|
2025-01-14 12:08:13
|
Also I know js/wasm decoders have disadvantages like waiting for DOM to load for example but most of the time no one is going to notice and you can even have progressive decoding in browsers that don't support it yet using that method
|
|
2025-01-14 12:08:29
|
So I'm honestly surprised it's not used more often
|
|
2025-01-14 12:09:31
|
If people just started using it more often with js/wasm fallback there would be more impetus for browsers to integrate native support
|
|
|
HCrikki
|
2025-01-14 12:09:35
|
custom webdev is hard enough, wasm should be part of that but many webdevs arent even aware jxl exists or how people can consume it without safari
|
|
|
Demiurge
|
2025-01-14 12:09:53
|
Nothing is really stopping all websites from using it immediately
|
|
2025-01-14 12:10:00
|
In all browsers
|
|
2025-01-14 12:10:25
|
You literally just add 1 line of code to your html pointing to the js decoder
|
|
2025-01-14 12:11:11
|
It requires no brains at all to start using
|
|
|
HCrikki
|
2025-01-14 12:11:18
|
link it ?
|
|
2025-01-14 12:11:37
|
im aware of a ludicrously outdated one, anything better ?
|
|
|
Kampidh
|
|
Also <@274048677851430913> the EPF setting in Krita's export dialogue can't be set to -1 to let the encoder choose. Group ordering wasn't working either but you already fixed that for the next release IIRC
|
|
2025-01-14 12:12:59
|
oh thanks for the report, on it
|
|
|
Demiurge
|
2025-01-14 12:13:00
|
https://github.com/niutech/jxl.js
|
|
2025-01-14 12:13:40
|
I just know about this one. It's braindead simple and just works so what more is there to ask for
|
|
|
HCrikki
|
2025-01-14 12:14:36
|
iinm magick wasm can handle jxl but some of such solutions are supposed to be part of custom webdev
|
|
2025-01-14 12:16:15
|
small sites wouldnt move the needle though, ones with high reach/impact ought to push (highest being cdns then photo/image hosts)
|
|
2025-01-14 12:17:13
|
take flickr or photobucket, its 2025 and neither supports dng 1.7
|
|
2025-01-14 12:17:56
|
flickr is egregious since its parent company (smugmug?) supported jxl
|
|
|
jonnyawsom3
|
2025-01-14 12:18:07
|
There was this on Reddit recently too https://bevara.com/
|
|
|
Demiurge
|
|
HCrikki
small sites wouldnt move the needle though, ones with high reach/impact ought to push (highest being cdns then photo/image hosts)
|
|
2025-01-14 12:20:13
|
Disagree strongly. People aren't even aware that it exists rn. People just need to start using it, doesn't matter who, just to prove it's possible and so people start running into it more often
|
|
|
jonnyawsom3
|
|
HCrikki
take flickr or photobucket, its 2025 and neither supports dng 1.7
|
|
2025-01-14 12:20:44
|
DNG 1.7 is mostly unsupported due to libraw not releasing with support yet. I think that was resolved but the next release is still months away. Then RawTherapee were concerned about the Adobe SDK with the libjxl decoder causing licence issues. https://github.com/Beep6581/RawTherapee/pull/6887#issuecomment-2241745859
|
|
|
Demiurge
|
2025-01-14 12:21:37
|
It's much easier for small sites to flip the switch than big ones
|
|
2025-01-14 12:21:52
|
Less process and bureaucracy
|
|
|
Oleksii Matiash
|
|
DNG 1.7 is mostly unsupported due to libraw not releasing with support yet. I think that was resolved but the next release is still months away. Then RawTherapee were concerned about the Adobe SDK with the libjxl decoder causing licence issues. https://github.com/Beep6581/RawTherapee/pull/6887#issuecomment-2241745859
|
|
2025-01-14 12:27:20
|
Unfortunately even the apps from the LibRaw developer still does not support jxl-in-dng
|
|
|
jonnyawsom3
|
2025-01-14 12:27:47
|
Yeah, it's in a 2024-03 snapshot, but not an actual release yet https://github.com/LibRaw/LibRaw/issues/615#issuecomment-2027946301
|
|
|
HCrikki
|
2025-01-14 12:30:29
|
i think the raw plugin for windows 10/11 got upated with that wip code without waiting for the next big update, worth rechecking
|
|
|
jonnyawsom3
|
2025-01-14 12:31:33
|
We checked it a while ago but there was a bug causing it to error
|
|
|
HCrikki
i think the raw plugin for windows 10/11 got upated with that wip code without waiting for the next big update, worth rechecking
|
|
2025-01-14 12:41:02
|
JPEG XL DNGs with JPEG previews load, but JPEG XL previews fail
|
|
2025-01-14 12:45:08
|
```[EXIF] Subfile Type : Full-resolution image
[EXIF] Image Width : 5712
[EXIF] Image Height : 4284
[EXIF] Bits Per Sample : 16 16 16
[EXIF] Compression : JPEG XL
[EXIF] Photometric Interpretation : Linear Raw
[EXIF] Subfile Type : Reduced-resolution image
[EXIF] Image Width : 5712
[EXIF] Image Height : 4284
[EXIF] Bits Per Sample : 8 8 8
[EXIF] Compression : JPEG
[EXIF] Photometric Interpretation : YCbCr```
|
|
|
monad
|
|
spider-mario
here is lossless compression
|
|
2025-01-14 05:10:32
|
remember those results represent the specific case tested and should not be assumed general <https://github.com/jxl-community/jxl-community.github.io/issues/41>
|
|
|
_wb_
|
2025-01-14 06:51:47
|
It would be an interesting research project to create a corpus of ~10k images that is representative (in terms of compression) for "all images". How to construct/collect such a set is very nontrivial though. Just crawling the web will not do, since the set of images on the public web is not representative for all actual images (e.g. private photos, medical images, game graphics etc would be underrepresented), and also because you typically only get lossy downscaled images that way, not originals.
|
|
|
AccessViolation_
|
2025-01-14 07:05:28
|
Wikimedia Commons might be a good starting poing
|
|
|
_wb_
|
2025-01-14 07:29:25
|
Yeah but that is only representative for the specific category of images suitable for wikipedia, which is likely not distributed in the same way as "all images", e.g. it will have more diagrams, logos, maps, and pictures of famous people and landmarks, and fewer random holiday pictures, insurance claim pictures, medical images, etc.
|
|
|
AccessViolation_
|
2025-01-14 07:31:25
|
Wikimedia Commons has tagged images (or more like categories it seems) with a lot of different genres, I was just looking at the "pictures of art" category but there are many. I expect those present on Wikipedia (which is its own category) are probably a large portion of all images though yeah
|
|
2025-01-14 07:32:59
|
some examples
|
|
2025-01-14 07:34:31
|
And yeah those random images you mention, probably not many of those
|
|
|
_wb_
|
2025-01-14 07:35:24
|
I guess the question is: how to estimate the distribution of non-public images, like stock photography, medical archives, images on all kinds of forums, chats and social networks, screenshots people keep on their phones or computers, etc.
|
|
2025-01-14 07:36:20
|
But yeah, maybe a representative sample of wikimedia would be at least representative of _something_ that is also relevant.
|
|
|
AccessViolation_
|
2025-01-14 07:43:43
|
Estimating the distribution of types of images sounds hard yeah. It would still be interesting to see if it does particularly poorly on certain types of images without initially knowing how common they are. You could figure out how common that type of images is as a second step
|
|
|
Quackdoc
|
2025-01-14 07:45:03
|
allow people to publicly submit images I guess? 10k would be small, you would wind up getting like, 100k xD
|
|
|
jonnyawsom3
|
2025-01-14 07:45:43
|
God forbid a troll finds the upload button
|
|
|
AccessViolation_
|
2025-01-14 07:46:31
|
Ask our Google Research Zurich friends to send over a copy of all the pictures on Google Photos
|
|
2025-01-14 07:47:08
|
a few trillion images should do it
|
|
|
jonnyawsom3
|
|
AccessViolation_
a few trillion images should do it
|
|
2025-01-14 07:50:11
|
https://youtu.be/tVQsxLfKPNI
|
|
|
AccessViolation_
|
|
God forbid a troll finds the upload button
|
|
2025-01-14 08:07:26
|
honestly images uploaded by trolls probably make up a significant amount of all images in general so it'll be good representation in the dataset <:galaxybrain:821831336372338729>
|
|
|
jonnyawsom3
|
2025-01-14 08:21:49
|
Soyjack detection algorithms
|
|
|
_wb_
|
|
AccessViolation_
Ask our Google Research Zurich friends to send over a copy of all the pictures on Google Photos
|
|
2025-01-14 08:50:55
|
I guess that would have a disproportional amount of photos taken on Android phones, and they're usually already JPEG-compressed before getting uploaded (and I guess often further transcoded by Google Photos)..
|
|
|
AccessViolation_
|
2025-01-14 08:51:24
|
Yeah I think Google Photos turns them into WebP lol
|
|
2025-01-14 08:52:08
|
Unless you have the subscription to store them uncompressed (is it still a subscription? I haven't used google photos in years)
|
|
2025-01-14 08:54:16
|
To be clear it wasn't a serious suggestion to use random people's Google Photos data, BUT if someone generously donated their whole uncompressed Google Photos library and tried several encoding options including lossless JPEG transcoding, the results might be appealing to the Photos team, possibly making them take an interest in JXL? ๐
|
|
|
A homosapien
|
2025-01-14 08:54:36
|
It's a subscription for Google's cloud service to store them uncompressed
|
|
|
_wb_
|
2025-01-14 08:55:14
|
I have been thinking about extracting a corpus from all images on Cloudinary (if I can get something like that cleared with Legal, since the images are owned by our customers, not by us, so I have to be very careful), which would also of course only be representative of Cloudinary's customers/users, but still, that might be a diverse enough set of use cases. Question then is: how to do it. Extracting randomly gets you a lot of long-tail images that are not at all representative for typical web traffic, but extracting weighted by popularity will bias it the other way towards landing page hero images and logos and stuff like that.
|
|
|
AccessViolation_
|
2025-01-14 08:57:47
|
I think this might be subject to selection bias. People will manually seek 'efficient' images for those that see lots of traffic. If there is a connection between traffic volume and image characteristics at all, that correlation is the only one I could see it being
|
|
|
_wb_
|
2025-01-14 08:58:57
|
also there are bunch of use cases that still wouldn't be covered, either because our terms & conditions don't allow it or because we're not a good fit for such use cases. E.g. porn, military imagery, medical images etc. And probably e-commerce would be overrepresented.
|
|
|
AccessViolation_
|
2025-01-14 09:01:15
|
I'm not a lawyer, but I feel like it might be more legal and less controversial to do all the comparisons in-memory and just save the statistics in the end. So instead of creating a corpus, you're just using (some subset of) all images for every experiment. But this of course prevents others from using it, unless they can request an experiment to be run on your images or something
|
|
|
_wb_
|
2025-01-14 09:05:01
|
Yeah having a corpus that can be shared would be nice but that's really hard to do since you need to get a license for every single image. An alternative is a list of URLs, if the images are on the public web, which circumvents the issue but is prone to link rot.
|
|
|
AccessViolation_
|
2025-01-14 09:07:41
|
I wonder if you can get a giant dump of images from the Internet Archive
|
|
2025-01-14 09:09:02
|
Even if they're not representative of all images in general, knowing how valuable JXL is in use cases like the Internet Archive, or Wikimedia Commons, is valuable in itself, because these are orgs that just have lots of images, regardless of what types of images, and probably would have an interest in storing them efficiently
|
|
|
|
veluca
|
2025-01-14 09:10:41
|
I have at some point gotten a dump of images from the google indexer, but of course that's of limited use to everyone not at G (and also to many people at G xD)
|
|
|
_wb_
|
2025-01-14 09:15:35
|
Storing already-lossy images is something quite different from compressing a pristine image though.
|
|
|
AccessViolation_
|
2025-01-14 09:19:33
|
I don't remember what it's called, but there's a site that has collections of raw files from various camera models. It might be possible to automate some software like Darktable that develops them and exports them to a lossless format, and then you have a corpus of real photographs from from various camera and lens combinations. The processing done wouldn't be identical to what the camera itself would do though
|
|
2025-01-14 09:20:47
|
So then you effectively have a bunch of photographs from right before the final "encode to jpeg" step
|
|
2025-01-14 09:21:58
|
I mean in practice collecting original lossless things just sounds hard, I imagine lots of pngs online are just screenshots of jpegs... you'd need to filter that or it inadvertently becomes a generation loss experiment instead... sounds like a mess
|
|
|
HCrikki
|
2025-01-14 09:42:36
|
dpreview ?
|
|
|
AccessViolation_
|
2025-01-14 09:54:25
|
Nah, some other site just dedicated to collecting raws
|
|
|
spider-mario
|
2025-01-14 10:09:22
|
https://raw.pixls.us/ ?
|
|
|
AccessViolation_
|
2025-01-14 10:27:34
|
That might be it
|
|
|
jonnyawsom3
|
|
AccessViolation_
So then you effectively have a bunch of photographs from right before the final "encode to jpeg" step
|
|
2025-01-15 04:55:15
|
If RawTherapee can get the PR done, they'll have native JXL export, so you could just directly use the command line *and* use the automatic preview matching to try and be similar to the in-camera processing
|
|
|
AccessViolation_
|
2025-01-15 12:20:14
|
Hang on, automatic preview matching actually sounds amazing
|
|
2025-01-15 12:20:42
|
I've had a hard time trying to recreate the original of my out of camera JPEGs in Darktable
|
|
|
lucius
|
2025-01-15 06:51:10
|
I am experimenting with the API and have made a puzzling observation: My program reads a lossless uint16 Jxl image (created in Lightroom) into a buffer, decodes it twice (first as uint16 and then as float), and saves both versions. Both display nicely in XnView and are reported by jxlinfo to be:
"JPEG XL image, 4745x3163, lossy, 16-bit RGB"
"JPEG XL image, 4745x3163, lossy, 32-bit float (8 exponent bits) RGB"
What puzzles me is that the two saved images have exactly the same size, and a byte-by-byte comparison shows they are more than 99.999% identical. The remaining five differences are located near the beginning of the file:
0000002E E2 92
0000002F 27 4B
00000030 A1 28
00000031 B8 2E
00000032 10 04
Is it possible for a uint16 image and a float image based on the same source image to have JPEG XL representations that are so similar? I would have expected no resemblance at all due to the different bit formats of the datatypes, and I would have expected the float version to be much larger than the uint16 version. I have taken steps to verify that the code path that I *think* is executing actually is the one that *is* executing, such as adding a tiny float value to each RGB component. This removes all similarity, and leads to a modest increase in size of the float version (456 bytes).
I would appreciate it if someone could take a look at the images at https://www.bosnes.net/ and help me figure out what is going on.
|
|
|
jonnyawsom3
|
2025-01-15 07:01:56
|
Lossy JXL is always stored as float32, the only difference is the metadata specifying what format to decode to
|
|
2025-01-15 07:03:14
|
If you tried with lossless, you'd see the differences you expected
|
|
|
lucius
|
2025-01-15 07:14:43
|
Thank you for the swift response! This also explains another puzzling thing I had noticed: why images "stored as" float16 and byte also have approximately the same size
|
|
|
jonnyawsom3
|
|
lucius
Thank you for the swift response! This also explains another puzzling thing I had noticed: why images "stored as" float16 and byte also have approximately the same size
|
|
2025-01-15 07:33:34
|
Any time. I'd recommend trying to decode them to pfm files, they should be identical if I'm right. I also tried to find a relevant portion of the spec but this is the closest I found
|
|
|
_wb_
|
|
lucius
Thank you for the swift response! This also explains another puzzling thing I had noticed: why images "stored as" float16 and byte also have approximately the same size
|
|
2025-01-15 07:56:50
|
In case of lossy, the bit depth is just metadata in the header but the actual encoding does not depend on it. It is just a suggestion of what bit depth to decode it to, if you decode to RGB.
|
|
|
lucius
|
2025-01-15 08:06:42
|
Thank you both! Much appreciated
|
|
|
Demiurge
|
2025-01-15 08:35:48
|
I'm pretty sure float32 can perfectly represent any int16 value too
|
|
|
AccessViolation_
|
|
Lossy JXL is always stored as float32, the only difference is the metadata specifying what format to decode to
|
|
2025-01-15 09:28:23
|
That's interesting, what's the reason for this? Just simplifying the format/code by always using f32 in lossy?
|
|
|
jonnyawsom3
|
|
AccessViolation_
That's interesting, what's the reason for this? Just simplifying the format/code by always using f32 in lossy?
|
|
2025-01-15 09:31:34
|
I know float16 for a 'low precision encoder' has been mentioned a few times, so I think mostly for simplicity and to avoid unnecessary precision loss causing banding during quanization/decoding
|
|
2025-01-15 09:32:52
|
Pretty old, but seems relevant still https://www.reddit.com/r/jpegxl/comments/l6rv3u/comment/gl7fc7i/
|
|
2025-01-15 09:33:42
|
I really wish Reddit didn't cut off the message with a gradient...
|
|
|
AccessViolation_
|
2025-01-15 09:40:41
|
I wonder if/how redlib does previews
https://redlib.nl/r/jpegxl/comments/l6rv3u/comment/gl7fc7i/
|
|
2025-01-15 09:40:50
|
poorly, it seems
|
|
2025-01-15 09:41:32
|
Anyway thanks for the info
|
|
|
_wb_
|
|
I know float16 for a 'low precision encoder' has been mentioned a few times, so I think mostly for simplicity and to avoid unnecessary precision loss causing banding during quanization/decoding
|
|
2025-01-15 10:37:40
|
There is a compile flag for lower precision in certain decode stages, iirc it uses int16 instead of float32 for the XYB to RGB. But yes, in general most things are float32 so there is just a single code path.
|
|
2025-01-16 03:09:47
|
does djxl --allow_partial_files work for anyone? doesn't seem to work for me
|
|
|
jonnyawsom3
|
2025-01-16 03:12:29
|
When I tried deleting bytes instead of zeroing for leniency testing, it asked for the parameter and worked for me. I can try again when I get home, but IIRC it never actually decoded partial files when trying to test progressiveness, just errored
|
|
|
_wb_
|
2025-01-16 03:17:11
|
I seem to always just get "Input file is truncated and there is no preview available yet."
|
|
2025-01-16 03:26:54
|
oh, I guess this is a side effect of defaulting to chunked encode
|
|
|
jonnyawsom3
|
2025-01-16 03:33:06
|
Oh... *Ohhh that makes sense*
I don't think I tried the truncated argument since learning --progressive_dc=1 fixes progressiveness
|
|
|
CrushedAsian255
|
2025-01-16 03:33:10
|
Didnโt someone find out HfGlobal is written at the end when using chunked?
|
|
|
jonnyawsom3
|
2025-01-16 03:33:29
|
LfGlobal IIRC but yeah
|
|
|
CrushedAsian255
|
2025-01-16 03:34:11
|
https://discord.com/channels/794206087879852103/805176455658733570/1314895435730649108
|
|
2025-01-16 03:35:10
|
https://discord.com/channels/794206087879852103/805176455658733570/1314868178140266546
|
|
2025-01-16 03:35:19
|
Turns out in different situations itโs both!
|
|
|
jonnyawsom3
|
|
CrushedAsian255
https://discord.com/channels/794206087879852103/805176455658733570/1314868178140266546
|
|
2025-01-16 08:25:50
|
That might've just been me getting confused
|
|
|
_wb_
|
2025-01-16 08:46:36
|
We should really make some jxltran tool that can reshuffle the sections into an order more suitable for progressive decode
|
|
2025-01-16 08:47:34
|
It's not super critical since for image sizes under 2048x2048 it will be progressive anyway, and that still covers most web images.
|
|
2025-01-16 08:52:02
|
But still, it would be nice to have. If you make it as a tool that requires an input file in which it can freely seek (as opposed to the streaming io model libjxl uses), it should be pretty easy to implement all kinds of bitstream remixing stuff.
|
|
|
jonnyawsom3
|
2025-01-16 08:53:46
|
I've said it before, but cjxl already buffers the output unless `--streaming_output` is specified, so the HfGlobal could theoretically already be moved without issue. At least for manual encodes
|
|
2025-01-17 10:57:52
|
I might slowly go though the github issues and comment on any that have since been fixed.
There's quite a few high memory usage ones from 2021/22 that never got closed after v0.10
Don't want to be spammy though, so thought I'd ask here first
|
|
|
_wb_
|
2025-01-17 04:45:13
|
Sure, any help with reducing the amount of open issues would be appreciated!
|
|
|
AccessViolation_
|
|
If RawTherapee can get the PR done, they'll have native JXL export, so you could just directly use the command line *and* use the automatic preview matching to try and be similar to the in-camera processing
|
|
2025-01-17 05:01:13
|
The preview matching in this is so good thanks for mentioning it
|
|
2025-01-17 05:02:13
|
I can finally stop messing around in Darktable to get my raws to look like the out of camera jpegs
|
|
|
jonnyawsom3
|
2025-01-17 05:44:03
|
My DNGs don't actually have a preview, but the matching still gives the same image that my phone does when viewing them so I'm happy enough (The JPEGs have far too much smoothing/AI upscaling)
|
|
2025-01-17 08:21:25
|
Looking into this a little while I'm cleaning up old issues https://github.com/libjxl/libjxl/issues/1470
|
|
2025-01-17 08:22:10
|
Do jpegli and libjxl use the same upsampling for the chroma channels?
|
|
2025-01-17 08:26:49
|
I'm noticing a slight hue shift towards red, as if the chroma is bleeding or was sharpened slightly
|
|
2025-01-17 08:49:59
|
I forgor about the CFL, but it's still.. Strange. Jpegli almost seems to do some kind of local correction. The mosquito noise is lessened and the region matches the orignal better, but high contrast details are desaturated too
|
|
|
_wb_
Sure, any help with reducing the amount of open issues would be appreciated!
|
|
2025-01-18 01:34:08
|
May god help your notifications xD
Up to page 6 of 14 so far
|
|
|
|
veluca
|
2025-01-18 09:36:24
|
you could also have closed them while you were going through them ๐
|
|
|
CrushedAsian255
|
|
veluca
you could also have closed them while you were going through them ๐
|
|
2025-01-18 10:05:17
|
don't think they have write perms on the repo
|
|
|
|
veluca
|
2025-01-18 10:08:19
|
Ah you need write permissions to close?
|
|
2025-01-18 10:08:22
|
Sigh
|
|
|
_wb_
|
2025-01-18 10:09:16
|
is JxlEncoderOutputProcessor assuming the buffers are write-only? or can you assume that if it supports seeking, then reading would also be ok?
|
|
2025-01-18 10:15:57
|
it might be nice to have a way to avoid the non/less-progressiveness of streaming encode, at least as an option. That requires having HfGlobal before HfGroups, and to make room for that you'd need to do seek/read/write, but that is probably usually not a big problem/overhead.
|
|
2025-01-18 10:17:14
|
Actually, what is in HfGlobal that is only available after writing HfGroups but is not needed to write HfGroups?
|
|
|
jonnyawsom3
|
|
veluca
Ah you need write permissions to close?
|
|
2025-01-18 10:20:02
|
Yeah, letting anyone close other people's issues wouldn't be a *great* idea usually. But someone might have to sort by "Last Updated" when I'm done and close the ones I marked (some are asking for additional info or answering questions)
|
|
|
|
veluca
|
|
_wb_
is JxlEncoderOutputProcessor assuming the buffers are write-only? or can you assume that if it supports seeking, then reading would also be ok?
|
|
2025-01-18 10:22:26
|
Uh, I don't think it assumes much
|
|
|
_wb_
|
2025-01-18 10:24:17
|
I think it currently is doing write-only
|
|
|
|
veluca
|
2025-01-18 10:24:55
|
Yes, I think so too
|
|
|
jonnyawsom3
|
2025-01-18 10:40:35
|
It might not be related, but could chunked JPEG Transcoding be feasable too? Or would that need a new API for the bitstream input
|
|
|
_wb_
|
2025-01-18 10:51:42
|
If it's a sequential jpeg then I guess in principle it could be possible to do it in a chunked way. With a progressive one though... I don't think so.
|
|
|
Traneptora
|
|
_wb_
it might be nice to have a way to avoid the non/less-progressiveness of streaming encode, at least as an option. That requires having HfGlobal before HfGroups, and to make room for that you'd need to do seek/read/write, but that is probably usually not a big problem/overhead.
|
|
2025-01-19 07:17:49
|
Do you put HFGlobal after the PassGroups using a TOC permutation?
|
|
|
_wb_
|
|
Traneptora
|
2025-01-19 07:19:00
|
Toc permutations is how I did it in hydrium
|
|
2025-01-19 07:19:14
|
but hfglobal is fixed there
|
|
2025-01-19 07:19:31
|
so I just put it at the front because it's only one
|
|
2025-01-19 07:20:17
|
Or rather, wait no that has the histograms
|
|
2025-01-19 07:20:26
|
hm
|
|
2025-01-19 07:26:53
|
I just double checked, apparently what hydrium does is buffer the HF coefficients, build the histograms, then entropy-encode
|
|
2025-01-19 07:27:13
|
since I tend to only output one lf group at a time I can do that without being memory greedy
|
|
|
_wb_
|
2025-01-19 07:28:14
|
You write multiple frames, right?
|
|
|
Traneptora
|
2025-01-19 07:30:05
|
yes, unless `--one-frame` is passed on the CLI
|
|
2025-01-19 07:30:47
|
then it only writes one frame. I think I might still buffer all the HF coefficients, but I've found it doesn't use that much more memory
|
|
|
_wb_
|
2025-01-19 07:30:50
|
I suppose you could also make histograms when encoding the first LF group and then in the other LF groups just encode the HF with fixed histograms. Then you could write everything in a single frame, and probably get some speedups since less need to buffer/compute histograms, at the cost of some compression but probably not that much.
|
|
|
Traneptora
|
2025-01-19 07:32:13
|
doing some benchmarking I found that doing 2048x2048 frames was the fastest. doing one frame was almost as fast, and 256x256 frames were notably slower. but also used like 2MiB of memory so it's a different use
|
|
|
_wb_
|
2025-01-19 07:32:18
|
Might even compress better since there's less histogram / frame header signaling overhead
|
|
|
Traneptora
|
2025-01-19 07:32:43
|
using one histogram for each 2048x2048 gave the best ratio
|
|
2025-01-19 07:32:53
|
in my benchmarking
|
|
2025-01-19 07:33:06
|
because the histograms were most accurate to the tile they were encoding
|
|
2025-01-19 07:33:31
|
using one frame with one histogram had lower signalling overhead, but the histograms weren't always as correct for each tile
|
|
|
_wb_
|
2025-01-19 07:38:48
|
Makes sense
|
|
|
Traneptora
|
2025-01-19 07:39:31
|
```
malloc(): unsorted double linked list corrupted
Aborted (core dumped)
```
ooo, fun. I don't know what this means
|
|
2025-01-19 07:42:51
|
time for a valgrind run
|
|
2025-01-19 08:42:04
|
valgrind is so useful, bug found and fixed
|
|
|
_wb_
Makes sense
|
|
2025-01-19 08:55:22
|
at least, that was my observation, and it's the guess that veluca came up with as to why that observation was holding
|
|
2025-01-19 08:56:56
|
I just tested on a *massive* PNG
|
|
2025-01-19 08:57:20
|
got 160.41 MiB for the one-frame-per-LF-group
and 161.20 MiB for one frame total
|
|
2025-01-19 08:57:36
|
turns out for the massive massive files it does inflate memory usage quite a bit to encode one frame
|
|
2025-01-19 08:57:42
|
which is why I don't really recommend it
|
|
|
jonnyawsom3
|
|
Traneptora
turns out for the massive massive files it does inflate memory usage quite a bit to encode one frame
|
|
2025-01-19 09:32:54
|
'quite a bit' meaning the 0.8 MiB? Or do mean something else
|
|
|
Traneptora
|
|
'quite a bit' meaning the 0.8 MiB? Or do mean something else
|
|
2025-01-19 09:34:58
|
that's file size
|
|
2025-01-19 09:35:05
|
4.5 GiB vs ~700 MiB
|
|
|
jonnyawsom3
|
2025-01-19 09:35:20
|
Ohhh right, yeah that sounds more like my results
|
|
|
lucius
|
2025-01-20 11:18:30
|
I am experimenting with the libjxl API, and have an anomalous result when writing and retrieving extra channels. I add extra channels to an image by using the green channels from images that have the same dimensions as the main image. When I use lossless compression, the size of the main image and the sizes of the added images add up nicely to the size of the main image with the extra channels added:
12 955 437 ExtraChan_0.jxl
13 094 838 ExtraChan_1.jxl
40 001 982 MainImage.jxl
66 043 467 MainImage_2_extra_channels.jxl
>jxlinfo MainImage_2_extra_channels.jxl
JPEG XL file format container (ISO/IEC 18181-2)
JPEG XL image, 2560x1920, (possibly) lossless, 32-bit float (8 exponent bits) RGB+Alpha+Thermal
Color space: 940-byte ICC profile, CMM type: "KCMS", color space: "RGB ", rendering intent: 0
When using lossy compression, however, the size of the main image with extra channels added, is more than 10 times the sum of its components. In fact, it matches the size of the lossily compressed main image plus the sizes of the losslessly compressed extra channels:
786 095 ExtraChan_0.jxl
610 665 ExtraChan_1.jxl
877 991 MainImage.jxl
26 985 570 MainImage_2_extra_channels.jxl
>jxlinfo MainImage_2_extra_channels.jxl
JPEG XL file format container (ISO/IEC 18181-2)
JPEG XL image, 2560x1920, lossy, 32-bit float (8 exponent bits) RGB+Alpha+Thermal
Color space: 940-byte ICC profile, CMM type: "KCMS", color space: "RGB ", rendering intent: 0
I suspect that the reason for the large size, is that lossless compression has been applied to the extra channels even though the main image was compressed lossily. Is there something I should have done to tell the API that I wanted lossy compression of the extra channels?
|
|
|
jonnyawsom3
|
2025-01-20 11:31:29
|
<@1328688054348812390> you want `JxlEncoderSetExtraChannelDistance` though this will set the distance for all extra channels, there's no individual control currently
<https://github.com/libjxl/libjxl/issues/1707> <https://github.com/libjxl/libjxl/issues/3906>
|
|
2025-01-20 11:32:10
|
It's set to lossless by default due to Alpha usually compressing better
|
|
|
lucius
|
2025-01-21 01:09:03
|
Thank you, that makes sense, but unfortunately, it didn't make much difference to the size of the image with extra channels. I made the call to JxlEncoderSetExtraChannelDistance just after the calls to JxlEncoderFrameSettingsCreate and JxlEncoderSetFrameDistance. I used value 3.0 for distance, and called the function once for each index. JxlEncoderFrameSettingsCreate returned success, and I confirmed that the value in frame_settings->values.cparams.ec_distance[index] still was 3.0 at the time JxlEncoderSetExtraChannelBuffer was called. Its late here, but I will try and debug further tomorrow. Any pointers as to how I can proceed, will be much appreciated. Thank you for your help!
|
|
|
Me
|
2025-01-21 07:34:27
|
I'm trying to use the cjxl/djxl command line tools to do progressive with middle-out. I'd really like to be able to get a file that just getting the first, say, 24k lets me do something meaningful and then scale quality as i get up to a meg or whatever. Application is for a student-built satellite with a 4800 baud modem that expects to download ~72kbytes on a typical pass; would be cool to get meaningful previews of 3 images in a way that "counts" towards downloading the entire file
|
|
|
CrushedAsian255
|
2025-01-21 08:40:23
|
If attempting that use JXL-oxide as libjxl doesnโt support full progressive decoding
|
|
|
Meow
|
2025-01-21 11:21:02
|
Even worse for converting Greyscale now
|
|
2025-01-21 11:22:51
|
Fine without Alpha but the file size still increases much more like before
|
|
|
jonnyawsom3
|
|
Me
I'm trying to use the cjxl/djxl command line tools to do progressive with middle-out. I'd really like to be able to get a file that just getting the first, say, 24k lets me do something meaningful and then scale quality as i get up to a meg or whatever. Application is for a student-built satellite with a 4800 baud modem that expects to download ~72kbytes on a typical pass; would be cool to get meaningful previews of 3 images in a way that "counts" towards downloading the entire file
|
|
2025-01-21 11:49:23
|
You want to use `cjxl --progressive_dc 1 --group_order 1` to make sure it's progressive and loads centre first.
Depending on the hardware and image resolution, quality and encoding speed could be adjusted too.
As Jia said, you should probably use jxl-oxide to decode the partial files. That allows decoding down to 0.1% loaded in some cases, though there is a PR for libjxl that allows decoding corrupt files if the transmission isn't stable
|
|
2025-01-21 02:46:37
|
I've thought about doing this for satellite imagery for quite a while, so by all means share the results and give us updates if you can. Just give me a ping or ask here again if you have any questions or encounter any issues
|
|
|
Meow
|
2025-01-21 02:56:56
|
What kind of satellite imageries do you use?
|
|
|
Me
|
|
You want to use `cjxl --progressive_dc 1 --group_order 1` to make sure it's progressive and loads centre first.
Depending on the hardware and image resolution, quality and encoding speed could be adjusted too.
As Jia said, you should probably use jxl-oxide to decode the partial files. That allows decoding down to 0.1% loaded in some cases, though there is a PR for libjxl that allows decoding corrupt files if the transmission isn't stable
|
|
2025-01-21 03:07:20
|
Hey, thank you, this is is very helpful. I've been using those command line options but didn't realize djxl had trouble on partial decode. I will try jxl-oxide.
|
|
|
Meow
What kind of satellite imageries do you use?
|
|
2025-01-21 03:08:26
|
It's just going to be pictures from a raspberry pi camera. About a third of the frame is one side of the satellite, and if we have attitude control, the other 2/3rds will be the Earth
|
|
|
Meow
|
2025-01-21 03:10:16
|
|
|
2025-01-21 03:10:17
|
I was thinking of you being able to generate imageries like this
|
|
|
jonnyawsom3
|
|
Me
It's just going to be pictures from a raspberry pi camera. About a third of the frame is one side of the satellite, and if we have attitude control, the other 2/3rds will be the Earth
|
|
2025-01-21 03:35:02
|
Do you know the resolution? And how much memory will be available for encoding? The downside to progressive currently is quite a large memory hit due to buffering the entire image, but it's being worked on https://discord.com/channels/794206087879852103/804324493420920833/1330118476731383838
|
|
|
Me
|
|
Do you know the resolution? And how much memory will be available for encoding? The downside to progressive currently is quite a large memory hit due to buffering the entire image, but it's being worked on https://discord.com/channels/794206087879852103/804324493420920833/1330118476731383838
|
|
2025-01-21 04:21:13
|
We've got a little baby spacecraft computer that buffers the images for downlink and runs things, but we've got a pi zero 2 w with 512MB of ram and cycles to compress images. 3840x2464 is full res but we'll often be thinking about half in each dim or one quarter in each dim.
Downlink is really where we're constrained. So many bytes of image data, so little ability to send it down.
Sending a kilobyte costs us 10 joules; running the computer in the imaging subsystem for a second costs 2 joules.
|
|
2025-01-21 04:23:44
|
(We also have science and technology development payloads fighting for that downlink time and energy)
|
|
2025-01-21 04:28:54
|
OK, very nice:
```
mlyle@sliver avif % cjxl -v -v -q 85 --lossless_jpeg=0 --container=1 --progressive --progressive_dc=2 --group_order=1 bluemarb.jpg trial.jxl
JPEG XL encoder v0.11.1 0.11.1 [NEON]
Read 3000x3002 image, 6486234 bytes, 477.5 MP/s
Encoding [Container | VarDCT, d1.450, effort: 7]
Compressed to 901.2 kB including container (0.801 bpp).
3000 x 3002, 11.503 MP/s [11.50, 11.50], , 1 reps, 16 threads.
mlyle@sliver avif % ls -al trial.jxl
-rw-r--r--@ 1 mlyle staff 901238 Jan 21 08:27 trial.jxl
mlyle@sliver avif % dd if=trial.jxl of=test.jxl bs=1024 count=4 && jxl-oxide test.jxl -o test.png && open test.png
```
|
|
2025-01-21 04:31:04
|
```
mlyle@sliver avif % dd if=trial.jxl of=test.jxl bs=1024 count=32 && jxl-oxide test.jxl -o test.png && open test.png
32+0 records in
32+0 records out
32768 bytes transferred in 0.000158 secs (207392405 bytes/sec)
```
I notice the group-order only applies to the final image in the progressive sequence
|
|
|
AccessViolation_
|
2025-01-21 04:37:58
|
I wonder why some of the lower quality tiles look pixelated while others look blurred
|
|
|
Me
|
2025-01-21 04:38:36
|
Yah, I thought that interesting.
Also, jxl-oxide is not able to decode the full image. Only when it truncates relatively early
|
|
|
jonnyawsom3
|
2025-01-21 05:15:39
|
`--progressive_dc` 1 gives an image at `9600 bytes 1.2%` and 2 gives an image at `5600 bytes 0.6%` loaded
|
|
2025-01-21 05:16:23
|
2 loads sooner, but has higher bpp so you get less in the same amount of data
|
|
2025-01-21 05:22:46
|
This was the original for comparison, a game screenshot but 4K so should be close to your images at full resolution (Though memory may require half res)
|
|
|
AccessViolation_
I wonder why some of the lower quality tiles look pixelated while others look blurred
|
|
2025-01-21 06:01:42
|
Progressive DC 2 makes it into Modular 1:64 and VarDCT 1:8 LF frames, so the blur is likely the VarDCT and the pixilation is probably the Modular
|
|
2025-01-21 06:02:57
|
```Frame #0
Modular (maybe lossless)
Frame type: LF, level 2 (64x downsampled)
60x34
Frame #1
VarDCT (lossy)
Frame type: LF, level 1 (8x downsampled)
480x270
Frame #2 (keyframe)
VarDCT (lossy)
Frame type: Regular
3840x2160; (0, 0)```
|
|
2025-01-21 06:04:59
|
Oh, also <@526322998521888768> you can use `jxl-oxide -I --all-frames --with-offset` to get some debug info about the JXL files and when scans of the image should be loaded. Might be useful to calibrate how much data to send per pass
|
|
2025-01-21 06:06:09
|
Apologies for all the pings, you gave us something to do haha
|
|
|
Me
|
2025-01-21 06:19:53
|
Hey, no, I really appreciate all the support and help!
|
|
2025-01-21 06:20:16
|
I'm hoping we can be dumb and just send a few K, then a few K more of interesting images, and so on
|
|
|
AccessViolation_
|
|
Progressive DC 2 makes it into Modular 1:64 and VarDCT 1:8 LF frames, so the blur is likely the VarDCT and the pixilation is probably the Modular
|
|
2025-01-21 06:20:43
|
Is there anything in JXL that can signal how certain layers should be interpolated, or is that completely up to implementations?
|
|
|
jonnyawsom3
|
|
AccessViolation_
Is there anything in JXL that can signal how certain layers should be interpolated, or is that completely up to implementations?
|
|
2025-01-21 06:33:39
|
Uhh, you mean like upsampling algorythms?
|
|
|
Tirr
|
2025-01-21 06:34:21
|
partial files are not considered by the spec as those are invalid bitstreams
|
|
2025-01-21 06:35:37
|
libjxl does non-separable upsampling, and jxl-oxide does nearest neighbor
|
|
|
AccessViolation_
|
|
Uhh, you mean like upsampling algorythms?
|
|
2025-01-21 06:36:19
|
No, more like when the image has finished decoding already, how the viewer is supposed to handle interpolation when the user zooms in.
(I asked about layer specific interpolation, but this doesn't make sense when talking about about an image that has finished decoding, so ignore that)
|
|
2025-01-21 06:37:13
|
Like usually this is a setting in the viewer but I could see at least some use cases for this to be specified in the format itself
|
|
|
Tirr
|
2025-01-21 06:38:24
|
then nope, the spec only defines 1x zoom
|
|
|
AccessViolation_
|
2025-01-21 06:38:49
|
Ah okay. Honestly fair, was just curious
|
|
|
jonnyawsom3
|
2025-01-21 06:42:52
|
I mean, there is this https://github.com/libjxl/libjxl/pull/2571
|
|
2025-01-21 06:45:29
|
*Technically* an insane viewer could increase the upsampling scale as you zoom in, but it's a lot more effort than it's probably worth
|
|
|
AccessViolation_
|
2025-01-21 06:51:02
|
Huh so JXL supports that, it's an encoder thing
|
|
2025-01-21 06:51:08
|
Kinda cool
|
|
|
A homosapien
|
2025-01-21 06:55:03
|
The benefit of having an expressive format
|
|
|
_wb_
|
2025-01-21 08:19:43
|
If you want the upsampling to be baked into the image and done by the jxl decoder, you can use the 2x/4x/8x nonseparable upsampling defined in the spec, either with default filter weights (which are nice imo) or with something custom.
|
|
|
AccessViolation_
|
2025-01-21 08:32:46
|
I think upsampling to x8 basically removes the need for the image to signal how it wants to be interpolated when zooming yeah
|
|
|
jonnyawsom3
|
2025-01-21 08:36:33
|
Issue then is, normal decoders will honor the 8x upscale regardless of zoom level. So you'd need a closed ecosystem for what you want
|
|
|
Me
|
2025-01-22 04:16:04
|
Visualization of the blue marble image, compressed as ```cjxl -v -v -q 85 --lossless_jpeg=0 --container=1 --progressive --progressive_dc=2 --group_order=1 bluemarb.jpg trial.jxl``` and then having the first n kilobytes peeled off, where n is 1, 9, 17, ...up to 217k (out of 901k total size). Progressive rendering definitely works, but some of the choices the encoder makes are interesting.
|
|
|
CrushedAsian255
|
2025-01-22 09:18:12
|
https://music.apple.com/au/album/not-alone/1746873815?i=1746873826
|
|
2025-01-22 09:18:36
|
Oops wrong server
|
|
|
eustas
|
|
Yeah, letting anyone close other people's issues wouldn't be a *great* idea usually. But someone might have to sort by "Last Updated" when I'm done and close the ones I marked (some are asking for additional info or answering questions)
|
|
2025-01-22 01:47:57
|
Hi, Jonathan. Thanks for your awesome contribution in triaging JXL issues. And welcome - you will obtain "triage" role and will be able to close the issues (hopefully).
|
|
|
jonnyawsom3
|
2025-01-22 04:13:23
|
Thank you, I'll check it out soon
|
|
|
Me
Visualization of the blue marble image, compressed as ```cjxl -v -v -q 85 --lossless_jpeg=0 --container=1 --progressive --progressive_dc=2 --group_order=1 bluemarb.jpg trial.jxl``` and then having the first n kilobytes peeled off, where n is 1, 9, 17, ...up to 217k (out of 901k total size). Progressive rendering definitely works, but some of the choices the encoder makes are interesting.
|
|
2025-01-22 04:14:04
|
Also, if you're re-encoding JPEGs, there's likely EXIF data too correct?
`--brotli_effort 11` will increase the compression time spent on metadata
|
|
|
Me
|
2025-01-22 04:15:04
|
Cool, thanks for the tip. I had had a command line argument to strip EXIF but I had taken it out when things were failing
|
|
2025-01-22 04:15:25
|
I should probably ensure our toolchain puts some meaningful metadata in (and then compress it well)
|
|
|
jonnyawsom3
|
|
eustas
Hi, Jonathan. Thanks for your awesome contribution in triaging JXL issues. And welcome - you will obtain "triage" role and will be able to close the issues (hopefully).
|
|
2025-01-22 05:21:46
|
Seems to have worked, thanks again and hopefully I can lend a hand in future
|
|
|
Me
|
|
Me
Visualization of the blue marble image, compressed as ```cjxl -v -v -q 85 --lossless_jpeg=0 --container=1 --progressive --progressive_dc=2 --group_order=1 bluemarb.jpg trial.jxl``` and then having the first n kilobytes peeled off, where n is 1, 9, 17, ...up to 217k (out of 901k total size). Progressive rendering definitely works, but some of the choices the encoder makes are interesting.
|
|
2025-01-22 06:59:34
|
Does anyone understand this of how it is choosing to fill in the blocks ... how it does the left two thirds of the image top to bottom, then the right two thirds? I'd really prefer it to be middle out.
(The last phase is middle out, but this one is weird)
|
|
|
AccessViolation_
|
|
Me
Does anyone understand this of how it is choosing to fill in the blocks ... how it does the left two thirds of the image top to bottom, then the right two thirds? I'd really prefer it to be middle out.
(The last phase is middle out, but this one is weird)
|
|
2025-01-22 07:12:33
|
It might be this, I also noticed this behavior for some other image test a while ago
https://discord.com/channels/794206087879852103/794206170445119489/1285551387647938580
|
|
2025-01-22 07:14:07
|
For your convenience:
> It says group_order=1 is center first, is that the one where it spirals outward like the example from the whitepaper? It doesn't look like that's what it's doing, it looks more like a scanline pattern on three columns, doing the center one first, but it's hard to tell
> I see what you mean now, and I think I know why.
> That happens during the DC/LF part of the image, which are 2048 blocks instead of 256. So it probably is a spiral, but there's only 3 blocks so it just goes middle, left, right (probably)
|
|
|
jonnyawsom3
|
2025-01-22 07:51:58
|
I mentioned it before, but I think with `jxl-oxide -I --all-frames --with-offset` you can actually see the center-first reordering, and it doesn't seem to have applied to the DC
|
|
|
Me
|
2025-01-22 08:48:54
|
yah, I have a hard time knowing the group number to spatial relation. I do see how pass_idx=2 they start near the middle.
This is already a huge win for us. Seems like the win could be much bigger I could control frame #1 a little bit.
47x47 is great from 64x downsampling on frame #0-- down to 6k or so, able to send a lot of these per satellite contact. But frame #1 at 8x downsampling -- 115k before we get through the first group of the first pass, and the ordering isn't great.
I suspect I either want frame #1 to be 4x downsampled -- so that the middle-out does something useful -- or to be 16x downsampled so that it is just smaller.
|
|
|
jonnyawsom3
|
2025-01-22 09:05:58
|
I wonder if it could be done by editing libjxl to do a 2x or 4x downsample for DC 2 instead of 8x. I can't find anything in the spec mentioning something like `--progressive_dc 2`, only stating that VarDCT requires a 1:8 image for it's LF frame
|
|
|
Me
|
2025-01-22 09:09:25
|
```
cjxl -v -v -q 85 -m 0 --lossless_jpeg=0 --container=1 --progressive --progressive_dc=1 --group_order=1 -x strip=exif,xmp,jumbf bluemarb.jpg trial.jxl
```
This is with progressive_dc=1 .. e.g. no intermediate frame. Seems to be much more usefully "progressive" in practice (and smaller in size)
|
|
2025-01-22 09:09:39
|
same 8k chunks of file
|
|
2025-01-22 09:09:42
|
per frame
|
|
|
jonnyawsom3
|
2025-01-22 09:14:00
|
Yeah, DC 2 essentially embeds a 1:64 preview of the image, so using DC 1 you get more value for your bytes, but takes twice as many for a first image.
Depending how far you want to go, you could parse the TOC and send the bare minimum 'first image' per file.
It's a shame we don't have a better test image, since the 1/3 satellite could increase the size due to fine details. Though, if you use half-resolution like you mentioned, you could also increase the effort setting for smaller files and higher quality for a memory increase
|
|
|
Me
|
2025-01-22 09:16:02
|
Yah, but that 1:64 is tiny.. 6k there's something more going on
|
|
2025-01-22 09:17:16
|
This is 41k . better than the progressive_dc=2 image gets by 80k
|
|
2025-01-22 09:17:18
|
|
|
2025-01-22 09:18:26
|
let me pull progressive_dc=2 at 80k
|
|
2025-01-22 09:21:09
|
|
|
2025-01-22 09:22:36
|
trial == progressive_dc=1, trial2 == progressive_dc=2
|
|
2025-01-22 09:23:21
|
Two pngs above corresponding to progressive_dc=1 at 41 kilobytes, and progressive_dc=2 at 80 kilobytes
|
|
|
jonnyawsom3
|
2025-01-22 09:36:39
|
A slight improvement, modular arguments still apply to VarDCT's modular LF frame. Adding `-g 3 -E 3 -I 100` shaved off 1.5 KiB from progressive_dc=1 for me
`LfGlobal: 134708 (0x20e34) bytes`
`LfGlobal: 133237 (0x20875) bytes`
My exact command was this, the container is automatically enabled/disabled depending on metadata and some arguments have short variants
`cjxl -v -v -q 85 -m 0 -j 0 -p --progressive_dc=1 --group_order=1 -x strip=all -E 3 -I 100`
|
|
2025-01-22 09:38:46
|
Oh...
|
|
2025-01-22 09:39:03
|
|
|
|
|
embed
|
|
|
|
2025-01-22 09:39:08
|
https://embed.moe/https://cdn.discordapp.com/attachments/804324493420920833/1331739938294595675/Test.jxl?ex=6792b6f7&is=67916577&hm=826ab605bd614e2eaaac2e753180ffbf92d69a44206ee977609c17e68c22f1c2&
|
|
|
jonnyawsom3
|
2025-01-22 09:39:36
|
Maybe the modular arguements aren't meant to work...
|
|
2025-01-22 09:41:23
|
Turns out it was group size, didn't effect filesize anyway so I edited the command above
|
|
|
Me
This is 41k . better than the progressive_dc=2 image gets by 80k
|
|
2025-01-22 09:43:28
|
Almost seems like a bug, I don't think `--progressive_dc=2` has been tested much
|
|
|
AccessViolation_
|
2025-01-22 09:55:04
|
All these LF things are isolated to their groups right? So can't you make the group sizes smaller so that center first actually does something for the first few passes
|
|
2025-01-22 09:55:39
|
Instead of the whole image, or a lot of it of it, being in a single group
|
|
|
jonnyawsom3
|
|
https://embed.moe/https://cdn.discordapp.com/attachments/804324493420920833/1331739938294595675/Test.jxl?ex=6792b6f7&is=67916577&hm=826ab605bd614e2eaaac2e753180ffbf92d69a44206ee977609c17e68c22f1c2&
|
|
2025-01-22 09:56:49
|
Making groups bigger did that, I imagine smaller might corrupt it too, but <@526322998521888768> could try adding `-g 0` and see what happens
|
|
|
Me
|
2025-01-22 09:57:56
|
yah -m 0 does nothing. I have to go teach a competitive math class but i'll be back later
|
|
2025-01-22 09:57:59
|
to play with it more
|
|
|
AccessViolation_
|
2025-01-22 09:59:05
|
what if you make the group size the height/width of the image divided by three (rounding up to not create groups that just contain an edge of pixels)
|
|
2025-01-22 09:59:38
|
That should give you a center group that is decoded first
|
|
2025-01-22 10:00:03
|
or should be rather
|
|
|
Me
|
2025-01-22 10:00:04
|
I will play with encoding settings and middle out. I think I'm most concerned that progressive_dc=2 looks much worse for every size than progressive_dc=1
|
|
2025-01-22 10:00:31
|
progressive_dc=2 adds a 6k small preview but then is worse at sizes 40-60k larger than progressive_dc=1
|
|
|
jonnyawsom3
|
|
AccessViolation_
what if you make the group size the height/width of the image divided by three (rounding up to not create groups that just contain an edge of pixels)
|
|
2025-01-22 10:01:09
|
Group size is fixed at 128x128, 256x256 (Default), 512x512 or 1024x1024
|
|
|
AccessViolation_
|
2025-01-22 10:01:54
|
Oh huh, I thought they could be anything up to 1024x1024
|
|
2025-01-22 10:02:05
|
good to know
|
|
|
jonnyawsom3
|
2025-01-22 10:02:06
|
One sec, I'll check the spec
Well that was fast `naturally aligned rectangle covering up to 2n ร 2n input pixels, with n between 7 and 10, inclusive`
|
|
|
Me
|
2025-01-22 10:03:27
|
You get whatI'm saying? I'd expect 2 to be, say, 4k "behind" 1 in quality if there's a 6k lowres first, not 60k+ "behind" to reach same quality
|
|
|
jonnyawsom3
|
2025-01-22 10:04:33
|
Yeah, maybe <@794205442175402004> has some idea what's going on
|
|
2025-01-22 10:06:51
|
`--progressive_dc=2` is taking twice the data to reach the same progressive qualityhttps://discord.com/channels/794206087879852103/804324493420920833/1331734747914965074
|
|
|
Me
|
2025-01-22 10:24:51
|
Yay, test being proctored.
Re: satellite in frame. I expect it to not use too many bits, because it's going to be lowpass filtered --- out of focus ๐
|
|
|
Meow
|
2025-01-23 03:40:03
|
|
|
2025-01-23 03:40:04
|
This didn't get response. Is this a bug?
|
|
2025-01-23 03:40:49
|
This is similar to what libheif would cause
|
|
|
Tirr
|
2025-01-23 03:42:02
|
I think it's a macOS bug
|
|
2025-01-23 03:43:07
|
grayscale jxl doesn't work well in Preview or Finder for some reason
|
|
|
Meow
|
2025-01-23 03:44:29
|
I'll test again when I can access my own computer later today (or tomorrow for some)
|
|
|
Tirr
grayscale jxl doesn't work well in Preview or Finder for some reason
|
|
2025-01-23 03:45:24
|
Grayscale+Alpha for this
|
|
|
novomesk
|
2025-01-23 09:29:21
|
One GIMP3 user complained about ugly blue artifact when he uses distance 0.1 and 8-bit JXL with uses_original_profile = JXL_TRUE in BasicInfo + ICC.
I have impression that it was already mentioned somewhere, but not sure.
He shared picture in
https://gitlab.gnome.org/GNOME/gimp/-/issues/12785#note_2328039
|
|
|
A homosapien
|
|
novomesk
One GIMP3 user complained about ugly blue artifact when he uses distance 0.1 and 8-bit JXL with uses_original_profile = JXL_TRUE in BasicInfo + ICC.
I have impression that it was already mentioned somewhere, but not sure.
He shared picture in
https://gitlab.gnome.org/GNOME/gimp/-/issues/12785#note_2328039
|
|
2025-01-23 11:58:04
|
I can replicate, unchecking the "save original profile" fixes the issue
|
|
2025-01-23 11:59:06
|
```jxlinfo bubbles-save-original-profile.jxl
JPEG XL image, 1920x1200, (possibly) lossless, 8-bit RGB
Color space: 672-byte ICC profile, CMM type: "lcms", color space: "RGB ", rendering intent: 0
jxlinfo bubbles-no-icc.jxl
JPEG XL image, 1920x1200, lossy, 8-bit RGB
Color space: RGB, D65, sRGB primaries, sRGB transfer function, rendering intent: Relative```
|
|
2025-01-23 12:01:17
|
GIMP is definitely doing something wrong here
|
|
|
Tirr
|
2025-01-23 12:05:16
|
iirc `uses_original_profile` shouldn't be set to true when doing lossy
|
|
2025-01-23 12:06:51
|
ICC profile will always be embedded if there's one (but the encoded image will be in XYB), but I'm not very sure
|
|
|
|
veluca
|
|
Tirr
iirc `uses_original_profile` shouldn't be set to true when doing lossy
|
|
2025-01-23 12:10:04
|
yes, please don't do that ๐
|
|
2025-01-23 12:10:18
|
maybe we should rename that flag, the amount of people that get confused by it is a bit high
|
|
2025-01-23 12:10:56
|
I'm not sure there's ever a good reason to have that flag be different from "I am doing lossless"
|
|
2025-01-23 12:11:12
|
(well, maybe with modular lossy...)
|
|
|
CrushedAsian255
|
2025-01-23 12:12:30
|
what does the flag actually do? force decoding using the colour space defined at encode time?
|
|
|
|
veluca
|
2025-01-23 12:23:12
|
it disables XYB
|
|
|
A homosapien
|
2025-01-23 12:25:32
|
so it compresses in RGB ๐คข
|
|
|
|
veluca
|
|
spider-mario
|
2025-01-23 12:26:44
|
you see the problem
|
|
|
CrushedAsian255
|
|
A homosapien
so it compresses in RGB ๐คข
|
|
2025-01-23 12:33:37
|
oh geez, ahhhhhhh
|
|
|
Meow
|
|
Tirr
I think it's a macOS bug
|
|
2025-01-23 12:37:21
|
You're possibly right. Only Affinity series on my macOS can display Grayscale+Alpha JXL correctly
|
|
2025-01-23 12:40:22
|
The JXL one is only 0.2% smaller
|
|
|
novomesk
|
|
veluca
yes, please don't do that ๐
|
|
2025-01-23 02:24:32
|
I set uses_original_profile when encoding CMYK. Doesn't it mean that lossy CMYK is also not a good idea?
|
|
|
|
veluca
|
2025-01-23 02:26:21
|
I would not set uses_original_profile ๐
|
|
2025-01-23 02:27:06
|
although if I had to say I know what the encoder does with CMYK I would lie
|
|
2025-01-23 02:27:18
|
<@794205442175402004> probably knows better than me
|
|
|
_wb_
|
2025-01-23 05:18:21
|
Lossy CMYK is not tested at all, probably does not work.
|
|
2025-01-23 05:33:52
|
I mean, YCC like in CMYK jpegs should work (but we have no encoder for that). Using XYB with CMYK is a bit weird since the XYB only represents the CMY components, and I am not sure if the spec is sufficiently clear on how XYB should be converted to CMY - I think we intended to define it to do the XYB to CMY conversion by pretending it is producing sRGB. In any case the XYB will be abused as "just a transform" as opposed to being the absolute color space it is supposed to be, since the K component cannot be factored in.
|
|
2025-01-23 05:35:10
|
I don't really see the use case for lossy CMYK tbh. If you want lossy, you can just as well use a sufficiently wide gamut RGB space imo.
|
|
|
Me
|
2025-01-23 06:08:59
|
<@794205442175402004> Did you see the thing I had above? ```--progressive_dc=2``` resulted in a 64x downsampled modular frame that was like 5-6k at the beginning of the file, but then quality from 10-50k is 50k+ behind ```--progressive_dc=1``` (I'd expect to be paying a tax that was more like a fraction of the 6k spent on that first downsampled frame)
|
|
2025-01-23 06:09:31
|
e.g. progressive_dc=1 at 40k truncation looks way better than progressive_dc=2 at 80k truncation
|
|
|
_wb_
|
2025-01-23 06:10:17
|
Yeah that makes sense actually
|
|
|
Me
|
2025-01-23 06:10:24
|
(progressive_dc2 is also like 100k larger)
|
|
2025-01-23 06:10:59
|
Oh, I found it surprising. I'd expect for it to be worse / a few K behind, but not that much worse
|
|
|
_wb_
|
2025-01-23 06:11:19
|
Progressive DC > 1 is not really useful unless the image is super huge and even then it is not useful for better progression, just for better performance
|
|
|
Me
|
2025-01-23 06:11:41
|
as it stands now, i'd be better off sending a 5k PNG + a progressive_dc1 file -- better quality at any number of bytes received
|
|
2025-01-23 06:12:23
|
well, progressive_dc=2 is better when less than 5k is received
|
|
2025-01-23 06:12:34
|
but way worse from 5k on
|
|
|
_wb_
|
2025-01-23 06:12:44
|
Progressive_dc=1 does the 1:8 image using modular with squeeze, which already is as progressive as it gets
|
|
2025-01-23 06:13:20
|
Progressive_dc does the 1:8 image as VarDCT and only the 1:64 image as Modular with squeeze
|
|
|
Me
|
2025-01-23 06:14:16
|
Does modular with squeeze benefit in any way from a prior frame layer, or does only VarDCT?
|
|
2025-01-23 06:15:06
|
Sorry for noob questions. I don't really know image compression
|
|
2025-01-23 06:15:18
|
Application is for constrained downlink from a small student-built satellite.
|
|
2025-01-23 06:17:14
|
In any case, thank you very much for your help / listening. Jpeg-XL is a big win for us, but it'd be an much bigger win if we had something with the very-short-truncation performance of progressive_dc=2 but something closer to the longer-truncation performance of progressive_dc=1
|
|
|
AccessViolation_
|
|
Me
as it stands now, i'd be better off sending a 5k PNG + a progressive_dc1 file -- better quality at any number of bytes received
|
|
2025-01-23 06:18:55
|
You can always replace the PNG with a lossless JXL that should work out to about half the size :)
|
|
|
Me
|
2025-01-23 06:19:36
|
๐ Handling thumbnails and lots of files adds a whole lot of complexity to what students have to do
|
|