summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lcms2mt/src/cmsgamma.c')
-rw-r--r--lcms2mt/src/cmsgamma.c76
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;
+}