Repository navigation
fix(j2k): write sRGB-equivalent ICC samples to RGB8/RGBA8 region output - #322
Merged
Merged
Conversation
A JP2 tagged with an IEC 61966-2-1 sRGB ICC profile failed region and pow2-scaled region decodes to Rgb8/Rgba8 with "backend color space cannot be mapped to requested 8-bit pixel format", leaving decode_srgb8, a whole-image decode, as the only route. Treat a three-channel ICC profile as RGB for 8-bit RGB output when it is a restricted matrix/TRC RGB profile whose linear matrix to sRGB is within 2.5e-4 (off-diagonal row sums) and 1e-3 (diagonal) of identity, and whose 8-bit transform to sRGB moves no channel or neutral ramp sample by more than one code value. The matrix is checked directly because the ramps alone miss negative crosstalk, which clips on single-channel ramps and cancels on neutrals but shifts mixed colours by tens of code values. This applies to decode_region_into, decode_region_scaled_pow2_into, the prepared region path, the whole-image decode_into fallback, and the streamed stripes of decode_rows_u8_bounded. Other ICC profiles and 16-bit outputs remain unsupported. Fixes frames-sg#321
jcoyne
force-pushed
the
fix/srgb-icc-region-rgb8
branch
from
November 5, 2026 18:27
bfbee0d to
7d91a73
Compare
Member
|
lgtm, thanks for this! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fixes #321.
Problem
A three-component JP2 tagged with an embedded IEC 61966-2-1 sRGB ICC profile failed
decode_region_intoanddecode_region_scaled_pow2_intotoRgb8/Rgba8:The only working route was
decode_srgb8, which decodes the whole image. That isn't practical for large IIIF sources.Change
The 8-bit output paths now treat a three-channel ICC profile as plain RGB for
Rgb8/Rgba8output when the profile is equivalent to sRGB. Samples are written without a colour transform. A profile qualifies when:decode_srgb8accepts;transform_matrix) is within 2.5e-4 (off-diagonal row sums) and 1e-3 (diagonal) of identity. Near zero, one 8-bit sRGB code value is about 3.0e-4 of linear light, so the off-diagonal limit keeps crosstalk under one code value;The ramps alone are not enough. A negative off-diagonal term clips to zero on a single-channel ramp and cancels on neutrals, but it still shifts mixed colours: a test profile with matrix
[[1.01, -0.01, 0], [0, 1, 0], [0, 0, 1]]moved (30, 255, 0) to a red of 10. That is why the matrix is checked directly.This applies to
decode_region_into,decode_region_scaled_pow2_into, the prepared region path, the whole-imagedecode_intofallback, and the streamed stripes ofdecode_rows_u8_bounded. The colour space is resolved once when each row sink is built, so the profile isn't re-checked per band. Other ICC profiles and 16-bit output stay unsupported, with the same error.Tests
New file
crates/j2k/tests/srgb_icc_region.rs:Rgb8/Rgba8, scaled regions at 1 and 2 levels, and whole-imagedecode_into, for both moxcms's parametric sRGB profile and a 1024-entry sampled-curve sRGB profile like the common HP one. Whole-image output is also within one code value ofdecode_srgb8.decode_rows_u8_boundedat 1, 5 and 16 rows per stripe matches the enumerated-sRGB image. This test fails without the stripe-sink change.The three sRGB tests fail without the source change.
cargo test -p j2kpasses. A manual check against the macOS system profiles acceptedsRGB Profile.iccand rejected Display P3, ITU-709, Generic RGB and AdobeRGB1998.Notes