2362N/A * or visit www.oracle.com if you need additional information or have any
2693N/A#include "lcms2_internal.h"
2693N/A// The curve is stored in segments, where each segment can be sampled or specified by parameters.
2693N/A// a 16.bit simplification of the *whole* curve is kept for optimization purposes. For float operation,
2693N/A// each segment is evaluated separately. Plug-ins may be used to define new parametric schemes,
2693N/A// each plug-in may define up to MAX_TYPES_IN_LCMS_PLUGIN functions types. For defining a function,
2693N/A// the plug-in should provide the type id, how many parameters each type has, and a pointer to
2693N/A// a procedure that evaluates the function. In the case of reverse evaluation, the evaluator will
2693N/A// be called with the type id as a negative value, and a sampled version of the reversed curve
2693N/Astatic cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R);
2693N/A fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(sizeof(_cmsParametricCurvesCollection));
2693N/A memmove(fl->FunctionTypes, Plugin ->FunctionTypes, fl->nFunctions * sizeof(cmsUInt32Number));
2693N/A memmove(fl->ParameterCount, Plugin ->ParameterCount, fl->nFunctions * sizeof(cmsUInt32Number));
2693N/A for (i=0; i < c ->nFunctions; i++)
2693N/A// Low level allocate, which takes care of memory details. nEntries may be zero, and in this case
2693N/A// no optimation curve is computed. nSegments may also be zero in the inverse case, where only the
2693N/A cmsToneCurve* p;
2693N/A cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve of more than 65530 entries");
2693N/A cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve with zero segments and no table");
2693N/A p ->Segments = (cmsCurveSegment*) _cmsCalloc(ContextID, nSegments, sizeof(cmsCurveSegment));
2693N/A p ->Evals = (cmsParametricCurveEvaluator*) _cmsCalloc(ContextID, nSegments, sizeof(cmsParametricCurveEvaluator));
2693N/A // This 16-bit table contains a limited precision representation of the whole curve and is kept for
2693N/A // Initialize the segments stuff. The evaluator for each segment is located and a pointer to it
2693N/A p ->SegInterp = (cmsInterpParams**) _cmsCalloc(ContextID, nSegments, sizeof(cmsInterpParams*));
2693N/A p ->SegInterp[i] = _cmsComputeInterpParams(ContextID, Segments[i].nGridPoints, 1, 1, NULL, CMS_LERP_FLAGS_FLOAT);
2693N/A p ->Segments[i].SampledPoints = (cmsFloat32Number*) _cmsDupMem(ContextID, Segments[i].SampledPoints, sizeof(cmsFloat32Number) * Segments[i].nGridPoints);
2693N/A p ->InterpParams = _cmsComputeInterpParams(ContextID, p ->nEntries, 1, 1, p->Table16, CMS_LERP_FLAGS_16BITS);
2693N/AcmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R)
2693N/A // Types 6,7,8 comes from segmented curves as described in ICCSpecRevision_02_11_06_Float.pdf
2693N/A// Create an empty gamma curve, by using tables. This specifies only the limited-precision part, and leaves the
2693N/AcmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsInt32Number nEntries, const cmsUInt16Number Values[])
2693N/A cmsToneCurve* g;
2693N/A // Once we have the floating point version, we can approximate a 16 bit table of 4096 entries
2693N/A // for performance reasons. This table would normally not be used except on 8/16 bits transforms.
2693N/A for (i=0; i < nGridPoints; i++) {
2693N/AcmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurveFloat(cmsContext ContextID, cmsUInt32Number nEntries, const cmsFloat32Number values[])
2693N/AcmsToneCurve* CMSEXPORT cmsBuildParametricToneCurve(cmsContext ContextID, cmsInt32Number Type, const cmsFloat64Number Params[])
2693N/A cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Invalid parametric curve type %d", Type);
2693N/A return AllocateToneCurveStruct(In ->InterpParams ->ContextID, In ->nEntries, In ->nSegments, In ->Segments, In ->Table16);
2693N/A const cmsToneCurve* X,
2693N/A cmsFloat32Number t, x;
2693N/A Res = (cmsFloat32Number*) _cmsCalloc(ContextID, nResultingPoints, sizeof(cmsFloat32Number));
2693N/A for (i=0; i < nResultingPoints; i++) {
2693N/A x = cmsEvalToneCurveFloat(X, t);
2693N/Aint GetInterval(cmsFloat64Number In, const cmsUInt16Number LutTable[], const struct _cms_interp_struc* p)
2693N/AcmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, const cmsToneCurve* InCurve)
2693N/A if (InCurve ->nSegments == 1 && InCurve ->Segments[0].Type > 0 && InCurve -> Segments[0].Type <= 5) {
2693N/A out = cmsBuildTabulatedToneCurve16(InCurve ->InterpParams->ContextID, nResultSamples, NULL);
2693N/A for (i=0; i < nResultSamples; i++) {
2693N/AcmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[], cmsFloat32Number z[], cmsFloat32Number lambda, int m)
2693N/A cmsFloat32Number *c, *d, *e;
2693N/A c = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number));
2693N/A d = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number));
2693N/A e = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number));
2693N/A cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: too many points.");
2693N/A if (!smooth2(Tab ->InterpParams->ContextID, w, y, z, (cmsFloat32Number) lambda, nItems)) return FALSE;
2693N/A// Is a table linear? Do not use parametric since we cannot guarantee some weird parameters resulting
2693N/A// in a linear table. This way assures it is linear in 12 bits, which should be enought in most cases.
6271N/A if (lDescending) {
2693N/AcmsFloat32Number CMSEXPORT cmsEvalToneCurveFloat(const cmsToneCurve* Curve, cmsFloat32Number v)
2693N/A// minimizing the sum of the squares of the offsets ("the residuals") of the points from the curve.
2693N/A// The sum of the squares of the offsets is used instead of the offset absolute values because