summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Maria <info@littlecms.com>2017-08-24 18:24:17 +0200
committerMarti Maria <info@littlecms.com>2017-08-24 18:24:17 +0200
commit47188d79264bb3b50eb78f30753d02a1dad5644a (patch)
tree4fbb7a83c3736772bf85bb65dad51ad3379b5dee
parentf3fb695620c10677377c657551b8de634ae495cc (diff)
downloadlcms2-47188d79264bb3b50eb78f30753d02a1dad5644a.tar.gz
changes in cmsSmoothToneCurve contributed by Noel Carboni
Many thanks!
-rw-r--r--src/cmsgamma.c144
1 files changed, 96 insertions, 48 deletions
diff --git a/src/cmsgamma.c b/src/cmsgamma.c
index 081a2a9..dccade2 100644
--- a/src/cmsgamma.c
+++ b/src/cmsgamma.c
@@ -141,7 +141,7 @@ cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase*
// Copy the parameters
fl ->Evaluator = Plugin ->Evaluator;
- fl ->nFunctions = (int) Plugin ->nFunctions;
+ fl ->nFunctions = Plugin ->nFunctions;
// Make sure no mem overwrites
if (fl ->nFunctions > MAX_TYPES_IN_LCMS_PLUGIN)
@@ -164,9 +164,9 @@ cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase*
static
int IsInSet(int Type, _cmsParametricCurvesCollection* c)
{
- cmsUInt32Number i;
+ int i;
- for (i=0; i < c ->nFunctions; i++)
+ for (i=0; i < (int) c ->nFunctions; i++)
if (abs(Type) == c ->FunctionTypes[i]) return i;
return -1;
@@ -1152,61 +1152,109 @@ cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[]
// Smooths a curve sampled at regular intervals.
cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda)
{
- cmsFloat32Number w[MAX_NODES_IN_CURVE], y[MAX_NODES_IN_CURVE], z[MAX_NODES_IN_CURVE];
+ cmsBool SuccessStatus = TRUE;
+ cmsFloat32Number *w, *y, *z;
cmsUInt32Number i, nItems, Zeros, Poles;
- if (Tab == NULL) return FALSE;
-
- if (cmsIsToneCurveLinear(Tab)) return TRUE; // Nothing to do
-
- nItems = Tab -> nEntries;
-
- if (nItems >= MAX_NODES_IN_CURVE) {
- cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: too many points.");
- return FALSE;
- }
-
- memset(w, 0, nItems * sizeof(cmsFloat32Number));
- memset(y, 0, nItems * sizeof(cmsFloat32Number));
- memset(z, 0, nItems * sizeof(cmsFloat32Number));
-
- for (i=0; i < nItems; i++)
+ if (Tab != NULL && Tab->InterpParams != NULL)
{
- y[i+1] = (cmsFloat32Number) Tab -> Table16[i];
- w[i+1] = 1.0;
- }
+ cmsContext ContextID = Tab->InterpParams->ContextID;
- if (!smooth2(Tab ->InterpParams->ContextID, w, y, z, (cmsFloat32Number) lambda, (int) nItems)) return FALSE;
+ if (!cmsIsToneCurveLinear(Tab)) // Only non-linear curves need smoothing
+ {
+ nItems = Tab->nEntries;
+ if (nItems < MAX_NODES_IN_CURVE)
+ {
+ // Allocate one more item than needed
+ w = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number));
+ y = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number));
+ z = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number));
+
+ if (w != NULL && y != NULL && z != NULL) // Ensure no memory allocation failure
+ {
+ memset(w, 0, (nItems + 1) * sizeof(cmsFloat32Number));
+ memset(y, 0, (nItems + 1) * sizeof(cmsFloat32Number));
+ memset(z, 0, (nItems + 1) * sizeof(cmsFloat32Number));
+
+ for (i = 0; i < nItems; i++)
+ {
+ y[i + 1] = (cmsFloat32Number)Tab->Table16[i];
+ w[i + 1] = 1.0;
+ }
+
+ if (smooth2(ContextID, w, y, z, (cmsFloat32Number)lambda, (int)nItems))
+ {
+ // Do some reality - checking...
+
+ Zeros = Poles = 0;
+ for (i = nItems; i > 1; --i)
+ {
+ if (z[i] == 0.) Zeros++;
+ if (z[i] >= 65535.) Poles++;
+ if (z[i] < z[i - 1])
+ {
+ cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic.");
+ SuccessStatus = FALSE;
+ break;
+ }
+ }
+
+ if (SuccessStatus && Zeros > (nItems / 3))
+ {
+ cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros.");
+ SuccessStatus = FALSE;
+ }
+
+ if (SuccessStatus && Poles > (nItems / 3))
+ {
+ cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles.");
+ SuccessStatus = FALSE;
+ }
+
+ if (SuccessStatus) // Seems ok
+ {
+ for (i = 0; i < nItems; i++)
+ {
+ // Clamp to cmsUInt16Number
+ Tab->Table16[i] = _cmsQuickSaturateWord(z[i + 1]);
+ }
+ }
+ }
+ else // Could not smooth
+ {
+ cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Function smooth2 failed.");
+ SuccessStatus = FALSE;
+ }
+ }
+ else // One or more buffers could not be allocated
+ {
+ cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Could not allocate memory.");
+ SuccessStatus = FALSE;
+ }
- // Do some reality - checking...
- Zeros = Poles = 0;
- for (i=nItems; i > 1; --i) {
+ if (z != NULL)
+ _cmsFree(ContextID, z);
- if (z[i] == 0.) Zeros++;
- if (z[i] >= 65535.) Poles++;
- if (z[i] < z[i-1]) {
- cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic.");
- return FALSE;
- }
- }
+ if (y != NULL)
+ _cmsFree(ContextID, y);
- if (Zeros > (nItems / 3)) {
- cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros.");
- return FALSE;
- }
- if (Poles > (nItems / 3)) {
- cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles.");
- return FALSE;
+ if (w != NULL)
+ _cmsFree(ContextID, w);
+ }
+ else // too many items in the table
+ {
+ cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Too many points.");
+ SuccessStatus = FALSE;
+ }
+ }
}
-
- // Seems ok
- for (i=0; i < nItems; i++) {
-
- // Clamp to cmsUInt16Number
- Tab -> Table16[i] = _cmsQuickSaturateWord(z[i+1]);
+ else // Tab parameter or Tab->InterpParams is NULL
+ {
+ // Can't signal an error here since the ContextID is not known at this point
+ SuccessStatus = FALSE;
}
- return TRUE;
+ return SuccessStatus;
}
// Is a table linear? Do not use parametric since we cannot guarantee some weird parameters resulting