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;
}
Exemple #2
0
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
}
Exemple #4
0
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]);

    
}