You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of #323. Blocked by #324 (scaffold), #325 (curves), #326 (CLUT), #321 (Lab), #322 (oracle).
Goal
Build runnable pipelines from LUT-based profiles — lut8, lut16, lutAToB (mAB ), and lutBToA (mBA ) — and implement per-rendering-intent tag selection. These are the profiles that
carry CMYK printers, camera input profiles, and device links.
gamut-icc parses all four structurally and completely; none of them has an eval. This issue
turns the parsed structure into a Pipeline.
Every stage but the B-curves is optional. Note that gamut-icc deliberately accepts any stage
combination a profile signals, not only the four combinations §10.12.1 permits — so this issue
must decide whether to evaluate a non-conforming combination or reject it, and document the choice.
PCS encoding per tag type
Gotcha to encode as an explicit test:lut16Type uses the v2 16-bit Lab encoding for
PCSLAB even inside a v4 profile. Using the v4 encoding there is a small, plausible-looking,
entirely wrong result. Uses the encodings from #321.
Per-intent tag selection
A2B0/A2B1/A2B2 and B2A0/B2A1/B2A2 map to perceptual / media-relative colorimetric /
saturation. Implement selection plus the fallback rule when the requested intent's tag is absent.
Research areas
Fallback order. ICC §8's required-tag models say which tags must be present per device
class; they do not fully specify what a CMM does when an optional one is missing. Determine
lcms2's actual order in third_party/lcms2/src/cmsio1.c (its input/output LUT readers) — in
particular whether a missing intent falls back to intent 0 unconditionally.
lcms2 via #322 — the new v4 CMYK prtr with distinct A2B0/1/2 and B2A0/1/2 synthesizer exists
precisely so intent selection is observable, plus the scnr input-class camera profile and the
existing device-link synthesizers.
Acceptance criteria
All four LUT tag types assemble into a Pipeline with correct stage order, verified
stage-by-stage against lcms2 with cmsFLAGS_NOOPTIMIZE.
A v4 profile carrying a lut16Type tag decodes its PCSLAB with the v2 encoding — asserted
by a dedicated test, not incidentally.
Selecting each of the four intents on the CMYK prtr profile yields different output,
matching lcms2 per intent.
Requesting an intent whose tag is absent follows the documented fallback and matches lcms2.
The stage-combination policy (lenient vs strict) is documented in STATUS.md with its
rationale.
Part of #323. Blocked by #324 (scaffold), #325 (curves), #326 (CLUT), #321 (Lab), #322 (oracle).
Goal
Build runnable pipelines from LUT-based profiles —
lut8,lut16,lutAToB(mAB), andlutBToA(mBA) — and implement per-rendering-intent tag selection. These are the profiles thatcarry CMYK printers, camera input profiles, and device links.
gamut-iccparses all four structurally and completely; none of them has aneval. This issueturns the parsed structure into a
Pipeline.Scope
Stage assembly
Per ICC.1:2022 §10.10–10.13:
lut8/lut16: 3×3 matrix → input tables → CLUT → output tables.lutAToB(device→PCS): A-curves → CLUT → M-curves → matrix(3×3 + 3 offset) → B-curves.lutBToA(PCS→device): B-curves → matrix → M-curves → CLUT → A-curves.Every stage but the B-curves is optional. Note that
gamut-iccdeliberately accepts any stagecombination a profile signals, not only the four combinations §10.12.1 permits — so this issue
must decide whether to evaluate a non-conforming combination or reject it, and document the choice.
PCS encoding per tag type
Per-intent tag selection
A2B0/A2B1/A2B2andB2A0/B2A1/B2A2map to perceptual / media-relative colorimetric /saturation. Implement selection plus the fallback rule when the requested intent's tag is absent.
Research areas
class; they do not fully specify what a CMM does when an optional one is missing. Determine
lcms2's actual order in
third_party/lcms2/src/cmsio1.c(its input/output LUT readers) — inparticular whether a missing intent falls back to intent 0 unconditionally.
which does the CMM use, and does it depend on the requested intent? Interacts with gamut-cmm: matrix/TRC pipelines and chad / white-point conventions #327.
gamut-iccchose lenientparsing; the engine can legitimately choose strict evaluation. Pick one, document it.
lut8/lut163×3 matrix is only meaningful for XYZ PCS input; confirm the behaviour when itis present on a Lab-PCS profile.
Reference
ICC.1:2022 §10.10 (
lut8Type), §10.11 (lut16Type), §10.12 (lutAToBType), §10.13 (lutBToAType),§8 (required tags per class), Annex A (PCS encodings) — all in the vendored
references/icc/icc.1-2022-05.pdf. v2 Lab encoding:references/icc/icc.1-2001-04.pdf§6.3.4.2.The stage orderings are also transcribed in
references/icc/README.md.Behavioral oracle:
third_party/lcms2/src/cmsio1.c.Oracle
lcms2 via #322 — the new v4 CMYK
prtrwith distinct A2B0/1/2 and B2A0/1/2 synthesizer existsprecisely so intent selection is observable, plus the
scnrinput-class camera profile and theexisting device-link synthesizers.
Acceptance criteria
Pipelinewith correct stage order, verifiedstage-by-stage against lcms2 with
cmsFLAGS_NOOPTIMIZE.lut16Typetag decodes its PCSLAB with the v2 encoding — assertedby a dedicated test, not incidentally.
prtrprofile yields different output,matching lcms2 per intent.
STATUS.mdwith itsrationale.