74#pragma warning( disable: 4786)
88#ifdef USEREFICCMAXNAMESPACE
107#define IsSpaceColorimetricPCS(x) ((x)==icSigXYZPcsData || (x)==icSigLabPcsData)
108#define IsSpaceNChannel(x) (icGetColorSpaceType(x)==icSigNChannelData)
109#define IsSpacePCS(x) (IsSpaceColorimetricPCS(x) || IsSpaceSpectralPCS(x))
110#define IsSpaceMCS(x) (icGetColorSpaceType(x)==icSigSrcMCSChannelData)
111#define IsSpaceCMYK(x) ((x)==icSigCmykData || (x)==icSig4colorData)
113#define IsNChannelCompat(x, y) ((IsSpaceNChannel(x) && icNumColorSpaceChannels(x)==icGetSpaceSamples(y)) || (IsSpaceNChannel(y) && icNumColorSpaceChannels(y)==icGetSpaceSamples(x)))
115#define IsCompatSpace(x, y) ((x)==(y) || (IsSpacePCS(x) && IsSpacePCS(y)) || (IsSpaceMCS(x) && IsSpaceMCS(y)))
118#define ICCPCSSTEPDUMPFMT ICCMTXSTEPDUMPFMT
134CIccPCS::CIccPCS() : m_Convert{}
138 m_bLastPcsXform =
false;
156 m_bIsV2Lab =
IsSpacePCS(StartSpace) && bUseLegacyPCS;
157 m_Space = StartSpace;
179 bool bIsV2 = pXform->UseLegacyPCS();
180 bool bIsNextV2Lab = bIsV2 && (NextSpace ==
icSigLabData);
182 bool bNoClip = pXform->NoClipPCS();
184 if (m_bLastPcsXform) {
187 else if (m_bIsV2Lab && !bIsNextV2Lab) {
188 Lab2ToLab4(m_Convert, SrcPixel, bNoClip);
190 LabToXyz(m_Convert, m_Convert, bNoClip);
194 else if (!m_bIsV2Lab && bIsNextV2Lab) {
196 XyzToLab(m_Convert, SrcPixel, bNoClip);
197 SrcPixel = m_Convert;
199 Lab4ToLab2(m_Convert, SrcPixel);
202 else if (m_Space==NextSpace) {
206 XyzToLab(m_Convert, SrcPixel, bNoClip);
210 LabToXyz(m_Convert, SrcPixel, bNoClip);
217 m_Space = pXform->GetDstSpace();
241 Lab2ToLab4(Pixel, Pixel, bNoClip);
243 LabToXyz(Pixel, Pixel, bNoClip);
246 else if (m_Space==DestSpace) {
250 XyzToLab(Pixel, Pixel, bNoClip);
253 LabToXyz(Pixel, Pixel, bNoClip);
303 memcpy(&Lab,Src,
sizeof(Lab));
377 Lab2ToLab4(Dst, Src, bNoClip);
378 LabToXyz(Dst, Dst, bNoClip);
392 XyzToLab(Dst, Src, bNoClip);
393 Lab4ToLab2(Dst, Dst);
442CIccCreateXformHintManager::~CIccCreateXformHintManager()
445 IIccCreateXformHintList::iterator i;
447 for (i=m_pList->begin(); i!=m_pList->end(); i++) {
471bool CIccCreateXformHintManager::AddHint(IIccCreateXformHint* pHint)
474 m_pList =
new IIccCreateXformHintList;
478 if (GetHint(pHint->GetHintType())) {
482 IIccCreateXformHintPtr Hint;
484 m_pList->push_back(Hint);
507bool CIccCreateXformHintManager::DeleteHint(IIccCreateXformHint* pHint)
509 if (m_pList && pHint) {
510 IIccCreateXformHintList::iterator i;
511 for (i=m_pList->begin(); i!=m_pList->end(); i++) {
513 if (i->ptr == pHint) {
540IIccCreateXformHint* CIccCreateXformHintManager::GetHint(
const char* hintName)
542 IIccCreateXformHint* pHint=NULL;
545 IIccCreateXformHintList::iterator i;
546 for (i=m_pList->begin(); i!=m_pList->end(); i++) {
548 if (!strcmp(i->ptr->GetHintType(), hintName)) {
567CIccXform::CIccXform()
570 m_bOwnsProfile =
true;
574 m_bAdjustPCS =
false;
577 m_bUseSpectralPCS =
false;
578 m_bSrcPcsConversion =
true;
579 m_bDstPcsConversion =
true;
580 m_pConnectionConditions = NULL;
581 m_bDeleteEnvLooup =
true;
582 m_pCmmEnvVarLookup = NULL;
586 m_bUseD2BTags =
false;
587 m_bLuminanceMatching =
false;
588 m_PCSOffset[0] = m_PCSOffset[1] = m_PCSOffset[2] = 0;
600CIccXform::~CIccXform()
602 if (m_pProfile && m_bOwnsProfile)
609 if (m_pCmmEnvVarLookup && m_bDeleteEnvLooup) {
610 delete m_pCmmEnvVarLookup;
616void CIccXform::DetachAll()
619 m_bOwnsProfile =
true;
620 m_pConnectionConditions = NULL;
646CIccXform *CIccXform::Create(CIccProfile *pProfile,
652 bool bUseD2BTags, CIccCreateXformHintManager *pHintManager)
654 CIccXform *rv = NULL;
656 bool bUseSpectralPCS =
false;
657 bool bAbsToRel =
false;
658 bool bRelToAbs =
false;
661 bool bUseColorimeticTags =
true;
666 bUseColorimeticTags =
false;
673 CIccProfile *pEncProfile;
677 pProfile = pEncProfile;
686 switch (nUseLutType) {
708 bUseSpectralPCS =
true;
740 if (bUseColorimeticTags) {
796 switch(pProfile->m_Header.colorSpace) {
858 bUseSpectralPCS =
true;
872 if (bUseColorimeticTags) {
926 switch(pProfile->m_Header.pcs) {
945 CIccCreateNamedColorXformHint* pNamedColorHint =
new CIccCreateNamedColorXformHint();
946 pNamedColorHint->csPcs = pProfile->m_Header.pcs;
947 pNamedColorHint->csDevice = pProfile->m_Header.colorSpace;
948 pNamedColorHint->csSpectralPcs = pProfile->m_Header.spectralPCS;
949 pNamedColorHint->spectralRange = pProfile->m_Header.spectralRange;
950 pNamedColorHint->biSpectralRange = pProfile->m_Header.biSpectralRange;
952 pHintManager->AddHint(pNamedColorHint);
954 pHintManager->DeleteHint(pNamedColorHint);
957 CIccCreateXformHintManager HintManager;
958 HintManager.AddHint(pNamedColorHint);
962 if (pProfile->m_Header.spectralPCS)
963 bUseSpectralPCS =
true;
978 switch(pProfile->m_Header.pcs) {
998 switch(pProfile->m_Header.pcs) {
1016 if (pProfile->m_Header.spectralPCS) {
1021 bUseSpectralPCS =
true;
1036 if (pStructTag != NULL)
1060 if (pProfile->m_Header.spectralPCS) {
1065 bUseSpectralPCS =
true;
1091 if (pProfile->m_Header.spectralPCS) {
1122 bUseSpectralPCS =
true;
1124 if (!pTag && pProfile->m_Header.pcs != 0) {
1162 if (pTag && pProfile->m_Header.mcs) {
1183 if (pProfile->m_Header.spectralPCS) {
1214 bUseSpectralPCS =
true;
1216 if (!pTag && pProfile->m_Header.pcs!=0) {
1256 if (pTag && pProfile->m_Header.mcs) {
1268 rv->m_pConnectionConditions = pPcc;
1270 rv->m_pConnectionConditions = pProfile;
1272 rv->SetParams(pProfile, bInput, nIntent, nTagIntent, bUseSpectralPCS, nInterp, pHintManager, bAbsToRel, nMCS);
1301CIccXform *CIccXform::Create(CIccProfile *pProfile,
1307 bool bUseSpectralPCS,
1308 CIccCreateXformHintManager *pHintManager)
1310 CIccXform *rv = NULL;
1312 bool bAbsToRel =
false;
1313 bool bRelToAbs =
false;
1338 switch (pProfile->m_Header.colorSpace) {
1368 switch (pProfile->m_Header.pcs) {
1382 rv->m_pConnectionConditions = pPcc;
1384 rv->m_pConnectionConditions = pProfile;
1386 rv->SetParams(pProfile, bInput, nIntent, nTagIntent, bUseSpectralPCS, nInterp, pHintManager, bAbsToRel, nMCS);
1406 bool bUseSpectralPCS,
icXformInterp nInterp, CIccCreateXformHintManager *pHintManager,
1409 m_pProfile = pProfile;
1411 m_nIntent = nIntent;
1412 m_nTagIntent = nTagIntent;
1413 m_nInterp = nInterp;
1414 m_pAdjustPCS = NULL;
1415 m_bUseSpectralPCS = bUseSpectralPCS;
1416 m_bAbsToRel = bAbsToRel;
1418 m_bLuminanceMatching =
false;
1421 IIccCreateXformHint *pHint=NULL;
1423 pHint = pHintManager->GetHint(
"CIccCreateAdjustPCSXformHint");
1425 CIccCreateAdjustPCSXformHint *pAdjustPCSHint = (CIccCreateAdjustPCSXformHint*)pHint;
1426 m_pAdjustPCS = pAdjustPCSHint->GetNewAdjustPCSXform();
1429 pHint = pHintManager->GetHint(
"CIccCreateCmmEnvVarXformHint");
1431 CIccCreateCmmEnvVarXformHint *pCmmEnvVarHint = (CIccCreateCmmEnvVarXformHint*)pHint;
1432 m_pCmmEnvVarLookup = pCmmEnvVarHint->GetNewCmmEnvVarLookup();
1435 pHint = pHintManager->GetHint(
"CIccLuminanceMatchingHint");
1437 m_bLuminanceMatching =
true;
1465CIccXform *CIccXform::Create(CIccProfile &Profile,
1471 bool bUseD2BxB2DxTags,
1472 CIccCreateXformHintManager *pHintManager)
1474 CIccProfile *pProfile =
new CIccProfile(Profile);
1475 CIccXform *pXform = Create(pProfile, bInput, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
1506 m_MediaXYZ.X =
icFtoF16(mediaXYZ[0]);
1507 m_MediaXYZ.Y =
icFtoF16(mediaXYZ[1]);
1508 m_MediaXYZ.Z =
icFtoF16(mediaXYZ[2]);
1518 m_MediaXYZ = (*pXyzTag)[0];
1519 mediaXYZ[0] =
icFtoD(m_MediaXYZ.X);
1520 mediaXYZ[1] =
icFtoD(m_MediaXYZ.Y);
1521 mediaXYZ[2] =
icFtoD(m_MediaXYZ.Z);
1528 illXYZ.
X =
icDtoF(illumXYZ[0]);
1529 illXYZ.
Y =
icDtoF(illumXYZ[1]);
1530 illXYZ.
Z =
icDtoF(illumXYZ[2]);
1533 illXYZ = m_pProfile->m_Header.illuminant;
1534 illumXYZ[0] =
icFtoD(illXYZ.
X);
1535 illumXYZ[1] =
icFtoD(illXYZ.
Y);
1536 illumXYZ[2] =
icFtoD(illXYZ.
Z);
1541 (m_MediaXYZ.X != illXYZ.
X ||
1542 m_MediaXYZ.Y != illXYZ.
Y ||
1543 m_MediaXYZ.Z != illXYZ.
Z)) {
1548 m_bAdjustPCS =
true;
1553 m_PCSScale[0] = illumXYZ[0] / mediaXYZ[0];
1554 m_PCSScale[1] = illumXYZ[1] / mediaXYZ[1];
1555 m_PCSScale[2] = illumXYZ[2] / mediaXYZ[2];
1558 m_PCSScale[0] = mediaXYZ[0] / illumXYZ[0];
1559 m_PCSScale[1] = mediaXYZ[1] / illumXYZ[1];
1560 m_PCSScale[2] = mediaXYZ[2] / illumXYZ[2];
1564 m_PCSOffset[0] = 0.0;
1565 m_PCSOffset[1] = 0.0;
1566 m_PCSOffset[2] = 0.0;
1569 else if (m_nIntent ==
icPerceptual && (IsVersion2() || !HasPerceptualHandling())) {
1573 m_bAdjustPCS =
true;
1589 m_PCSOffset[0] = - m_PCSOffset[0] * m_PCSScale[0];
1590 m_PCSOffset[1] = - m_PCSOffset[1] * m_PCSScale[1];
1591 m_PCSOffset[2] = - m_PCSOffset[2] * m_PCSScale[2];
1598 CIccProfile ProfileCopy(*m_pProfile);
1601 if (!ProfileCopy.ReadTags(m_pProfile)) {
1605 if (!m_pAdjustPCS->CalcFactors(&ProfileCopy,
this, m_PCSScale, m_PCSOffset)) {
1609 m_bAdjustPCS =
true;
1610 delete m_pAdjustPCS;
1611 m_pAdjustPCS = NULL;
1626CIccApplyXform *CIccXform::GetNewApply(
icStatusCMM &status)
1628 CIccApplyXform *rv =
new CIccApplyXform(
this);
1658 if (UseLegacyPCS()) {
1659 CIccPCS::Lab2ToXyz(DstPixel, SrcPixel,
true);
1662 CIccPCS::LabToXyz(DstPixel, SrcPixel,
true);
1666 DstPixel[0] = SrcPixel[0];
1667 DstPixel[1] = SrcPixel[1];
1668 DstPixel[2] = SrcPixel[2];
1671 DstPixel[0] = DstPixel[0] * m_PCSScale[0] + m_PCSOffset[0];
1672 DstPixel[1] = DstPixel[1] * m_PCSScale[1] + m_PCSOffset[1];
1673 DstPixel[2] = DstPixel[2] * m_PCSScale[2] + m_PCSOffset[2];
1676 if (UseLegacyPCS()) {
1678 CIccPCS::XyzToLab2(DstPixel, DstPixel,
true);
1681 CIccPCS::XyzToLab(DstPixel, DstPixel,
true);
1684#ifndef SAMPLEICC_NOCLIPLABTOXYZ
1686 DstPixel[0] = CIccPCS::NegClip(DstPixel[0]);
1687 DstPixel[1] = CIccPCS::NegClip(DstPixel[1]);
1688 DstPixel[2] = CIccPCS::NegClip(DstPixel[2]);
1711 if (m_bAdjustPCS && !m_bInput && m_bSrcPcsConversion) {
1713 AdjustPCS(pAbsLab, Pixel);
1736 if (m_bAdjustPCS && m_bInput && m_bDstPcsConversion) {
1737 AdjustPCS(Pixel, Pixel);
1758 if (m_bPcsAdjustXform)
1759 rv = m_pProfile->m_Header.pcs;
1761 rv = m_pProfile->m_Header.colorSpace;
1774 else if (!m_bUseSpectralPCS || !m_pProfile->m_Header.spectralPCS) {
1775 rv = m_pProfile->m_Header.pcs;
1802 else if (m_bInput) {
1805 else if (!m_bUseSpectralPCS || !m_pProfile->m_Header.spectralPCS) {
1834 else if (m_bInput) {
1835 if (m_bUseSpectralPCS && m_pProfile->m_Header.spectralPCS)
1838 rv = m_pProfile->m_Header.pcs;
1841 rv = m_pProfile->m_Header.colorSpace;
1875 else if (!m_bInput) {
1878 else if (!m_bUseSpectralPCS || !m_pProfile->m_Header.spectralPCS) {
1897CIccApplyXform::CIccApplyXform(CIccXform *pXform) : m_AbsLab{}
1910CIccApplyXform::~CIccApplyXform()
1923CIccApplyNDLutXform::CIccApplyNDLutXform(CIccXformNDLut* pXform,
CIccApplyCLUT *pApply) : CIccApplyXform(pXform)
1937CIccApplyNDLutXform::~CIccApplyNDLutXform()
1952CIccApplyPcsXform::CIccApplyPcsXform(CIccXform *pXform) : CIccApplyXform(pXform)
1954 m_list =
new CIccApplyPcsStepList();
1967CIccApplyPcsXform::~CIccApplyPcsXform()
1971 CIccApplyPcsStepList::iterator i;
1972 for (i=m_list->begin(); i!=m_list->end(); i++) {
1994bool CIccApplyPcsXform::Init()
1996 CIccPcsXform *pXform = (CIccPcsXform*)m_pXform;
2004 return m_temp1!=NULL && m_temp2!=NULL;
2008void CIccApplyPcsXform::AppendApplyStep(CIccApplyPcsStep *pStep)
2010 CIccApplyPcsStepPtr ptr;
2012 if (pStep && m_list) {
2014 m_list->push_back(ptr);
2027CIccPcsXform::CIccPcsXform()
2029 m_list =
new CIccPcsStepList();
2046CIccPcsXform::~CIccPcsXform()
2049 CIccPcsStepList::iterator step;
2050 for (step=m_list->begin(); step!=m_list->end(); step++) {
2069icStatusCMM CIccPcsXform::Connect(CIccXform *pFromXform, CIccXform *pToXform)
2073 if (!pFromXform || !pToXform)
2076 if (pFromXform->IsMCS() && pToXform->IsMCS()) {
2077 CIccProfile *pFromProfile = pFromXform->GetProfilePtr();
2078 CIccProfile *pToProfile = pToXform->GetProfilePtr();
2080 if (!pFromProfile || !pToProfile) {
2086 if (!pFromChannels || !pToChannels) {
2096 m_nSrcSamples = pFromXform->GetNumDstSamples();
2097 m_nDstSamples = pToXform->GetNumSrcSamples();
2099 if (pFromChannels->
GetSize() != m_nSrcSamples || pToChannels->
GetSize() != m_nDstSamples) {
2105 for (i=0; i<m_nSrcSamples; i++) {
2107 for (j=0; j<m_nDstSamples; j++) {
2112 if (j==m_nDstSamples)
2118 for (i=0; i<m_nDstSamples; i++) {
2120 for (j=0; j<m_nSrcSamples; j++) {
2125 if (j==m_nSrcSamples)
2135 pushRouteMcs(pFromChannels, pToChannels, pDefaults);
2138 if (!pFromXform->IsInput() || (pToXform->IsInput() && !pToXform->IsAbstract())) {
2142 m_srcSpace = pFromXform->GetDstSpace();
2146 m_nSrcSamples = pFromXform->GetNumDstSamples();
2148 m_dstSpace = pToXform->GetSrcSpace();
2152 m_nDstSamples = pToXform->GetNumSrcSamples();
2154 switch (m_srcSpace) {
2156 switch (m_dstSpace) {
2158 if (pFromXform->UseLegacyPCS())
2159 pushLab2ToXyz(pFromXform->m_pConnectionConditions);
2161 pushLabToXyz(pFromXform->m_pConnectionConditions);
2162 if (pFromXform->NeedAdjustPCS()) {
2163 pushScale3(pFromXform->m_PCSScale[0], pFromXform->m_PCSScale[1], pFromXform->m_PCSScale[2]);
2164 pushOffset3(pFromXform->m_PCSOffset[0], pFromXform->m_PCSOffset[1], pFromXform->m_PCSOffset[2]);
2166 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2169 if (pToXform->NeedAdjustPCS()) {
2170 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2171 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2172 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2173 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2175 if (pToXform->UseLegacyPCS())
2176 pushXyzToLab2(pToXform->m_pConnectionConditions);
2178 pushXyzToLab(pToXform->m_pConnectionConditions);
2182 if (pFromXform->UseLegacyPCS())
2183 pushLab2ToXyz(pFromXform->m_pConnectionConditions);
2185 pushLabToXyz(pFromXform->m_pConnectionConditions);
2186 if (pFromXform->NeedAdjustPCS()) {
2187 pushScale3(pFromXform->m_PCSScale[0], pFromXform->m_PCSScale[1], pFromXform->m_PCSScale[2]);
2188 pushOffset3(pFromXform->m_PCSOffset[0], pFromXform->m_PCSOffset[1], pFromXform->m_PCSOffset[2]);
2190 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2193 if (pToXform->NeedAdjustPCS()) {
2194 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2195 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2196 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2197 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2212 switch (m_dstSpace) {
2215 if (pFromXform->NeedAdjustPCS()) {
2216 pushScale3(pFromXform->m_PCSScale[0], pFromXform->m_PCSScale[1], pFromXform->m_PCSScale[2]);
2217 pushOffset3(pFromXform->m_PCSOffset[0], pFromXform->m_PCSOffset[1], pFromXform->m_PCSOffset[2]);
2219 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2222 if (pToXform->NeedAdjustPCS()) {
2223 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2224 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2225 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2226 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2228 if (pToXform->UseLegacyPCS())
2229 pushXyzToLab2(pToXform->m_pConnectionConditions);
2231 pushXyzToLab(pToXform->m_pConnectionConditions);
2236 if (pFromXform->NeedAdjustPCS()) {
2237 pushScale3(pFromXform->m_PCSScale[0], pFromXform->m_PCSScale[1], pFromXform->m_PCSScale[2]);
2238 pushOffset3(pFromXform->m_PCSOffset[0], pFromXform->m_PCSOffset[1], pFromXform->m_PCSOffset[2]);
2240 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2243 if (pToXform->NeedAdjustPCS()) {
2244 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2245 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2246 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2247 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2263 switch (m_dstSpace) {
2265 pushRef2Xyz(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions);
2266 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2269 if (pToXform->NeedAdjustPCS()) {
2270 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2271 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2272 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2273 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2275 if (pToXform->UseLegacyPCS())
2276 pushXyzToLab2(pToXform->m_pConnectionConditions);
2278 pushXyzToLab(pToXform->m_pConnectionConditions);
2282 pushRef2Xyz(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions);
2283 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2286 if (pToXform->NeedAdjustPCS()) {
2287 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2288 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2289 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2290 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2297 pushSpecToRange(pFromXform->m_pProfile->m_Header.spectralRange,
2298 pToXform->m_pProfile->m_Header.spectralRange);
2302 pushApplyIllum(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions);
2303 pushSpecToRange(pFromXform->m_pProfile->m_Header.spectralRange,
2304 pToXform->m_pProfile->m_Header.spectralRange);
2314 CIccProfile *pFromProfile = pFromXform->GetProfilePtr();
2315 CIccProfile *pToProfile = pToXform->GetProfilePtr();
2317 switch (m_dstSpace) {
2319 pushRad2Xyz(pFromProfile, pFromXform->m_pConnectionConditions,
false);
2320 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2323 if (pToXform->NeedAdjustPCS()) {
2324 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2325 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2326 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2327 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2329 if (pToXform->UseLegacyPCS())
2330 pushXyzToLab2(pToXform->m_pConnectionConditions);
2332 pushXyzToLab(pToXform->m_pConnectionConditions);
2336 pushRad2Xyz(pFromProfile, pFromXform->m_pConnectionConditions,
false);
2337 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2340 if (pToXform->NeedAdjustPCS()) {
2341 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2342 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2343 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2344 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2355 pushSpecToRange(pFromXform->m_pProfile->m_Header.spectralRange,
2356 pToXform->m_pProfile->m_Header.spectralRange);
2368 switch (m_dstSpace) {
2370 pushBiRef2Xyz(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions);
2371 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2374 if (pToXform->NeedAdjustPCS()) {
2375 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2376 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2377 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2378 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2380 if (pToXform->UseLegacyPCS())
2381 pushXyzToLab2(pToXform->m_pConnectionConditions);
2383 pushXyzToLab(pToXform->m_pConnectionConditions);
2387 if ((stat=pushBiRef2Xyz(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions))!=
icCmmStatOk) {
2390 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2393 if (pToXform->NeedAdjustPCS()) {
2394 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2395 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2396 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2397 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2404 if ((stat=pushBiRef2Ref(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions))!=
icCmmStatOk) {
2407 pushSpecToRange(pFromXform->m_pProfile->m_Header.spectralRange,
2408 pToXform->m_pProfile->m_Header.spectralRange);
2412 if ((stat=pushBiRef2Rad(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions))!=
icCmmStatOk) {
2415 pushSpecToRange(pFromXform->m_pProfile->m_Header.spectralRange,
2416 pToXform->m_pProfile->m_Header.spectralRange);
2420 if (
icSameSpectralRange(pFromXform->m_pProfile->m_Header.spectralRange, pToXform->m_pProfile->m_Header.spectralRange) &&
2421 icSameSpectralRange(pFromXform->m_pProfile->m_Header.biSpectralRange, pToXform->m_pProfile->m_Header.biSpectralRange))
2437 if (m_list->begin()==m_list->end())
2457 CIccPcsStepList steps = *m_list;
2458 CIccPcsStepList::iterator next, last;
2463 for (next = steps.begin(); next != steps.end(); next++) {
2464 next->ptr->dump(str);
2466 printf(
"PCS_Steps:\n%s", str.c_str());
2470 CIccPcsStepList newSteps;
2475 next = steps.begin();
2476 if (next==steps.end()) {
2483 ptr.ptr = last->ptr;
2485 for (;next!=steps.end(); next++) {
2486 CIccPcsStep *pStep = ptr.ptr->concat(next->ptr);
2496 if (!ptr.ptr->isIdentity()) {
2497 newSteps.push_back(ptr);
2499 ptr.ptr = next->ptr;
2502 if (!ptr.ptr->isIdentity()) {
2503 newSteps.push_back(ptr);
2515 if (!steps.empty()) {
2516 CIccPcsStepList newSteps;
2519 for (next=steps.begin(); next != steps.end(); next++) {
2520 ptr.ptr = next->ptr->reduce();
2521 if (ptr.ptr != next->ptr)
2523 newSteps.push_back(ptr);
2543CIccApplyXform *CIccPcsXform::GetNewApply(
icStatusCMM &status)
2545 CIccApplyPcsXform *pNew =
new CIccApplyPcsXform(
this);
2548 if (!pNew->Init()) {
2559 CIccPcsStepList::iterator i;
2560 CIccApplyPcsStep *pStep;
2562 for (i=m_list->begin(); i!=m_list->end(); i++) {
2563 pStep = i->ptr->GetNewApply();
2568 pNew->AppendApplyStep(pStep);
2586 CIccPcsStepList::const_iterator s = m_list->begin();
2587 if (s==m_list->end())
2589 nMax = s->ptr->GetDstChannels();
2591 for (; s!= m_list->end(); s++) {
2592 if (s->ptr->GetSrcChannels()>nMax)
2593 nMax = s->ptr->GetSrcChannels();
2610 ptr.ptr =
new CIccPcsStepRouteMcs(pSrcChannels, pDstChannels, pDefaults);
2611 m_list->push_back(ptr);
2630 ptr.ptr =
new CIccPcsStepLab2ToXYZ(xyzWhite);
2631 m_list->push_back(ptr);
2650 ptr.ptr =
new CIccPcsStepXYZToLab2(xyzWhite);
2651 m_list->push_back(ptr);
2670 ptr.ptr =
new CIccPcsStepLabToXYZ(xyzWhite);
2671 m_list->push_back(ptr);
2690 ptr.ptr =
new CIccPcsStepXYZToLab(xyzWhite);
2691 m_list->push_back(ptr);
2705 CIccPcsStepScale *scale;
2708 scale =
new CIccPcsStepScale(3);
2715 m_list->push_back(ptr);
2726void CIccPcsXform::pushXyzToXyzIn()
2729 pushScale3(scale, scale, scale);
2741void CIccPcsXform::pushXyzInToXyz()
2744 return pushScale3(scale, scale, scale);
2763 return pushScale3(scale, scale, scale);
2782 return pushScale3(scale, scale, scale);
2798 CIccPcsStepOffset *offset;
2801 offset =
new CIccPcsStepOffset(3);
2803 if (bConvertIntXyzOffset) {
2804 data[0] = v1*65535.0f/32768.0f;
2805 data[1] = v2*65535.0f/32768.0f;
2806 data[2] = v3*65535.0f/32768.0f;
2815 m_list->push_back(ptr);
2830 CIccPcsStepScale *scale =
new CIccPcsStepScale(n);
2835 m_list->push_back(ptr);
2849 CIccPcsStepMatrix *mtx =
new CIccPcsStepMatrix(nRows, nCols);
2850 memcpy(mtx->entry(0), vals, nRows*nCols*
sizeof(
icFloatNumber));
2854 m_list->push_back(ptr);
2868icStatusCMM CIccPcsXform::pushXYZConvert(CIccXform *pFromXform, CIccXform *pToXform)
2873 if (!pSrcPcc || !pDstPcc)
2902 if (pMat && (!pOffset || (pOffset[0]==0.0 && pOffset[1]==0.0 && pOffset[2]==0.0))) {
2903 CIccPcsStepMatrix *pStepMtx =
new CIccPcsStepMatrix(3, 3);
2906 memcpy(pStepMtx->entry(0,0), pMat, 9*
sizeof(
icFloatNumber));
2920 if (!pStepMpe->Begin()) {
2928 m_list->push_back(ptr);
2950 if (pMat && (!pOffset || (pOffset[0]==0.0 && pOffset[1]==0.0 && pOffset[2]==0.0))) {
2951 CIccPcsStepMatrix *pStepMtx =
new CIccPcsStepMatrix(3, 3);
2954 memcpy(pStepMtx->entry(0,0), pMat, 9*
sizeof(
icFloatNumber));
2968 if (!pStepMpe->Begin()) {
2976 m_list->push_back(ptr);
2979 if (pFromXform->LuminanceMatching()) {
2980 pushXyzToXyzLum(pSrcPcc);
2982 if (pToXform->LuminanceMatching()) {
2983 pushXyzLumToXyz(pDstPcc);
3002 tmp.pushSpecToRange(illuminantRange, srcRange);
3003 tmp.pushSpecToRange(srcRange, dstRange);
3004 tmp.pushSpecToRange(dstRange, observerRange);
3007 tmp.pushSpecToRange(illuminantRange, observerRange);
3009 tmp.pushMatrix(3, observerRange.
steps, observer);
3012 CIccApplyXform *pApply = tmp.GetNewApply(stat);
3017 tmp.Apply(pApply, xyz, illuminant);
3020 normxyz[0] = xyz[0] / xyz[1];
3021 normxyz[1] = xyz[1] / xyz[1];
3022 normxyz[2] = xyz[2] / xyz[1];
3029 pushScale3(pccxyz[0] / (normxyz[0] * xyz[1]),
3030 pccxyz[1] / (normxyz[1] * xyz[1]),
3031 pccxyz[2] / (normxyz[2] * xyz[1]));
3033 pushScale3(1.0f/xyz[1], 1.0f/xyz[1], 1.0f/xyz[1]);
3061 pushSpecToRange(pProfile->m_Header.spectralRange, illuminantRange);
3062 pushScale(illuminantRange.
steps, illuminant);
3063 pushSpecToRange(illuminantRange, observerRange);
3064 pushMatrix(3, observerRange.
steps, observer);
3066 pushXYZNormalize(pPcc, illuminantRange, illuminantRange);
3084 srcRange.
end != dstRange.
end) {
3085 CIccPcsStepMatrix *mtx =
new CIccPcsStepMatrix(dstRange.
steps, srcRange.
steps);
3086 if (!mtx->SetRange(srcRange, dstRange))
3111 ptr.ptr = rangeMap(srcRange, dstRange);
3114 m_list->push_back(ptr);
3140 CIccPcsStepScale *pScale =
new CIccPcsStepScale(illuminantRange.
steps);
3145 m_list->push_back(ptr);
3148 ptr.ptr = rangeMap(pProfile->m_Header.spectralRange, illuminantRange);
3150 m_list->push_back(ptr);
3154 m_list->push_back(ptr);
3156 ptr.ptr = rangeMap(illuminantRange, pProfile->m_Header.spectralRange);
3158 m_list->push_back(ptr);
3178 if (pProfView && pView) {
3189 if (dPCSStepSize<dObsStepSize) {
3192 pushMatrix(3, pProfile->m_Header.spectralRange.steps, obs);
3196 pushSpecToRange(pProfile->m_Header.spectralRange, observerRange);
3197 pushMatrix(3, observerRange.
steps, observer);
3201 if (bAbsoluteCIEColorimetry) {
3207 pushScale3(k, k, k);
3230 CIccPcsStepSrcSparseMatrix *pMtx =
new CIccPcsStepSrcSparseMatrix(pProfile->m_Header.spectralRange.steps,
3231 pProfile->m_Header.biSpectralRange.steps,
3236 CIccPcsStepMatrix *illumMtx = rangeMap(illuminantRange, pProfile->m_Header.biSpectralRange);
3238 illumMtx->Apply(NULL, pMtx->data(), illuminant);
3247 m_list->push_back(ptr);
3251 CIccPcsStepSrcMatrix *pMtx =
new CIccPcsStepSrcMatrix(pProfile->m_Header.spectralRange.steps, pProfile->m_Header.biSpectralRange.steps);
3255 CIccPcsStepMatrix *illumMtx = rangeMap(illuminantRange, pProfile->m_Header.biSpectralRange);
3257 illumMtx->Apply(NULL, pMtx->data(), illuminant);
3266 m_list->push_back(ptr);
3298 pushSpecToRange(pProfile->m_Header.spectralRange, observerRange);
3299 pushMatrix(3, observerRange.
steps, observer);
3300 pushXYZNormalize(pPcc, pProfile->m_Header.biSpectralRange, pProfile->m_Header.spectralRange);
3332 CIccPcsStepScale *pScale =
new CIccPcsStepScale(pProfile->m_Header.spectralRange.steps);
3336 CIccPcsStepMatrix *illumMtx = rangeMap(illuminantRange, pProfile->m_Header.spectralRange);
3340 illumMtx->Apply(NULL, pData, illuminant);
3341 for (i=0; i<pProfile->m_Header.spectralRange.steps; i++)
3342 pData[i] = 1.0f / pData[i];
3348 m_list->push_back(ptr);
3351 for (i=0; i<pProfile->m_Header.spectralRange.steps; i++) {
3352 pData[i] = 1.0f / illuminant[i];
3368#ifdef DUMPCSSTEPRESULTS
3369 #define ICCDUMPPIXEL(n, pix) \
3373 for (i=0; i<(n); i++) { \
3376 printf(" %.5f", pix[i]); \
3381 printf("[ BigAray with %d elements]\n", (n)); \
3384 #define ICCDUMPPIXEL(n, pix)
3387 #define ICCDUMPPIXEL(n, pix)
3401 CIccApplyPcsXform *pApplyXform = (CIccApplyPcsXform*)pXform;
3402 CIccApplyPcsStepList *pList = pApplyXform->m_list;
3407 memcpy(DstPixel, SrcPixel, GetNumSrcSamples()*
sizeof(
icFloatNumber));
3412 CIccApplyPcsStepList::iterator s, n;
3413 s = n =pList->begin();
3415 if (s==pList->end()) {
3416 memcpy(DstPixel, SrcPixel, GetNumSrcSamples()*
sizeof(
icFloatNumber));
3423 if (n==pList->end()) {
3424 s->ptr->Apply(DstPixel, SrcPixel);
3425 ICCDUMPPIXEL(s->ptr->GetStep()->GetDstChannels(), DstPixel);
3433 for (;n!=pList->end(); s=n, n++) {
3434 s->ptr->Apply(p1, src);
3439 s->ptr->Apply(DstPixel, src);
3440 ICCDUMPPIXEL(s->ptr->GetStep()->GetDstChannels(), DstPixel);
3452CIccApplyPcsStep* CIccPcsStep::GetNewApply()
3454 return new CIccApplyPcsStep(
this);
3481void CIccPcsStepIdentity::dump(std::string &str)
const
3483 str +=
"\nCIccPcsStepIdentity\n\n";
3499 m_Index =
new int[m_nDstChannels];
3502 memset(m_Defaults, 0, m_nDstChannels*
sizeof(
icFloatNumber));
3505 pDefaults->
GetValues(m_Defaults, 0, m_nDstChannels);
3511 for (i=0; i<m_nDstChannels; i++) {
3513 for (j=0; j<m_nSrcChannels; j++) {
3515 szSrc = (
char*)szSrcChan;
3519 if (j==m_nSrcChannels) {
3538CIccPcsStepRouteMcs::~CIccPcsStepRouteMcs()
3543 delete [] m_Defaults;
3555bool CIccPcsStepRouteMcs::isIdentity()
const
3557 if (m_nSrcChannels!=m_nDstChannels)
3561 for (i=0; i<m_nDstChannels; i++) {
3583 for (i=0; i<m_nDstChannels; i++) {
3585 pDst[i] = pSrc[m_Index[i]];
3587 pDst[i] = m_Defaults[i];
3601void CIccPcsStepRouteMcs::dump(std::string &str)
const
3603 str +=
"\nCIccPcsStepRouteMcs\n\n";
3616bool CIccPcsLabStep::isSameWhite(
const icFloatNumber *xyzWhite)
3618 return (m_xyzWhite[0]==xyzWhite[0] &&
3619 m_xyzWhite[1]==xyzWhite[1] &&
3620 m_xyzWhite[2]==xyzWhite[2]);
3633CIccPcsStepLabToXYZ::CIccPcsStepLabToXYZ(
const icFloatNumber *xyzWhite)
3636 memcpy(m_xyzWhite, xyzWhite,
sizeof(m_xyzWhite));
3639 memcpy(m_xyzWhite,
icD50XYZ,
sizeof(m_xyzWhite));
3657 Lab[0] = pSrc[0] * 100.0f;
3673void CIccPcsStepLabToXYZ::dump(std::string &str)
const
3675 str +=
"\nCIccPcsStepLabToXYZ\n\n";
3689CIccPcsStep *CIccPcsStepLabToXYZ::concat(CIccPcsStep *pNext)
const
3691 if (pNext && pNext->GetType()==icPcsStepXYZToLab) {
3692 CIccPcsLabStep *pStep = (CIccPcsLabStep *)pNext;
3693 if (pStep->isSameWhite(m_xyzWhite))
3694 return new CIccPcsStepIdentity(3);
3708CIccPcsStepXYZToLab::CIccPcsStepXYZToLab(
const icFloatNumber *xyzWhite)
3711 memcpy(m_xyzWhite, xyzWhite,
sizeof(m_xyzWhite));
3714 memcpy(m_xyzWhite,
icD50XYZ,
sizeof(m_xyzWhite));
3732 pDst[0] = Lab[0] / 100.0f;
3746void CIccPcsStepXYZToLab::dump(std::string &str)
const
3748 str +=
"\nCIccPcsStepXYZToLab\n\n";
3762CIccPcsStep *CIccPcsStepXYZToLab::concat(CIccPcsStep *pNext)
const
3764 if (pNext && pNext->GetType()==icPcsStepLabToXYZ) {
3765 CIccPcsLabStep *pStep = (CIccPcsLabStep *)pNext;
3766 if (pStep->isSameWhite(m_xyzWhite))
3767 return new CIccPcsStepIdentity(3);
3781CIccPcsStepLab2ToXYZ::CIccPcsStepLab2ToXYZ(
const icFloatNumber *xyzWhite)
3784 memcpy(m_xyzWhite, xyzWhite,
sizeof(m_xyzWhite));
3787 memcpy(m_xyzWhite,
icD50XYZ,
sizeof(m_xyzWhite));
3804 Lab[0] = pSrc[0] * (65535.0f / 65280.0f) * 100.0f;
3805 Lab[1] = (
icFloatNumber)(pSrc[1] * 65535.0f / 65280.0f * 255.0f - 128.0f);
3806 Lab[2] = (
icFloatNumber)(pSrc[2] * 65535.0f / 65280.0f * 255.0f - 128.0f);
3820void CIccPcsStepLab2ToXYZ::dump(std::string &str)
const
3822 str +=
"\nCIccPcsStepLab2ToXYZ\n\n";
3836CIccPcsStep *CIccPcsStepLab2ToXYZ::concat(CIccPcsStep *pNext)
const
3838 if (pNext && pNext->GetType()==icPcsStepXYZToLab2) {
3839 CIccPcsLabStep *pStep = (CIccPcsLabStep *)pNext;
3840 if (pStep->isSameWhite(m_xyzWhite))
3841 return new CIccPcsStepIdentity(3);
3855CIccPcsStepXYZToLab2::CIccPcsStepXYZToLab2(
const icFloatNumber *xyzWhite)
3858 memcpy(m_xyzWhite, xyzWhite,
sizeof(m_xyzWhite));
3861 memcpy(m_xyzWhite,
icD50XYZ,
sizeof(m_xyzWhite));
3879 pDst[0] = (Lab[0] / 100.0f) * (65280.0f / 65535.0f);
3880 pDst[1] = (
icFloatNumber)((Lab[1] + 128.0f) / 255.0f) * (65280.0f / 65535.0f);
3881 pDst[2] = (
icFloatNumber)((Lab[2] + 128.0f) / 255.0f) * (65280.0f / 65535.0f);
3893void CIccPcsStepXYZToLab2::dump(std::string &str)
const
3895 str +=
"\nCIccPcsStepXYZToLab2\n\n";
3909CIccPcsStep *CIccPcsStepXYZToLab2::concat(CIccPcsStep *pNext)
const
3911 if (pNext && pNext->GetType()==icPcsStepLab2ToXYZ) {
3912 CIccPcsLabStep *pStep = (CIccPcsLabStep *)pNext;
3913 if (pStep->isSameWhite(m_xyzWhite))
3914 return new CIccPcsStepIdentity(3);
3930 m_nChannels = nChannels;
3943CIccPcsStepOffset::~CIccPcsStepOffset()
3960 if (m_nChannels==3) {
3961 pDst[0] = m_vals[0] + pSrc[0];
3962 pDst[1] = m_vals[1] + pSrc[1];
3963 pDst[2] = m_vals[2] + pSrc[2];
3967 for (i=0; i<m_nChannels; i++) {
3968 pDst[i] = m_vals[i] + pSrc[i];
3982void CIccPcsStepOffset::dump(std::string &str)
const
3984 str +=
"\nCIccPcsStepOffset\n\n";
3986 for (
int i=0; i<m_nChannels; i++) {
4003CIccPcsStepOffset *CIccPcsStepOffset::Add(
const CIccPcsStepOffset *offset)
const
4005 if (offset->m_nChannels != m_nChannels)
4008 CIccPcsStepOffset *pNew =
new CIccPcsStepOffset(m_nChannels);
4012 for (i=0; i<m_nChannels; i++) {
4013 pNew->m_vals[i] = m_vals[i] + offset->m_vals[i];
4030CIccPcsStep *CIccPcsStepOffset::concat(CIccPcsStep *pNext)
const
4032 if (pNext && pNext->GetType()==icPcsStepOffset && m_nChannels==pNext->GetSrcChannels())
4033 return Add((
const CIccPcsStepOffset*)pNext);
4047bool CIccPcsStepOffset::isIdentity()
const
4050 for (i=0; i<m_nChannels; i++) {
4069 m_nChannels = nChannels;
4082CIccPcsStepScale::~CIccPcsStepScale()
4098 if (m_nChannels==3) {
4099 pDst[0] = m_vals[0] * pSrc[0];
4100 pDst[1] = m_vals[1] * pSrc[1];
4101 pDst[2] = m_vals[2] * pSrc[2];
4105 for (i=0; i<m_nChannels; i++) {
4106 pDst[i] = m_vals[i] * pSrc[i];
4120void CIccPcsStepScale::dump(std::string &str)
const
4122 str +=
"\nCIccPcsStepScale\n\n";
4124 for (
int i=0; i<m_nChannels; i++) {
4141CIccPcsStepScale *CIccPcsStepScale::Mult(
const CIccPcsStepScale *scale)
const
4143 if (scale->m_nChannels != m_nChannels)
4146 CIccPcsStepScale *pNew =
new CIccPcsStepScale(m_nChannels);
4150 for (i=0; i<m_nChannels; i++) {
4151 pNew->m_vals[i] = m_vals[i] * scale->m_vals[i];
4166CIccPcsStepMatrix *CIccPcsStepScale::Mult(
const CIccPcsStepMatrix *matrix)
const
4168 if (matrix->GetSrcChannels() != m_nChannels)
4171 CIccPcsStepMatrix *pNew =
new CIccPcsStepMatrix(matrix->GetDstChannels(), matrix->GetSrcChannels());
4175 for (j=0; j<matrix->GetDstChannels(); j++) {
4179 for (i=0; i<m_nChannels; i++) {
4180 to[i] = m_vals[i] * row[i];
4197CIccPcsStepMatrix *CIccPcsStepScale::Mult(
const CIccMpeMatrix *matrix)
const
4211 for (i = 0; i < m_nChannels; i++) {
4212 to[i] = m_vals[i] * row[i];
4231CIccPcsStep *CIccPcsStepScale::concat(CIccPcsStep *pNext)
const
4234 if (pNext->GetType()==icPcsStepScale && m_nChannels==pNext->GetSrcChannels())
4235 return Mult((
const CIccPcsStepScale*)pNext);
4236 if (pNext->GetType()==icPcsStepMatrix && m_nChannels==pNext->GetSrcChannels())
4237 return Mult((
const CIccPcsStepMatrix*)pNext);
4238 if (pNext->GetType() == icPcsStepMpe && m_nChannels == pNext->GetSrcChannels()) {
4239 CIccPcsStepMpe *pMpe = (CIccPcsStepMpe*)pNext;
4242 return Mult(pMatrix);
4258bool CIccPcsStepScale::isIdentity()
const
4261 for (i=0; i<m_nChannels; i++) {
4279void CIccPcsStepMatrix::dump(std::string &str)
const
4281 str +=
"\nCIccPcsStepMatrix\n\n";
4295CIccPcsStepMatrix *CIccPcsStepMatrix::Mult(
const CIccPcsStepScale *scale)
const
4300 if (m_nRows != mCols)
4303 CIccPcsStepMatrix *pNew =
new CIccPcsStepMatrix(m_nRows, m_nCols);
4307 for (j=0; j<m_nRows; j++) {
4310 for (i=0; i<m_nCols; i++) {
4311 to[i] = data[j] * row[i];
4327CIccPcsStepMatrix *CIccPcsStepMatrix::Mult(
const CIccPcsStepMatrix *matrix)
const
4332 if (m_nRows != mCols)
4335 CIccPcsStepMatrix *pNew =
new CIccPcsStepMatrix(mRows, m_nCols);
4338 for (j=0; j<mRows; j++) {
4340 for (i=0; i<m_nCols; i++) {
4345 for (k=0; k<m_nRows; k++) {
4346 *to += row[k] * (*from);
4366CIccPcsStep *CIccPcsStepMatrix::concat(CIccPcsStep *pNext)
const
4369 if (pNext->GetType()==icPcsStepScale && GetDstChannels()==pNext->GetSrcChannels())
4370 return Mult((
const CIccPcsStepScale*)pNext);
4371 if (pNext->GetType()==icPcsStepMatrix && GetDstChannels()==pNext->GetSrcChannels())
4372 return Mult((
const CIccPcsStepMatrix*)pNext);
4388CIccPcsStep *CIccPcsStepMatrix::reduce()
const
4390 int nVals = m_nRows*m_nCols;
4394 for (i=0; i<nVals; i++) {
4399 if (nNonZeros<nVals*3/4) {
4401 CIccPcsStepSparseMatrix *pMtx =
new CIccPcsStepSparseMatrix(m_nRows, m_nCols, nMatrixBytes);
4403 mtx.Init(m_nRows, m_nCols,
true);
4404 mtx.FillFromFullMatrix(m_vals);
4408 return (CIccPcsStep*)
this;
4435CIccPcsStepMpe::~CIccPcsStepMpe()
4450CIccApplyPcsStep* CIccPcsStepMpe::GetNewApply()
4452 CIccApplyPcsStepMpe *rv =
new CIccApplyPcsStepMpe(
this, m_pMpe->GetNewApply());
4468 CIccApplyPcsStepMpe *pMpeApply = (CIccApplyPcsStepMpe*)pApply;
4470 m_pMpe->Apply(pMpeApply->m_pApply, pDst, pSrc);
4482void CIccPcsStepMpe::dump(std::string &str)
const
4484 str +=
"\nCIccPcsStepMpe\n\n";
4485 m_pMpe->Describe(str, 100);
4497bool CIccPcsStepMpe::isIdentity()
const
4499 if (!m_pMpe || !m_pMpe->NumElements())
4515 return m_pMpe->NumInputChannels();
4530 return m_pMpe->NumOutputChannels();
4546 if (m_pMpe->NumElements() == 1) {
4573bool CIccPcsStepMpe::Begin()
4575 return m_pMpe->
Begin();
4603CIccPcsStepSrcMatrix::~CIccPcsStepSrcMatrix()
4623 for (j=0; j<m_nRows; j++) {
4625 for (i=0; i<m_nCols; i++) {
4626 pDst[j] += row[i] * m_vals[i];
4641void CIccPcsStepSrcMatrix::dump(std::string &str)
const
4643 str +=
"\nCIccPcsStepSrcMatrix\n\n";
4645 for (
int i=0; i<m_nCols; i++) {
4665 m_nBytesPerMatrix = nBytesPerMatrix;
4679CIccPcsStepSparseMatrix::~CIccPcsStepSparseMatrix()
4699 mtx.MultiplyVector(pDst, pSrc);
4711void CIccPcsStepSparseMatrix::dump(std::string &str)
const
4713 str +=
"\nCIccPcsStepSparseMatrix\n\n";
4735 m_nChannels = nChannels;
4750CIccPcsStepSrcSparseMatrix::~CIccPcsStepSrcSparseMatrix()
4770 mtx.MultiplyVector(pDst, m_vals);
4782void CIccPcsStepSrcSparseMatrix::dump(std::string &str)
const
4784 str +=
"\nCIccPcsStepSrcSparseMatrix\n\n";
4786 for (
int i=0; i<m_nCols; i++) {
4802CIccXformMonochrome::CIccXformMonochrome()
4805 m_ApplyCurvePtr = NULL;
4806 m_bFreeCurve =
false;
4817CIccXformMonochrome::~CIccXformMonochrome()
4819 if (m_bFreeCurve && m_Curve) {
4838 status = CIccXform::Begin();
4842 m_ApplyCurvePtr = NULL;
4853 m_bFreeCurve =
true;
4861 if (!m_Curve->IsIdentity()) {
4862 m_ApplyCurvePtr = m_Curve;
4884 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
4887 Pixel[0] = SrcPixel[0];
4889 if (m_ApplyCurvePtr) {
4890 Pixel[0] = m_ApplyCurvePtr->Apply(Pixel[0]);
4900 if (UseLegacyPCS()) {
4901 CIccPCS::XyzToLab2(DstPixel, DstPixel,
true);
4904 CIccPCS::XyzToLab(DstPixel, DstPixel,
true);
4908 DstPixel[0] *= Pixel[0];
4909 DstPixel[1] *= Pixel[0];
4910 DstPixel[2] *= Pixel[0];
4920 if (UseLegacyPCS()) {
4921 CIccPCS::XyzToLab2(Pixel, Pixel,
true);
4924 CIccPCS::XyzToLab(Pixel, Pixel,
true);
4926 DstPixel[0] = SrcPixel[0]/Pixel[0];
4929 DstPixel[0] = SrcPixel[1]/Pixel[1];
4932 if (m_ApplyCurvePtr) {
4933 DstPixel[0] = m_ApplyCurvePtr->Apply(DstPixel[0]);
4937 CheckDstAbs(DstPixel);
4984 if (!(pCurve = GetCurve(
sig)))
4995 for (i=0; i<2048; i++) {
4998 Lut[i] = pCurve->
Find(x);
5018LPIccCurve* CIccXformMonochrome::ExtractInputCurves()
5024 m_ApplyCurvePtr = NULL;
5046LPIccCurve* CIccXformMonochrome::ExtractOutputCurves()
5052 m_ApplyCurvePtr = NULL;
5068CIccXformMatrixTRC::CIccXformMatrixTRC() : m_e{}
5070 m_Curve[0] = m_Curve[1] = m_Curve[2] = NULL;
5071 m_ApplyCurvePtr = NULL;
5072 m_bFreeCurve =
false;
5083CIccXformMatrixTRC::~CIccXformMatrixTRC()
5110 status = CIccXform::Begin();
5119 m_e[0] =
icFtoD((*pXYZ)[0].X);
5120 m_e[3] =
icFtoD((*pXYZ)[0].Y);
5121 m_e[6] =
icFtoD((*pXYZ)[0].Z);
5128 m_e[1] =
icFtoD((*pXYZ)[0].X);
5129 m_e[4] =
icFtoD((*pXYZ)[0].Y);
5130 m_e[7] =
icFtoD((*pXYZ)[0].Z);
5137 m_e[2] =
icFtoD((*pXYZ)[0].X);
5138 m_e[5] =
icFtoD((*pXYZ)[0].Y);
5139 m_e[8] =
icFtoD((*pXYZ)[0].Z);
5141 m_ApplyCurvePtr = NULL;
5148 if (!m_Curve[0] || !m_Curve[1] || !m_Curve[2]) {
5162 m_bFreeCurve =
true;
5164 if (!m_Curve[0] || !m_Curve[1] || !m_Curve[2]) {
5173 m_Curve[0]->Begin();
5174 m_Curve[1]->Begin();
5175 m_Curve[2]->Begin();
5177 if (!m_Curve[0]->IsIdentity() || !m_Curve[1]->IsIdentity() || !m_Curve[2]->IsIdentity()) {
5178 m_ApplyCurvePtr = m_Curve;
5199 return(pCurve->
Apply(0));
5201 return (pCurve->
Apply(1.0));
5203 return pCurve->
Apply(v);
5223 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
5224 Pixel[0] = SrcPixel[0];
5225 Pixel[1] = SrcPixel[1];
5226 Pixel[2] = SrcPixel[2];
5230 double LinR, LinG, LinB;
5231 if (m_ApplyCurvePtr) {
5232 LinR = m_ApplyCurvePtr[0]->Apply(Pixel[0]);
5233 LinG = m_ApplyCurvePtr[1]->Apply(Pixel[1]);
5234 LinB = m_ApplyCurvePtr[2]->Apply(Pixel[2]);
5251 if (m_ApplyCurvePtr) {
5252 DstPixel[0] =
RGBClip((
icFloatNumber)(m_e[0] * X + m_e[1] * Y + m_e[2] * Z), m_ApplyCurvePtr[0]);
5253 DstPixel[1] =
RGBClip((
icFloatNumber)(m_e[3] * X + m_e[4] * Y + m_e[5] * Z), m_ApplyCurvePtr[1]);
5254 DstPixel[2] =
RGBClip((
icFloatNumber)(m_e[6] * X + m_e[7] * Y + m_e[8] * Z), m_ApplyCurvePtr[2]);
5257 DstPixel[0] = (
icFloatNumber)(m_e[0] * X + m_e[1] * Y + m_e[2] * Z);
5258 DstPixel[1] = (
icFloatNumber)(m_e[3] * X + m_e[4] * Y + m_e[5] * Z);
5259 DstPixel[2] = (
icFloatNumber)(m_e[6] * X + m_e[7] * Y + m_e[8] * Z);
5263 CheckDstAbs(DstPixel);
5335 if (!(pCurve = GetCurve(
sig)))
5346 for (i=0; i<2048; i++) {
5349 Lut[i] = pCurve->
Find(x);
5369LPIccCurve* CIccXformMatrixTRC::ExtractInputCurves()
5374 Curve[0] = (
LPIccCurve)(m_Curve[0]->NewCopy());
5375 Curve[1] = (
LPIccCurve)(m_Curve[1]->NewCopy());
5376 Curve[2] = (
LPIccCurve)(m_Curve[2]->NewCopy());
5377 m_ApplyCurvePtr = NULL;
5399LPIccCurve* CIccXformMatrixTRC::ExtractOutputCurves()
5404 Curve[0] = (
LPIccCurve)(m_Curve[0]->NewCopy());
5405 Curve[1] = (
LPIccCurve)(m_Curve[1]->NewCopy());
5406 Curve[2] = (
LPIccCurve)(m_Curve[2]->NewCopy());
5407 m_ApplyCurvePtr = NULL;
5426CIccXform3DLut::CIccXform3DLut(
CIccTag *pTag)
5434 m_ApplyCurvePtrA = m_ApplyCurvePtrB = m_ApplyCurvePtrM = NULL;
5435 m_ApplyMatrixPtr = NULL;
5446CIccXform3DLut::~CIccXform3DLut()
5466 status = CIccXform::Begin();
5471 m_pTag->InputChannels()!=3) {
5475 m_ApplyCurvePtrA = NULL;
5476 m_ApplyCurvePtrB = NULL;
5477 m_ApplyCurvePtrM = NULL;
5479 if (m_pTag->m_bInputMatrix) {
5480 if (m_pTag->m_CurvesB) {
5481 Curve = m_pTag->m_CurvesB;
5487 if (!Curve[0]->IsIdentity() || !Curve[1]->IsIdentity() || !Curve[2]->IsIdentity()) {
5488 m_ApplyCurvePtrB = Curve;
5492 if (m_pTag->m_CurvesM) {
5493 Curve = m_pTag->m_CurvesM;
5499 if (!Curve[0]->IsIdentity() || !Curve[1]->IsIdentity() || !Curve[2]->IsIdentity()) {
5500 m_ApplyCurvePtrM = Curve;
5504 if (m_pTag->m_CLUT) {
5505 m_pTag->m_CLUT->
Begin();
5508 if (m_pTag->m_CurvesA) {
5509 Curve = m_pTag->m_CurvesA;
5511 for (i=0; i<m_pTag->m_nOutput; i++) {
5515 for (i=0; i<m_pTag->m_nOutput; i++) {
5516 if (!Curve[i]->IsIdentity()) {
5517 m_ApplyCurvePtrA = Curve;
5525 if (m_pTag->m_CurvesA) {
5526 Curve = m_pTag->m_CurvesA;
5532 if (!Curve[0]->IsIdentity() || !Curve[1]->IsIdentity() || !Curve[2]->IsIdentity()) {
5533 m_ApplyCurvePtrA = Curve;
5537 if (m_pTag->m_CLUT) {
5538 m_pTag->m_CLUT->
Begin();
5541 if (m_pTag->m_CurvesM) {
5542 Curve = m_pTag->m_CurvesM;
5544 for (i=0; i<m_pTag->m_nOutput; i++) {
5548 for (i=0; i<m_pTag->m_nOutput; i++) {
5549 if (!Curve[i]->IsIdentity()) {
5550 m_ApplyCurvePtrM = Curve;
5556 if (m_pTag->m_CurvesB) {
5557 Curve = m_pTag->m_CurvesB;
5559 for (i=0; i<m_pTag->m_nOutput; i++) {
5563 for (i=0; i<m_pTag->m_nOutput; i++) {
5564 if (!Curve[i]->IsIdentity()) {
5565 m_ApplyCurvePtrB = Curve;
5572 m_ApplyMatrixPtr = NULL;
5573 if (m_pTag->m_Matrix) {
5574 if (m_pTag->m_bInputMatrix) {
5575 if (m_pTag->m_nInput!=3) {
5580 if (m_pTag->m_nOutput!=3) {
5585 if (!m_pTag->m_Matrix->IsIdentity()) {
5586 m_ApplyMatrixPtr = m_pTag->m_Matrix;
5611 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
5612 Pixel[0] = SrcPixel[0];
5613 Pixel[1] = SrcPixel[1];
5614 Pixel[2] = SrcPixel[2];
5616 if (m_pTag->m_bInputMatrix) {
5617 if (m_ApplyCurvePtrB) {
5618 Pixel[0] = m_ApplyCurvePtrB[0]->Apply(Pixel[0]);
5619 Pixel[1] = m_ApplyCurvePtrB[1]->Apply(Pixel[1]);
5620 Pixel[2] = m_ApplyCurvePtrB[2]->Apply(Pixel[2]);
5623 if (m_ApplyMatrixPtr) {
5624 m_ApplyMatrixPtr->Apply(Pixel);
5627 if (m_ApplyCurvePtrM) {
5628 Pixel[0] = m_ApplyCurvePtrM[0]->Apply(Pixel[0]);
5629 Pixel[1] = m_ApplyCurvePtrM[1]->Apply(Pixel[1]);
5630 Pixel[2] = m_ApplyCurvePtrM[2]->Apply(Pixel[2]);
5633 if (m_pTag->m_CLUT) {
5635 m_pTag->m_CLUT->Interp3d(Pixel, Pixel);
5637 m_pTag->m_CLUT->Interp3dTetra(Pixel, Pixel);
5640 if (m_ApplyCurvePtrA) {
5641 for (i=0; i<m_pTag->m_nOutput; i++) {
5642 Pixel[i] = m_ApplyCurvePtrA[i]->Apply(Pixel[i]);
5648 if (m_ApplyCurvePtrA) {
5649 Pixel[0] = m_ApplyCurvePtrA[0]->Apply(Pixel[0]);
5650 Pixel[1] = m_ApplyCurvePtrA[1]->Apply(Pixel[1]);
5651 Pixel[2] = m_ApplyCurvePtrA[2]->Apply(Pixel[2]);
5654 if (m_pTag->m_CLUT) {
5656 m_pTag->m_CLUT->Interp3d(Pixel, Pixel);
5658 m_pTag->m_CLUT->Interp3dTetra(Pixel, Pixel);
5661 if (m_ApplyCurvePtrM) {
5662 for (i=0; i<m_pTag->m_nOutput; i++) {
5663 Pixel[i] = m_ApplyCurvePtrM[i]->Apply(Pixel[i]);
5667 if (m_ApplyMatrixPtr) {
5668 m_ApplyMatrixPtr->Apply(Pixel);
5671 if (m_ApplyCurvePtrB) {
5672 for (i=0; i<m_pTag->m_nOutput; i++) {
5673 Pixel[i] = m_ApplyCurvePtrB[i]->Apply(Pixel[i]);
5678 for (i=0; i<m_pTag->m_nOutput; i++) {
5679 DstPixel[i] = Pixel[i];
5682 CheckDstAbs(DstPixel);
5699LPIccCurve* CIccXform3DLut::ExtractInputCurves()
5702 if (m_pTag->m_bInputMatrix) {
5703 if (m_pTag->m_CurvesB) {
5705 Curve[0] = (
LPIccCurve)(m_pTag->m_CurvesB[0]->NewCopy());
5706 Curve[1] = (
LPIccCurve)(m_pTag->m_CurvesB[1]->NewCopy());
5707 Curve[2] = (
LPIccCurve)(m_pTag->m_CurvesB[2]->NewCopy());
5708 m_ApplyCurvePtrB = NULL;
5713 if (m_pTag->m_CurvesA) {
5715 Curve[0] = (
LPIccCurve)(m_pTag->m_CurvesA[0]->NewCopy());
5716 Curve[1] = (
LPIccCurve)(m_pTag->m_CurvesA[1]->NewCopy());
5717 Curve[2] = (
LPIccCurve)(m_pTag->m_CurvesA[2]->NewCopy());
5718 m_ApplyCurvePtrA = NULL;
5741LPIccCurve* CIccXform3DLut::ExtractOutputCurves()
5744 if (m_pTag->m_bInputMatrix) {
5745 if (m_pTag->m_CurvesA) {
5747 for (
int i=0; i<m_pTag->m_nOutput; i++) {
5748 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesA[i]->NewCopy());
5750 m_ApplyCurvePtrA = NULL;
5755 if (m_pTag->m_CurvesB) {
5757 for (
int i=0; i<m_pTag->m_nOutput; i++) {
5758 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesB[i]->NewCopy());
5760 m_ApplyCurvePtrB = NULL;
5780CIccXform4DLut::CIccXform4DLut(
CIccTag *pTag)
5788 m_ApplyCurvePtrA = m_ApplyCurvePtrB = m_ApplyCurvePtrM = NULL;
5789 m_ApplyMatrixPtr = NULL;
5801CIccXform4DLut::~CIccXform4DLut()
5822 status = CIccXform::Begin();
5828 m_pTag->InputChannels()!=4) {
5832 m_ApplyCurvePtrA = m_ApplyCurvePtrB = m_ApplyCurvePtrM = NULL;
5834 if (m_pTag->m_bInputMatrix) {
5835 if (m_pTag->m_CurvesB) {
5836 Curve = m_pTag->m_CurvesB;
5843 if (!Curve[0]->IsIdentity() || !Curve[1]->IsIdentity() ||
5844 !Curve[2]->IsIdentity() || !Curve[3]->IsIdentity())
5846 m_ApplyCurvePtrB = Curve;
5850 if (m_pTag->m_CLUT) {
5851 m_pTag->m_CLUT->
Begin();
5854 if (m_pTag->m_CurvesA) {
5855 Curve = m_pTag->m_CurvesA;
5857 for (i=0; i<m_pTag->m_nOutput; i++) {
5861 for (i=0; i<m_pTag->m_nOutput; i++) {
5862 if (!Curve[i]->IsIdentity()) {
5863 m_ApplyCurvePtrA = Curve;
5871 if (m_pTag->m_CurvesA) {
5872 Curve = m_pTag->m_CurvesA;
5879 if (!Curve[0]->IsIdentity() || !Curve[1]->IsIdentity() ||
5880 !Curve[2]->IsIdentity() || !Curve[3]->IsIdentity())
5882 m_ApplyCurvePtrA = Curve;
5886 if (m_pTag->m_CLUT) {
5887 m_pTag->m_CLUT->
Begin();
5890 if (m_pTag->m_CurvesM) {
5891 Curve = m_pTag->m_CurvesM;
5893 for (i=0; i<m_pTag->m_nOutput; i++) {
5897 for (i=0; i<m_pTag->m_nOutput; i++) {
5898 if (!Curve[i]->IsIdentity()) {
5899 m_ApplyCurvePtrM = Curve;
5905 if (m_pTag->m_CurvesB) {
5906 Curve = m_pTag->m_CurvesB;
5908 for (i=0; i<m_pTag->m_nOutput; i++) {
5912 for (i=0; i<m_pTag->m_nOutput; i++) {
5913 if (!Curve[i]->IsIdentity()) {
5914 m_ApplyCurvePtrB = Curve;
5921 m_ApplyMatrixPtr = NULL;
5922 if (m_pTag->m_Matrix) {
5923 if (m_pTag->m_bInputMatrix) {
5927 if (m_pTag->m_nOutput!=3) {
5932 if (!m_pTag->m_Matrix->IsIdentity()) {
5933 m_ApplyMatrixPtr = m_pTag->m_Matrix;
5959 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
5960 Pixel[0] = SrcPixel[0];
5961 Pixel[1] = SrcPixel[1];
5962 Pixel[2] = SrcPixel[2];
5963 Pixel[3] = SrcPixel[3];
5965 if (m_pTag->m_bInputMatrix) {
5966 if (m_ApplyCurvePtrB) {
5967 Pixel[0] = m_ApplyCurvePtrB[0]->Apply(Pixel[0]);
5968 Pixel[1] = m_ApplyCurvePtrB[1]->Apply(Pixel[1]);
5969 Pixel[2] = m_ApplyCurvePtrB[2]->Apply(Pixel[2]);
5970 Pixel[3] = m_ApplyCurvePtrB[3]->Apply(Pixel[3]);
5973 if (m_pTag->m_CLUT) {
5974 m_pTag->m_CLUT->Interp4d(Pixel, Pixel);
5977 if (m_ApplyCurvePtrA) {
5978 for (i=0; i<m_pTag->m_nOutput; i++) {
5979 Pixel[i] = m_ApplyCurvePtrA[i]->Apply(Pixel[i]);
5985 if (m_ApplyCurvePtrA) {
5986 Pixel[0] = m_ApplyCurvePtrA[0]->Apply(Pixel[0]);
5987 Pixel[1] = m_ApplyCurvePtrA[1]->Apply(Pixel[1]);
5988 Pixel[2] = m_ApplyCurvePtrA[2]->Apply(Pixel[2]);
5989 Pixel[3] = m_ApplyCurvePtrA[3]->Apply(Pixel[3]);
5992 if (m_pTag->m_CLUT) {
5993 m_pTag->m_CLUT->Interp4d(Pixel, Pixel);
5996 if (m_ApplyCurvePtrM) {
5997 for (i=0; i<m_pTag->m_nOutput; i++) {
5998 Pixel[i] = m_ApplyCurvePtrM[i]->Apply(Pixel[i]);
6002 if (m_ApplyMatrixPtr) {
6003 m_ApplyMatrixPtr->Apply(Pixel);
6006 if (m_ApplyCurvePtrB) {
6007 for (i=0; i<m_pTag->m_nOutput; i++) {
6008 Pixel[i] = m_ApplyCurvePtrB[i]->Apply(Pixel[i]);
6013 for (i=0; i<m_pTag->m_nOutput; i++) {
6014 DstPixel[i] = Pixel[i];
6017 CheckDstAbs(DstPixel);
6034LPIccCurve* CIccXform4DLut::ExtractInputCurves()
6037 if (m_pTag->m_bInputMatrix) {
6038 if (m_pTag->m_CurvesB) {
6040 Curve[0] = (
LPIccCurve)(m_pTag->m_CurvesB[0]->NewCopy());
6041 Curve[1] = (
LPIccCurve)(m_pTag->m_CurvesB[1]->NewCopy());
6042 Curve[2] = (
LPIccCurve)(m_pTag->m_CurvesB[2]->NewCopy());
6043 Curve[3] = (
LPIccCurve)(m_pTag->m_CurvesB[3]->NewCopy());
6044 m_ApplyCurvePtrB = NULL;
6049 if (m_pTag->m_CurvesA) {
6051 Curve[0] = (
LPIccCurve)(m_pTag->m_CurvesA[0]->NewCopy());
6052 Curve[1] = (
LPIccCurve)(m_pTag->m_CurvesA[1]->NewCopy());
6053 Curve[2] = (
LPIccCurve)(m_pTag->m_CurvesA[2]->NewCopy());
6054 Curve[3] = (
LPIccCurve)(m_pTag->m_CurvesA[3]->NewCopy());
6055 m_ApplyCurvePtrA = NULL;
6078LPIccCurve* CIccXform4DLut::ExtractOutputCurves()
6081 if (m_pTag->m_bInputMatrix) {
6082 if (m_pTag->m_CurvesA) {
6084 for (
int i=0; i<m_pTag->m_nOutput; i++) {
6085 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesA[i]->NewCopy());
6087 m_ApplyCurvePtrA = NULL;
6092 if (m_pTag->m_CurvesB) {
6094 for (
int i=0; i<m_pTag->m_nOutput; i++) {
6095 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesB[i]->NewCopy());
6097 m_ApplyCurvePtrB = NULL;
6118CIccXformNDLut::CIccXformNDLut(
CIccTag *pTag)
6126 m_ApplyCurvePtrA = m_ApplyCurvePtrB = m_ApplyCurvePtrM = NULL;
6127 m_ApplyMatrixPtr = NULL;
6140CIccXformNDLut::~CIccXformNDLut()
6161 status = CIccXform::Begin();
6166 if (!m_pTag || (m_pTag->InputChannels()>2 && m_pTag->InputChannels()<5)) {
6170 m_nNumInput = m_pTag->m_nInput;
6172 m_ApplyCurvePtrA = m_ApplyCurvePtrB = m_ApplyCurvePtrM = NULL;
6174 if (m_pTag->m_bInputMatrix) {
6175 if (m_pTag->m_CurvesB) {
6176 Curve = m_pTag->m_CurvesB;
6178 for (i=0; i<m_nNumInput; i++)
6181 for (i=0; i<m_nNumInput; i++) {
6182 if (!Curve[i]->IsIdentity()) {
6183 m_ApplyCurvePtrB = Curve;
6189 if (m_pTag->m_CLUT) {
6190 m_pTag->m_CLUT->
Begin();
6193 if (m_pTag->m_CurvesA) {
6194 Curve = m_pTag->m_CurvesA;
6196 for (i=0; i<m_pTag->m_nOutput; i++) {
6200 for (i=0; i<m_pTag->m_nOutput; i++) {
6201 if (!Curve[i]->IsIdentity()) {
6202 m_ApplyCurvePtrA = Curve;
6210 if (m_pTag->m_CurvesA) {
6211 Curve = m_pTag->m_CurvesA;
6213 for (i=0; i<m_nNumInput; i++)
6216 for (i=0; i<m_nNumInput; i++) {
6217 if (!Curve[i]->IsIdentity()) {
6218 m_ApplyCurvePtrA = Curve;
6224 if (m_pTag->m_CLUT) {
6225 m_pTag->m_CLUT->
Begin();
6228 if (m_pTag->m_CurvesM) {
6229 Curve = m_pTag->m_CurvesM;
6231 for (i=0; i<m_pTag->m_nOutput; i++) {
6235 for (i=0; i<m_pTag->m_nOutput; i++) {
6236 if (!Curve[i]->IsIdentity()) {
6237 m_ApplyCurvePtrM = Curve;
6243 if (m_pTag->m_CurvesB) {
6244 Curve = m_pTag->m_CurvesB;
6246 for (i=0; i<m_pTag->m_nOutput; i++) {
6250 for (i=0; i<m_pTag->m_nOutput; i++) {
6251 if (!Curve[i]->IsIdentity()) {
6252 m_ApplyCurvePtrB = Curve;
6259 m_ApplyMatrixPtr = NULL;
6260 if (m_pTag->m_Matrix) {
6261 if (m_pTag->m_bInputMatrix) {
6265 if (m_pTag->m_nOutput!=3) {
6270 if (!m_pTag->m_Matrix->IsIdentity()) {
6271 m_ApplyMatrixPtr = m_pTag->m_Matrix;
6290CIccApplyXform* CIccXformNDLut::GetNewApply(
icStatusCMM& status)
6295 CIccCLUT* pCLUT = m_pTag->GetCLUT();
6298 if (pCLUT && m_nNumInput > 6) {
6306 CIccApplyNDLutXform* rv =
new CIccApplyNDLutXform(
this, pApply);
6337 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
6338 for (i=0; i<m_nNumInput; i++)
6339 Pixel[i] = SrcPixel[i];
6341 if (m_pTag->m_bInputMatrix) {
6342 if (m_ApplyCurvePtrB) {
6343 for (i=0; i<m_nNumInput; i++)
6344 Pixel[i] = m_ApplyCurvePtrB[i]->Apply(Pixel[i]);
6347 if (m_pTag->m_CLUT) {
6348 switch(m_nNumInput) {
6350 m_pTag->m_CLUT->Interp5d(Pixel, Pixel);
6353 m_pTag->m_CLUT->Interp6d(Pixel, Pixel);
6357 CIccApplyNDLutXform* pNDApply = (CIccApplyNDLutXform*)pApply;
6358 m_pTag->m_CLUT->InterpND(Pixel, Pixel, pNDApply->m_pApply);
6364 if (m_ApplyCurvePtrA) {
6365 for (i=0; i<m_pTag->m_nOutput; i++) {
6366 Pixel[i] = m_ApplyCurvePtrA[i]->Apply(Pixel[i]);
6372 if (m_ApplyCurvePtrA) {
6373 for (i=0; i<m_nNumInput; i++)
6374 Pixel[i] = m_ApplyCurvePtrA[i]->Apply(Pixel[i]);
6377 if (m_pTag->m_CLUT) {
6378 switch(m_nNumInput) {
6380 m_pTag->m_CLUT->Interp5d(Pixel, Pixel);
6383 m_pTag->m_CLUT->Interp6d(Pixel, Pixel);
6387 CIccApplyNDLutXform* pNDApply = (CIccApplyNDLutXform*)pApply;
6388 m_pTag->m_CLUT->InterpND(Pixel, Pixel, pNDApply->m_pApply);
6395 if (m_ApplyCurvePtrM) {
6396 for (i=0; i<m_pTag->m_nOutput; i++) {
6397 Pixel[i] = m_ApplyCurvePtrM[i]->Apply(Pixel[i]);
6401 if (m_ApplyMatrixPtr) {
6402 m_ApplyMatrixPtr->Apply(Pixel);
6405 if (m_ApplyCurvePtrB) {
6406 for (i=0; i<m_pTag->m_nOutput; i++) {
6407 Pixel[i] = m_ApplyCurvePtrB[i]->Apply(Pixel[i]);
6412 for (i=0; i<m_pTag->m_nOutput; i++) {
6413 DstPixel[i] = Pixel[i];
6416 CheckDstAbs(DstPixel);
6433LPIccCurve* CIccXformNDLut::ExtractInputCurves()
6436 if (m_pTag->m_bInputMatrix) {
6437 if (m_pTag->m_CurvesB) {
6439 for (
int i=0; i<m_pTag->m_nInput; i++) {
6440 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesB[i]->NewCopy());
6442 m_ApplyCurvePtrB = NULL;
6447 if (m_pTag->m_CurvesA) {
6449 for (
int i=0; i<m_pTag->m_nInput; i++) {
6450 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesA[i]->NewCopy());
6452 m_ApplyCurvePtrA = NULL;
6475LPIccCurve* CIccXformNDLut::ExtractOutputCurves()
6478 if (m_pTag->m_bInputMatrix) {
6479 if (m_pTag->m_CurvesA) {
6481 for (
int i=0; i<m_pTag->m_nOutput; i++) {
6482 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesA[i]->NewCopy());
6484 m_ApplyCurvePtrA = NULL;
6489 if (m_pTag->m_CurvesB) {
6491 for (
int i=0; i<m_pTag->m_nOutput; i++) {
6492 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesB[i]->NewCopy());
6494 m_ApplyCurvePtrB = NULL;
6521 m_nApplyInterface = icApplyPixel2Pixel;
6528 m_pTag->SetColorSpaces(csPcs, csDevice);
6537 pNamed->
SetColorSpaces(csPcs, csDevice, csSpectralPcs, pSpectralRange, pBiSpectralRange);
6556CIccXformNamedColor::~CIccXformNamedColor()
6574 status = CIccXform::Begin();
6578 if (m_pTag==NULL && m_pArray==NULL) {
6589 m_nApplyInterface = icApplyPixel2Pixel;
6592 m_nApplyInterface = icApplyPixel2Named;
6597 m_nApplyInterface = icApplyNamed2Pixel;
6604 if (m_pTag && !m_pTag->InitFindCachedPCSColor())
6606 else if (m_pArray && !m_pArray->Begin())
6634 std::string NamedColor;
6640 NamedColor = pColor->
getName();
6645 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
6658 NamedColor = pColor->
getName();
6666 NamedColor = pColor->
getName();
6671 sprintf(DstColorName,
"%s", NamedColor.c_str());
6677 std::string NamedColor;
6681 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
6683 PCSPix[i] = SrcPixel[i];
6689 for(i=0; i<m_pTag->GetDeviceCoords(); i++)
6690 DevicePix[i] = SrcPixel[i];
6696 sprintf(DstColorName,
"%s", NamedColor.c_str());
6729 pColor = pArray->
FindColor(SrcColorName);
6739 if (!pArray->
GetPcsTint(DstPixel, pColor, tint))
6748 CheckDstAbs(DstPixel);
6776 CheckDstAbs(DstPixel);
6808 if (nSrcSpace!=pTag->
GetPCS())
6814 m_nSrcSpace = nSrcSpace;
6832 if (m_nSrcSpace == nDestSpace)
6841 if (nDestSpace!=pTag->
GetPCS())
6847 m_nDestSpace = nDestSpace;
6860bool CIccXformNamedColor::IsSrcPCS()
const
6863 return m_nSrcSpace == m_pTag->
GetPCS();
6865 else if (m_pArray) {
6881bool CIccXformNamedColor::IsDestPCS()
const
6884 return m_nDestSpace == m_pTag->GetPCS();
6886 else if (m_pArray) {
6902CIccXformMpe::CIccXformMpe(
CIccTag *pTag)
6909 m_bUsingAcs =
false;
6910 m_pAppliedPCC = NULL;
6911 m_bDeleteAppliedPCC =
false;
6922CIccXformMpe::~CIccXformMpe()
6924 if (m_pAppliedPCC && m_bDeleteAppliedPCC)
6925 delete m_pAppliedPCC;
6950CIccXform *CIccXformMpe::Create(CIccProfile *pProfile,
bool bInput,
icRenderingIntent nIntent,
6952 CIccCreateXformHintManager *pHintManager)
6954 CIccXform *rv = NULL;
6956 bool bUseSpectralPCS =
false;
6957 bool bAbsToRel =
false;
6959 bool bUseColorimeticTags =
true;
6960 bool bUseDToB =
true;
6964 bUseColorimeticTags =
false;
6974 switch (nUseLutType) {
7003 if (pTag && pProfile->m_Header.spectralPCS) {
7004 bUseSpectralPCS =
true;
7007 if (bUseColorimeticTags) {
7021 rv =
new CIccXformMatrixTRC();
7027 rv =
new CIccXformMpe(pTag);
7030 switch(pProfile->m_Header.colorSpace) {
7041 rv =
new CIccXform3DLut(pTag);
7046 rv =
new CIccXform4DLut(pTag);
7050 rv =
new CIccXformNDLut(pTag);
7083 if (bUseColorimeticTags) {
7097 rv =
new CIccXformMatrixTRC();
7104 rv =
new CIccXformMpe(pTag);
7107 switch(pProfile->m_Header.pcs) {
7110 rv =
new CIccXform3DLut(pTag);
7125 rv =
new CIccXformNamedColor(pTag, pProfile->m_Header.pcs, pProfile->m_Header.colorSpace,
7126 pProfile->m_Header.spectralPCS,
7127 &pProfile->m_Header.spectralRange,
7128 &pProfile->m_Header.biSpectralRange);
7143 switch(pProfile->m_Header.pcs) {
7146 rv =
new CIccXform3DLut(pTag);
7163 switch(pProfile->m_Header.pcs) {
7166 rv =
new CIccXform3DLut(pTag);
7177 rv->SetParams(pProfile, bInput, nIntent, nTagIntent, bUseSpectralPCS, nInterp, pHintManager, bAbsToRel);
7192bool CIccXformMpe::IsLateBinding()
const
7195 return m_pTag->IsLateBinding();
7209bool CIccXformMpe::IsLateBindingReflectance()
const
7212 return m_pTag->IsLateBindingReflectance();
7228 return m_pAppliedPCC;
7230 return m_pConnectionConditions;
7246 if (m_pAppliedPCC && m_bDeleteAppliedPCC) {
7247 delete m_pAppliedPCC;
7249 m_pAppliedPCC = NULL;
7250 m_bDeleteAppliedPCC =
false;
7255 bool bReflectance = m_pTag->IsLateBindingReflectance();
7258 if (!bReflectance) {
7262 if (pViewPCC && pViewProfile &&
7266 m_pAppliedPCC = pPCC;
7267 m_bDeleteAppliedPCC =
false;
7271 m_bDeleteAppliedPCC =
true;
7276 m_bDeleteAppliedPCC =
true;
7280 m_pAppliedPCC = NULL;
7284 m_pAppliedPCC = pPCC;
7285 m_bDeleteAppliedPCC =
false;
7304 status = CIccXform::Begin();
7313 if (!m_pTag->Begin(
icElemInterpLinear, GetProfileCC(), GetConnectionConditions(), GetCmmEnvVarLookup())) {
7330CIccApplyXform *CIccXformMpe::GetNewApply(
icStatusCMM &status)
7335 CIccApplyXformMpe *rv=
new CIccApplyXformMpe(
this);
7342 rv->m_pApply = m_pTag->GetNewApply();
7343 if (!rv->m_pApply) {
7372 if (!m_bInput || m_bPcsAdjustXform) {
7374 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
7379 switch (GetSrcSpace()) {
7383 SrcPixel = &temp[0];
7389 SrcPixel = &temp[0];
7398 CIccApplyXformMpe *pApplyMpe = (CIccApplyXformMpe *)pApply;
7400 pTag->
Apply(pApplyMpe->m_pApply, DstPixel, SrcPixel);
7405 switch(GetDstSpace()) {
7419 CheckDstAbs(DstPixel);
7432CIccApplyXformMpe::CIccApplyXformMpe(CIccXformMpe *pXform) : CIccApplyXform(pXform)
7445CIccApplyXformMpe::~CIccApplyXformMpe()
7461CIccApplyCmm::CIccApplyCmm(CIccCmm *pCmm)
7464 m_pPCS = m_pCmm->GetPCS();
7466 m_Xforms =
new CIccApplyXformList;
7481CIccApplyCmm::~CIccApplyCmm()
7484 CIccApplyXformList::iterator i;
7486 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
7503bool CIccApplyCmm::InitPixel()
7505 if (m_Pixel && m_Pixel2)
7509 CIccApplyXformList::iterator i;
7511 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
7512 if (i->ptr->GetXform()) {
7513 icUInt16Number nXformSamples = i->ptr->GetXform()->GetNumDstSamples();
7514 if (nXformSamples>nSamples)
7515 nSamples=nXformSamples;
7521 if (!m_Pixel || !m_Pixel2)
7529#ifdef DEBUG_CMM_APPLY
7532 printf(
"Xfm%d:", nCount);
7536 printf(
" %.3f", pPixel[i]);
7559 CIccApplyXformList::iterator i;
7560 const CIccXform *pLastXform;
7561 int j, n = (int)m_Xforms->size();
7567 if (!m_Pixel && !InitPixel()) {
7571 m_pPCS->Reset(m_pCmm->m_nSrcSpace);
7576#ifdef DEBUG_CMM_APPLY
7578 printf(
"Start ApplyCmm\n");
7583 for (j=0, i=m_Xforms->begin(); j<n-1 && i!=m_Xforms->end(); i++, j++) {
7585 i->ptr->Apply(pDst, m_pPCS->Check(pSrc, i->ptr->GetXform()));
7587#ifdef DEBUG_CMM_APPLY
7588 DumpCmmApplyPixel(nCount++, pDst, i->ptr->GetXform()->GetNumDstSamples());
7593 if (pTmp == SrcPixel)
7599 pLastXform = i->ptr->GetXform();
7600 i->ptr->Apply(DstPixel, m_pPCS->Check(pSrc, pLastXform));
7601 bNoClip = pLastXform->NoClipPCS();
7604 i = m_Xforms->begin();
7606 pLastXform = i->ptr->GetXform();
7607 i->ptr->Apply(DstPixel, m_pPCS->Check(SrcPixel, pLastXform));
7609#ifdef DEBUG_CMM_APPLY
7610 DumpCmmApplyPixel(nCount++, pDst, i->ptr->GetXform()->GetNumDstSamples());
7613 bNoClip = pLastXform->NoClipPCS();
7619 m_pPCS->CheckLast(DstPixel, m_pCmm->m_nDestSpace, bNoClip);
7621#ifdef DEBUG_CMM_APPLY
7623 printf(
"End ApplyCmm\n\n");
7645 CIccApplyXformList::iterator i;
7646 int j, n = (int)m_Xforms->size();
7652 if (!m_Pixel && !InitPixel()) {
7656 for (k=0; k<nPixels; k++) {
7657 m_pPCS->Reset(m_pCmm->m_nSrcSpace);
7663 for (j=0, i=m_Xforms->begin(); j<n-1 && i!=m_Xforms->end(); i++, j++) {
7665 i->ptr->Apply(pDst, m_pPCS->Check(pSrc, i->ptr->GetXform()));
7674 i->ptr->Apply(DstPixel, m_pPCS->Check(pSrc, i->ptr->GetXform()));
7677 i = m_Xforms->begin();
7678 i->ptr->Apply(DstPixel, m_pPCS->Check(SrcPixel, i->ptr->GetXform()));
7681 m_pPCS->CheckLast(DstPixel, m_pCmm->m_nDestSpace);
7683 DstPixel += m_pCmm->GetDestSamples();
7684 SrcPixel += m_pCmm->GetSourceSamples();
7690void CIccApplyCmm::AppendApplyXform(CIccApplyXform *pApplyXform)
7692 CIccApplyXformPtr ptr;
7693 ptr.ptr = pApplyXform;
7695 m_Xforms->push_back(ptr);
7717 m_bLastInput = !bFirstInput;
7718 m_nSrcSpace = nSrcSpace;
7719 m_nDestSpace = nDestSpace;
7721 m_nLastSpace = nSrcSpace;
7724 m_Xforms =
new CIccXformList;
7741 CIccXformList::iterator i;
7743 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
7763 return "Cannot open profile";
7765 return "Invalid space link";
7767 return "Invalid profile";
7769 return "Invalid profile transform";
7771 return "Invalid Look-Up Table";
7773 return "Missing tag in profile";
7775 return "Color not found";
7777 return "Incorrect Apply object";
7779 return "Invalid color encoding used";
7781 return "Memory allocation error";
7783 return "Invalid Look-Up Table type";
7785 return "Identity transform used";
7787 return "Unsupported PCS Link used";
7789 return "Invalid profile connection";
7791 return "Invalid tint transform";
7793 return "Too many samples used";
7795 return "Invalid MCS link connection";
7797 return "Unknown CMM Status value";
7825 bool bUseD2BxB2DxTags ,
7826 CIccCreateXformHintManager *pHintManager ,
7827 bool bUseSubProfile )
7829 CIccProfile *pProfile =
OpenIccProfile(szProfilePath, bUseSubProfile);
7834 icStatusCMM rv = AddXform(pProfile, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
7870 bool bUseD2BxB2DxTags ,
7871 CIccCreateXformHintManager *pHintManager ,
7872 bool bUseSubProfile )
7876 if (!pFile || !pFile->
Attach(pProfileMem, nProfileLen, bUseSubProfile))
7879 CIccProfile *pProfile =
new CIccProfile;
7884 if (!pProfile->Attach(pFile)) {
7890 icStatusCMM rv = AddXform(pProfile, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
7918icStatusCMM CIccCmm::AddXform(CIccProfile *pProfile,
7923 bool bUseD2BxB2DxTags ,
7924 CIccCreateXformHintManager *pHintManager )
7927 bool bInput = !m_bLastInput;
7932 switch(pProfile->m_Header.deviceClass) {
7950 nSrcSpace = pProfile->m_Header.colorSpace;
7955 nDstSpace = pProfile->m_Header.pcs;
7969 nSrcSpace = pProfile->m_Header.pcs;
7971 nDstSpace = pProfile->m_Header.colorSpace;
7977 nSrcSpace = pProfile->m_Header.pcs;
7978 nDstSpace = pProfile->m_Header.pcs;
7983 nSrcSpace = pProfile->m_Header.pcs;
7991 nSrcSpace = pProfile->m_Header.colorSpace;
8000 nDstSpace = pProfile->m_Header.pcs;
8013 nSrcSpace = pProfile->m_Header.colorSpace;
8017 if (m_Xforms->size()) {
8018 CIccXformList::iterator prev = --(m_Xforms->end());
8023 if (!prev->ptr->GetProfile()->m_Header.mcs) {
8027 CIccXform *pPrev = prev->ptr;
8028 CIccXform *pNew = CIccXform::Create(pPrev->GetProfilePtr(), pPrev->IsInput(), pPrev->GetIntent(), pPrev->GetInterp(),
8029 pPrev->GetConnectionConditions(),
icXformLutMCS, bUseD2BxB2DxTags, pHintManager);
8046 if (bUseD2BxB2DxTags && pProfile->m_Header.spectralPCS) {
8050 nDstSpace = pProfile->m_Header.pcs;
8054 nDstSpace = pProfile->m_Header.colorSpace;
8067 if (!m_Xforms->size()) {
8069 m_nLastSpace = nSrcSpace;
8070 m_nSrcSpace = nSrcSpace;
8089 nIntent = m_nLastIntent;
8097 Xform.ptr = CIccXform::Create(pProfile, bInput, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
8107 m_nLastSpace = nDstSpace;
8108 m_nLastIntent = nIntent;
8109 m_bLastInput = bInput;
8111 m_Xforms->push_back(Xform);
8135icStatusCMM CIccCmm::AddXform(CIccProfile *pProfile,
8140 bool bUseSpectralPCS ,
8141 CIccCreateXformHintManager *pHintManager )
8144 bool bInput = !m_bLastInput;
8149 switch (pProfile->m_Header.deviceClass) {
8161 nSrcSpace = pProfile->m_Header.colorSpace;
8163 if (bUseSpectralPCS && pProfile->m_Header.spectralPCS)
8166 nDstSpace = pProfile->m_Header.pcs;
8167 bUseSpectralPCS =
false;
8179 if (bUseSpectralPCS && pProfile->m_Header.spectralPCS)
8182 nSrcSpace = pProfile->m_Header.pcs;
8183 bUseSpectralPCS =
false;
8186 nDstSpace = pProfile->m_Header.colorSpace;
8190 if (!m_Xforms->size()) {
8192 m_nLastSpace = nSrcSpace;
8193 m_nSrcSpace = nSrcSpace;
8212 nIntent = m_nLastIntent;
8220 Xform.ptr = CIccXform::Create(pProfile, pXformTag, bInput, nIntent, nInterp, pPcc, bUseSpectralPCS, pHintManager);
8226 m_nLastSpace = nDstSpace;
8227 m_nLastIntent = nIntent;
8228 m_bLastInput = bInput;
8230 m_Xforms->push_back(Xform);
8254icStatusCMM CIccCmm::AddXform(CIccProfile &Profile,
8259 bool bUseD2BxB2DxTags ,
8260 CIccCreateXformHintManager *pHintManager )
8262 CIccProfile *pProfile =
new CIccProfile(Profile);
8267 icStatusCMM stat = AddXform(pProfile, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
8275icStatusCMM CIccCmm::CheckPCSConnections(
bool bUsePCSConversions)
8279 CIccXformList::iterator last, next;
8280 CIccXformList xforms;
8282 bool bUsesPcsXforms =
false;
8284 next=m_Xforms->begin();
8286 if (next!=m_Xforms->end()) {
8290 xforms.push_back(*last);
8292 for (;next!=m_Xforms->end(); last=next, next++) {
8293 if ((last->ptr->IsInput() && last->ptr->IsMCS() && next->ptr->IsMCS()) ||
8295 (!bUsePCSConversions &&
8297 last->ptr->SetDstPCSConversion(
false);
8298 next->ptr->SetSrcPCSConversion(
false);
8299 CIccPcsXform *pPcs =
new CIccPcsXform();
8305 rv = pPcs->Connect(last->ptr, next->ptr);
8312 xforms.push_back(ptr);
8318 bUsesPcsXforms =
true;
8320 xforms.push_back(*next);
8324 if (bUsesPcsXforms) {
8335 CIccXformList::iterator last, next;
8336 CIccXformList xforms;
8338 bool bUsesRangeConversion =
false;
8340 next = m_Xforms->begin();
8342 if (next != m_Xforms->end()) {
8346 xforms.push_back(*last);
8348 for (; next != m_Xforms->end(); last = next, next++) {
8350 if (last->ptr->IsInput() && last->ptr->IsExtendedPCS() &&
IsSpaceColorimetricPCS(last->ptr->GetDstSpace()) &&
8351 !next->ptr->IsExtendedPCS()) {
8352 CIccProfile* pProfile = last->ptr->GetProfilePtr();
8362 ptr.ptr = CIccXform::Create(pProfile, pTag,
true, last->ptr->GetIntent(), last->ptr->GetInterp(),
8363 last->ptr->GetConnectionConditions(),
false);
8365 ptr.ptr->ShareProfile();
8366 ptr.ptr->SetPcsAdjustXform();
8367 ptr.ptr->AttachCmmEnvVarLookup(last->ptr->GetCmmEnvVarLookup());
8368 xforms.push_back(ptr);
8369 bUsesRangeConversion =
true;
8374 xforms.push_back(*next);
8378 if (bUsesRangeConversion) {
8396void CIccCmm::SetLateBindingCC()
8398 CIccXformList::iterator i;
8399 CIccXform *pLastXform = NULL;
8401 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
8402 if (i->ptr->IsInput()) {
8403 if (i->ptr->IsLateBinding()) {
8404 CIccXformList::iterator j=i;
8406 if (j!=m_Xforms->end()) {
8407 if (j->ptr->IsLateBinding()) {
8408 i->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8409 j->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8410 pLastXform = i->ptr;
8413 i->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8414 j->ptr->SetAppliedCC(j->ptr->GetConnectionConditions());
8419 i->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8424 CIccXformList::iterator j=i;
8426 if (j!=m_Xforms->end()) {
8427 if (j->ptr->IsLateBinding()) {
8428 j->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8429 pLastXform = i->ptr;
8431 else if (!j->ptr->IsAbstract()){
8432 j->ptr->SetAppliedCC(j->ptr->GetConnectionConditions());
8443 i->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8461icStatusCMM CIccCmm::Begin(
bool bAllocApplyCmm,
bool bUsePCSConversions)
8467 m_nDestSpace = m_nLastSpace;
8477 CheckPCSRangeConversions();
8481 CIccXformList::iterator i;
8483 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
8485 rv = i->ptr->Begin();
8491 rv = CheckPCSConnections(bUsePCSConversions);
8495 if (bAllocApplyCmm) {
8496 m_pApply = GetNewApplyCmm(rv);
8516CIccApplyCmm *CIccCmm::GetNewApplyCmm(
icStatusCMM &status)
8518 CIccApplyCmm *pApply =
new CIccApplyCmm(
this);
8525 CIccXformList::iterator i;
8526 CIccApplyXform *pXform;
8528 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
8529 pXform = i->ptr->GetNewApply(status);
8534 pApply->AppendApplyXform(pXform);
8557 return m_pApply->Apply(DstPixel, SrcPixel);
8573 return m_pApply->Apply(DstPixel, SrcPixel, nPixels);
8596 CIccXformList::iterator i;
8598 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
8623 if (!((
unsigned int)((*pInternal)*255.0)))
8702 case icEncode16BitV2:
8708 CIccPCS::Lab2ToLab4(pInput, pInput);
8729 case icEncodePercent:
8744 case icEncode16BitV2:
8767 if (!bCLRspace || nSamples<3) {
8775 case icEncodePercent:
8778 for(i=0; i<nSamples; i++) {
8780 if (pInput[i] < 0.0) pInput[i] = 0.0;
8781 if (pInput[i] > 1.0) pInput[i] = 1.0;
8785 for(i=0; i<nSamples; i++) {
8795 for(i=0; i<nSamples; i++) {
8796 if (pInput[i] < 0.0) pInput[i] = 0.0;
8797 if (pInput[i] > 1.0) pInput[i] = 1.0;
8805 for(i=0; i<nSamples; i++) {
8812 case icEncode16BitV2:
8814 for(i=0; i<nSamples; i++) {
8873 if (!FloatPixel.get())
8876 for(i=0; i<nSamples; i++) {
8879 return ToInternalEncoding(nSpace, icEncode8Bit, pInternal, FloatPixel);
8926 if (!pFloatPixel.get())
8929 for(i=0; i<nSamples; i++) {
8932 return ToInternalEncoding(nSpace, icEncode16Bit, pInternal, pFloatPixel);
8979 case icEncodeUnitFloat:
9000 case icEncode16BitV2:
9002 CIccPCS::Lab4ToLab2(pInput, pInput);
9024 case icEncodePercent:
9033 case icEncodeUnitFloat:
9040 case icEncode16BitV2:
9067 else if (bCLRspace && nSamples >=3) {
9072 case icEncodePercent:
9075 for(i=0; i<nSamples; i++) {
9076 if (pInput[i] < 0.0) pInput[i] = 0.0;
9077 if (pInput[i] > 1.0) pInput[i] = 1.0;
9082 for(i=0; i<nSamples; i++) {
9092 case icEncodeUnitFloat:
9095 for(i=0; i<nSamples; i++) {
9096 if (pInput[i] < 0.0) pInput[i] = 0.0;
9097 if (pInput[i] > 1.0) pInput[i] = 1.0;
9105 for(i=0; i<nSamples; i++) {
9106 pInput[i] =
icFtoU8(pInput[i]);
9112 case icEncode16BitV2:
9114 for(i=0; i<nSamples; i++) {
9154 pData[0] =
icFtoU8(pInternal[0]);
9155 pData[1] =
icFtoU8(pInternal[1]);
9156 pData[2] =
icFtoU8(pInternal[2]);
9162 pData[0] =
icFtoU8(pInternal[0]);
9163 pData[1] =
icFtoU8(pInternal[1]);
9164 pData[2] =
icFtoU8(pInternal[2]);
9165 pData[3] =
icFtoU8(pInternal[3]);
9177 if (!pFloatPixel.get())
9180 convertStat = FromInternalEncoding(nSpace, icEncode8Bit, pFloatPixel, pInternal);
9183 for(i=0; i<nSamples; i++) {
9236 if (!pFloatPixel.get())
9239 convertStat = FromInternalEncoding(nSpace, icEncode16Bit, pFloatPixel, pInternal);
9242 for(i=0; i<nSamples; i++) {
9266const icChar* CIccCmm::GetFloatColorEncoding(icFloatColorEncoding val)
9271 return "icEncodeValue";
9274 return "icEncodeFloat";
9276 case icEncodeUnitFloat:
9277 return "icEncodeUnitFloat";
9279 case icEncodePercent:
9280 return "icEncodePercent";
9283 return "icEncode8Bit";
9286 return "icEncode16Bit";
9288 case icEncode16BitV2:
9289 return "icEncode16BitV2";
9292 return "icEncodeUnknown";
9310icFloatColorEncoding CIccCmm::GetFloatColorEncoding(
const icChar* val)
9312 if (!
stricmp(val,
"icEncodePercent")) {
9313 return icEncodePercent;
9315 else if (!
stricmp(val,
"icEncodeUnitFloat")) {
9316 return icEncodeUnitFloat;
9318 else if (!
stricmp(val,
"icEncodeFloat")) {
9319 return icEncodeFloat;
9321 else if (!
stricmp(val,
"icEncode8Bit")) {
9322 return icEncode8Bit;
9324 else if (!
stricmp(val,
"icEncode16Bit")) {
9325 return icEncode16Bit;
9327 else if (!
stricmp(val,
"icEncode16BitV2")) {
9328 return icEncode16BitV2;
9330 else if (!
stricmp(val,
"icEncodeValue")) {
9331 return icEncodeValue;
9334 return icEncodeUnknown;
9365void CIccCmm::IterateXforms( IXformIterator* pIterater)
const
9367 for (
auto x = m_Xforms->begin(); x != m_Xforms->end(); x++) {
9368 pIterater->iterate(x->ptr);
9386 if (!m_Xforms->size())
9389 return m_Xforms->begin()->ptr->GetSrcSpace();
9405 if (!m_Xforms->size())
9406 return m_nDestSpace;
9408 return m_Xforms->rbegin()->ptr->GetDstSpace();
9422CIccApplyNamedColorCmm::CIccApplyNamedColorCmm(CIccNamedColorCmm *pCmm) : CIccApplyCmm(pCmm)
9435CIccApplyNamedColorCmm::~CIccApplyNamedColorCmm()
9456 CIccApplyXformList::iterator i;
9457 int j, n = (int)m_Xforms->size();
9458 CIccApplyXform *pApply;
9459 const CIccXform *pApplyXform;
9460 CIccXformNamedColor *pXform;
9465 if (!m_Pixel && !InitPixel()) {
9472 m_pPCS->Reset(m_pCmm->GetSourceSpace());
9477#ifdef DEBUG_CMM_APPLY
9479 printf(
"Start ApplyNamedCmm\n");
9485 for (j=0, i=m_Xforms->begin(); j<n-1 && i!=m_Xforms->end(); i++, j++) {
9488 pApplyXform = pApply->GetXform();
9490 pXform = (CIccXformNamedColor*)pApplyXform;
9492 switch(pXform->GetInterface()) {
9493 case icApplyPixel2Pixel:
9494 pXform->Apply(pApply, pDst, m_pPCS->Check(pSrc, pXform));
9495#ifdef DEBUG_CMM_APPLY
9496 DumpCmmApplyPixel(nCount++, pDst, pXform->GetNumDstSamples());
9500 case icApplyPixel2Named:
9501 pXform->Apply(pApply, NamedColor, m_pPCS->Check(pSrc, pXform));
9502#ifdef DEBUG_CMM_APPLY
9503 printf(
"Xfm%d: \"%s\"\n", nCount++, NamedColor);
9507 case icApplyNamed2Pixel:
9512 rv = pXform->Apply(pApply, pDst, NamedColor);
9513#ifdef DEBUG_CMM_APPLY
9514 DumpCmmApplyPixel(nCount++, pDst, pXform->GetNumDstSamples());
9527 pApplyXform->Apply(pApply, pDst, m_pPCS->Check(pSrc, pApplyXform));
9528#ifdef DEBUG_CMM_APPLY
9529 DumpCmmApplyPixel(nCount++, pDst, pApplyXform->GetNumDstSamples());
9541 pApplyXform = pApply->GetXform();
9543 pXform = (CIccXformNamedColor*)pApplyXform;
9545 switch(pXform->GetInterface()) {
9546 case icApplyPixel2Pixel:
9547 pXform->Apply(pApply, DstPixel, m_pPCS->Check(pSrc, pXform));
9548#ifdef DEBUG_CMM_APPLY
9549 DumpCmmApplyPixel(nCount++, DstPixel, pXform->GetNumDstSamples());
9553 case icApplyPixel2Named:
9558 case icApplyNamed2Pixel:
9559 rv = pXform->Apply(pApply, DstPixel, NamedColor);
9560#ifdef DEBUG_CMM_APPLY
9561 DumpCmmApplyPixel(nCount++, DstPixel, pXform->GetNumDstSamples());
9571 pApplyXform->Apply(pApply, DstPixel, m_pPCS->Check(pSrc, pApplyXform));
9572#ifdef DEBUG_CMM_APPLY
9573 DumpCmmApplyPixel(nCount++, DstPixel, pApplyXform->GetNumDstSamples());
9579 i = m_Xforms->begin();
9582 pApplyXform = pApply->GetXform();
9587 pApplyXform->Apply(pApply, DstPixel, m_pPCS->Check(pSrc, pApplyXform));
9588#ifdef DEBUG_CMM_APPLY
9589 DumpCmmApplyPixel(nCount++, DstPixel, pApplyXform->GetNumDstSamples());
9593 m_pPCS->CheckLast(DstPixel, m_pCmm->GetDestSpace(),
true);
9594#ifdef DEBUG_CMM_APPLY
9595 DumpCmmApplyPixel(nCount++, DstPixel,
icGetSpaceSamples(m_pCmm->GetDestSpace()));
9596 printf(
"End ApplyNamedCmm\n\n");
9619 CIccApplyXformList::iterator i;
9620 int j, n = (int)m_Xforms->size();
9621 CIccApplyXform *pApply;
9622 const CIccXform *pApplyXform;
9623 CIccXformNamedColor *pXform;
9629 if (!m_Pixel && !InitPixel()) {
9636 for (k=0; k<nPixels; k++) {
9637 m_pPCS->Reset(m_pCmm->GetSourceSpace());
9643 for (j=0, i=m_Xforms->begin(); j<n-1 && i!=m_Xforms->end(); i++, j++) {
9646 pApplyXform = pApply->GetXform();
9648 pXform = (CIccXformNamedColor*)pApplyXform;
9650 switch(pXform->GetInterface()) {
9651 case icApplyPixel2Pixel:
9652 pXform->Apply(pApply, pDst, m_pPCS->Check(pSrc, pXform));
9655 case icApplyPixel2Named:
9656 pXform->Apply(pApply, NamedColor, m_pPCS->Check(pSrc, pXform));
9659 case icApplyNamed2Pixel:
9664 rv = pXform->Apply(pApply, pDst, NamedColor);
9676 pApplyXform->Apply(pApply, pDst, m_pPCS->Check(pSrc, pApplyXform));
9682 pApplyXform = pApply->GetXform();
9684 pXform = (CIccXformNamedColor*)pApplyXform;
9686 switch(pXform->GetInterface()) {
9687 case icApplyPixel2Pixel:
9688 pXform->Apply(pApply, DstPixel, m_pPCS->Check(pSrc, pXform));
9691 case icApplyPixel2Named:
9696 case icApplyNamed2Pixel:
9697 rv = pXform->Apply(pApply, DstPixel, NamedColor);
9706 pApplyXform->Apply(pApply, DstPixel, m_pPCS->Check(pSrc, pApplyXform));
9711 i = m_Xforms->begin();
9714 pApplyXform = pApply->GetXform();
9719 pApplyXform->Apply(pApply, DstPixel, m_pPCS->Check(pSrc, pApplyXform));
9722 m_pPCS->CheckLast(DstPixel, m_pCmm->GetDestSpace());
9724 SrcPixel += m_pCmm->GetSourceSamples();
9725 DstPixel += m_pCmm->GetDestSamples();
9748 CIccApplyXformList::iterator i;
9749 int j, n = (int)m_Xforms->size();
9750 CIccApplyXform *pApply;
9751 const CIccXform *pApplyXform;
9752 CIccXformNamedColor *pXform;
9757 if (!m_Pixel && !InitPixel()) {
9764 m_pPCS->Reset(m_pCmm->GetSourceSpace());
9770 for (j=0, i=m_Xforms->begin(); j<n-1 && i!=m_Xforms->end(); i++, j++) {
9773 pApplyXform = pApply->GetXform();
9775 pXform = (CIccXformNamedColor*)pApplyXform;
9776 switch(pXform->GetInterface()) {
9777 case icApplyPixel2Pixel:
9778 pXform->Apply(pApply, pDst, m_pPCS->Check(pSrc, pXform));
9781 case icApplyPixel2Named:
9782 pXform->Apply(pApply, NamedColor, m_pPCS->Check(pSrc, pXform));
9785 case icApplyNamed2Pixel:
9789 rv = pXform->Apply(pApply, pDst, NamedColor);
9800 pApplyXform->Apply(pApply, pDst, m_pPCS->Check(pSrc, pApplyXform));
9811 pApplyXform = pApply->GetXform();
9813 pXform = (CIccXformNamedColor*)pApplyXform;
9814 switch(pXform->GetInterface()) {
9816 case icApplyPixel2Named:
9817 pXform->Apply(pApply, DstColorName, m_pPCS->Check(pSrc, pXform));
9820 case icApplyPixel2Pixel:
9821 case icApplyNamed2Pixel:
9833 i = m_Xforms->begin();
9835 pApplyXform = pApply->GetXform();
9840 pXform = (CIccXformNamedColor*)pApplyXform;
9841 pXform->Apply(pApply, DstColorName, m_pPCS->Check(pSrc, pXform));
9864 CIccApplyXformList::iterator i;
9865 int j, n = (int)m_Xforms->size();
9866 CIccApplyXform *pApply;
9867 const CIccXform *pApplyXform;
9868 CIccXformNamedColor *pXform;
9873 if (!m_Pixel && !InitPixel()) {
9880 i=m_Xforms->begin();
9882 pApplyXform = pApply->GetXform();
9886 pXform = (CIccXformNamedColor*)pApplyXform;
9887 m_pPCS->Reset(pXform->GetSrcSpace(), pXform->UseLegacyPCS());
9892 rv = pXform->Apply(pApply, pDst, SrcColorName, tint);
9900 for (j=0, i++; j<n-2 && i!=m_Xforms->end(); i++, j++) {
9903 pApplyXform = pApply->GetXform();
9905 CIccXformNamedColor *pXform = (CIccXformNamedColor*)pApplyXform;
9906 switch(pXform->GetInterface()) {
9907 case icApplyPixel2Pixel:
9908 pXform->Apply(pApply, pDst, m_pPCS->Check(pSrc, pXform));
9911 case icApplyPixel2Named:
9912 pXform->Apply(pApply, NamedColor, m_pPCS->Check(pSrc, pXform));
9915 case icApplyNamed2Pixel:
9916 rv = pXform->Apply(pApply, pDst, NamedColor);
9927 pApplyXform->Apply(pApply, pDst, m_pPCS->Check(pSrc, pApplyXform));
9935 pApplyXform = pApply->GetXform();
9937 pXform = (CIccXformNamedColor*)pApplyXform;
9938 switch(pXform->GetInterface()) {
9939 case icApplyPixel2Pixel:
9940 pXform->Apply(pApply, DstPixel, m_pPCS->Check(pSrc, pXform));
9943 case icApplyPixel2Named:
9948 case icApplyNamed2Pixel:
9949 rv = pXform->Apply(pApply, DstPixel, NamedColor);
9958 pApplyXform->Apply(pApply, DstPixel, m_pPCS->Check(pSrc, pApplyXform));
9963 rv = pXform->Apply(pApply, DstPixel, SrcColorName, tint);
9967 m_pPCS->Check(DstPixel, pXform);
9970 m_pPCS->CheckLast(DstPixel, m_pCmm->GetDestSpace());
9991 CIccApplyXformList::iterator i;
9992 int j, n = (int)m_Xforms->size();
9995 CIccApplyXform *pApply;
9996 const CIccXform *pApplyXform;
9997 CIccXformNamedColor *pXform;
10002 if (!m_Pixel && !InitPixel()) {
10006 i=m_Xforms->begin();
10009 pApplyXform = pApply->GetXform();
10013 pXform = (CIccXformNamedColor*)pApplyXform;
10015 m_pPCS->Reset(pXform->GetSrcSpace(), pXform->UseLegacyPCS());
10020 rv = pXform->Apply(pApply, pDst, SrcColorName, tint);
10029 for (j=0, i++; j<n-2 && i!=m_Xforms->end(); i++, j++) {
10032 pApplyXform = pApply->GetXform();
10034 pXform = (CIccXformNamedColor*)pApplyXform;
10035 switch(pXform->GetInterface()) {
10036 case icApplyPixel2Pixel:
10037 pXform->Apply(pApply, pDst, m_pPCS->Check(pSrc, pXform));
10041 case icApplyPixel2Named:
10042 pXform->Apply(pApply, NamedColor, m_pPCS->Check(pSrc, pXform));
10045 case icApplyNamed2Pixel:
10046 rv = pXform->Apply(pApply, pDst, NamedColor);
10057 pApplyXform->Apply(pApply, pDst, m_pPCS->Check(pSrc, pXform));
10065 pApplyXform = pApply->GetXform();
10067 pXform = (CIccXformNamedColor*)pApplyXform;
10068 switch(pXform->GetInterface()) {
10069 case icApplyPixel2Named:
10070 pXform->Apply(pApply, DstColorName, m_pPCS->Check(pSrc, pXform));
10073 case icApplyPixel2Pixel:
10074 case icApplyNamed2Pixel:
10106 bool bFirstInput) : CIccCmm(nSrcSpace, nDestSpace, bFirstInput)
10108 m_nApplyInterface = icApplyPixel2Pixel;
10119CIccNamedColorCmm::~CIccNamedColorCmm()
10146 bool bUseD2BxB2DxTags ,
10147 CIccCreateXformHintManager *pHintManager ,
10148 bool bUseSubProfile )
10150 CIccProfile *pProfile =
OpenIccProfile(szProfilePath, bUseSubProfile);
10155 icStatusCMM rv = AddXform(pProfile, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
10181icStatusCMM CIccNamedColorCmm::AddXform(CIccProfile *pProfile,
10186 bool bUseD2BxB2DxTags ,
10187 CIccCreateXformHintManager *pHintManager )
10190 CIccXformPtr Xform;
10191 bool bInput = !m_bLastInput;
10195 switch(pProfile->m_Header.deviceClass) {
10211 switch (nUseLutType) {
10226 bUseD2BxB2DxTags =
true;
10229 nSrcSpace = pProfile->m_Header.pcs;
10232 if (!m_Xforms->size()) {
10234 m_nSrcSpace = nSrcSpace;
10237 nSrcSpace = m_nSrcSpace;
10242 m_nLastSpace = nSrcSpace;
10245 nSrcSpace = m_nLastSpace;
10252 bUseD2BxB2DxTags =
true;
10255 nDstSpace = pProfile->m_Header.pcs;
10264 Xform.ptr = CIccXform::Create(pProfile, bInput, nIntent, nInterp, pPcc,
icXformLutNamedColor, bUseD2BxB2DxTags, pHintManager);
10268 CIccXformNamedColor *pXform = (CIccXformNamedColor *)Xform.ptr;
10269 rv = pXform->SetSrcSpace(nSrcSpace);
10273 rv = pXform->SetDestSpace(nDstSpace);
10284 nSrcSpace = pProfile->m_Header.colorSpace;
10288 bUseD2BxB2DxTags =
true;
10291 nDstSpace = pProfile->m_Header.pcs;
10304 bUseD2BxB2DxTags =
true;
10307 nSrcSpace = pProfile->m_Header.pcs;
10309 nDstSpace = pProfile->m_Header.colorSpace;
10316 nSrcSpace = pProfile->m_Header.pcs;
10317 nDstSpace = pProfile->m_Header.pcs;
10322 nSrcSpace = pProfile->m_Header.pcs;
10328 nSrcSpace = pProfile->m_Header.colorSpace;
10333 nSrcSpace = pProfile->m_Header.colorSpace;
10338 switch(pProfile->m_Header.deviceClass)
10342 nSrcSpace = pProfile->m_Header.colorSpace;
10347 if (bUseD2BxB2DxTags && pProfile->m_Header.spectralPCS) {
10351 nDstSpace = pProfile->m_Header.pcs;
10358 nDstSpace = pProfile->m_Header.colorSpace;
10371 if (!m_Xforms->size()) {
10373 m_nLastSpace = nSrcSpace;
10374 m_nSrcSpace = nSrcSpace;
10390 nIntent = m_nLastIntent;
10397 Xform.ptr = CIccXform::Create(pProfile, bInput, nIntent, nInterp, pPcc, nUseLutType, bUseD2BxB2DxTags, pHintManager);
10403 m_nLastSpace = Xform.ptr->GetDstSpace();
10404 m_nLastIntent = nIntent;
10408 m_bLastInput = bInput;
10410 m_Xforms->push_back(Xform);
10425 icStatusCMM CIccNamedColorCmm::Begin(
bool bAllocNewApply,
bool bUsePcsConversion)
10428 m_nDestSpace = m_nLastSpace;
10436 m_nApplyInterface = icApplyPixel2Pixel;
10439 m_nApplyInterface = icApplyPixel2Named;
10444 m_nApplyInterface = icApplyNamed2Pixel;
10447 m_nApplyInterface = icApplyNamed2Named;
10451 CheckPCSRangeConversions();
10452 SetLateBindingCC();
10455 CIccXformList::iterator i;
10457 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
10458 rv = i->ptr->Begin();
10465 rv = CheckPCSConnections(bUsePcsConversion);
10469 if (bAllocNewApply) {
10472 m_pApply = GetNewApplyCmm(rv);
10490 CIccApplyCmm *CIccNamedColorCmm::GetNewApplyCmm(
icStatusCMM &status)
10492 CIccApplyCmm *pApply =
new CIccApplyNamedColorCmm(
this);
10494 CIccXformList::iterator i;
10496 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
10497 CIccApplyXform *pXform = i->ptr->GetNewApply(status);
10502 pApply->AppendApplyXform(pXform);
10526 return ((CIccApplyNamedColorCmm*)m_pApply)->Apply(DstColorName, SrcPixel);
10544 return ((CIccApplyNamedColorCmm*)m_pApply)->Apply(DstPixel, SrcColorName, tint);
10562 return ((CIccApplyNamedColorCmm*)m_pApply)->Apply(DstColorName, SrcColorName, tint);
10579 int n = (int)m_Xforms->size();
10580 CIccXformPtr *pLastXform;
10585 pLastXform = &m_Xforms->back();
10588 CIccXformNamedColor *pXform = (CIccXformNamedColor *)pLastXform->ptr;
10599 return pXform->SetDestSpace(nDestSpace);
10613CIccMruCmm::CIccMruCmm()
10616 m_bDeleteCmm =
false;
10628CIccMruCmm::~CIccMruCmm()
10630 if (m_pCmm && m_bDeleteCmm)
10655CIccMruCmm* CIccMruCmm::Attach(CIccCmm *pCmm,
icUInt8Number nCacheSize,
bool bDeleteCmm)
10657 if (!pCmm || !nCacheSize)
10660 if (!pCmm->Valid()) {
10666 CIccMruCmm *rv =
new CIccMruCmm();
10669 rv->m_nCacheSize = nCacheSize;
10670 rv->m_bDeleteCmm = bDeleteCmm;
10672 rv->m_nSrcSpace = pCmm->GetSourceSpace();
10673 rv->m_nDestSpace = pCmm->GetDestSpace();
10674 rv->m_nLastSpace = pCmm->GetLastSpace();
10675 rv->m_nLastIntent = pCmm->GetLastIntent();
10685CIccApplyCmm *CIccMruCmm::GetNewApplyCmm(
icStatusCMM &status)
10687 CIccApplyMruCmm *rv =
new CIccApplyMruCmm(
this);
10694 if (!rv->Init(m_pCmm, m_nCacheSize)) {
10711CIccMruCache<T>::CIccMruCache()
10715 m_pixelData = NULL;
10728CIccMruCache<T>::~CIccMruCache()
10754 m_nSrcSamples = nSrcSamples;
10755 m_nSrcSize = nSrcSamples *
sizeof(T);
10756 m_nDstSize = nDstSamples *
sizeof(T);
10758 m_nTotalSamples = m_nSrcSamples + nDstSamples;
10761 m_nCacheSize = nCacheSize;
10764 m_cache =
new CIccMruPixel<T>[nCacheSize];
10769 m_pixelData = (T*)malloc((
int)nCacheSize * m_nTotalSamples *
sizeof(T));
10780 CIccMruCache<T> *rv =
new CIccMruCache<T>;
10782 if (!rv->Init(nSrcSamples, nDstSamples, nCacheSize)) {
10806bool CIccMruCache<T>::Apply(T *DstPixel,
const T *SrcPixel)
10808 CIccMruPixel<T> *ptr, *prev = NULL, *last = NULL;
10812 for (ptr = m_pFirst, i = 0; ptr; ptr = ptr->pNext, i++) {
10813 if (!memcmp(SrcPixel, ptr->pPixelData, m_nSrcSize)) {
10814 memcpy(DstPixel, &ptr->pPixelData[m_nSrcSamples], m_nDstSize);
10815 if (ptr != m_pFirst) {
10816 last->pNext = ptr->pNext;
10818 ptr->pNext = m_pFirst;
10828 if (i < m_nCacheSize) {
10829 pixel = &m_pixelData[i*m_nTotalSamples];
10832 ptr->pPixelData = pixel;
10835 ptr->pNext = m_pFirst;
10840 prev->pNext = NULL;
10841 last->pNext = m_pFirst;
10844 pixel = last->pPixelData;
10846 T *dest = &pixel[m_nSrcSamples];
10848 memcpy(pixel, SrcPixel, m_nSrcSize);
10854void CIccMruCache<T>::Update(T* DstPixel)
10856 memcpy(&m_pFirst->pPixelData[m_nSrcSamples], DstPixel, m_nDstSize);
10860template class CIccMruCache<icFloatNumber>;
10861template class CIccMruCache<icUInt8Number>;
10862template class CIccMruCache<icUInt16Number>;
10865CIccApplyMruCmm::CIccApplyMruCmm(CIccMruCmm *pCmm) : CIccApplyCmm(pCmm)
10867 m_pCachedCmm = NULL;
10878CIccApplyMruCmm::~CIccApplyMruCmm()
10899bool CIccApplyMruCmm::Init(CIccCmm *pCachedCmm,
icUInt16Number nCacheSize)
10901 m_pCachedCmm = pCachedCmm;
10903 m_pCache = CIccMruCacheFloat::NewMruCache(m_pCmm->GetSourceSamples(), m_pCmm->GetDestSamples(), nCacheSize);
10932 if (!m_pCache->Apply(DstPixel, SrcPixel)) {
10934 m_pCachedCmm->Apply(DstPixel, SrcPixel);
10936 m_pCache->Update(DstPixel);
10966 for (k=0; k<nPixels;k++) {
10967 if (!m_pCache->Apply(DstPixel, SrcPixel)) {
10968 m_pCachedCmm->Apply(DstPixel, SrcPixel);
10969 m_pCache->Update(DstPixel);
10971 SrcPixel += m_pCmm->GetSourceSamples();
10972 DstPixel += m_pCmm->GetDestSamples();
10979#ifdef USEREFICCMAXNAMESPACE
static __inline bool IsSpaceSpectralPCS(icUInt32Number sig)
#define ICCPCSSTEPDUMPFMT
#define IsCompatSpace(x, y)
static icFloatNumber RGBClip(icFloatNumber v, CIccCurve *pCurve)
icFloatNumber icD50XYZ[3]
static icFloatNumber XYZScale(icFloatNumber v)
#define IsSpaceColorimetricPCS(x)
#define IsNChannelCompat(x, y)
#define ICCDUMPPIXEL(n, pix)
static icFloatNumber XYZDescale(icFloatNumber v)
icXformLutType
CMM Xform LUT types.
#define icPerceptualRefWhiteX
icXformInterp
CMM Interpolation types.
#define icPerceptualRefBlackZ
#define icPerceptualRefBlackY
#define icPerceptualRefWhiteZ
icStatusCMM
CMM return status values.
@ icCmmStatInvalidProfile
@ icCmmStatTooManySamples
@ icCmmStatProfileMissingTag
@ icCmmStatIncorrectApply
@ icCmmStatUnsupportedPcsLink
@ icCmmStatBadColorEncoding
@ icCmmStatCantOpenProfile
#define icPerceptualRefWhiteY
#define icPerceptualRefBlackX
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
icUInt16Number icU1Fixed15Number
#define icSigDevLabData
Additional convenience color space signatures to distinguish between device encoding and PCS encoding...
icStatusEncConvert icConvertEncodingProfile(CIccProfilePtr &newIcc, CIccProfile *pEncodeIcc)
CIccProfile * OpenIccProfile(const icChar *szFilename, bool bUseSubProfile)
Name: OpenIccProfile.
icU1Fixed15Number icDtoUSF(icFloatNumber num)
icFloatNumber icU8toAB(icUInt8Number num)
icFloatNumber icU16toF(icUInt16Number num)
icUInt8Number icABtoU8(icFloatNumber num)
void icXyzToPcs(icFloatNumber *XYZ)
void icXyzFromPcs(icFloatNumber *XYZ)
Floating point encoding of XYZ in PCS is in range 0.0 to 1.0 (Note: X=1.0 is encoded as about 0....
bool icSameSpectralRange(const icSpectralRange &rng1, const icSpectralRange &rng2)
bool icMatrixInvert3x3(icFloatNumber *M)
Name: icMatrixInvert3x3.
icUInt32Number icGetSpaceSamples(icColorSpaceSignature sig)
icFloatNumber icFtoD(icS15Fixed16Number num)
icFloatNumber icU8toF(icUInt8Number num)
icUInt32Number icGetSpectralSpaceSamples(const icHeader *pHdr)
void icLabFromPcs(icFloatNumber *Lab)
Floating point encoding of Lab in PCS is in range 0.0 to 1.0.
icUInt8Number icFtoU8(icFloatNumber num)
void icLabToPcs(icFloatNumber *Lab)
void icLabtoXYZ(icFloatNumber *XYZ, const icFloatNumber *Lab, const icFloatNumber *WhiteXYZ)
icFloat16Number icFtoF16(icFloat32Number num)
bool icIsSpaceCLR(icColorSpaceSignature sig)
icS15Fixed16Number icDtoF(icFloatNumber num)
icUInt16Number icFtoU16(icFloatNumber num)
icFloatNumber icUSFtoD(icU1Fixed15Number num)
void icXYZtoLab(icFloatNumber *Lab, const icFloatNumber *XYZ, const icFloatNumber *WhiteXYZ)
icFloatNumber icF16toF(icFloat16Number num)
#define icUtf8StrCmp(x, y)
unsigned int icUInt32Number
Class: CIccArrayNamedColor.
CIccStructNamedColor * FindColor(const icChar *szColor) const
bool GetSpectralTint(icFloatNumber *dstColor, const CIccStructNamedColor *pColor, icFloatNumber tint=1.0f, icNamedColorlMemberSignature sig=icSigNmclSpectralDataMbr) const
CIccStructNamedColor * FindSpectralColor(const icFloatNumber *pSpec, icFloatNumber dMinRms=1000.0) const
void SetColorSpaces(icColorSpaceSignature csPcs, icColorSpaceSignature csDevice, icSpectralColorSignature csSpectralPCS=icSigNoSpectralData, const icSpectralRange *pSpectralRange=NULL, const icSpectralRange *pBiSPectralRange=NULL)
CIccStructNamedColor * FindDeviceColor(const icFloatNumber *pDevColor) const
CIccStructNamedColor * FindPcsColor(const icFloatNumber *pPCS, icFloatNumber dMinDE=1000.0) const
bool GetDeviceTint(icFloatNumber *dstColor, const CIccStructNamedColor *pColor, icFloatNumber tint=1.0f, icNamedColorlMemberSignature sig=icSigNmclDeviceDataMbr) const
bool GetPcsTint(icFloatNumber *dstColor, const CIccStructNamedColor *pColor, icFloatNumber tint=1.0f, icNamedColorlMemberSignature sig=icSigNmclPcsDataMbr) const
CIccApplyCLUT * GetNewApply()
virtual icFloatNumber Apply(icFloatNumber v) const
icFloatNumber Find(icFloatNumber v)
bool Attach(icUInt8Number *pData, icUInt32Number nSize, bool bWrite=false)
icFloatNumber * GetConstants() const
virtual bool Begin(icElemInterp nInterp, CIccTagMultiProcessElement *pMPE)
Name: CIccMpeMatrix::Begin.
icFloatNumber * GetMatrix() const
bool GetApplyConstants() const
Class: CIccMultiProcessElement.
virtual icUInt16Number NumInputChannels() const
virtual icUInt16Number NumOutputChannels() const
virtual icElemTypeSignature GetType() const =0
static icUInt32Number MemSize(icUInt32Number nMaxEntries, icUInt16Number nRows, icUInt8Number nTypeSize)
Class: CIccStructNamedColor.
std::string getName() const
CIccTag * GetElem(icSignature sigElem) const
bool AreAllOfType(icTagTypeSignature sigTagType)
Name: CIccTagArray::AreAllOftype.
IIccArray * GetArrayHandler()
Name: CIccTagArray::GetArrayHandler.
CIccTag * GetIndex(icUInt32Number index) const
Name: CIccTagArray::GetIndex.
icUInt32Number GetSize() const
Returns the size of the data array.
virtual icArraySignature GetTagArrayType() const
virtual icTagTypeSignature GetType() const
Function: GetType()
virtual bool IsSupported()
Function: IsSupported(size, pIO) - Check if tag fully supported for apply purposes.
virtual bool IsNumArrayType() const
virtual icArraySignature GetTagArrayType() const
Class: CIccTagMultiProcessElement.
icUInt16Number NumInputChannels() const
icUInt16Number NumOutputChannels() const
virtual CIccTag * NewCopy() const
Function: NewCopy(sDescription) Each derived tag will implement it's own NewCopy() function.
virtual void Apply(CIccApplyTagMpe *pApply, icFloatNumber *pDestPixel, const icFloatNumber *pSrcPixel) const
Name: CIccTagMultiProcessElement::Apply.
icUInt32Number NumElements() const
CIccMultiProcessElement * GetElement(int nIndex)
Name: CIccTagMultiProcessElement::GetElement.
Class: CIccTagNamedColor2.
icInt32Number FindDeviceColor(icFloatNumber *pDevColor) const
Name: CIccTagNamedColor2::FindDeviceColor.
bool GetColorName(std::string &sColorName, icInt32Number index) const
Name: CIccTagNamedColor2::GetColorName.
icInt32Number FindColor(const icChar *szColor) const
Name: CIccTagNamedColor2::FindColor.
icColorSpaceSignature GetPCS() const
icUInt32Number GetDeviceCoords() const
icColorSpaceSignature GetDeviceSpace() const
icInt32Number FindCachedPCSColor(icFloatNumber *pPCS, icFloatNumber dMinDE=1000.0) const
Name: CIccTagNamedColor2::FindPCSColor.
SIccNamedColorEntry * GetEntry(icUInt32Number index) const
virtual bool GetValues(icFloatNumber *DstVector, icUInt32Number nStart=0, icUInt32Number nVectorSize=1) const =0
Class: CIccTagSpectralViewingConditions.
const icFloatNumber * getObserver(icSpectralRange &observerRange) const
icFloatNumber getIlluminantCCT() const
icIlluminant getStdIllumiant() const
const icFloatNumber * getIlluminant(icSpectralRange &illumRange) const
icFloatNumber * applyRangeToObserver(const icSpectralRange &newRange) const
virtual CIccTagMultiProcessElement * getStandardToCustomPcc()=0
virtual const CIccTagSpectralViewingConditions * getPccViewingConditions()=0
virtual CIccTagMultiProcessElement * getCustomToStandardPcc()=0
virtual void getLumIlluminantXYZ(icFloatNumber *pXYZ)=0
virtual bool getMediaWhiteXYZ(icFloatNumber *pXYZ)=0
icFloatNumber getObserverWhiteScaleFactor(const icFloatNumber *pWhite, const icSpectralRange &whiteRange)
virtual void getNormIlluminantXYZ(icFloatNumber *pXYZ)=0
bool isEquivalentPcc(IIccProfileConnectionConditions &IPCC)
static icFloatNumber UnitClip(icFloatNumber v)
icFloatNumber deviceCoords[1]
icFloatNumber pcsCoords[3]