JPEG XL

Info

rules 57
github 35276
reddit 647

JPEG XL

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

General chat

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

Voice Channels

General 2147

Archived

bot-spam 4380

libjxl

Traneptora
veluca it should either have failed in the OOB PR too or in nothing at all
2024-01-29 02:45:23
it did
veluca
2024-01-29 02:45:36
... why did GH merge it then
Traneptora
2024-01-29 02:45:55
they're not listed as required
2024-01-29 02:46:17
2024-01-29 02:46:21
here's the history on the OOB merge
veluca
2024-01-29 02:47:08
ah, I wonder why they run then
Traneptora
2024-01-29 02:48:29
fwiw the thing that fixed the msvc builds broke clang builds
2024-01-29 02:48:46
the problem is that msvc requires a lambda campture
2024-01-29 02:48:53
but clang is fine
2024-01-29 02:48:56
``` /home/runner/work/libjxl/libjxl/lib/jxl/enc_icc_codec.cc:240:37: error: lambda capture 'kSizeLimit' is not required to be captured for this use [-Werror,-Wunused-lambda-capture] const auto tag_sane = [&tagsize, &kSizeLimit]() { ```
2024-01-29 02:49:05
and we have `-Werror=unused-lambda-capture`
2024-01-29 02:49:11
this is the problem with Werror IMO
veluca
2024-01-29 02:49:36
you don't have to convince me to dislike Werror 😛
Traneptora the problem is that msvc requires a lambda campture
2024-01-29 02:50:01
and this is the part where I say that writing C++ for multiple compiler is a nightmare
lonjil
2024-01-29 02:50:02
`-Weverything -Werror`
Traneptora
2024-01-29 02:50:48
we ran into this issue in FFmpeg where ``` struct Foo { int a; int b; }; struct Foo bar = (struct Foo){.a = 0, .b = 1}; ``` this doesn't compile on MSVC for no apparent reason
lonjil
veluca and this is the part where I say that writing C++ for multiple compiler is a nightmare
2024-01-29 02:51:12
just yesterday I tried building a project and got an error over the use of int64_t, the file in question missing an include for cstdint. Ain't that something.
Traneptora
2024-01-29 02:51:36
well that's an error that should occur
2024-01-29 02:51:42
surprised the compiler they used didn't produce one
2024-01-29 02:51:55
int64_t isn't a builtin type
2024-01-29 02:51:58
it's a typedef
veluca
2024-01-29 02:52:04
something else was including cstdint indirectly
2024-01-29 02:52:29
that depends on the libc, libc++, OS, compiler, cpu arch, and probably phase of the moon too
Traneptora
2024-01-29 02:53:25
just depends on header
2024-01-29 02:53:59
it doesn't really depend on the OS
veluca
2024-01-29 02:53:59
oh I mean that sometimes `cstdlib` (say) includes `cstdint`, and sometimes it doesn't
lonjil
2024-01-29 02:54:05
what's funny is the build instructions had steps for like a bazillion different OS and compiler combinations which I guess they just never test
Traneptora
2024-01-29 02:54:32
stdlib isn't required to include stdint
2024-01-29 02:55:00
so that kind of transitive include assumption is incorrect code
2024-01-29 02:55:09
sometimee they are required by spec
2024-01-29 02:55:18
stdlib is required to include stddef
veluca
Traneptora so that kind of transitive include assumption is incorrect code
2024-01-29 02:55:23
I agree, but it's almost impossible to detect
2024-01-29 02:55:51
if we had modules or just anything that is not direct textual inclusion, it would be a *lot* easier
lonjil
2024-01-29 02:55:55
On Plan 9, headers never include other headers, and the man pages for each header tell you which other headers you must manually include first for it to work.
Traneptora
2024-01-29 02:55:56
yes but almost all code needs stdint so that one is easy
2024-01-29 02:56:18
maybe im used to C where things are harder
veluca
lonjil On Plan 9, headers never include other headers, and the man pages for each header tell you which other headers you must manually include first for it to work.
2024-01-29 02:56:29
not sure if that's a lot better xD
Traneptora
2024-01-29 02:56:40
but it's bad practice to assume transitive includes that aren't guarateed by spec
2024-01-29 02:56:56
eg inttypes guarantees stdint, per spec
lonjil
2024-01-29 02:57:02
Sure they just didn't notice they forgot it because it compiled
veluca
2024-01-29 02:57:05
oh for sure, it's just hard to notice that you did assume it
2024-01-29 02:57:26
stuff such as `iwyu` exists but half of the time it doesn't really work
lonjil
2024-01-29 02:57:27
I noticed that *most* files in the project does include cstdint
2024-01-29 02:57:33
Just, a couple were missing it.
Traneptora
2024-01-29 02:57:43
though messups do happen
2024-01-29 02:58:10
like I accidentally included error.h in one of my projects cause I thought it was the header for errno
2024-01-29 02:58:27
but error.h is a glibc extension that I wasn't using tho
lonjil `-Weverything -Werror`
2024-01-29 02:59:49
nothing makes me add `-w` faster than `-Weverything -pedantic`
lonjil
2024-01-29 03:00:02
lol
Traneptora
2024-01-29 03:00:33
Generally there's a few things I Werror
2024-01-29 03:00:41
like implicit function declaration
2024-01-29 03:00:56
since that tends to be a typo that fails at link time
2024-01-29 03:01:06
Werroring it catches it earlier
veluca thanks 🙂
2024-01-29 03:05:09
in other news, DecodeTest.AlignTest is actually failing
2024-01-29 03:05:11
which may be relevant
veluca
Traneptora in other news, DecodeTest.AlignTest is actually failing
2024-01-29 03:33:43
yeah probably
Traneptora like implicit function declaration
2024-01-29 03:34:03
that should just be a hard error nowadays 🤣
Traneptora
veluca yeah probably
2024-01-29 03:34:04
currently running the tests locally to see if I can figure out why
veluca that should just be a hard error nowadays 🤣
2024-01-29 03:34:16
I think it is in C++, just not in C
2024-01-29 03:34:19
and it might be in C11
veluca
2024-01-29 03:34:20
yup
Traneptora
veluca yeah probably
2024-01-29 03:36:32
do you know how to run a specific test and only that test?
2024-01-29 03:36:46
trying to run all 6k tests is taking an exceptionally long time
veluca
2024-01-29 03:37:05
I know you can do it with ctest, but I usually just `./lib/test/the_test --gtest_filter=...`
Traneptora
2024-01-29 03:37:15
makes sense
2024-01-29 03:38:14
what's the `--gtest_filter` argument?
lonjil
Traneptora and it might be in C11
2024-01-29 03:39:29
C99, actually
Traneptora
2024-01-29 03:39:49
ah, figured it out
2024-01-29 03:39:59
apparently `AlignTest` is failing because the test is incorrect
2024-01-29 03:40:34
``` EXPECT_EQ(expected_line_bytes * ysize, pixels2.size()); ```
veluca
2024-01-29 03:43:36
that makes sense
Traneptora
veluca that makes sense
2024-01-29 03:51:14
I force pushed to the PR, fixing the test
spider-mario
Traneptora I think it is in C++, just not in C
2024-01-29 04:01:25
I recently got a compiler warning that it’s been deprecated for a while and will be removed in the next C standard (or something like that)
lonjil
2024-01-29 04:04:48
lmao
2024-01-29 04:04:52
it was removed in C99!
2024-01-29 04:05:27
Maybe C2y should explicitly mandate generating an error...
spider-mario
lonjil it was removed in C99!
2024-01-29 04:07:51
sorry, I meant _defining_ a function without declaring it, not calling it
2024-01-29 04:08:16
what `-Wmissing-prototypes` warns about
2024-01-29 04:08:33
(but testing it now, I’m not seeing the warning I remember seeing about the standard)
Traneptora
spider-mario sorry, I meant _defining_ a function without declaring it, not calling it
2024-01-29 04:13:25
I don't think that's against the rules
2024-01-29 04:13:46
if it was a lot of code that had `static int helper_func(foo) {` would be invalid
spider-mario
2024-01-29 04:14:51
static could very well be a special case
2024-01-29 04:15:19
defining a non-static function without having declared it anywhere could be a sign that it should, in fact, be static
Moritz Firsching
2024-02-02 11:50:14
I think so, yes
Quackdoc
2024-02-05 07:58:57
is it worth creating an issue ticket on a file that seems to require a lot of data to initially load? I have an image that requires 271k bytes to start decoding with libjxl stable (havent had the chance to test git yet) and the full file is 408k here is the original file, and output files from djxl and jxl-oxide EDIT: I can also upload the source png if needed
Tirr
2024-02-05 08:29:23
(note that jxl-oxide doesn't wait for a complete progressive scan)
Quackdoc
2024-02-05 02:01:37
I think the behavior of jxl-oxide here is generally preferred, I tested using the attention center demo https://google.github.io/attention-center/ and the image doesn't show up until around 70% of the file is loaded.
Quackdoc is it worth creating an issue ticket on a file that seems to require a lot of data to initially load? I have an image that requires 271k bytes to start decoding with libjxl stable (havent had the chance to test git yet) and the full file is 408k here is the original file, and output files from djxl and jxl-oxide EDIT: I can also upload the source png if needed
2024-02-05 02:14:54
ah I forgot to mention, jxl-oxide produced this image with 4kb of data loaded (tested with `head -c 4000 input.jxl > partial.jxl`)
Tirr
2024-02-05 02:18:11
I think a hybrid approach is possible. Wait until progressive scan if the stream is not ended, render as much as possible if stream is ended early.
Quackdoc
2024-02-05 02:20:58
yeah 66% is a lot to need to load for a progressive image IMO. Honestly im not sure it *really* matters on a sub 400kb large image, but IMO it would still be nice
2024-02-05 02:26:41
that and the accursed public wifi, I swear sometimes it feels like dialup
2024-02-05 02:33:21
~~until you walk the the wrong side of a building~~
Jim
2024-02-05 02:54:08
Odd, it seems to wait until the entirety of the image is available before actually rendering it. The polyfill I was working on was hard to capture it loading progressively because they loaded so fast, but even slowing down the bitrate I think it would start rendering at about 20%. That was with lossy though. Is that image lossless? Might work differently with lossless. https://discord.com/channels/794206087879852103/1036951308294434857/1045481067664134154
2024-02-05 02:55:34
Also could be that the browser code itself waits until all the blocks are available so it doesn't show individual blocks loading with a bunch of white space.
veluca
2024-02-05 03:46:48
sooo lossless streaming on huge images seems to be a whole lot faster than non-streaming
2024-02-05 03:46:56
``` JPEG XL encoder v0.10.0 5ed84a80 [AVX2,SSE4,SSE2] Encoding [Modular, lossless, effort: 7] Compressed to 48235.9 kB (9.881 bpp). 7216 x 5412, geomean: 5.014 MP/s [4.92, 5.02], 4 reps, 8 threads. 227.59user 1.83system 0:31.33elapsed 732%CPU (0avgtext+0avgdata 386908maxresident)k JPEG XL encoder v0.10.0 8803b203 [AVX2,SSE4,SSE2] Encoding [Modular, lossless, effort: 7] Compressed to 47974.1 kB (9.827 bpp). 7216 x 5412, geomean: 0.406 MP/s [0.28, 0.46], 4 reps, 8 threads. 391.78user 85.60system 7:08.85elapsed 111%CPU (0avgtext+0avgdata 5571068maxresident)k ```
2024-02-05 03:47:17
and parallelizes better too
2024-02-05 03:47:26
I didn't expect things to improve so much
qdwang
2024-02-05 04:09:27
Is JXL normal to have more compression artifacts than normal JPEG?
2024-02-05 04:11:42
2024-02-05 04:12:46
JXL seems to have more DCT squares
2024-02-05 04:13:53
The JPEG screenshot on the left: DNG -> Lightroom -> export 90% quality JPEG -> Lightroom -> Set Sharpening to 150
2024-02-05 04:15:29
The JXL screenshot on the right: DNG -> Decode to RGB -> libjxl conversion with 0.19 distance effort 4 -> Lightroom -> Set Sharpening to 150
lonjil
2024-02-05 04:16:20
Why the sharpening? And are the two compressed files the same size?
qdwang
lonjil Why the sharpening? And are the two compressed files the same size?
2024-02-05 04:17:51
Size are almost the same, the jxl one is 7.4mb and the jpeg one is 8mb. I just tried to use sharpening to check the image quality visually.
lonjil
2024-02-05 04:20:02
I'm not so sure that that is a valid method
Traneptora
2024-02-05 04:21:35
sharpening an image to check is quality is not a good method
_wb_
2024-02-05 04:23:49
it's a weird method — but if you do it, then you should compare to the sharpened original, not just see which one looks smoothest after sharpening
2024-02-05 04:24:18
I wouldn't use sharpening though, maybe contrast stretching or something but sharpening seems weird to me
damian101
2024-02-05 04:24:48
yes, sharpening distorts structurally, not good
Quackdoc
2024-02-05 04:25:45
I usually create a diff then crank the contrast, not a great method but it works xD
_wb_
2024-02-05 04:25:56
also: I wouldn't recommend effort 4 lossy encoding. Effort 6 should be fast enough for any normal use cases, and it gives significantly nicer results imo.
qdwang
Traneptora sharpening an image to check is quality is not a good method
2024-02-05 04:32:27
I know. But increasing the brightness can also show the artifacts.
_wb_ also: I wouldn't recommend effort 4 lossy encoding. Effort 6 should be fast enough for any normal use cases, and it gives significantly nicer results imo.
2024-02-05 04:33:02
I’ve tried 7
2024-02-05 04:33:43
_wb_
2024-02-05 04:38:08
I can't judge artifacts if you don't show me the original to compare against
Traneptora
I know. But increasing the brightness can also show the artifacts.
2024-02-05 04:38:31
If you can't seee the difference by just zooming in then I suppose the lossy codecs have done their jobs
qdwang
Traneptora If you can't seee the difference by just zooming in then I suppose the lossy codecs have done their jobs
2024-02-05 04:42:37
All right. I’m actually building an app to compress DNG to JXL DNG, but with even 0.1 distance, some post processing can still show some artifacts which may reduce the usage of jxl dng. So I just want to check if it’s normal.
Traneptora
2024-02-05 04:43:09
do keep in mind that JXL is a visual codec that's tuned for the content being displayed
2024-02-05 04:43:31
so doing things like amplifying distortions can cause differences that the codec (correctly) determines to be not noticeable
2024-02-05 04:43:52
the encoder makes decisions based on how the image is going to be presented
2024-02-05 04:44:25
as it stands, distance 0.1 is very low
2024-02-05 04:44:34
and it should be extremely hard to tell the difference between it and the original
_wb_
2024-02-05 04:48:07
yes, but it all depends on viewing conditions. Distance 1 is supposed to be 1 JND unit when viewed at ~1000 pixels distance and on a 200 nits or so display in normal indoors conditions. If you're going to view 3x zoomed on a 500 nits display in a dark room, then that might be equivalent to 5 JND units or so (I dunno how it scales but you get the point)
2024-02-05 04:54:27
One thing that might be worth doing for a use case where further processing is expected, is to bump up the intensity target, i.e. pretend that the image is 1000 nits or even more (by default libjxl assumes it is 255 nits for an SDR image). This will cause the darks to be preserved better, i.e. as if exposure was two stops higher.
qdwang
_wb_ One thing that might be worth doing for a use case where further processing is expected, is to bump up the intensity target, i.e. pretend that the image is 1000 nits or even more (by default libjxl assumes it is 255 nits for an SDR image). This will cause the darks to be preserved better, i.e. as if exposure was two stops higher.
2024-02-05 05:08:15
Thank you for mentioning this. I feed the raw linear 16bit RGB data to libjxl, and the primaries is set to `JXL_PRIMARIES_2100` and the transfer function is set to `Linear`, so should I use 10000 nits? How can i choose the proper intensity target for such input?
_wb_
2024-02-05 05:09:25
https://github.com/libjxl/libjxl/blob/main/lib/include/jxl/codestream_header.h#L138
Traneptora
Thank you for mentioning this. I feed the raw linear 16bit RGB data to libjxl, and the primaries is set to `JXL_PRIMARIES_2100` and the transfer function is set to `Linear`, so should I use 10000 nits? How can i choose the proper intensity target for such input?
2024-02-05 05:18:59
if you have HDR data, then intensity target is already important metadata that you should know
2024-02-05 05:19:11
is it actually HDR or just wide-gamut SDR?
_wb_
2024-02-05 05:20:00
Ideally I guess for raw images where the goal is to preserve the scene light, the intensity target should be set to something that corresponds more or less to reality. Reality is about 5000 nits for a typical sunny-day outdoors scene but peak intensities from specular reflections or direct light sources can be much higher than that (e.g. 600k nits for the sun at sunset/sunrise). Setting it to 10000 nits should be fine to allow further processing without having to worry that the darks will get artifacts when brightened in postprocessing. (you'll end up producing a jxl file that will be very bright and painful to look at though, when displayed on an HDR screen) Or what do you think, <@604964375924834314> ?
Traneptora
2024-02-05 05:21:08
10,000 nits shouldn't be bright and painful to look at
2024-02-05 05:21:12
that's pretty typical of PQ content, for example
Quackdoc
2024-02-05 05:24:21
if you have an actual 10k nit display, and are in dim surropundings it could produce a mild headache
_wb_
2024-02-05 05:24:29
well most displays cannot do more than 1000-2000 nits. Professional mastering monitors can go to 4000 nits typically.
Quackdoc
2024-02-05 05:24:32
flashes could be legitimately painful though
Traneptora
2024-02-05 05:25:33
but 10k nits is also the typical intensity target for PQ-HDR content
2024-02-05 05:25:35
that's all I meant
2024-02-05 05:25:42
so it's not like you're setting it unnaturally high by doing so
_wb_
2024-02-05 05:27:02
the content is typically mastered to 1k-4k nits, 10k is the signal limit PQ can do but it's not the actual content peak that is typically used, since there are no displays that can do that anyway
Quackdoc
2024-02-05 05:28:21
~~just don't tell that to people producing HDR demos~~
_wb_
2024-02-05 05:29:25
10k nits is pretty bright — of course our eyes can handle it, it's just a bit brighter than a clear sky, but compared to the usual SDR white that is 100-300 nits, 10k nits is pretty blinding
qdwang
2024-02-05 05:30:56
thank you guys, I've tried 1000nits. It already works. Although the size is a little bigger, but the result is awesome even with effort 4 and distance 0.45
2024-02-05 05:32:29
The intensity target seems to have a huge impact on the encoding quality for non SDR inputs.
jonnyawsom3
veluca and parallelizes better too
2024-02-05 05:33:21
What was the memory usage looking like? Because I'd have guessed the blocks used for streaming encoding might be running on separate threads entirely, but that would also raise the memory usage considerably too. Or at least that's my thoughts from peeking at the code the other day and those timings
veluca
What was the memory usage looking like? Because I'd have guessed the blocks used for streaming encoding might be running on separate threads entirely, but that would also raise the memory usage considerably too. Or at least that's my thoughts from peeking at the code the other day and those timings
2024-02-05 05:35:29
400 mb or so? The main difference is that we learn 64 trees in parallel, as opposed to a global one 😛
jonnyawsom3
2024-02-05 05:37:18
Ahh right
damian101
Traneptora that's pretty typical of PQ content, for example
2024-02-05 05:48:12
PQ content is not supposed to be painful to look at
2024-02-05 05:48:31
well, the Dolby demo files are, though
Traneptora
2024-02-05 05:48:44
yea, but 10k nits is a typical intensity target
2024-02-05 05:48:59
most (non-demo) content doesn't use that range
2024-02-05 05:49:01
but that's the *target*
_wb_
2024-02-05 06:02:24
PQ by definition has a 10k nits maxval. For HLG it's not defined in an absolute way, the maxval is 12 times whatever SDR white is...
afed
veluca 400 mb or so? The main difference is that we learn 64 trees in parallel, as opposed to a global one 😛
2024-02-05 06:02:58
does it make sense to extend streaming up to e9? also maybe different group sizes might be better/faster for some cases and as I mentioned, it would be nice to have it for e1 <:KekDog:805390049033191445> lossy might be faster too, because it's more linear threading and less memory, so memory bandwidth is not a bottleneck
veluca
2024-02-05 06:03:48
E1 has been able to do streaming for a while 😛
2024-02-05 06:04:02
Also different group sizes works too
2024-02-05 06:04:34
Lossy vardct can do streaming too, but only up to speed 6
2024-02-05 06:04:41
IIRC
2024-02-05 06:05:21
Not sure if streaming e9 lossless would make sense, perhaps we need to add a e10 too
afed
veluca Also different group sizes works too
2024-02-05 06:05:28
i mean different group sizes for e1 <:Poggers:805392625934663710>
veluca
2024-02-05 06:05:41
And move current E10 to E11 😛
afed i mean different group sizes for e1 <:Poggers:805392625934663710>
2024-02-05 06:05:45
?
Traneptora
2024-02-05 06:06:39
have e10 exhaustively choose all options including various values of group size shift?
afed
veluca ?
2024-02-05 06:07:14
previously it was not possible to choose group size for e1
veluca
2024-02-05 06:07:54
Ahhh, yeah, It doesn't do that still
Traneptora have e10 exhaustively choose all options including various values of group size shift?
2024-02-05 06:08:44
That's already there, but we could do streaming up to e9, E10= non streaming E9, E11 = current E10
Traneptora
2024-02-05 06:08:53
¯\_(ツ)_/¯
2024-02-05 06:09:05
I have no real opinions on exhaustive searches anyway since they're mostly toys
2024-02-05 06:09:09
and not for real production use
afed
veluca That's already there, but we could do streaming up to e9, E10= non streaming E9, E11 = current E10
2024-02-05 06:10:14
but, if streaming is not going to be the default for efforts higher than e7, does it make sense? or because it is much faster, it would be better to make it default for all efforts? <:Thonk:805904896879493180>
lonjil
2024-02-05 06:10:52
I've said it before and I'll say it again, really exhaustive stuff should be called something like e99, just to make sure people understand how bad it is.
2024-02-05 06:10:56
Maybe e1000
_wb_
veluca That's already there, but we could do streaming up to e9, E10= non streaming E9, E11 = current E10
2024-02-05 06:11:01
I'm in favor. Currently there is too big a mismatch between lossy and lossless effort, and that would help fix that.
veluca
lonjil I've said it before and I'll say it again, really exhaustive stuff should be called something like e99, just to make sure people understand how bad it is.
2024-02-05 06:11:23
It Is behind a --allow_expert_options
_wb_
2024-02-05 06:13:58
So basically e1-e9 become streaming by default, e10 becomes the old e9, and e11 is locked behind --allow_expert_options and is the old e10
2024-02-05 06:16:31
Maybe we could have an e11 and e12, where e11 is something like the current e10 but less exhaustively (say, try 4 things or so, so it's only 4x as slow as the current e9), and e12 is the crazy exhaustive thing that we want to lock behind a toggle because it is too crazy
2024-02-05 06:17:13
Having e1-e11 available to the general public is satisfying in a Spinal Tap sense
2024-02-05 06:17:55
afed
2024-02-05 06:18:21
maybe it's better to squeeze some efforts or is their arrangement most optimal currently?
_wb_
2024-02-05 06:28:49
I think having more fine grained control over effort is nicer. Makes us more complete in covering the Pareto front...
veluca
2024-02-05 06:33:52
If you can make the PR you'd make me happy 😛
_wb_
2024-02-05 06:36:22
Not now, maybe later this week though
afed
veluca If you can make the PR you'd make me happy 😛
2024-02-05 06:39:16
and then we need the opposite, to inform in cli when it's a non-streaming encoding mode <:KekDog:805390049033191445>
_wb_ So basically e1-e9 become streaming by default, e10 becomes the old e9, and e11 is locked behind --allow_expert_options and is the old e10
2024-02-05 06:53:36
and even faster e0, with some settings from fjxl <:kekw:808717074305122316>
Traneptora
2024-02-05 06:55:21
e1 is basically just fjxl keep in mind
2024-02-05 06:55:23
but in libjxl
afed
2024-02-05 06:57:50
yeah, but without access for some more specific settings
_wb_
2024-02-05 07:23:04
Right, there is fjxl effort too, like trying palette or not
sklwmp
afed and then we need the opposite, to inform in cli when it's a non-streaming encoding mode <:KekDog:805390049033191445>
2024-02-05 11:16:46
actually this, we need a way for people to know that e10 lossless is significantly slower than e9 lossless if it's not hidden behind expert options i also thought about just keeping e1-9 but adding a flag to disable streaming (and note its tradeoffs), but maybe that just adds complexity?
2024-02-05 11:20:33
or maybe just document somewhere what each effort level does (i swear we had this before?) i think i really only know what they do since i've asked and read a lot about cjxl 😛 would be useful to new users who don't yet know which effort to pick and their pros and cons
afed
2024-02-05 11:23:44
https://github.com/libjxl/libjxl/blob/main/doc/encode_effort.md
sklwmp
2024-02-05 11:23:54
right, thanks for finding it! but maybe add notes when there's a significant drop off in speed (e1 to e2 lossless, streaming vs non streaming, etc.) or just highlight the differences between each effort (e.g., e2 is decently slower than e1 for decent compression gains)
2024-02-05 11:24:22
or e9 is slightly better than e7 for significantly slower speed
afed
2024-02-05 11:27:27
i think because speed is something that is not constant and can be optimized, it is not something that needs to be noted in cli or documentation, maybe just links to some benchmarks
jonnyawsom3
2024-02-06 12:08:46
Benchmarks are already run at various qualities and efforts when density or speed changes are made in PRs, so it could make sense to have one with each release too. Also show improvements across versions that way too
monad
sklwmp actually this, we need a way for people to know that e10 lossless is significantly slower than e9 lossless if it's not hidden behind expert options i also thought about just keeping e1-9 but adding a flag to disable streaming (and note its tradeoffs), but maybe that just adds complexity?
2024-02-06 06:23:00
The sitch with e10 (e11 preemptively) is quite plain: don't use it. It's very dumb and very bad. If you absolutely _must_ waste some cycles, using a combination of e9 settings can yield a better result.
afed
2024-02-06 02:10:11
<:monkaMega:809252622900789269> `if (cparams.speed_tier == SpeedTier::kTectonicPlate)` https://github.com/libjxl/libjxl/pull/3248
veluca
2024-02-06 02:12:56
that's just the old effort10
2024-02-06 02:13:05
with a more appropriate name 😛
2024-02-06 02:13:20
(<@794205442175402004>'s idea from some time ago)
username
2024-02-06 02:13:46
I love these names lol, I thought "Glacier" was great but now we are gonna have "Tectonic Plate"
Quackdoc
afed <:monkaMega:809252622900789269> `if (cparams.speed_tier == SpeedTier::kTectonicPlate)` https://github.com/libjxl/libjxl/pull/3248
2024-02-06 02:22:55
man. I just finished figuring out what settings I wanted to use for manga T.T
afed
veluca that's just the old effort10
2024-02-06 02:24:24
for streaming mode larger group size can improve compression or is it almost the same as for normal mode (just for some specific images)?
veluca
2024-02-06 02:28:01
it can improve yep
yoochan
Quackdoc man. I just finished figuring out what settings I wanted to use for manga T.T
2024-02-06 02:28:04
which settings ? I'm curious 🙂 manga scans ? or directly from the creator file ? There is a lot of preconceived opinions about the performance of AVIF for mangas, but I would prefer to convince the world jxl does it better
sklwmp
2024-02-06 02:41:22
ngl streaming mode sounds really exciting, i can finally encode many large images without using 20GB of RAM <:BlobYay:806132268186861619> and ofc the speed improvements are amazing too
afed
2024-02-06 02:44:50
with streaming png support, memory usage would be even somewhat lower <:YEP:808828808127971399>
jonnyawsom3
2024-02-06 02:48:13
I think the main killer will be chunked int to float for 8bit images, since that alone quadruples memory usage when run all at once IIRC
afed
afed <:monkaMega:809252622900789269> `if (cparams.speed_tier == SpeedTier::kTectonicPlate)` https://github.com/libjxl/libjxl/pull/3248
2024-02-06 02:51:58
probably the encoding speed for streaming mode can be higher even for single-threaded mode, because there is less memory usage <:Thonk:805904896879493180>
jonnyawsom3
afed probably the encoding speed for streaming mode can be higher even for single-threaded mode, because there is less memory usage <:Thonk:805904896879493180>
2024-02-06 02:57:43
Considering how often people were hitting the swapfile due to low system memory, yeah it could make quite the difference haha
Oleksii Matiash
2024-02-06 03:02:04
For those who missed the key point - what is tradeoff for streaming mode vs non-streaming?
Quackdoc
yoochan which settings ? I'm curious 🙂 manga scans ? or directly from the creator file ? There is a lot of preconceived opinions about the performance of AVIF for mangas, but I would prefer to convince the world jxl does it better
2024-02-06 03:03:10
mangascans, anything png I get ill use this, I just use `cjxl Untitled.png -d 1.5 -e 6 -m 1` I don't use yuv444 wtih avif since I also read a lot of colored comics. This is very comparable with avif yuv444, a wee bit larger for the same quality, but since I get stuff like progressive decode and what not, its worth it for me
jonnyawsom3
Oleksii Matiash For those who missed the key point - what is tradeoff for streaming mode vs non-streaming?
2024-02-06 03:03:44
A multiplication of speed, a large reduction in memory usage, but marginally increased filesize
Oleksii Matiash
A multiplication of speed, a large reduction in memory usage, but marginally increased filesize
2024-02-06 03:04:08
Thank you!
afed
Oleksii Matiash For those who missed the key point - what is tradeoff for streaming mode vs non-streaming?
2024-02-06 03:04:45
with streaming the encoder does not have access for the whole image at once, only for a individual block/tile, so compression can be a slightly worse
veluca
2024-02-06 03:05:24
oh if you do modular lossy then streaming mode is going to do pretty much nothing
jonnyawsom3
2024-02-06 03:06:20
Current > Encoding [Modular, lossless, effort: 7] > Compressed to 47974.1 kB (9.827 bpp). > 7216 x 5412, geomean: 0.255 MP/s [0.25, 0.26], 5 reps, 72 threads. > 847.79user 141.99system 12:48.70elapsed 128%CPU (0avgtext+0avgdata 7066772maxresident)k Streaming > Encoding [Modular, lossless, effort: 7] > Compressed to 48235.9 kB (9.881 bpp). > 7216 x 5412, geomean: 10.826 MP/s [10.47, 11.02], 5 reps, 72 threads. > 609.18user 138.46system 0:19.57elapsed 3819%CPU (0avgtext+0avgdata 1003488maxresident)k
afed
2024-02-06 03:07:14
but also because `72 threads` <:KekDog:805390049033191445> with less threads, there will probably be less difference
jonnyawsom3
2024-02-06 03:08:21
So 50x faster, 7x less memory and 1% larger filesize (Assuming you have enough cores)
veluca
afed but also because `72 threads` <:KekDog:805390049033191445> with less threads, there will probably be less difference
2024-02-06 03:08:44
it's plenty fast even with 8 threads or so 🙂
jonnyawsom3
2024-02-06 03:09:20
Assuming 1 thread per group, I'd be surprised if it fully utilised that many threads
veluca
2024-02-06 03:10:00
it's a *big* image - but it should do up to 64 threads only
2024-02-06 03:10:09
``` Encoding [Modular, lossless, effort: 7] Compressed to 48235.9 kB (9.881 bpp). 7216 x 5412, second: 4.058 MP/s [4.00, 4.06], 2 reps, 8 threads. ```
2024-02-06 03:10:19
with 8 threads
jonnyawsom3
2024-02-06 03:10:42
Mind doing 16 threads? To see how it scales
veluca
2024-02-06 03:11:16
``` Encoding [Modular, lossless, effort: 7] Compressed to 48235.9 kB (9.881 bpp). 7216 x 5412, second: 7.026 MP/s [6.84, 7.03], 2 reps, 16 threads. ```
jonnyawsom3
2024-02-06 03:11:40
So fairly linear, nice
veluca
2024-02-06 03:12:25
and if you bump up group size... ``` JPEG XL encoder v0.10.0 796c1439 [AVX2,SSE4,SSE2] Encoding [Modular, lossless, effort: 7] Compressed to 47805.9 kB (9.793 bpp). 7216 x 5412, second: 5.642 MP/s [5.51, 5.64], 2 reps, 16 threads. ```
2024-02-06 03:12:34
(`-g 3`)
afed
2024-02-06 03:13:01
need some heuristics for the best group size for resolution and number of threads <:YEP:808828808127971399>
jonnyawsom3
2024-02-06 03:14:38
If larger groups were always better, then that alone would offset the size increase of streaming
veluca
2024-02-06 03:14:54
they aren't
2024-02-06 03:15:17
they are in streaming mode if the image is pretty uniform (which tends to be the case for photo)
jonnyawsom3
2024-02-06 03:16:20
Yeah, hence the if. It was a few months ago I had a file that was almost 10x smaller with -g 1 than it was with any other. Or something similar, I know I talked about it here at the time
2024-02-06 03:17:34
Discovered it when e 8 was much smaller than e9 which had me scratching my head for a while
lonjil
2024-02-06 09:02:00
whelp I pulled the latest libjxl before starting to play with jxl_from_tree's code, but now builds fail because of a problem with libpng
2024-02-06 09:13:24
Not bunding PNG solves that I guess 🙂
Traneptora
2024-02-06 09:39:46
FORCE_SYSTEM_ETC. flags should all be enabled on linux if possible
lonjil
2024-02-07 12:36:47
is there a convenient way to build the bare minimum needed for jxl_from_tree? I don't know a whole lot about CMake
2024-02-07 12:40:06
maybe doing unclean builds is fine when bisecting...
2024-02-07 12:45:41
`cmake --build build_dir --target jxl_from_tree` and `ninja -C build_dir tools/jxl_from_tree` both seem to work, in that they only link that tool, but they still build a lot of stuff not needed by jxl_from_tree.
_wb_
2024-02-07 06:53:22
Strange, did we remove anything?
Moritz Firsching
2024-02-07 07:51:50
https://github.com/libjxl/libjxl/compare/v0.9.0...v0.9.1 I would have expected that it just works, but perhaps one of those commits is causing a breakage? I plan to try to build chrome and make patches for v0.9.1 (and the upcoming v0.9.2)
spider-mario
2024-02-07 08:40:09
at first glance, I don’t see any removal in there that can’t be expressed in terms of what remains
2024-02-07 08:40:19
(which is presumably why we removed it)
Moritz Firsching
2024-02-07 11:04:58
patchset 8 is rebased on today's chrome with v0.9.1 is here: https://chromium-review.googlesource.com/c/chromium/src/+/4255409 builds fine, there were only minor merge conflicts, because stuff in chrome changed a bit... Will upload patchset 9 with v0.9.2, but I expect that bump to be trivial
2024-02-07 12:26:49
Patchset 9 with v0.9.2 is now also there
username
2024-02-07 08:15:39
could zlib be switched out with [zlib-ng](https://github.com/zlib-ng/zlib-ng) in libjxl? I assume zlib is only used for PNG handling in the tools but it should have noticeable benefits for people batch converting folders of PNGs and such. there's some small benchmarks people have done in the past here https://github.com/opencv/opencv/issues/22573
jonnyawsom3
2024-02-08 02:03:00
There's .161 now too
yurume
username could zlib be switched out with [zlib-ng](https://github.com/zlib-ng/zlib-ng) in libjxl? I assume zlib is only used for PNG handling in the tools but it should have noticeable benefits for people batch converting folders of PNGs and such. there's some small benchmarks people have done in the past here https://github.com/opencv/opencv/issues/22573
2024-02-08 05:42:26
I would rather like libdeflate https://github.com/ebiggers/libdeflate instead, if it's a major concern
username
yurume I would rather like libdeflate https://github.com/ebiggers/libdeflate instead, if it's a major concern
2024-02-08 04:05:58
never heard of this before, it seems cool! although it doesn't seem to work as a drop in replacement for zlib and the reason I sent zlib-ng is because it can function as a direct replacement for zlib and zlib seems to only really be used by libpng in libjxl's tools so it wouldn't make sense going through all the effort of making a fork of libpng just so it can use libdeflate
MSLP
2024-02-08 04:14:14
i guess then it would be looking at <https://github.com/chromium/chromium/tags>
2024-02-08 04:15:11
or better <https://chromium.googlesource.com/chromium/src/+refs>
gb82
Quackdoc mangascans, anything png I get ill use this, I just use `cjxl Untitled.png -d 1.5 -e 6 -m 1` I don't use yuv444 wtih avif since I also read a lot of colored comics. This is very comparable with avif yuv444, a wee bit larger for the same quality, but since I get stuff like progressive decode and what not, its worth it for me
2024-02-08 09:27:55
is effort 6 *that* much faster than e7 where it'd be worth using for this?
Traneptora
gb82 is effort 6 *that* much faster than e7 where it'd be worth using for this?
2024-02-08 09:28:08
e6 is considerably faster than e7, yea
2024-02-08 09:28:36
there's minimal diference in quality tho between e5 and e6
gb82
2024-02-08 09:28:42
gotcha
Traneptora
2024-02-08 09:28:44
so I don't particularly see much reason to use e6 over e5
2024-02-08 09:29:03
at least atm, e3 and e4 are very similar in speed, so e4 ends up being better most of the time
2024-02-08 09:29:17
e5 and e6 end up being very similar in quality, so e5 ends up being better most of the time
2024-02-08 09:29:20
it's nonlinear
gb82
2024-02-08 09:30:05
huh, interesting
Traneptora
2024-02-08 09:30:24
ye, it changes which features are enabled
gb82
2024-02-08 09:30:49
this is what I was able to test before 0.9.0 was released
Traneptora
2024-02-08 09:30:53
for example, e3 uses only 8x8 dct blocks, but e4 enables the algorithm that calculates the block layout
2024-02-08 09:31:48
that algorithm is fairly inexpensive, so it doesn't improve compute time much
2024-02-08 09:31:56
it's why e4 is the default in mpv for screenshots
gb82 this is what I was able to test before 0.9.0 was released
2024-02-08 09:32:24
vardct floors at e3
2024-02-08 09:32:37
so not sure why this is giving different numbers for e2 and e3
2024-02-08 09:32:44
e1 and e2 are only interesting for modular
gb82
2024-02-08 09:33:03
it is such a tiny number that it is probably run to run variance
Traneptora
2024-02-08 09:33:08
¯\_(ツ)_/¯
2024-02-08 09:33:09
maybe
2024-02-08 09:33:13
vardct e3 is essentially glorified xyb jpeg
gb82
2024-02-08 09:33:18
although it is the average across 20 runs with 5 warmups
Traneptora
2024-02-08 09:33:21
since it only uses 8x8 dct blocks
2024-02-08 09:33:43
it's still better than xyb jpeg because it can take advantage of JXL's entroy coding
gb82
2024-02-08 09:33:49
yeah but you get JXL entropy coding features right? so its still gonna beat xyb jpeg
Traneptora
2024-02-08 09:33:51
but it's similar
2024-02-08 09:33:52
ye
gb82
Traneptora it's still better than xyb jpeg because it can take advantage of JXL's entroy coding
2024-02-08 09:34:00
lol yea u got it b4 me
2024-02-08 09:34:47
ig I considered e5/6/7 much closer to each other because I was looking at them relative to e8/9
Quackdoc
gb82 is effort 6 *that* much faster than e7 where it'd be worth using for this?
2024-02-08 09:42:34
yes, especially when doing parallel encodes
afed
Traneptora it's why e4 is the default in mpv for screenshots
2024-02-08 09:43:09
if jxl benefits from streaming even for non-streaming input formats, just by encoding with tiles and streaming output, is it possible to use this in mpv/ffmpeg? <:Thonk:805904896879493180>
Traneptora
2024-02-08 09:43:42
ffmpeg's structure buffers entire AVFrames and AVPackets
2024-02-08 09:44:06
so streamed decoding and encoding for a single AVFrame is not going to be useful in the FFmpeg context
gb82
Quackdoc yes, especially when doing parallel encodes
2024-02-08 09:44:13
how long does it take to encode your entire corpus
Quackdoc
gb82 how long does it take to encode your entire corpus
2024-02-08 09:44:59
no idea, but a while ago I was testing on my phone anyways. Im waiting for streaming mode to be enabled by default before doing any more testing
gb82
2024-02-08 09:46:45
ah gotcha
veluca
Traneptora vardct e3 is essentially glorified xyb jpeg
2024-02-08 10:12:54
e3 as is today should be e2, and probably there should be an e1 like fjxl
2024-02-08 10:13:10
e3 probably should do adaptive quantization like jpegli does
2024-02-08 10:13:45
the end result would likely be somewhat better than jpegli and still quite fast
2024-02-08 10:14:57
the main difference between e7 and e6 performance-wise are things like dots and patches, which IMO are not that useful below distance 3 or so... which is why cjxl main disables them in that case since a few commits ago (well, enables streaming, which is effectively the same thing)
Traneptora
veluca e3 probably should do adaptive quantization like jpegli does
2024-02-09 05:40:40
how does AQ work in libjxl?
veluca
2024-02-09 06:16:41
Nobody knows 😛
Traneptora
2024-02-09 08:28:59
what does that mean
2024-02-09 08:29:35
like, is AQ adjusting hf_mult based on the varblock's data basically?
veluca
2024-02-09 08:30:00
well, it's setting the quantization field, which does change the hf multiplier
Traneptora
2024-02-09 08:30:24
ah, I have a static quant table in hydrium and a static hf multiplier
veluca
2024-02-09 08:30:44
but how it chooses to do so is... well, we have code, it seems to work, and it seems to do sensible stuff, but that's all I know
Traneptora
2024-02-09 08:30:47
I used to adjust the HF multiplier based on content but it was too slow and didnt' affect visuals much
2024-02-09 08:31:04
so I dropped it, now hf_mult is constant 5
2024-02-09 08:31:29
may make sense to redo my HF quant tables so I can raise that number a bit
2024-02-09 08:32:06
cause atm I do `hf_quant_table[i] * hf_mult` and if I bake that number into the quant table, I can then calculate it in higher precision
2024-02-09 08:32:12
like there's a 7 in there
2024-02-09 08:32:15
which just becomes 35
2024-02-09 08:32:20
changing it to 8 would be -> 40 effectively
2024-02-09 08:32:25
but what if 37 is correct? etc.
2024-02-09 08:33:00
although I don't remember exactly how I calculated them in the first place
Tirr
2024-02-10 11:17:34
cjxl seems to set bitdepth to float32 when converting from vardct jxl image. is this intended or a bug?
_wb_
2024-02-10 11:28:54
Probably not intended.
Tirr
2024-02-10 11:45:03
I'll file a bug when I have time
Traneptora
2024-02-10 04:59:47
I mentioned this in the past iirc
Tirr cjxl seems to set bitdepth to float32 when converting from vardct jxl image. is this intended or a bug?
2024-02-12 05:29:24
it was supposedly fixed in https://github.com/libjxl/libjxl/pull/2591
2024-02-12 05:29:35
but looks like not entirely
lonjil
2024-02-14 10:01:48
what's the difference between ssimulacra2 in libjxl and v2.1 from this repo? https://github.com/cloudinary/ssimulacra2
_wb_
2024-02-14 10:11:13
it's the same
lonjil
2024-02-14 10:11:37
👍
Traneptora
2024-02-14 05:08:52
would it be possible to have `ssimulacra2` from libjxl installed with the rest of the base tools without all the devtools?
2024-02-14 05:09:09
I don't want `exr_to_pq` and the like installed when I run make install, but I do want ssimulacra2
2024-02-14 05:09:13
is there a way to adjust that with cmake?
_wb_
2024-02-14 05:16:03
No idea, but maybe it would make sense to have metrics, hdr tools, and "rest of dev tools" behind different build flags instead for some more fine grained control...
Traneptora
2024-02-14 09:15:04
yea, cause ssimulacra2 is useful for testing other things
2024-02-14 09:15:10
(I use it when tweaking hydrium for example)
yoochan
2024-02-14 09:26:02
It doesn't take long to compile everything...
Traneptora
2024-02-14 09:38:30
The problem is I don't want them installed
spider-mario
2024-02-14 09:42:12
to the best of my knowledge, the only way to control this within cmake is to have our own variable like `JPEGXL_INSTALL_EXR_TO_PQ` and then `if (JPEGXL_INSTALL_EXR_TO_PQ) install(TARGETS exr_to_pq) endif ()`
2024-02-14 09:43:01
if using a PKGBUILD or equivalent, though, there is also the option of: ```bash package() { # ... make install DESTDIR="$pkgdir" rm "$pkgdir/usr/bin/exr_to_pq" } ```
2024-02-14 09:44:14
ooh, I was wrong, the cmake `install` command has a concept of “components” that we might be able to take advantage of
2024-02-14 09:44:54
“the best of my knowledge” has been upgraded
2024-02-14 09:44:58
I like when this happens
lonjil
2024-02-14 09:59:07
`doas cp build/tools/ssimulacra2 /usr/local/bin` is my install procedure
Traneptora
2024-02-14 10:53:46
if you build the devtools they'll be installed by make install
2024-02-14 10:54:28
so you need to build with devtools off, make install, turn it on, build again, copy
spider-mario
2024-02-15 08:07:21
or: build with devtools on, copy, turn them off, make install
Kremzli
2024-02-15 03:34:24
How much work is left for a version 1.0?
Olav
Kremzli How much work is left for a version 1.0?
2024-02-15 05:13:47
https://github.com/libjxl/libjxl/milestone/1
lonjil
2024-02-15 05:38:55
what's the timeline on officially releasing jpegli?
Demiurge
2024-02-16 12:47:09
I wonder if libjxl conversion tools and jpeg decoder will be able to make use of HDR JPEG files on android 14. https://developer.android.com/media/platform/hdr-image-format
2024-02-16 12:48:15
Ideally decoding them as HDR image data instead of treating them as a SDR JPEG
2024-02-16 12:50:13
Looking at it, it looks worse than just a regular JPEG file with a HDR color profile attached.
2024-02-16 12:51:04
But libjxl should ideally at least be able to read and interpret this new android thing correctly.
2024-02-16 01:14:17
Looks like it encodes a downscaled gain map image as an XMP metadata object
2024-02-16 01:14:39
Instead of just using a color profile like a normal person would do
_wb_
2024-02-16 07:46:28
The gain map is not inside the xmp, it's tail data of the first jpeg iirc. It's basically a messy hacky reinvention of JPEG XT.
Demiurge
2024-02-16 08:40:02
Weird that they went with such a dumb reinvention instead of literally anything else
Quackdoc
2024-02-16 11:38:35
they needed to because nothing else actually does what they want,
Traneptora
2024-02-17 04:08:31
except jxl but shhh
Demiurge
2024-02-17 05:19:09
Quack, couldn't they have just used an ICC profile and floating point encoder/decoder?
CrushedAsian255
Traneptora except jxl but shhh
2024-02-17 05:19:15
and you know, jpeg-xt
Demiurge
2024-02-17 05:19:30
You know, like how libjxl/jpegli does?
Quackdoc
Traneptora except jxl but shhh
2024-02-17 05:19:42
strictly speaking about android and only android which is a bit disingenuous IMO but worth it, this may be true in 3-4 years from now. A large part of their new HDR stuff is that it will work fine on old and legacy stuff where HDR is unavailable or inconvenient, which is still the vast majority of devices out there. This is a massive win since content creators can now actually make HDR images without messing up SDR viewers. This is a major issues with "General use" HDR adoption which was very much a chicken and egg problem, that google essentially solved. So gainmaps themselves are necessary regardless of the image format itself. A10 devices are still common let alone A11 devices. and it was only with A12 or A13 that the media codec pipeline in android has become upgradeable without flashing a new rom. it will still need the gainmap + extra data ofc. And there needs to be *some way* of decoding that. so A12+ (or maybe A13 can't remeber) this would be possible
CrushedAsian255
2024-02-17 05:20:24
so it's trying to do a HLG?
2024-02-17 05:20:35
as in being backwards-compagtible
Quackdoc
Demiurge Quack, couldn't they have just used an ICC profile and floating point encoder/decoder?
2024-02-17 05:20:43
In the end, supporting both SDR and HDR **with good quality on both** is the key issue, when doing any kind of mapping, you can make it "usable but not great"
CrushedAsian255 so it's trying to do a HLG?
2024-02-17 05:20:51
HLG on steroids
CrushedAsian255
Quackdoc HLG on steroids
2024-02-17 05:21:57
then use avif with hlg? /sarcasm
Quackdoc
2024-02-17 05:22:07
[dogelol](https://cdn.discordapp.com/emojis/867794291652558888.webp?size=48&quality=lossless&name=dogelol)
Demiurge
2024-02-17 05:22:08
Is there something wrong with just encoding HDR JPEG? So the gainmap is only there so that it can subjectively look better when viewed on a crappier monitor?
Quackdoc
2024-02-17 05:22:22
the gainmap is there so you can have a good SDR experience
2024-02-17 05:22:25
so yes
2024-02-17 05:22:44
HDR pictures actually have a **very low** base that actually consumes them
2024-02-17 05:25:22
and "General use" hdr is kinda... well very few people are actually pushing for it because windows' implementation is garbage, Apple's impl on ios and osx is... fine, but a small userbase would actually appreciate them. Wayland is doing some impressive work that may be ready 10 years from now. Android has been actively pushing for it for a long time and it's finally ready
2024-02-17 05:25:49
but now that it is a thing, hardly anyone actually wants to make HDR images because they look like trash on SDR displays which is most people
2024-02-17 05:26:30
google"s HDR stuff actually solves this issue out right
Demiurge
2024-02-17 05:37:07
But apparently there was already a standard for embedding gainmaps and they had to invent yet another one for android?
Quackdoc
2024-02-17 05:39:04
was there ever a "standard" for it?
2024-02-17 05:39:23
at least one somewhat agreed upon.
_wb_
2024-02-17 08:43:16
https://jpeg.org/jpegxt/index.html
2024-02-17 08:46:01
ISO/IEC 18477-2:2016 does exactly the same thing as UltraHDR, except with different syntax (instead of putting the gain map just concatenated to the SDR jpeg, it embeds the gain map in app markers inside the SDR jpeg).
Quackdoc
2024-02-17 08:53:24
isn't jpeg-xt patent encumbered though? i remeber seeing s licencing program for it, well considering it was from sisvel, its probably bogus lol
_wb_
Quackdoc isn't jpeg-xt patent encumbered though? i remeber seeing s licencing program for it, well considering it was from sisvel, its probably bogus lol
2024-02-17 09:24:45
Nope, it isn't. I assume the folks who came up with UltraHDR just didn't bother to check if it already existed.
spider-mario
2024-02-17 09:34:54
or they thought their approach provided some form of advantage
2024-02-17 09:35:00
(it’s just unclear what that is)
Quackdoc
2024-02-17 04:10:37
interesting. I thought it was encumbered, then yeah, best guess I have is that the current format allows them to expand support to any other format fairly easily I guess
Cacodemon345
2024-02-17 09:30:54
JPEG XT's reference library being GPLv3 may have played a part in Google's decisions.
2024-02-17 09:31:12
Also it being very unsupported everywhere.
spider-mario
2024-02-17 10:06:25
eh, it changed “reimplementing JPEG XT” into “implementing something else”
Demiurge
2024-02-18 07:23:56
Can jpeg xl have a gain map?
paperboyo
Demiurge Can jpeg xl have a gain map?
2024-02-18 07:30:11
Technically, probably docx could have 😜 . But, yeah: `https://helpx.adobe.com/content/dam/help/en/camera-raw/using/gain-map/jcr_content/root/content/flex/items/position/position-par/table/row-io13dug-column-4a63daf/download_section/download-1/Gain_Map_1_0d14.pdf#%5B%7B%22num%22%3A60%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C69%2C226%2C0%5D`.
_wb_
Demiurge Can jpeg xl have a gain map?
2024-02-18 07:33:39
There's a proposal by Eric Chan (Adobe), we're discussing it.
Demiurge
2024-02-18 07:33:48
Apple has been using heic for a long time. It's strange that android is still using JPEG for HDR instead of jpegxl
_wb_
Demiurge Apple has been using heic for a long time. It's strange that android is still using JPEG for HDR instead of jpegxl
2024-02-18 07:35:26
The big advantage of the UltraHDR approach is that it gracefully degrades with any old software. That's also its big disadvantage though imo, since it puts little incentive on old software to actually support it.
paperboyo
_wb_ The big advantage of the UltraHDR approach is that it gracefully degrades with any old software. That's also its big disadvantage though imo, since it puts little incentive on old software to actually support it.
2024-02-18 07:46:40
Agreed it seems to be both a blessing (if base is SDR only, though) and a curse (these maps left there unrotated by apps which didn’t even bother to strip them when rotating the base…). But leaving this, hairy, argument, it also promises something that I understand is uniquely better (?) about this approach. How beneficial are these (esp. local adaptation)?
2024-02-18 07:52:22
Unrelatedly, this went from “proposal” to production in no time. Only the other day, a friend asked me why his Pixel 7 “lights up” specular highlights in Photos app a split-second after it shows the base pic 😁 .
_wb_
2024-02-18 07:57:57
In my opinion, I think the better approach is to standardize a good tone mapping algorithm (can be local tone mapping) and not signal the tone mapping weights explicitly. Yes, in principle it allows artistic control over the tone mapping when they are signaled, but in practice I assume that in 99.9% of the cases people will just go with the default, which will be something algorithmically generated. To me, it breaks too many assumptions if you have one image that is actually two images: an SDR one and an HDR one, which can be completely unrelated in principle. Things like rotation and cropping are one thing, but I don't see how to implement generic image processing pipelines in a way that operates on both the HDR and SDR image in a way that somehow preserves the artistic intent.
2024-02-18 08:01:04
If you really want full control over the SDR rendition of an HDR image, just make two images and use css media queries. Just like you can have different images for e-readers or for the printed version of a website, if you want. But for the typical case, I would prefer if we can just serve an HDR image, and standardize how it will be rendered on less capable displays so there is consistency and predictability.
Demiurge
2024-02-18 08:14:04
The difference between a jpeg encoder and a jpegxl encoder is just the header, and the entropy coding, essentially, yeah?
spider-mario
2024-02-18 08:16:59
XYB, the predictors, the variable-size DCTs
lonjil
2024-02-18 08:46:09
modular subimages...
Quackdoc
_wb_ If you really want full control over the SDR rendition of an HDR image, just make two images and use css media queries. Just like you can have different images for e-readers or for the printed version of a website, if you want. But for the typical case, I would prefer if we can just serve an HDR image, and standardize how it will be rendered on less capable displays so there is consistency and predictability.
2024-02-18 08:47:46
But how viable is this really to standardize how tonemapping is done? There are "Standard tonemapping methods" for various industries, but even these aren't actually standard and keep changing. We used to use Aces, then some people started using reinhardt, and now a lot of people are using "Blender filmic" or tonymcmapface (I still chuckle at this name btw) which requires luts too. Game engines are constantly changing which tonemapper is used. It feels like the whole "tonemapping as a solution" is one of those things that sounds good in theory, but will always be significantly limiting in implementation. On the otherhand gainmaps are pretty much already tried and the results from them have been legitimately great.
_wb_
Quackdoc But how viable is this really to standardize how tonemapping is done? There are "Standard tonemapping methods" for various industries, but even these aren't actually standard and keep changing. We used to use Aces, then some people started using reinhardt, and now a lot of people are using "Blender filmic" or tonymcmapface (I still chuckle at this name btw) which requires luts too. Game engines are constantly changing which tonemapper is used. It feels like the whole "tonemapping as a solution" is one of those things that sounds good in theory, but will always be significantly limiting in implementation. On the otherhand gainmaps are pretty much already tried and the results from them have been legitimately great.
2024-02-18 08:52:55
I'm thinking something like ICC rendering intent could be used to signal a few options, possibly more could be added over time. The main issue right now is that everyone does something different so there is no way to have consistency of the SDR rendition. Consistency is the first step imo, and then you can decide if the default option(s) are good enough, or if something specific is still needed and you have to send an inverse gain map (or just two different images).
Quackdoc
2024-02-18 08:53:27
well, consistentcy in SDR isn't something we even have today because of sRGB vs gamma2.2 lol
_wb_
2024-02-18 08:56:50
The thing with gain maps is that it works as a delivery format, but what to do with it in a processing pipeline is much less clear. How do you apply sharpening or a text overlay to such an image in a way that makes sense?
lonjil
2024-02-18 08:58:55
Also, isn't it a bit more complicated than SDR vs HDR? If something was mastered on a 3000 nits display that has a certain very wide color gamut, but I'm watching it on a 1000 nit display with a narrow but still pretty wide gamut, well, the SDR gainmap version won't be right, but surely the HDR version will also require some kind of mapping, right?
_wb_
2024-02-18 08:59:35
Yes, the current gain map approach just interpolates between the two images in that case, which is a reasonable thing to do I guess
Quackdoc
2024-02-18 09:00:13
I do understand the potential issues for sure. I think discarding the gainmap is necessary if processing an already processed video. That or "Prerender" each photo so you have no choice but to work on either the SDR or HDR at a time, from there you could remake the gainmap I guess
lonjil Also, isn't it a bit more complicated than SDR vs HDR? If something was mastered on a 3000 nits display that has a certain very wide color gamut, but I'm watching it on a 1000 nit display with a narrow but still pretty wide gamut, well, the SDR gainmap version won't be right, but surely the HDR version will also require some kind of mapping, right?
2024-02-18 09:01:18
with something like PQ we can rely on absolute luminance for tonemapping, but yes, you need to tonemap a video with a peak 3k nit down to whatever your display is
2024-02-18 09:02:00
thankfully tonemapping within the same transfer is a lot easier then changing transfers
_wb_
2024-02-18 09:02:57
If the gain map contains artistic intent that was manually created (say, local tone mapping decisions), then you cannot just regenerate it after an edit/processing step. If it is automatically generated, then why signal it? It's better to signal how it was generated than to signal the result of the algorithm, because then the choice of method can be preserved across editing.
2024-02-18 09:04:39
(then again, signaling the result of the algorithm is future proof in the sense that it allows current decoders to render the result of future tone mapping algorithms)
Quackdoc
2024-02-18 09:04:49
If you have both the rendered HDR and the pre-rendered SDR couldn't you recreate the gainmap using that?
2024-02-18 09:05:05
I suppose it may not be so simply hmm
_wb_
2024-02-18 09:11:18
If you overlay, say, a logo on an image, this is well-defined if both layers are in the same colorspace, but say you do the actual alpha blending in the HDR space, how do you then decide what the SDR image is supposed to look like? You have the original tone mapping choices, but clearly they will have to be revised to take the editing into account. But in what way? Basically all image processing operations would need to get extra parameters for conveying how the operation should affect tone mapping choices.
2024-02-18 09:12:56
It's a mess if you really embrace the concept that the SDR image and the HDR image are both important, are not necessarily algorithmically related to one another, and both need to be preserved in a processing pipeline.
2024-02-18 09:13:13
So I would suggest not embracing that concept 🙂
Quackdoc
2024-02-18 09:18:04
well worst case scenario, it's more likely the editor will only work with either the SDR image or HDR image at one time, it's not super likely that an editor will allow editing "in place" and not mess up the gainmap, unless the editor itself supports gainmaps and stuff, at which point you are back to the standard gain map process. I don't really think that is too massive of an issue. the real issue would be if you were to edit an image, and export a SDR + HDR image without knowledge.
Demiurge
2024-02-19 11:04:00
So if they have some super special hdr jpeg encoder they could probably make it output jpegxl with a better entropy coder and more efficient container format. Then designing the perceptual model around XYB would be another win, and then adding other features like variable block sizes can be added too...
2024-02-19 11:04:37
Sorry, I posted this late. I mean if Google has a super special HDR jpeg encoder
2024-02-19 11:09:16
Basically it would not require a lot of changes to turn a jpeg encoder into a jpegxl encoder, since jpegxl is a similar format
lonjil
2024-02-19 11:13:06
What do you mean by super special HDR jpeg encoder?
Demiurge
2024-02-19 11:13:33
I believe google calls it "ultra hdr jpeg"
2024-02-19 11:14:08
They probably thought "super special" would be too much
jonnyawsom3
2024-02-19 11:14:16
Well, there was meant to be a jpeg compatible version of JXL, as seen in the middle of the 'cloud' https://res.cloudinary.com/cloudinary-marketing/image/upload/w_700,c_fill,f_auto,q_auto,dpr_2.0/Web_Assets/blog/transition_path.png
lonjil
Demiurge Basically it would not require a lot of changes to turn a jpeg encoder into a jpegxl encoder, since jpegxl is a similar format
2024-02-19 11:14:17
The more benefit you would want from JXL over jpeg, the more work making that JXL encoder would be.
Demiurge
2024-02-19 11:15:11
No existing encoder uses all of the available features of jpegxl format, and encoders can always be improved later, over time, to take advantage of more jpegxl-specific tricks. You would get immediate returns just by using better entropy coding.
lonjil
Well, there was meant to be a jpeg compatible version of JXL, as seen in the middle of the 'cloud' https://res.cloudinary.com/cloudinary-marketing/image/upload/w_700,c_fill,f_auto,q_auto,dpr_2.0/Web_Assets/blog/transition_path.png
2024-02-19 11:16:08
I think if you used jpegli and then did a lossless conversion to JXL it would be basically that.
jonnyawsom3
2024-02-19 11:16:37
Yeah, pretty much
lonjil
Demiurge No existing encoder uses all of the available features of jpegxl format, and encoders can always be improved later, over time, to take advantage of more jpegxl-specific tricks. You would get immediate returns just by using better entropy coding.
2024-02-19 11:16:59
But what does them having a jpeg encoder have to do with it? They're probably just using libjpeg-turbo anyway.
2024-02-19 11:17:12
If they wanted to use JXL, they'd just use libjxl
jonnyawsom3
2024-02-19 11:17:50
They need something to add the HDR gainmap to the jpeg, therefore they must have either a custom or forked encoder
lonjil
2024-02-19 11:18:01
The whole point of ultra HDR jpeg is that it works on all devices that already exist, and all software
They need something to add the HDR gainmap to the jpeg, therefore they must have either a custom or forked encoder
2024-02-19 11:18:42
It's just tacked on at the end, isn't it? And most encoders allow you to tack on whatever metadata you want.
Oleksii Matiash
lonjil The whole point of ultra HDR jpeg is that it works on all devices that already exist, and all software
2024-02-19 11:36:53
Until you want to edit it. I. e. it "works" just for viewing untouched HDR jpeg out of phone
lonjil
2024-02-19 11:41:12
Yes
Ufnv
2024-02-19 12:15:06
Hi! A quick question about JxlEncoderSetExtraChannelDistance - does it really work? I am trying to do lossy encoding (Distance 3.0) of the same file with JxlEncoderSetExtraChannelDistance(settings, 0, 0) and without it and get the same result...
2024-02-19 12:16:35
trying to do this to improve the decompression speed, as decoding lossy with alpha is really slow (6 times slower than webp, two times slower than without alpha)
jonnyawsom3
Ufnv Hi! A quick question about JxlEncoderSetExtraChannelDistance - does it really work? I am trying to do lossy encoding (Distance 3.0) of the same file with JxlEncoderSetExtraChannelDistance(settings, 0, 0) and without it and get the same result...
2024-02-19 12:25:05
If I recall Alpha is now Distance 0 by default already
Ufnv
2024-02-19 12:59:31
yes, looks like this is the case. Not that it helps much, though. Decoding is like 10% faster, while the file is 80% larger 😦
jonnyawsom3
2024-02-19 01:02:54
I assume you've tried the faster decoding flag?
Ufnv
I assume you've tried the faster decoding flag?
2024-02-19 01:15:15
it makes little sense as well. file size is much larger with marginal decoding speed improvements
2024-02-19 01:17:08
for now the best size/decoding speed combination for my data is default setting with 3.0 distance with 0.8.2 library
2024-02-19 01:18:15
the biggest surprise is how much slower it is comparing to webp
jonnyawsom3
2024-02-19 01:19:24
Oh, we're on 0.9.1, with 0.10.0 coming out in around a week. For 10 especially encoding speed is improved, haven't checked decoding actually...
Ufnv
2024-02-19 01:22:03
I find encoding with 0.9 something like 50-80% slower compared to 0.8, but encoding is not very important for me, as it is done once. Decoding speed really is important, will try 0.10 when it is out... Thanks!
jonnyawsom3
2024-02-19 02:16:31
Made an issue for it, since apparently it's stopping me from trying the streaming https://github.com/libjxl/libjxl/issues/3303
lonjil
2024-02-19 07:43:48
the code has some (in my opinion) lowkey funny lines ```c++ const int bit_depth = std::min(input.bitdepth, 24); ```
Traneptora
2024-02-19 08:17:46
seems like it would make more sense to just do something like
2024-02-19 08:18:01
```c int bit_depth = input.bitdepth < 24 ? input.bitdepth : 24; ```
2024-02-19 08:18:11
this can be accomplished with a cmov, whereas `std::min` is a function call
2024-02-19 08:18:25
C++ compiler may optimize it out tho
veluca
Traneptora C++ compiler may optimize it out tho
2024-02-19 08:21:38
it usually does yep
lonjil
2024-02-19 08:22:25
what I find funny that is that greater than 24 bits is allowed (since it apparently isn't an error) but it just silently gets reduced.
_wb_
2024-02-19 08:24:12
24 bit ought to be enough for everyone
2024-02-19 08:24:28
Just like 640 kb of RAM
Traneptora
2024-02-19 08:27:07
my family computer in the early 2000s had a second drive that was 4.5 GB and I remember thinking "there's no way I we'll ever fill that up"
2024-02-19 08:27:39
in hindsight that's kind of a strange drive size
_wb_
2024-02-19 08:27:57
But seriously, even at 14 bit the least significant bits are pretty much noise, I cannot really imagine use cases where you really have 24 bit data that is worth storing losslessly (i.e. not just 12 bits of real data plus 12 bits of noise)
Traneptora
2024-02-19 08:29:01
higher bit depth is relevant for TRC tho
2024-02-19 08:29:15
like linear -> sRGB etc.
_wb_
2024-02-19 08:29:36
Ah sure, while processing you need more bits
lonjil
2024-02-19 08:29:53
uhh maybe if I have details near zero nits that I need to preserve, as well as details near 500000 nits that I need to preserve. maybe not.
_wb_
2024-02-19 08:30:40
You can always define a weird sigmoid transfer curve and encode your images with that 🙂
spider-mario
2024-02-19 08:31:01
that would take quite a bit of bracketing (not sure many cameras can even do the amount of bracketing required), or a synthetic image
2024-02-19 08:31:41
for reference, 600k nits is “solar disk at horizon” according to wikipedia
2024-02-19 08:31:53
7 million nits is “filament of a clear incandescent lamp”
lonjil
2024-02-19 08:32:07
hm
2024-02-19 08:32:10
actually
Traneptora
2024-02-19 08:32:17
I wonder what the nitcount was of voyager I looking at the sun
spider-mario
2024-02-19 08:32:24
5 nits is roughly where colour vision starts to transition into “mesopic” (mixture of colour and night) vision
Traneptora
2024-02-19 08:32:45
https://science.nasa.gov/wp-content/uploads/2023/09/PIA00450_320.jpg
2024-02-19 08:32:50
this one
lonjil
2024-02-19 08:32:56
I've seen HDR photography of welding, that just tonemapped immediately to something useful, but I wonder if the full range data could be stored...
spider-mario
2024-02-19 08:32:58
(0.005 nits, roughly where “scotopic” i.e. night vision takes over)
lonjil
2024-02-19 08:33:29
welding can EXTREMELY bright, like sunburn in seconds levels of bright
Traneptora
2024-02-19 08:33:45
ye, that's why you have that welding mask
Quackdoc
lonjil welding can EXTREMELY bright, like sunburn in seconds levels of bright
2024-02-19 08:33:55
~~me looking directly at the torch when welding~~
Traneptora
2024-02-19 08:34:13
my younger brother is a welder and he took some welding protective glass from work with him when we went to go see a solar eclipse
lonjil
2024-02-19 08:34:15
I got sunburned on my eyelids when I did a quick weld without the mask
spider-mario
2024-02-19 08:34:43
that sounds painful
Quackdoc
2024-02-19 08:35:31
welding is weird, it's one of those odd things you can actually get used to, well pain wise. it's never good for you, but the amount of times me and the guys would just weld with the mask up and just not caring is not small
_wb_
2024-02-19 08:36:01
I guess there might be astronomy data that has huge range — but I dunno what kind of precision they can get from their instruments, maybe it's basically just data with a very steep transfer curve
Traneptora
2024-02-19 08:36:32
ye, especially when you're looking at images of deep space that may have a nearby star
lonjil
2024-02-19 08:37:05
with astronomy you sometimes have many exposures, possibly with different filters
2024-02-19 08:37:27
so the level of precision can be much larger than in typical photography, though to what degree I'm not sure
Traneptora
2024-02-19 08:37:38
https://cdn.esahubble.org/archives/images/screen/opo9601c.jpg I imagine an image like this one is modified with some sort of tone mapping
2024-02-19 08:37:54
the stars are probably extremely bright compared to the galaxies in the background
lonjil
2024-02-19 08:40:10
I guess if anyone needs that many bits they'll continue using J2K?
Traneptora
2024-02-19 08:40:16
38 bits ye
lonjil
2024-02-19 08:41:10
I just find it funny/odd that it's allowed but not actually supported in JXL to use a value greater than 24 bits. Does the standard actually say 32 bits, but libjxl only supports 24? I don't recall.
_wb_
2024-02-19 08:48:01
Level 10 allows 24 bit uint, or float with up to 23 mantissa bits (plus one implicit mantissa bit), 8 exp bits and 1 sign bit, i.e. anything that fits in a single precision float.
2024-02-19 08:48:34
We drew the line there because then you can just use float32 buffers for everything and it will work
2024-02-19 08:49:12
Header syntax allows up to 64-bit but that's outside current profiles/levels and libjxl does not implement that.
lonjil
2024-02-19 08:50:09
mm. And using floating point math for everything works well? I know it's supposed to, but still.
_wb_
2024-02-19 08:50:14
I dunno how j2k ended up with a weird limit like 38-bit, it makes little sense to me tbh.
veluca
lonjil mm. And using floating point math for everything works well? I know it's supposed to, but still.
2024-02-19 08:51:19
... define well
_wb_
lonjil mm. And using floating point math for everything works well? I know it's supposed to, but still.
2024-02-19 08:51:49
I mean, we do use int32 for the modular parts and only translate to float32 when converting to the generic frame format (where frame blending and spline drawing etc happens)
lonjil
veluca ... define well
2024-02-19 08:52:03
as precise as an actual 24-bit integer implementation, when you have 24-bit integers?
veluca
2024-02-19 08:52:17
depends on what you do
_wb_
2024-02-19 08:52:18
But yeah, float32 does represent 24-bit ints exactly
veluca
2024-02-19 08:52:30
if you do EPF, probably not
2024-02-19 08:52:48
things like DCT also will likely mess up some of the lower bits
2024-02-19 08:52:59
(but then an integer DCT would need more bits)
lonjil
2024-02-19 08:53:58
Conceptually, VarDCT works on reals anyway though, right? While modular is specified in terms of integers.
_wb_
2024-02-19 08:54:05
Yes
veluca
2024-02-19 08:54:08
yup
_wb_
2024-02-19 08:54:56
Well everything is specified in reals, but within the modular parts those reals happen to be integers 🙂
lonjil
2024-02-19 08:55:04
😄
2024-02-19 08:55:24
30 years from now, JPEG XXL will allow for up to 113 bits, to allow the use of binary128 buffers...
Traneptora
_wb_ I dunno how j2k ended up with a weird limit like 38-bit, it makes little sense to me tbh.
2024-02-19 09:50:35
dicom requires full byte coded entries and it's coded as 40
2024-02-19 09:51:31
iirc the two bits are lost in an RCT