-
-
Notifications
You must be signed in to change notification settings - Fork 700
Improve JPEG XL support #3712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve JPEG XL support #3712
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
This looks great @DarthSim, thank you for doing this work. I tested using libjxl 0.8.2:
And it all worked well. |
FWIW, I think this is due to that PR #3774 backports commit 4caf924 to 8.15, which should be safe now that libjxl v0.6 is our minimum required version. |
Have the |
The revised JXL load and save will be in 8.16, so summer 2024, probably. You can build master yourself in the meantime, of course. |
@jcupitt Thank you for the reply. I built the branch DarthSim:feature/jxl-better-support rather than the master, but that shouldn't make a difference right? I see some improvements in the handling of metadata, but fields including |
You'd need to share a test file, but the usual problem is that libtiff does not store EXIF in a standard way. Instead of an EXIF block (like jpeg, webp, png, etc.), EXIF is broken out into a set of separate TIFF tags, making them very hard to work with. You'd probably be better off using XMP or IPTC. Additionally, most RAW cameras files will be loaded via imagemagick, which will not pass on many metadata fields. Try |
Using
I have shared this file with Dropbox as that is easiest with a larger tiff file like I am working with.
|
exiftool will be unpacking the XMP, IPTC and PhotoShop data tags, so they are probably seeing the same number of things. You can use You could look at the JXL and see if that has the XMP and IPTC data attached. |
I tried with your file and I see:
So the XMP has made it over. The PhotoShop metadata is not supported by JXL. The colour profile is different, but I think that's expected to change, JXL has slightly funky colour handling (maybe we should check this). The IPTC has been removed, but it was probably empty. The EXIF was added by libvips and is the minimal set required by the standard. If you extract the XMP you get: <?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 12.23'>
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<rdf:Description rdf:about=''
xmlns:aux='http://ns.adobe.com/exif/1.0/aux/'>
<aux:Lens>Fujifilm EBC Fujinon SW 105mm f8</aux:Lens>
</rdf:Description>
<rdf:Description rdf:about=''
xmlns:crs='http://ns.adobe.com/camera-raw-settings/1.0/'>
<crs:AlreadyApplied>True</crs:AlreadyApplied>
<crs:AutoLateralCA>0</crs:AutoLateralCA>
<crs:Blacks2012>0</crs:Blacks2012>
<crs:BlueHue>0</crs:BlueHue>
... a lot more So you probably just need to extract that and put it through an XML parser. |
@jcupitt Again, thank you for all your time. The XMP is in fact successful at being passed over and includes the lens used, but Would there be future plans for better handling metadata copying between tiff and jxl or should I script an alternate solution? |
You'll need to find out where this extra metadata is being held. Is it in the Your image has an extra EXIF directory under the main image with some more metadata:
But you can see libtiff is really struggling to read it. It's not really standard TIFF, so you're probably out of luck there too. Maybe use |
I tested this on another sample TIFF and the data I need is really spread out. There is more than one TIFF directory it seems, but none of what I would consider essential data is contained in the Photoshop block.
and another TIFF block
and yet another
All the data relevant to me is contained in these three TIFF blocks and theoretically should make its way over. When I use
This worked for me. Outputting a JSON and then writing that to the JXL is successful. This strikes me as odd because using |
Are you sure? I see:
And with JXL:
You can see they are almost identical. |
What are you using to view the metadata on the JXL? Perhaps it does not support XMP in JXL? |
After writing the extracted json to JXL I can read from the JXL using
When I use
What would be the cause of the discrepancy?
After writing the JSON to the JXL files I can view it using either exiftool or Photoshop/Lightroom. Lightroom has been successful in reading the metadata from the JXL after it's been written to from the JSON. |
As I said, libvips is not reading those strange extra TIFF directories, because that style of TIFF metadata is hard to read correctly. I think adding support for this would be out of scope for libvips. Just finding a specification of each tag and the expected value would be tricky, if it's even documented anywhere. |
Maybe that was a bit of hyperbole. We agree that the PNG and JXL show the same metadata when using Thank you for all your help. |
@DarthSim, is there any news about improving lossless mode? |
@sergeevabc I answered in the discussion |
Might be the wrong place but any news about progressive image loading with jxl? |
@SimplyCorbett if you mean loading an image in chunks rather than all in one go, it's not in libjxl yet. It's on the roadmap for 1.0, but no one's implemented it, as far as I know. Chunked jxlsave is in a libvips branch right now, it'll be merged early next year (at a guess). |
Hey there 👋
Apple added JPEG XL support to macOS, iOS, and Safari, and lots of people want to try it. Unfortunately, JPEG XL support in libvips is pretty limited right now, and this PR fixes this.
jxlload, jxlsave: support EXIF and XMP metadata
JPEG XL has two file formats:
Currently,
jxlload
doesn't extract EXIF/XMP from the container format, andjxlsave
doesn't save files JXL in the container format. This PR adds extracting EXIF/XMP from ISOBMFF boxes and saving it to ISOBMFF boxes.jxlload: close input on EOF instead of throwing an error
Currently,
jxlload
fails when meets the end of input. But in some cases, libjxl tries to read while the input is opened. So instead of returning an error on the end of input libvips should close the input.jxlload: add animation support
Unfortunately, JPEG XL header doesn't have contain frames count so we have to subscribe to
JXL_DEC_FRAME
and count frames ourselves. Luckily, libjxl doesn't decode frames unless we subscribe toJXL_DEC_FULL_IMAGE
.The sequential decoding of frames is done in
webpload
manner: we decode a frame to a separate image when we reach it and read it line-by-line invips_image_generate
.jxlsave: add animation support
This is done in a
webpsave
manner: we write image data in a memory buffer duringvips_sink_disc
and as soon as we've written a full frame, we add it to libjxl. Also, we process output after each frame to save memory.jxlsave: lower min effort value to 1
The valid range for
effort
in libjxl is 1-9 but libvips currently allows a range of 3-9, not sure why