Skip to content

JPEG-XL: Expand more functionality

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 Black and 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, Spot channels only comes as grayscale layers instead of real spot color stored in JxlExtraChannelInfo->spot_color as float RGBA values. Check with libjxl conformance->spot.
  • On both read/write, only still images are supported.
  • Further potential functions are yet to be discovered; eg. making use of SelectionMask channel for a proper selection mask, Depth channel 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 JxlDecoderSetCoalescing. 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...

Master(996e14fe) MR-Callback MR-Buffer
Large photo (36MP) bigphoto-master bigphoto-mr-callback bigphoto-mr-buffer
Sunset Logo (Layered) sunset-master sunset-mr-callback sunset-mr-buffer

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_MULADD for 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.

Test Plan

  • Build Krita
  • Verify that JPEG-XL unit test is passed
  • [dismissed] 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 conformance->cmyk_layers or conformance->sunset_logo)
  • Verify multi-layer export functionality by exporting layered image as JPEG-XL

Formalities Checklist

  • 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,

Edited by Rasyuqa A H

Merge request reports