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

Kleis Auke
2023-01-12 02:39:44
AFAIK, the only drawback of the CLA used by libjxl is that it requires a Google account to sign it. I'm aware that this caused issues on other projects, see e.g. <https://github.com/protocolbuffers/protobuf/pull/8710#issuecomment-856879761>.
Demiurge
spider-mario of course, if it’s unmodified, it’s rather pointless since the original is still available under just the BSD license’s restrictions (i.e. not much)
2023-01-12 02:41:12
That's what I was trying to explain.
_wb_ As far as I understand (but IANAL), the CLA serves two main purposes: - copyright: your contribution is not just BSD-3 licensed, we also can relicense it under another (even more permissive) license should the need arise. We already did that once when relicensing from Apache 2.0 to BSD-3. Relicensing without CLAs means we need to track all contributors and get their permission, which tends to be problematic when some contributors are no longer reachable. Since BSD-3 is already about as permissive as it gets (and seems to be acceptable to e.g. Adobe and Serif), I don't think there will be a need to relicense, but you never know. - patents: by signing the CLA, you also grant a patent license under the same conditions as Google and Cloudinary granted their patents (royalty-free, with a defensive clause). Should your contribution contain anything you don't just have copyright on but also patents, this is important, since the BSD-3 license is only a copyright license that does not say anything about patents. We need to ensure that no contribution accidentally or intentionally injects patent-encumbered things into libjxl. The CLA helps prevent that. I agree that the CLA is a bit of an annoying obstacle for new contributors, but I think it's there for good reasons.
2023-01-12 02:42:40
It makes sense considering that the license was already changed from Apache to BSD before. There are few licenses that are more permissive than 3 clause BSD though
_wb_
2023-01-12 02:50:17
Agreed. I think at this point it's mostly a safeguard to prevent introducing patent-encumbered techniques. Not foolproof of course, since an external troll who did not sign the CLA can always show up and make claims, but at least we can be sure that contributors are not sneaking in things they themselves have patents on so they can then later start asking royalties.
Demiurge
2023-01-12 02:59:57
That would be pretty silly. And not very consequential. libjxl is just an example implementation of how to implement an encoder/decoder library.
afed
2023-01-12 03:13:12
would be good to have a fix for palette detection for -e 1 before the 0.8 release https://discord.com/channels/794206087879852103/794206087879852106/1060234070409347173
Demiurge
2023-01-12 07:34:09
I tried compiling fast-lossless and apparently it depends on libgcc_s.so.1 - wouldn't it make more sense for it to statically link this library for performance reasons?
veluca
Demiurge I tried compiling fast-lossless and apparently it depends on libgcc_s.so.1 - wouldn't it make more sense for it to statically link this library for performance reasons?
2023-01-12 07:54:19
wait, what?
2023-01-12 07:54:39
did you use the bash script?
2023-01-12 07:54:50
if so you could try adding a `-static` there and see what happens
improver
2023-01-12 08:14:47
static linking is needlessly hard on linux tbh
Demiurge
2023-01-12 08:15:33
I'm on Arch Linux using the build.sh script, yeah. Using clang. Seems weird that libgcc would be dynamic and not static
2023-01-12 08:15:47
adding `-static-libgcc` does nothing
improver
2023-01-12 08:16:11
is it added in all the places where it's needed to be added i wonder
Demiurge
2023-01-12 08:16:19
actually is it strange that clang is using libgcc?
improver
2023-01-12 08:16:32
nah that part isn't that strange
Demiurge
2023-01-12 08:16:45
I would think clang would have its own similar runtime
improver
2023-01-12 08:16:46
i think for C++ code there's one more flag
2023-01-12 08:16:48
u need to use
2023-01-12 08:17:04
`-static-libstdc++`
Demiurge
2023-01-12 08:17:37
ok but I doubt that would make as much a performance impact as libgcc
improver
2023-01-12 08:17:56
i'm not sure why are you talking about performance impact here
Demiurge
2023-01-12 08:18:20
well it's called fast-lossless, it's supposed to be fast...
improver
2023-01-12 08:19:15
i think that libstdc++ being dynamic ends up pulling in dynamic libgcc too
2023-01-12 08:20:02
either way i can't see static compilation doing much either way
2023-01-12 08:20:31
there in theory (i haven't looked) shouldn't be a lot of standard library calls on hot paths
Demiurge
2023-01-12 08:21:53
Heeeeey, that did the trick <@260412131034267649> thanks!
improver there in theory (i haven't looked) shouldn't be a lot of standard library calls on hot paths
2023-01-12 08:22:24
Yeah, but libgcc is not standard library. It's processor instruction emulation
2023-01-12 08:22:34
Which ideally you would want to be inlined
2023-01-12 08:22:45
I would assume
improver
2023-01-12 08:22:46
isn't it already?
Demiurge
2023-01-12 08:23:15
I assume not if it's dynamically linking to libgcc
improver
2023-01-12 08:23:21
intristics and builtin perf critical functions i would assume should be static inline in headers
Demiurge
2023-01-12 08:24:19
Then why do most of the packages installed on my Arch box require libgcc?
improver
2023-01-12 08:24:46
because pretty much all of them use some library calls for IO
Demiurge
2023-01-12 08:24:58
IO would be in libc
improver
2023-01-12 08:25:08
oh. hmm
Hello71
2023-01-12 08:25:17
libgcc provides a number of different functions, mainly certain math functions and unwinding
Demiurge
2023-01-12 08:25:26
libgcc seems to be a low level library for CPU instruction emulation
Hello71
2023-01-12 08:25:28
it's not really "processor instruction emulation"
Demiurge
2023-01-12 08:26:11
Maybe other low level functions that the compiler inserts into programs
2023-01-12 08:26:31
It's a low level runtime for the compiler to use and looks like something that is not meant to be dynamically linked
Hello71
2023-01-12 08:27:22
libgcc_s is the shared library, the gcc toolchain will link it when necessary
Demiurge
2023-01-12 08:27:58
I was using the clang toolchain...
Hello71
2023-01-12 08:28:06
for example, libstdc++ requires stack unwinding which is implemented in libgcc
2023-01-12 08:28:59
libgcc is arch-specific, libstdc++ is (theoretically) arch-independent
Demiurge
2023-01-12 08:29:56
Yeah I guess like dec said libstdc++ was depending on that since it's part of the GNU toolchain and clang was linking to libstdc++ for some reason because I guess that's how Arch is set up
2023-01-12 08:33:38
It's funny that Arch Linux used to pride itself as "the most BSD-like Linux" and absolutely nothing about it is BSD-like anymore...
improver
2023-01-12 08:35:13
it's kinda wild-west version of fedora now
2023-01-12 08:35:51
not that it's a bad thing
Hello71
2023-01-12 08:41:29
clang uses libstdc++ by default because it used libstdc++ for many years because libc++ did not exist, and also because libc++ is not ABI-compatible with libstdc++ so if you default to libc++ then you can't link against any system C++ libraries
veluca
2023-01-12 08:58:45
I doubt statically linking changes performance in any way 🙂
Demiurge
2023-01-12 09:36:18
Well depends on how much the symbols are actually used I guess
2023-01-12 09:37:55
Veluca should I write a makefile for you so you don't need to use build.sh anymore? :)
veluca
2023-01-12 10:21:20
I can write makefiles 😛 I don't remember why I chose not to, there was a reason... (Possibly me not being super comfortable with the idea of doing wget in a makefile)
Demiurge
2023-01-12 11:15:59
Well you're using curl so you should be a ok :)
Traneptora
Demiurge I tried compiling fast-lossless and apparently it depends on libgcc_s.so.1 - wouldn't it make more sense for it to statically link this library for performance reasons?
2023-01-13 01:36:58
why would you want to do that
Demiurge
2023-01-13 01:46:15
Because they're low level routines that might be called often
2023-01-13 01:46:25
at least that's what it looks like libgcc is
2023-01-13 01:46:34
looks like stuff that is meant to be inlined
Traneptora
2023-01-13 01:51:10
if it's stuff that should be inlined that makes sense but only if it's compiled like so, just statically linking a libgcc.a won't do that
2023-01-13 01:51:33
since that ends up stripping things like "inline" keywords in C
2023-01-13 01:51:43
which routines did you have in mind though?
Demiurge
2023-01-13 02:08:39
I'm not terribly familiar with gcc's helper library but it looks like it's meant to contain low level routines that are meant to be embedded in the binaries GCC creates
sklwmp
2023-01-13 03:13:52
How do you get the JNI to build? I can't seem to get it to build on the latest git master.
2023-01-13 04:10:12
Nevermind, I had to run `sudo archlinux-java set java-19-openjdk` because it was defaulting to the Java 8 JRE.
Demiurge Is there a way to have `make test` use all of my CPU cores? It seems to only be running 1 test at a time even though `make build` is multi core.
2023-01-13 06:29:32
I couldn't figure that out, since ninja also seems to use just one core... I just end up running `ctest` directly. FWIW, those two tests only fail when `-Wp,-D_GLIBCXX_ASSERTIONS` is passed. Without it, it's fine. And on the latest commit, all tests seem to pass fine even with the flag.
Demiurge
2023-01-13 07:12:33
Oh, so I'm not the only one.
2023-01-13 07:20:33
<@179701849576833024> Here ya go, it's pretty similar to your build.sh ```makefile CXX = clang++ CXXFLAGS = -O3 -march=native -mtune=native LDFLAGS = -flto -static-libgcc -static-libstdc++ OBJDIR = ./build TARGET = fjxl _GITHUB = https://raw.githubusercontent.com/lvandeve/lodepng/$(_COMMIT) _COMMIT = 8c6a9e30576f07bf470ad6f09458a2dcd7a6a84a OBJ = $(OBJDIR)/enc.o $(OBJDIR)/main.o $(OBJDIR)/lodepng.o $(OBJDIR)/$(TARGET): $(OBJ) $(CXX) $(LDFLAGS) $(OBJ) -o $(@) $(OBJDIR)/enc.o: ../../lib/jxl/enc_fast_lossless.cc $(CXX) -I$(OBJDIR) -I../../ $(CXXFLAGS) -c -o $(@) $(<) $(OBJDIR)/main.o: fast_lossless_main.cc $(CXX) -I$(OBJDIR) -I../../ $(CXXFLAGS) -c -o $(@) $(<) $(OBJDIR)/lodepng.o: $(OBJDIR)/lodepng.cpp $(CXX) $(CXXFLAGS) -c -o $(@) $(<) # lodepng retrieval $(OBJDIR)/lodepng.{cpp,h}: objdir curl -o $(@) --url $(_GITHUB)/$(@F) $(OBJDIR)/lodepng.cpp: $(OBJDIR)/lodepng.h objdir: mkdir -p "$(OBJDIR)" .phony: objdir ```
2023-01-13 07:23:56
It's not very standards compliant or anything, it could be better.
2023-01-13 07:28:47
Actually, funny story. I used < because I originally wrote inference rules.
2023-01-13 07:31:11
For some reason they did not work, maybe due to a bug in GNU make or something, so I changed them all to target rules but forgot to change `$(<)` since that isn't standards compliant.
2023-01-13 07:31:39
But it worked as intended anyways
2023-01-13 07:33:02
For some reason if a target and a prerequisite are not in the same directory, make is behaving as if the inference rules don't exist.
JendaLinda
2023-01-13 10:31:55
cjxl can read sBIT chunk in PNG and encodes JXL accordingly. The correct bit depth is printed by jxlinfo. However djxl won't recreate sBIT chunk when decoded to PNG.
_wb_
2023-01-13 10:45:09
Please open an issue - should be easy enough to fix
sklwmp
2023-01-13 01:19:19
From: https://github.com/libvips/libvips/issues/3132 Is a streaming decode API not available yet? I know progressive decode is available, but is that different from streaming? Sorry, I don't really know the technical details of most image formats, I'm just a normal user for the most part.
veluca
2023-01-13 01:24:06
there's plenty of streaming decode options 🙂
_wb_
2023-01-13 01:46:06
Just no streaming encode yet. Decode is streaming already for a while (though there's no cropped decode option yet)
JendaLinda
_wb_ Please open an issue - should be easy enough to fix
2023-01-13 03:51:32
I will. cjxl ignores sBIT if different channels are said to have different bit depths but that seems to be intentional.
Demiurge
_wb_ so I suppose it depends on the quality: at high enough quality where the 'bleeding' of Y (from YCbCr) into X and B ends up getting costly, it might be better to stay in YUV — just like when doing lossless, it will be better to store it as lossless yuv420 than converting to rgb and storing that losslessly.
2023-01-13 08:57:05
libjxl is currently tuned for the most part for high fidelity. So it would be nice if libjxl could be given a buffer of YUV-coded data and produce YUV JXL at high fidelity lossy targets.
2023-01-13 08:58:19
Not sure how useful it will be in practice... Maybe it would benefit mpv usage.
2023-01-13 09:00:36
If there are any mpv developers here maybe they would know more
2023-01-13 11:32:14
Is there ever a situation where effort > 7 should ever be used (for lossy mode)?
2023-01-13 11:34:43
Effort 8 and 9 are mostly there for "lol just because" reasons right? For VarDCT it's next to useless or am I wrong?
Traneptora
2023-01-13 11:40:56
as far as I'm aware e8 uses buttleraugli but e7 just uses heuristics to estimate distance
2023-01-13 11:41:08
e9 has minimal improvement over e8 so it's not useful
2023-01-13 11:41:24
but e8 over e7 is actually useful
afed
2023-01-13 11:44:58
effort 8 is slightly better, also it is better to match the specified quality, because using real butteraugli calculations, instead of approximate, if I understood correctly
Demiurge
2023-01-14 01:37:19
Alright. Still -e7 seems to really be the best possible speed/compression tradeoff both for lossy and for lossless, especially when using multiple threads.
Fraetor
2023-01-14 02:27:38
That's why it is the default.
Demiurge
2023-01-14 03:55:07
Yup. Very good default. Too bad https://github.com/Blobfolio/refract hard-codes effort=9 with no way to change this aside from recompiling.
2023-01-14 03:56:36
This is also from the same guy that complains that JXL is too slow. I wonder if anyone has ever told this guy that there's a good reason why 7 is the default setting.
yurume
Demiurge Yup. Very good default. Too bad https://github.com/Blobfolio/refract hard-codes effort=9 with no way to change this aside from recompiling.
2023-01-14 04:15:33
Oh that's really bad.
2023-01-14 04:16:03
Will look at the issues once I went through this session of dental clinic.
2023-01-14 04:33:17
Do they use the same kind of extreme setting for other encoders?
Demiurge
2023-01-14 04:35:25
Yes
2023-01-14 04:35:31
Always the slowest option
yurume
2023-01-14 04:35:58
For avif they explicitly avoid speed 0 because it's too slow for little benefit, maybe the same can be said for jxl effort 9
Demiurge
2023-01-14 04:41:27
Wow you're right, there's a comment saying "There is a speed 0, but ... brutally slow" for "very little benefit."
2023-01-14 04:42:19
AFAIK there is very little benefit (maybe 2%?) of going above e7
2023-01-14 04:42:27
Even less benefit than avif
veluca
2023-01-14 11:17:36
for compressing photographic content, I'd actually just use e6
2023-01-14 11:17:47
in most cases
2023-01-14 11:19:19
or e8 if you're willing to make it 10x slower for a couple % of gains
_wb_
2023-01-14 11:42:31
Besides patches, what's the difference between e6 and e7 that makes e7 slower?
2023-01-14 11:44:29
Maybe we should do patches at e6 already and make that the new default? Assuming patches is not what makes most of the difference (at least on photos)...
veluca
2023-01-14 12:27:18
patches are very slow for no benefit on photo
2023-01-14 12:31:32
(as in they easily take 25% of the encoding time)
2023-01-14 12:40:55
other than that, the main difference is that -e 7 quantizes differently and has a different way of computing CfL, both of which I think have somewhat limited benefits
_wb_
2023-01-14 01:13:58
can we speed up patch detection? I mean in particular in the case where there are none. And is it mostly the is_screenshot type patches or the dot detection that is slow?
veluca
2023-01-14 01:24:08
dot detection doesn't run at high enough q
2023-01-14 01:24:24
unless we changed that, but I don't think we did
2023-01-14 01:24:40
can we speed it up? probably
_wb_
2023-01-14 01:30:09
Maybe some cheap photo/nonphoto heuristic (say looking at a few rows per group) and only do the full patch detection if the overall image looks sufficiently nonphoto. And then probably there is some room to speed that up too, I dunno how simdified and threaded it is atm...
veluca
2023-01-14 01:43:26
Not too much
2023-01-14 01:43:40
In particular it's not SIMDfied at all
Demiurge
2023-01-14 09:59:20
from benchmarking.md: squirrel (default) enables dots, patches, and spline detection, and full context clustering
2023-01-14 09:59:36
didn't know there was spline detection
veluca
2023-01-14 10:56:35
there isn't
2023-01-14 10:56:41
don't trust that file 😛
Demiurge
2023-01-15 01:25:22
Okay I've been playing around with gmake and bmake and I think I understand why no one wants to use this terrible garbage
2023-01-15 01:25:51
Then again not all of it is make's fault
2023-01-15 01:26:54
Just trying to use it for a use case that it's not designed for such as a separate objdir and srcdir
2023-01-15 01:27:34
But it does seem overall unreasonably bad
zamfofex
2023-01-15 01:28:31
I’unno, makefiles have always worked well enough for me. 🤔
Demiurge
2023-01-15 01:33:36
Hmm, then can you explain to me what is wrong with this makefile? ```make CXX = clang++ CXXFLAGS = -O3 -march=native -mtune=native LDFLAGS = -flto -static-libgcc -static-libstdc++ OBJDIR = ./build TARGET = fjxl _GITHUB = https://raw.githubusercontent.com/lvandeve/lodepng/$(_COMMIT) _COMMIT = 8c6a9e30576f07bf470ad6f09458a2dcd7a6a84a $(OBJDIR)/$(TARGET): $(OBJ) $(CXX) $(LDFLAGS) -o $(@) $(OBJ) OBJ = $(OBJDIR)/enc.o $(OBJDIR)/main.o $(OBJDIR)/lodepng.o $(OBJDIR)/enc.o: ../../lib/jxl/enc_fast_lossless.cc mkdir -p "$(OBJDIR)" $(CXX) -I../../ $(CXXFLAGS) -c -o $(@) $(?) $(OBJDIR)/main.o: fast_lossless_main.cc mkdir -p "$(OBJDIR)" $(CXX) -I$(OBJDIR) -I../../ $(CXXFLAGS) -c -o $(@) $(?) $(OBJDIR)/lodepng.o: $(OBJDIR)/lodepng.cpp $(CXX) $(CXXFLAGS) -c -o $(@) $(?) # lodepng retrieval $(OBJDIR)/lodepng.cpp $(OBJDIR)/lodepng.h: mkdir -p "$(OBJDIR)" curl -o $(@) --url $(_GITHUB)/$(@F) ```
veluca
2023-01-15 01:34:12
don't you need to swap the _GITHUB and _COMMIT lines?
Demiurge
2023-01-15 01:34:37
both bmake and gmake know how to build all the targets if the targets are specified explicitly on the command line. But they seem to not have any clue about dependency.
2023-01-15 01:34:50
And no, variables are evaluated as-needed in makefiles
2023-01-15 01:35:12
If i run gmake or bmake, it tries to build fjxl right off the bat and immediately fails.
2023-01-15 01:35:26
But if you explicitly tell it to build each target in order of dependency it works
2023-01-15 01:36:18
The Makefile specifies a dependency tree which is utterly ignored.
veluca
2023-01-15 01:36:22
my guess would be that it would work moving the OBJ = line above the definition of the first target
Demiurge
2023-01-15 01:37:03
actually hold on I realized I made a mistake here while I was editing
2023-01-15 01:37:41
veluca I think that might actually have done the trick
veluca
2023-01-15 01:37:57
I mean, in general, not much of a point defining the OBJ variable no? it's used in only one place anyway
Demiurge
2023-01-15 01:38:17
Yeah it's just tradition I guess
veluca
2023-01-15 01:38:22
(and in the recipe you can put some automatic variable I don't remember the name of)
2023-01-15 01:38:42
ah, `$?`
Demiurge
2023-01-15 01:39:12
It's on two lines actually
2023-01-15 01:39:15
obj
veluca
2023-01-15 01:39:42
``` $(OBJDIR)/$(TARGET): $(OBJDIR)/enc.o $(OBJDIR)/main.o $(OBJDIR)/lodepng.o $(CXX) $(LDFLAGS) -o $(@) $(?) ```
2023-01-15 01:39:46
wouldn't that work?
Demiurge
2023-01-15 01:40:29
No because $? only lists OOD prerequisites, not all
veluca
2023-01-15 01:40:55
ah you're right
Demiurge
2023-01-15 01:40:57
So if only one file changes it won't be able to build fjxl with an incomplete list of objects
2023-01-15 01:41:05
Yeah, it's pretty sad
veluca
2023-01-15 01:41:07
`$^` perhaps
Demiurge
2023-01-15 01:41:10
I made some changes
2023-01-15 01:41:28
```make CXX = clang++ CXXFLAGS = -O3 -march=native -mtune=native LDFLAGS = -flto -static-libgcc -static-libstdc++ OBJDIR = ./build TARGET = fjxl _GITHUB = https://raw.githubusercontent.com/lvandeve/lodepng/$(_COMMIT) _COMMIT = 8c6a9e30576f07bf470ad6f09458a2dcd7a6a84a OBJ = $(OBJDIR)/enc.o $(OBJDIR)/main.o $(OBJDIR)/lodepng.o $(OBJDIR)/$(TARGET): $(OBJ) $(CXX) $(LDFLAGS) -o $(@) $(OBJ) $(OBJDIR)/enc.o: ../../lib/jxl/enc_fast_lossless.cc mkdir -p "$(OBJDIR)" $(CXX) -I../../ $(CXXFLAGS) -c -o $(@) $(?) $(OBJDIR)/main.o: fast_lossless_main.cc $(OBJDIR)/lodepng.h mkdir -p "$(OBJDIR)" $(CXX) -I$(OBJDIR) -I../../ $(CXXFLAGS) -c -o $(@) fast_lossless_main.cc $(OBJDIR)/lodepng.o: $(OBJDIR)/lodepng.cpp $(CXX) $(CXXFLAGS) -c -o $(@) $(?) # lodepng retrieval $(OBJDIR)/lodepng.cpp $(OBJDIR)/lodepng.h: mkdir -p "$(OBJDIR)" curl -o $(@) --url $(_GITHUB)/$(@F) ```
2023-01-15 01:41:48
It works is OBJ is defined early
2023-01-15 01:42:06
If OBJ is defined before the fjxl rule it does not work.
2023-01-15 01:42:14
That is what was causing the bad behavior
veluca
2023-01-15 01:42:36
I'm not entirely surprised 😄 old enough tools operate pretty much single pass
Demiurge
2023-01-15 01:42:49
Also I have to have lodepng.h as a dependency otherwise it won't be fetched if it is not needed. Anyways this makefile works perfectly now including with parallel make
veluca
2023-01-15 01:43:26
check this out: https://github.com/veluca93/magic_makefile
Demiurge
2023-01-15 01:43:31
$^ is a GNUism. On BSD the macro $> does the same thing
2023-01-15 01:44:08
Which is really annoying... One of them just needs to support both
veluca
2023-01-15 01:44:36
... stuff like that is the main reason I have to use either `sh` or `cmake` 😛
Demiurge
2023-01-15 01:44:44
Right now they support just one or the other. Would be nice if gmake adds support to $> as an alias for $^
2023-01-15 01:45:40
Actually I can probably figure out a trick to use it in a way that works on both...
2023-01-15 02:06:17
Well anyways that makefile does exactly what your build.sh does except more parallel and it creates object files for main and enc_fast_lossless before linking.
2023-01-15 02:07:04
Hope you like it. WTFPL and CC0 and whatever else you like, I waive all rights to the shitty makefile
2023-01-15 02:07:17
:)
veluca check this out: https://github.com/veluca93/magic_makefile
2023-01-15 06:38:55
I have been comparing the features and syntax of bsd make vs gnu make. I have come to the conclusion that all the fancy nonstandard conditional functionality in makefiles is better off being avoided completely. While it's fun and tempting to see what you can do and push the limits as far as possible, after you're done you should realize you created something that no one should ever attempt to use and should rewrite the whole thing as plain and simple and basic as possible with absolutely no smart conditional logic whatsoever
2023-01-15 06:40:32
And then you'll see the "stupid" makefile is a lot less lines and a lot easier for you and everyone else to debug and a lot less time wasted :)
2023-01-15 06:41:34
Basically everything that's not here should not be used: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
2023-01-15 06:45:24
Not because POSIX is particularly "good" or anything like that. But just because as soon as soon as you introduce complex logic into a makefile you are about to waste too much time with the build system.
2023-01-15 06:46:25
In practice you and everyone else forced to use your build system end up wasting way less time making the makefile as stupid as possible rather than as smart as possible
2023-01-15 06:47:54
At least that's just what I've noticed.
JendaLinda
2023-01-15 02:37:05
Despite JXL not packing pixels, images with low bit depth produce usually smaller files than the equivalent files using full 8 bits. Bit depth is expanded by multiplying rather than bit manipulations. For 2 bit and 4 bit it ends up with the same exact values like bit manipulations would, so it works out very well. When encoding an 8 bit picture marked as lower bit depth, it seems the LSBs are removed, although I couldn't figure out where in the code it's done.
improver
2023-01-15 03:09:09
could name the file GNUmakefile to force BSD users to use gmake
_wb_
JendaLinda Despite JXL not packing pixels, images with low bit depth produce usually smaller files than the equivalent files using full 8 bits. Bit depth is expanded by multiplying rather than bit manipulations. For 2 bit and 4 bit it ends up with the same exact values like bit manipulations would, so it works out very well. When encoding an 8 bit picture marked as lower bit depth, it seems the LSBs are removed, although I couldn't figure out where in the code it's done.
2023-01-15 05:02:59
It's here: https://github.com/libjxl/libjxl/blob/main/lib/jxl/enc_modular.cc#L569
2023-01-15 05:05:09
Basically 6-bit images get converted to range 0..63 and entropy coding will benefit from the symbol range being smaller.
2023-01-15 05:06:08
We can effectively even do non-integer bitdepths, since the channel palette transform can compactify the ranges.
2023-01-15 05:08:39
So say you have an 8-bit image but some values don't occur (this can happen e.g. when changing the contrast/brightness of an 8-bit image), so there are some holes in the range and it's effectively only a 7.5-bit image.
2023-01-15 05:10:46
Then channel palette can remove the holes and turn the range into 0..200 or whatever. And for entropy coding, that will be better than keeping the range 0..255 but with holes in it (especially when doing RCTs and/or prediction).
JendaLinda
2023-01-15 05:13:52
That's what I thought. If palette is used, I thought there shouldn't be difference between 2bit 0, 1, 2, 3 and 8bit 0, 85, 170, 255.
2023-01-15 05:15:13
Although the palette itself has to be encoded, so that could make the difference.
_wb_
2023-01-15 05:19:13
That's quite compact, since the palettes themselves are also treated like a 1D image (or not quite 1D, it's nb_colors x nb_channels, but for channel palettes that's 1D) and compressed. So especially if there's some structure in it, it will compress well.
2023-01-15 05:21:36
E.g. if you take an 8-bit image but convert it to 16-bit and encode it like that, the channel palette will be basically a 16-bit 256x1 image with a very regular gradient in it, which should compress to just a few bytes.
2023-01-15 05:23:33
(I suppose you could the experiment and see what's the difference in size between an 8-bit image and the same image but encoded as a 16-bit image, it should be small).
JendaLinda
2023-01-15 05:28:51
So the palettes are used for sample values in the individual channels, not for the whole pixels? I didn't know that.
_wb_
2023-01-15 05:31:49
No, both can be done
2023-01-15 05:32:16
Palettes can be applied to N number of channels
2023-01-15 05:36:28
Channel palettes (where N=1 and the palette transform is applied multiple times) are useful for these bitdepth-type things, but they keep the number of channels the same so for things like gif/png8 palettes, we use palette with N=3 or N=4. Palette represents N channels using 1 channel with palette indices (and 1 metachannel of dimensions nb_colors x N to represent the palette itself).
JendaLinda
2023-01-15 05:42:02
Alright. And if let's say 4 bit/channel image is encoded, the palette is 4 bits, but the palette indices can be as wide as needed or are those also limited to 4 bits?
sklwmp
2023-01-15 06:07:41
Not sure if this is a libjxl bug or in the specification, but the transfer functions are documented differently (https://github.com/libjxl/libjxl/blob/f5d6e2922820d5862f0334cf1e15d5d9eed6ff1a/lib/include/jxl/color_encoding.h#L82):
2023-01-15 06:13:09
Also, does the specification really state that the transfer function for 709 have to be 1/0.45? It seems like the recommendation is actually to use BT.1886 (gamma 2.4) since the Rec. 709 spec doesn't actually specify a transfer function *to* display things.
Demiurge
improver could name the file GNUmakefile to force BSD users to use gmake
2023-01-15 06:35:21
Or you could just write plain and simple makefiles without overcomplicating things with cool-looking features that in practice just end up eating up more time than they are worth.
improver
2023-01-15 06:47:10
you do it if you want to do it that way. lead others by example
2023-01-15 06:48:03
if your simple features are so convenient to use and maintainable i'm sure people will accept your changes
_wb_
JendaLinda Alright. And if let's say 4 bit/channel image is encoded, the palette is 4 bits, but the palette indices can be as wide as needed or are those also limited to 4 bits?
2023-01-15 06:48:16
Palette indices can be as wide as needed. I don't remember what the limit is of nb_colors that can be signaled, there is some limit but it's quite high.
sklwmp Also, does the specification really state that the transfer function for 709 have to be 1/0.45? It seems like the recommendation is actually to use BT.1886 (gamma 2.4) since the Rec. 709 spec doesn't actually specify a transfer function *to* display things.
2023-01-15 06:51:21
Ah, that's a good point about rec709 not actually giving a gamma value. Can you raise it in <#1021189485960114198> too so we don't forget?
2023-01-15 06:55:25
I guess for kPQ, the SMPTE and ITU-R reference should boil down to the same thing, right? In the spec I think we prefer ITU references since the J in JPEG is because it's working under both ISO/IEC and ITU.
zamfofex
2023-01-15 07:38:22
Is there some way to disable multithreading in `cjxl`? I’m using a makefile for my project, which already has inbuilt concurrency.
afed
2023-01-15 07:40:21
`--num_threads=0`
zamfofex
2023-01-15 07:43:08
I see! 🤔 Is there a difference between that and `--num_threads=1`? I guess I should have checked the manpage, but I thought it’d have been in `--help`.
_wb_
2023-01-15 07:50:26
I suppose in current cjxl/djxl it's --num_threads=1
2023-01-15 07:51:12
(i think setting it to 0 makes it use the default number of threads now, which is generally more than 1)
afed
2023-01-15 07:53:02
🤔 then yeah, if that's the case, it should be in `--help`
_wb_
2023-01-15 08:06:33
ah no, -1 makes it the default
2023-01-15 08:06:41
0 is doing everything in main thread
2023-01-15 08:07:01
1 is forking one thread
2023-01-15 08:07:32
there shouldn't really be any noticeable difference between 0 and 1, it's just technically slightly different
veluca
_wb_ Palette indices can be as wide as needed. I don't remember what the limit is of nb_colors that can be signaled, there is some limit but it's quite high.
2023-01-15 08:27:06
about 70k
_wb_ ah no, -1 makes it the default
2023-01-15 08:27:35
note djxl is different, which we probably ought to fix xD
_wb_
2023-01-15 08:32:12
ah that's why I was confused
2023-01-15 08:32:28
yes we should make it behave the same way in both cjxl and djxl, this is very confusing 🙂
afed
2023-01-15 08:35:12
and for fjxl <:YEP:808828808127971399>
_wb_
veluca about 70k
2023-01-15 08:38:25
right. IIRC the idea was that we wanted to be able to do channel palettes for 16-bit images where the number of colors is somewhat but not much smaller than 2^16. That could still be useful in principle. For multi-channel palettes, more than 2k colors or so is probably never a good idea for compression, so the limit is not limiting at all. We didn't really worry about > 16-bit, but I think that's fine since when you're using > 16-bit, likely it's in an authoring workflow where compression is not the main concern so subtle things like being able to do non-integer bitdepths effectively are not that important.
Demiurge
improver you do it if you want to do it that way. lead others by example
2023-01-15 11:10:25
Yeah well like I said, in my practice, I notice that a lot more time is wasted debugging the build system once any non-standard GNU or BSD features are added to the Makefile. Trying to circumvent the built-in limitations by introducing logic and control flow to work around it, is not the correct solution and will waste everybody's time. The build system should be as stupid and basic as possible so time isn't wasted on debugging failures of the build system. Especially failures that happen for extremely simple reasons (some wrong flag) but are made way more complicated and time consuming to correct because of the complexity of the makefile.
2023-01-15 11:13:12
So the correct solution is either, don't use any features other than very basic macro assignment and rule definition, and don't try to be clever or work around the built in limitations of make by using clever features from the GNU and BSD variants
2023-01-15 11:14:36
Then as a side effect your project will simply build everywhere with a very minimum amount of time spent debugging `make`
2023-01-15 11:15:13
If someone on an exotic system can't build it then it will be very quick to figure out what's wrong
improver
2023-01-15 11:15:42
do you think that things what actually reduce amount of typing like pathsubst in gnu make are here to waste everybody's time?
Demiurge
2023-01-15 11:16:46
Alternatively, use a different tool if the limitations of make are too inconvenient for you. For example, if you want targets and dependencies to be in different folders, or if you want filenames with spaces in them, don't use make
improver do you think that things what actually reduce amount of typing like pathsubst in gnu make are here to waste everybody's time?
2023-01-15 11:18:05
There here because the `make` tool has extreme and obtuse limits on certain things in its design for no good reason. So it's very tempting to work around those limitations by introducing clever control flow.
2023-01-15 11:18:17
But a better solution would be: don't use `make`
2023-01-15 11:18:41
Or if you use `make` don't try to work around the limitations.
improver
2023-01-15 11:18:59
i've actually used very simple makefile.in with autoconf to generate makefiles that are capable of outputting binaries in separate folders than source
Demiurge
2023-01-15 11:19:24
Yes, but then... you have to use autoconf.
2023-01-15 11:19:47
It's possible but that doesn't mean it's a good idea.
improver
2023-01-15 11:19:59
yeah. but it ends up kinda okay. other than obtuse autoconf syntax
Demiurge
2023-01-15 11:20:33
It's possible to do all sorts of things in make but then you are wasting way too much time trying to figure out how to get it to compile right
improver
2023-01-15 11:21:47
it hasn't been breaking in obscure ways and i didn't spend too much of my time getting it right, and i only need to use autoreconf to generate configure script for releases, and require gnu make for ones compiling stuff
2023-01-15 11:22:52
also pretty minimal solution build dependency wise, only need gnu make
Demiurge
2023-01-15 11:23:29
If you just stick with the most extremely basic features, common to all versions of make, then it's very clear at a glance what's going on if something doesn't build.
improver
2023-01-15 11:23:50
oh also i've used makedepend for header dependencies
Demiurge
2023-01-15 11:24:16
Well makedepend is pretty clever and it does not really complicate things I don't think
2023-01-15 11:24:28
It outputs standard dependency syntax
improver
2023-01-15 11:24:36
i have many .c and .h files so writing up these dependencies by hand woulda been pain
Demiurge
2023-01-15 11:24:59
And `include` is a standard feature in makefiles
improver
2023-01-15 11:25:28
i think out of build systems i only really liked redo
2023-01-15 11:25:52
https://redo.readthedocs.io/en/latest/ this thingy
2023-01-15 11:27:16
but that would be either asking people to install it before building, or bundling it with source myself
2023-01-15 11:27:33
and i just wasn't too familiar with it yet at that point
Demiurge
2023-01-15 11:32:05
A lot of developers use GNU autofool. There's literally nothing good about it.
improver
2023-01-15 11:32:21
i hate gnu automake
2023-01-15 11:32:29
autoconf is kinda oki but automake is ew
Demiurge
2023-01-15 11:32:37
It really overcomplicates things and it's just plain bad
2023-01-15 11:32:53
Like most GNU stuff.
Moritz Firsching
veluca note djxl is different, which we probably ought to fix xD
2023-01-16 12:51:53
I have been meaning to open an issue about that for a long time: https://github.com/libjxl/libjxl/issues/2073
2023-01-16 01:37:27
https://github.com/libjxl/libjxl/pull/2074
Jim
2023-01-18 09:25:54
Congrats on the 0.8 release!
Demiurge
2023-01-19 12:58:55
0.8 is out already? Nice!
vertexgamer
2023-01-19 04:59:52
Grande Luca!!! <@179701849576833024> e anche tutto il team ovviamente
Demiurge
2023-01-20 12:34:43
I don't know about other encoders, but rav1e default settings perform pretty outstanding. It produces files that are SLIGHTLY lower fidelity than JXL by default. However, the file size is a massive decrease compared to libjxl default. Typically more than 4 TIMES smaller files for a very minor reduction in fidelity. if you dial down libjxl to produce a similar sized file, a lot more image detail and texture is lost compared to the AVIF. Probably because rav1e is highly tuned for that bitrate and libjxl is not.
2023-01-20 12:36:11
Would be nice for a low-bitrate-tuned libjxl to beat avif at its own game
2023-01-20 02:09:12
``` $ ffmpeg -hide_banner -h encoder=libjxl Encoder libjxl [libjxl JPEG XL]: General capabilities: threads Threading capabilities: other Supported pixel formats: rgb24 rgba rgb48le rgba64le gray ya8 gray16le ya16le grayf32le libjxl AVOptions: -effort <int> E..V....... Encoding effort (from 1 to 9) (default 7) -distance <float> E..V....... Maximum Butteraugli distance (quality setting, lower = better, zero = lossless, default 1.0) (from -1 to 15) (default -1) -modular <int> E..V....... Force modular mode (from 0 to 1) (default 0) ```
2023-01-20 02:11:58
useful settings like progressive or gaborish are not there
2023-01-20 02:12:04
Only -modular lol
2023-01-20 02:12:26
For some reason that setting just... has a strange attraction to people.
2023-01-20 02:12:51
Also it would be nice if it supported additional pixel formats.
2023-01-20 02:13:28
Both for encoding and decoding
2023-01-20 02:45:01
After all, some JXL is YUV, like lossless-jpeg
Traneptora
Demiurge Also it would be nice if it supported additional pixel formats.
2023-01-20 02:45:13
such as?
Demiurge
2023-01-20 02:45:48
Would be nice to be able to both decode and encode and if there was a way to inquire if the JXL is using YUV encoding
Traneptora
2023-01-20 02:45:52
libjxl doesn't accept those as input
2023-01-20 02:45:56
or provide them as output
Demiurge
2023-01-20 02:46:15
Would be nice
Traneptora
2023-01-20 02:46:22
needs to be added to libjxl first
2023-01-20 02:46:29
and that's a post-1.0 target
Demiurge
2023-01-20 02:46:43
Yeah I'm talking about the api
Traneptora
2023-01-20 02:47:04
I don't really see the advantage of it anyway as the only kind of YUV that JPEG XL is capable of is full-range BT470BG matrix
2023-01-20 02:47:22
and that's extremely rare in the wild outside of JPEG files themselves
2023-01-20 02:48:45
and you explicitly don't want to take any other YUV, such as BT.709, and pass it as-is as JPEG XL cannot code anything else. so it will assume that it's BT470BG and the colors will be incorrect.
2023-01-20 02:50:09
to properly code BT.709 YUV4:2:0 as BT470BG you'd have to convert it to RGB first anyway, and then to BT470BG
2023-01-20 02:50:35
(well in theory you'd multiply the matrices and do it in one step, but my point is it requires a matrix conversion anyway so you gain nothing by being able to feed YUV)
Demiurge
2023-01-20 02:57:54
All I know is that if you take a jpeg and losslessly encode it to JXL the JXL uses the same color encoding as the original JPEG it seems.
2023-01-20 03:00:47
BT.470 BG is a color space I think, and, I'm not terribly familiar with all the countless color spaces there are... but it seems like a possibly useful thing for libjxl to support more pixel formats as input and output
2023-01-20 03:01:29
If it really isn't a useful thing maybe I've got the wrong idea
Traneptora
Demiurge BT.470 BG is a color space I think, and, I'm not terribly familiar with all the countless color spaces there are... but it seems like a possibly useful thing for libjxl to support more pixel formats as input and output
2023-01-20 03:02:06
BT470BG is a colorspace definition that includes in it a YUV matrix definition. That's the matrix that is used in legacy JPEGs
Demiurge
2023-01-20 03:02:20
Two files can have the same pixel format but different color spaces
Traneptora
2023-01-20 03:03:13
don't confuse color space with YUV matrix color space is a description of RGB properties like gamut or transfer curve
2023-01-20 03:03:26
YUV matrix describes the affine linear transformation from RGB -> YUV
2023-01-20 03:03:55
JPEG only supports YUV with the matrix defined in BT470BG
2023-01-20 03:04:12
it doesn't support any other YUV matrix, and for that reason, JPEG XL only supports exactly that YUV matrix
2023-01-20 03:04:37
the *color space* of a JPEG file is much more permissive, and can even be described by an ICC profile
2023-01-20 03:10:01
it *would* be nice if libjxl accepted more pixel formats, especially planar gbr for bit depths between 8 and 16, so those can be done losslessly
2023-01-20 03:10:12
but I don't believe YUV input would be useful
_wb_
2023-01-20 03:13:02
There's the RGB colorspace which depends on icc profile, and then there's the transform from RGB to (possibly subsampled) YCbCr, which is fixed in JPEG to a specific matrix and upsampling procedure (which implies a specific sample alignment), and JXL only supports specifically what JPEG does there. In video codecs, generally a variety of matrices and sample alignments exist, but we didn't want to put all of those in the spec / code since it just complicates things while it isn't needed for lossless jpeg recompression.
2023-01-20 03:14:59
What buffer formats to use (planar vs interleaved, integer or float, endianness, various precisions, various component orders), that's only a software library API question, not a spec thing.
JendaLinda
2023-01-23 10:47:04
It seems that the maximum integer sample bit depth supported by JXL is 24 bits, but no format supported by cjxl/djxl can do that.
_wb_
2023-01-23 11:35:10
Correct. We could in principle extend ppm/pam to do that, using 3 bytes per sample instead of 2 or 3. So far we haven't really encountered use cases for that though. Anything >16-bit is in practice either float32 or fp24.
JendaLinda
2023-01-23 01:00:24
That makes sense, 24 bit depth doesn't seem to be that useful. I discovered that when I was playing with with --override_bitdepth to see what will happen. There is a hole in the range from 25 to 31, where the encoder refuses to proceed.
2023-01-23 01:14:45
Speaking of ppm/pam, the PNM writer in djxl is pretty dumb. It requires specifying the exact appropriate format. The pnm extension is not accepted, although pnm extension can be used for both ppm and pgm formats. If pgm is specified for a color image, the decoding will fail. If ppm is specified for a grayscale image, the decoding will fail as well. PAM supersedes both ppm and pgm but the decoding will fail if pam is specified for images without alpha.
Demiurge
2023-01-23 04:59:05
Is there anything PNM can do that PNG cannot?
_wb_
2023-01-23 05:14:44
Not really. Well it can do all bitdepths up to 16 while PNG can only do 1,2,4,8,16.
2023-01-23 05:15:49
Strictly speaking e.g. 3-bit cannot be represented exactly in png, since a value like 1/7 cannot be represented exactly in 4-bit or in any other bitdepth supported by png.
2023-01-23 05:17:51
(2/15 is less than 1/7 and 3/15 is more)
JendaLinda
2023-01-23 06:26:01
PNG can store information about the original bit depth in sBIT chunk. 3 bit samples has to be scaled to 8 bits but scaling is done in a way that the original bits can be restored by removing the additional LSBs.
_wb_
2023-01-23 06:30:41
Yes, but that's a chunk viewers can ignore...
JendaLinda
2023-01-23 06:32:14
Yes, sBIT chunk is not needed for viewers. That's why the scaling is being done, so the image will look right.
2023-01-23 06:36:05
JXL decoder can also upscale bit depth and it supposedly uses more accurate method.
_wb_
2023-01-23 07:29:21
Well 1/7 is about 14.3% but represented in 4-bit PNG it would become 13.3%. The difference between how an sBIT-aware viewer shows that and how a non sBIT-aware viewer shows that might be noticeable. It's an off-by-two in 8-bit...
JendaLinda
2023-01-23 08:39:23
Well, 4bit PNG can be only grayscale, there is no 4bit RGB in PNG. 3bit grayscale is only 8 shades, so it's quite forgiving and slight inaccuracy would be unnoticeable. 3bit RGB would have to be expanded to 8 bits anyway.
2023-01-23 08:43:52
Alternatively, 3bit grayscale could be converted to 16 color palette which is always 8bit RGB.
Demiurge
_wb_ Strictly speaking e.g. 3-bit cannot be represented exactly in png, since a value like 1/7 cannot be represented exactly in 4-bit or in any other bitdepth supported by png.
2023-01-23 10:46:41
Why not just zero out all the least significant bits?
_wb_
2023-01-23 10:47:34
Because then white becomes light gray...
Demiurge
2023-01-23 10:48:12
Even with sBIT set?
_wb_
2023-01-23 10:48:14
If you do that with a 1-bit image, white becomes 50% gray
2023-01-23 10:48:40
That's my point: most viewers just ignore sBIT.
2023-01-23 10:49:54
It's a chunk of the 'ancillary' type, so viewers are free to simply ignore it.
Demiurge
2023-01-23 10:50:49
Sorry, I'm still reading the backlog.
2023-01-23 10:51:05
Well, sucks for those viewers then.
2023-01-23 10:51:09
Most people use libpng tho
2023-01-23 10:51:30
So pretty sure most viewers support whatever libpng supports
2023-01-23 10:51:48
So I really doubt most viewers have broken support for PNG
2023-01-23 10:52:54
Sounds like the proper thing to do in this situation is tell the publishers of broken software "hey your software is broken"
2023-01-24 12:31:13
png encoding step is quite slow indeed in djxl
2023-01-24 12:49:52
So in my testing rav1e default settings produce file sizes that are approximately the same as -q 75 in cjxl. Yet at that size the AVIF preserves more detail if you compare the current state of both encoders.
2023-01-24 12:52:08
At higher bitrate libjxl might preserve more detail but I have not tested this
2023-01-24 12:52:35
So it's possible rav1e performs well at high bitrates too.
_wb_
2023-01-24 06:02:51
Better than libaom, according to my testing. But speed is even slower...
Demiurge
2023-01-24 06:13:34
Depends on the CPU. libaom is basically garbage in my experience.
2023-01-24 06:14:11
Slow, bad defaults, bad options, bad quality.
2023-01-24 06:18:41
SVT-AV1 is decent speed but I heard it has no ARM optimization
JendaLinda
2023-01-24 07:22:21
The last word to the sBIT topic. The PNG spec requires the sample values to be upscaled. http://www.libpng.org/pub/png/spec/1.2/PNG-Encoders.html#E.Sample-depth-scaling The sBIT chunk itself is only informative. http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.sBIT
Demiurge
JendaLinda The last word to the sBIT topic. The PNG spec requires the sample values to be upscaled. http://www.libpng.org/pub/png/spec/1.2/PNG-Encoders.html#E.Sample-depth-scaling The sBIT chunk itself is only informative. http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.sBIT
2023-01-24 09:05:18
Wow that's really shitty. So PNG requires lossy sampling.
JendaLinda
Demiurge Wow that's really shitty. So PNG requires lossy sampling.
2023-01-24 09:07:42
It's not lossy if it's done right. The goal is to fill only the additional bits, keeping the original bits intact.
Demiurge
2023-01-24 09:09:53
Ah, I see. I'm reading it now and yeah there is a way to have it be lossless still
2023-01-24 09:11:03
Too bad that everything except zero fill will be bad for compression
_wb_
2023-01-24 11:07:11
Even zero fill is bad for compression. PNG does not have separate context for the odd bytes and the even ones...
2023-01-24 11:08:40
It's not as bad as replicating msbs though
Demiurge
2023-01-24 11:27:30
And deflate is too dumb to notice the pattern either way
JendaLinda
2023-01-25 08:42:53
It seems in JXL all channels must use the same sample bit depth. And possibly all frames as well, am I right?
_wb_
2023-01-25 09:21:22
The 3 color channels have the same bitdepth. Extra channels can each have their own bitdepth.
2023-01-25 09:21:43
And yes, it's an image header thing so the same for all frames
JendaLinda
2023-01-25 10:21:13
Alright, but if extra channels have different bit depth, that won't correspond to the image header.
2023-01-25 10:36:08
Also, in cjxl's PNG decoder, alpha with different bit depth is being rejected, but alpha is considered to be a special case of extra channel, right?
Demiurge
2023-01-25 10:46:24
What if there's only 2 color channels?
JendaLinda
2023-01-25 11:32:08
AFAIK there are always three color channels but two of them can be empty.
Demiurge
2023-01-25 11:33:00
I dunno, pretty sure Y is luma.
2023-01-25 11:33:26
:) Just being silly for the most part though
_wb_
2023-01-25 12:01:13
There are either 3 color channels (RGB or XYB or YCbCr) or 1 (grayscale).
JendaLinda Also, in cjxl's PNG decoder, alpha with different bit depth is being rejected, but alpha is considered to be a special case of extra channel, right?
2023-01-25 12:02:20
Yes, in principle we could handle alpha being at a different bitdepth than rgb.
JendaLinda
2023-01-25 12:39:11
This might be useful for artworks, where transparency is just 1bit mask instead of full alpha channel.
_wb_
2023-01-25 01:37:20
Compression-wise, if alpha is only using 0 and 255, it will be encoded in basically the same way as when it's 1-bit.
Traneptora
2023-01-25 02:20:45
but if the alpha channel is *tagged* as 1-bit then it probably shouldn't fail to encode to PNG
2023-01-25 02:20:57
even if in theory it could have been tagged on encode as 8-bit
JendaLinda
2023-01-25 03:49:36
If RGB channels are tagged as different bit depths, the sBIT info is ignored and the bit depth from PNG header is used. If alpha is tagged differently from RGB channels, loading PNG will fail. I think the behaviour should be consistent in these cases.
2023-01-25 03:50:06
The relevant part of the code starts here: https://github.com/libjxl/libjxl/blob/a67e97090d5e0287ededc5b691b56cee30becbf8/lib/extras/dec/apng.cc#L700
2023-01-25 06:32:24
Expanding 1 bit alpha to the same bit depth used by color channels is probably better than enforcing 1 bit. After all, if the source was gif or png with tRNS, it is possible to restore losslessly encoded image to png with tRNS.
TheBigBadBoy - 𝙸𝚛
2023-01-26 09:19:05
Is JXL good at compressing pixel art? I would love a codec that supports defining what "upscaler" should use the viewer. For example, pixel arts pictures would be compressed really well if we save only one color per block and specify that the viewer should use "nearest neighbours" upscale I'm just wondering how good JXL support pixel art compression (preferably lossless) 🤔 Don't really know if this is the good channel :/
Traneptora
2023-01-26 09:25:18
lossless JXL does compress pixel art quite well because it uses a palette transform
_wb_
2023-01-26 09:59:06
Nearest neighbor upsampling can in principle be done with custom weights for the upsampler. Only 2x, 4x and 8x though.
Traneptora
2023-01-26 10:00:55
can the library accept custom upweights?
veluca
2023-01-26 10:30:29
as far as I know it is not exposed
Demiurge
2023-01-28 10:33:09
I think probably in the future squeeze/wavelet/modular lossy compression might be more effective at low bitrate/fidelity targets than DCT-based compression.
2023-01-28 10:33:49
Probably depends on the visual characteristics of the input too.
yoochan
2023-01-28 12:21:54
I have a question about the lossless conversion of jpeg to jpegxl, is the converted image pixel perfect (with optimized everything inside including coefficients if needed) or is everything saved to reconstruct exactly the byte perfect original jpeg ?
_wb_
2023-01-28 12:34:36
Both
yoochan
2023-01-28 01:36:14
The question missed the initial target 😄 can I have only the pixel perfect without the byte perfect ? 😅
_wb_
2023-01-28 01:47:29
Yes, just strip the `jbrd` box
JendaLinda
yoochan The question missed the initial target 😄 can I have only the pixel perfect without the byte perfect ? 😅
2023-01-28 02:32:56
Just be aware that without jbrd, the current implementation is not able to restore the coefficients to jpeg file, so it is one way conversion.
yoochan
2023-01-28 04:15:45
one way yes, but pixel perfect. Thank you all for the answers
Demiurge
JendaLinda Just be aware that without jbrd, the current implementation is not able to restore the coefficients to jpeg file, so it is one way conversion.
2023-01-28 04:18:56
Is this ever going to be fixed so that a legacy-compatible JXL can still be reconstructed into a valid pixel-perfect JPEG even after the JBRD is stripped?
2023-01-28 04:19:53
Because maybe sometimes being pixel perfect is all that actually matters, not pedantically-perfect
Fraetor
2023-01-28 04:20:19
I don't think there is a technical barrier. Someone just needs to do the work.
Demiurge
2023-01-28 04:20:36
Yeah, I guess it was a dumb question.
2023-01-28 04:21:39
I guess it will also be easier to do once the libjpeg API features are more fleshed out too
2023-01-28 04:22:29
Hmm, if libjxl ever becomes a real drop-in replacement for libjpeg, I wonder if that means it will provide a cjpeg, jpegtran, etc tools as well
2023-01-28 04:22:56
Or even better, jxltran tool and API
Kampidh
2023-01-31 02:50:39
whoops, I think I trigger something when encoding with -d 25
2023-01-31 02:52:19
the image is RGBA F16 with couple of extra channels
JendaLinda
2023-01-31 04:23:51
I've noticed that the Brotli related dlls have disappeared form the Windows build. Does it mean they're not needed anymore?
2023-01-31 08:23:30
It seems the Brotli dlls have disappeared after the Brotli update, the build from 30-Jan doesn't include those dlls anymore.
Traneptora
yoochan one way yes, but pixel perfect. Thank you all for the answers
2023-01-31 09:58:36
do keep in mind that JPEG decoding isn't fully specified
2023-01-31 09:58:49
so you can decode the same JPEG file to a pixel buffer in multiple compliant ways
2023-01-31 09:59:18
converting that JPEG file to JXL losslessly will lock in a specific decoding of pixel data, since JXL is fully specified
_wb_
2023-01-31 10:15:11
Though you can still go back to JPEG and decode in a different way if you want
afed
2023-01-31 10:52:36
SSIMULACRA2 ```css 81.47468192 jpeg:enc-jpegli:q88 82.07433231 jpeg:enc-jpegli:q88:dec-jpegli 82.10371363 jpeg:enc-jpegli:q88:dec-jpegli:bd16 82.49778292 enc-jpegli:q88 - lossless jpeg.jxl ``` does jpeg transcoded to jxl has even more quality improvements than the jpegli decoder? and what are the differences, higher precision and jpegli needs to be faster?
Traneptora
Kampidh whoops, I think I trigger something when encoding with -d 25
2023-02-01 04:43:04
distance max is 15, it should refuse to encode more than that
novomesk
Traneptora distance max is 15, it should refuse to encode more than that
2023-02-01 07:44:30
25 is maximum in cjxl but in headers there is written only 15.
_wb_
afed SSIMULACRA2 ```css 81.47468192 jpeg:enc-jpegli:q88 82.07433231 jpeg:enc-jpegli:q88:dec-jpegli 82.10371363 jpeg:enc-jpegli:q88:dec-jpegli:bd16 82.49778292 enc-jpegli:q88 - lossless jpeg.jxl ``` does jpeg transcoded to jxl has even more quality improvements than the jpegli decoder? and what are the differences, higher precision and jpegli needs to be faster?
2023-02-01 07:49:43
I suppose jpegli only decodes to uint8 or uint16, while libjxl is decoding to float32 which is more precise
JendaLinda
2023-02-01 09:34:23
cjxl still refuses to work without the Brotli DLLs, so these are actually missing in the Windows build. It seems that something went wrong during the Broitli update.
Kampidh
novomesk 25 is maximum in cjxl but in headers there is written only 15.
2023-02-01 01:24:43
ah yes, this discrepancy kinda confuses me~ because most of the time it encodes fine when I set the distance to 25
Kleis Auke
JendaLinda It seems the Brotli dlls have disappeared after the Brotli update, the build from 30-Jan doesn't include those dlls anymore.
2023-02-03 02:35:28
AFAIK, Brotli is now statically linked within the pre-built libjxl Windows binaries. Issue <https://github.com/libjxl/libjxl/issues/1694> contains some details on this.
JendaLinda
Kleis Auke AFAIK, Brotli is now statically linked within the pre-built libjxl Windows binaries. Issue <https://github.com/libjxl/libjxl/issues/1694> contains some details on this.
2023-02-03 03:12:24
This issue was once solved and now it's not working again. cjxl is complaining about brotlidec and brotlienc dlls missing. I'm testing the build from here: https://artifacts.lucaversari.it/libjxl/libjxl/latest/
Kleis Auke
JendaLinda This issue was once solved and now it's not working again. cjxl is complaining about brotlidec and brotlienc dlls missing. I'm testing the build from here: https://artifacts.lucaversari.it/libjxl/libjxl/latest/
2023-02-03 03:17:09
Ah, I could also reproduce this on the artifacts listed at <https://github.com/libjxl/libjxl/actions/runs/4084058635>, investigating.
Kleis Auke Ah, I could also reproduce this on the artifacts listed at <https://github.com/libjxl/libjxl/actions/runs/4084058635>, investigating.
2023-02-03 03:29:06
```diff --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -332,6 +332,7 @@ jobs: set -x mkdir build cmake -Bbuild -H. ${{ matrix.arch }} \ + -DJPEGXL_STATIC=ON \ -DBUILD_TESTING=OFF \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=`pwd`/prefix \``` would probally fix that, let me open a PR for that.
novomesk
Kampidh ah yes, this discrepancy kinda confuses me~ because most of the time it encodes fine when I set the distance to 25
2023-02-03 03:30:44
I think they just forgot to change 15->25 in the headers. Anyway, in my Qt plug-in I use distance range only from 0 till 10. Values above 10 didn't look very attractive.
Kleis Auke
JendaLinda This issue was once solved and now it's not working again. cjxl is complaining about brotlidec and brotlienc dlls missing. I'm testing the build from here: https://artifacts.lucaversari.it/libjxl/libjxl/latest/
2023-02-03 03:58:21
I just opened PR <https://github.com/libjxl/libjxl/pull/2144> and <https://github.com/libjxl/libjxl/pull/2145> for this. Thanks for reporting this!
yoochan
2023-02-03 04:36:40
how did you installed it ?
2023-02-03 04:49:39
sorry... switching languages every 5 minutes made me answer in french 😄
2023-02-03 04:53:01
I can't find any good answer but ! looking here https://github.com/libjxl/libjxl/tree/main/debian should help you find the files you may have installed ... don't delete /usr/bin though ! But you can compare what you have in your build/ directory and find what was installed where
2023-02-03 04:53:42
(because it is a shitty process, we invented package managers :D)
_wb_
2023-02-03 05:28:43
I mean, on a recent debian you can just do `sudo apt install libjxl-tools`
2023-02-03 05:29:40
not sure how other distros are doing, but if your distro doesn't have a package, I would recommend complaining to your distro 🙂
2023-02-03 05:38:38
could someone make a list of what distros have packages and what the commands are to install them? I agree that this would be useful to put in the README. We're no longer at the stage where we can expect most people to build it from sources to try it out, most people just want to quickly get a binary they can run. Maybe we should even move the build instructions to a separate document instead of spending half of the README on that.
zamfofex
2023-02-03 05:59:05
<https://repology.org/project/libjxl/versions> tada?
Kleis Auke
JendaLinda This issue was once solved and now it's not working again. cjxl is complaining about brotlidec and brotlienc dlls missing. I'm testing the build from here: https://artifacts.lucaversari.it/libjxl/libjxl/latest/
2023-02-03 06:05:33
FWIW, the build artifacts listed at <https://github.com/libjxl/libjxl/actions/runs/4085744605#artifacts> would probably fix this.
JendaLinda
Kleis Auke FWIW, the build artifacts listed at <https://github.com/libjxl/libjxl/actions/runs/4085744605#artifacts> would probably fix this.
2023-02-03 06:14:11
Everything looks good. Thank you.
yoochan
2023-02-03 07:14:31
If you need to reclaim space on your disk, uninstalling clang would be much more efficient than uninstalling libjxl 😊
2023-02-03 07:17:02
What's the conf of your box to be in such a need?
yurume
2023-02-03 07:25:56
can I ask you why you have that severe storage limit
2023-02-03 07:27:27
yeah let's go to <#806898911091753051> for that
_wb_
2023-02-03 07:27:40
Try stripping debug symbols from all binaries, that can reduce their size quite a bit
sklwmp
2023-02-04 06:03:48
To compile without Clang, just don't do `export CC="clang" CXX="clang++"`, then CMake will use your system default compiler, probably GCC. That's what the Arch package does IIRC, since it doesn't specify Clang.
2023-02-04 06:07:01
wow, termux updates fast, it's the only one v.0.8.1, released 10 hours ago
Traneptora
2023-02-04 01:19:30
when was JxlBitDepth added?
2023-02-04 01:27:01
ah nvm, git blame says last october
2023-02-04 04:59:11
does libjxl include version numbers as preprocessor directives?
2023-02-04 04:59:17
or is it only the runtime JxlDecoderVersion()?
veluca
2023-02-04 05:20:10
IIIRC we have both, there's a version.h
Traneptora
2023-02-04 07:08:00
I see it, thanks. It's not documented though
2023-02-04 07:08:08
is that patches welcome territory?
veluca
2023-02-04 07:26:41
I guess so xD
Demiurge
2023-02-05 08:04:08
So, I took a (rather large, panoramic) photo with my iPhone and tried compressing it using distance=2 and the results are... okayish I guess maybe? But I would not call it perceptually uniform. For an HDR-focused format, it seems odd how it gets noticeably blurry, but ONLY in the parts of the image with the shadow on the ground.
2023-02-05 08:04:58
Details are preserved well across the image with this one weird glaring exception. The texture is noticeably smudged and blurred on the part of the ground where I'm casting a shadow
_wb_
2023-02-05 08:07:34
How did you get pristine pixels to start with?
Demiurge
2023-02-05 08:08:33
Started out life as a JPEG.
2023-02-05 08:11:52
2023-02-05 08:12:31
It looks less noticeable than I remember the second time around. :)
2023-02-05 08:13:10
But basically I thought that compared to the rest of the image this is the only part where it's actually noticeable.
2023-02-05 08:14:01
And JXL and other HDR-focused formats are supposed to be good at retaining detail and texture in shaded areas
_wb_
2023-02-05 08:21:01
Likely that jpeg is transcoded from a heic, so doing a third lossy compression is not so great for retaining detail...
Demiurge
2023-02-05 08:22:15
No, it was taken before HEIC was a thing
2023-02-05 08:22:37
And I'm careful not to transcode HEIC to JPEG
2023-02-05 08:22:59
I'm aware of Apple's automatic transcoding
2023-02-05 08:23:23
Is there a way to get djxl to reconstruct jpeg to stdout?
2023-02-05 08:23:43
For piping into another program that accepts JPEG on stdin
_wb_
2023-02-05 08:29:53
At some point `djxl foo.jxl -` would do that, no idea it that still works
Demiurge
2023-02-05 08:30:10
No, does not
2023-02-05 08:30:15
I tried
2023-02-05 08:30:31
Also, cjxl does not support JPEG with arithmetic coding?
_wb_
2023-02-05 08:30:37
Ah wait, no idea if that would work for jpg reconstruction, since it doesn't know what extension the output file gas
Demiurge
2023-02-05 08:31:38
``` JxlEncoderAddJPEGFrame() failed. EncodeImageJXL() failed. ```
2023-02-05 08:32:04
Yeah it fails because it uses file extension to determine output format
2023-02-05 08:32:30
I guess djxl does not support stdout
2023-02-05 08:32:43
also cjxl does not support arithmetic-coding in JPEG input
2023-02-05 08:38:09
Hmm also I can losslessly optimize my JPEGs almost as good with `jpegtran` compared to using cjxl
2023-02-05 08:38:27
Especially if I use arithmetic coding
2023-02-05 08:38:58
Within 10% of what I can get with cjxl
2023-02-05 08:39:43
As in cjxl still wins but not by a lot
2023-02-05 08:42:19
It might be a good idea to have a more helpful error message when this happen
2023-02-05 08:42:54
making it clear why it fails and that cjxl is not capable of reading arithmetic-coded JPEG
2023-02-05 08:43:15
but if libjxl intends to implement the libjpeg api it might be a good idea to implement arithmetic coding
2023-02-05 08:58:29
JPG = 15 MB JXL = 14.1 MB
2023-02-05 09:06:10
The reconstruction data is 289 KB... That's pretty big...
2023-02-05 09:07:31
Too bad JBRD is required to transcode to JPEG...
2023-02-05 09:10:01
Here is the whole, lossy d2 image. The lossless is too big for discord.
2023-02-05 09:40:51
using rav1e at the highest speed setting I was able to produce this file just for shits and giggles. Despite using the highest speed setting it looks like AVIF actually retains more detail and texture in dark areas compared to JXL
2023-02-05 09:41:05
2023-02-05 09:41:44
This is despite being a smaller file size and using the highest available speed
2023-02-05 09:42:54
Produced using: `avifenc -j all -c rav1e -s 10 --min 28 --max 29 IMG_0116.JPG IMG_0116.AVIF`
2023-02-05 09:55:09
Here is the original file, truncated to fit within discord limits. Restore with `cat`
2023-02-05 09:55:58
I used `dd` in order to divvy it up.
2023-02-05 10:04:27
I hope this example has been helpful in identifying shortcomings with the encoder's strategy of economy.
2023-02-05 10:14:35
also `jxlinfo` says that the image is "possibly lossless" somehow, but it's a DCT image that was encoded from a JPEG so it is definitely not lossless.
2023-02-05 10:14:45
There is no possibility
2023-02-05 10:14:49
Is that a bug?
_wb_
2023-02-05 10:35:56
It says "possibly lossless" it it's not XYB
2023-02-05 10:36:18
So that includes losslessly recompressed jpegs
2023-02-05 10:37:55
Of course you can argue that a losslessly recompressed jpeg is not lossless, since jpeg is already lossy.
2023-02-05 10:39:25
It all kind of depends on what you consider the pristine source. If your camera produces only jpeg output (at q96 or something), then that's as pristine as it gets — converting it to 8-bit rgb pixels is not making it any more pristine, to the contrary.
2023-02-05 10:40:51
But of course a jpeg can also be low quality, just like rgb pixels may be low quality. It only says "possibly lossless", since there is no way to know the history of the image.
Demiurge
2023-02-05 10:55:13
Not only that but it uses chroma subsampling too
2023-02-05 10:55:29
So calling it "possibly lossless" is just wrong on so many levels
2023-02-05 10:57:37
I think it should only say "possibly lossless" on images that are "possibly lossless"
2023-02-05 10:58:15
There is no way this is possibly lossless
2023-02-05 10:59:22
If it's known for a fact to use lossy encoding then it shouldn't say that
_wb_
2023-02-05 11:08:49
The thing is, the current libjxl api exposes the color space (xyb or rgb) but not the frame encoding that was used (modular or vardct) or other frame header fields (like ycbcr and chroma subsampling)
2023-02-05 11:11:04
"possibly" doesn't mean "certainly", and it is philosophically not so clear what "lossless" means anyway — if the only remaining source for the image is a q60 4:2:0 jpeg, then arguably that is "lossless", imo.
Demiurge
2023-02-05 11:12:53
It would also be nice if there was a recommended way for an encoder to write to the output file what alleged encoder settings were used and whether the file is meant to be a lossless representation of the source or not.
_wb_ "possibly" doesn't mean "certainly", and it is philosophically not so clear what "lossless" means anyway — if the only remaining source for the image is a q60 4:2:0 jpeg, then arguably that is "lossless", imo.
2023-02-05 11:23:08
It's a lossless representation of the JPEG source... But we know that JPEG images are never lossless by their nature, it's quantized and then approximated in a different domain than the one it's being displayed in, etc
2023-02-05 11:25:08
So it's a bad idea calling an image like that "possibly lossless" if it's known to have undergone so many lossy transforms like DCT and chroma subsampling... Actually it's pretty weird that XYB is the only thing that is considered.
2023-02-05 11:25:27
Because isn't XYB theoretically a mathematically reversible transform?
Traneptora
2023-02-05 11:26:17
XYB is not bit-exact reversible
2023-02-05 11:26:51
it's mathematically invertible if you had infinite precision
2023-02-05 11:27:11
but you don't
2023-02-05 11:28:33
The reason it says "possibly lossless" for nonXYB is that the frame headers aren't exposed by the API so the decoder client doesn't have that information
2023-02-05 11:28:47
so it can't say "lossy" if VarDCT
2023-02-05 11:29:00
cause it doesn't know if VarDCT or Modular
Demiurge
2023-02-05 11:29:38
Traneptora
2023-02-05 11:30:04
LMS* have a cuberoot and bias factor
Demiurge
2023-02-05 11:30:12
Maybe LMS don't precisely coincide with RGB but I wouldn't understand why not
Traneptora
2023-02-05 11:31:03
L* = cbrt(L - bias) + bias2
2023-02-05 11:31:25
you apply this, then do that linear transform
Demiurge
2023-02-05 11:32:04
It's possible that in the future content will be created in XYB domain from source.
Traneptora
2023-02-05 11:32:45
https://github.com/thebombzen/jxlatte/blob/5b02554f9ab01134b7a19c1182f81b366fd3bcd1/java/com/thebombzen/jxlatte/color/OpsinInverseMatrix.java#L90
Demiurge It's possible that in the future content will be created in XYB domain from source.
2023-02-05 11:34:36
unlikely as XYB is modeled after human perception, not after tristimulus RGB hardware like CCDs
Demiurge
2023-02-05 11:36:11
We wouldn't have RGB if we didn't have LMS cones in our eyes
Traneptora
2023-02-05 11:36:30
Also XYB is specifically designed after linear sRGB
2023-02-05 11:37:02
although the opsin inverse matrices could be multiplied
2023-02-05 11:37:20
so I suppose maybe that's not an issue
Demiurge We wouldn't have RGB if we didn't have LMS cones in our eyes
2023-02-05 11:38:06
it would make more sense to model hardware after LMS than XYB, for that reason
_wb_
Demiurge It would also be nice if there was a recommended way for an encoder to write to the output file what alleged encoder settings were used and whether the file is meant to be a lossless representation of the source or not.
2023-02-05 11:38:29
That's the kind of metadata that a new adhoc group in jpeg is going to standardize. But it's tricky, since not just the last step matters, but the entire history. If the last step is losslessencoding but the image has been a q50 jpeg that was converted to a gif before being converted to a 16-bit PNG, then it would be rather silly to have metadata saying it's a lossless 16-bit image.
Traneptora
2023-02-05 11:39:10
at least encoding settings could be an extensions payload. safe to ignore on decode
Demiurge
_wb_ That's the kind of metadata that a new adhoc group in jpeg is going to standardize. But it's tricky, since not just the last step matters, but the entire history. If the last step is losslessencoding but the image has been a q50 jpeg that was converted to a gif before being converted to a 16-bit PNG, then it would be rather silly to have metadata saying it's a lossless 16-bit image.
2023-02-05 11:40:59
Well you cannot control the entire history of the image but the encoder can at the very least have an opportunity to record how it was allegedly configured at the time it did its work.
_wb_
2023-02-05 11:41:22
For display/capture technology it makes sense to use primaries that allow you to get a nice gamut, i.e. as saturated as possible. For perceptual modeling though, LMS makes more sense. The L and M are commonly referred to as the 'red' and 'green' cones but in reality they both peak at a kind of lime green, L just a bit more yellowy than M.
Demiurge
2023-02-05 11:43:24
L peaks at a yellowy green?
_wb_
Demiurge Well you cannot control the entire history of the image but the encoder can at the very least have an opportunity to record how it was allegedly configured at the time it did its work.
2023-02-05 11:43:33
Making cjxl or libjxl add some custom xmp or exif field, or a new isobmf box with encode settings wouldn't be too hard.
2023-02-05 11:44:08
2023-02-05 11:45:55
The transfer curve of sRGB wasn't intended to be perceptually relevant, it was intended to model how CRT displays of the early 1990s translated voltage to intensity.
Demiurge
2023-02-05 11:46:55
Is that a good idea of what those colors look like at that frequency? Because the spot where S is peaking is a lot darker than the spot to the right of it. I would expect the brightest-looking spot to be where the peak is.
2023-02-05 11:53:24
Object-oriented code makes me want to sit in a corner and cry... :(
2023-02-05 11:54:21
Its like it was invented by business executives trying to think of ways to suck all of the joy out of programming