diff options
author | Marti Maria <info@littlecms.com> | 2017-08-24 18:24:17 +0200 |
---|---|---|
committer | Marti Maria <info@littlecms.com> | 2017-08-24 18:24:17 +0200 |
commit | 47188d79264bb3b50eb78f30753d02a1dad5644a (patch) | |
tree | 4fbb7a83c3736772bf85bb65dad51ad3379b5dee | |
parent | f3fb695620c10677377c657551b8de634ae495cc (diff) | |
download | lcms2-47188d79264bb3b50eb78f30753d02a1dad5644a.tar.gz |
changes in cmsSmoothToneCurve contributed by Noel Carboni
Many thanks!
-rw-r--r-- | src/cmsgamma.c | 144 |
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 |