void LcmsColorProfileContainer::LinearizeFloatValueFast(QVector <double> & Value) const
{
    //we can only reliably delinearise in the 0-1.0 range, outside of that leave the value alone.
    QVector <quint16> TRCtriplet(3);
    TRCtriplet[0] = Value[0]*65535;
    TRCtriplet[1] = Value[1]*65535;
    TRCtriplet[2] = Value[2]*65535;
    

    if (d->hasColorants) {
        if (!cmsIsToneCurveLinear(d->redTRC) && Value[0]<1.0) {
            TRCtriplet[0] = cmsEvalToneCurve16(d->redTRC, TRCtriplet[0]);
            Value[0] = TRCtriplet[0]/65535.0;
        }
        if (!cmsIsToneCurveLinear(d->greenTRC) && Value[1]<1.0) {
            TRCtriplet[1] = cmsEvalToneCurve16(d->greenTRC, TRCtriplet[1]);
            Value[1] = TRCtriplet[1]/65535.0;
        }
        if (!cmsIsToneCurveLinear(d->blueTRC) && Value[2]<1.0) {
            TRCtriplet[2] = cmsEvalToneCurve16(d->blueTRC, TRCtriplet[2]);
            Value[2] = TRCtriplet[2]/65535.0;
        }
            
    } else {
        if (cmsIsTag(d->profile, cmsSigGrayTRCTag) && Value[0]<1.0) {
            TRCtriplet[0] = (cmsEvalToneCurve16(d->grayTRC, Value[0]*65535));
            Value.fill(TRCtriplet[0]/65535.0);
        }
    }
}
void LcmsColorProfileContainer::DelinearizeFloatValueFast(QVector <double> & Value) const
{
    const qreal scale = 65535.0;
    const qreal invScale = 1.0 / scale;

    if (d->hasColorants) {
        //we can only reliably delinearise in the 0-1.0 range, outside of that leave the value alone.
        QVector <quint16> TRCtriplet(3);
        TRCtriplet[0] = Value[0] * scale;
        TRCtriplet[1] = Value[1] * scale;
        TRCtriplet[2] = Value[2] * scale;

        if (!cmsIsToneCurveLinear(d->redTRC) && Value[0]<1.0) {
            TRCtriplet[0] = cmsEvalToneCurve16(d->redTRCReverse, TRCtriplet[0]);
            Value[0] = TRCtriplet[0] * invScale;
        }
        if (!cmsIsToneCurveLinear(d->greenTRC) && Value[1]<1.0) {
            TRCtriplet[1] = cmsEvalToneCurve16(d->greenTRCReverse, TRCtriplet[1]);
            Value[1] = TRCtriplet[1] * invScale;
        }
        if (!cmsIsToneCurveLinear(d->blueTRC) && Value[2]<1.0) {
            TRCtriplet[2] = cmsEvalToneCurve16(d->blueTRCReverse, TRCtriplet[2]);
            Value[2] = TRCtriplet[2] * invScale;
        }
    } else {
        if (cmsIsTag(d->profile, cmsSigGrayTRCTag) && Value[0]<1.0) {
            quint16 newValue = cmsEvalToneCurve16(d->grayTRCReverse, Value[0] * scale);
            Value[0] = newValue * invScale;
        }
    }
}
Exemple #3
0
// We need accuracy this time
cmsFloat32Number CMSEXPORT cmsEvalToneCurveFloat(const cmsToneCurve* Curve, cmsFloat32Number v)
{
    _cmsAssert(Curve != NULL);

    // Check for 16 bits table. If so, this is a limited-precision tone curve
    if (Curve ->nSegments == 0) {

        cmsUInt16Number In, Out;
        
        In = (cmsUInt16Number) _cmsQuickSaturateWord(v * 65535.0);
        Out = cmsEvalToneCurve16(Curve, In);
        
        return (cmsFloat32Number) (Out / 65535.0);
    }

    return (cmsFloat32Number) EvalSegmentedFn(Curve, v);
}
// Preserve black only if that is the only ink used
static
int BlackPreservingGrayOnlySampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
{
    GrayOnlyParams* bp = (GrayOnlyParams*) Cargo;

    // If going across black only, keep black only
    if (In[0] == 0 && In[1] == 0 && In[2] == 0) {

        // TAC does not apply because it is black ink!
        Out[0] = Out[1] = Out[2] = 0;
        Out[3] = cmsEvalToneCurve16(bp->KTone, In[3]);
        return TRUE;
    }

    // Keep normal transform for other colors
    bp ->cmyk2cmyk ->Eval16Fn(In, Out, bp ->cmyk2cmyk->Data);
    return TRUE;
}