LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints) { LPGAMMATABLE in, out; LPGAMMATABLE KTone; _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) hCMYK2CMYK; // Make sure CMYK -> CMYK if (p -> EntryColorSpace != icSigCmykData || p -> ExitColorSpace != icSigCmykData) return NULL; // Create individual curves. BPC works also as each K to L* is // computed as a BPC to zero black point in case of L* in = ComputeKToLstar(p ->InputProfile, nPoints, p->Intent, p -> dwOriginalFlags); out = ComputeKToLstar(p ->OutputProfile, nPoints, p->Intent, p -> dwOriginalFlags); // Build the relationship KTone = cmsJoinGamma(in, out); cmsFreeGamma(in); cmsFreeGamma(out); // Make sure it is monotonic if (!IsMonotonic(KTone)) { cmsFreeGamma(KTone); return NULL; } return KTone; }
// Compute Black tone curve on a CMYK -> CMYK transform. This is done by // using the proof direction on both profiles to find K->L* relationship // then joining both curves. dwFlags may include black point compensation. cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID, cmsUInt32Number nPoints, cmsUInt32Number nProfiles, const cmsUInt32Number Intents[], const cmsHPROFILE hProfiles[], const cmsBool BPC[], const cmsFloat64Number AdaptationStates[], cmsUInt32Number dwFlags) { cmsToneCurve *in, *out, *KTone; // Make sure CMYK -> CMYK if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData || cmsGetColorSpace(hProfiles[nProfiles-1])!= cmsSigCmykData) return NULL; // Make sure last is an output profile if (cmsGetDeviceClass(hProfiles[nProfiles - 1]) != cmsSigOutputClass) return NULL; // Create individual curves. BPC works also as each K to L* is // computed as a BPC to zero black point in case of L* in = ComputeKToLstar(ContextID, nPoints, nProfiles - 1, Intents, hProfiles, BPC, AdaptationStates, dwFlags); if (in == NULL) return NULL; out = ComputeKToLstar(ContextID, nPoints, 1, Intents + (nProfiles - 1), hProfiles + (nProfiles - 1), BPC + (nProfiles - 1), AdaptationStates + (nProfiles - 1), dwFlags); if (out == NULL) { cmsFreeToneCurve(in); return NULL; } // Build the relationship. This effectively limits the maximum accuracy to 16 bits, but // since this is used on black-preserving LUTs, we are not loosing accuracy in any case KTone = cmsJoinToneCurve(ContextID, in, out, nPoints); // Get rid of components cmsFreeToneCurve(in); cmsFreeToneCurve(out); // Something went wrong... if (KTone == NULL) return NULL; // Make sure it is monotonic if (!cmsIsToneCurveMonotonic(KTone)) { cmsFreeToneCurve(KTone); return NULL; } return KTone; }