Am 23.04.12, 11:46 +0200 schrieb marti.ma...@littlecms.com:
I think it makes complete sense. I would, however, only modify case of pure gamma function (type 0). It happens that the spec already defines what to do on negative parts for other types. Just try the build-in sRGB for example, that already has this feature enabled:transicc -i*XYZ -o *sRGB LittleCMS ColorSpace conversion calculator - 4.1 [LittleCMS 2.04] Enter values, 'q' to quit X? -10 Y? -10 Z? -10 R=-350.9086 G=-332.4046 B=-424.3584
wonderful :-)
I'm adding the change to my development sources, will commit in a week or so (I have many changes for 2.4 this time)
The attached patch covers the remaining occurences of pow in DefaultEvalParametricFn(). However, I could not test it appropriately.
kind regards Kai-Uwe Behrmann -- www.oyranos.org PS: the patch is attributed to Marti Maria and MIT licensed.
diff --git a/src/cmsgamma.c b/src/cmsgamma.c index 02dc910..1eb127f 100644 --- a/src/cmsgamma.c +++ b/src/cmsgamma.c @@ -250,16 +250,24 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu // X = Y ^ Gamma case 1: - if (R < 0) - Val = 0; + if (R < 0) { + if (Params[0] == 1.0) + Val = R; + else + Val = 0; + } else Val = pow(R, Params[0]); break; // Type 1 Reversed: X = Y ^1/gamma case -1: - if (R < 0) - Val = 0; + if (R < 0) { + if (Params[0] == 1.0) + Val = R; + else + Val = 0; + } else Val = pow(R, 1/Params[0]); break; @@ -276,8 +284,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu if (e > 0) Val = pow(e, Params[0]); - else - Val = 0; + else { + if (Params[0] == 1.0) + Val = e; + else + Val = 0; + } } else Val = 0; @@ -286,13 +298,14 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu // Type 2 Reversed // X = (Y ^1/g - b) / a case -2: - if (R < 0) - Val = 0; + if (R < 0) { + if (Params[0] == 1.0) + Val = R; + else + Val = 0; + } else Val = (pow(R, 1.0/Params[0]) - Params[2]) / Params[1]; - - if (Val < 0) - Val = 0; break; @@ -301,8 +314,6 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu // Y = c | else case 3: disc = -Params[2] / Params[1]; - if (disc < 0) - disc = 0; if (R >= disc) { @@ -310,8 +321,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu if (e > 0) Val = pow(e, Params[0]) + Params[3]; - else - Val = 0; + else { + if (Params[0] == 1.0) + Val = pow(e, Params[0]) + Params[3]; + else + Val = 0; + } } else Val = Params[3]; @@ -328,8 +343,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu if (e > 0) Val = (pow(e, 1/Params[0]) - Params[2]) / Params[1]; - else - Val = 0; + else { + if (Params[0] == 1.0) + Val = (pow(e, 1/Params[0]) - Params[2]) / Params[1]; + else + Val = 0; + } } else { Val = -Params[2] / Params[1]; @@ -347,8 +366,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu if (e > 0) Val = pow(e, Params[0]); - else - Val = 0; + else { + if (Params[0] == 1.0) + Val = e; + else + Val = 0; + } } else Val = R * Params[3]; @@ -359,8 +382,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu // X=Y/c | Y< (ad+b)^g case -4: e = Params[1] * Params[4] + Params[2]; - if (e < 0) - disc = 0; + if (e < 0) { + if (Params[0] == 1.0) + disc = Params[0]; + else + disc = 0; + } else disc = pow(e, Params[0]); @@ -383,8 +410,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu if (e > 0) Val = pow(e, Params[0]) + Params[5]; - else - Val = 0; + else { + if (Params[0] == 1.0) + Val = e + Params[5]; + else + Val = 0; + } } else Val = R*Params[3] + Params[6]; @@ -400,8 +431,12 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu if (R >= disc) { e = R - Params[5]; - if (e < 0) - Val = 0; + if (e < 0) { + if (Params[0] == 1.0) + Val = (e - Params[2]) / Params[1]; + else + Val = 0; + } else Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1]; } @@ -418,8 +453,11 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu case 6: e = Params[1]*R + Params[2]; - if (e < 0) - Val = 0; + if (e < 0) { + if (Params[0] == 1.0) + Val = e + Params[3]; + else + Val = 0; else Val = pow(e, Params[0]) + Params[3]; break; @@ -427,10 +465,14 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu // ((Y - c) ^1/Gamma - b) / a case -6: e = R - Params[3]; - if (e < 0) - Val = 0; + if (e < 0) { + if (Params[0] == 1.0) + Val = (e - Params[2]) / Params[1]; + else + Val = 0; + } else - Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1]; + Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1]; break;
------------------------------------------------------------------------------ For Developers, A Lot Can Happen In A Second. Boundary is the first to Know...and Tell You. Monitor Your Applications in Ultra-Fine Resolution. Try it FREE! http://p.sf.net/sfu/Boundary-d2dvs2
_______________________________________________ Lcms-user mailing list Lcms-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lcms-user