Skip to content

Should a D2B/B2D opt-out fall back to the spectral tag when a dual-PCS profile has no colorimetric tag in that direction? Testing/Calc/CameraModel.xml now refuses (IccCmm.cpp:759) #2294

Description

@colourbill-ctrl

The question

After #2292 (09bba400) a dual-PCS profile that carries no colorimetric tag in the
direction being used
no longer resolves under the D2B/B2D opt-out: it refuses with
icCmmStatProfileMissingTag where master previously fell back to the spectral tag and
wrote a link.

Is refusing correct, or should the opt-out fall back to BToDx/DToBx when the profile
has no BToAx/AToBx to offer?

I have no strong view and did not decide it in #2292 — the fix there deliberately changed
only which tag is preferred, not what happens when the preferred one is absent. Whichever
way this is ruled I will PR it; I am not filing this to hand it off.

Why it changed

CIccXform::Create now gates the spectral branch on spectralPCS && !pcs
(IccProfLib/IccCmm.cpp:611 input, :759 output), matching the five space-selection
sites in CIccCmm::AddXform (:9093, :9112) and CIccNamedColorCmm::AddXform
(:11718, :11796, :11813). For a dual-PCS profile under the opt-out the spectral
branch is now skipped, the colorimetric block below it runs, and if that finds no tag
either the function falls through to the MatrixTRC / monochrome arms and then returns
NULL.

Before #2292 the opt-out was ignored, so the spectral tag was selected and the chain
resolved. That is the defect #1982 reported — but for a profile with only a spectral tag
in that direction, ignoring the opt-out was also the only thing keeping it working.

The affected shape, and how rare it is

Testing/Calc/CameraModel.xml: Input class, v5.00, RgbData, PCS = XYZData,
Spectral PCS = 0x0021ChannelReflectanceData, tags A2B3 and B2D3no B2A3. So
as a destination it can only go through B2D3.

Sweeping all 221 tracked *.xml for a non-empty <PCS> plus a <SpectralPCS> plus a
B2D tag gives exactly three profiles:

profile A2B B2A D2B B2D
Testing/SpecRef/SixChanCameraRef.xml 3 3 3 3
Testing/hybrid/MultSpectralRGB.xml - - - yes
Testing/Calc/CameraModel.xml 3 - - 3

Only CameraModel.xml is missing the reverse colorimetric tag, and it is used only for
XML→ICC conversion, dumping and writer-failure tests (CreateAllProfiles.sh:49,
iccdev-stdobserver-regression-tests.sh:261,275,
iccdev-issue-1148-writer-device-regression.sh:159,161,
iccdev-tool-coverage-baseline.sh:526,573-574, a iccDumpProfile -v only) — never as a
CMM source or destination. Nothing in the
suite covers this, which is why all 220 CTests on #2292's ASAN+UBSAN leg stayed green.

Build Instructions

cmake -S Build/Cmake -B build -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
cmake --build build -j4

Reproduce

build/Tools/IccFromXml/iccFromXml Testing/SpecRef/SixChanInputRef.xml six.icc
build/Tools/IccFromXml/iccFromXml Testing/Calc/CameraModel.xml       camodel.icc

# both ends opt out of D2B/B2D (intent code 11 -> icXformLutColor, bUseD2BxB2DxTags=false)
build/Tools/IccApplyToLink/iccApplyToLink link.icc 0 2 1 T 0 1 1 0 six.icc 11 camodel.icc 11

Measured Clang 21.1.3 Release. d1a7d42a is the commit before #2292 and its IccCmm.cpp
is byte-identical to f78e915a.

chain d1a7d42a (before) 09bba400 (after)
six 11 → camodel 11 exit 0, MPE Element Chain: 1 elements, 6->3 channels exit 255, status 6: Missing tag in profile
six 13 → camodel 13 exit 0, 6→3 exit 255, status 6
six 1 → camodel 1 (opt in) exit 0, 6→3 exit 0, link written

The opt-in path is unaffected; only the opt-out changed.

The two candidate rulings

  1. Refusing is correct. The caller asked for the colorimetric transform and the profile
    does not have one in that direction, so icCmmStatProfileMissingTag is the honest
    answer. Arguably ICC.2:2023 §0.1.2 supports this: the two PCS types are independent, so
    the absence of a colorimetric reverse transform is a real property of the profile, not
    something the CMM should paper over. Nothing to do but note it.

  2. Fall back to the spectral tag when there is no colorimetric one. This keeps
    CameraModel.xml-shaped profiles working and makes the carve-out tag-level ("use
    BToDx on opt-in, or when there is no BToAx") rather than header-level ("use BToDx
    on opt-in, or when the profile is spectral-only"). It is a larger change: the
    colorimetric block at IccCmm.cpp:803-837 already runs as the fallback after the
    spectral block, so a retry would need to be threaded in between that block and the
    MatrixTRC / monochrome arms at :839-848, inside a long lifetime-sensitive function.

Related: #1982, #2292.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BuildBuild system, CMake, compiler, or packagingQuestionQuestion or support requestTestingCTest, regression, or test coverageciContinuous integration workflow changesfeatureFeature request or enhancementneeds-triageMaintainer triage required

Type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions