Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions IccConnect/IccLibConnect/IccConnect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,16 @@ icStatusCMM CIccConnectCmm::AddXformFromConfig(CIccCmm* pCmm,
sErrorMsg = "unable to open ICC profile '" + pCfg->m_iccFile + "'";
}
else if (stat != icCmmStatOk) {
// AddXform rejects a profile for chain-level reasons as well as
// profile-level ones (e.g. icCmmStatBadSpaceLink (2) means the profile's
// connecting color space does not match the output space of the previous
// stage - or, for the first stage, the color space of the source data).
// A bare numeric status forced users to look up the icStatusCMM enum to
// triage failures (issue #1323), so decode it with
// CIccCmm::GetStatusText alongside the number.
std::ostringstream oss;
oss << "AddXform failed for '" << pCfg->m_iccFile << "' (status " << (int)stat << ")";
oss << "AddXform failed for '" << pCfg->m_iccFile << "' (status " << (int)stat
<< ": " << CIccCmm::GetStatusText(stat) << ")";
sErrorMsg = oss.str();
}
return stat;
Expand Down Expand Up @@ -295,8 +303,12 @@ CIccConnectCmm* CIccConnectCmm::CreateNamed(const CIccCfgProfileSequence& profil

icStatusCMM beginStat = pCmm->Begin();
if (beginStat != icCmmStatOk) {
// Decode the status (issue #1323) - Begin() is where the named-color CMM
// finalizes connections between the queued xforms, so failures here are
// chain-compatibility problems rather than per-profile ones.
std::ostringstream oss;
oss << "Begin() failed (status " << (int)beginStat << "); profile chain is incompatible";
oss << "Begin() failed (status " << (int)beginStat << ": "
<< CIccCmm::GetStatusText(beginStat) << "); profile chain is incompatible";
sErrorMsg = oss.str();
ReleasePccList(pccList);
return nullptr;
Expand Down Expand Up @@ -394,8 +406,11 @@ CIccConnectCmm* CIccConnectCmm::CreateStandard(const CIccCfgProfileSequence& pro
pCfg->m_useV5SubProfile
);
if (stat != icCmmStatOk) {
// Same status decoding as AddXformFromConfig (issue #1323): report
// the icStatusCMM name, not just the raw number.
std::ostringstream oss;
oss << "AddXform failed for embedded source profile (status " << (int)stat << ")";
oss << "AddXform failed for embedded source profile (status " << (int)stat
<< ": " << CIccCmm::GetStatusText(stat) << ")";
sStageErr = oss.str();
}
}
Expand All @@ -418,7 +433,10 @@ CIccConnectCmm* CIccConnectCmm::CreateStandard(const CIccCfgProfileSequence& pro
icStatusCMM beginStat = pCmm->Begin();
if (beginStat != icCmmStatOk) {
std::ostringstream oss;
oss << "Begin() failed (status " << (int)beginStat
// Decode the status name (issue #1323) in addition to the raw number and
// the source/destination spaces already reported below.
oss << "Begin() failed (status " << std::dec << (int)beginStat << ": "
<< CIccCmm::GetStatusText(beginStat)
<< "); profile chain is incompatible (srcSpace=0x"
<< std::hex << (unsigned)pCmm->GetSourceSpace()
<< " dstSpace=0x" << (unsigned)pCmm->GetDestSpace() << ")";
Expand Down Expand Up @@ -500,8 +518,11 @@ CIccConnectCmm* CIccConnectCmm::CreateSearch(const CIccCfgSearchApply& searchApp
sStageErr = "unable to open ICC profile '" + pCfg->m_iccFile + "'";
}
else if (stat != icCmmStatOk) {
// Same status decoding as AddXformFromConfig (issue #1323): report
// the icStatusCMM name, not just the raw number.
std::ostringstream oss;
oss << "AddXform failed for '" << pCfg->m_iccFile << "' (status " << (int)stat << ")";
oss << "AddXform failed for '" << pCfg->m_iccFile << "' (status " << (int)stat
<< ": " << CIccCmm::GetStatusText(stat) << ")";
sStageErr = oss.str();
}

Expand Down Expand Up @@ -591,7 +612,9 @@ CIccConnectCmm* CIccConnectCmm::CreateSearch(const CIccCfgSearchApply& searchApp
icStatusCMM beginStat = pCmm->Begin();
if (beginStat != icCmmStatOk) {
std::ostringstream oss;
oss << "Begin() failed (status " << (int)beginStat
// Decode the status name (issue #1323) in addition to the raw number.
oss << "Begin() failed (status " << (int)beginStat << ": "
<< CIccCmm::GetStatusText(beginStat)
<< "); search-profile chain is incompatible";
sErrorMsg = oss.str();
ReleasePccList(pccList);
Expand Down
6 changes: 6 additions & 0 deletions IccProfLib/IccCmm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8298,6 +8298,12 @@ const icChar* CIccCmm::GetStatusText(icStatusCMM stat)
return "Too many samples used";
case icCmmStatBadMCSLink:
return "Invalid MCS link connection";
// icCmmStatUnsupported was added to icStatusCMM without a matching case
// here (the enum declaration in IccCmm.h asks for GetStatusText to be kept
// in sync). Added while wiring status names into the CLI tool error
// messages for issues #1322/#1323 so every enum value decodes to text.
case icCmmStatUnsupported:
return "Unsupported operation";
default:
return "Unknown CMM Status value";

Expand Down
23 changes: 21 additions & 2 deletions Tools/CmdLine/IccApplyToLink/iccApplyToLink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,21 @@ int main(int argc, icChar* argv[])
stat = theCmm.AddXform(pXformProfile, nIntent<0 ? icUnknownIntent : (icRenderingIntent)nIntent, nInterp, pPccProfile,
(icXformLutType)nType, bUseD2BxB2DxTags, &Hint);
if (stat) {
printf("Invalid Profile(%d): %s\n", stat, argv[nCount]);
// AddXform can fail for reasons that have nothing to do with the
// profile itself. In particular icCmmStatBadSpaceLink (2) means the
// profile's source color space does not connect to the output space
// of the previous transform in the chain (CIccCmm alternates the
// input/output direction of successive profiles based on the
// first_transform argument, so the connecting spaces depend on chain
// position and direction, not just the profile). The old message
// here ("Invalid Profile(N)") reported any failure as an invalid
// profile, which misled users when a structurally valid profile was
// simply chained incompatibly - see issue #1322. Decode the status
// with CIccCmm::GetStatusText so the real cause is visible.
printf("Error - Unable to add '%s' to transform chain (status %d: %s)\n", argv[nCount], stat, CIccCmm::GetStatusText(stat));
if (stat == icCmmStatBadSpaceLink) {
printf("The profile's color spaces do not connect with the previous transform in the chain.\n");
}
return -1;
}
sigMap.clear();
Expand All @@ -809,7 +823,12 @@ int main(int argc, icChar* argv[])

//All profiles have been added to CMM. Tell CMM that we are ready to begin applying colors/pixels
if((stat=theCmm.Begin())) {
printf("Error %d - Unable to begin profile application - Possibly invalid or incompatible profiles\n", stat);
// Begin() walks the assembled xform list and connects/optimizes the
// transforms; it is where cross-profile incompatibilities that AddXform
// could not see (PCS conversion setup, connection conditions) surface.
// Decode the status code into text (issue #1322 follow-through) instead
// of printing a bare number.
printf("Error - Unable to begin profile application (status %d: %s) - Possibly invalid or incompatible profiles\n", stat, CIccCmm::GetStatusText(stat));
return -1;
}

Expand Down
Loading