87 case icEncodeUnitFloat:
107static const char*
clrEncNames[] = {
"value",
"float",
"unitFloat",
"percent",
108 "8Bit",
"16Bit",
"16BitV2",
nullptr };
109static icFloatColorEncoding
clrEncValues[] = { icEncodeValue, icEncodeFloat, icEncodeUnitFloat, icEncodePercent,
110 icEncode8Bit, icEncode16Bit, icEncode16BitV2, icEncodeUnknown };
146static const char*
fileEncNames[] = {
"8Bit",
"16Bit",
"float",
"sameAsSource",
nullptr};
147static icFloatColorEncoding
fileEncValues[] = { icEncode8Bit, icEncode16Bit, icEncodeFloat, icEncodeUnknown, icEncode8Bit };
197 if (str ==
"colorData")
199 else if (str ==
"legacy")
201 else if (str ==
"it8")
242 const char *colon = strchr(args[1],
':');
247 colon = strchr(colon,
':');
267 if (j.find(
"srcSpace")!=j.end())
318 else if (j.is_string()) {
319 std::string str = j.get<std::string>();
322 else if (str ==
"false")
324 else if (str ==
"sameAsSource")
357 int n = atoi(args[2]);
392 j[
szName] =
"sameAsSoure";
460 int n = atoi(args[1]);
462 int o = atoi(args[3]);
500 std::string linkType;
502 if (!
stricmp(linkType.c_str(),
"cubeFile"))
504 else if (!
stricmp(linkType.c_str(),
"iccDeviceLinkV5"))
526 j[
"linkType"] =
"cubeFile";
531 j[
"linkType"] =
"iccDeviceLinkV4";
534 j[
"linkType"] =
"iccDeviceLinkV5";
568 std::string str = j.get<std::string>();
569 if (str ==
"perceptual")
571 else if (str ==
"relative")
573 else if (str ==
"saturation")
575 else if (str ==
"absolute")
580 else if (j.is_number_integer()) {
589static const char*
icTranNames[] = {
"default",
"named",
"colorimetric",
"spectral",
590 "MCS",
"preview",
"gamut",
"brdfParam",
591 "brdfDirect",
"brdfMcsParam" ,
nullptr };
606 for (
auto e = j.begin(); e != j.end(); e++) {
607 if (e->is_object()) {
667 for (
auto e = map.begin(); e != map.end(); e++) {
670 var[
"value"] = e->second;
673 return j.is_array() && j.size() > 0;
682 j[
"iccEnvVars"] = iccMap;
687 j[
"pccEnvVars"] = pccMap;
732 while (nArg >= 2 && !
strnicmp(args[0],
"-ENV:", 5)) {
739 pProf->m_iccEnvVars[
sig] = val;
744 pProf->m_iccFile = args[0];
746 if (!
stricmp(args[0],
"-embedded")) {
747 pProf->m_iccFile.clear();
752 int nIntent = atoi(args[1]);
754 pProf->m_useD2BxB2Dx =
true;
755 pProf->m_useHToS = (nIntent / 100000) != 0;
756 pProf->m_useV5SubProfile = (nIntent / 10000) != 0;
757 nIntent = nIntent % 10000;
758 pProf->m_adjustPcsLuminance = nIntent / 1000 != 0;
759 nIntent = nIntent % 1000;
760 nType = abs(nIntent) / 10;
761 nIntent = nIntent % 10;
764 pProf->m_useD2BxB2Dx =
false;
767 else if (nType == 4) {
768 pProf->m_useBPC =
true;
774 pProf->m_interpolation = interpolation;
781 if (nArg >= 2 && !
stricmp(args[0],
"-PCC")) {
782 pProf->m_pccFile = args[1];
801 for (
auto p = j.begin(); p != j.end(); p++) {
802 if (p->is_object()) {
804 if (pProf->fromJson(*p)) {
834 bool open(
const char* szFilename) {
837 m_f =
new std::ifstream(szFilename);
838 return m_f !=
nullptr;
859 else if (c ==
'\r') {
863 else if (c ==
'\t') {
884 if (line[0] == szToken)
916 while (*ptr && nNumbersRead < nSamples) {
917 while (*ptr ==
' ' || *ptr ==
'\t' || *ptr ==
'\n' || *ptr ==
'\r')
919 if (sscanf(ptr,
ICFLOATFMT, &pData[nNumbersRead]) == 1)
923 while (*ptr && *ptr !=
' ' && *ptr !=
'\t' && *ptr !=
'n' && *ptr !=
'\r')
927 if (nNumbersRead != nSamples) {
940 while (*ptr ==
' ') ptr++;
941 if ((*ptr >=
'0' && *ptr <=
'9') || *ptr ==
'.') {
944 while (*ptr && *ptr !=
' ') ptr++;
957 if (strncmp(pString,
"{ \"", 3))
960 icChar* ptr = strstr(pString,
"\" }");
970 strncpy(pName, pString + 3, nNameLen);
971 pName[nNameLen] =
'\0';
982 std::ifstream InputData(filename);
991 InputData.getline(tempBuf,
sizeof(tempBuf));
994 for (i = 0; (i < 4 || tempBuf[i + 1] !=
'\'') && i < 6; i++) {
995 ColorSig[i] = tempBuf[i + 1];
1010 InputData.getline(tempBuf,
sizeof(tempBuf));
1011 sscanf(tempBuf,
"%s", tempBuf);
1014 m_encoding = CIccCmm::GetFloatColorEncoding(tempBuf);
1019 char SrcNameBuf[256];
1023 while (!InputData.eof()) {
1028 InputData.getline(tempBuf,
sizeof(tempBuf));
1032 data->m_name = SrcNameBuf;
1034 icChar* numptr = strstr(tempBuf,
"\" }");
1041 data->m_values.push_back(tint);
1045 InputData.getline(tempBuf,
sizeof(tempBuf));
1049 for (
int n = 0; n < nSamples; n++) {
1050 data->m_values.push_back(Pixel[n]);
1077static void setSampleIndex(std::vector<icValueVector>& samples,
int index,
const char* szFmt,
const char** szChannels)
1079 size_t nPos = samples.size() - 1;
1080 for (
int i = 0; i < samples[nPos].size(); i++) {
1081 if (!strcmp(szFmt, szChannels[i])) {
1082 samples[nPos][i].nIndex = index;
1094 if (!f.
open(filename))
1097 std::vector<std::string> line;
1103 if (line.size() >= 2) {
1104 nFields = atoi(line[1].c_str());
1111 if (line.size() != nFields)
1114 std::string lastSpace;
1115 std::vector<icValueVector> samples;
1116 std::vector<std::string> spaces;
1117 std::vector<icIndexName> names;
1125 for (
auto fmt = line.begin(); fmt != line.end(); fmt++, index++) {
1126 if (*fmt ==
"SAMPLE_ID") {
1129 else if (*fmt ==
"SAMPLE_NAME") {
1134 const char* szFmt = fmt->c_str();
1135 if (!strncmp(szFmt,
"SRC_", 4)) {
1139 if (!strcmp(szFmt,
"NAME")) {
1143 else if (!strncmp(szFmt,
"TINT", 4)) {
1145 if (space != lastSpace) {
1147 val[0].nIndex = index;
1149 samples.push_back(val);
1153 else if (!strncmp(szFmt,
"RGB_", 4)) {
1156 if (space != lastSpace) {
1160 samples.push_back(val);
1161 spaces.push_back(space);
1163 const char* szChannels[] = {
"R",
"G",
"B" };
1166 else if (!strncmp(szFmt,
"CMYK_", 5)) {
1169 if (space != lastSpace) {
1173 spaces.push_back(space);
1175 const char* szChannels[] = {
"C",
"M",
"Y",
"K" };
1178 else if (!strncmp(szFmt,
"LAB_", 4)) {
1181 if (space != lastSpace) {
1185 samples.push_back(val);
1186 spaces.push_back(space);
1188 const char* szChannels[] = {
"L",
"A",
"B" };
1191 else if (!strncmp(szFmt,
"XYZ_", 4)) {
1194 if (space != lastSpace) {
1198 samples.push_back(val);
1199 spaces.push_back(space);
1201 const char* szChannels[] = {
"X",
"Y",
"Z" };
1206 if (sscanf(szFmt,
"%uCOLOR_", &nColor) && nColor >= 1) {
1208 sprintf(buf,
"%uCOLOR", nColor);
1211 if (space != lastSpace) {
1215 samples.push_back(val);
1216 spaces.push_back(space);
1219 szFmt = strchr(szFmt,
'_');
1222 int nChannel = atoi(szFmt);
1223 size_t last = samples.size() - 1;
1224 if (nChannel > 0 && samples[last].size() >= nChannel) {
1225 samples[samples.size() - 1][nChannel - 1].nIndex = index;
1240 if (line.size() > 1) {
1241 nSets = atoi(line[1].c_str());
1252 if (nId >= 0 && nId < line.size()) {
1253 pData->m_index = atoi(line[nId].c_str());
1255 else if (nLabel >= 0 && nLabel < line.size()) {
1256 pData->m_label = line[nLabel];
1259 if (names.size() > 0) {
1260 if (names[0].second ==
"NAME") {
1261 if (names[0].first >= 0)
1262 pData->m_name = line[names[0].first];
1263 if (names.size() > 1) {
1264 if (names[1].first >= 0)
1265 pData->m_srcName = line[names[1].first];
1268 else if (names[0].second ==
"SRC_NAME") {
1269 if (names[0].first >= 0)
1270 pData->m_srcName = line[names[0].first];
1271 if (names.size() > 1) {
1272 if (names[1].first >= 0)
1273 pData->m_name = line[names[1].first];
1279 for (nValueIdx = 0; nValueIdx < samples.size(); nValueIdx++) {
1280 if (samples[nValueIdx][0].space ==
m_space)
1283 if (nValueIdx != samples.size()) {
1284 for (
int i = 0; i < samples[nValueIdx].size(); i++) {
1285 int nPos = samples[nValueIdx][i].nIndex;
1286 if (nPos < line.size()) {
1287 pData->m_values.push_back((
icFloatNumber)atof(line[nPos].c_str()));
1292 for (nValueIdx = 0; nValueIdx < spaces.size(); nValueIdx++) {
1293 if (strncmp(spaces[nValueIdx].c_str(),
"SRC_", 4))
1296 if (nValueIdx != spaces.size() && nValueIdx < samples.size()) {
1297 m_space = samples[nValueIdx][0].space;
1298 for (
int j = 0; j < samples[nValueIdx].size(); j++) {
1299 int nPos = samples[nValueIdx][j].nIndex;
1300 if (nPos < line.size()) {
1301 pData->m_values.push_back((
icFloatNumber)atof(line[nPos].c_str()));
1308 for (nSrcIndex = 0; nSrcIndex < samples.size(); nSrcIndex++) {
1309 if (samples[nSrcIndex][0].space ==
m_srcSpace)
1312 if (nSrcIndex != samples.size() && nSrcIndex != nValueIdx) {
1313 for (
int i = 0; i < samples[nSrcIndex].size(); i++) {
1314 int nPos = samples[nSrcIndex][i].nIndex;
1315 if (nPos < line.size()) {
1316 pData->m_values.push_back((
icFloatNumber)atof(line[nPos].c_str()));
1321 for (nSrcIndex = 0; nSrcIndex < spaces.size(); nSrcIndex++) {
1322 if (!strncmp(spaces[nValueIdx].c_str(),
"SRC_", 4))
1325 if (nSrcIndex != spaces.size() && nSrcIndex < samples.size()) {
1327 for (
int j = 0; j < samples[nValueIdx].size(); j++) {
1328 int nPos = samples[nValueIdx][j].nIndex;
1329 if (nPos < line.size()) {
1330 pData->m_srcValues.push_back((
icFloatNumber)atof(line[nPos].c_str()));
1335 for (nSrcIndex = 0; nSrcIndex < samples.size(); nSrcIndex++) {
1336 if (nSrcIndex != nValueIdx)
1339 if (nSrcIndex < samples.size()) {
1341 for (
int j = 0; j < samples[nValueIdx].size(); j++) {
1342 int nPos = samples[nValueIdx][j].nIndex;
1343 if (nPos < line.size()) {
1344 pData->m_srcValues.push_back((
icFloatNumber)atof(line[nPos].c_str()));
1351 if (pData->m_values.size() || pData->m_srcValues.size() || pData->m_name.size() || pData->m_srcName.size())
1356 }
while (!f.
isEOF());
1358 return m_data.size() == nSets;
1379 if (j.find(
"data")!=j.end()) {
1380 json data = j[
"data"];
1381 if (data.is_array()) {
1382 for (
auto d = data.begin(); d != data.end(); d++) {
1383 if (d->is_object()) {
1385 if (entry->fromJson(*d)) {
1404 sprintf(fmt,
" %%.%df", nPrecision);
1406 sprintf(fmt,
" %%%d.%df", nDigits, nPrecision);
1408 if (!filename || !filename[0])
1411 f = fopen(filename,
"wt");
1419 out +=
"Data Format\n";
1420 fwrite(out.c_str(), out.size(), 1, f);
1422 sprintf(tempBuf,
"%s\t; ", CIccCmm::GetFloatColorEncoding(
m_encoding));
1424 out +=
"Encoding\n\n";
1425 fwrite(out.c_str(), out.size(), 1, f);
1427 out =
";Source Data Format: ";
1430 fwrite(out.c_str(), out.size(), 1, f);
1432 out =
";Source Data Encoding: ";
1433 sprintf(tempBuf,
"%s\n", CIccCmm::GetFloatColorEncoding(
m_srcEncoding));
1435 fwrite(out.c_str(), out.size(), 1, f);
1437 fprintf(f,
";Source data is after semicolon\n");
1439 fprintf(f,
"\n;Profiles applied\n");
1440 for (
auto pIter = pProfiles->
m_profiles.begin(); pIter != pProfiles->
m_profiles.end(); pIter++) {
1448 fprintf(f,
"; %s\n", pProf->
m_iccFile.c_str());
1454 for (
auto dIter =
m_data.begin(); dIter !=
m_data.end(); dIter++) {
1461 fprintf(f,
"; %s\n", l->c_str());
1465 if (pData->
m_name.size()) {
1466 fprintf(f,
"{ \"%s\" }\t;", pData->
m_name.c_str());
1469 for (
int i = 0; i < pData->
m_values.size(); i++) {
1470 fprintf(f, fmt, pData->
m_values[i]);
1476 fprintf(f,
"{ \"%s\" }", pData->
m_srcName.c_str());
1482 for (
int i = 0; i < pData->
m_srcValues.size(); i++) {
1514 sprintf(buf,
"%dCOLOR", nSamples);
1522 std::string tabStr =
"\t";
1528 if (nFields) dataFormat += tabStr;
1529 dataFormat += prefix +
"RGB_R";
1530 dataFormat += tabStr + prefix +
"RGB_G";
1531 dataFormat += tabStr + prefix +
"RGB_B";
1532 nFields += nSamples;
1536 if (nFields) dataFormat += tabStr;
1537 dataFormat += prefix +
"CMYK_C";
1538 dataFormat += tabStr + prefix +
"CMYK_M";
1539 dataFormat += tabStr + prefix +
"CMYK_Y";
1540 dataFormat += tabStr + prefix +
"CMYK_K";
1541 nFields += nSamples;
1546 if (nFields) dataFormat += tabStr;
1547 dataFormat += prefix +
"LAB_L";
1548 dataFormat += tabStr + prefix +
"LAB_A";
1549 dataFormat += tabStr + prefix +
"LAB_B";
1550 nFields += nSamples;
1555 if (nFields) dataFormat += tabStr;
1556 dataFormat += prefix +
"XYZ_X";
1557 dataFormat += tabStr + prefix +
"XYZ_Y";
1558 dataFormat += tabStr + prefix +
"XYZ_Z";
1563 if (nFields) dataFormat += tabStr;
1564 dataFormat += prefix +
"TINT";
1565 nFields += nSamples;
1569 if (nFields) dataFormat += tabStr;
1570 for (
int i = 0; i < nSamples; i++) {
1571 sprintf(buf,
"%dCOLOR_%d", nSamples, i + 1);
1573 dataFormat += tabStr;
1576 nFields += nSamples;
1589 sprintf(fmt,
" %%.%df", nPrecision);
1591 sprintf(fmt,
" %%%d.%df", nDigits, nPrecision);
1593 auto first =
m_data.begin();
1596 std::string dataFormat;
1598 bool bShowIndex =
false;
1599 bool bShowLabel =
false;
1600 bool bShowSrcName =
false;
1601 bool bShowSrcValues =
false;
1602 bool bShowName =
false;
1603 bool bShowValues =
false;
1605 int nSrcSamples = 0, nDstSamples = 0;
1608 dataFormat =
"INDEX";
1614 if (nFields) dataFormat+=
"\t";
1615 dataFormat +=
"SAMPLE_ID";
1622 if (pEntry->
m_name.size()) {
1623 if (nFields) dataFormat +=
"\t";
1624 dataFormat +=
"NAME";
1636 if (nFields) dataFormat +=
"\t";
1638 dataFormat +=
"SRC_";
1639 dataFormat +=
"NAME";
1641 bShowSrcName =
true;
1647 bShowSrcValues =
true;
1653 if (!filename || !filename[0])
1656 f = fopen(filename,
"wt");
1661 fprintf(f,
"CGATS.17\n");
1662 fprintf(f,
"ORIGINATOR\t\"DemoIccMAX\"\n");
1663 fprintf(f,
"FILE_DESCRIPTOR\t\"Color Data\"\n");
1665 fprintf(f,
"NUMBER_OF_FIELDS\t%d\n", nFields);
1666 fprintf(f,
"BEGIN_DATA_FORMAT\n");
1667 fprintf(f,
"%s\n", dataFormat.c_str());
1668 fprintf(f,
"END_DATA_FORMAT\n");
1669 fprintf(f,
"NUMBER_OF_SETS\t%u\n", (
int)
m_data.size());
1674 fprintf(f,
"BEGIN_DATA\n");
1675 for (
auto e =
m_data.begin(); e !=
m_data.end(); e++) {
1683 sprintf(buf,
"%d", pEntry->
m_index);
1688 if (line.size()) line +=
"\t";
1696 if (line.size()) line +=
"\t";
1697 if (!pEntry->
m_name.size())
1704 if (line.size()) line +=
"\t";
1705 for (
int i = 0; i < nDstSamples; i++) {
1707 sprintf(buf, fmt, v);
1715 if (line.size()) line +=
"\t";
1722 if (bShowSrcValues) {
1723 if (line.size()) line +=
"\t";
1724 for (
int i = 0; i < nSrcSamples; i++) {
1726 sprintf(buf, fmt, v);
1733 fprintf(f,
"%s\n", line.c_str());
1735 fprintf(f,
"END_DATA\n");
1752 for (
auto e =
m_data.begin(); e !=
m_data.end(); e++) {
1759 if (entry.is_object())
1760 data.push_back(entry);
1762 if (data.is_array() && data.size()) {
icXformLutType
CMM Xform LUT types.
icXformInterp
CMM Interpolation types.
static bool ParseNextNumber(icFloatNumber &num, icChar **text)
static int icTranValues[]
static const char * icTranNames[]
void jsonSetValue(json &j, const char *szName, icCfgDataType v)
bool jsonToValue(const json &j, icFloatColorEncoding &v)
static bool ParseName(icChar *pName, icChar *pString)
static icFloatColorEncoding fileEncValues[]
const char * icGetJsonFileEncoding(icFloatColorEncoding v)
static bool icGetJsonRenderingIntent(const json &j, int &v)
static bool jsonFromEnvMap(json &j, const icCmmEnvSigMap &map)
const char * icGetJsonColorEncoding(icFloatColorEncoding v)
icFloatColorEncoding icSetJsonFileEncoding(const char *szEncode)
std::pair< int, std::string > icIndexName
static icXformInterp icInterpValues[]
static const char * clrEncNames[]
static const char * fileEncNames[]
static bool ParseNumbers(icFloatNumber *pData, icChar *pString, icUInt32Number nSamples)
static const char * icInterpNames[]
static icFloatColorEncoding clrEncValues[]
std::vector< CIccIndexValue > icValueVector
static void setSampleIndex(std::vector< icValueVector > &samples, int index, const char *szFmt, const char **szChannels)
static void setDstBool(json &j, const char *szName, icDstBool v)
static const icChar * icGetJsonFloatColorEncoding(icFloatColorEncoding val)
icFloatColorEncoding icSetJsonColorEncoding(const char *szEncode)
std::shared_ptr< CIccCfgDataEntry > CIccCfgDataEntryPtr
std::shared_ptr< CIccCfgProfile > CIccCfgProfilePtr
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
#define icSigDevLabData
Additional convenience color space signatures to distinguish between device encoding and PCS encoding...
std::map< icSignature, icFloatNumber > icCmmEnvSigMap
bool jsonToArray(const json &v, T *vals, int n)
bool jsonToList(const json &v, std::list< std::string > &vals)
bool jsonToColorSpace(const json &j, icColorSpaceSignature &sig)
const icChar * icGetColorSig(icChar *pBuf, icUInt32Number nSig, bool bGetHexVal)
icUInt32Number icGetSpaceSamples(icColorSpaceSignature sig)
const icChar * icGetColorSigStr(icChar *pBuf, icUInt32Number nSig)
icUInt32Number icGetSigVal(const icChar *pBuf)
const icChar * icGetSigStr(icChar *pBuf, icUInt32Number nSig)
unsigned int icUInt32Number
bool fromLegacy(const char *filename, bool bReset=false)
icFloatColorEncoding m_srcEncoding
bool toIt8(const char *filename, icUInt8Number nDigits, icUInt8Number nPrecision)
void addFields(std::string &dataFormat, int &nFields, int &nSamples, icColorSpaceSignature sig, std::string prefix)
icColorSpaceSignature m_srcSpace
bool fromJson(json obj, bool bReset=false)
bool fromIt8(const char *filename, bool bReset=false)
std::string spaceName(icColorSpaceSignature sig)
void toJson(json &obj) const
icFloatColorEncoding m_encoding
CIccCfgDataEntryList m_data
icColorSpaceSignature m_space
bool toLegacy(const char *filename, CIccCfgProfileSequence *pProfiles, icUInt8Number nDigits, icUInt8Number nPrecision, bool bShowDebug=false)
icFloatNumber m_linkMaxRange
void toJson(json &obj) const
bool fromJson(json obj, bool bReset=false)
int fromArgs(const char **args, int nArg, bool bReset=false)
icFloatNumber m_linkMinRange
bool m_useSourceTransform
icUInt8Number m_linkGridSize
icUInt8Number m_linkPrecision
bool fromJson(json obj, bool bReset=false)
icUInt8Number m_dstPrecision
void toJson(json &obj) const
int fromArgs(const char **args, int nArg, bool bReset=false)
icColorSpaceSignature m_srcSpace
icUInt8Number m_dstDigits
icFloatColorEncoding m_dstEncoding
std::vector< icFloatNumber > m_srcValues
bool fromJson(json obj, bool bReset=false)
std::vector< icFloatNumber > m_values
std::list< std::string > m_debugInfo
icFloatColorEncoding m_dstEncoding
void toJson(json &obj) const
int fromArgs(const char **args, int nArg, bool bReset=false)
bool fromJson(json obj, bool bReset=false)
icDstBool m_dstCompression
icCmmEnvSigMap m_pccEnvVars
icXformInterp m_interpolation
void toJson(json &obj) const
icXformLutType m_transform
icCmmEnvSigMap m_iccEnvVars
bool m_adjustPcsLuminance
bool fromJson(json obj, bool bReset=false)
CIccCfgProfileArray m_profiles
int fromArgs(const char **args, int nArg, bool bReset=false)
bool fromJson(json obj, bool bReset=false)
void toJson(json &obj) const
icColorSpaceSignature space
bool open(const char *szFilename)
bool findTokenLine(std::vector< std::string > &line, const char *szToken)
bool parseNextLine(std::vector< std::string > &line)
bool parseLine(std::vector< std::string > &line)