make kXYB images work, and make color_space=XYB do something better #2506
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
A JPEG XL image can be in three colorspaces: kRGB, kGray or kXYB. We don't currently produce kXYB images by default (but you can if you encode with
-x color_space=XYB_Per
). Such images don't decode at the moment; this fixes that.Also, when loading an input image with
cjxl -x color_space=XYB_Per
, or when storing an output image withdjxl --color_space=XYB_Per
, the actual color space that is used is not actually XYB. It is a rescaled variant of XYB.For PNG and other uint formats, using the rescaled variant makes sense, since the 'real' XYB has weird ranges so it cannot just be converted to uint. For PFM though, using the 'real' XYB makes much more sense than using the scaled one: the whole point of working in XYB is to avoid unnecessary color conversions and to stay in the space that is actually used internally. Also the rescaled XYB is not really documented anywhere so it is a very unexpected behavior to get a PFM output that doesn't correspond at all to what you would expect.
This PR changes the decoder behavior in case XYB output is desired: it now only produces scaled XYB when requesting uint samples and produces unscaled XYB when requesting float samples. It also changes the encoder behavior in case the input is marked as XYB: it now treats that as unscaled XYB, not scaled XYB.
For the case of PNGs saved with
--color_space=XYB_Per
, nothing changes: djxl will produce the same file as before (scaled XYB), cjxl will interpret it correctly since the ICC profile corresponds to the data. For PFMs saved with--color_space=XYB_Per
, the behavior does change: djxl will produce a file that uses unscaled XYB, and when using cjxl on this PFM file with-x color_space=XYB_Per
, it will interpret it as unscaled XYB.This partially/mostly fixes these issues. I left one TODO: the ICC profile that gets generated for kXYB color encodings is still always the scaled variant — this should be changed so it generates a profile corresponding to unscaled XYB whenever that is what will be produced. It's not a huge problem since PFM doesn't support ICC profiles, but it should be addressed so applications that request float data in the original colorspace from the decoder do get a correct ICC profile that describes their data, in case the image is tagged as kXYB.