|
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_
|
|
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
|
|
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
|
|