Hi! As I promised to @lsegovia on !1722 (merged), I stashed the preliminary support for JPEG-XL read/write special channels data and move it to a separate draft. Along with that, I also added some basic layer reading functionality here. Most of the test files mentioned here are from libjxl conformance.
Add preliminary ability to read/write special channel data
JPEG-XL has an ability to store multiple kinds of extra channels beside
Alpha. This MR gives us basic support to read those extra channels as grayscale data
and displays them in layer stack. For writing, it gives us the basic ability to export specifically-named layers as extra channels for JPEG-XL.
However, this still have some limitations:
- On read,
Spotchannels only comes as grayscale layers instead of real spot color stored in
JxlExtraChannelInfo->spot_coloras float RGBA values. Check with libjxl
- On both read/write, only still images are supported.
- Further potential functions are yet to be discovered; eg. making use of
SelectionMaskchannel for a proper selection mask,
Depthchannel as depth information data for depth filters or bump-mapping, etc.; For now, it only served as a more complete/verbose decoding so that more features got extracted.
Edit: dismissed as layered JXL will be more suitable for our use cases.
Add preliminary ability to read layered JPEG-XL
When the JPEG-XL image is not animated and the
frame_duration is 0, the frames are basically works as simple layers with several blending modes available by utilizing
However, as stated by @jonsneyers at !1363 (comment 452656), only the normal alpha blending mode
JXL_BLEND_BLEND that can be used in Krita.
The limitations are:
- Only still images, on animated the frames are coalesced like the default decoding.
Currently only supports read, if we also wants write we should have quite a number of checks to make sure that the document can comform with layered JPEG-XL (make sure that all layers are in normal blending mode, converting vector layers, etc.)(see below)
- There might be a slowdown on reading some JPEG-XL file, because here I utilize a decoder rewind if it founds an unsupported layer features and revert it back to coalescing decode to get the proper image (see below).
- Same as special channels, further potential functions are also yet to be discovered; eg. multi-layer TIFF alternative with both lossless/lossy support?
For this MR, JXL image with supported layer modes and/or extra channels are always loaded with layers being separated. Maybe it would be nice to prompt the user to flatten or keep it on import?
Use image out buffer instead of image out callback function on read
Some JPEG-XL file (
conformance->sunset_logo in particular during my testing), have a very slow decoding performance on this MR while using image callback function, and got a significant speed boost while using
JxlDecoderSetImageOutBuffer instead. However, this might requires more review as I modified a number of the functions...
|Large photo (36MP)|
|Sunset Logo (Layered)|
Add preliminary ability to write layered JPEG-XL
JPEG-XL layered features are very basic:
- No clipping layers / mask
- Only normal blending mode, yes I experimentally added
JXL_BLEND_MULADDfor additive blending mode also for testing purposes. Other blending modes are converted to normal.
- For layer types other than paint layer / raster, will be converted to paint layer.
- No partial layer opacity, visible layers will be exported at 100% opacity and invisible layers will be skipped.
- No nested / group layers. Layers are visited non-recursively and group layer will be flattened.
- Only still image.
On a positive note, JPEG-XL can store layers in crops and can preserve out-of-bound pixels.
- Build Krita
- Verify that JPEG-XL unit test is passed
Verify special channel functionality by opening JPEG-XL images with special channels (eg. libjxl
conformance->spot, or test file from unittest)
- Verify multi-layer functionality by opening layered JPEG-XL images (eg. libjxl
- Verify multi-layer export functionality by exporting layered image as JPEG-XL
I confirmed this builds.
I confirmed Krita ran and the relevant functions work.
I tested the relevant unit tests and can confirm they are not broken. (If not possible, don't hesitate to ask for help!)
I made sure my commits build individually and have good descriptions as per KDE guidelines.
I made sure my code conforms to the standards set in the HACKING file.
I can confirm the code is licensed and attributed appropriately, and that unattributed code is mine, as per KDE Licensing Policy.
Reminder: the reviewer is responsible for merging the patch, this is to ensure at the least two people can build the patch. In case a patch breaks the build, both the author and the reviewer should be contacted to fix the build. If this is not possible, the commits shall be reverted, and a notification with the reasoning and any relevant logs shall be sent to the mailing list, email@example.com.