QVector <double> LcmsColorProfileContainer::getEstimatedTRC() const { QVector <double> TRCtriplet(3); if (d->hasColorants) { if (cmsIsToneCurveLinear(d->redTRC)) { TRCtriplet[0] = 1.0; } else { TRCtriplet[0] = cmsEstimateGamma(d->redTRC, 0.01); } if (cmsIsToneCurveLinear(d->greenTRC)) { TRCtriplet[1] = 1.0; } else { TRCtriplet[1] = cmsEstimateGamma(d->greenTRC, 0.01); } if (cmsIsToneCurveLinear(d->blueTRC)) { TRCtriplet[2] = 1.0; } else { TRCtriplet[2] = cmsEstimateGamma(d->blueTRC, 0.01); } } else { if (cmsIsTag(d->profile, cmsSigGrayTRCTag)) { if (cmsIsToneCurveLinear(d->grayTRC)) { TRCtriplet.fill(1.0); } else { TRCtriplet.fill(cmsEstimateGamma(d->grayTRC, 0.01)); } } else { TRCtriplet.fill(1.0); } } return TRCtriplet; }
static void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table) { cmsUInt32Number i; cmsFloat64Number gamma; if (Table ->nEntries <= 0) return; // Empty table // Suppress whole if identity if (cmsIsToneCurveLinear(Table)) return; // Check if is really an exponential. If so, emit "exp" gamma = cmsEstimateGamma(Table, 0.001); if (gamma > 0) { _cmsIOPrintf(m, "{ %g exp } bind ", gamma); return; } _cmsIOPrintf(m, "{ "); // Bounds check EmitRangeCheck(m); // Emit intepolation code // PostScript code Stack // =============== ======================== // v _cmsIOPrintf(m, " ["); for (i=0; i < Table->nEntries; i++) { _cmsIOPrintf(m, "%d ", Table->Table16[i]); } _cmsIOPrintf(m, "] "); // v tab _cmsIOPrintf(m, "dup "); // v tab tab _cmsIOPrintf(m, "length 1 sub "); // v tab dom _cmsIOPrintf(m, "3 -1 roll "); // tab dom v _cmsIOPrintf(m, "mul "); // tab val2 _cmsIOPrintf(m, "dup "); // tab val2 val2 _cmsIOPrintf(m, "dup "); // tab val2 val2 val2 _cmsIOPrintf(m, "floor cvi "); // tab val2 val2 cell0 _cmsIOPrintf(m, "exch "); // tab val2 cell0 val2 _cmsIOPrintf(m, "ceiling cvi "); // tab val2 cell0 cell1 _cmsIOPrintf(m, "3 index "); // tab val2 cell0 cell1 tab _cmsIOPrintf(m, "exch "); // tab val2 cell0 tab cell1 _cmsIOPrintf(m, "get "); // tab val2 cell0 y1 _cmsIOPrintf(m, "4 -1 roll "); // val2 cell0 y1 tab _cmsIOPrintf(m, "3 -1 roll "); // val2 y1 tab cell0 _cmsIOPrintf(m, "get "); // val2 y1 y0 _cmsIOPrintf(m, "dup "); // val2 y1 y0 y0 _cmsIOPrintf(m, "3 1 roll "); // val2 y0 y1 y0 _cmsIOPrintf(m, "sub "); // val2 y0 (y1-y0) _cmsIOPrintf(m, "3 -1 roll "); // y0 (y1-y0) val2 _cmsIOPrintf(m, "dup "); // y0 (y1-y0) val2 val2 _cmsIOPrintf(m, "floor cvi "); // y0 (y1-y0) val2 floor(val2) _cmsIOPrintf(m, "sub "); // y0 (y1-y0) rest _cmsIOPrintf(m, "mul "); // y0 t1 _cmsIOPrintf(m, "add "); // y _cmsIOPrintf(m, "65535 div "); // result _cmsIOPrintf(m, " } bind "); }
void TestKoLcmsColorProfile::testProfileCreationFromChromaticities() { #if 0 KoLcmsRGBColorProfile::Chromaticities chromaticities; chromaticities.primaries.Red.x = 0.7347f; chromaticities.primaries.Red.y = 0.2653f; chromaticities.primaries.Red.Y = 1.0f; chromaticities.primaries.Green.x = 0.1596f; chromaticities.primaries.Green.y = 0.8404f; chromaticities.primaries.Green.Y = 1.0f; chromaticities.primaries.Blue.x = 0.0366f; chromaticities.primaries.Blue.y = 0.0001f; chromaticities.primaries.Blue.Y = 1.0f; chromaticities.whitePoint.x = 0.34567f; chromaticities.whitePoint.y = 0.35850f; chromaticities.whitePoint.Y = 1.0f; qreal gamma = 1.75f; KoLcmsRGBColorProfile *profile = new KoLcmsRGBColorProfile(chromaticities, gamma); QVERIFY(profile != 0); QCOMPARE(profile->colorSpaceSignature(), icSigRgbData); cmsHPROFILE lcmsProfile = profile->lcmsProfile(); KoLcmsRGBColorProfile::Chromaticities profileChromaticities = KoLcmsRGBColorProfile::chromaticitiesFromProfile(lcmsProfile); QCOMPARE(testRounding(profileChromaticities.primaries.Red.x), testRounding(chromaticities.primaries.Red.x)); QCOMPARE(testRounding(profileChromaticities.primaries.Red.y), testRounding(chromaticities.primaries.Red.y)); QCOMPARE(testRounding(profileChromaticities.primaries.Green.x), testRounding(chromaticities.primaries.Green.x)); QCOMPARE(testRounding(profileChromaticities.primaries.Green.y), testRounding(chromaticities.primaries.Green.y)); QCOMPARE(testRounding(profileChromaticities.primaries.Blue.x), testRounding(chromaticities.primaries.Blue.x)); QCOMPARE(testRounding(profileChromaticities.primaries.Blue.y), testRounding(chromaticities.primaries.Blue.y)); QCOMPARE(testRounding(profileChromaticities.whitePoint.x), testRounding(chromaticities.whitePoint.x)); QCOMPARE(testRounding(profileChromaticities.whitePoint.y), testRounding(chromaticities.whitePoint.y)); LPGAMMATABLE redGamma = cmsReadICCGamma(lcmsProfile, icSigRedTRCTag); LPGAMMATABLE greenGamma = cmsReadICCGamma(lcmsProfile, icSigGreenTRCTag); LPGAMMATABLE blueGamma = cmsReadICCGamma(lcmsProfile, icSigBlueTRCTag); QCOMPARE(testRounding(cmsEstimateGamma(redGamma)), gamma); QCOMPARE(testRounding(cmsEstimateGamma(greenGamma)), gamma); QCOMPARE(testRounding(cmsEstimateGamma(blueGamma)), gamma); QString expectedProfileName = QString("lcms virtual RGB profile - R(%1, %2) G(%3, %4) B(%5, %6) W(%7, %8) gamma %9") .arg(chromaticities.primaries.Red.x) .arg(chromaticities.primaries.Red.y) .arg(chromaticities.primaries.Green.x) .arg(chromaticities.primaries.Green.y) .arg(chromaticities.primaries.Blue.x) .arg(chromaticities.primaries.Blue.y) .arg(chromaticities.whitePoint.x) .arg(chromaticities.whitePoint.y) .arg(gamma); QCOMPARE(profile->name(), expectedProfileName); QCOMPARE(QString(cmsTakeProductDesc(lcmsProfile)), expectedProfileName); profileChromaticities = profile->chromaticities(); QCOMPARE(profileChromaticities.primaries.Red.x, chromaticities.primaries.Red.x); QCOMPARE(profileChromaticities.primaries.Red.y, chromaticities.primaries.Red.y); QCOMPARE(profileChromaticities.primaries.Green.x, chromaticities.primaries.Green.x); QCOMPARE(profileChromaticities.primaries.Green.y, chromaticities.primaries.Green.y); QCOMPARE(profileChromaticities.primaries.Blue.x, chromaticities.primaries.Blue.x); QCOMPARE(profileChromaticities.primaries.Blue.y, chromaticities.primaries.Blue.y); QCOMPARE(profileChromaticities.whitePoint.x, chromaticities.whitePoint.x); QCOMPARE(profileChromaticities.whitePoint.y, chromaticities.whitePoint.y); const QString testProfileName = "Test Profile Name"; profile = new KoLcmsRGBColorProfile(chromaticities, gamma, testProfileName); lcmsProfile = profile->lcmsProfile(); QCOMPARE(profile->name(), testProfileName); QCOMPARE(QString(cmsTakeProductDesc(lcmsProfile)), testProfileName); #endif }
void _cmsComputePrelinearizationTablesFromXFORM(cmsHTRANSFORM h[], int nTransforms, LPLUT Grid) { LPGAMMATABLE Trans[MAXCHANNELS]; unsigned int t, i, v; int j; WORD In[MAXCHANNELS], Out[MAXCHANNELS]; BOOL lIsSuitable; _LPcmsTRANSFORM InputXForm = (_LPcmsTRANSFORM) h[0]; _LPcmsTRANSFORM OutputXForm = (_LPcmsTRANSFORM) h[nTransforms-1]; // First space is *Lab, use our specialized curves for v2 Lab if (InputXForm ->EntryColorSpace == icSigLabData && OutputXForm->ExitColorSpace != icSigLabData) { CreateLabPrelinearization(Trans); cmsAllocLinearTable(Grid, Trans, 1); cmsFreeGammaTriple(Trans); return; } // Do nothing on all but RGB to RGB transforms if ((InputXForm ->EntryColorSpace != icSigRgbData) || (OutputXForm->ExitColorSpace != icSigRgbData)) return; for (t = 0; t < Grid -> InputChan; t++) Trans[t] = cmsAllocGamma(PRELINEARIZATION_POINTS); for (i=0; i < PRELINEARIZATION_POINTS; i++) { v = _cmsQuantizeVal(i, PRELINEARIZATION_POINTS); for (t=0; t < Grid -> InputChan; t++) In[t] = (WORD) v; cmsDoTransform(h[0], In, Out, 1); for (j=1; j < nTransforms; j++) cmsDoTransform(h[j], Out, Out, 1); for (t=0; t < Grid -> InputChan; t++) Trans[t] ->GammaTable[i] = Out[t]; } // Check transfer curves lIsSuitable = TRUE; for (t=0; (lIsSuitable && (t < Grid->InputChan)); t++) { // Exclude if already linear if (MostlyLinear(Trans[t]->GammaTable, PRELINEARIZATION_POINTS)) lIsSuitable = FALSE; // Exclude if non-monotonic if (!IsMonotonic(Trans[t])) lIsSuitable = FALSE; // Exclude if weird endpoints if (!HasProperEndpoints(Trans[t])) lIsSuitable = FALSE; // Exclude if transfer function is not smooth enough // to be modelled as a gamma function, or the gamma is reversed if (cmsEstimateGamma(Trans[t]) < 1.0) lIsSuitable = FALSE; } if (lIsSuitable) { for (t = 0; t < Grid ->InputChan; t++) SlopeLimiting(Trans[t]->GammaTable, Trans[t]->nEntries); } if (lIsSuitable) cmsAllocLinearTable(Grid, Trans, 1); for (t = 0; t < Grid ->InputChan; t++) cmsFreeGamma(Trans[t]); }