diff options
Diffstat (limited to 'lcms2mt/src/cmsgamma.c')
-rw-r--r-- | lcms2mt/src/cmsgamma.c | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/lcms2mt/src/cmsgamma.c b/lcms2mt/src/cmsgamma.c index ad00b129..6edbc841 100644 --- a/lcms2mt/src/cmsgamma.c +++ b/lcms2mt/src/cmsgamma.c @@ -59,11 +59,11 @@ static cmsFloat64Number DefaultEvalParametricFn(cmsContext ContextID, cmsInt32Nu // The built-in list static _cmsParametricCurvesCollection DefaultCurves = { - 9, // # of curve types - { 1, 2, 3, 4, 5, 6, 7, 8, 108 }, // Parametric curve ID - { 1, 3, 4, 5, 7, 4, 5, 5, 1 }, // Parameters by type - DefaultEvalParametricFn, // Evaluator - NULL // Next in chain + 10, // # of curve types + { 1, 2, 3, 4, 5, 6, 7, 8, 108, 109 }, // Parametric curve ID + { 1, 3, 4, 5, 7, 4, 5, 5, 1, 1 }, // Parameters by type + DefaultEvalParametricFn, // Evaluator + NULL // Next in chain }; // Duplicates the zone of memory used by the plug-in in the new context @@ -300,8 +300,8 @@ cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsUInt32Number nEnt return p; Error: - if (p->SegInterp) _cmsFree(ContextID, p->SegInterp); - if (p -> Segments) _cmsFree(ContextID, p ->Segments); + if (p -> SegInterp) _cmsFree(ContextID, p -> SegInterp); + if (p -> Segments) _cmsFree(ContextID, p -> Segments); if (p -> Evals) _cmsFree(ContextID, p -> Evals); if (p ->Table16) _cmsFree(ContextID, p ->Table16); _cmsFree(ContextID, p); @@ -309,6 +309,32 @@ Error: } +// Generates a sigmoidal function with desired steepness. +cmsINLINE double sigmoid_base(double k, double t) +{ + return (1.0 / (1.0 + exp(-k * t))) - 0.5; +} + +cmsINLINE double inverted_sigmoid_base(double k, double t) +{ + return -log((1.0 / (t + 0.5)) - 1.0) / k; +} + +cmsINLINE double sigmoid_factory(double k, double t) +{ + double correction = 0.5 / sigmoid_base(k, 1); + + return correction * sigmoid_base(k, 2.0 * t - 1.0) + 0.5; +} + +cmsINLINE double inverse_sigmoid_factory(double k, double t) +{ + double correction = 0.5 / sigmoid_base(k, 1); + + return (inverted_sigmoid_base(k, (t - 0.5) / correction) + 1.0) / 2.0; +} + + // Parametric Fn using floating point static cmsFloat64Number DefaultEvalParametricFn(cmsContext ContextID, cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R) @@ -641,6 +667,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsContext ContextID, cmsInt32Number Ty } break; + // S-Shaped: (1 - (1-x)^1/g)^1/g case 108: if (fabs(Params[0]) < MATRIX_DET_TOLERANCE) @@ -658,6 +685,15 @@ cmsFloat64Number DefaultEvalParametricFn(cmsContext ContextID, cmsInt32Number Ty Val = 1 - pow(1 - pow(R, Params[0]), Params[0]); break; + // Sigmoidals + case 109: + Val = sigmoid_factory(Params[0], R); + break; + + case -109: + Val = inverse_sigmoid_factory(Params[0], R); + break; + default: // Unsupported parametric curve. Should never reach here return 0; @@ -941,7 +977,7 @@ cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID, //Iterate for (i=0; i < nResultingPoints; i++) { - t = (cmsFloat32Number) i / (nResultingPoints-1); + t = (cmsFloat32Number) i / (cmsFloat32Number)(nResultingPoints-1); x = cmsEvalToneCurveFloat(ContextID, X, t); Res[i] = cmsEvalToneCurveFloat(ContextID, Yreversed, x); } @@ -1155,6 +1191,7 @@ cmsBool CMSEXPORT cmsSmoothToneCurve(cmsContext ContextID, cmsToneCurve* Tab, c cmsBool SuccessStatus = TRUE; cmsFloat32Number *w, *y, *z; cmsUInt32Number i, nItems, Zeros, Poles; + cmsBool notCheck = FALSE; if (Tab != NULL && Tab->InterpParams != NULL) { @@ -1180,6 +1217,12 @@ cmsBool CMSEXPORT cmsSmoothToneCurve(cmsContext ContextID, cmsToneCurve* Tab, c w[i + 1] = 1.0; } + if (lambda < 0) + { + notCheck = TRUE; + lambda = -lambda; + } + if (smooth2(ContextID, w, y, z, (cmsFloat32Number)lambda, (int)nItems)) { // Do some reality - checking... @@ -1192,7 +1235,7 @@ cmsBool CMSEXPORT cmsSmoothToneCurve(cmsContext ContextID, cmsToneCurve* Tab, c if (z[i] < z[i - 1]) { cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic."); - SuccessStatus = FALSE; + SuccessStatus = notCheck; break; } } @@ -1200,13 +1243,13 @@ cmsBool CMSEXPORT cmsSmoothToneCurve(cmsContext ContextID, cmsToneCurve* Tab, c if (SuccessStatus && Zeros > (nItems / 3)) { cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros."); - SuccessStatus = FALSE; + SuccessStatus = notCheck; } if (SuccessStatus && Poles > (nItems / 3)) { cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles."); - SuccessStatus = FALSE; + SuccessStatus = notCheck; } if (SuccessStatus) // Seems ok @@ -1433,3 +1476,14 @@ cmsFloat64Number CMSEXPORT cmsEstimateGamma(cmsContext ContextID, const cmsToneC return (sum / n); // The mean } + + +// Retrieve parameters on one-segment tone curves + +cmsFloat64Number* CMSEXPORT cmsGetToneCurveParams(cmsContext contextID, const cmsToneCurve* t) +{ + _cmsAssert(t != NULL); + + if (t->nSegments != 1) return NULL; + return t->Segments[0].Params; +} |