142{
143 if (v<0)
144 v = 0;
145 if (v>1.0)
146 v = 1.0;
147
148 return v;
149}
150
160{
161 if (v<0)
162 v=0;
163
164 return v;
165}
166
176{
178
179 memcpy(&Lab,Src,sizeof(Lab));
180
182
184
186
187 if (!bNoClip) {
191 }
192 else {
193 Dst[0] = Lab[0];
194 Dst[1] = Lab[1];
195 Dst[2] = Lab[2];
196 }
197}
198
199
209{
211
212
213 if (!bNoClip) {
217 }
218 else {
219 XYZ[0] = Src[0];
220 XYZ[1] = Src[1];
221 XYZ[2] = Src[2];
222 }
223
225
227
229
230 if (!bNoClip) {
234 }
235 else {
236 Dst[0] = XYZ[0];
237 Dst[1] = XYZ[1];
238 Dst[2] = XYZ[2];
239 }
240}
241
242
252{
253 Lab2ToLab4(Dst, Src, bNoClip);
254 LabToXyz(Dst, Dst, bNoClip);
255}
256
257
267{
268 XyzToLab(Dst, Src, bNoClip);
269 Lab4ToLab2(Dst, Dst);
270}
271
272
282{
283 if (bNoClip) {
287 }
288 else {
292 }
293}
294
304{
308}
309
310
319CIccCreateXformHintManager::~CIccCreateXformHintManager()
320{
321 if (m_pList) {
322 IIccCreateXformHintList::iterator i;
323
324 for (i=m_pList->begin(); i!=m_pList->end(); i++) {
325 if (i->ptr)
326 delete i->ptr;
327 }
328
329 delete m_pList;
330 }
331}
332
348bool CIccCreateXformHintManager::AddHint(IIccCreateXformHint* pHint)
349{
350 if (!m_pList) {
351 m_pList = new IIccCreateXformHintList;
352 }
353
354 if (pHint) {
355 if (GetHint(pHint->GetHintType())) {
356 delete pHint;
357 return false;
358 }
359 IIccCreateXformHintPtr Hint;
360 Hint.ptr = pHint;
361 m_pList->push_back(Hint);
362 return true;
363 }
364
365 return false;
366}
367
384bool CIccCreateXformHintManager::DeleteHint(IIccCreateXformHint* pHint)
385{
386 if (m_pList && pHint) {
387 IIccCreateXformHintList::iterator i;
388 for (i=m_pList->begin(); i!=m_pList->end(); i++) {
389 if (i->ptr) {
390 if (i->ptr == pHint) {
391 delete pHint;
392 pHint = NULL;
393 m_pList->erase(i);
394 return true;
395 }
396 }
397 }
398 }
399
400 return false;
401}
402
417IIccCreateXformHint* CIccCreateXformHintManager::GetHint(const char* hintName)
418{
419 IIccCreateXformHint* pHint=NULL;
420
421 if (m_pList) {
422 IIccCreateXformHintList::iterator i;
423 for (i=m_pList->begin(); i!=m_pList->end(); i++) {
424 if (i->ptr) {
425 if (!strcmp(i->ptr->GetHintType(), hintName)) {
426 pHint = i->ptr;
427 break;
428 }
429 }
430 }
431 }
432
433 return pHint;
434}
435
444CIccXform::CIccXform()
445{
446 m_pProfile = NULL;
447 m_bOwnsProfile = true;
448 m_bInput = true;
450 m_pAdjustPCS = NULL;
451 m_bAdjustPCS = false;
452 m_bAbsToRel = false;
454 m_bUseSpectralPCS = false;
455 m_bSrcPcsConversion = true;
456 m_bDstPcsConversion = true;
457 m_pConnectionConditions = NULL;
458 m_bDeleteEnvLooup = true;
459 m_pCmmEnvVarLookup = NULL;
461 m_MediaXYZ = {};
463 m_bUseD2BTags = false;
464 m_bLuminanceMatching = false;
465 m_PCSOffset[0] = m_PCSOffset[1] = m_PCSOffset[2] = 0;
466}
467
468
477CIccXform::~CIccXform()
478{
479 if (m_pProfile && m_bOwnsProfile)
480 delete m_pProfile;
481
482 if (m_pAdjustPCS) {
483 delete m_pAdjustPCS;
484 }
485
486 if (m_pCmmEnvVarLookup && m_bDeleteEnvLooup) {
487 delete m_pCmmEnvVarLookup;
488 }
489
490}
491
492
493void CIccXform::DetachAll()
494{
495 m_pProfile = NULL;
496 m_bOwnsProfile = true;
497 m_pConnectionConditions = NULL;
498}
499
524 bool bInput,
529 bool bUseD2BTags, CIccCreateXformHintManager *pHintManager)
530{
531 CIccXform *rv = NULL;
533 bool bUseSpectralPCS = false;
534 bool bAbsToRel = false;
535 bool bRelToAbs = false;
538 bool bUseColorimeticTags = true;
539
542 bUseD2BTags = true;
543 bUseColorimeticTags = false;
544 }
547 }
548
552 return NULL;
553 delete pProfile;
554 pProfile = pEncProfile;
555 }
558 }
559
562
563 switch (nUseLutType) {
565 if (bInput) {
567 if (bUseD2BTags) {
570
573 if (pTag)
575 }
578 if (pTag) {
580 bAbsToRel = true;
581 }
582 }
583
584 if (pTag)
585 bUseSpectralPCS = true;
586
587 if (!pTag) {
589 }
590 if (!pTag) {
592 }
593 if (!pTag) {
595 if (pTag) {
597 bAbsToRel = true;
598 }
599 }
600 }
603
606 if (pTag)
608 }
609
610
613 }
614 }
615 }
616
617 if (bUseColorimeticTags) {
618 if (!pTag) {
620 }
621
624 if (pTag)
626 }
629 if (pTag) {
631 bAbsToRel = true;
632 }
633 }
634
635 if (!pTag) {
637 }
638 if (!pTag) {
640 }
641 if (!pTag) {
643 if (pTag) {
645 bAbsToRel = true;
646 }
647 }
648 }
649
650
652 pTag = NULL;
653
654 if (!pTag) {
656
659 }
662 }
663 else
664 return NULL;
665 }
666 else
667 return NULL;
668 }
671 }
672 else {
673 switch(pProfile->m_Header.colorSpace) {
685 break;
686
690 break;
691
692 default:
694 break;
695 }
696 }
697 }
698 else {
700
702 bUseD2BTags = false;
703 }
704
705 if (bUseD2BTags) {
707
708
711
712 if (!pTag) {
714 if (pTag) {
717 bRelToAbs = true;
718 }
719 }
720
721 if (!pTag) {
723 if (pTag) {
725 bAbsToRel = true;
726 }
727 }
728 }
729
730
732 pTag = NULL;
733
734 if (pTag)
735 bUseSpectralPCS = true;
736
739
740
742 pTag = NULL;
743
744 if (pTag)
746 }
747 }
748
749 if (bUseColorimeticTags) {
750
751 if (!pTag) {
753 }
754
757 if (pTag)
759 }
760
761 if (!pTag) {
763 }
764
765
767
769 if (pTag) {
772 bRelToAbs = true;
773 }
774
775 if (!pTag) {
777 if (pTag) {
779 bAbsToRel = true;
780 }
781 }
782 }
783 }
784
785 if (!pTag) {
789 }
792 }
793 else
794 return NULL;
795 }
796 else
797 return NULL;
798 }
801 }
802 else {
803 switch(pProfile->m_Header.pcs) {
807 break;
808
809 default:
810 break;
811 }
812 }
813 }
814 break;
815
817{
819 if (!pTag)
820 return NULL;
821
822
823 CIccCreateNamedColorXformHint* pNamedColorHint = new CIccCreateNamedColorXformHint();
824 pNamedColorHint->csPcs = pProfile->m_Header.pcs;
825 pNamedColorHint->csDevice = pProfile->m_Header.colorSpace;
826 pNamedColorHint->csSpectralPcs = pProfile->m_Header.spectralPCS;
827 pNamedColorHint->spectralRange = pProfile->m_Header.spectralRange;
828 pNamedColorHint->biSpectralRange = pProfile->m_Header.biSpectralRange;
829
830 if (pHintManager) {
831
832 pHintManager->AddHint(pNamedColorHint);
834
835 pNamedColorHint = nullptr;
836 }
837 else {
838 CIccCreateXformHintManager HintManager;
839 HintManager.AddHint(pNamedColorHint);
841
842 pNamedColorHint = nullptr;
843 }
844
845
846
847
848
849 if (pProfile->m_Header.spectralPCS)
850 bUseSpectralPCS = true;
851}
852break;
853
855 {
856 bInput = false;
858 if (!pTag) {
860 }
861 if (!pTag) {
862 return NULL;
863 }
864 else {
865 switch(pProfile->m_Header.pcs) {
869
870 default:
871 break;
872 }
873 }
874 }
875 break;
876
878 {
879 bInput = false;
881 if (!pTag) {
882 return NULL;
883 }
884 else {
885 switch(pProfile->m_Header.pcs) {
889
890 default:
891 break;
892 }
893 }
894 }
895 break;
896
898 {
899
900
902 if (bUseD2BTags) {
903 if (pProfile->m_Header.spectralPCS) {
904
906
907 if (pTag)
908 bUseSpectralPCS = true;
909 }
910 }
911 else
912 {
914
915
917 pTag = NULL;
918 }
919
920
922
923 if (pStructTag != NULL)
924 {
926
927 switch (nLutType) {
930 break;
931 default:
932
933 break;
934 }
935 if (pTag2)
937 }
938 }
939 break;
940
942 {
943
944
946 if (bUseD2BTags) {
947 if (pProfile->m_Header.spectralPCS) {
948
950
951 if (pTag)
952 bUseSpectralPCS = true;
953 }
954 }
955 else
956 {
958
959
961 pTag = NULL;
962 }
963
964 if (pTag != NULL)
965 {
967 }
968 }
969 break;
970
972 {
975 bInput = true;
977
978 if (pProfile->m_Header.spectralPCS) {
980
983 if (pTag)
985 }
988 if (pTag) {
990 bAbsToRel = true;
991 }
992 }
993
994 if (!pTag) {
996 }
997 if (!pTag) {
999 }
1000 if (!pTag) {
1002 if (pTag) {
1004 bAbsToRel = true;
1005 }
1006 }
1007
1008 if (pTag)
1009 bUseSpectralPCS = true;
1010 }
1011 if (!pTag && pProfile->m_Header.pcs != 0) {
1013
1016 if (pTag)
1018 }
1021 if (pTag) {
1023 bAbsToRel = true;
1024 }
1025 }
1026 if (!pTag) {
1028 }
1029 if (!pTag) {
1031 }
1032 if (!pTag) {
1034 if (pTag) {
1036 bAbsToRel = true;
1037 }
1038 }
1039 }
1040
1041
1043 pTag = NULL;
1044
1045
1047 pTag = NULL;
1048 }
1049 if (pTag && pProfile->m_Header.mcs) {
1051 }
1052 else
1053 rv = NULL;
1054 }
1055 break;
1056
1058 {
1062 bInput = true;
1065 }
1067 bInput = true;
1069
1070 if (pProfile->m_Header.spectralPCS) {
1072
1075 if (pTag)
1077 }
1080 if (pTag) {
1082 bAbsToRel = true;
1083 }
1084 }
1085
1086 if (!pTag) {
1088 }
1089 if (!pTag) {
1091 }
1092 if (!pTag) {
1094 if (pTag) {
1096 bAbsToRel = true;
1097 }
1098 }
1099
1100 if (pTag)
1101 bUseSpectralPCS = true;
1102 }
1103 if (!pTag && pProfile->m_Header.pcs!=0) {
1105
1108 if (pTag)
1110 }
1113 if (pTag) {
1115 bAbsToRel = true;
1116 }
1117 }
1118
1119 if (!pTag) {
1121 }
1122 if (!pTag) {
1124 }
1125 if (!pTag) {
1127 if (pTag) {
1129 bAbsToRel = true;
1130 }
1131 }
1132 }
1133
1134
1136 pTag = NULL;
1137 }
1139 bInput = false;
1142 }
1143 if (pTag && pProfile->m_Header.mcs) {
1145 }
1146 else
1147 rv = NULL;
1148 }
1149 break;
1150
1151 }
1152
1153 if (rv) {
1154 if (pPcc)
1155 rv->m_pConnectionConditions = pPcc;
1156 else
1157 rv->m_pConnectionConditions = pProfile;
1158
1159 rv->SetParams(pProfile, bInput, nIntent, nTagIntent, bUseSpectralPCS, nInterp, pHintManager, bAbsToRel, nMCS);
1160 }
1161
1162 return rv;
1163}
1164
1188CIccXform *CIccXform::Create(
CIccProfile *pProfile,
1190 bool bInput,
1194 bool bUseSpectralPCS,
1195 CIccCreateXformHintManager *pHintManager)
1196{
1197 CIccXform *rv = NULL;
1199 bool bAbsToRel = false;
1200 bool bRelToAbs = false;
1202
1204 return NULL;
1205 }
1206
1209 }
1210
1213
1214
1215 if (pTag == NULL)
1216 return NULL;
1218 return NULL;
1219
1220 if (bInput) {
1223 }
1224 else {
1225 switch (pProfile->m_Header.colorSpace) {
1237 break;
1238
1242 break;
1243
1244 default:
1246 break;
1247 }
1248 }
1249 }
1250 else {
1253 }
1254 else {
1255 switch (pProfile->m_Header.pcs) {
1259 break;
1260
1261 default:
1262 break;
1263 }
1264 }
1265 }
1266
1267 if (rv) {
1268 if (pPcc)
1269 rv->m_pConnectionConditions = pPcc;
1270 else
1271 rv->m_pConnectionConditions = pProfile;
1272
1273 rv->SetParams(pProfile, bInput, nIntent, nTagIntent, bUseSpectralPCS, nInterp, pHintManager, bAbsToRel, nMCS);
1274 }
1275
1276 return rv;
1277}
1278
1293 bool bUseSpectralPCS,
icXformInterp nInterp, CIccCreateXformHintManager *pHintManager,
1295{
1296 m_pProfile = pProfile;
1297 m_bInput = bInput;
1298 m_nIntent = nIntent;
1299 m_nTagIntent = nTagIntent;
1300 m_nInterp = nInterp;
1301 m_pAdjustPCS = NULL;
1302 m_bUseSpectralPCS = bUseSpectralPCS;
1303 m_bAbsToRel = bAbsToRel;
1304 m_nMCS = nMCS;
1305 m_bLuminanceMatching = false;
1306
1307 if (pHintManager) {
1308 IIccCreateXformHint *pHint=NULL;
1309
1310 pHint = pHintManager->GetHint("CIccCreateAdjustPCSXformHint");
1311 if (pHint) {
1312 CIccCreateAdjustPCSXformHint *pAdjustPCSHint = (CIccCreateAdjustPCSXformHint*)pHint;
1313 m_pAdjustPCS = pAdjustPCSHint->GetNewAdjustPCSXform();
1314 }
1315
1316 pHint = pHintManager->GetHint("CIccCreateCmmEnvVarXformHint");
1317 if (pHint) {
1318 CIccCreateCmmEnvVarXformHint *pCmmEnvVarHint = (CIccCreateCmmEnvVarXformHint*)pHint;
1319 m_pCmmEnvVarLookup = pCmmEnvVarHint->GetNewCmmEnvVarLookup();
1320 }
1321
1322 pHint = pHintManager->GetHint("CIccLuminanceMatchingHint");
1323 if (pHint) {
1324 m_bLuminanceMatching = true;
1325 }
1326 }
1327}
1328
1353 bool bInput,
1358 bool bUseD2BxB2DxTags,
1359 CIccCreateXformHintManager *pHintManager)
1360{
1362 CIccXform *pXform = Create(pProfile, bInput, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
1363
1364 if (!pXform)
1365 delete pProfile;
1366
1367 return pXform;
1368}
1369
1370
1383{
1385
1388
1390 if (pCond) {
1392
1393 m_MediaXYZ.X =
icFtoF16(mediaXYZ[0]);
1394 m_MediaXYZ.Y =
icFtoF16(mediaXYZ[1]);
1395 m_MediaXYZ.Z =
icFtoF16(mediaXYZ[2]);
1396 }
1397 else {
1399
1402
1404
1405 m_MediaXYZ = (*pXyzTag)[0];
1406 mediaXYZ[0] =
icFtoD(m_MediaXYZ.X);
1407 mediaXYZ[1] =
icFtoD(m_MediaXYZ.Y);
1408 mediaXYZ[2] =
icFtoD(m_MediaXYZ.Z);
1409 }
1410 }
1411
1413 if (pCond) {
1415 illXYZ.
X =
icDtoF(illumXYZ[0]);
1416 illXYZ.
Y =
icDtoF(illumXYZ[1]);
1417 illXYZ.
Z =
icDtoF(illumXYZ[2]);
1418 }
1419 else {
1420 illXYZ = m_pProfile->m_Header.illuminant;
1421 illumXYZ[0] =
icFtoD(illXYZ.
X);
1422 illumXYZ[1] =
icFtoD(illXYZ.
Y);
1423 illumXYZ[2] =
icFtoD(illXYZ.
Z);
1424 }
1425
1426
1428 (m_MediaXYZ.X != illXYZ.
X ||
1429 m_MediaXYZ.Y != illXYZ.
Y ||
1430 m_MediaXYZ.Z != illXYZ.
Z)) {
1431
1433
1435 m_bAdjustPCS = true;
1436
1437
1438
1439 if (!m_bInput) {
1440 m_PCSScale[0] = illumXYZ[0] / mediaXYZ[0];
1441 m_PCSScale[1] = illumXYZ[1] / mediaXYZ[1];
1442 m_PCSScale[2] = illumXYZ[2] / mediaXYZ[2];
1443 }
1444 else {
1445 m_PCSScale[0] = mediaXYZ[0] / illumXYZ[0];
1446 m_PCSScale[1] = mediaXYZ[1] / illumXYZ[1];
1447 m_PCSScale[2] = mediaXYZ[2] / illumXYZ[2];
1448
1449 }
1450
1451 m_PCSOffset[0] = 0.0;
1452 m_PCSOffset[1] = 0.0;
1453 m_PCSOffset[2] = 0.0;
1454 }
1455 }
1456 else if (m_nIntent ==
icPerceptual && (IsVersion2() || !HasPerceptualHandling())) {
1458
1460 m_bAdjustPCS = true;
1461
1462
1466
1470
1471 if (!m_bInput) {
1475
1476 m_PCSOffset[0] = - m_PCSOffset[0] * m_PCSScale[0];
1477 m_PCSOffset[1] = - m_PCSOffset[1] * m_PCSScale[1];
1478 m_PCSOffset[2] = - m_PCSOffset[2] * m_PCSScale[2];
1479 }
1480 }
1481 }
1482
1483
1484 if (m_pAdjustPCS) {
1486
1487
1488 if (!ProfileCopy.ReadTags(m_pProfile)) {
1490 }
1491
1492 if (!m_pAdjustPCS->CalcFactors(&ProfileCopy, this, m_PCSScale, m_PCSOffset)) {
1494 }
1495
1496 m_bAdjustPCS = true;
1497 delete m_pAdjustPCS;
1498 m_pAdjustPCS = NULL;
1499 }
1500
1502}
1503
1513CIccApplyXform *CIccXform::GetNewApply(
icStatusCMM &status)
1514{
1515 CIccApplyXform *rv = new CIccApplyXform(this);
1516
1517 if (!rv) {
1519 return NULL;
1520 }
1521
1523 return rv;
1524}
1525
1541{
1543
1545 if (UseLegacyPCS()) {
1546 CIccPCSUtil::Lab2ToXyz(DstPixel, SrcPixel, true);
1547 }
1548 else {
1549 CIccPCSUtil::LabToXyz(DstPixel, SrcPixel, true);
1550 }
1551 }
1552 else {
1553 DstPixel[0] = SrcPixel[0];
1554 DstPixel[1] = SrcPixel[1];
1555 DstPixel[2] = SrcPixel[2];
1556 }
1557
1558 DstPixel[0] = DstPixel[0] * m_PCSScale[0] + m_PCSOffset[0];
1559 DstPixel[1] = DstPixel[1] * m_PCSScale[1] + m_PCSOffset[1];
1560 DstPixel[2] = DstPixel[2] * m_PCSScale[2] + m_PCSOffset[2];
1561
1563 if (UseLegacyPCS()) {
1564
1565 CIccPCSUtil::XyzToLab2(DstPixel, DstPixel, true);
1566 }
1567 else {
1568 CIccPCSUtil::XyzToLab(DstPixel, DstPixel, true);
1569 }
1570 }
1571#ifndef SAMPLEICC_NOCLIPLABTOXYZ
1572 else {
1573 DstPixel[0] = CIccPCSUtil::NegClip(DstPixel[0]);
1574 DstPixel[1] = CIccPCSUtil::NegClip(DstPixel[1]);
1575 DstPixel[2] = CIccPCSUtil::NegClip(DstPixel[2]);
1576 }
1577#endif
1578}
1579
1597{
1598 if (m_bAdjustPCS && !m_bInput) {
1600 AdjustPCS(pAbsLab, Pixel);
1601 return pAbsLab;
1602 }
1603
1604 return Pixel;
1605}
1606
1622{
1623 if (m_bAdjustPCS && m_bInput) {
1624 AdjustPCS(Pixel, Pixel);
1625 }
1626}
1627
1640{
1643
1644 if (m_bInput) {
1645 if (m_bPcsAdjustXform)
1646 rv = m_pProfile->m_Header.pcs;
1647 else {
1648 rv = m_pProfile->m_Header.colorSpace;
1649
1651
1654 }
1657 }
1658 }
1659 }
1660 }
1661 else if (!m_bUseSpectralPCS || !m_pProfile->m_Header.spectralPCS) {
1662 rv = m_pProfile->m_Header.pcs;
1663 }
1664 else {
1666 }
1667
1668 return rv;
1669}
1670
1683{
1685
1688 }
1689 else if (m_bInput) {
1691 }
1692 else if (!m_bUseSpectralPCS || !m_pProfile->m_Header.spectralPCS) {
1694 }
1695 else {
1697 }
1698
1699 return rv;
1700}
1701
1714{
1717
1720 }
1721 else if (m_bInput) {
1722 if (m_bUseSpectralPCS && m_pProfile->m_Header.spectralPCS)
1724 else
1725 rv = m_pProfile->m_Header.pcs;
1726 }
1727 else {
1728 rv = m_pProfile->m_Header.colorSpace;
1729
1730
1734 }
1737 }
1738 }
1739 }
1740
1741 return rv;
1742}
1743
1756{
1758
1761 }
1762 else if (!m_bInput) {
1764 }
1765 else if (!m_bUseSpectralPCS || !m_pProfile->m_Header.spectralPCS) {
1767 }
1768 else {
1770 }
1771
1772 return rv;
1773}
1774
1775
1784CIccApplyXform::CIccApplyXform(CIccXform *pXform) : m_AbsLab{}
1785{
1786 m_pXform = pXform;
1787}
1788
1797CIccApplyXform::~CIccApplyXform()
1798{
1799}
1800
1801
1810CIccApplyNDLutXform::CIccApplyNDLutXform(CIccXformNDLut* pXform,
CIccApplyCLUT *pApply) : CIccApplyXform(pXform)
1811{
1812 m_pApply = pApply;
1813}
1814
1815
1824CIccApplyNDLutXform::~CIccApplyNDLutXform()
1825{
1826 if (m_pApply)
1827 delete m_pApply;
1828}
1829
1830
1839CIccApplyPcsXform::CIccApplyPcsXform(CIccXform *pXform) : CIccApplyXform(pXform)
1840{
1841 m_list = new CIccApplyPcsStepList();
1842 m_temp1 = NULL;
1843 m_temp2 = NULL;
1844}
1845
1854CIccApplyPcsXform::~CIccApplyPcsXform()
1855{
1856
1857 if (m_list) {
1858 CIccApplyPcsStepList::iterator i;
1859 for (i=m_list->begin(); i!=m_list->end(); i++) {
1860 if (i->ptr)
1861 delete i->ptr;
1862 }
1863
1864 delete m_list;
1865 }
1866
1867 if (m_temp1)
1868 delete [] m_temp1;
1869 if (m_temp2)
1870 delete [] m_temp2;
1871}
1872
1881bool CIccApplyPcsXform::Init()
1882{
1883 CIccPcsXform *pXform = (CIccPcsXform*)m_pXform;
1885
1886 if (nChan) {
1889 }
1890
1891 return m_temp1!=NULL && m_temp2!=NULL;
1892}
1893
1894
1895void CIccApplyPcsXform::AppendApplyStep(CIccApplyPcsStep *pStep)
1896{
1897 CIccApplyPcsStepPtr ptr;
1898
1899 if (pStep && m_list) {
1900 ptr.ptr = pStep;
1901 m_list->push_back(ptr);
1902 }
1903}
1904
1905
1914CIccPcsXform::CIccPcsXform()
1915{
1916 m_list = new CIccPcsStepList();
1917
1919 m_nSrcSamples = 0;
1920
1922 m_nDstSamples = 0;
1923}
1924
1933CIccPcsXform::~CIccPcsXform()
1934{
1935 if (m_list) {
1936 CIccPcsStepList::iterator step;
1937 for (step=m_list->begin(); step!=m_list->end(); step++) {
1938 if (step->ptr) {
1939 delete step->ptr;
1940 step->ptr = NULL;
1941 }
1942 }
1943 delete m_list;
1944 }
1945}
1946
1956icStatusCMM CIccPcsXform::Connect(CIccXform *pFromXform, CIccXform *pToXform)
1957{
1959
1960 if (!pFromXform || !pToXform)
1962
1963 if (pFromXform->IsMCS() && pToXform->IsMCS()) {
1964 CIccProfile *pFromProfile = pFromXform->GetProfilePtr();
1965 CIccProfile *pToProfile = pToXform->GetProfilePtr();
1966
1967 if (!pFromProfile || !pToProfile) {
1969 }
1972
1973 if (!pFromChannels || !pToChannels) {
1975 }
1981 }
1982
1983 m_nSrcSamples = pFromXform->GetNumDstSamples();
1984 m_nDstSamples = pToXform->GetNumSrcSamples();
1985
1986 if (pFromChannels->
GetSize() != m_nSrcSamples || pToChannels->
GetSize() != m_nDstSamples) {
1988 }
1989 int i, j;
1990
1992 for (i=0; i<m_nSrcSamples; i++) {
1994 for (j=0; j<m_nDstSamples; j++) {
1997 break;
1998 }
1999 if (j==m_nDstSamples)
2001 }
2002 }
2003
2005 for (i=0; i<m_nDstSamples; i++) {
2007 for (j=0; j<m_nSrcSamples; j++) {
2010 break;
2011 }
2012 if (j==m_nSrcSamples)
2014 }
2015 }
2020 }
2021
2022 pushRouteMcs(pFromChannels, pToChannels, pDefaults);
2023 }
2024 else {
2025 if (!pFromXform->IsInput() || (pToXform->IsInput() && !pToXform->IsAbstract())) {
2027 }
2028
2029 m_srcSpace = pFromXform->GetDstSpace();
2032
2033 m_nSrcSamples = pFromXform->GetNumDstSamples();
2034
2035 m_dstSpace = pToXform->GetSrcSpace();
2038
2039 m_nDstSamples = pToXform->GetNumSrcSamples();
2040
2041 switch (m_srcSpace) {
2043 switch (m_dstSpace) {
2045 if (pFromXform->UseLegacyPCS())
2046 pushLab2ToXyz(pFromXform->m_pConnectionConditions);
2047 else
2048 pushLabToXyz(pFromXform->m_pConnectionConditions);
2049 if (pFromXform->NeedAdjustPCS()) {
2050 pushScale3(pFromXform->m_PCSScale[0], pFromXform->m_PCSScale[1], pFromXform->m_PCSScale[2]);
2051 pushOffset3(pFromXform->m_PCSOffset[0], pFromXform->m_PCSOffset[1], pFromXform->m_PCSOffset[2]);
2052 }
2053 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2054 return stat;
2055 }
2056 if (pToXform->NeedAdjustPCS()) {
2057 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2058 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2059 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2060 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2061 }
2062 if (pToXform->UseLegacyPCS())
2063 pushXyzToLab2(pToXform->m_pConnectionConditions);
2064 else
2065 pushXyzToLab(pToXform->m_pConnectionConditions);
2066 break;
2067
2069 if (pFromXform->UseLegacyPCS())
2070 pushLab2ToXyz(pFromXform->m_pConnectionConditions);
2071 else
2072 pushLabToXyz(pFromXform->m_pConnectionConditions);
2073 if (pFromXform->NeedAdjustPCS()) {
2074 pushScale3(pFromXform->m_PCSScale[0], pFromXform->m_PCSScale[1], pFromXform->m_PCSScale[2]);
2075 pushOffset3(pFromXform->m_PCSOffset[0], pFromXform->m_PCSOffset[1], pFromXform->m_PCSOffset[2]);
2076 }
2077 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2078 return stat;
2079 }
2080 if (pToXform->NeedAdjustPCS()) {
2081 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2082 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2083 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2084 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2085 }
2086 pushXyzToXyzIn();
2087 break;
2088
2095 }
2096 break;
2097
2099 switch (m_dstSpace) {
2101 pushXyzInToXyz();
2102 if (pFromXform->NeedAdjustPCS()) {
2103 pushScale3(pFromXform->m_PCSScale[0], pFromXform->m_PCSScale[1], pFromXform->m_PCSScale[2]);
2104 pushOffset3(pFromXform->m_PCSOffset[0], pFromXform->m_PCSOffset[1], pFromXform->m_PCSOffset[2]);
2105 }
2106 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2107 return stat;
2108 }
2109 if (pToXform->NeedAdjustPCS()) {
2110 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2111 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2112 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2113 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2114 }
2115 if (pToXform->UseLegacyPCS())
2116 pushXyzToLab2(pToXform->m_pConnectionConditions);
2117 else
2118 pushXyzToLab(pToXform->m_pConnectionConditions);
2119 break;
2120
2122 pushXyzInToXyz();
2123 if (pFromXform->NeedAdjustPCS()) {
2124 pushScale3(pFromXform->m_PCSScale[0], pFromXform->m_PCSScale[1], pFromXform->m_PCSScale[2]);
2125 pushOffset3(pFromXform->m_PCSOffset[0], pFromXform->m_PCSOffset[1], pFromXform->m_PCSOffset[2]);
2126 }
2127 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2128 return stat;
2129 }
2130 if (pToXform->NeedAdjustPCS()) {
2131 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2132 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2133 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2134 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2135 }
2136 pushXyzToXyzIn();
2137 break;
2138
2145 }
2146 break;
2147
2150 switch (m_dstSpace) {
2152 pushRef2Xyz(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions);
2153 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2154 return stat;
2155 }
2156 if (pToXform->NeedAdjustPCS()) {
2157 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2158 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2159 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2160 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2161 }
2162 if (pToXform->UseLegacyPCS())
2163 pushXyzToLab2(pToXform->m_pConnectionConditions);
2164 else
2165 pushXyzToLab(pToXform->m_pConnectionConditions);
2166 break;
2167
2169 pushRef2Xyz(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions);
2170 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2171 return stat;
2172 }
2173 if (pToXform->NeedAdjustPCS()) {
2174 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2175 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2176 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2177 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2178 }
2179 pushXyzToXyzIn();
2180 break;
2181
2184 pushSpecToRange(pFromXform->m_pProfile->m_Header.spectralRange,
2185 pToXform->m_pProfile->m_Header.spectralRange);
2186 break;
2187
2189 pushApplyIllum(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions);
2190 pushSpecToRange(pFromXform->m_pProfile->m_Header.spectralRange,
2191 pToXform->m_pProfile->m_Header.spectralRange);
2192 break;
2193
2197 }
2198 break;
2199
2201 CIccProfile *pFromProfile = pFromXform->GetProfilePtr();
2202 CIccProfile *pToProfile = pToXform->GetProfilePtr();
2203
2204 switch (m_dstSpace) {
2206 pushRad2Xyz(pFromProfile, pFromXform->m_pConnectionConditions, false);
2207 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2208 return stat;
2209 }
2210 if (pToXform->NeedAdjustPCS()) {
2211 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2212 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2213 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2214 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2215 }
2216 if (pToXform->UseLegacyPCS())
2217 pushXyzToLab2(pToXform->m_pConnectionConditions);
2218 else
2219 pushXyzToLab(pToXform->m_pConnectionConditions);
2220 break;
2221
2223 pushRad2Xyz(pFromProfile, pFromXform->m_pConnectionConditions, false);
2224 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2225 return stat;
2226 }
2227 if (pToXform->NeedAdjustPCS()) {
2228 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2229 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2230 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2231 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2232 }
2233 pushXyzToXyzIn();
2234 break;
2235
2239
2240
2242 pushSpecToRange(pFromXform->m_pProfile->m_Header.spectralRange,
2243 pToXform->m_pProfile->m_Header.spectralRange);
2244 break;
2245
2249 }
2250 }
2251 break;
2252
2255 switch (m_dstSpace) {
2257 pushBiRef2Xyz(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions);
2258 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2259 return stat;
2260 }
2261 if (pToXform->NeedAdjustPCS()) {
2262 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2263 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2264 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2265 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2266 }
2267 if (pToXform->UseLegacyPCS())
2268 pushXyzToLab2(pToXform->m_pConnectionConditions);
2269 else
2270 pushXyzToLab(pToXform->m_pConnectionConditions);
2271 break;
2272
2274 if ((stat=pushBiRef2Xyz(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions))!=
icCmmStatOk) {
2275 return stat;
2276 }
2277 if ((stat=pushXYZConvert(pFromXform, pToXform))!=
icCmmStatOk) {
2278 return stat;
2279 }
2280 if (pToXform->NeedAdjustPCS()) {
2281 pushOffset3(pToXform->m_PCSOffset[0]/pToXform->m_PCSScale[0],
2282 pToXform->m_PCSOffset[1]/pToXform->m_PCSScale[1],
2283 pToXform->m_PCSOffset[2]/pToXform->m_PCSScale[2]);
2284 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2285 }
2286 pushXyzToXyzIn();
2287 break;
2288
2291 if ((stat=pushBiRef2Ref(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions))!=
icCmmStatOk) {
2292 return stat;
2293 }
2294 pushSpecToRange(pFromXform->m_pProfile->m_Header.spectralRange,
2295 pToXform->m_pProfile->m_Header.spectralRange);
2296 break;
2297
2299 if ((stat=pushBiRef2Rad(pFromXform->m_pProfile, pFromXform->m_pConnectionConditions))!=
icCmmStatOk) {
2300 return stat;
2301 }
2302 pushSpecToRange(pFromXform->m_pProfile->m_Header.spectralRange,
2303 pToXform->m_pProfile->m_Header.spectralRange);
2304 break;
2305
2307 if (
icSameSpectralRange(pFromXform->m_pProfile->m_Header.spectralRange, pToXform->m_pProfile->m_Header.spectralRange) &&
2308 icSameSpectralRange(pFromXform->m_pProfile->m_Header.biSpectralRange, pToXform->m_pProfile->m_Header.biSpectralRange))
2309 break;
2310 else
2312
2315 }
2316 break;
2317 }
2318 }
2319
2322 return rv;
2323
2324 if (m_list->begin()==m_list->end())
2326
2328}
2329
2330
2341{
2342 if (!pToXform)
2344
2345
2347 pushXyzInToXyz();
2348 if (pToXform->NeedAdjustPCS()) {
2349 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2350 pushOffset3(pToXform->m_PCSOffset[0], pToXform->m_PCSOffset[1], pToXform->m_PCSOffset[2]);
2351 }
2352
2354 if (pToXform->UseLegacyPCS())
2355 pushXyzToLab2(pToXform->m_pConnectionConditions);
2356 else
2357 pushXyzToLab(pToXform->m_pConnectionConditions);
2358 }
2359 }
2361
2363 pushLabToXyz(pToXform->m_pConnectionConditions);
2364 if (pToXform->NeedAdjustPCS()) {
2365 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2366 pushOffset3(pToXform->m_PCSOffset[0], pToXform->m_PCSOffset[1], pToXform->m_PCSOffset[2]);
2367 }
2368 }
2369 else if (pToXform->NeedAdjustPCS()) {
2370 pushLabToXyz(pToXform->m_pConnectionConditions);
2371 pushScale3(pToXform->m_PCSScale[0], pToXform->m_PCSScale[1], pToXform->m_PCSScale[2]);
2372 pushOffset3(pToXform->m_PCSOffset[0], pToXform->m_PCSOffset[1], pToXform->m_PCSOffset[2]);
2373 if (pToXform->UseLegacyPCS())
2374 pushXyzToLab2(pToXform->m_pConnectionConditions);
2375 else
2376 pushXyzToLab(pToXform->m_pConnectionConditions);
2377 }
2378 }
2379
2381}
2382
2383
2394{
2395 if (!pFromXform)
2398
2401 if (pFromXform->UseLegacyPCS())
2402 pushLab2ToXyz(pFromXform->m_pConnectionConditions);
2403 else
2404 pushLabToXyz(pFromXform->m_pConnectionConditions);
2405
2406 pushScale3(pFromXform->m_PCSScale[0], pFromXform->m_PCSScale[1], pFromXform->m_PCSScale[2]);
2407 pushOffset3(pFromXform->m_PCSOffset[0], pFromXform->m_PCSOffset[1], pFromXform->m_PCSOffset[2]);
2408
2410 }
2411 }
2412
2414 pushXyzToLab(pFromXform->m_pConnectionConditions);
2415 }
2417 if (pFromXform->UseLegacyPCS())
2418 pushLab2ToXyz(pFromXform->m_pConnectionConditions);
2419 else
2420 pushLabToXyz(pFromXform->m_pConnectionConditions);
2421 if (pFromXform->IsInput())
2422 pushXyzToXyzIn();
2423 }
2425 pushXyzToXyzIn();
2426 }
2427
2429}
2430
2431
2441{
2442 if (!m_list)
2444
2445 CIccPcsStepList steps = *m_list;
2446 CIccPcsStepList::iterator next, last;
2447 bool done=false;
2448
2449#if 0
2450 std::string str;
2451 for (next = steps.begin(); next != steps.end(); next++) {
2452 next->ptr->dump(str);
2453 }
2454 printf("PCS_Steps:\n%s", str.c_str());
2455#endif
2456
2457 while (!done) {
2458 CIccPcsStepList newSteps;
2459 CIccPcsStepPtr ptr;
2460
2461 done = true;
2462
2463 next = steps.begin();
2464 if (next==steps.end()) {
2465 *m_list = steps;
2467 }
2468 last = next;
2469 next++;
2470
2471 ptr.ptr = last->ptr;
2472
2473 for (;next!=steps.end(); next++) {
2474 CIccPcsStep *pStep = ptr.ptr->concat(next->ptr);
2475
2476 if (pStep) {
2477 done = false;
2478
2479 delete ptr.ptr;
2480 delete next->ptr;
2481 ptr.ptr = pStep;
2482 }
2483 else {
2484 if (!ptr.ptr->isIdentity()) {
2485 newSteps.push_back(ptr);
2486 }
2487 ptr.ptr = next->ptr;
2488 }
2489 }
2490 if (!ptr.ptr->isIdentity()) {
2491 newSteps.push_back(ptr);
2492 }
2493
2494 steps = newSteps;
2495
2496
2497
2498
2499
2500
2501 }
2502
2503 if (!steps.empty()) {
2504 CIccPcsStepList newSteps;
2505 CIccPcsStepPtr ptr;
2506
2507 for (next=steps.begin(); next != steps.end(); next++) {
2508 ptr.ptr = next->ptr->reduce();
2509 if (ptr.ptr != next->ptr)
2510 delete next->ptr;
2511 newSteps.push_back(ptr);
2512 }
2513 steps = newSteps;
2514 }
2515
2516 *m_list = steps;
2517
2519}
2520
2521
2531CIccApplyXform *CIccPcsXform::GetNewApply(
icStatusCMM &status)
2532{
2533 CIccApplyPcsXform *pNew = new CIccApplyPcsXform(this);
2534
2535 if (pNew) {
2536 if (!pNew->Init()) {
2537 delete pNew;
2539 return NULL;
2540 }
2541 }
2542 else {
2544 return NULL;
2545 }
2546
2547 CIccPcsStepList::iterator i;
2548 CIccApplyPcsStep *pStep;
2549
2550 for (i=m_list->begin(); i!=m_list->end(); i++) {
2551 pStep = i->ptr->GetNewApply();
2553 delete pNew;
2554 return NULL;
2555 }
2556 pNew->AppendApplyStep(pStep);
2557 }
2558
2559 return pNew;
2560}
2561
2562
2572{
2574 CIccPcsStepList::const_iterator s = m_list->begin();
2575 if (s==m_list->end())
2576 return nMax;
2577 nMax = s->ptr->GetDstChannels();
2578 s++;
2579 for (; s!= m_list->end(); s++) {
2580 if (s->ptr->GetSrcChannels()>nMax)
2581 nMax = s->ptr->GetSrcChannels();
2582 }
2583 return nMax;
2584}
2585
2595{
2596 CIccPcsStepPtr ptr;
2597
2598 ptr.ptr = new CIccPcsStepRouteMcs(pSrcChannels, pDstChannels, pDefaults);
2599 m_list->push_back(ptr);
2600}
2601
2602
2612{
2615
2616 CIccPcsStepPtr ptr;
2617
2618 ptr.ptr = new CIccPcsStepLab2ToXYZ(xyzWhite);
2619 m_list->push_back(ptr);
2620}
2621
2622
2632{
2635
2636 CIccPcsStepPtr ptr;
2637
2638 ptr.ptr = new CIccPcsStepXYZToLab2(xyzWhite);
2639 m_list->push_back(ptr);
2640}
2641
2642
2652{
2655
2656 CIccPcsStepPtr ptr;
2657
2658 ptr.ptr = new CIccPcsStepLabToXYZ(xyzWhite);
2659 m_list->push_back(ptr);
2660}
2661
2662
2672{
2675
2676 CIccPcsStepPtr ptr;
2677
2678 ptr.ptr = new CIccPcsStepXYZToLab(xyzWhite);
2679 m_list->push_back(ptr);
2680}
2681
2692{
2693 CIccPcsStepScale *scale;
2694 CIccPcsStepPtr ptr;
2695
2696 scale = new CIccPcsStepScale(3);
2698 data[0] = v1;
2699 data[1] = v2;
2700 data[2] = v3;
2701
2702 ptr.ptr = scale;
2703 m_list->push_back(ptr);
2704}
2705
2714void CIccPcsXform::pushXyzToXyzIn()
2715{
2717 pushScale3(scale, scale, scale);
2718}
2719
2720
2729void CIccPcsXform::pushXyzInToXyz()
2730{
2732 return pushScale3(scale, scale, scale);
2733}
2734
2735
2745{
2748
2750
2751 return pushScale3(scale, scale, scale);
2752}
2753
2754
2764{
2767
2769
2770 return pushScale3(scale, scale, scale);
2771}
2772
2773
2785{
2786 CIccPcsStepOffset *offset;
2787 CIccPcsStepPtr ptr;
2788
2789 offset = new CIccPcsStepOffset(3);
2791 if (bConvertIntXyzOffset) {
2792 data[0] = v1*65535.0f/32768.0f;
2793 data[1] = v2*65535.0f/32768.0f;
2794 data[2] = v3*65535.0f/32768.0f;
2795 }
2796 else {
2797 data[0] = v1;
2798 data[1] = v2;
2799 data[2] = v3;
2800 }
2801
2802 ptr.ptr = offset;
2803 m_list->push_back(ptr);
2804}
2805
2806
2817{
2818 CIccPcsStepScale *scale = new CIccPcsStepScale(n);
2820
2821 CIccPcsStepPtr ptr;
2822 ptr.ptr = scale;
2823 m_list->push_back(ptr);
2824}
2825
2826
2836{
2837 CIccPcsStepMatrix *mtx = new CIccPcsStepMatrix(nRows, nCols);
2838 memcpy(mtx->entry(0), vals, nRows*nCols*
sizeof(
icFloatNumber));
2839
2840 CIccPcsStepPtr ptr;
2841 ptr.ptr = mtx;
2842 m_list->push_back(ptr);
2843}
2844
2845
2856icStatusCMM CIccPcsXform::pushXYZConvert(CIccXform *pFromXform, CIccXform *pToXform)
2857{
2860
2861 if (!pSrcPcc || !pDstPcc)
2863
2864
2867 }
2868
2869 CIccPcsStepPtr ptr;
2870
2872
2874
2877
2878 ptr.ptr = NULL;
2879
2880
2883 if (pElem) {
2886
2889
2890 if (pMat && (!pOffset || (pOffset[0]==0.0 && pOffset[1]==0.0 && pOffset[2]==0.0))) {
2891 CIccPcsStepMatrix *pStepMtx = new CIccPcsStepMatrix(3, 3);
2892
2893 if (pStepMtx ) {
2894 memcpy(pStepMtx->entry(0,0), pMat, 9*
sizeof(
icFloatNumber));
2895 }
2896 ptr.ptr = pStepMtx;
2897 }
2898 }
2899 }
2900 }
2901
2902 if (!ptr.ptr) {
2904
2905 if (!pStepMpe)
2907
2908 if (!pStepMpe->Begin()) {
2909 delete pStepMpe;
2911 }
2912
2913 ptr.ptr = pStepMpe;
2914 }
2915
2916 m_list->push_back(ptr);
2917 }
2918
2920
2922
2925
2926 ptr.ptr = NULL;
2927
2928
2931 if (pElem) {
2934
2937
2938 if (pMat && (!pOffset || (pOffset[0]==0.0 && pOffset[1]==0.0 && pOffset[2]==0.0))) {
2939 CIccPcsStepMatrix *pStepMtx = new CIccPcsStepMatrix(3, 3);
2940
2941 if (pStepMtx ) {
2942 memcpy(pStepMtx->entry(0,0), pMat, 9*
sizeof(
icFloatNumber));
2943 }
2944 ptr.ptr = pStepMtx;
2945 }
2946 }
2947 }
2948 }
2949
2950 if (!ptr.ptr) {
2952
2953 if (!pStepMpe)
2955
2956 if (!pStepMpe->Begin()) {
2957 delete pStepMpe;
2959 }
2960
2961 ptr.ptr = pStepMpe;
2962 }
2963
2964 m_list->push_back(ptr);
2965 }
2966
2967 if (pFromXform->LuminanceMatching()) {
2968 pushXyzToXyzLum(pSrcPcc);
2969 }
2970 if (pToXform->LuminanceMatching()) {
2971 pushXyzLumToXyz(pDstPcc);
2972 }
2973
2975}
2976
2978{
2980 CIccPcsXform tmp;
2981
2984
2987
2988
2990 tmp.pushSpecToRange(illuminantRange, srcRange);
2991 tmp.pushSpecToRange(srcRange, dstRange);
2992 tmp.pushSpecToRange(dstRange, observerRange);
2993 }
2994 else {
2995 tmp.pushSpecToRange(illuminantRange, observerRange);
2996 }
2997 tmp.pushMatrix(3, observerRange.
steps, observer);
2998
3000 CIccApplyXform *pApply = tmp.GetNewApply(stat);
3001 if (pApply) {
3003
3004
3005 tmp.Apply(pApply, xyz, illuminant);
3006
3007
3008 normxyz[0] = xyz[0] / xyz[1];
3009 normxyz[1] = xyz[1] / xyz[1];
3010 normxyz[2] = xyz[2] / xyz[1];
3011
3012
3014
3015#if 1
3016
3017 pushScale3(pccxyz[0] / (normxyz[0] * xyz[1]),
3018 pccxyz[1] / (normxyz[1] * xyz[1]),
3019 pccxyz[2] / (normxyz[2] * xyz[1]));
3020#else
3021 pushScale3(1.0f/xyz[1], 1.0f/xyz[1], 1.0f/xyz[1]);
3022#endif
3023
3024 delete pApply;
3025 }
3026}
3027
3039{
3041
3042 if (pView) {
3045
3048
3049 pushSpecToRange(pProfile->m_Header.spectralRange, illuminantRange);
3050 pushScale(illuminantRange.
steps, illuminant);
3051 pushSpecToRange(illuminantRange, observerRange);
3052 pushMatrix(3, observerRange.
steps, observer);
3053
3054 pushXYZNormalize(pPcc, illuminantRange, illuminantRange);
3055 }
3056}
3057
3058
3069{
3072 srcRange.
end != dstRange.
end) {
3073 CIccPcsStepMatrix *mtx =
new CIccPcsStepMatrix(dstRange.
steps, srcRange.
steps);
3074 if (!mtx->SetRange(srcRange, dstRange))
3075 {
3076 delete mtx;
3077 return NULL;
3078 }
3079 return mtx;
3080 }
3081
3082 return NULL;
3083}
3084
3085
3096{
3098 CIccPcsStepPtr ptr;
3099 ptr.ptr = rangeMap(srcRange, dstRange);
3100
3101 if (ptr.ptr)
3102 m_list->push_back(ptr);
3103 }
3104}
3105
3106
3119{
3121
3122 if (pView) {
3123 CIccPcsStepPtr ptr;
3124
3127
3128 CIccPcsStepScale *pScale =
new CIccPcsStepScale(illuminantRange.
steps);
3130
3132 ptr.ptr = pScale;
3133 m_list->push_back(ptr);
3134 }
3135 else {
3136 ptr.ptr = rangeMap(pProfile->m_Header.spectralRange, illuminantRange);
3137 if (ptr.ptr) {
3138 m_list->push_back(ptr);
3139 }
3140
3141 ptr.ptr = pScale;
3142 m_list->push_back(ptr);
3143
3144 ptr.ptr = rangeMap(illuminantRange, pProfile->m_Header.spectralRange);
3145 if (ptr.ptr)
3146 m_list->push_back(ptr);
3147 }
3148 }
3149}
3150
3151
3163{
3166 if (pProfView && pView) {
3169
3172
3173
3176
3177 if (dPCSStepSize<dObsStepSize) {
3179
3180 pushMatrix(3, pProfile->m_Header.spectralRange.steps, obs);
3181 free(obs);
3182 }
3183 else {
3184 pushSpecToRange(pProfile->m_Header.spectralRange, observerRange);
3185 pushMatrix(3, observerRange.
steps, observer);
3186
3187 }
3189 if (bAbsoluteCIEColorimetry) {
3190 k = 683;
3191 }
3192 else {
3194 }
3195 pushScale3(k, k, k);
3196 }
3197}
3198
3199
3210{
3212
3213 if (pView) {
3216
3218 CIccPcsStepSrcSparseMatrix *pMtx = new CIccPcsStepSrcSparseMatrix(pProfile->m_Header.spectralRange.steps,
3219 pProfile->m_Header.biSpectralRange.steps,
3221 if (!pMtx)
3223
3224 CIccPcsStepMatrix *illumMtx = rangeMap(illuminantRange, pProfile->m_Header.biSpectralRange);
3225 if (illumMtx) {
3226 illumMtx->Apply(NULL, pMtx->data(), illuminant);
3227 delete illumMtx;
3228 }
3229 else {
3231 }
3232
3233 CIccPcsStepPtr ptr;
3234 ptr.ptr = pMtx;
3235 m_list->push_back(ptr);
3236
3237 }
3238 else {
3239 CIccPcsStepSrcMatrix *pMtx = new CIccPcsStepSrcMatrix(pProfile->m_Header.spectralRange.steps, pProfile->m_Header.biSpectralRange.steps);
3240 if (!pMtx)
3242
3243 CIccPcsStepMatrix *illumMtx = rangeMap(illuminantRange, pProfile->m_Header.biSpectralRange);
3244 if (illumMtx) {
3245 illumMtx->Apply(NULL, pMtx->data(), illuminant);
3246 delete illumMtx;
3247 }
3248 else {
3250 }
3251
3252 CIccPcsStepPtr ptr;
3253 ptr.ptr = pMtx;
3254 m_list->push_back(ptr);
3255
3256 }
3257 }
3258
3260}
3261
3262
3275{
3278 return stat;
3279
3281
3282 if (pView) {
3285
3286 pushSpecToRange(pProfile->m_Header.spectralRange, observerRange);
3287 pushMatrix(3, observerRange.
steps, observer);
3288 pushXYZNormalize(pPcc, pProfile->m_Header.biSpectralRange, pProfile->m_Header.spectralRange);
3289 }
3290 else {
3292 }
3293
3295}
3296
3297
3309{
3312 return stat;
3313
3315
3316 if (pView) {
3319
3320 CIccPcsStepScale *pScale = new CIccPcsStepScale(pProfile->m_Header.spectralRange.steps);
3321
3322 if (pScale) {
3324 CIccPcsStepMatrix *illumMtx = rangeMap(illuminantRange, pProfile->m_Header.spectralRange);
3325 int i;
3326
3327 if (illumMtx) {
3328 illumMtx->Apply(NULL, pData, illuminant);
3329 for (i=0; i<pProfile->m_Header.spectralRange.steps; i++)
3330 pData[i] = 1.0f / pData[i];
3331
3332 delete illumMtx;
3333
3334 }
3335 else {
3336 for (i=0; i<pProfile->m_Header.spectralRange.steps; i++) {
3337 pData[i] = 1.0f / illuminant[i];
3338 }
3339 }
3340
3341 CIccPcsStepPtr ptr;
3342 ptr.ptr = pScale;
3343 m_list->push_back(ptr);
3344 }
3345 else
3347 }
3348 else
3350
3352}
3353
3354
3355#ifdef _DEBUG
3356
3357#ifdef DUMPCSSTEPRESULTS
3358 #define ICCDUMPPIXEL(n, pix) \
3359 if ((n)<96) { \
3360 printf("["); \
3361 int i; \
3362 for (i=0; i<(n); i++) { \
3363 if (i && !(i%12)) \
3364 printf("...\n"); \
3365 printf(" %.5f", pix[i]); \
3366 } \
3367 printf("]\n"); \
3368 } \
3369 else { \
3370 printf("[ BigAray with %d elements]\n", (n)); \
3371 }
3372#else
3373 #define ICCDUMPPIXEL(n, pix)
3374#endif
3375#else
3376 #define ICCDUMPPIXEL(n, pix)
3377#endif
3378
3379
3389{
3390 CIccApplyPcsXform *pApplyXform = (CIccApplyPcsXform*)pXform;
3391 CIccApplyPcsStepList *pList = pApplyXform->m_list;
3392
3394
3395 if (!pList) {
3396 memcpy(DstPixel, SrcPixel, GetNumSrcSamples()*
sizeof(
icFloatNumber));
3398 return;
3399 }
3400
3401 CIccApplyPcsStepList::iterator s, n;
3402 s = n =pList->begin();
3403
3404 if (s==pList->end()) {
3405 memcpy(DstPixel, SrcPixel, GetNumSrcSamples()*
sizeof(
icFloatNumber));
3407 return;
3408 }
3409
3410 n++;
3411
3412 if (n==pList->end()) {
3413 s->ptr->Apply(DstPixel, SrcPixel);
3414 ICCDUMPPIXEL(s->ptr->GetStep()->GetDstChannels(), DstPixel);
3415 }
3416 else {
3421
3422 for (;n!=pList->end(); s=n, n++) {
3423 s->ptr->Apply(p1, src);
3425 src=p1;
3426 t=p1; p1=p2; p2=t;
3427 }
3428 s->ptr->Apply(DstPixel, src);
3429 ICCDUMPPIXEL(s->ptr->GetStep()->GetDstChannels(), DstPixel);
3430 }
3431}
3432
3441CIccApplyPcsStep* CIccPcsStep::GetNewApply()
3442{
3443 return new CIccApplyPcsStep(this);
3444}
3445
3446
3456{
3457 if (pDst != pSrc)
3459}
3460
3461
3470void CIccPcsStepIdentity::dump(std::string &str) const
3471{
3472 str += "\nCIccPcsStepIdentity\n\n";
3473}
3474
3475
3485{
3488 m_Index = new int[m_nDstChannels];
3490
3491 memset(m_Defaults, 0, m_nDstChannels*
sizeof(
icFloatNumber));
3492
3493 if (pDefaults) {
3494 pDefaults->
GetValues(m_Defaults, 0, m_nDstChannels);
3495 }
3496
3497 int i, j;
3498 char *szSrc;
3499
3500 for (i=0; i<m_nDstChannels; i++) {
3502 for (j=0; j<m_nSrcChannels; j++) {
3504 szSrc = (char*)szSrcChan;
3506 break;
3507 }
3508 if (j==m_nSrcChannels) {
3509 m_Index[i] = -1;
3510 }
3511 else {
3512 m_Index[i] = j;
3513 }
3514
3515 }
3516}
3517
3518
3527CIccPcsStepRouteMcs::~CIccPcsStepRouteMcs()
3528{
3529 if (m_Index)
3530 delete [] m_Index;
3531 if (m_Defaults)
3532 delete [] m_Defaults;
3533}
3534
3535
3544bool CIccPcsStepRouteMcs::isIdentity() const
3545{
3546 if (m_nSrcChannels!=m_nDstChannels)
3547 return false;
3548
3549 int i;
3550 for (i=0; i<m_nDstChannels; i++) {
3551 if (m_Index[i]!=i)
3552 return false;
3553 }
3554
3555 return true;
3556}
3557
3558
3559
3569{
3570 if (pDst != pSrc) {
3571 int i;
3572 for (i=0; i<m_nDstChannels; i++) {
3573 if (m_Index[i]>=0)
3574 pDst[i] = pSrc[m_Index[i]];
3575 else
3576 pDst[i] = m_Defaults[i];
3577 }
3578 }
3579}
3580
3581
3590void CIccPcsStepRouteMcs::dump(std::string &str) const
3591{
3592 str += "\nCIccPcsStepRouteMcs\n\n";
3593}
3594
3596
3605bool CIccPcsLabStep::isSameWhite(
const icFloatNumber *xyzWhite)
3606{
3607 return (m_xyzWhite[0]==xyzWhite[0] &&
3608 m_xyzWhite[1]==xyzWhite[1] &&
3609 m_xyzWhite[2]==xyzWhite[2]);
3610}
3611
3612
3613
3622CIccPcsStepLabToXYZ::CIccPcsStepLabToXYZ(
const icFloatNumber *xyzWhite)
3623{
3624 if (xyzWhite) {
3625 memcpy(m_xyzWhite, xyzWhite, sizeof(m_xyzWhite));
3626 }
3627 else {
3628 memcpy(m_xyzWhite,
icD50XYZ,
sizeof(m_xyzWhite));
3629 }
3630}
3631
3632
3642{
3644
3645
3646 Lab[0] = pSrc[0] * 100.0f;
3649
3651}
3652
3653
3662void CIccPcsStepLabToXYZ::dump(std::string &str) const
3663{
3664 str += "\nCIccPcsStepLabToXYZ\n\n";
3665}
3666
3667
3678CIccPcsStep *CIccPcsStepLabToXYZ::concat(CIccPcsStep *pNext) const
3679{
3680 if (pNext) {
3681 if (pNext->GetType() == icPcsStepXYZToLab) {
3682 CIccPcsLabStep* pStep = (CIccPcsLabStep*)pNext;
3683 if (pStep->isSameWhite(m_xyzWhite))
3684 return new CIccPcsStepIdentity(3);
3685 }
3686 else if (pNext->GetType() == icPcsStepXYZToLab2) {
3687 CIccPcsLabStep* pStep = (CIccPcsLabStep*)pNext;
3688 if (pStep->isSameWhite(m_xyzWhite))
3689 return new CIccPcsStepLabToLab2();
3690 }
3691 }
3692 return NULL;
3693}
3694
3695
3704CIccPcsStepXYZToLab::CIccPcsStepXYZToLab(
const icFloatNumber *xyzWhite)
3705{
3706 if (xyzWhite) {
3707 memcpy(m_xyzWhite, xyzWhite, sizeof(m_xyzWhite));
3708 }
3709 else {
3710 memcpy(m_xyzWhite,
icD50XYZ,
sizeof(m_xyzWhite));
3711 }
3712}
3713
3714
3724{
3727
3728 pDst[0] = Lab[0] / 100.0f;
3731}
3732
3733
3742void CIccPcsStepXYZToLab::dump(std::string &str) const
3743{
3744 str += "\nCIccPcsStepXYZToLab\n\n";
3745}
3746
3747
3758CIccPcsStep *CIccPcsStepXYZToLab::concat(CIccPcsStep *pNext) const
3759{
3760 if (pNext && pNext->GetType()==icPcsStepLabToXYZ) {
3761 CIccPcsLabStep *pStep = (CIccPcsLabStep *)pNext;
3762 if (pStep->isSameWhite(m_xyzWhite))
3763 return new CIccPcsStepIdentity(3);
3764 }
3765 return NULL;
3766}
3767
3768
3777CIccPcsStepLab2ToXYZ::CIccPcsStepLab2ToXYZ(
const icFloatNumber *xyzWhite)
3778{
3779 if (xyzWhite) {
3780 memcpy(m_xyzWhite, xyzWhite, sizeof(m_xyzWhite));
3781 }
3782 else {
3783 memcpy(m_xyzWhite,
icD50XYZ,
sizeof(m_xyzWhite));
3784 }
3785}
3786
3796{
3798
3799
3800 Lab[0] = pSrc[0] * (65535.0f / 65280.0f) * 100.0f;
3801 Lab[1] = (
icFloatNumber)(pSrc[1] * 65535.0f / 65280.0f * 255.0f - 128.0f);
3802 Lab[2] = (
icFloatNumber)(pSrc[2] * 65535.0f / 65280.0f * 255.0f - 128.0f);
3803
3805}
3806
3807
3816void CIccPcsStepLab2ToXYZ::dump(std::string &str) const
3817{
3818 str += "\nCIccPcsStepLab2ToXYZ\n\n";
3819}
3820
3821
3832CIccPcsStep *CIccPcsStepLab2ToXYZ::concat(CIccPcsStep *pNext) const
3833{
3834 if (pNext) {
3835 if (pNext->GetType() == icPcsStepXYZToLab2) {
3836 CIccPcsLabStep* pStep = (CIccPcsLabStep*)pNext;
3837 if (pStep->isSameWhite(m_xyzWhite))
3838 return new CIccPcsStepIdentity(3);
3839 }
3840 else if (pNext->GetType() == icPcsStepXYZToLab) {
3841 CIccPcsLabStep* pStep = (CIccPcsLabStep*)pNext;
3842 if (pStep->isSameWhite(m_xyzWhite))
3843 return new CIccPcsStepLab2ToLab();
3844 }
3845 }
3846
3847 return NULL;
3848}
3849
3850
3859CIccPcsStepXYZToLab2::CIccPcsStepXYZToLab2(
const icFloatNumber *xyzWhite)
3860{
3861 if (xyzWhite) {
3862 memcpy(m_xyzWhite, xyzWhite, sizeof(m_xyzWhite));
3863 }
3864 else {
3865 memcpy(m_xyzWhite,
icD50XYZ,
sizeof(m_xyzWhite));
3866 }
3867}
3868
3869
3879{
3882
3883 pDst[0] = (Lab[0] / 100.0f) * (65280.0f / 65535.0f);
3884 pDst[1] = (
icFloatNumber)((Lab[1] + 128.0f) / 255.0f) * (65280.0f / 65535.0f);
3885 pDst[2] = (
icFloatNumber)((Lab[2] + 128.0f) / 255.0f) * (65280.0f / 65535.0f);
3886}
3887
3888
3897void CIccPcsStepXYZToLab2::dump(std::string &str) const
3898{
3899 str += "\nCIccPcsStepXYZToLab2\n\n";
3900}
3901
3902
3913CIccPcsStep *CIccPcsStepXYZToLab2::concat(CIccPcsStep *pNext) const
3914{
3915 if (pNext && pNext->GetType()==icPcsStepLab2ToXYZ) {
3916 CIccPcsLabStep *pStep = (CIccPcsLabStep *)pNext;
3917 if (pStep->isSameWhite(m_xyzWhite))
3918 return new CIccPcsStepIdentity(3);
3919 }
3920 return NULL;
3921}
3922
3923
3933{
3937}
3938
3939
3948void CIccPcsStepLabToLab2::dump(std::string& str) const
3949{
3950 str += "\nCIccPcsStepLabToLab2\n\n";
3951}
3952
3963CIccPcsStep* CIccPcsStepLabToLab2::concat(CIccPcsStep* pNext) const
3964{
3965 if (pNext && pNext->GetType() == icPcsStepLab2ToLab) {
3966 return new CIccPcsStepIdentity(3);
3967 }
3968 return NULL;
3969}
3970
3971
3981{
3985}
3986
3987
3996void CIccPcsStepLab2ToLab::dump(std::string& str) const
3997{
3998 str += "\nCIccPcsStepLab2ToLab\n\n";
3999}
4000
4001
4012CIccPcsStep* CIccPcsStepLab2ToLab::concat(CIccPcsStep* pNext) const
4013{
4014 if (pNext && pNext->GetType() == icPcsStepLabToLab2) {
4015 return new CIccPcsStepIdentity(3);
4016 }
4017 return NULL;
4018}
4019
4020
4030{
4031 m_nChannels = nChannels;
4033}
4034
4035
4044CIccPcsStepOffset::~CIccPcsStepOffset()
4045{
4046 if (m_vals)
4047 delete [] m_vals;
4048}
4049
4050
4060{
4061 if (m_nChannels==3) {
4062 pDst[0] = m_vals[0] + pSrc[0];
4063 pDst[1] = m_vals[1] + pSrc[1];
4064 pDst[2] = m_vals[2] + pSrc[2];
4065 }
4066 else {
4067 int i;
4068 for (i=0; i<m_nChannels; i++) {
4069 pDst[i] = m_vals[i] + pSrc[i];
4070 }
4071 }
4072}
4073
4074
4083void CIccPcsStepOffset::dump(std::string &str) const
4084{
4085 str += "\nCIccPcsStepOffset\n\n";
4086 char buf[80];
4087 for (int i=0; i<m_nChannels; i++) {
4089 str += buf;
4090 }
4091 str +="\n";
4092}
4093
4094
4104CIccPcsStepOffset *CIccPcsStepOffset::Add(const CIccPcsStepOffset *offset) const
4105{
4106 if (offset->m_nChannels != m_nChannels)
4107 return NULL;
4108
4109 CIccPcsStepOffset *pNew = new CIccPcsStepOffset(m_nChannels);
4110
4111 if (pNew) {
4112 int i;
4113 for (i=0; i<m_nChannels; i++) {
4114 pNew->m_vals[i] = m_vals[i] + offset->m_vals[i];
4115 }
4116 }
4117
4118 return pNew;
4119}
4120
4131CIccPcsStep *CIccPcsStepOffset::concat(CIccPcsStep *pNext) const
4132{
4133 if (pNext && pNext->GetType()==icPcsStepOffset && m_nChannels==pNext->GetSrcChannels())
4134 return Add((const CIccPcsStepOffset*)pNext);
4135
4136 return NULL;
4137}
4138
4139
4148bool CIccPcsStepOffset::isIdentity() const
4149{
4150 int i;
4151 for (i=0; i<m_nChannels; i++) {
4153 return false;
4154 }
4155
4156 return true;
4157}
4158
4159
4169{
4170 m_nChannels = nChannels;
4172}
4173
4174
4183CIccPcsStepScale::~CIccPcsStepScale()
4184{
4185 if (m_vals)
4186 delete [] m_vals;
4187}
4188
4198{
4199 if (m_nChannels==3) {
4200 pDst[0] = m_vals[0] * pSrc[0];
4201 pDst[1] = m_vals[1] * pSrc[1];
4202 pDst[2] = m_vals[2] * pSrc[2];
4203 }
4204 else {
4205 int i;
4206 for (i=0; i<m_nChannels; i++) {
4207 pDst[i] = m_vals[i] * pSrc[i];
4208 }
4209 }
4210}
4211
4212
4221void CIccPcsStepScale::dump(std::string &str) const
4222{
4223 str += "\nCIccPcsStepScale\n\n";
4224 char buf[80];
4225 for (int i=0; i<m_nChannels; i++) {
4227 str += buf;
4228 }
4229 str +="\n";
4230}
4231
4232
4242CIccPcsStepScale *CIccPcsStepScale::Mult(const CIccPcsStepScale *scale) const
4243{
4244 if (scale->m_nChannels != m_nChannels)
4245 return NULL;
4246
4247 CIccPcsStepScale *pNew = new CIccPcsStepScale(m_nChannels);
4248
4249 if (pNew) {
4250 int i;
4251 for (i=0; i<m_nChannels; i++) {
4252 pNew->m_vals[i] = m_vals[i] * scale->m_vals[i];
4253 }
4254 }
4255 return pNew;
4256}
4257
4267CIccPcsStepMatrix *CIccPcsStepScale::Mult(const CIccPcsStepMatrix *matrix) const
4268{
4269 if (matrix->GetSrcChannels() != m_nChannels)
4270 return NULL;
4271
4272 CIccPcsStepMatrix *pNew = new CIccPcsStepMatrix(matrix->GetDstChannels(), matrix->GetSrcChannels());
4273
4274 if (pNew) {
4275 int i, j;
4276 for (j=0; j<matrix->GetDstChannels(); j++) {
4279
4280 for (i=0; i<m_nChannels; i++) {
4281 to[i] = m_vals[i] * row[i];
4282 }
4283 }
4284 }
4285
4286 return pNew;
4287}
4288
4298CIccPcsStepMatrix *CIccPcsStepScale::Mult(
const CIccMpeMatrix *matrix)
const
4299{
4301 return NULL;
4302
4304
4305 if (pNew) {
4306 int i, j;
4311
4312 for (i = 0; i < m_nChannels; i++) {
4313 to[i] = m_vals[i] * row[i];
4314 }
4315 }
4316 }
4317
4318 return pNew;
4319}
4320
4321
4332CIccPcsStep *CIccPcsStepScale::concat(CIccPcsStep *pNext) const
4333{
4334 if (pNext) {
4335 if (pNext->GetType()==icPcsStepScale && m_nChannels==pNext->GetSrcChannels())
4336 return Mult((const CIccPcsStepScale*)pNext);
4337 if (pNext->GetType()==icPcsStepMatrix && m_nChannels==pNext->GetSrcChannels())
4338 return Mult((const CIccPcsStepMatrix*)pNext);
4339 if (pNext->GetType() == icPcsStepMpe && m_nChannels == pNext->GetSrcChannels()) {
4340 CIccPcsStepMpe *pMpe = (CIccPcsStepMpe*)pNext;
4342 if (pMatrix)
4343 return Mult(pMatrix);
4344 }
4345 }
4346
4347 return NULL;
4348}
4349
4350
4359bool CIccPcsStepScale::isIdentity() const
4360{
4361 int i;
4362 for (i=0; i<m_nChannels; i++) {
4364 return false;
4365 }
4366
4367 return true;
4368}
4369
4370
4371
4380void CIccPcsStepMatrix::dump(std::string &str) const
4381{
4382 str += "\nCIccPcsStepMatrix\n\n";
4383 dumpMtx(str);
4384}
4385
4386
4396CIccPcsStepMatrix *CIccPcsStepMatrix::Mult(const CIccPcsStepScale *scale) const
4397{
4400
4401 if (m_nRows != mCols)
4402 return NULL;
4403
4404 CIccPcsStepMatrix *pNew = new CIccPcsStepMatrix(m_nRows, m_nCols);
4406
4407 int i, j;
4408 for (j=0; j<m_nRows; j++) {
4411 for (i=0; i<m_nCols; i++) {
4412 to[i] = data[j] * row[i];
4413 }
4414 }
4415
4416 return pNew;
4417}
4418
4428CIccPcsStepMatrix *CIccPcsStepMatrix::Mult(const CIccPcsStepMatrix *matrix) const
4429{
4432
4433 if (m_nRows != mCols)
4434 return NULL;
4435
4436 CIccPcsStepMatrix *pNew = new CIccPcsStepMatrix(mRows, m_nCols);
4437
4438 int i, j, k;
4439 for (j=0; j<mRows; j++) {
4441 for (i=0; i<m_nCols; i++) {
4444
4445 *to = 0.0f;
4446 for (k=0; k<m_nRows; k++) {
4447 *to += row[k] * (*from);
4448 from += m_nCols;
4449 }
4450 }
4451 }
4452
4453 return pNew;
4454}
4455
4456
4467CIccPcsStep *CIccPcsStepMatrix::concat(CIccPcsStep *pNext) const
4468{
4469 if (pNext) {
4470 if (pNext->GetType()==icPcsStepScale && GetDstChannels()==pNext->GetSrcChannels())
4471 return Mult((const CIccPcsStepScale*)pNext);
4472 if (pNext->GetType()==icPcsStepMatrix && GetDstChannels()==pNext->GetSrcChannels())
4473 return Mult((const CIccPcsStepMatrix*)pNext);
4474 }
4475
4476 return NULL;
4477}
4478
4489CIccPcsStep *CIccPcsStepMatrix::reduce() const
4490{
4491 int nVals = m_nRows*m_nCols;
4492 int nNonZeros = 0;
4493 int i;
4494
4495 for (i=0; i<nVals; i++) {
4498 nNonZeros++;
4499 }
4500 if (nNonZeros<nVals*3/4) {
4502 CIccPcsStepSparseMatrix *pMtx = new CIccPcsStepSparseMatrix(m_nRows, m_nCols, nMatrixBytes);
4504 mtx.Init(m_nRows, m_nCols, true);
4505 mtx.FillFromFullMatrix(m_vals);
4506 return pMtx;
4507 }
4508
4509 return (CIccPcsStep*)this;
4510}
4511
4512
4513
4523{
4524 m_pMpe = pMpe;
4525}
4526
4527
4536CIccPcsStepMpe::~CIccPcsStepMpe()
4537{
4538 if (m_pMpe)
4539 delete m_pMpe;
4540}
4541
4542
4551CIccApplyPcsStep* CIccPcsStepMpe::GetNewApply()
4552{
4553 CIccApplyPcsStepMpe *rv = new CIccApplyPcsStepMpe(this, m_pMpe->GetNewApply());
4554
4555 return rv;
4556}
4557
4558
4568{
4569 CIccApplyPcsStepMpe *pMpeApply = (CIccApplyPcsStepMpe*)pApply;
4570
4571 m_pMpe->Apply(pMpeApply->m_pApply, pDst, pSrc);
4572}
4573
4574
4583void CIccPcsStepMpe::dump(std::string &str) const
4584{
4585 str += "\nCIccPcsStepMpe\n\n";
4586 m_pMpe->Describe(str, 100);
4587}
4588
4589
4598bool CIccPcsStepMpe::isIdentity() const
4599{
4600 if (!m_pMpe || !m_pMpe->NumElements())
4601 return true;
4602 return false;
4603}
4604
4615{
4616 return m_pMpe->NumInputChannels();
4617}
4618
4619
4630{
4631 return m_pMpe->NumOutputChannels();
4632}
4633
4634
4645{
4646
4647 if (m_pMpe->NumElements() == 1) {
4649
4652
4653
4655 return pMtx;
4656 }
4657 }
4658
4659 return NULL;
4660}
4661
4662
4663
4664
4674bool CIccPcsStepMpe::Begin()
4675{
4676 return m_pMpe->
Begin();
4677}
4678
4679
4689{
4690 m_nRows = nRows;
4691 m_nCols = nCols;
4693}
4694
4695
4704CIccPcsStepSrcMatrix::~CIccPcsStepSrcMatrix()
4705{
4706 if (m_vals)
4707 delete m_vals;
4708}
4709
4710
4721{
4722 int i, j;
4724 for (j=0; j<m_nRows; j++) {
4725 pDst[j] = 0.0f;
4726 for (i=0; i<m_nCols; i++) {
4727 pDst[j] += row[i] * m_vals[i];
4728 }
4729 row += m_nCols;
4730 }
4731}
4732
4733
4742void CIccPcsStepSrcMatrix::dump(std::string &str) const
4743{
4744 str += "\nCIccPcsStepSrcMatrix\n\n";
4745 char buf[80];
4746 for (int i=0; i<m_nCols; i++) {
4748 str += buf;
4749 }
4750 str += "\n";
4751}
4752
4753
4763{
4764 m_nRows = nRows;
4765 m_nCols = nCols;
4766 m_nBytesPerMatrix = nBytesPerMatrix;
4767 m_nChannels = 0;
4769}
4770
4771
4780CIccPcsStepSparseMatrix::~CIccPcsStepSparseMatrix()
4781{
4782 if (m_vals)
4783 delete [] m_vals;
4784}
4785
4786
4797{
4799
4800 mtx.MultiplyVector(pDst, pSrc);
4801}
4802
4803
4812void CIccPcsStepSparseMatrix::dump(std::string &str) const
4813{
4814 str += "\nCIccPcsStepSparseMatrix\n\n";
4815
4816
4817
4818
4819
4820
4821}
4822
4823
4833{
4834 m_nRows = nRows;
4835 m_nCols = nCols;
4836 m_nChannels = nChannels;
4838
4840}
4841
4842
4851CIccPcsStepSrcSparseMatrix::~CIccPcsStepSrcSparseMatrix()
4852{
4853 if (m_vals)
4854 delete [] m_vals;
4855}
4856
4857
4868{
4870
4871 mtx.MultiplyVector(pDst, m_vals);
4872}
4873
4874
4883void CIccPcsStepSrcSparseMatrix::dump(std::string &str) const
4884{
4885 str += "\nCIccPcsStepSrcSparseMatrix\n\n";
4886 char buf[80];
4887 for (int i=0; i<m_nCols; i++) {
4889 str += buf;
4890 }
4891 str += "\n";
4892}
4893
4894
4903CIccXformMonochrome::CIccXformMonochrome()
4904{
4905 m_Curve = NULL;
4906 m_ApplyCurvePtr = NULL;
4907 m_bFreeCurve = false;
4908}
4909
4918CIccXformMonochrome::~CIccXformMonochrome()
4919{
4920 if (m_bFreeCurve && m_Curve) {
4921 delete m_Curve;
4922 }
4923}
4924
4936{
4938
4939 status = CIccXform::Begin();
4941 return status;
4942
4943 m_ApplyCurvePtr = NULL;
4944
4945 if (m_bInput) {
4947
4948 if (!m_Curve) {
4950 }
4951 }
4952 else {
4954 m_bFreeCurve = true;
4955
4956 if (!m_Curve) {
4958 }
4959 }
4960
4961 m_Curve->Begin();
4962 if (!m_Curve->IsIdentity()) {
4963 m_ApplyCurvePtr = m_Curve;
4964 }
4965
4967}
4968
4983{
4985
4986 if (m_bSrcPcsConversion)
4987 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
4988
4989 if (m_bInput) {
4990 Pixel[0] = SrcPixel[0];
4991
4992 if (m_ApplyCurvePtr) {
4993 Pixel[0] = m_ApplyCurvePtr->Apply(Pixel[0]);
4994 }
4995
4999
5001
5003 if (UseLegacyPCS()) {
5004 CIccPCSUtil::XyzToLab2(DstPixel, DstPixel, true);
5005 }
5006 else {
5007 CIccPCSUtil::XyzToLab(DstPixel, DstPixel, true);
5008 }
5009 }
5010
5011 DstPixel[0] *= Pixel[0];
5012 DstPixel[1] *= Pixel[0];
5013 DstPixel[2] *= Pixel[0];
5014 }
5015 else {
5019
5021
5023 if (UseLegacyPCS()) {
5024 CIccPCSUtil::XyzToLab2(Pixel, Pixel, true);
5025 }
5026 else {
5027 CIccPCSUtil::XyzToLab(Pixel, Pixel, true);
5028 }
5029 DstPixel[0] = SrcPixel[0]/Pixel[0];
5030 }
5031 else {
5032 DstPixel[0] = SrcPixel[1]/Pixel[1];
5033 }
5034
5035 if (m_ApplyCurvePtr) {
5036 DstPixel[0] = m_ApplyCurvePtr->Apply(DstPixel[0]);
5037 }
5038 }
5039
5040 if (m_bDstPcsConversion)
5041 CheckDstAbs(DstPixel);
5042}
5043
5059{
5060 CIccTag *pTag = m_pProfile->FindTag(sig);
5061
5064 }
5065
5066 return NULL;
5067}
5068
5084{
5087
5088 if (!(pCurve = GetCurve(sig)))
5089 return NULL;
5090
5092
5094
5095 int i;
5098
5099 for (i=0; i<2048; i++) {
5101
5102 Lut[i] = pCurve->
Find(x);
5103 }
5104
5105 return pInvCurve;
5106}
5107
5122LPIccCurve* CIccXformMonochrome::ExtractInputCurves()
5123{
5124 if (m_bInput) {
5125 if (m_Curve) {
5128 m_ApplyCurvePtr = NULL;
5129 return Curve;
5130 }
5131 }
5132
5133 return NULL;
5134}
5135
5150LPIccCurve* CIccXformMonochrome::ExtractOutputCurves()
5151{
5152 if (!m_bInput) {
5153 if (m_Curve) {
5156 m_ApplyCurvePtr = NULL;
5157 return Curve;
5158 }
5159 }
5160
5161 return NULL;
5162}
5163
5172CIccXformMatrixTRC::CIccXformMatrixTRC() : m_e{}
5173{
5174 m_Curve[0] = m_Curve[1] = m_Curve[2] = NULL;
5175 m_ApplyCurvePtr = NULL;
5176 m_bFreeCurve = false;
5177}
5178
5187CIccXformMatrixTRC::~CIccXformMatrixTRC()
5188{
5189 if (m_bFreeCurve) {
5190 if (m_Curve[0])
5191 delete m_Curve[0];
5192 if (m_Curve[1])
5193 delete m_Curve[1];
5194 if (m_Curve[2])
5195 delete m_Curve[2];
5196 }
5197}
5198
5210{
5213
5214 status = CIccXform::Begin();
5216 return status;
5217
5219 if (!pXYZ) {
5221 }
5222
5223 m_e[0] =
icFtoD((*pXYZ)[0].X);
5224 m_e[3] =
icFtoD((*pXYZ)[0].Y);
5225 m_e[6] =
icFtoD((*pXYZ)[0].Z);
5226
5228 if (!pXYZ) {
5230 }
5231
5232 m_e[1] =
icFtoD((*pXYZ)[0].X);
5233 m_e[4] =
icFtoD((*pXYZ)[0].Y);
5234 m_e[7] =
icFtoD((*pXYZ)[0].Z);
5235
5237 if (!pXYZ) {
5239 }
5240
5241 m_e[2] =
icFtoD((*pXYZ)[0].X);
5242 m_e[5] =
icFtoD((*pXYZ)[0].Y);
5243 m_e[8] =
icFtoD((*pXYZ)[0].Z);
5244
5245 m_ApplyCurvePtr = NULL;
5246
5247 if (m_bInput) {
5251
5252 if (!m_Curve[0] || !m_Curve[1] || !m_Curve[2]) {
5254 }
5255
5256 }
5257 else {
5260 }
5261
5265
5266 m_bFreeCurve = true;
5267
5268 if (!m_Curve[0] || !m_Curve[1] || !m_Curve[2]) {
5270 }
5271
5274 }
5275 }
5276
5277 m_Curve[0]->Begin();
5278 m_Curve[1]->Begin();
5279 m_Curve[2]->Begin();
5280
5281 if (!m_Curve[0]->IsIdentity() || !m_Curve[1]->IsIdentity() || !m_Curve[2]->IsIdentity()) {
5282 m_ApplyCurvePtr = m_Curve;
5283 }
5284
5286}
5287
5288
5290{
5292 return v;
5293}
5294
5296{
5298}
5299
5301{
5302 if (v<=0)
5303 return(pCurve->
Apply(0));
5304 else if (v>=1.0)
5305 return (pCurve->
Apply(1.0));
5306
5307 return pCurve->
Apply(v);
5308}
5309
5324{
5326
5327 if (m_bSrcPcsConversion)
5328 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
5329
5330 Pixel[0] = SrcPixel[0];
5331 Pixel[1] = SrcPixel[1];
5332 Pixel[2] = SrcPixel[2];
5333
5334 if (m_bInput) {
5335
5336 double LinR, LinG, LinB;
5337 if (m_ApplyCurvePtr) {
5338 LinR = m_ApplyCurvePtr[0]->Apply(Pixel[0]);
5339 LinG = m_ApplyCurvePtr[1]->Apply(Pixel[1]);
5340 LinB = m_ApplyCurvePtr[2]->Apply(Pixel[2]);
5341 }
5342 else {
5343 LinR = Pixel[0];
5344 LinG = Pixel[1];
5345 LinB = Pixel[2];
5346 }
5347
5351 }
5352 else {
5356
5357 if (m_ApplyCurvePtr) {
5358 DstPixel[0] =
RGBClip((
icFloatNumber)(m_e[0] * X + m_e[1] * Y + m_e[2] * Z), m_ApplyCurvePtr[0]);
5359 DstPixel[1] =
RGBClip((
icFloatNumber)(m_e[3] * X + m_e[4] * Y + m_e[5] * Z), m_ApplyCurvePtr[1]);
5360 DstPixel[2] =
RGBClip((
icFloatNumber)(m_e[6] * X + m_e[7] * Y + m_e[8] * Z), m_ApplyCurvePtr[2]);
5361 }
5362 else {
5363 DstPixel[0] = (
icFloatNumber)(m_e[0] * X + m_e[1] * Y + m_e[2] * Z);
5364 DstPixel[1] = (
icFloatNumber)(m_e[3] * X + m_e[4] * Y + m_e[5] * Z);
5365 DstPixel[2] = (
icFloatNumber)(m_e[6] * X + m_e[7] * Y + m_e[8] * Z);
5366 }
5367 }
5368
5369 if (m_bDstPcsConversion)
5370 CheckDstAbs(DstPixel);
5371}
5372
5388{
5389 CIccTag *pTag = m_pProfile->FindTag(sig);
5390
5393 }
5394
5395 return NULL;
5396}
5397
5413{
5414 CIccTag *pTag = m_pProfile->FindTag(sig);
5415
5417 return NULL;
5418 }
5419
5421}
5422
5438{
5441
5442 if (!(pCurve = GetCurve(sig)))
5443 return NULL;
5444
5446
5448
5449 int i;
5452
5453 for (i=0; i<2048; i++) {
5455
5456 Lut[i] = pCurve->
Find(x);
5457 }
5458
5459 return pInvCurve;
5460}
5461
5476LPIccCurve* CIccXformMatrixTRC::ExtractInputCurves()
5477{
5478 if (m_bInput) {
5479 if (m_Curve[0]) {
5481 Curve[0] = (
LPIccCurve)(m_Curve[0]->NewCopy());
5482 Curve[1] = (
LPIccCurve)(m_Curve[1]->NewCopy());
5483 Curve[2] = (
LPIccCurve)(m_Curve[2]->NewCopy());
5484 m_ApplyCurvePtr = NULL;
5485 return Curve;
5486 }
5487 }
5488
5489 return NULL;
5490}
5491
5506LPIccCurve* CIccXformMatrixTRC::ExtractOutputCurves()
5507{
5508 if (!m_bInput) {
5509 if (m_Curve[0]) {
5511 Curve[0] = (
LPIccCurve)(m_Curve[0]->NewCopy());
5512 Curve[1] = (
LPIccCurve)(m_Curve[1]->NewCopy());
5513 Curve[2] = (
LPIccCurve)(m_Curve[2]->NewCopy());
5514 m_ApplyCurvePtr = NULL;
5515 return Curve;
5516 }
5517 }
5518
5519 return NULL;
5520}
5521
5533CIccXform3DLut::CIccXform3DLut(
CIccTag *pTag)
5534{
5537 }
5538 else
5539 m_pTag = NULL;
5540
5541 m_ApplyCurvePtrA = m_ApplyCurvePtrB = m_ApplyCurvePtrM = NULL;
5542 m_ApplyMatrixPtr = NULL;
5543}
5544
5553CIccXform3DLut::~CIccXform3DLut()
5554{
5555}
5556
5568{
5571 int i;
5572
5573 status = CIccXform::Begin();
5575 return status;
5576
5577 if (!m_pTag ||
5578 m_pTag->InputChannels()!=3) {
5580 }
5581
5582 m_ApplyCurvePtrA = NULL;
5583 m_ApplyCurvePtrB = NULL;
5584 m_ApplyCurvePtrM = NULL;
5585
5586 if (m_pTag->m_bInputMatrix) {
5587 if (m_pTag->m_CurvesB) {
5588 Curve = m_pTag->m_CurvesB;
5589
5593
5594 if (!Curve[0]->IsIdentity() || !Curve[1]->IsIdentity() || !Curve[2]->IsIdentity()) {
5595 m_ApplyCurvePtrB = Curve;
5596 }
5597 }
5598
5599 if (m_pTag->m_CurvesM) {
5600 Curve = m_pTag->m_CurvesM;
5601
5605
5606 if (!Curve[0]->IsIdentity() || !Curve[1]->IsIdentity() || !Curve[2]->IsIdentity()) {
5607 m_ApplyCurvePtrM = Curve;
5608 }
5609 }
5610
5611 if (m_pTag->m_CLUT) {
5612 m_pTag->m_CLUT->
Begin();
5613 }
5614
5615 if (m_pTag->m_CurvesA) {
5616 Curve = m_pTag->m_CurvesA;
5617
5618 for (i=0; i<m_pTag->m_nOutput; i++) {
5620 }
5621
5622 for (i=0; i<m_pTag->m_nOutput; i++) {
5623 if (!Curve[i]->IsIdentity()) {
5624 m_ApplyCurvePtrA = Curve;
5625 break;
5626 }
5627 }
5628 }
5629
5630 }
5631 else {
5632 if (m_pTag->m_CurvesA) {
5633 Curve = m_pTag->m_CurvesA;
5634
5638
5639 if (!Curve[0]->IsIdentity() || !Curve[1]->IsIdentity() || !Curve[2]->IsIdentity()) {
5640 m_ApplyCurvePtrA = Curve;
5641 }
5642 }
5643
5644 if (m_pTag->m_CLUT) {
5645 m_pTag->m_CLUT->
Begin();
5646 }
5647
5648 if (m_pTag->m_CurvesM) {
5649 Curve = m_pTag->m_CurvesM;
5650
5651 for (i=0; i<m_pTag->m_nOutput; i++) {
5653 }
5654
5655 for (i=0; i<m_pTag->m_nOutput; i++) {
5656 if (!Curve[i]->IsIdentity()) {
5657 m_ApplyCurvePtrM = Curve;
5658 break;
5659 }
5660 }
5661 }
5662
5663 if (m_pTag->m_CurvesB) {
5664 Curve = m_pTag->m_CurvesB;
5665
5666 for (i=0; i<m_pTag->m_nOutput; i++) {
5668 }
5669
5670 for (i=0; i<m_pTag->m_nOutput; i++) {
5671 if (!Curve[i]->IsIdentity()) {
5672 m_ApplyCurvePtrB = Curve;
5673 break;
5674 }
5675 }
5676 }
5677 }
5678
5679 m_ApplyMatrixPtr = NULL;
5680 if (m_pTag->m_Matrix) {
5681 if (m_pTag->m_bInputMatrix) {
5682 if (m_pTag->m_nInput!=3) {
5684 }
5685 }
5686 else {
5687 if (m_pTag->m_nOutput!=3) {
5689 }
5690 }
5691
5692 if (!m_pTag->m_Matrix->IsIdentity()) {
5693 m_ApplyMatrixPtr = m_pTag->m_Matrix;
5694 }
5695 }
5696
5698}
5699
5714{
5716 for (int j = 0; j < m_pTag->m_nOutput && j < 16; ++j)
5717 Pixel[j] = 0.0f;
5718
5719 int i;
5720
5721 if (m_bSrcPcsConversion)
5722 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
5723
5724 Pixel[0] = SrcPixel[0];
5725 Pixel[1] = SrcPixel[1];
5726 Pixel[2] = SrcPixel[2];
5727
5728 if (m_pTag->m_bInputMatrix) {
5729 if (m_ApplyCurvePtrB) {
5730 Pixel[0] = m_ApplyCurvePtrB[0]->Apply(Pixel[0]);
5731 Pixel[1] = m_ApplyCurvePtrB[1]->Apply(Pixel[1]);
5732 Pixel[2] = m_ApplyCurvePtrB[2]->Apply(Pixel[2]);
5733 }
5734
5735 if (m_ApplyMatrixPtr) {
5736 m_ApplyMatrixPtr->Apply(Pixel);
5737 }
5738
5739 if (m_ApplyCurvePtrM) {
5740 Pixel[0] = m_ApplyCurvePtrM[0]->Apply(Pixel[0]);
5741 Pixel[1] = m_ApplyCurvePtrM[1]->Apply(Pixel[1]);
5742 Pixel[2] = m_ApplyCurvePtrM[2]->Apply(Pixel[2]);
5743 }
5744
5745 if (m_pTag->m_CLUT) {
5747 m_pTag->m_CLUT->Interp3d(Pixel, Pixel);
5748 else
5749 m_pTag->m_CLUT->Interp3dTetra(Pixel, Pixel);
5750 }
5751
5752 if (m_ApplyCurvePtrA) {
5753 for (i=0; i<m_pTag->m_nOutput; i++) {
5754 Pixel[i] = m_ApplyCurvePtrA[i]->Apply(Pixel[i]);
5755 }
5756 }
5757
5758 }
5759 else {
5760 if (m_ApplyCurvePtrA) {
5761 Pixel[0] = m_ApplyCurvePtrA[0]->Apply(Pixel[0]);
5762 Pixel[1] = m_ApplyCurvePtrA[1]->Apply(Pixel[1]);
5763 Pixel[2] = m_ApplyCurvePtrA[2]->Apply(Pixel[2]);
5764 }
5765
5766 if (m_pTag->m_CLUT) {
5768 m_pTag->m_CLUT->Interp3d(Pixel, Pixel);
5769 else
5770 m_pTag->m_CLUT->Interp3dTetra(Pixel, Pixel);
5771 }
5772
5773 if (m_ApplyCurvePtrM) {
5774 for (i=0; i<m_pTag->m_nOutput; i++) {
5775 Pixel[i] = m_ApplyCurvePtrM[i]->Apply(Pixel[i]);
5776 }
5777 }
5778
5779 if (m_ApplyMatrixPtr) {
5780 m_ApplyMatrixPtr->Apply(Pixel);
5781 }
5782
5783 if (m_ApplyCurvePtrB) {
5784 for (i=0; i<m_pTag->m_nOutput; i++) {
5785 Pixel[i] = m_ApplyCurvePtrB[i]->Apply(Pixel[i]);
5786 }
5787 }
5788 }
5789
5790 for (i = 0; i < m_pTag->m_nOutput && i < 16; i++) {
5791 DstPixel[i] = Pixel[i];
5792 }
5793
5794 if (m_bDstPcsConversion)
5795 CheckDstAbs(DstPixel);
5796}
5797
5812LPIccCurve* CIccXform3DLut::ExtractInputCurves()
5813{
5814 if (m_bInput) {
5815 if (m_pTag->m_bInputMatrix) {
5816 if (m_pTag->m_CurvesB) {
5818 Curve[0] = (
LPIccCurve)(m_pTag->m_CurvesB[0]->NewCopy());
5819 Curve[1] = (
LPIccCurve)(m_pTag->m_CurvesB[1]->NewCopy());
5820 Curve[2] = (
LPIccCurve)(m_pTag->m_CurvesB[2]->NewCopy());
5821 m_ApplyCurvePtrB = NULL;
5822 return Curve;
5823 }
5824 }
5825 else {
5826 if (m_pTag->m_CurvesA) {
5828 Curve[0] = (
LPIccCurve)(m_pTag->m_CurvesA[0]->NewCopy());
5829 Curve[1] = (
LPIccCurve)(m_pTag->m_CurvesA[1]->NewCopy());
5830 Curve[2] = (
LPIccCurve)(m_pTag->m_CurvesA[2]->NewCopy());
5831 m_ApplyCurvePtrA = NULL;
5832 return Curve;
5833 }
5834 }
5835 }
5836
5837 return NULL;
5838}
5839
5854LPIccCurve* CIccXform3DLut::ExtractOutputCurves()
5855{
5856 if (!m_bInput) {
5857 if (m_pTag->m_bInputMatrix) {
5858 if (m_pTag->m_CurvesA) {
5860 for (int i=0; i<m_pTag->m_nOutput; i++) {
5861 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesA[i]->NewCopy());
5862 }
5863 m_ApplyCurvePtrA = NULL;
5864 return Curve;
5865 }
5866 }
5867 else {
5868 if (m_pTag->m_CurvesB) {
5870 for (int i=0; i<m_pTag->m_nOutput; i++) {
5871 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesB[i]->NewCopy());
5872 }
5873 m_ApplyCurvePtrB = NULL;
5874 return Curve;
5875 }
5876 }
5877 }
5878
5879 return NULL;
5880}
5881
5893CIccXform4DLut::CIccXform4DLut(
CIccTag *pTag)
5894{
5897 }
5898 else
5899 m_pTag = NULL;
5900
5901 m_ApplyCurvePtrA = m_ApplyCurvePtrB = m_ApplyCurvePtrM = NULL;
5902 m_ApplyMatrixPtr = NULL;
5903}
5904
5905
5914CIccXform4DLut::~CIccXform4DLut()
5915{
5916}
5917
5918
5930{
5933 int i;
5934
5935 status = CIccXform::Begin();
5937 return status;
5938 }
5939
5940 if (!m_pTag ||
5941 m_pTag->InputChannels()!=4) {
5943 }
5944
5945 m_ApplyCurvePtrA = m_ApplyCurvePtrB = m_ApplyCurvePtrM = NULL;
5946
5947 if (m_pTag->m_bInputMatrix) {
5948 if (m_pTag->m_CurvesB) {
5949 Curve = m_pTag->m_CurvesB;
5950
5955
5956 if (!Curve[0]->IsIdentity() || !Curve[1]->IsIdentity() ||
5957 !Curve[2]->IsIdentity() || !Curve[3]->IsIdentity())
5958 {
5959 m_ApplyCurvePtrB = Curve;
5960 }
5961 }
5962
5963 if (m_pTag->m_CLUT) {
5964 m_pTag->m_CLUT->
Begin();
5965 }
5966
5967 if (m_pTag->m_CurvesA) {
5968 Curve = m_pTag->m_CurvesA;
5969
5970 for (i=0; i<m_pTag->m_nOutput; i++) {
5972 }
5973
5974 for (i=0; i<m_pTag->m_nOutput; i++) {
5975 if (!Curve[i]->IsIdentity()) {
5976 m_ApplyCurvePtrA = Curve;
5977 break;
5978 }
5979 }
5980 }
5981
5982 }
5983 else {
5984 if (m_pTag->m_CurvesA) {
5985 Curve = m_pTag->m_CurvesA;
5986
5991
5992 if (!Curve[0]->IsIdentity() || !Curve[1]->IsIdentity() ||
5993 !Curve[2]->IsIdentity() || !Curve[3]->IsIdentity())
5994 {
5995 m_ApplyCurvePtrA = Curve;
5996 }
5997 }
5998
5999 if (m_pTag->m_CLUT) {
6000 m_pTag->m_CLUT->
Begin();
6001 }
6002
6003 if (m_pTag->m_CurvesM) {
6004 Curve = m_pTag->m_CurvesM;
6005
6006 for (i=0; i<m_pTag->m_nOutput; i++) {
6008 }
6009
6010 for (i=0; i<m_pTag->m_nOutput; i++) {
6011 if (!Curve[i]->IsIdentity()) {
6012 m_ApplyCurvePtrM = Curve;
6013 break;
6014 }
6015 }
6016 }
6017
6018 if (m_pTag->m_CurvesB) {
6019 Curve = m_pTag->m_CurvesB;
6020
6021 for (i=0; i<m_pTag->m_nOutput; i++) {
6023 }
6024
6025 for (i=0; i<m_pTag->m_nOutput; i++) {
6026 if (!Curve[i]->IsIdentity()) {
6027 m_ApplyCurvePtrB = Curve;
6028 break;
6029 }
6030 }
6031 }
6032 }
6033
6034 m_ApplyMatrixPtr = NULL;
6035 if (m_pTag->m_Matrix) {
6036 if (m_pTag->m_bInputMatrix) {
6038 }
6039 else {
6040 if (m_pTag->m_nOutput!=3) {
6042 }
6043 }
6044
6045 if (!m_pTag->m_Matrix->IsIdentity()) {
6046 m_ApplyMatrixPtr = m_pTag->m_Matrix;
6047 }
6048 }
6049
6051}
6052
6053
6068{
6070 int i;
6071
6072 if (m_bSrcPcsConversion)
6073 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
6074
6075 Pixel[0] = SrcPixel[0];
6076 Pixel[1] = SrcPixel[1];
6077 Pixel[2] = SrcPixel[2];
6078 Pixel[3] = SrcPixel[3];
6079
6080 if (m_pTag->m_bInputMatrix) {
6081 if (m_ApplyCurvePtrB) {
6082 Pixel[0] = m_ApplyCurvePtrB[0]->Apply(Pixel[0]);
6083 Pixel[1] = m_ApplyCurvePtrB[1]->Apply(Pixel[1]);
6084 Pixel[2] = m_ApplyCurvePtrB[2]->Apply(Pixel[2]);
6085 Pixel[3] = m_ApplyCurvePtrB[3]->Apply(Pixel[3]);
6086 }
6087
6088 if (m_pTag->m_CLUT) {
6089 m_pTag->m_CLUT->Interp4d(Pixel, Pixel);
6090 }
6091
6092 if (m_ApplyCurvePtrA) {
6093 for (i=0; i<m_pTag->m_nOutput; i++) {
6094 Pixel[i] = m_ApplyCurvePtrA[i]->Apply(Pixel[i]);
6095 }
6096 }
6097
6098 }
6099 else {
6100 if (m_ApplyCurvePtrA) {
6101 Pixel[0] = m_ApplyCurvePtrA[0]->Apply(Pixel[0]);
6102 Pixel[1] = m_ApplyCurvePtrA[1]->Apply(Pixel[1]);
6103 Pixel[2] = m_ApplyCurvePtrA[2]->Apply(Pixel[2]);
6104 Pixel[3] = m_ApplyCurvePtrA[3]->Apply(Pixel[3]);
6105 }
6106
6107 if (m_pTag->m_CLUT) {
6108 m_pTag->m_CLUT->Interp4d(Pixel, Pixel);
6109 }
6110
6111 if (m_ApplyCurvePtrM) {
6112 for (i=0; i<m_pTag->m_nOutput; i++) {
6113 Pixel[i] = m_ApplyCurvePtrM[i]->Apply(Pixel[i]);
6114 }
6115 }
6116
6117 if (m_ApplyMatrixPtr) {
6118 m_ApplyMatrixPtr->Apply(Pixel);
6119 }
6120
6121 if (m_ApplyCurvePtrB) {
6122 for (i=0; i<m_pTag->m_nOutput; i++) {
6123 Pixel[i] = m_ApplyCurvePtrB[i]->Apply(Pixel[i]);
6124 }
6125 }
6126 }
6127
6128 for (i=0; i<m_pTag->m_nOutput; i++) {
6129 DstPixel[i] = Pixel[i];
6130 }
6131
6132 if (m_bDstPcsConversion)
6133 (DstPixel);
6134}
6135
6150LPIccCurve* CIccXform4DLut::ExtractInputCurves()
6151{
6152 if (m_bInput) {
6153 if (m_pTag->m_bInputMatrix) {
6154 if (m_pTag->m_CurvesB) {
6156 Curve[0] = (
LPIccCurve)(m_pTag->m_CurvesB[0]->NewCopy());
6157 Curve[1] = (
LPIccCurve)(m_pTag->m_CurvesB[1]->NewCopy());
6158 Curve[2] = (
LPIccCurve)(m_pTag->m_CurvesB[2]->NewCopy());
6159 Curve[3] = (
LPIccCurve)(m_pTag->m_CurvesB[3]->NewCopy());
6160 m_ApplyCurvePtrB = NULL;
6161 return Curve;
6162 }
6163 }
6164 else {
6165 if (m_pTag->m_CurvesA) {
6167 Curve[0] = (
LPIccCurve)(m_pTag->m_CurvesA[0]->NewCopy());
6168 Curve[1] = (
LPIccCurve)(m_pTag->m_CurvesA[1]->NewCopy());
6169 Curve[2] = (
LPIccCurve)(m_pTag->m_CurvesA[2]->NewCopy());
6170 Curve[3] = (
LPIccCurve)(m_pTag->m_CurvesA[3]->NewCopy());
6171 m_ApplyCurvePtrA = NULL;
6172 return Curve;
6173 }
6174 }
6175 }
6176
6177 return NULL;
6178}
6179
6194LPIccCurve* CIccXform4DLut::ExtractOutputCurves()
6195{
6196 if (!m_bInput) {
6197 if (m_pTag->m_bInputMatrix) {
6198 if (m_pTag->m_CurvesA) {
6200 for (int i=0; i<m_pTag->m_nOutput; i++) {
6201 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesA[i]->NewCopy());
6202 }
6203 m_ApplyCurvePtrA = NULL;
6204 return Curve;
6205 }
6206 }
6207 else {
6208 if (m_pTag->m_CurvesB) {
6210 for (int i=0; i<m_pTag->m_nOutput; i++) {
6211 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesB[i]->NewCopy());
6212 }
6213 m_ApplyCurvePtrB = NULL;
6214 return Curve;
6215 }
6216 }
6217 }
6218
6219 return NULL;
6220}
6221
6222
6234CIccXformNDLut::CIccXformNDLut(
CIccTag *pTag)
6235{
6238 }
6239 else
6240 m_pTag = NULL;
6241
6242 m_ApplyCurvePtrA = m_ApplyCurvePtrB = m_ApplyCurvePtrM = NULL;
6243 m_ApplyMatrixPtr = NULL;
6244 m_nNumInput = 0;
6245}
6246
6247
6256CIccXformNDLut::~CIccXformNDLut()
6257{
6258}
6259
6260
6272{
6275 int i;
6276
6277 status = CIccXform::Begin();
6279 return status;
6280 }
6281
6282 if (!m_pTag || (m_pTag->InputChannels()>2 && m_pTag->InputChannels()<5)) {
6284 }
6285
6286 m_nNumInput = m_pTag->m_nInput;
6287
6288 m_ApplyCurvePtrA = m_ApplyCurvePtrB = m_ApplyCurvePtrM = NULL;
6289
6290 if (m_pTag->m_bInputMatrix) {
6291 if (m_pTag->m_CurvesB) {
6292 Curve = m_pTag->m_CurvesB;
6293
6294 for (i=0; i<m_nNumInput; i++)
6295 Curve[i]->Begin();
6296
6297 for (i=0; i<m_nNumInput; i++) {
6298 if (!Curve[i]->IsIdentity()) {
6299 m_ApplyCurvePtrB = Curve;
6300 break;
6301 }
6302 }
6303 }
6304
6305 if (m_pTag->m_CLUT) {
6306 m_pTag->m_CLUT->
Begin();
6307 }
6308
6309 if (m_pTag->m_CurvesA) {
6310 Curve = m_pTag->m_CurvesA;
6311
6312 for (i=0; i<m_pTag->m_nOutput; i++) {
6314 }
6315
6316 for (i=0; i<m_pTag->m_nOutput; i++) {
6317 if (!Curve[i]->IsIdentity()) {
6318 m_ApplyCurvePtrA = Curve;
6319 break;
6320 }
6321 }
6322 }
6323
6324 }
6325 else {
6326 if (m_pTag->m_CurvesA) {
6327 Curve = m_pTag->m_CurvesA;
6328
6329 for (i=0; i<m_nNumInput; i++)
6330 Curve[i]->Begin();
6331
6332 for (i=0; i<m_nNumInput; i++) {
6333 if (!Curve[i]->IsIdentity()) {
6334 m_ApplyCurvePtrA = Curve;
6335 break;
6336 }
6337 }
6338 }
6339
6340 if (m_pTag->m_CLUT) {
6341 m_pTag->m_CLUT->
Begin();
6342 }
6343
6344 if (m_pTag->m_CurvesM) {
6345 Curve = m_pTag->m_CurvesM;
6346
6347 for (i=0; i<m_pTag->m_nOutput; i++) {
6349 }
6350
6351 for (i=0; i<m_pTag->m_nOutput; i++) {
6352 if (!Curve[i]->IsIdentity()) {
6353 m_ApplyCurvePtrM = Curve;
6354 break;
6355 }
6356 }
6357 }
6358
6359 if (m_pTag->m_CurvesB) {
6360 Curve = m_pTag->m_CurvesB;
6361
6362 for (i=0; i<m_pTag->m_nOutput; i++) {
6364 }
6365
6366 for (i=0; i<m_pTag->m_nOutput; i++) {
6367 if (!Curve[i]->IsIdentity()) {
6368 m_ApplyCurvePtrB = Curve;
6369 break;
6370 }
6371 }
6372 }
6373 }
6374
6375 m_ApplyMatrixPtr = NULL;
6376 if (m_pTag->m_Matrix) {
6377 if (m_pTag->m_bInputMatrix) {
6379 }
6380 else {
6381 if (m_pTag->m_nOutput!=3) {
6383 }
6384 }
6385
6386 if (!m_pTag->m_Matrix->IsIdentity()) {
6387 m_ApplyMatrixPtr = m_pTag->m_Matrix;
6388 }
6389 }
6390
6392}
6393
6394
6406CIccApplyXform* CIccXformNDLut::GetNewApply(
icStatusCMM& status)
6407{
6408 if (!m_pTag)
6409 return NULL;
6410
6411 CIccCLUT* pCLUT = m_pTag->GetCLUT();
6413
6414 if (pCLUT && m_nNumInput > 6) {
6416 if (!pApply) {
6418 return NULL;
6419 }
6420 }
6421
6422 CIccApplyNDLutXform* rv = new CIccApplyNDLutXform(this, pApply);
6423
6424 if (!rv) {
6425 if (pApply)
6426 delete pApply;
6428 return NULL;
6429 }
6430
6432 return rv;
6433}
6434
6449{
6451 int i;
6452
6453 if (m_bSrcPcsConversion)
6454 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
6455
6456 for (i=0; i<m_nNumInput; i++)
6457 Pixel[i] = SrcPixel[i];
6458
6459 if (m_pTag->m_bInputMatrix) {
6460 if (m_ApplyCurvePtrB) {
6461 for (i=0; i<m_nNumInput; i++)
6462 Pixel[i] = m_ApplyCurvePtrB[i]->Apply(Pixel[i]);
6463 }
6464
6465 if (m_pTag->m_CLUT) {
6466 switch(m_nNumInput) {
6467 case 5:
6468 m_pTag->m_CLUT->Interp5d(Pixel, Pixel);
6469 break;
6470 case 6:
6471 m_pTag->m_CLUT->Interp6d(Pixel, Pixel);
6472 break;
6473 default:
6474 {
6475 CIccApplyNDLutXform* pNDApply = (CIccApplyNDLutXform*)pApply;
6476 m_pTag->m_CLUT->InterpND(Pixel, Pixel, pNDApply->m_pApply);
6477 break;
6478 }
6479 }
6480 }
6481
6482 if (m_ApplyCurvePtrA) {
6483 for (i=0; i<m_pTag->m_nOutput; i++) {
6484 Pixel[i] = m_ApplyCurvePtrA[i]->Apply(Pixel[i]);
6485 }
6486 }
6487
6488 }
6489 else {
6490 if (m_ApplyCurvePtrA) {
6491 for (i=0; i<m_nNumInput; i++)
6492 Pixel[i] = m_ApplyCurvePtrA[i]->Apply(Pixel[i]);
6493 }
6494
6495 if (m_pTag->m_CLUT) {
6496 switch(m_nNumInput) {
6497 case 5:
6498 m_pTag->m_CLUT->Interp5d(Pixel, Pixel);
6499 break;
6500 case 6:
6501 m_pTag->m_CLUT->Interp6d(Pixel, Pixel);
6502 break;
6503 default:
6504 {
6505 CIccApplyNDLutXform* pNDApply = (CIccApplyNDLutXform*)pApply;
6506 m_pTag->m_CLUT->InterpND(Pixel, Pixel, pNDApply->m_pApply);
6507 break;
6508 }
6509 break;
6510 }
6511 }
6512
6513 if (m_ApplyCurvePtrM) {
6514 for (i=0; i<m_pTag->m_nOutput; i++) {
6515 Pixel[i] = m_ApplyCurvePtrM[i]->Apply(Pixel[i]);
6516 }
6517 }
6518
6519 if (m_ApplyMatrixPtr) {
6520 m_ApplyMatrixPtr->Apply(Pixel);
6521 }
6522
6523 if (m_ApplyCurvePtrB) {
6524 for (i=0; i<m_pTag->m_nOutput; i++) {
6525 Pixel[i] = m_ApplyCurvePtrB[i]->Apply(Pixel[i]);
6526 }
6527 }
6528 }
6529
6530 for (i=0; i<m_pTag->m_nOutput; i++) {
6531 DstPixel[i] = Pixel[i];
6532 }
6533
6534 if (m_bDstPcsConversion)
6535 CheckDstAbs(DstPixel);
6536}
6537
6552LPIccCurve* CIccXformNDLut::ExtractInputCurves()
6553{
6554 if (m_bInput) {
6555 if (m_pTag->m_bInputMatrix) {
6556 if (m_pTag->m_CurvesB) {
6558 for (int i=0; i<m_pTag->m_nInput; i++) {
6559 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesB[i]->NewCopy());
6560 }
6561 m_ApplyCurvePtrB = NULL;
6562 return Curve;
6563 }
6564 }
6565 else {
6566 if (m_pTag->m_CurvesA) {
6568 for (int i=0; i<m_pTag->m_nInput; i++) {
6569 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesA[i]->NewCopy());
6570 }
6571 m_ApplyCurvePtrA = NULL;
6572 return Curve;
6573 }
6574 }
6575 }
6576
6577 return NULL;
6578}
6579
6594LPIccCurve* CIccXformNDLut::ExtractOutputCurves()
6595{
6596 if (!m_bInput) {
6597 if (m_pTag->m_bInputMatrix) {
6598 if (m_pTag->m_CurvesA) {
6600 for (int i=0; i<m_pTag->m_nOutput; i++) {
6601 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesA[i]->NewCopy());
6602 }
6603 m_ApplyCurvePtrA = NULL;
6604 return Curve;
6605 }
6606 }
6607 else {
6608 if (m_pTag->m_CurvesB) {
6610 for (int i=0; i<m_pTag->m_nOutput; i++) {
6611 Curve[i] = (
LPIccCurve)(m_pTag->m_CurvesB[i]->NewCopy());
6612 }
6613 m_ApplyCurvePtrB = NULL;
6614 return Curve;
6615 }
6616 }
6617 }
6618
6619 return NULL;
6620}
6621
6639{
6640 m_nApplyInterface = icApplyPixel2Pixel;
6641 m_pTag = NULL;
6642 if (pTag) {
6645 m_pArray = NULL;
6646
6647 m_pTag->SetColorSpaces(csPcs, csDevice);
6648 }
6652
6653 if (pNamed) {
6654 m_pTag = NULL;
6655 m_pArray = pNamed;
6656 pNamed->
SetColorSpaces(csPcs, csDevice, csSpectralPcs, pSpectralRange, pBiSpectralRange);
6657 }
6658 }
6659 }
6660
6663 m_pArray = NULL;
6664}
6665
6666
6675CIccXformNamedColor::~CIccXformNamedColor()
6676{
6677}
6678
6690{
6692
6693 status = CIccXform::Begin();
6695 return status;
6696
6697 if (m_pTag==NULL && m_pArray==NULL) {
6699 }
6700
6704 }
6705
6708 m_nApplyInterface = icApplyPixel2Pixel;
6709 }
6710 else {
6711 m_nApplyInterface = icApplyPixel2Named;
6712 }
6713 }
6714 else {
6716 m_nApplyInterface = icApplyNamed2Pixel;
6717 }
6718 else {
6720 }
6721 }
6722
6723 if (m_pTag && !m_pTag->InitFindCachedPCSColor())
6725 else if (m_pArray && !m_pArray->Begin())
6727
6729}
6730
6731
6732
6747{
6748
6749 if (m_pArray) {
6752
6753 std::string NamedColor;
6754
6755 if (IsSrcPCS()) {
6758 if (pColor)
6759 NamedColor = pColor->
getName();
6760 else
6762 }
6763 else {
6764 if (m_bSrcPcsConversion)
6765 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
6766
6769
6772 else {
6775 }
6776
6778 if (pColor)
6779 NamedColor = pColor->
getName();
6780 else
6782 }
6783 }
6784 else {
6786 if (pColor)
6787 NamedColor = pColor->
getName();
6788 else
6790 }
6791
6792 sprintf(DstColorName, "%s", NamedColor.c_str());
6793 }
6794 else if (m_pTag) {
6796
6798 std::string NamedColor;
6800
6801 if (IsSrcPCS()) {
6802 if (m_bSrcPcsConversion)
6803 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
6804
6805 for(i=0; i<3; i++)
6806 PCSPix[i] = SrcPixel[i];
6807
6810 }
6811 else {
6812 for(i=0; i<m_pTag->GetDeviceCoords(); i++)
6813 DevicePix[i] = SrcPixel[i];
6814
6817 }
6818
6819 sprintf(DstColorName, "%s", NamedColor.c_str());
6820 }
6821 else
6823
6825}
6826
6827
6842{
6843
6844 if (m_pArray) {
6846
6848
6851
6852 pColor = pArray->
FindColor(SrcColorName);
6853 if (!pColor)
6855
6856 if (IsDestPCS()) {
6860 }
6861 else {
6862 if (!pArray->
GetPcsTint(DstPixel, pColor, tint))
6864
6867 }
6868 else {
6870 }
6871 if (m_bDstPcsConversion)
6872 CheckDstAbs(DstPixel);
6873 }
6874 }
6875 else {
6878 }
6879 }
6880 else if (m_pTag) {
6882
6884
6887
6888 if (IsDestPCS()) {
6889
6891 if (j<0)
6893
6896 }
6897 else {
6899 }
6900 if (m_bDstPcsConversion)
6901 CheckDstAbs(DstPixel);
6902 }
6903 else {
6905 if (j<0)
6908 }
6909 }
6910
6912}
6913
6926{
6927 if (m_pArray) {
6928
6929 }
6930 else if (m_pTag) {
6932
6933 if (nSrcSpace!=pTag->
GetPCS())
6937 }
6938
6939 m_nSrcSpace = nSrcSpace;
6940
6942}
6943
6956{
6957 if (m_nSrcSpace == nDestSpace)
6959
6960 if (m_pArray) {
6961
6962 }
6963 else if (m_pTag) {
6965
6966 if (nDestSpace!=pTag->
GetPCS())
6970 }
6971
6972 m_nDestSpace = nDestSpace;
6973
6975}
6976
6985bool CIccXformNamedColor::IsSrcPCS() const
6986{
6987 if (m_pTag) {
6988 return m_nSrcSpace == m_pTag->
GetPCS();
6989 }
6990 else if (m_pArray) {
6992 }
6993 else
6994 return false;
6995}
6996
6997
7006bool CIccXformNamedColor::IsDestPCS() const
7007{
7008 if (m_pTag) {
7009 return m_nDestSpace == m_pTag->GetPCS();
7010 }
7011 else if (m_pArray) {
7013 }
7014 else
7015 return false;
7016}
7017
7018
7027CIccXformMpe::CIccXformMpe(
CIccTag *pTag)
7028{
7031 else
7032 m_pTag = NULL;
7033
7034 m_bUsingAcs = false;
7035 m_pAppliedPCC = NULL;
7036 m_bDeleteAppliedPCC = false;
7037}
7038
7047CIccXformMpe::~CIccXformMpe()
7048{
7049 if (m_pAppliedPCC && m_bDeleteAppliedPCC)
7050 delete m_pAppliedPCC;
7051}
7052
7077 CIccCreateXformHintManager *pHintManager)
7078{
7079 CIccXform *rv = NULL;
7081 bool bUseSpectralPCS = false;
7082 bool bAbsToRel = false;
7084 bool bUseColorimeticTags = true;
7085 bool bUseDToB = true;
7086
7089 bUseColorimeticTags = false;
7090 }
7093 bUseDToB = false;
7094 }
7095
7098
7099 switch (nUseLutType) {
7101 if (bInput) {
7103 if (bUseDToB) {
7105
7108 if (pTag)
7110 }
7113 if (pTag) {
7115 bAbsToRel = true;
7116 }
7117 }
7118
7119 if (!pTag) {
7121 }
7122 }
7123
7124
7126 pTag = NULL;
7127
7128 if (pTag && pProfile->m_Header.spectralPCS) {
7129 bUseSpectralPCS = true;
7130 }
7131
7132 if (bUseColorimeticTags) {
7133 if (!pTag) {
7137 }
7138
7139 if (!pTag) {
7141 }
7142 }
7143
7144 if (!pTag) {
7146 rv = new CIccXformMatrixTRC();
7147 }
7148 else
7149 return NULL;
7150 }
7152 rv = new CIccXformMpe(pTag);
7153 }
7154 else {
7155 switch(pProfile->m_Header.colorSpace) {
7166 rv = new CIccXform3DLut(pTag);
7167 break;
7168
7171 rv = new CIccXform4DLut(pTag);
7172 break;
7173
7174 default:
7175 rv = new CIccXformNDLut(pTag);
7176 break;
7177 }
7178 }
7179 }
7180 else {
7182
7183 if (bUseDToB) {
7185
7188 if (pTag)
7190 }
7193 if (pTag) {
7195 bAbsToRel = true;
7196 }
7197 }
7198
7199 if (!pTag) {
7201 }
7202 }
7203
7204
7206 pTag = NULL;
7207
7208 if (bUseColorimeticTags) {
7209 if (!pTag) {
7213 }
7214
7215 if (!pTag) {
7217 }
7218 }
7219
7220 if (!pTag) {
7222 rv = new CIccXformMatrixTRC();
7223 }
7224 else
7225 return NULL;
7226 }
7227
7229 rv = new CIccXformMpe(pTag);
7230 }
7231 else {
7232 switch(pProfile->m_Header.pcs) {
7235 rv = new CIccXform3DLut(pTag);
7236
7237 default:
7238 break;
7239 }
7240 }
7241 }
7242 break;
7243
7245 {
7247 if (!pTag)
7248 return NULL;
7249
7250 rv = new CIccXformNamedColor(pTag, pProfile->m_Header.pcs, pProfile->m_Header.colorSpace,
7251 pProfile->m_Header.spectralPCS,
7252 &pProfile->m_Header.spectralRange,
7253 &pProfile->m_Header.biSpectralRange);
7254 }
7255 break;
7256
7258 {
7259 bInput = false;
7261 if (!pTag) {
7263 }
7264 if (!pTag) {
7265 return NULL;
7266 }
7267 else {
7268 switch(pProfile->m_Header.pcs) {
7271 rv = new CIccXform3DLut(pTag);
7272
7273 default:
7274 break;
7275 }
7276 }
7277 }
7278 break;
7279
7281 {
7282 bInput = false;
7284 if (!pTag) {
7285 return NULL;
7286 }
7287 else {
7288 switch(pProfile->m_Header.pcs) {
7291 rv = new CIccXform3DLut(pTag);
7292
7293 default:
7294 break;
7295 }
7296 }
7297 }
7298 break;
7299 }
7300
7301 if (rv) {
7302 rv->SetParams(pProfile, bInput, nIntent, nTagIntent, bUseSpectralPCS, nInterp, pHintManager, bAbsToRel);
7303 }
7304
7305 return rv;
7306}
7307
7317bool CIccXformMpe::IsLateBinding() const
7318{
7319 if (m_pTag)
7320 return m_pTag->IsLateBinding();
7321
7322 return false;
7323}
7324
7334bool CIccXformMpe::IsLateBindingReflectance() const
7335{
7336 if (m_pTag)
7337 return m_pTag->IsLateBindingReflectance();
7338
7339 return false;
7340}
7341
7351{
7352 if (m_pAppliedPCC)
7353 return m_pAppliedPCC;
7354
7355 return m_pConnectionConditions;
7356}
7357
7369{
7370 if (!pPCC) {
7371 if (m_pAppliedPCC && m_bDeleteAppliedPCC) {
7372 delete m_pAppliedPCC;
7373 }
7374 m_pAppliedPCC = NULL;
7375 m_bDeleteAppliedPCC = false;
7376 return;
7377 }
7378
7379 if (m_pTag) {
7380 bool bReflectance = m_pTag->IsLateBindingReflectance();
7381
7383 if (!bReflectance) {
7386
7387 if (pViewPCC && pViewProfile &&
7391 m_pAppliedPCC = pPCC;
7392 m_bDeleteAppliedPCC = false;
7393 }
7394 else {
7396 m_bDeleteAppliedPCC = true;
7397 }
7398 }
7399 else {
7401 m_bDeleteAppliedPCC = true;
7402 }
7403 }
7404 else {
7405 m_pAppliedPCC = NULL;
7406 }
7407 }
7408 else {
7409 m_pAppliedPCC = pPCC;
7410 m_bDeleteAppliedPCC = false;
7411 }
7412}
7413
7414
7427{
7429 status = CIccXform::Begin();
7430
7432 return status;
7433
7434 if (!m_pTag) {
7436 }
7437
7438 if (!m_pTag->Begin(
icElemInterpLinear, GetProfileCC(), GetConnectionConditions(), GetCmmEnvVarLookup())) {
7440 }
7441
7443}
7444
7445
7455CIccApplyXform *CIccXformMpe::GetNewApply(
icStatusCMM &status)
7456{
7457 if (!m_pTag)
7458 return NULL;
7459
7460 CIccApplyXformMpe *rv= new CIccApplyXformMpe(this);
7461
7462 if (!rv) {
7464 return NULL;
7465 }
7466
7467 rv->m_pApply = m_pTag->GetNewApply();
7468 if (!rv->m_pApply) {
7470 delete rv;
7471 return NULL;
7472 }
7473
7475 return rv;
7476}
7477
7478
7493{
7495
7497 if (!m_bInput || m_bPcsAdjustXform) {
7499 if (m_bSrcPcsConversion)
7500 SrcPixel = CheckSrcAbs(pApply, SrcPixel);
7501 }
7502
7503
7504
7505 switch (GetSrcSpace()) {
7509 SrcPixel = &temp[0];
7510 break;
7511
7515 SrcPixel = &temp[0];
7516 break;
7517
7518 default:
7519 break;
7520 }
7521 }
7522
7523
7524 CIccApplyXformMpe *pApplyMpe = (CIccApplyXformMpe *)pApply;
7525
7526 pTag->
Apply(pApplyMpe->m_pApply, DstPixel, SrcPixel);
7527
7528 if (m_bInput) {
7529
7530
7531 switch(GetDstSpace()) {
7534 break;
7535
7538 break;
7539
7540 default:
7541 break;
7542 }
7543
7545 if (m_bDstPcsConversion)
7546 CheckDstAbs(DstPixel);
7547 }
7548 }
7549}
7550
7559CIccApplyXformMpe::CIccApplyXformMpe(CIccXformMpe *pXform) : CIccApplyXform(pXform)
7560{
7561 m_pApply = NULL;
7562}
7563
7572CIccApplyXformMpe::~CIccApplyXformMpe()
7573{
7574}
7575
7576
7588CIccApplyCmm::CIccApplyCmm(CIccCmm *pCmm)
7589{
7590 m_pCmm = pCmm;
7591
7592
7593 m_Xforms = new CIccApplyXformList;
7594 m_Xforms->clear();
7595
7596 m_Pixel = NULL;
7597 m_Pixel2 = NULL;
7598}
7599
7608CIccApplyCmm::~CIccApplyCmm()
7609{
7610 if (m_Xforms) {
7611 CIccApplyXformList::iterator i;
7612
7613 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
7614 if (i->ptr)
7615 delete i->ptr;
7616 }
7617
7618 delete m_Xforms;
7619 }
7620
7621
7622
7623
7624 if (m_Pixel)
7625 free(m_Pixel);
7626 if (m_Pixel2)
7627 free(m_Pixel2);
7628}
7629
7630bool CIccApplyCmm::InitPixel()
7631{
7632 if (m_Pixel && m_Pixel2)
7633 return true;
7634
7636 CIccApplyXformList::iterator i;
7637
7638 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
7639 if (i->ptr->GetXform()) {
7640 icUInt16Number nXformSamples = i->ptr->GetXform()->GetNumDstSamples();
7641 if (nXformSamples>nSamples)
7642 nSamples=nXformSamples;
7643 }
7644 }
7647
7648 if (!m_Pixel || !m_Pixel2)
7649 return false;
7650
7651 return true;
7652}
7653
7654
7655
7656#ifdef DEBUG_CMM_APPLY
7658{
7659 printf("Xfm%d:", nCount);
7661 if (i)
7662 printf(",");
7663 printf(" %.3f", pPixel[i]);
7664 }
7665 printf("\n");
7666
7667}
7668#endif
7669
7683{
7686 CIccApplyXformList::iterator i;
7687 const CIccXform *pLastXform;
7688 int j, n = (int)m_Xforms->size();
7689 bool bNoClip;
7690
7691 if (!n)
7693
7694 if (!m_Pixel && !InitPixel())
7696
7697 pSrc = SrcPixel;
7698 pDst = m_Pixel;
7699
7700#ifdef DEBUG_CMM_APPLY
7701 int nCount = 0;
7702 printf("Start ApplyCmm\n");
7704#endif
7705
7706 if (n > 1) {
7707 for (j = 0, i = m_Xforms->begin(); j < n - 1 && i != m_Xforms->end(); i++, j++) {
7708 i->ptr->Apply(pDst, pSrc);
7709
7710#ifdef DEBUG_CMM_APPLY
7711 DumpCmmApplyPixel(nCount++, pDst, i->ptr->GetXform()->GetNumDstSamples());
7712#endif
7713
7715 pSrc = pDst;
7716 pDst = (pTmp == SrcPixel) ? m_Pixel2 : pTmp;
7717 }
7718
7719 pLastXform = i->ptr->GetXform();
7720 i->ptr->Apply(DstPixel, pSrc);
7721 bNoClip = pLastXform->NoClipPCS();
7722 }
7723 else {
7724 i = m_Xforms->begin();
7725
7726 pLastXform = i->ptr->GetXform();
7727 i->ptr->Apply(DstPixel, SrcPixel);
7728
7729#ifdef DEBUG_CMM_APPLY
7730 DumpCmmApplyPixel(nCount++, DstPixel, pLastXform->GetNumDstSamples());
7731#endif
7732
7733 bNoClip = pLastXform->NoClipPCS();
7734 }
7735
7736 CIccPCSUtil::CheckLast(DstPixel, m_pCmm->m_nDestSpace, bNoClip);
7737
7738#ifdef DEBUG_CMM_APPLY
7740 printf("End ApplyCmm\n\n");
7741#endif
7742
7744}
7745
7758
7760{
7761 switch (destSpace) {
7763 CIccPCSUtil::XyzToLab(Dst, Dst, bNoClip);
7764 break;
7765
7767 CIccPCSUtil::XyzToLab2(Dst, Dst, bNoClip);
7768 break;
7769
7771
7772
7773 break;
7774
7775 default:
7776
7777 break;
7778 }
7779}
7780
7794{
7797 CIccApplyXformList::iterator i;
7798 int j, n = (int)m_Xforms->size();
7800
7801 if (!n)
7803
7804 if (!m_Pixel && !InitPixel()) {
7806 }
7807
7808 for (k=0; k<nPixels; k++) {
7809 pSrc = SrcPixel;
7810 pDst = m_Pixel;
7811
7812 if (n>1) {
7813 for (j=0, i=m_Xforms->begin(); j<n-1 && i!=m_Xforms->end(); i++, j++) {
7814
7815 i->ptr->Apply(pDst, pSrc);
7817 pSrc = pDst;
7818 if (pTmp==SrcPixel)
7819 pDst = m_Pixel2;
7820 else
7821 pDst = pTmp;
7822 }
7823
7824 i->ptr->Apply(DstPixel, pSrc);
7825 }
7826 else if (n==1) {
7827 i = m_Xforms->begin();
7828 i->ptr->Apply(DstPixel, SrcPixel);
7829 }
7830
7831 DstPixel += m_pCmm->GetDestSamples();
7832 SrcPixel += m_pCmm->GetSourceSamples();
7833 }
7834
7836}
7837
7838void CIccApplyCmm::AppendApplyXform(CIccApplyXform *pApplyXform)
7839{
7840 CIccApplyXformPtr ptr;
7841 ptr.ptr = pApplyXform;
7842
7843 m_Xforms->push_back(ptr);
7844}
7845
7861 bool bFirstInput )
7862{
7863 m_bValid = false;
7864
7865 m_bLastInput = !bFirstInput;
7866 m_nSrcSpace = nSrcSpace;
7867 m_nDestSpace = nDestSpace;
7868
7869 m_nLastSpace = nSrcSpace;
7871
7872 m_Xforms = new CIccXformList;
7873 m_Xforms->clear();
7874
7875 m_pApply = NULL;
7876}
7877
7886CIccCmm::~CIccCmm()
7887{
7888 if (m_Xforms) {
7889 CIccXformList::iterator i;
7890
7891 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
7892 if (i->ptr)
7893 delete i->ptr;
7894 }
7895
7896 delete m_Xforms;
7897 }
7898
7899 if (m_pApply)
7900 delete m_pApply;
7901}
7902
7904{
7905 switch (stat) {
7907 return "Bad CMM";
7909 return "OK";
7911 return "Cannot open profile";
7913 return "Invalid space link";
7915 return "Invalid profile";
7917 return "Invalid profile transform";
7919 return "Invalid Look-Up Table";
7921 return "Missing tag in profile";
7923 return "Color not found";
7925 return "Incorrect Apply object";
7927 return "Invalid color encoding used";
7929 return "Memory allocation error";
7931 return "Invalid Look-Up Table type";
7933 return "Identity transform used";
7935 return "Unsupported PCS Link used";
7937 return "Invalid profile connection";
7939 return "Invalid tint transform";
7941 return "Too many samples used";
7943 return "Invalid MCS link connection";
7944 default:
7945 return "Unknown CMM Status value";
7946
7947 }
7948}
7949
7973 bool bUseD2BxB2DxTags ,
7974 CIccCreateXformHintManager *pHintManager ,
7975 bool bUseSubProfile )
7976{
7978
7979 if (!pProfile)
7981
7982 icStatusCMM rv = AddXform(pProfile, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
7983
7985 delete pProfile;
7986
7987 return rv;
7988}
7989
7990
8018 bool bUseD2BxB2DxTags ,
8019 CIccCreateXformHintManager *pHintManager ,
8020 bool bUseSubProfile )
8021{
8023
8024 if (!pFile || !pFile->
Attach(pProfileMem, nProfileLen, bUseSubProfile))
8026
8028
8029 if (!pProfile)
8031
8032 if (!pProfile->Attach(pFile)) {
8033 delete pFile;
8034 delete pProfile;
8036 }
8037
8038 icStatusCMM rv = AddXform(pProfile, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
8039
8041 delete pProfile;
8042
8043 return rv;
8044}
8045
8046
8071 bool bUseD2BxB2DxTags ,
8072 CIccCreateXformHintManager *pHintManager )
8073{
8075 bool bInput = !m_bLastInput;
8076
8077 if (!pProfile)
8079
8080 switch(pProfile->m_Header.deviceClass) {
8086
8087 default:
8088 break;
8089 }
8090
8091 switch (nLutType) {
8095 {
8096
8097 if (bInput) {
8098 nSrcSpace = pProfile->m_Header.colorSpace;
8099
8102 else
8103 nDstSpace = pProfile->m_Header.pcs;
8104 }
8105 else {
8108 }
8110 bInput = true;
8112 }
8113
8116 else
8117 nSrcSpace = pProfile->m_Header.pcs;
8118
8119 nDstSpace = pProfile->m_Header.colorSpace;
8120 }
8121 }
8122 break;
8123
8125 nSrcSpace = pProfile->m_Header.pcs;
8126 nDstSpace = pProfile->m_Header.pcs;
8127 bInput = false;
8128 break;
8129
8131 nSrcSpace = pProfile->m_Header.pcs;
8133 bInput = true;
8134 break;
8135
8137 if (!bInput)
8139 nSrcSpace = pProfile->m_Header.colorSpace;
8141 bInput = true;
8142 break;
8143
8145 if (!bInput)
8148 nDstSpace = pProfile->m_Header.pcs;
8149 bInput = true;
8150 break;
8151
8153 if (!bInput)
8157 break;
8158
8160 if (bInput) {
8161 nSrcSpace = pProfile->m_Header.colorSpace;
8163 }
8164 else {
8165 if (m_Xforms->size()) {
8166 CIccXformList::iterator prev = --(m_Xforms->end());
8167
8168
8170
8171 if (!prev->ptr->GetProfile()->m_Header.mcs) {
8173 }
8174
8175 CIccXform *pPrev = prev->ptr;
8176 CIccXform *pNew = CIccXform::Create(pPrev->GetProfilePtr(), pPrev->IsInput(), pPrev->GetIntent(), pPrev->GetInterp(),
8177 pPrev->GetConnectionConditions(),
icXformLutMCS, bUseD2BxB2DxTags, pHintManager);
8178
8179 if (pNew) {
8180 pPrev->DetachAll();
8181 delete pPrev;
8182 }
8183
8184 prev->ptr = pNew;
8185
8186 }
8187 }
8188 else {
8190 }
8191
8194 if (bUseD2BxB2DxTags && pProfile->m_Header.spectralPCS) {
8196 }
8197 else {
8198 nDstSpace = pProfile->m_Header.pcs;
8199 }
8200 }
8202 nDstSpace = pProfile->m_Header.colorSpace;
8203 }
8204 else {
8206 }
8207 }
8208 break;
8209
8210 default:
8212 }
8213
8214
8215 if (!m_Xforms->size()) {
8217 m_nLastSpace = nSrcSpace;
8218 m_nSrcSpace = nSrcSpace;
8219 }
8222 }
8223 }
8226 }
8227
8230
8231
8233 if (bInput) {
8235 }
8236 else {
8237 nIntent = m_nLastIntent;
8238 }
8241 }
8242
8243 CIccXformPtr Xform;
8244
8245 Xform.ptr = CIccXform::Create(pProfile, bInput, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
8246
8247 if (!Xform.ptr) {
8249 }
8250
8252 bInput = true;
8253 }
8254
8255 m_nLastSpace = nDstSpace;
8256 m_nLastIntent = nIntent;
8257 m_bLastInput = bInput;
8258
8259 m_Xforms->push_back(Xform);
8260
8262}
8263
8288 bool bUseSpectralPCS ,
8289 CIccCreateXformHintManager *pHintManager )
8290{
8292 bool bInput = !m_bLastInput;
8293
8294 if (!pProfile)
8296
8297 switch (pProfile->m_Header.deviceClass) {
8302
8303 default:
8304 break;
8305 }
8306
8307
8308 if (bInput) {
8309 nSrcSpace = pProfile->m_Header.colorSpace;
8310
8311 if (bUseSpectralPCS && pProfile->m_Header.spectralPCS)
8313 else {
8314 nDstSpace = pProfile->m_Header.pcs;
8315 bUseSpectralPCS = false;
8316 }
8317 }
8318 else {
8321 }
8323 bInput = true;
8325 }
8326
8327 if (bUseSpectralPCS && pProfile->m_Header.spectralPCS)
8329 else {
8330 nSrcSpace = pProfile->m_Header.pcs;
8331 bUseSpectralPCS = false;
8332 }
8333
8334 nDstSpace = pProfile->m_Header.colorSpace;
8335 }
8336
8337
8338 if (!m_Xforms->size()) {
8340 m_nLastSpace = nSrcSpace;
8341 m_nSrcSpace = nSrcSpace;
8342 }
8345 }
8346 }
8349 }
8350
8353
8354
8356 if (bInput) {
8358 }
8359 else {
8360 nIntent = m_nLastIntent;
8361 }
8364 }
8365
8366 CIccXformPtr Xform;
8367
8368 Xform.ptr = CIccXform::Create(pProfile, pXformTag, bInput, nIntent, nInterp, pPcc, bUseSpectralPCS, pHintManager);
8369
8370 if (!Xform.ptr) {
8372 }
8373
8374 m_nLastSpace = nDstSpace;
8375 m_nLastIntent = nIntent;
8376 m_bLastInput = bInput;
8377
8378 m_Xforms->push_back(Xform);
8379
8381}
8382
8407 bool bUseD2BxB2DxTags ,
8408 CIccCreateXformHintManager *pHintManager )
8409{
8411
8412 if (!pProfile)
8414
8415 icStatusCMM stat = AddXform(pProfile, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
8416
8418 delete pProfile;
8419
8420 return stat;
8421}
8422
8423icStatusCMM CIccCmm::CheckPCSConnections(
bool bUsePCSConversions)
8424{
8426
8427 CIccXformList::iterator last, next;
8428 CIccXformList xforms;
8429 CIccXformPtr ptr;
8430 bool bUsesPcsXforms = false;
8431
8432 next=m_Xforms->begin();
8433
8434 if (next!=m_Xforms->end()) {
8435 last = next;
8436 next++;
8437
8440 CIccPcsXform* pPcs = new CIccPcsXform();
8441
8442 if (!pPcs) {
8444 }
8445
8446 rv = pPcs->ConnectFirst(last->ptr, GetSourceSpace());
8447
8449 delete pPcs;
8450 return rv;
8451 }
8452
8454 ptr.ptr = pPcs;
8455 xforms.push_back(ptr);
8456
8457 bUsesPcsXforms = true;
8458 }
8459 else {
8460 delete pPcs;
8461 }
8462 }
8463
8464 xforms.push_back(*last);
8465
8466 for (;next!=m_Xforms->end(); last=next, next++) {
8467 if ((last->ptr->IsInput() && last->ptr->IsMCS() && next->ptr->IsMCS()) ||
8469 (!bUsePCSConversions &&
8471 last->ptr->SetDstPCSConversion(false);
8472 next->ptr->SetSrcPCSConversion(false);
8473 CIccPcsXform *pPcs = new CIccPcsXform();
8474
8475 if (!pPcs) {
8477 }
8478
8479 rv = pPcs->Connect(last->ptr, next->ptr);
8480
8482 return rv;
8483
8485 ptr.ptr = pPcs;
8486 xforms.push_back(ptr);
8487
8488 bUsesPcsXforms = true;
8489 }
8490 else {
8491 delete pPcs;
8492 }
8493 }
8494 xforms.push_back(*next);
8495 }
8496
8497 lastSpace = last->ptr->GetDstSpace();
8499 (last->ptr->NeedAdjustPCS() || GetDestSpace() != lastSpace)) {
8500 CIccPcsXform* pPcs = new CIccPcsXform();
8501
8502 if (!pPcs) {
8504 }
8505 rv = pPcs->ConnectLast(last->ptr, GetDestSpace());
8506
8508 return rv;
8509
8511 ptr.ptr = pPcs;
8512 xforms.push_back(ptr);
8513
8514 bUsesPcsXforms = true;
8515 }
8516 else {
8517 delete pPcs;
8518 }
8519 }
8520 }
8521
8522
8523 if (bUsesPcsXforms) {
8524 *m_Xforms = xforms;
8525 }
8526
8527 return rv;
8528}
8529
8531{
8533
8534 CIccXformList::iterator last, next;
8535 CIccXformList xforms;
8536 CIccXformPtr ptr;
8537 bool bUsesRangeConversion = false;
8538
8539 next = m_Xforms->begin();
8540
8541 if (next != m_Xforms->end()) {
8542 last = next;
8543 next++;
8544
8545 xforms.push_back(*last);
8546
8547 for (; next != m_Xforms->end(); last = next, next++) {
8548
8549 if (last->ptr->IsInput() && last->ptr->IsExtendedPCS() &&
IsSpaceColorimetricPCS(last->ptr->GetDstSpace()) &&
8550 !next->ptr->IsExtendedPCS()) {
8551 CIccProfile* pProfile = last->ptr->GetProfilePtr();
8553 if (!pTag) {
8555 if (!pTag) {
8557 }
8558 }
8559
8560 if (pTag) {
8561 ptr.ptr = CIccXform::Create(pProfile, pTag, true, last->ptr->GetIntent(), last->ptr->GetInterp(),
8562 last->ptr->GetConnectionConditions(), false);
8563 if (ptr.ptr) {
8564 ptr.ptr->ShareProfile();
8565 ptr.ptr->SetPcsAdjustXform();
8566 ptr.ptr->AttachCmmEnvVarLookup(last->ptr->GetCmmEnvVarLookup());
8567 xforms.push_back(ptr);
8568 bUsesRangeConversion = true;
8569 }
8570 }
8571 }
8572
8573 xforms.push_back(*next);
8574 }
8575 }
8576
8577 if (bUsesRangeConversion) {
8578 *m_Xforms = xforms;
8579 }
8580
8581 return rv;
8582}
8583
8584
8595void CIccCmm::SetLateBindingCC()
8596{
8597 CIccXformList::iterator i;
8598 CIccXform *pLastXform = NULL;
8599
8600 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
8601 if (i->ptr->IsInput()) {
8602 if (i->ptr->IsLateBinding()) {
8603 CIccXformList::iterator j=i;
8604 j++;
8605 if (j!=m_Xforms->end()) {
8606 if (j->ptr->IsLateBinding()) {
8607 i->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8608 j->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8609 pLastXform = i->ptr;
8610 }
8611 else {
8612 i->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8613 j->ptr->SetAppliedCC(j->ptr->GetConnectionConditions());
8614 pLastXform = NULL;
8615 }
8616 }
8617 else {
8618 i->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8619 pLastXform = NULL;
8620 }
8621 }
8623 CIccXformList::iterator j=i;
8624 j++;
8625 if (j!=m_Xforms->end()) {
8626 if (j->ptr->IsLateBinding()) {
8627 j->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8628 pLastXform = i->ptr;
8629 }
8630 else if (!j->ptr->IsAbstract()){
8631 j->ptr->SetAppliedCC(j->ptr->GetConnectionConditions());
8632 pLastXform = NULL;
8633 }
8634 }
8635 }
8636 else {
8637 pLastXform = NULL;
8638 }
8639 }
8640 else {
8641 if (!pLastXform)
8642 i->ptr->SetAppliedCC(i->ptr->GetConnectionConditions());
8643 else
8644 pLastXform = NULL;
8645 }
8646 }
8647}
8648
8649
8660icStatusCMM CIccCmm::Begin(
bool bAllocApplyCmm,
bool bUsePCSConversions)
8661{
8662 if (m_pApply)
8664
8666 m_nDestSpace = m_nLastSpace;
8667 }
8670 }
8671
8674 }
8675
8676 CheckPCSRangeConversions();
8677 SetLateBindingCC();
8678
8680 CIccXformList::iterator i;
8681
8682 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
8683
8684 rv = i->ptr->Begin();
8685
8687 return rv;
8688 }
8689
8690 rv = CheckPCSConnections(bUsePCSConversions);
8692 return rv;
8693
8694 if (bAllocApplyCmm) {
8695 m_pApply = GetNewApplyCmm(rv);
8696 }
8697 else
8699
8700 return rv;
8701}
8702
8703
8715CIccApplyCmm *CIccCmm::GetNewApplyCmm(
icStatusCMM &status)
8716{
8717 CIccApplyCmm *pApply = new CIccApplyCmm(this);
8718
8719 if (!pApply) {
8721 return NULL;
8722 }
8723
8724 CIccXformList::iterator i;
8725 CIccApplyXform *pXform;
8726
8727 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
8728 pXform = i->ptr->GetNewApply(status);
8730 delete pApply;
8731 return NULL;
8732 }
8733 pApply->AppendApplyXform(pXform);
8734 }
8735
8736 m_bValid = true;
8737
8739
8740 return pApply;
8741}
8742
8743
8755{
8756 return m_pApply->Apply(DstPixel, SrcPixel);
8757}
8758
8759
8771{
8772 return m_pApply->Apply(DstPixel, SrcPixel, nPixels);
8773}
8774
8775
8791{
8792 if (!Valid())
8794
8795 CIccXformList::iterator i;
8796
8797 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
8798 i->ptr->RemoveIO();
8799 }
8800
8802}
8803
8821{
8822 if (!((unsigned int)((*pInternal)*255.0)))
8823 return true;
8824 return false;
8825}
8826
8827
8845 bool bClip)
8846{
8848 if (!nSamples)
8850
8851
8854
8855 if (!pInput.get())
8857
8860
8862 {
8867 bCLRspace = true;
8868 break;
8869 }
8870
8871 switch(nSpace) {
8872
8874 {
8875 switch(nEncode) {
8876 case icEncodeValue:
8877 {
8879 break;
8880 }
8881 case icEncodeFloat:
8882 {
8883 break;
8884 }
8885 case icEncode8Bit:
8886 {
8890
8892 break;
8893 }
8894 case icEncode16Bit:
8895 {
8899 break;
8900 }
8901 case icEncode16BitV2:
8902 {
8906
8907 CIccPCSUtil::Lab2ToLab4(pInput, pInput);
8908 break;
8909 }
8910 default:
8912 break;
8913 }
8914 break;
8915 }
8916
8918 {
8919 switch(nEncode) {
8920 case icEncodeValue:
8921 {
8926 break;
8927 }
8928 case icEncodePercent:
8929 {
8934 break;
8935 }
8936 case icEncodeFloat:
8937 {
8939 break;
8940 }
8941
8942 case icEncode16Bit:
8943 case icEncode16BitV2:
8944 {
8948 break;
8949 }
8950
8951 default:
8953 break;
8954 }
8955 break;
8956 }
8957
8960
8961 default:
8962 {
8963 switch(nEncode) {
8964 case icEncodeValue:
8965 {
8966 if (!bCLRspace || nSamples<3) {
8968 }
8969 if (nSamples==3)
8971 break;
8972 }
8973
8974 case icEncodePercent:
8975 {
8976 if (bClip) {
8977 for(i=0; i<nSamples; i++) {
8979 if (pInput[i] < 0.0) pInput[i] = 0.0;
8980 if (pInput[i] > 1.0) pInput[i] = 1.0;
8981 }
8982 }
8983 else {
8984 for(i=0; i<nSamples; i++) {
8986 }
8987 }
8988 break;
8989 }
8990
8991 case icEncodeFloat:
8992 {
8993 if (bClip) {
8994 for(i=0; i<nSamples; i++) {
8995 if (pInput[i] < 0.0) pInput[i] = 0.0;
8996 if (pInput[i] > 1.0) pInput[i] = 1.0;
8997 }
8998 }
8999 break;
9000 }
9001
9002 case icEncode8Bit:
9003 {
9004 for(i=0; i<nSamples; i++) {
9006 }
9007 break;
9008 }
9009
9010 case icEncode16Bit:
9011 case icEncode16BitV2:
9012 {
9013 for(i=0; i<nSamples; i++) {
9015 }
9016 break;
9017 }
9018
9019 default:
9021 break;
9022 }
9023 break;
9024 }
9025 }
9026
9029}
9030
9031
9049{
9050 switch(nSpace) {
9052 {
9056
9058 }
9060 {
9066 }
9067 default:
9068 {
9072 if (!FloatPixel.get())
9074
9075 for(i=0; i<nSamples; i++) {
9077 }
9078 return ToInternalEncoding(nSpace, icEncode8Bit, pInternal, FloatPixel);
9079 }
9080 }
9081
9082}
9083
9084
9102{
9103 switch(nSpace) {
9105 {
9109
9111 }
9113 {
9119 }
9120 default:
9121 {
9125 if (!pFloatPixel.get())
9127
9128 for(i=0; i<nSamples; i++) {
9130 }
9131 return ToInternalEncoding(nSpace, icEncode16Bit, pInternal, pFloatPixel);
9132 }
9133 }
9134}
9135
9136
9154{
9156 if (!nSamples)
9158
9161
9162 if (!pInput.get())
9164
9167
9168 switch(nSpace) {
9169
9171 {
9172 switch(nEncode) {
9173 case icEncodeValue:
9174 {
9176 break;
9177 }
9178 case icEncodeUnitFloat:
9179 case icEncodeFloat:
9180 {
9181 break;
9182 }
9183 case icEncode8Bit:
9184 {
9186
9190 break;
9191 }
9192 case icEncode16Bit:
9193 {
9197 break;
9198 }
9199 case icEncode16BitV2:
9200 {
9201 CIccPCSUtil::Lab4ToLab2(pInput, pInput);
9202
9206 break;
9207 }
9208 default:
9210 break;
9211 }
9212 break;
9213 }
9214
9216 {
9217 switch(nEncode) {
9218 case icEncodeValue:
9219 {
9221 break;
9222 }
9223 case icEncodePercent:
9224 {
9229 break;
9230 }
9231 case icEncodeFloat:
9232 case icEncodeUnitFloat:
9233 {
9235 break;
9236 }
9237
9238 case icEncode16Bit:
9239 case icEncode16BitV2:
9240 {
9245 break;
9246 }
9247
9248 default:
9250 break;
9251 }
9252 break;
9253 }
9254
9257
9258 default:
9259 {
9260 switch(nEncode) {
9261 case icEncodeValue:
9262 {
9265 }
9266 else if (bCLRspace && nSamples >=3) {
9268 }
9269 break;
9270 }
9271 case icEncodePercent:
9272 {
9273 if (bClip) {
9274 for(i=0; i<nSamples; i++) {
9275 if (pInput[i] < 0.0) pInput[i] = 0.0;
9276 if (pInput[i] > 1.0) pInput[i] = 1.0;
9278 }
9279 }
9280 else {
9281 for(i=0; i<nSamples; i++) {
9283 }
9284 }
9285 break;
9286 }
9287
9288 case icEncodeFloat:
9289 break;
9290
9291 case icEncodeUnitFloat:
9292 {
9293 if (bClip) {
9294 for(i=0; i<nSamples; i++) {
9295 if (pInput[i] < 0.0) pInput[i] = 0.0;
9296 if (pInput[i] > 1.0) pInput[i] = 1.0;
9297 }
9298 }
9299 break;
9300 }
9301
9302 case icEncode8Bit:
9303 {
9304 for(i=0; i<nSamples; i++) {
9305 pInput[i] =
icFtoU8(pInput[i]);
9306 }
9307 break;
9308 }
9309
9310 case icEncode16Bit:
9311 case icEncode16BitV2:
9312 {
9313 for(i=0; i<nSamples; i++) {
9315 }
9316 break;
9317 }
9318
9319 default:
9321 break;
9322 }
9323 break;
9324 }
9325 }
9326
9329}
9330
9331
9349{
9350 switch(nSpace) {
9352 {
9353 pData[0] =
icFtoU8(pInternal[0]);
9354 pData[1] =
icFtoU8(pInternal[1]);
9355 pData[2] =
icFtoU8(pInternal[2]);
9356
9358 }
9360 {
9361 pData[0] =
icFtoU8(pInternal[0]);
9362 pData[1] =
icFtoU8(pInternal[1]);
9363 pData[2] =
icFtoU8(pInternal[2]);
9364 pData[3] =
icFtoU8(pInternal[3]);
9365
9367 }
9368 default:
9369 {
9372
9375
9376 if (!pFloatPixel.get())
9378
9379 convertStat = FromInternalEncoding(nSpace, icEncode8Bit, pFloatPixel, pInternal);
9380 if (convertStat)
9381 return convertStat;
9382 for(i=0; i<nSamples; i++) {
9384 }
9385
9387 }
9388 }
9389}
9390
9391
9409{
9410 switch(nSpace) {
9412 {
9416
9418 }
9420 {
9425
9427 }
9428 default:
9429 {
9434
9435 if (!pFloatPixel.get())
9437
9438 convertStat = FromInternalEncoding(nSpace, icEncode16Bit, pFloatPixel, pInternal);
9439 if (convertStat)
9440 return convertStat;
9441 for(i=0; i<nSamples; i++) {
9443 }
9444
9446 }
9447 }
9448}
9449
9450
9465const icChar* CIccCmm::GetFloatColorEncoding(icFloatColorEncoding val)
9466{
9467 switch(val) {
9468
9469 case icEncodeValue:
9470 return "icEncodeValue";
9471
9472 case icEncodeFloat:
9473 return "icEncodeFloat";
9474
9475 case icEncodeUnitFloat:
9476 return "icEncodeUnitFloat";
9477
9478 case icEncodePercent:
9479 return "icEncodePercent";
9480
9481 case icEncode8Bit:
9482 return "icEncode8Bit";
9483
9484 case icEncode16Bit:
9485 return "icEncode16Bit";
9486
9487 case icEncode16BitV2:
9488 return "icEncode16BitV2";
9489
9490 default:
9491 return "icEncodeUnknown";
9492 }
9493}
9494
9509icFloatColorEncoding CIccCmm::GetFloatColorEncoding(
const icChar* val)
9510{
9511 if (!
stricmp(val,
"icEncodePercent")) {
9512 return icEncodePercent;
9513 }
9514 else if (!
stricmp(val,
"icEncodeUnitFloat")) {
9515 return icEncodeUnitFloat;
9516 }
9517 else if (!
stricmp(val,
"icEncodeFloat")) {
9518 return icEncodeFloat;
9519 }
9520 else if (!
stricmp(val,
"icEncode8Bit")) {
9521 return icEncode8Bit;
9522 }
9523 else if (!
stricmp(val,
"icEncode16Bit")) {
9524 return icEncode16Bit;
9525 }
9526 else if (!
stricmp(val,
"icEncode16BitV2")) {
9527 return icEncode16BitV2;
9528 }
9529 else if (!
stricmp(val,
"icEncodeValue")) {
9530 return icEncodeValue;
9531 }
9532 else {
9533 return icEncodeUnknown;
9534 }
9535
9536}
9537
9550{
9552}
9553
9554
9564void CIccCmm::IterateXforms( IXformIterator* pIterater) const
9565{
9566 for (auto x = m_Xforms->begin(); x != m_Xforms->end(); x++) {
9567 pIterater->iterate(x->ptr);
9568 }
9569}
9570
9571
9584{
9585 if (!m_Xforms->size())
9586 return m_nSrcSpace;
9587
9588 return m_Xforms->begin()->ptr->GetSrcSpace();
9589}
9590
9603{
9604 if (!m_Xforms->size())
9605 return m_nDestSpace;
9606
9607 return m_Xforms->rbegin()->ptr->GetDstSpace();
9608}
9609
9621CIccApplyNamedColorCmm::CIccApplyNamedColorCmm(CIccNamedColorCmm *pCmm) : CIccApplyCmm(pCmm)
9622{
9623}
9624
9625
9634CIccApplyNamedColorCmm::~CIccApplyNamedColorCmm()
9635{
9636}
9637
9638
9652{
9655 CIccApplyXformList::iterator i;
9656 int j, n = (int)m_Xforms->size();
9657 CIccApplyXform *pApply;
9658 const CIccXform *pApplyXform;
9659 CIccXformNamedColor *pXform;
9660
9661 if (!n)
9663
9664 if (!m_Pixel && !InitPixel()) {
9666 }
9667
9670
9671 pSrc = SrcPixel;
9672 pDst = m_Pixel;
9673
9674#ifdef DEBUG_CMM_APPLY
9675 int nCount = 0;
9676 printf("Start ApplyNamedCmm\n");
9678#endif
9679
9680
9681 if (n>1) {
9682 for (j=0, i=m_Xforms->begin(); j<n-1 && i!=m_Xforms->end(); i++, j++) {
9683
9684 pApply = i->ptr;
9685 pApplyXform = pApply->GetXform();
9687 pXform = (CIccXformNamedColor*)pApplyXform;
9688
9689 switch(pXform->GetInterface()) {
9690 case icApplyPixel2Pixel:
9691 pXform->Apply(pApply, pDst, pSrc);
9692#ifdef DEBUG_CMM_APPLY
9693 DumpCmmApplyPixel(nCount++, pDst, pXform->GetNumDstSamples());
9694#endif
9695 break;
9696
9697 case icApplyPixel2Named:
9698 pXform->Apply(pApply, NamedColor, pSrc);
9699#ifdef DEBUG_CMM_APPLY
9700 printf("Xfm%d: \"%s\"\n", nCount++, NamedColor);
9701#endif
9702 break;
9703
9704 case icApplyNamed2Pixel:
9705 if (j==0) {
9707 }
9708
9709 rv = pXform->Apply(pApply, pDst, NamedColor);
9710#ifdef DEBUG_CMM_APPLY
9711 DumpCmmApplyPixel(nCount++, pDst, pXform->GetNumDstSamples());
9712#endif
9713
9714 if (rv) {
9715 return rv;
9716 }
9717 break;
9718
9719 default:
9720 break;
9721 }
9722 }
9723 else {
9724 pApplyXform->Apply(pApply, pDst, pSrc);
9725#ifdef DEBUG_CMM_APPLY
9726 DumpCmmApplyPixel(nCount++, pDst, pApplyXform->GetNumDstSamples());
9727#endif
9728 }
9730 pSrc = pDst;
9731 if (pTmp==SrcPixel)
9732 pDst = m_Pixel2;
9733 else
9734 pDst = pTmp;
9735 }
9736
9737 pApply = i->ptr;
9738 pApplyXform = pApply->GetXform();
9740 pXform = (CIccXformNamedColor*)pApplyXform;
9741
9742 switch(pXform->GetInterface()) {
9743 case icApplyPixel2Pixel:
9744 pXform->Apply(pApply, DstPixel, pSrc);
9745#ifdef DEBUG_CMM_APPLY
9746 DumpCmmApplyPixel(nCount++, DstPixel, pXform->GetNumDstSamples());
9747#endif
9748 break;
9749
9750 case icApplyPixel2Named:
9751 default:
9753 break;
9754
9755 case icApplyNamed2Pixel:
9756 rv = pXform->Apply(pApply, DstPixel, NamedColor);
9757#ifdef DEBUG_CMM_APPLY
9758 DumpCmmApplyPixel(nCount++, DstPixel, pXform->GetNumDstSamples());
9759#endif
9760 if (rv) {
9761 return rv;
9762 }
9763 break;
9764
9765 }
9766 }
9767 else {
9768 pApplyXform->Apply(pApply, DstPixel, pSrc);
9769#ifdef DEBUG_CMM_APPLY
9770 DumpCmmApplyPixel(nCount++, DstPixel, pApplyXform->GetNumDstSamples());
9771#endif
9772 }
9773
9774 }
9775 else if (n==1) {
9776 i = m_Xforms->begin();
9777
9778 pApply = i->ptr;
9779 pApplyXform = pApply->GetXform();
9782 }
9783
9784 pApplyXform->Apply(pApply, DstPixel, pSrc);
9785#ifdef DEBUG_CMM_APPLY
9786 DumpCmmApplyPixel(nCount++, DstPixel, pApplyXform->GetNumDstSamples());
9787#endif
9788 }
9789
9790#ifdef DEBUG_CMM_APPLY
9791 DumpCmmApplyPixel(nCount++, DstPixel,
icGetSpaceSamples(m_pCmm->GetDestSpace()));
9792 printf("End ApplyNamedCmm\n\n");
9793#endif
9794
9796}
9797
9798
9812{
9815 CIccApplyXformList::iterator i;
9816 int j, n = (int)m_Xforms->size();
9817 CIccApplyXform *pApply;
9818 const CIccXform *pApplyXform;
9819 CIccXformNamedColor *pXform;
9821
9822 if (!n)
9824
9825 if (!m_Pixel && !InitPixel()) {
9827 }
9828
9831
9832 for (k=0; k<nPixels; k++) {
9833
9834 pSrc = SrcPixel;
9835 pDst = m_Pixel;
9836
9837 if (n>1) {
9838 for (j=0, i=m_Xforms->begin(); j<n-1 && i!=m_Xforms->end(); i++, j++) {
9839
9840 pApply = i->ptr;
9841 pApplyXform = pApply->GetXform();
9843 pXform = (CIccXformNamedColor*)pApplyXform;
9844
9845 switch(pXform->GetInterface()) {
9846 case icApplyPixel2Pixel:
9847 pXform->Apply(pApply, pDst, pSrc);
9848 break;
9849
9850 case icApplyPixel2Named:
9851 pXform->Apply(pApply, NamedColor, pSrc);
9852 break;
9853
9854 case icApplyNamed2Pixel:
9855 if (j==0) {
9857 }
9858
9859 rv = pXform->Apply(pApply, pDst, NamedColor);
9860
9861 if (rv) {
9862 return rv;
9863 }
9864 break;
9865
9866 default:
9867 break;
9868 }
9869 }
9870 else {
9871 pApplyXform->Apply(pApply, pDst, pSrc);
9872 }
9873 pSrc = pDst;
9874 }
9875
9876 pApply = i->ptr;
9877 pApplyXform = pApply->GetXform();
9879 pXform = (CIccXformNamedColor*)pApplyXform;
9880
9881 switch(pXform->GetInterface()) {
9882 case icApplyPixel2Pixel:
9883 pXform->Apply(pApply, DstPixel, pSrc);
9884 break;
9885
9886 case icApplyPixel2Named:
9887 default:
9889 break;
9890
9891 case icApplyNamed2Pixel:
9892 rv = pXform->Apply(pApply, DstPixel, NamedColor);
9893 if (rv) {
9894 return rv;
9895 }
9896 break;
9897
9898 }
9899 }
9900 else {
9901 pApplyXform->Apply(pApply, DstPixel, pSrc);
9902 }
9903
9904 }
9905 else if (n==1) {
9906 i = m_Xforms->begin();
9907
9908 pApply = i->ptr;
9909 pApplyXform = pApply->GetXform();
9912 }
9913
9914 pApplyXform->Apply(pApply, DstPixel, pSrc);
9915 }
9916
9917 SrcPixel += m_pCmm->GetSourceSamples();
9918 DstPixel += m_pCmm->GetDestSamples();
9919 }
9920
9922}
9923
9924
9938{
9941 CIccApplyXformList::iterator i;
9942 int j, n = (int)m_Xforms->size();
9943 CIccApplyXform *pApply;
9944 const CIccXform *pApplyXform;
9945 CIccXformNamedColor *pXform;
9946
9947 if (!n)
9949
9950 if (!m_Pixel && !InitPixel()) {
9952 }
9953
9956
9957 pSrc = SrcPixel;
9958 pDst = m_Pixel;
9959
9960 if (n>1) {
9961 for (j=0, i=m_Xforms->begin(); j<n-1 && i!=m_Xforms->end(); i++, j++) {
9962
9963 pApply = i->ptr;
9964 pApplyXform = pApply->GetXform();
9966 pXform = (CIccXformNamedColor*)pApplyXform;
9967 switch(pXform->GetInterface()) {
9968 case icApplyPixel2Pixel:
9969 pXform->Apply(pApply, pDst, pSrc);
9970 break;
9971
9972 case icApplyPixel2Named:
9973 pXform->Apply(pApply, NamedColor, pSrc);
9974 break;
9975
9976 case icApplyNamed2Pixel:
9977 if (j==0) {
9979 }
9980 rv = pXform->Apply(pApply, pDst, NamedColor);
9981 if (rv) {
9982 return rv;
9983 }
9984 break;
9985
9986 default:
9987 break;
9988 }
9989 }
9990 else {
9991 pApplyXform->Apply(pApply, pDst, pSrc);
9992 }
9994 pSrc = pDst;
9995 if (pTmp==SrcPixel)
9996 pDst = m_Pixel2;
9997 else
9998 pDst = pTmp;
9999 }
10000
10001 pApply = i->ptr;
10002 pApplyXform = pApply->GetXform();
10004 pXform = (CIccXformNamedColor*)pApplyXform;
10005 switch(pXform->GetInterface()) {
10006
10007 case icApplyPixel2Named:
10008 pXform->Apply(pApply, DstColorName, pSrc);
10009 break;
10010
10011 case icApplyPixel2Pixel:
10012 case icApplyNamed2Pixel:
10013 default:
10015 break;
10016 }
10017 }
10018 else {
10020 }
10021
10022 }
10023 else if (n==1) {
10024 i = m_Xforms->begin();
10025 pApply = i->ptr;
10026 pApplyXform = pApply->GetXform();
10029 }
10030
10031 pXform = (CIccXformNamedColor*)pApplyXform;
10032 pXform->Apply(pApply, DstColorName, pSrc);
10033 }
10034
10036}
10037
10038
10052{
10055 CIccApplyXformList::iterator i;
10056 int j, n = (int)m_Xforms->size();
10057 CIccApplyXform *pApply;
10058 const CIccXform *pApplyXform;
10059 CIccXformNamedColor *pXform;
10060
10061 if (!n)
10063
10064 if (!m_Pixel && !InitPixel()) {
10066 }
10067
10070
10071 i=m_Xforms->begin();
10072 pApply = i->ptr;
10073 pApplyXform = pApply->GetXform();
10076
10077 pXform = (CIccXformNamedColor*)pApplyXform;
10078
10079 pDst = m_Pixel;
10080
10081 if (n>1) {
10082 rv = pXform->Apply(pApply, pDst, SrcColorName, tint);
10083 if (rv) {
10084 return rv;
10085 }
10086
10087 pSrc = pDst;
10088 pDst = m_Pixel2;
10089
10090 for (j=0, i++; j<n-2 && i!=m_Xforms->end(); i++, j++) {
10091
10092 pApply = i->ptr;
10093 pApplyXform = pApply->GetXform();
10095 CIccXformNamedColor *pXform = (CIccXformNamedColor*)pApplyXform;
10096 switch(pXform->GetInterface()) {
10097 case icApplyPixel2Pixel:
10098 pXform->Apply(pApply, pDst, pSrc);
10099 break;
10100
10101 case icApplyPixel2Named:
10102 pXform->Apply(pApply, NamedColor, pSrc);
10103 break;
10104
10105 case icApplyNamed2Pixel:
10106 rv = pXform->Apply(pApply, pDst, NamedColor);
10107 if (rv) {
10108 return rv;
10109 }
10110 break;
10111
10112 default:
10113 break;
10114 }
10115 }
10116 else {
10117 pApplyXform->Apply(pApply, pDst, pSrc);
10118 }
10120 pSrc = pDst;
10121 pDst = pTmp;
10122 }
10123
10124 pApply = i->ptr;
10125 pApplyXform = pApply->GetXform();
10127 pXform = (CIccXformNamedColor*)pApplyXform;
10128 switch(pXform->GetInterface()) {
10129 case icApplyPixel2Pixel:
10130 pXform->Apply(pApply, DstPixel, pSrc);
10131 break;
10132
10133 case icApplyPixel2Named:
10134 default:
10136 break;
10137
10138 case icApplyNamed2Pixel:
10139 rv = pXform->Apply(pApply, DstPixel, NamedColor);
10140 if (rv) {
10141 return rv;
10142 }
10143 break;
10144
10145 }
10146 }
10147 else {
10148 pApplyXform->Apply(pApply, DstPixel, pSrc);
10149 }
10150
10151 }
10152 else if (n==1) {
10153 rv = pXform->Apply(pApply, DstPixel, SrcColorName, tint);
10154 if (rv) {
10155 return rv;
10156 }
10157 }
10158
10159
10161}
10162
10176{
10179 CIccApplyXformList::iterator i;
10180 int j, n = (int)m_Xforms->size();
10183 CIccApplyXform *pApply;
10184 const CIccXform *pApplyXform;
10185 CIccXformNamedColor *pXform;
10186
10187 if (!n)
10189
10190 if (!m_Pixel && !InitPixel()) {
10192 }
10193
10194 i=m_Xforms->begin();
10195
10196 pApply = i->ptr;
10197 pApplyXform = pApply->GetXform();
10200
10201 pXform = (CIccXformNamedColor*)pApplyXform;
10202
10203 pDst = m_Pixel;
10204
10205 if (n>1) {
10206 rv = pXform->Apply(pApply, pDst, SrcColorName, tint);
10207
10208 if (rv) {
10209 return rv;
10210 }
10211
10212 pSrc = pDst;
10213 pDst = m_Pixel2;
10214
10215 for (j=0, i++; j<n-2 && i!=m_Xforms->end(); i++, j++) {
10216
10217 pApply = i->ptr;
10218 pApplyXform = pApply->GetXform();
10220 pXform = (CIccXformNamedColor*)pApplyXform;
10221 switch(pXform->GetInterface()) {
10222 case icApplyPixel2Pixel:
10223 pXform->Apply(pApply, pDst, pSrc);
10224 break;
10225
10226
10227 case icApplyPixel2Named:
10228 pXform->Apply(pApply, NamedColor, pSrc);
10229 break;
10230
10231 case icApplyNamed2Pixel:
10232 rv = pXform->Apply(pApply, pDst, NamedColor);
10233 if (rv) {
10234 return rv;
10235 }
10236 break;
10237
10238 default:
10239 break;
10240 }
10241 }
10242 else {
10243 pApplyXform->Apply(pApply, pDst, pSrc);
10244 }
10246 pSrc = pDst;
10247 pDst = pTmp;
10248 }
10249
10250 pApply = i->ptr;
10251 pApplyXform = pApply->GetXform();
10253 pXform = (CIccXformNamedColor*)pApplyXform;
10254 switch(pXform->GetInterface()) {
10255 case icApplyPixel2Named:
10256 pXform->Apply(pApply, DstColorName, pSrc);
10257 break;
10258
10259 case icApplyPixel2Pixel:
10260 case icApplyNamed2Pixel:
10261 default:
10263 break;
10264 }
10265 }
10266 else {
10268 }
10269
10270 }
10271 else if (n==1) {
10273 }
10274
10276}
10277
10292 bool bFirstInput) : CIccCmm(nSrcSpace, nDestSpace, bFirstInput)
10293{
10294 m_nApplyInterface = icApplyPixel2Pixel;
10295}
10296
10305CIccNamedColorCmm::~CIccNamedColorCmm()
10306{
10307}
10308
10309
10332 bool bUseD2BxB2DxTags ,
10333 CIccCreateXformHintManager *pHintManager ,
10334 bool bUseSubProfile )
10335{
10337
10338 if (!pProfile)
10340
10341 icStatusCMM rv = AddXform(pProfile, nIntent, nInterp, pPcc, nLutType, bUseD2BxB2DxTags, pHintManager);
10342
10344 delete pProfile;
10345
10346 return rv;
10347}
10348
10372 bool bUseD2BxB2DxTags ,
10373 CIccCreateXformHintManager *pHintManager )
10374{
10376 CIccXformPtr Xform;
10377 bool bInput = !m_bLastInput;
10380
10381 switch(pProfile->m_Header.deviceClass) {
10386 break;
10387
10390 break;
10391
10392 default:
10393 break;
10394 }
10395
10396 Xform.ptr = NULL;
10397 switch (nUseLutType) {
10398
10403 {
10405
10407 if (bInput) {
10409 }
10412 bUseD2BxB2DxTags = true;
10413 }
10414 else {
10415 nSrcSpace = pProfile->m_Header.pcs;
10416 }
10417
10418 if (!m_Xforms->size()) {
10420 m_nSrcSpace = nSrcSpace;
10421 }
10422 else {
10423 nSrcSpace = m_nSrcSpace;
10424 }
10425 }
10426 else {
10428 m_nLastSpace = nSrcSpace;
10429 }
10430 else {
10431 nSrcSpace = m_nLastSpace;
10432 }
10433 }
10434
10438 bUseD2BxB2DxTags = true;
10439 }
10440 else {
10441 nDstSpace = pProfile->m_Header.pcs;
10442 }
10443 bInput = true;
10444 }
10445 else {
10447 bInput = false;
10448 }
10449
10450 Xform.ptr = CIccXform::Create(pProfile, bInput, nIntent, nInterp, pPcc,
icXformLutNamedColor, bUseD2BxB2DxTags, pHintManager);
10451 if (!Xform.ptr) {
10453 }
10454 CIccXformNamedColor *pXform = (CIccXformNamedColor *)Xform.ptr;
10455 rv = pXform->SetSrcSpace(nSrcSpace);
10456 if (rv)
10457 return rv;
10458
10459 rv = pXform->SetDestSpace(nDstSpace);
10460 if (rv)
10461 return rv;
10462 }
10463 else {
10464
10467
10468
10469 if (bInput) {
10470 nSrcSpace = pProfile->m_Header.colorSpace;
10471
10474 bUseD2BxB2DxTags = true;
10475 }
10476 else
10477 nDstSpace = pProfile->m_Header.pcs;
10478 }
10479 else {
10482 }
10484 bInput = true;
10486 }
10487
10490 bUseD2BxB2DxTags = true;
10491 }
10492 else
10493 nSrcSpace = pProfile->m_Header.pcs;
10494
10495 nDstSpace = pProfile->m_Header.colorSpace;
10496 }
10497 }
10498 }
10499 break;
10500
10502 nSrcSpace = pProfile->m_Header.pcs;
10503 nDstSpace = pProfile->m_Header.pcs;
10504 bInput = false;
10505 break;
10506
10508 nSrcSpace = pProfile->m_Header.pcs;
10510 bInput = true;
10511 break;
10512
10514 nSrcSpace = pProfile->m_Header.colorSpace;
10516 break;
10517
10519 nSrcSpace = pProfile->m_Header.colorSpace;
10521 break;
10522
10524 switch(pProfile->m_Header.deviceClass)
10525 {
10528 nSrcSpace = pProfile->m_Header.colorSpace;
10530 break;
10533 if (bUseD2BxB2DxTags && pProfile->m_Header.spectralPCS) {
10535 }
10536 else {
10537 nDstSpace = pProfile->m_Header.pcs;
10538 }
10539 bInput = true;
10540 break;
10541
10544 nDstSpace = pProfile->m_Header.colorSpace;
10545 break;
10546
10547 default:
10549 }
10550 break;
10551
10552 default:
10554 }
10555
10556
10557 if (!m_Xforms->size()) {
10559 m_nLastSpace = nSrcSpace;
10560 m_nSrcSpace = nSrcSpace;
10561 }
10564 }
10565 }
10568 }
10569
10570 if (!m_Xforms->size())
10571 m_nSrcSpace = nSrcSpace;
10572
10573 m_nDestSpace = nDstSpace;
10574
10575
10577 if (bInput) {
10579 }
10580 else {
10581 nIntent = m_nLastIntent;
10582 }
10585 }
10586
10587 if (!Xform.ptr)
10588 Xform.ptr = CIccXform::Create(pProfile, bInput, nIntent, nInterp, pPcc, nUseLutType, bUseD2BxB2DxTags, pHintManager);
10589
10590 if (!Xform.ptr) {
10592 }
10593
10594 m_nLastSpace = Xform.ptr->GetDstSpace();
10595 m_nLastIntent = nIntent;
10596
10598 bInput = false;
10599 m_bLastInput = bInput;
10600
10601 m_Xforms->push_back(Xform);
10602
10604}
10605
10616 icStatusCMM CIccNamedColorCmm::Begin(
bool bAllocNewApply,
bool bUsePcsConversion)
10617{
10619 m_nDestSpace = m_nLastSpace;
10620 }
10623 }
10624
10627 m_nApplyInterface = icApplyPixel2Pixel;
10628 }
10629 else {
10630 m_nApplyInterface = icApplyPixel2Named;
10631 }
10632 }
10633 else {
10635 m_nApplyInterface = icApplyNamed2Pixel;
10636 }
10637 else {
10638 m_nApplyInterface = icApplyNamed2Named;
10639 }
10640 }
10641
10642 CheckPCSRangeConversions();
10643 SetLateBindingCC();
10644
10646 CIccXformList::iterator i;
10647
10648 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
10649 rv = i->ptr->Begin();
10650
10652 return rv;
10653 }
10654 }
10655
10656 rv = CheckPCSConnections(bUsePcsConversion);
10658 return rv;
10659
10660 if (bAllocNewApply) {
10662
10663 m_pApply = GetNewApplyCmm(rv);
10664 }
10665 else
10667
10668 return rv;
10669}
10670
10681 CIccApplyCmm *CIccNamedColorCmm::GetNewApplyCmm(
icStatusCMM &status)
10682 {
10683 CIccApplyCmm *pApply = new CIccApplyNamedColorCmm(this);
10684
10685 CIccXformList::iterator i;
10686
10687 for (i=m_Xforms->begin(); i!=m_Xforms->end(); i++) {
10688 CIccApplyXform *pXform = i->ptr->GetNewApply(status);
10690 delete pApply;
10691 return NULL;
10692 }
10693 pApply->AppendApplyXform(pXform);
10694 }
10695
10696 m_bValid = true;
10697
10699 return pApply;
10700}
10701
10702
10716{
10717 return ((CIccApplyNamedColorCmm*)m_pApply)->Apply(DstColorName, SrcPixel);
10718}
10719
10720
10734{
10735 return ((CIccApplyNamedColorCmm*)m_pApply)->Apply(DstPixel, SrcColorName, tint);
10736}
10737
10738
10752{
10753 return ((CIccApplyNamedColorCmm*)m_pApply)->Apply(DstColorName, SrcColorName, tint);
10754}
10755
10756
10769{
10770 int n = (int)m_Xforms->size();
10771 CIccXformPtr *pLastXform;
10772
10773 if (!n)
10775
10776 pLastXform = &m_Xforms->back();
10777
10779 CIccXformNamedColor *pXform = (CIccXformNamedColor *)pLastXform->ptr;
10783 }
10784
10788 }
10789
10790 return pXform->SetDestSpace(nDestSpace);
10791 }
10792
10794}
10795
10796
10804CIccMruCmm::CIccMruCmm()
10805{
10806 m_pCmm = NULL;
10807 m_bDeleteCmm = false;
10808 m_nCacheSize = 0;
10809}
10810
10811
10819CIccMruCmm::~CIccMruCmm()
10820{
10821 if (m_pCmm && m_bDeleteCmm)
10822 delete m_pCmm;
10823}
10824
10825
10846CIccMruCmm* CIccMruCmm::Attach(CIccCmm *pCmm,
icUInt8Number nCacheSize,
bool bDeleteCmm)
10847{
10848 if (!pCmm || !nCacheSize)
10849 return NULL;
10850
10851 if (!pCmm->Valid()) {
10852 if (bDeleteCmm)
10853 delete pCmm;
10854 return NULL;
10855 }
10856
10857 CIccMruCmm *rv = new CIccMruCmm();
10858
10859 rv->m_pCmm = pCmm;
10860 rv->m_nCacheSize = nCacheSize;
10861 rv->m_bDeleteCmm = bDeleteCmm;
10862
10863 rv->m_nSrcSpace = pCmm->GetSourceSpace();
10864 rv->m_nDestSpace = pCmm->GetDestSpace();
10865 rv->m_nLastSpace = pCmm->GetLastSpace();
10866 rv->m_nLastIntent = pCmm->GetLastIntent();
10867
10869 delete rv;
10870 return NULL;
10871 }
10872
10873 return rv;
10874}
10875
10876CIccApplyCmm *CIccMruCmm::GetNewApplyCmm(
icStatusCMM &status)
10877{
10878 CIccApplyMruCmm *rv = new CIccApplyMruCmm(this);
10879
10880 if (!rv) {
10882 return NULL;
10883 }
10884
10885 if (!rv->Init(m_pCmm, m_nCacheSize)) {
10886 delete rv;
10888 return NULL;
10889 }
10890
10891 return rv;
10892}
10893
10901template<class T>
10902CIccMruCache<T>::CIccMruCache()
10903{
10904 m_cache = NULL;
10905 m_nNumPixel = 0;
10906 m_pixelData = NULL;
10907 m_nSrcSamples = 0;
10908 m_pFirst = NULL;
10909}
10910
10918template<class T>
10919CIccMruCache<T>::~CIccMruCache()
10920{
10921 if (m_cache)
10922 delete[] m_cache;
10923
10924 if (m_pixelData)
10925 free(m_pixelData);
10926}
10927
10942template<class T>
10944{
10945 m_nSrcSamples = nSrcSamples;
10946 m_nSrcSize = nSrcSamples * sizeof(T);
10947 m_nDstSize = nDstSamples * sizeof(T);
10948
10949 m_nTotalSamples = m_nSrcSamples + nDstSamples;
10950
10951 m_nNumPixel = 0;
10952 m_nCacheSize = nCacheSize;
10953
10954 m_pFirst = NULL;
10955 m_cache = new CIccMruPixel<T>[nCacheSize];
10956
10957 if (!m_cache)
10958 return false;
10959
10960 m_pixelData = (T*)malloc((int)nCacheSize * m_nTotalSamples * sizeof(T));
10961
10962 if (!m_pixelData)
10963 return false;
10964
10965 return true;
10966}
10967
10968template<class T>
10970{
10971 CIccMruCache<T> *rv = new CIccMruCache<T>;
10972
10973 if (!rv->Init(nSrcSamples, nDstSamples, nCacheSize)) {
10974 delete rv;
10975 return NULL;
10976 }
10977
10978 return rv;
10979}
10980
10996template<class T>
10997bool CIccMruCache<T>::Apply(T* DstPixel, const T* SrcPixel)
10998{
10999 CIccMruPixel<T>* ptr, * prev = NULL, * last = NULL;
11000 int i;
11001 T* pixel;
11002
11003 for (ptr = m_pFirst, i = 0; ptr; ptr = ptr->pNext, i++) {
11004 if (!memcmp(SrcPixel, ptr->pPixelData, m_nSrcSize)) {
11005 memcpy(DstPixel, &ptr->pPixelData[m_nSrcSamples], m_nDstSize);
11006 if (ptr != m_pFirst) {
11007 if (last)
11008 last->pNext = ptr->pNext;
11009
11010 ptr->pNext = m_pFirst;
11011 m_pFirst = ptr;
11012 }
11013 return true;
11014 }
11015 prev = last;
11016 last = ptr;
11017 }
11018
11019
11020 if (i < m_nCacheSize) {
11021 pixel = &m_pixelData[i * m_nTotalSamples];
11022
11023 ptr = &m_cache[i];
11024 ptr->pPixelData = pixel;
11025 ptr->pNext = m_pFirst;
11026 m_pFirst = ptr;
11027 }
11028 else {
11029 if (last) {
11030 if (prev)
11031 prev->pNext = NULL;
11032
11033 last->pNext = m_pFirst;
11034 m_pFirst = last;
11035 pixel = last->pPixelData;
11036 }
11037 else {
11038
11039 pixel = &m_pixelData[0];
11040 ptr = &m_cache[0];
11041 ptr->pPixelData = pixel;
11042 ptr->pNext = nullptr;
11043 m_pFirst = ptr;
11044 }
11045 }
11046
11047 T* dest = &pixel[m_nSrcSamples];
11048 memcpy(pixel, SrcPixel, m_nSrcSize);
11049
11050 return false;
11051}
11052
11053
11054template<class T>
11055void CIccMruCache<T>::Update(T* DstPixel)
11056{
11057 memcpy(&m_pFirst->pPixelData[m_nSrcSamples], DstPixel, m_nDstSize);
11058}
11059
11060
11061template class CIccMruCache<icFloatNumber>;
11062template class CIccMruCache<icUInt8Number>;
11063template class CIccMruCache<icUInt16Number>;
11064
11065
11066CIccApplyMruCmm::CIccApplyMruCmm(CIccMruCmm *pCmm) : CIccApplyCmm(pCmm)
11067{
11068 m_pCachedCmm = NULL;
11069 m_pCache = NULL;
11070}
11071
11079CIccApplyMruCmm::~CIccApplyMruCmm()
11080{
11081 if (m_pCache)
11082 delete m_pCache;
11083
11084}
11085
11100bool CIccApplyMruCmm::Init(CIccCmm *pCachedCmm,
icUInt16Number nCacheSize)
11101{
11102 m_pCachedCmm = pCachedCmm;
11103
11104 m_pCache = CIccMruCacheFloat::NewMruCache(m_pCmm->GetSourceSamples(), m_pCmm->GetDestSamples(), nCacheSize);
11105
11106 if (!m_pCache)
11107 return false;
11108
11109 return true;
11110}
11111
11127{
11128#if defined(_DEBUG)
11129 if (!m_pCache)
11131#endif
11132
11133 if (!m_pCache->Apply(DstPixel, SrcPixel)) {
11134
11135 m_pCachedCmm->Apply(DstPixel, SrcPixel);
11136
11137 m_pCache->Update(DstPixel);
11138 }
11139
11141}
11142
11159{
11161
11162#if defined(_DEBUG)
11163 if (!m_pCache)
11165#endif
11166
11167 for (k=0; k<nPixels;k++) {
11168 if (!m_pCache->Apply(DstPixel, SrcPixel)) {
11169 m_pCachedCmm->Apply(DstPixel, SrcPixel);
11170 m_pCache->Update(DstPixel);
11171 }
11172 SrcPixel += m_pCmm->GetSourceSamples();
11173 DstPixel += m_pCmm->GetDestSamples();
11174 }
11175
11177}
11178
11179
11180#ifdef USEREFICCMAXNAMESPACE
11181}
11182#endif
#define icSigLabPcsData
Definition icProfileHeader.h:939
unsigned char icUInt8Number
Definition icProfileHeader.h:250
#define icUnknownIntent
Definition icProfileHeader.h:1152
#define icSigBRDFDirect
Definition icProfileHeader.h:902
unsigned short icUInt16Number
Definition icProfileHeader.h:256
#define icSigRadiantSpectralPcsData
Definition icProfileHeader.h:943
long icInt32Number
Definition icProfileHeader.h:291
#define icSigSparseMatrixSpectralPcsData
Definition icProfileHeader.h:945
icProfileClassSignature
Definition icProfileHeader.h:951
@ icSigAbstractClass
Definition icProfileHeader.h:956
@ icSigColorEncodingClass
Definition icProfileHeader.h:959
@ icSigMaterialVisualizationClass
Definition icProfileHeader.h:962
@ icSigInputClass
Definition icProfileHeader.h:952
@ icSigMaterialLinkClass
Definition icProfileHeader.h:961
@ icSigNamedColorClass
Definition icProfileHeader.h:958
@ icSigMaterialIdentificationClass
Definition icProfileHeader.h:960
@ icSigLinkClass
Definition icProfileHeader.h:955
@ icIlluminantUnknown
Definition icProfileHeader.h:1191
#define icSigXYZPcsData
Definition icProfileHeader.h:940
icUInt16Number steps
Definition icProfileHeader.h:1469
icS15Fixed16Number Y
Definition icProfileHeader.h:1430
#define icGetColorSpaceType(sig)
Definition icProfileHeader.h:932
#define icSparseMatrixFloatNum
Definition icProfileHeader.h:1359
@ icSigMatrixElemType
Definition icProfileHeader.h:644
icColorSpaceSignature
Definition icProfileHeader.h:843
@ icSigLuvData
Definition icProfileHeader.h:848
@ icSigNamedData
Definition icProfileHeader.h:873
@ icSigCmykData
Definition icProfileHeader.h:855
@ icSigRgbData
Definition icProfileHeader.h:851
@ icSigHlsData
Definition icProfileHeader.h:854
@ icSig4colorData
Definition icProfileHeader.h:861
@ icSigYCbCrData
Definition icProfileHeader.h:849
@ icSigCmyData
Definition icProfileHeader.h:856
@ icSigGrayData
Definition icProfileHeader.h:852
@ icSig3colorData
Definition icProfileHeader.h:860
@ icSigHsvData
Definition icProfileHeader.h:853
@ icSigYxyData
Definition icProfileHeader.h:850
unsigned long icUInt32Number
Definition icProfileHeader.h:262
icFloat16Number start
Definition icProfileHeader.h:1467
icUInt32Number icSignature
Definition icProfileHeader.h:271
@ icSigUtf8TextType
Definition icProfileHeader.h:574
@ icSigTagArrayType
Definition icProfileHeader.h:563
@ icSigMultiProcessElementType
Definition icProfileHeader.h:550
@ icSigParametricCurveType
Definition icProfileHeader.h:552
@ icSigXYZType
Definition icProfileHeader.h:576
@ icSigCurveType
Definition icProfileHeader.h:533
@ icSigNamedColor2Type
Definition icProfileHeader.h:551
#define icSigUnknownData
Definition icProfileHeader.h:903
#define icVersionNumberV5
Definition icProfileHeader.h:193
icFloat16Number end
Definition icProfileHeader.h:1468
icSpectralColorSignature
Definition icProfileHeader.h:907
icS15Fixed16Number Z
Definition icProfileHeader.h:1431
icS15Fixed16Number X
Definition icProfileHeader.h:1429
@ icSigNamedColorArray
Definition icProfileHeader.h:618
@ icSigUtf8TextTypeArray
Definition icProfileHeader.h:620
#define icSigReflectanceSpectralPcsData
Definition icProfileHeader.h:941
#define icSigBRDFParameters
Definition icProfileHeader.h:901
@ icSigBToD0Tag
Definition icProfileHeader.h:408
@ icSigGrayTRCTag
Definition icProfileHeader.h:421
@ icSigBRDFMToB1Tag
Definition icProfileHeader.h:367
@ icSigBRDFMToB3Tag
Definition icProfileHeader.h:369
@ icSigBRDFDToB0Tag
Definition icProfileHeader.h:362
@ icSigAToB3Tag
Definition icProfileHeader.h:345
@ icSigBlueMatrixColumnTag
Definition icProfileHeader.h:348
@ icSigMaterialDefaultValuesTag
Definition icProfileHeader.h:426
@ icSigMToS3Tag
Definition icProfileHeader.h:436
@ icSigBrdfSpectralParameter0Tag
Definition icProfileHeader.h:354
@ icSigGreenTRCTag
Definition icProfileHeader.h:424
@ icSigAToM0Tag
Definition icProfileHeader.h:346
@ icSigMToB0Tag
Definition icProfileHeader.h:429
@ icSigAToB0Tag
Definition icProfileHeader.h:342
@ icSigMToB3Tag
Definition icProfileHeader.h:432
@ icSigBToA1Tag
Definition icProfileHeader.h:375
@ icSigDToB3Tag
Definition icProfileHeader.h:407
@ icSigBRDFAToB0Tag
Definition icProfileHeader.h:358
@ icSigDToB0Tag
Definition icProfileHeader.h:404
@ icSigBToD3Tag
Definition icProfileHeader.h:411
@ icSigBToA0Tag
Definition icProfileHeader.h:374
@ icSigMToS0Tag
Definition icProfileHeader.h:433
@ icSigRedTRCTag
Definition icProfileHeader.h:463
@ icSigHToS1Tag
Definition icProfileHeader.h:418
@ icSigBToD1Tag
Definition icProfileHeader.h:409
@ icSigBlueTRCTag
Definition icProfileHeader.h:349
@ icSigMToB1Tag
Definition icProfileHeader.h:430
@ icSigHToS0Tag
Definition icProfileHeader.h:417
@ icSigGreenMatrixColumnTag
Definition icProfileHeader.h:423
@ icSigMediaWhitePointTag
Definition icProfileHeader.h:439
@ icSigBRDFMToS3Tag
Definition icProfileHeader.h:373
@ icSigAToB1Tag
Definition icProfileHeader.h:343
@ icSigBToA3Tag
Definition icProfileHeader.h:377
@ icSigBRDFMToS1Tag
Definition icProfileHeader.h:371
@ icSigBRDFMToS0Tag
Definition icProfileHeader.h:370
@ icSigPreview0Tag
Definition icProfileHeader.h:448
@ icSigNamedColor2Tag
Definition icProfileHeader.h:445
@ icSigRedMatrixColumnTag
Definition icProfileHeader.h:462
@ icSigGamutTag
Definition icProfileHeader.h:412
@ icSigMToA0Tag
Definition icProfileHeader.h:428
@ icSigMToS1Tag
Definition icProfileHeader.h:434
@ icSigDToB1Tag
Definition icProfileHeader.h:405
@ icSigBrdfColorimetricParameter0Tag
Definition icProfileHeader.h:350
@ icSigMaterialTypeArrayTag
Definition icProfileHeader.h:427
@ icSigBRDFMToB0Tag
Definition icProfileHeader.h:366
icRenderingIntent
Definition icProfileHeader.h:1142
@ icPerceptual
Definition icProfileHeader.h:1143
@ icRelativeColorimetric
Definition icProfileHeader.h:1144
@ icAbsoluteColorimetric
Definition icProfileHeader.h:1147
#define icMCSNeedsSubsetTrue
Definition icProfileHeader.h:225
#define icSigBiDirReflectanceSpectralPcsData
Definition icProfileHeader.h:944
@ icSigBrdfTransformMbr
Definition icProfileHeader.h:680
#define icSigTransmissionSpectralPcsData
Definition icProfileHeader.h:942
#define icSigGamutData
Definition icProfileHeader.h:900
Definition icProfileHeader.h:1428
Definition icProfileHeader.h:1466
icXformLutType
CMM Xform LUT types.
Definition IccCmm.h:125
@ icXformLutNamedColor
Definition IccCmm.h:127
@ icXformLutBRDFDirect
Definition IccCmm.h:132
@ icXformLutBRDFMcsParam
Definition IccCmm.h:133
@ icXformLutGamut
Definition IccCmm.h:129
@ icXformLutColorimetric
Definition IccCmm.h:135
@ icXformLutMCS
Definition IccCmm.h:134
@ icXformLutColor
Definition IccCmm.h:126
@ icXformLutSpectral
Definition IccCmm.h:136
@ icXformLutPreview
Definition IccCmm.h:128
@ icXformLutBRDFParam
Definition IccCmm.h:131
#define icPerceptualRefWhiteX
Definition IccCmm.h:143
icXformInterp
CMM Interpolation types.
Definition IccCmm.h:113
@ icInterpLinear
Definition IccCmm.h:114
#define icPerceptualRefBlackZ
Definition IccCmm.h:141
#define icPerceptualRefBlackY
Definition IccCmm.h:140
#define icPerceptualRefWhiteZ
Definition IccCmm.h:145
icStatusCMM
CMM return status values.
Definition IccCmm.h:90
@ icCmmStatBadLutType
Definition IccCmm.h:103
@ icCmmStatInvalidProfile
Definition IccCmm.h:95
@ icCmmStatTooManySamples
Definition IccCmm.h:108
@ icCmmStatProfileMissingTag
Definition IccCmm.h:98
@ icCmmStatBadSpaceLink
Definition IccCmm.h:94
@ icCmmStatBadMCSLink
Definition IccCmm.h:109
@ icCmmStatIncorrectApply
Definition IccCmm.h:100
@ icCmmStatUnsupportedPcsLink
Definition IccCmm.h:105
@ icCmmStatBadColorEncoding
Definition IccCmm.h:101
@ icCmmStatCantOpenProfile
Definition IccCmm.h:93
@ icCmmStatBadConnection
Definition IccCmm.h:106
@ icCmmStatBadXform
Definition IccCmm.h:96
@ icCmmStatBad
Definition IccCmm.h:91
@ icCmmStatBadTintXform
Definition IccCmm.h:107
@ icCmmStatColorNotFound
Definition IccCmm.h:99
@ icCmmStatOk
Definition IccCmm.h:92
@ icCmmStatIdentityXform
Definition IccCmm.h:104
@ icCmmStatInvalidLut
Definition IccCmm.h:97
@ icCmmStatAllocErr
Definition IccCmm.h:102
icMCSConnectionType
Definition IccCmm.h:118
@ icNoMCS
Definition IccCmm.h:119
@ icToMCS
Definition IccCmm.h:120
@ icFromMCS
Definition IccCmm.h:121
#define icPerceptualRefWhiteY
Definition IccCmm.h:144
@ icXformTypeMpe
Definition IccCmm.h:154
@ icXformTypeMatrixTRC
Definition IccCmm.h:149
@ icXformTypeNDLut
Definition IccCmm.h:152
@ icXformTypeMonochrome
Definition IccCmm.h:155
@ icXformType3DLut
Definition IccCmm.h:150
@ icXformType4DLut
Definition IccCmm.h:151
@ icXformTypeNamedColor
Definition IccCmm.h:153
#define icPerceptualRefBlackX
Definition IccCmm.h:139
#define stricmp
Definition IccProfLibConf.h:149
CIccCurve * LPIccCurve
Definition IccTagLut.h:112
icFloatNumber deviceCoords[icAny]
Definition IccTagBasic.h:567
icFloatNumber pcsCoords[3]
Definition IccTagBasic.h:566
class ICCPROFLIB_API CIccProfile
Definition IccPcc.h:80
CIccProfile * OpenIccProfile(const icChar *szFilename, bool bUseSubProfile)
Definition IccProfile.cpp:3387
unsigned char icUChar
Definition IccDefs.h:111
float icFloatNumber
Definition IccDefs.h:101
icUInt16Number icU1Fixed15Number
Definition IccDefs.h:82
char icChar
Definition IccDefs.h:110
#define icSigLab2Data
Definition IccDefs.h:94
#define icNearRange
Definition IccMatrixMath.h:82
ICCPROFLIB_API icUInt32Number icGetSpectralSpaceSamples(const icHeader *pHdr)
Definition IccUtil.cpp:1367
ICCPROFLIB_API icFloatNumber icU8toF(icUInt8Number num)
Definition IccUtil.cpp:738
ICCPROFLIB_API bool icIsSpaceCLR(icColorSpaceSignature sig)
Definition IccUtil.cpp:262
ICCPROFLIB_API icUInt8Number icFtoU8(icFloatNumber num)
Definition IccUtil.cpp:724
ICCPROFLIB_API icU1Fixed15Number icDtoUSF(icFloatNumber num)
Definition IccUtil.cpp:587
ICCPROFLIB_API icS15Fixed16Number icDtoF(icFloatNumber num)
Definition IccUtil.cpp:545
ICCPROFLIB_API void icXyzToPcs(icFloatNumber *XYZ)
Definition IccUtil.cpp:941
ICCPROFLIB_API void icXYZtoLab(icFloatNumber *Lab, const icFloatNumber *XYZ=NULL, const icFloatNumber *WhiteXYZ=NULL)
Definition IccUtil.cpp:846
ICCPROFLIB_API icFloatNumber icFtoD(icS15Fixed16Number num)
Definition IccUtil.cpp:559
ICCPROFLIB_API void icLabToPcs(icFloatNumber *Lab)
Definition IccUtil.cpp:927
ICCPROFLIB_API icUInt32Number icGetSpaceSamples(icColorSpaceSignature sig)
Definition IccUtil.cpp:1303
ICCPROFLIB_API icUInt16Number icFtoU16(icFloatNumber num)
Definition IccUtil.cpp:745
ICCPROFLIB_API void icXyzFromPcs(icFloatNumber *XYZ)
Here are some conversion routines to convert to regular XYZ encoding.
Definition IccUtil.cpp:934
ICCPROFLIB_API icFloat16Number icFtoF16(icFloat32Number num)
Definition IccUtil.cpp:673
ICCPROFLIB_API icUInt8Number icABtoU8(icFloatNumber num)
Definition IccUtil.cpp:766
ICCPROFLIB_API bool icMatrixInvert3x3(icFloatNumber *matrix)
Definition IccUtil.cpp:391
bool ICCPROFLIB_API icSameSpectralRange(const icSpectralRange &rng1, const icSpectralRange &rng2)
Definition IccUtil.cpp:1399
ICCPROFLIB_API icFloatNumber icU16toF(icUInt16Number num)
Definition IccUtil.cpp:759
ICCPROFLIB_API void icLabtoXYZ(icFloatNumber *XYZ, const icFloatNumber *Lab=NULL, const icFloatNumber *WhiteXYZ=NULL)
Definition IccUtil.cpp:830
ICCPROFLIB_API icFloatNumber icU8toAB(icUInt8Number num)
Definition IccUtil.cpp:777
ICCPROFLIB_API void icLabFromPcs(icFloatNumber *Lab)
Here are some conversion routines to convert to regular Lab encoding.
Definition IccUtil.cpp:919
ICCPROFLIB_API icFloatNumber icUSFtoD(icU1Fixed15Number num)
Definition IccUtil.cpp:601
#define icUtf8StrCmp(x, y)
Definition IccUtil.h:188
ICCPROFLIB_API icFloat32Number icF16toF(icFloat16Number num)
Definition IccUtil.cpp:629
#define icNotZero(v)
Definition IccUtil.h:89
static __inline bool IsSpaceSpectralPCS(icUInt32Number sig)
Definition IccCmm.cpp:104
#define ICCPCSSTEPDUMPFMT
Definition IccCmm.cpp:129
#define IsCompatSpace(x, y)
Definition IccCmm.cpp:124
static icFloatNumber RGBClip(icFloatNumber v, CIccCurve *pCurve)
Definition IccCmm.cpp:5300
#define IsCompatSpacePCS(x, y)
Definition IccCmm.cpp:126
icFloatNumber icD50XYZ[3]
Definition IccUtil.cpp:782
static icFloatNumber XYZScale(icFloatNumber v)
Definition IccCmm.cpp:5289
#define IsSpaceColorimetricPCS(x)
Definition IccCmm.cpp:116
#define IsNChannelCompat(x, y)
Definition IccCmm.cpp:122
#define ICCDUMPPIXEL(n, pix)
Definition IccCmm.cpp:3376
static icFloatNumber XYZDescale(icFloatNumber v)
Definition IccCmm.cpp:5295
#define IsSpacePCS(x)
Definition IccCmm.cpp:118
@ icElemInterpLinear
Definition IccTagMPE.h:94
icStatusEncConvert ICCPROFLIB_API icConvertEncodingProfile(CIccProfilePtr &newIcc, CIccProfile *pEncodeIcc)
Definition IccEncoding.cpp:538
@ icEncConvertOk
Definition IccEncoding.h:75
static icFloatNumber UnitClip(icFloatNumber v)
Definition iccApplyProfiles.cpp:83
Definition IccArrayBasic.h:144
CIccStructNamedColor * FindColor(const icChar *szColor) const
Definition IccArrayBasic.cpp:303
bool GetSpectralTint(icFloatNumber *dstColor, const CIccStructNamedColor *pColor, icFloatNumber tint=1.0f, icNamedColorlMemberSignature sig=icSigNmclSpectralDataMbr) const
Definition IccArrayBasic.cpp:461
CIccStructNamedColor * FindSpectralColor(const icFloatNumber *pSpec, icFloatNumber dMinRms=1000.0) const
Definition IccArrayBasic.cpp:387
void SetColorSpaces(icColorSpaceSignature csPcs, icColorSpaceSignature csDevice, icSpectralColorSignature csSpectralPCS=icSigNoSpectralData, const icSpectralRange *pSpectralRange=NULL, const icSpectralRange *pBiSPectralRange=NULL)
Definition IccArrayBasic.cpp:261
CIccStructNamedColor * FindDeviceColor(const icFloatNumber *pDevColor) const
Definition IccArrayBasic.cpp:315
CIccStructNamedColor * FindPcsColor(const icFloatNumber *pPCS, icFloatNumber dMinDE=1000.0) const
Definition IccArrayBasic.cpp:349
bool GetDeviceTint(icFloatNumber *dstColor, const CIccStructNamedColor *pColor, icFloatNumber tint=1.0f, icNamedColorlMemberSignature sig=icSigNmclDeviceDataMbr) const
Definition IccArrayBasic.cpp:424
bool GetPcsTint(icFloatNumber *dstColor, const CIccStructNamedColor *pColor, icFloatNumber tint=1.0f, icNamedColorlMemberSignature sig=icSigNmclPcsDataMbr) const
Definition IccArrayBasic.cpp:443
CIccTag * GetElem(icSignature sigElem) const
Definition IccStructBasic.cpp:172
Definition IccStructBasic.h:127
std::string getName() const
Definition IccStructBasic.cpp:457
Definition IccStructBasic.h:161
Definition IccTagComposite.h:226
bool AreAllOfType(icTagTypeSignature sigTagType)
Definition IccTagComposite.cpp:1145
IIccArray * GetArrayHandler()
Definition IccTagComposite.cpp:1624
CIccTag * GetIndex(icUInt32Number index) const
Definition IccTagComposite.cpp:1544
icUInt32Number GetSize() const
Returns the size of the data array.
Definition IccTagComposite.h:260
virtual icArraySignature GetTagArrayType() const
Definition IccTagComposite.h:238
static CIccXform * CreateXform(icXformType xformType, CIccTag *pTag=NULL, CIccCreateXformHintManager *pHintManager=NULL)
Definition IccXformFactory.h:185
Definition IccMpeBasic.h:600
icFloatNumber * GetConstants() const
Definition IccMpeBasic.h:619
virtual bool Begin(icElemInterp nInterp, CIccTagMultiProcessElement *pMPE)
Definition IccMpeBasic.cpp:5204
icFloatNumber * GetMatrix() const
Definition IccMpeBasic.h:618
bool GetApplyConstants() const
Definition IccMpeBasic.h:620
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)
Definition IccPcc.cpp:198
bool isStandardPcc()
Definition IccPcc.cpp:139
virtual void getNormIlluminantXYZ(icFloatNumber *pXYZ)=0
bool isEquivalentPcc(IIccProfileConnectionConditions &IPCC)
Definition IccPcc.cpp:79
bool Attach(icUInt8Number *pData, icUInt32Number nSize, bool bWrite=false)
Definition IccIO.cpp:686
Definition IccSparseMatrix.h:154
static icUInt32Number MemSize(icUInt32Number nMaxEntries, icUInt16Number nRows, icUInt8Number nTypeSize)
Definition IccSparseMatrix.cpp:505
Definition IccTagBasic.h:108
virtual icTagTypeSignature GetType() const
Definition IccTagBasic.h:131
virtual bool IsSupported()
Definition IccTagBasic.h:153
virtual bool IsMBBType()
Definition IccTagBasic.h:136
virtual bool IsNumArrayType() const
Definition IccTagBasic.h:137
virtual icArraySignature GetTagArrayType() const
Definition IccTagBasic.h:133
Definition IccTagBasic.h:322
Definition IccTagBasic.h:582
icInt32Number FindDeviceColor(icFloatNumber *pDevColor) const
Definition IccTagBasic.cpp:3299
bool GetColorName(std::string &sColorName, icInt32Number index) const
Definition IccTagBasic.cpp:3348
icInt32Number FindColor(const icChar *szColor) const
Definition IccTagBasic.cpp:3255
icColorSpaceSignature GetPCS() const
Definition IccTagBasic.h:633
icUInt32Number GetDeviceCoords() const
Definition IccTagBasic.h:629
icColorSpaceSignature GetDeviceSpace() const
Definition IccTagBasic.h:634
icInt32Number FindCachedPCSColor(icFloatNumber *pPCS, icFloatNumber dMinDE=1000.0) const
Definition IccTagBasic.cpp:3180
SIccNamedColorEntry * GetEntry(icUInt32Number index) const
Definition IccTagBasic.h:626
Definition IccTagBasic.h:668
Definition IccTagBasic.h:791
virtual bool GetValues(icFloatNumber *DstVector, icUInt32Number nStart=0, icUInt32Number nVectorSize=1) const =0
Definition IccTagBasic.h:1692
const icFloatNumber * getObserver(icSpectralRange &observerRange) const
Definition IccTagBasic.cpp:11569
icFloatNumber getIlluminantCCT() const
Definition IccTagBasic.h:1713
icIlluminant getStdIllumiant() const
Definition IccTagBasic.h:1712
const icFloatNumber * getIlluminant(icSpectralRange &illumRange) const
Definition IccTagBasic.cpp:11405
icFloatNumber * applyRangeToObserver(const icSpectralRange &newRange) const
Definition IccTagBasic.cpp:11301
Definition IccTagLut.h:91
virtual icFloatNumber Apply(icFloatNumber v) const
Definition IccTagLut.h:101
virtual void Begin()
Definition IccTagLut.h:100
icFloatNumber Find(icFloatNumber v)
Definition IccTagLut.h:103
Definition IccTagLut.h:128
Definition IccTagLut.h:302
Definition IccTagLut.h:326
CIccApplyCLUT * GetNewApply()
Definition IccTagLut.cpp:2403
Definition IccTagLut.h:428
Definition IccTagMPE.h:146
virtual icUInt16Number NumInputChannels() const
Definition IccTagMPE.h:159
virtual icUInt16Number NumOutputChannels() const
Definition IccTagMPE.h:160
virtual icElemTypeSignature GetType() const =0
Definition IccTagMPE.h:358
icUInt16Number NumInputChannels() const
Definition IccTagMPE.h:393
icUInt16Number NumOutputChannels() const
Definition IccTagMPE.h:394
virtual CIccTag * NewCopy() const
Definition IccTagMPE.h:363
virtual void Apply(CIccApplyTagMpe *pApply, icFloatNumber *pDestPixel, const icFloatNumber *pSrcPixel) const
Definition IccTagMPE.cpp:1440
icUInt32Number NumElements() const
Definition IccTagMPE.h:398
CIccMultiProcessElement * GetElement(int nIndex)
Definition IccTagMPE.cpp:1189