Pillow
Pillow copied to clipboard
Add JPEG XL Open/Read support via libjxl
Helps #4247
This PR enables opening and reading JPEG XL images and animations.
Supported image modes are: RGB, RGBA, RGBa, L, LA, La.
A relatively recent libjxl version is needed to compile Pillow with libjxl support.
The main changes are the addition of _jxl.c and JxlImagePlugin.py.
I'm also the author of jxlpy so this PR was influenced by the work of contributors there. This PR is also largely based on WebPImagePlugin.py which had similar implementation.
Why?
JPEG XL has recently seen increased adoption especially in Apple ecosystem. A lot of users are requesting Pillow support for JPEG XL as their products use Pillow and need to be able to handle jxl files.
I'm open to suggestions and comments. I understand such change would need a lot of testing and probably changes. After all Pillow would need to become somewhat dependent on libjxl. Creating documentation will not be a big problem however I decided to wait for feedback from Pillow core developers.
May you please commit the images as LFS?
May you please commit the images as LFS?
Do you mean those .jxl files under Tests/images I've committed? I'm not really sure how to do that.
~~The explanation is outlined here: https://docs.github.com/en/repositories/working-with-files/managing-large-files/configuring-git-large-file-storage~~
Nevermind. I just noticed they are not putting the test images as lfs:
They already setup lfs and they only use for other larger stuff. Let it stay as you did.
Mac OS builds were failing because clang complained about goto labels being declared before variables in scope. I also merged @radarhere's commits that remove the jxl feature which was causing troubles before. Now it should be fine. Almost all checks pass except codecov.
I've merged in main to include https://github.com/python-pillow/Pillow/pull/7827 to fix a lot of the warnings I'm seeing on macOS 14.4 Sonoma with CommandLineTools installed.
And this is failing to build for me with:
src/_jxl.c:174:12: error: incompatible integer to pointer conversion returning 'int' from a function with result type 'void *' [-Wint-conversion]
return true;
^~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/stdbool.h:21:14: note: expanded from macro 'true'
#define true 1
^
Full log: log2.txt
I've merged in
mainto include #7827 to fix a lot of the warnings I'm seeing on macOS 14.4 Sonoma with CommandLineTools installed.And this is failing to build for me with:
src/_jxl.c:174:12: error: incompatible integer to pointer conversion returning 'int' from a function with result type 'void *' [-Wint-conversion] return true; ^~~~ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/stdbool.h:21:14: note: expanded from macro 'true' #define true 1 ^Full log: log2.txt
Thanks for reporting. The _jxl_decoder_count_frames function was declared to return void * instead of bool. That was an obvious mistake and I'm even not sure why it worked under gcc.
It would be excellent to see some progress in this area. I am currently working on introducing JPEG XL support to https://immich.app for previews and thumbnails (as Python is used for ML). However, an additional plugin pillow-jpegxl-plugin complicates the deployment process.
Could you still add support for 16 bit single channel files? Such images are commonly used in fluorescent microscopy, and storing them in jxl instead of tiff or png would lead to substantial storage savings. Pillow is used by various relevant software including imageio and CellProfiler.
In _pil_jxl_get_mode you would have to add:
if(bi->bits_per_sample == 16 && bi->num_color_channels == 1 && bi->alpha_bits == 0 && !bi->alpha_premultiplied) {
return "I;16";
}
and in _jxl_decoder_new, the line
if (decp->pixel_format.data_type != JXL_TYPE_UINT8) {
should be changed into:
if (decp->pixel_format.data_type != JXL_TYPE_UINT8 && decp->pixel_format.data_type != JXL_TYPE_UINT16) {
Any relation-to or overlap-with #1888 here? 🤔
Any relation-to or overlap-with #1888 here? 🤔
Not quite, fluorescent microscopy images are often stored in a single channel while #1888 is about multichannel files. Pillow already supports single channel images (as #1888 points out), so it makes sense that this JPEG XL reader supports them too.
It would be excellent to see some progress in this area. I am currently working on introducing JPEG XL support to https://immich.app for previews and thumbnails (as Python is used for ML). However, an additional plugin pillow-jpegxl-plugin complicates the deployment process.
@develar Sounds awesome, thank you for working on JPEG XL support in Immich. I presume that merging this PR is now up to Pillow core developers since all checks have passed. However by now we would probably need to resolve some merge conflicts.
Could you still add support for 16 bit single channel files? Such images are commonly used in fluorescent microscopy, and storing them in jxl instead of tiff or png would lead to substantial storage savings.
@bgorissen Yes, of course it's possible. Thank you for detailed description of changes. Could you provide some image(s) to test this mode?
@olokelo I 2nd @bgorissen request around 16 bit single channel support. I work with imaging systems that produce 16 bit single channel images, like thermal and depth, and the JXL format provides some significant cost savings storage-wise compared to our 16 bit single channel PNG format we are currently using. I would love to see the JXL ecosystem mature and this plugin would go a long way towards our adoption of the format
@olokelo I've attached a 16-bits grayscale jxl file (zipped because Github does not support jxl). You could crop it to create a smaller test file. The file was converted from a public tiff image from the dataset cpg0011 (Laber et al., 2023), available from the Cell Painting Gallery on the Registry of Open Data on AWS (https://registry.opendata.aws/cellpainting-gallery/), and released under CC0 1.0 Universal (which puts it in the public domain).
subcutaneous__D14__45adb24f-23b7-43f8-9612-0a7ecaa22ada__BR00101077__r02c03f01p01-ch1sk1fk1fl1.zip
This is very good work @olokelo! Is there any plan to add support for writing to JXL from Pillow?
@j99ca Yes of course, I just wanted to add reading support first to see what Pillow maintainers think about it. For now you can create JXL images using jxlpy.
@hugovk: It certainly would be nice to have this as feature in Pillow 11, wouldn't it? Maybe you can sketch out the required steps?
The iPhone 16 Pro models will support the JPEG-XL file format, according to code found in iOS 18.
I really hope this will be the next standard in photography, I would really like to see support for this in Pillow 11 by default.