summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Maria <info@littlecms.com>2011-04-21 17:53:14 +0200
committerMarti Maria <info@littlecms.com>2011-04-21 17:53:14 +0200
commitbc18758a508df0ff39a80f6b9f30e2cb4d7816a3 (patch)
treeadcd9dc4ef7e9a2e86327424f0984d8dc0fdb6cf
parent70a120d7e45e33efc8d2a8475abcd7e83d99f474 (diff)
downloadlcms2-bc18758a508df0ff39a80f6b9f30e2cb4d7816a3.tar.gz
Fixed a bug in black preservation and sligtly non-monotonic curves
-rw-r--r--AUTHORS2
-rw-r--r--src/cmscnvrt.c23
-rw-r--r--src/cmsgamma.c36
-rw-r--r--src/cmsgmt.c1
-rw-r--r--src/cmslut.c2
5 files changed, 45 insertions, 19 deletions
diff --git a/AUTHORS b/AUTHORS
index 47e0d3b..58dec56 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -17,7 +17,7 @@ Auke Nauta
Chris Evans
Lorenzo Ridolfi
Robin Watts
-
+Shawn Pedersen
Special Thanks
--------------
diff --git a/src/cmscnvrt.c b/src/cmscnvrt.c
index 8b5cd72..09e78cb 100644
--- a/src/cmscnvrt.c
+++ b/src/cmscnvrt.c
@@ -460,8 +460,8 @@ cmsPipeline* DefaultICCintents(cmsContext ContextID,
cmsProfileClassSignature ClassSig;
cmsUInt32Number i, Intent;
- // For safety
- if (nProfiles == 0) return NULL;
+ // For safety
+ if (nProfiles == 0) return NULL;
// Allocate an empty LUT for holding the result. 0 as channel count means 'undefined'
Result = cmsPipelineAlloc(ContextID, 0, 0);
@@ -478,14 +478,14 @@ cmsPipeline* DefaultICCintents(cmsContext ContextID,
lIsDeviceLink = (ClassSig == cmsSigLinkClass || ClassSig == cmsSigAbstractClass );
// First profile is used as input unless devicelink or abstract
- if ((i == 0) && !lIsDeviceLink) {
- lIsInput = TRUE;
- }
- else {
- // Else use profile in the input direction if current space is not PCS
+ if ((i == 0) && !lIsDeviceLink) {
+ lIsInput = TRUE;
+ }
+ else {
+ // Else use profile in the input direction if current space is not PCS
lIsInput = (CurrentColorSpace != cmsSigXYZData) &&
(CurrentColorSpace != cmsSigLabData);
- }
+ }
Intent = TheIntents[i];
@@ -865,6 +865,8 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
// Get total area coverage (in 0..1 domain)
bp.MaxTAC = cmsDetectTAC(hProfiles[nProfiles-1]) / 100.0;
+ if (bp.MaxTAC <= 0) goto Cleanup;
+
// Create a LUT holding normal ICC transform
bp.cmyk2cmyk = DefaultICCintents(ContextID,
@@ -874,6 +876,7 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
BPC,
AdaptationStates,
dwFlags);
+ if (bp.cmyk2cmyk == NULL) goto Cleanup;
// Now the tone curve
bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, nProfiles,
@@ -882,7 +885,7 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
BPC,
AdaptationStates,
dwFlags);
-
+ if (bp.KTone == NULL) goto Cleanup;
// To measure the output, Last profile to Lab
hLab = cmsCreateLab4ProfileTHR(ContextID, NULL);
@@ -890,6 +893,7 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
CHANNELS_SH(4)|BYTES_SH(2), hLab, TYPE_Lab_DBL,
INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE);
+ if ( bp.hProofOutput == NULL) goto Cleanup;
// Same as anterior, but lab in the 0..1 range
bp.cmyk2Lab = cmsCreateTransformTHR(ContextID, hProfiles[nProfiles-1],
@@ -897,6 +901,7 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
FLOAT_SH(1)|CHANNELS_SH(3)|BYTES_SH(4),
INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE);
+ if (bp.cmyk2Lab == NULL) goto Cleanup;
cmsCloseProfile(hLab);
// Error estimation (for debug only)
diff --git a/src/cmsgamma.c b/src/cmsgamma.c
index db156c7..02dc910 100644
--- a/src/cmsgamma.c
+++ b/src/cmsgamma.c
@@ -1008,20 +1008,42 @@ cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t)
{
int n;
int i, last;
+ cmsBool lDescending;
_cmsAssert(t != NULL);
+
+ // Degenerated curves are monotonic? Ok, let's pass them
+ n = t ->nEntries;
+ if (n < 2) return TRUE;
- n = t ->nEntries;
- last = t ->Table16[n-1];
+ // Curve direction
+ lDescending = cmsIsToneCurveDescending(t);
+
+ if (lDescending) {
- for (i = n-2; i >= 0; --i) {
+ last = t ->Table16[0];
- if (t ->Table16[i] > last)
+ for (i = 1; i < n; i++) {
- return FALSE;
- else
- last = t ->Table16[i];
+ if (t ->Table16[i] - last > 2) // We allow some ripple
+ return FALSE;
+ else
+ last = t ->Table16[i];
+ }
+ }
+ else {
+
+ last = t ->Table16[n-1];
+
+ for (i = n-2; i >= 0; --i) {
+
+ if (t ->Table16[i] - last > 2)
+ return FALSE;
+ else
+ last = t ->Table16[i];
+
+ }
}
return TRUE;
diff --git a/src/cmsgmt.c b/src/cmsgmt.c
index c2f3a9a..9fec390 100644
--- a/src/cmsgmt.c
+++ b/src/cmsgmt.c
@@ -183,7 +183,6 @@ cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
// Make sure it is monotonic
if (!cmsIsToneCurveMonotonic(KTone)) {
-
cmsFreeToneCurve(KTone);
return NULL;
}
diff --git a/src/cmslut.c b/src/cmslut.c
index e4475d2..aaad3b4 100644
--- a/src/cmslut.c
+++ b/src/cmslut.c
@@ -125,7 +125,7 @@ cmsBool CMSEXPORT cmsPipelineCheckAndRetreiveStages(const cmsPipeline* Lut, cms
for (i=0; i < n; i++) {
// Get asked type
- Type = va_arg(args, cmsStageSignature);
+ Type = (cmsStageSignature)va_arg(args, cmsStageSignature);
if (mpe ->Type != Type) {
va_end(args); // Mismatch. We are done.