diff options
author | Robin Watts <robin@ghostscript.com> | 2011-05-11 17:12:59 +0000 |
---|---|---|
committer | Robin Watts <robin@ghostscript.com> | 2011-05-11 17:12:59 +0000 |
commit | 2bde8dc655c36ef729964980aa373c26dbe873e5 (patch) | |
tree | 7f10039f9ba90a2ca0b85bfdd460a34ae4b527ee | |
parent | 6469f738123e0c212473f11d38e88bb3650a9087 (diff) |
Backout 6469f73 pending investigation of unexpected differences.
-rw-r--r-- | gs/base/lcms.mak | 2 | ||||
-rw-r--r-- | gs/lcms/include/lcms.h | 2 | ||||
-rw-r--r-- | gs/lcms/src/cmspack.c | 109 | ||||
-rw-r--r-- | gs/lcms/src/cmsxform.c | 667 |
4 files changed, 457 insertions, 323 deletions
diff --git a/gs/base/lcms.mak b/gs/base/lcms.mak index 5014c0ada..c7e8e6e71 100644 --- a/gs/base/lcms.mak +++ b/gs/base/lcms.mak @@ -125,7 +125,7 @@ $(LCMSOBJ)cmsmatsh.$(OBJ) : $(LCMSSRC)cmsmatsh.c $(lcms_HDRS) $(LCMSOBJ)cmsmtrx.$(OBJ) : $(LCMSSRC)cmsmtrx.c $(lcms_HDRS) $(LCMS_CC) $(LCMSO_)cmsmtrx.$(OBJ) $(C_) $(LCMSSRC)cmsmtrx.c -$(LCMSOBJ)cmspack.$(OBJ) : $(LCMSSRC)cmspack.c $(LCMSSRC)cmsxform.h $(lcms_HDRS) +$(LCMSOBJ)cmspack.$(OBJ) : $(LCMSSRC)cmspack.c $(lcms_HDRS) $(LCMS_CC) $(LCMSO_)cmspack.$(OBJ) $(C_) $(LCMSSRC)cmspack.c $(LCMSOBJ)cmspcs.$(OBJ) : $(LCMSSRC)cmspcs.c $(lcms_HDRS) diff --git a/gs/lcms/include/lcms.h b/gs/lcms/include/lcms.h index 269299425..7a061e6a1 100644 --- a/gs/lcms/include/lcms.h +++ b/gs/lcms/include/lcms.h @@ -2056,8 +2056,6 @@ LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints); // Validates a LUT LCMSBOOL cdecl _cmsValidateLUT(LPLUT NewLUT); -// Choose the transform function to use -void _cmsSetPrecalculatedTransform(_LPcmsTRANSFORM p); // These are two VITAL macros, from converting between 8 and 16 bit // representation. diff --git a/gs/lcms/src/cmspack.c b/gs/lcms/src/cmspack.c index 5c409b372..c4c16f9d4 100644 --- a/gs/lcms/src/cmspack.c +++ b/gs/lcms/src/cmspack.c @@ -2135,113 +2135,6 @@ void LCMSEXPORT cmsGetUserFormatters(cmsHTRANSFORM hTransform, } -extern WORD _cmsAlarmR, _cmsAlarmG, _cmsAlarmB; - -// RJW: Move the core transform routines in here, so they can benefit from -// being in the same compilation unit as the pack/unpack routines. -#define FUNCTION_NAME PrecalculatedXFORM -#include "cmsxform.h" - -#define FUNCTION_NAME PrecalculatedXFORMGamutCheck -#define GAMUTCHECK -#include "cmsxform.h" - -#define FUNCTION_NAME CachedXFORM -#define CACHED -#include "cmsxform.h" - -#define FUNCTION_NAME CachedXFORM4 -#define CACHED -#define INBYTES 4 -#include "cmsxform.h" - -#define FUNCTION_NAME CachedXFORM8 -#define CACHED -#define INBYTES 8 -#include "cmsxform.h" - -#define FUNCTION_NAME CachedXFORMGamutCheck -#define CACHED -#define GAMUTCHECK -#include "cmsxform.h" - -#define FUNCTION_NAME CachedXFORM3to1 -#define CACHED -#define INBYTES 6 -#define UNPACK(T,D,S) \ -do { \ - (D)[0] = RGB_8_TO_16(*(S)); (S)++; /* R */ \ - (D)[1] = RGB_8_TO_16(*(S)); (S)++; /* G */ \ - (D)[2] = RGB_8_TO_16(*(S)); (S)++; /* B */ \ -} while (0) -#define PACKFN Pack1Byte -#include "cmsxform.h" - -// Auxiliar: Handle precalculated gamut check - -void TransformOnePixelWithGamutCheck(_LPcmsTRANSFORM p, WORD wIn[], WORD wOut[]) -{ - WORD wOutOfGamut; - - cmsEvalLUT(p ->GamutCheck, wIn, &wOutOfGamut); - - if (wOutOfGamut >= 1) { - - ZeroMemory(wOut, sizeof(WORD) * MAXCHANNELS); - - wOut[0] = _cmsAlarmR; - wOut[1] = _cmsAlarmG; - wOut[2] = _cmsAlarmB; - - } - else - cmsEvalLUT(p -> DeviceLink, wIn, wOut); - -} - -// Identify whatever a transform is to be cached - -void _cmsSetPrecalculatedTransform(_LPcmsTRANSFORM p) -{ - if ((p->dwOriginalFlags & cmsFLAGS_GAMUTCHECK) && p ->GamutCheck != NULL) { - - p -> xform = PrecalculatedXFORMGamutCheck; - - if (!(p->dwOriginalFlags & cmsFLAGS_NOTCACHE)) { - - ZeroMemory(p ->CacheIn, sizeof(WORD) * MAXCHANNELS); - TransformOnePixelWithGamutCheck(p, p->CacheIn, p ->CacheOut); - p ->xform = CachedXFORMGamutCheck; - } - - } - else { - - p -> xform = PrecalculatedXFORM; - - if (!(p->dwOriginalFlags & cmsFLAGS_NOTCACHE)) { - - ZeroMemory(p ->CacheIn, sizeof(WORD) * MAXCHANNELS); - cmsEvalLUT(p ->DeviceLink, p->CacheIn, p ->CacheOut); - if ((p->FromInput == Unroll3Bytes) && - (p->ToOutput == Pack1Byte)) - { - p->xform = CachedXFORM3to1; - } else { - int inbytes = (T_CHANNELS(p->InputFormat) * - T_BYTES(p->InputFormat)); - if (inbytes <= 4) - p->xform = CachedXFORM4; - else if (inbytes <= 8) - p->xform = CachedXFORM8; - else - p->xform = CachedXFORM; - } - } - } -} - - // Change format of yet existing transform. No colorspace checking is performed void LCMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform, @@ -2254,6 +2147,4 @@ void LCMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform, (cmsFORMATTER) _cmsIdentifyInputFormat((_LPcmsTRANSFORM) hTransform, dwInputFormat), dwOutputFormat, (cmsFORMATTER) _cmsIdentifyOutputFormat((_LPcmsTRANSFORM) hTransform, dwOutputFormat)); - - _cmsSetPrecalculatedTransform((_LPcmsTRANSFORM) hTransform); } diff --git a/gs/lcms/src/cmsxform.c b/gs/lcms/src/cmsxform.c index 0ca889dde..8977c9347 100644 --- a/gs/lcms/src/cmsxform.c +++ b/gs/lcms/src/cmsxform.c @@ -2,22 +2,22 @@ // Little cms // Copyright (C) 1998-2007 Marti Maria // -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the Software +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software // is furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in +// The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -63,7 +63,7 @@ LCMSBOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, // Alarm RGB codes -WORD _cmsAlarmR = 0x8fff, _cmsAlarmG = 0x8fff, _cmsAlarmB = 0x8fff; +static WORD AlarmR = 0x8fff, AlarmG = 0x8fff, AlarmB = 0x8fff; // Tag tables, soted by intents @@ -91,7 +91,7 @@ static volatile double GlobalAdaptationState = 0; // --------------------------------Stages-------------------------------------- -// Following routines does implement several kind of steps inside +// Following routines does implement several kind of steps inside // transform. On building the transform, code chooses adequate. @@ -113,7 +113,7 @@ void LUTtoPCS(struct _cmstransform_struct *p, cmsEvalLUT(p -> Device2PCS, In, Out); } -// From indexed named color to PCS +// From indexed named color to PCS static void NC2toPCS(struct _cmstransform_struct *p, @@ -234,12 +234,12 @@ void NormalXFORM(_LPcmsTRANSFORM p, // Gamut check, enabled across CLUT cmsEvalLUT(p -> Gamut, wPCS, wGamut); - - if (wGamut[0] >= 1) { - - wOut[0] = _cmsAlarmR; // Gamut alarm - wOut[1] = _cmsAlarmG; - wOut[2] = _cmsAlarmB; + + if (wGamut[0] >= 1) { + + wOut[0] = AlarmR; // Gamut alarm + wOut[1] = AlarmG; + wOut[2] = AlarmB; wOut[3] = 0; output = p -> ToOutput((_LPcmsTRANSFORM)p, wOut, output); @@ -258,7 +258,7 @@ void NormalXFORM(_LPcmsTRANSFORM p, if (p -> Stage2) { p -> Stage2(wPCS, wStageLMN, &p->m2, &p->of2); - + if (wPCS[0] == 0xFFFF && wPCS[1] == 0xFFFF && wPCS[2] == 0xFFFF) { @@ -284,6 +284,219 @@ void NormalXFORM(_LPcmsTRANSFORM p, } } +// Using precalculated LUT + +static +void PrecalculatedXFORM(_LPcmsTRANSFORM p, + LPVOID in, + LPVOID out, unsigned int Size) +{ + register LPBYTE accum; + register LPBYTE output; + WORD wIn[MAXCHANNELS], wOut[MAXCHANNELS]; + unsigned int i, n; + + + accum = (LPBYTE) in; + output = (LPBYTE) out; + n = Size; // Buffer len + + + for (i=0; i < n; i++) { + + accum = p -> FromInput(p, wIn, accum); + + // Try to speedup things on plain devicelinks + + if (p ->DeviceLink ->wFlags == LUT_HAS3DGRID) { + + p ->DeviceLink ->CLut16params.Interp3D(wIn, wOut, + p ->DeviceLink -> T, + &p ->DeviceLink -> CLut16params); + } + else + cmsEvalLUT(p -> DeviceLink, wIn, wOut); + + + output = p -> ToOutput(p, wOut, output); + } +} + +// Auxiliar: Handle precalculated gamut check + +static +void TransformOnePixelWithGamutCheck(_LPcmsTRANSFORM p, WORD wIn[], WORD wOut[]) +{ + WORD wOutOfGamut; + + cmsEvalLUT(p ->GamutCheck, wIn, &wOutOfGamut); + + if (wOutOfGamut >= 1) { + + ZeroMemory(wOut, sizeof(WORD) * MAXCHANNELS); + + wOut[0] = AlarmR; + wOut[1] = AlarmG; + wOut[2] = AlarmB; + + } + else + cmsEvalLUT(p -> DeviceLink, wIn, wOut); + +} + + +static +void PrecalculatedXFORMGamutCheck(_LPcmsTRANSFORM p, + LPVOID in, + LPVOID out, unsigned int Size) +{ + register LPBYTE accum; + register LPBYTE output; + WORD wIn[MAXCHANNELS], wOut[MAXCHANNELS]; + register unsigned int i, n; + + + accum = (LPBYTE) in; + output = (LPBYTE) out; + n = Size; // Buffer len + + for (i=0; i < n; i++) { + + accum = p -> FromInput(p, wIn, accum); + + TransformOnePixelWithGamutCheck(p, wIn, wOut); + + output = p -> ToOutput(p, wOut, output); + } +} + + + +// Using precalculated LUT + Cache + +static +void CachedXFORM(_LPcmsTRANSFORM p, + LPVOID in, + LPVOID out, unsigned int Size) +{ + register LPBYTE accum; + register LPBYTE output; + WORD wIn[MAXCHANNELS], wOut[MAXCHANNELS]; + register unsigned int i, n; + WORD CacheIn[MAXCHANNELS], CacheOut[MAXCHANNELS]; + + + accum = (LPBYTE) in; + output = (LPBYTE) out; + n = Size; // Buffer len + + // Empty buffers for quick memcmp + + ZeroMemory(wIn, sizeof(WORD) * MAXCHANNELS); + ZeroMemory(wOut, sizeof(WORD) * MAXCHANNELS); + + + LCMS_READ_LOCK(&p ->rwlock); + CopyMemory(CacheIn, p ->CacheIn, sizeof(WORD) * MAXCHANNELS); + CopyMemory(CacheOut, p ->CacheOut, sizeof(WORD) * MAXCHANNELS); + LCMS_UNLOCK(&p ->rwlock); + + for (i=0; i < n; i++) { + + accum = p -> FromInput(p, wIn, accum); + + + if (memcmp(wIn, CacheIn, sizeof(WORD) * MAXCHANNELS) == 0) { + + CopyMemory(wOut, CacheOut, sizeof(WORD) * MAXCHANNELS); + } + else { + + // Try to speedup things on plain devicelinks + + if (p ->DeviceLink ->wFlags == LUT_HAS3DGRID) { + + p ->DeviceLink ->CLut16params.Interp3D(wIn, wOut, + p ->DeviceLink -> T, + &p ->DeviceLink -> CLut16params); + } + else + cmsEvalLUT(p -> DeviceLink, wIn, wOut); + + + CopyMemory(CacheIn, wIn, sizeof(WORD) * MAXCHANNELS); + CopyMemory(CacheOut, wOut, sizeof(WORD) * MAXCHANNELS); + } + + output = p -> ToOutput(p, wOut, output); + } + + + LCMS_WRITE_LOCK(&p ->rwlock); + CopyMemory(p->CacheIn, CacheIn, sizeof(WORD) * MAXCHANNELS); + CopyMemory(p->CacheOut, CacheOut, sizeof(WORD) * MAXCHANNELS); + LCMS_UNLOCK(&p ->rwlock); + +} + + + +// Using precalculated LUT + Cache + +static +void CachedXFORMGamutCheck(_LPcmsTRANSFORM p, + LPVOID in, + LPVOID out, unsigned int Size) +{ + register LPBYTE accum; + register LPBYTE output; + WORD wIn[MAXCHANNELS], wOut[MAXCHANNELS]; + register unsigned int i, n; + WORD CacheIn[MAXCHANNELS], CacheOut[MAXCHANNELS]; + + + accum = (LPBYTE) in; + output = (LPBYTE) out; + n = Size; // Buffer len + + // Empty buffers for quick memcmp + + ZeroMemory(wIn, sizeof(WORD) * MAXCHANNELS); + ZeroMemory(wOut, sizeof(WORD) * MAXCHANNELS); + + LCMS_READ_LOCK(&p ->rwlock); + CopyMemory(CacheIn, p ->CacheIn, sizeof(WORD) * MAXCHANNELS); + CopyMemory(CacheOut, p ->CacheOut, sizeof(WORD) * MAXCHANNELS); + LCMS_UNLOCK(&p ->rwlock); + + + for (i=0; i < n; i++) { + + accum = p -> FromInput(p, wIn, accum); + + if (memcmp(wIn, CacheIn, sizeof(WORD) * MAXCHANNELS) == 0) { + + CopyMemory(wOut, CacheOut, sizeof(WORD) * MAXCHANNELS); + } + else { + + TransformOnePixelWithGamutCheck(p, wIn, wOut); + + CopyMemory(CacheIn, wIn, sizeof(WORD) * MAXCHANNELS); + CopyMemory(CacheOut, wOut, sizeof(WORD) * MAXCHANNELS); + } + + output = p -> ToOutput(p, wOut, output); + } + + LCMS_WRITE_LOCK(&p ->rwlock); + CopyMemory(p->CacheIn, CacheIn, sizeof(WORD) * MAXCHANNELS); + CopyMemory(p->CacheOut, CacheOut, sizeof(WORD) * MAXCHANNELS); + LCMS_UNLOCK(&p ->rwlock); +} + + // Using smelted Matrix/Shaper static @@ -329,11 +542,11 @@ void NC2deviceXform(_LPcmsTRANSFORM p, for (i=0; i < Size; i++) { - accum = p -> FromInput(p, wIn, accum); + accum = p -> FromInput(p, wIn, accum); CopyMemory(wOut, p ->NamedColorList->List[wIn[0]].DeviceColorant, sizeof(WORD) * MAXCHANNELS); output = p -> ToOutput(p, wOut, output); } - + } @@ -404,12 +617,12 @@ LPMATSHAPER cmsBuildGrayInputMatrixShaper(cmsHPROFILE hProfile) else { Shapes[0] = cmsDupGamma(GrayTRC); Shapes[1] = cmsDupGamma(GrayTRC); - Shapes[2] = cmsDupGamma(GrayTRC); + Shapes[2] = cmsDupGamma(GrayTRC); } - + if (!Shapes[0] || !Shapes[1] || !Shapes[2]) return NULL; - + cmsFreeGamma(GrayTRC); // R=G=B as precondition @@ -417,8 +630,8 @@ LPMATSHAPER cmsBuildGrayInputMatrixShaper(cmsHPROFILE hProfile) VEC3init(&Scale.v[0], Illuminant.X/3, Illuminant.X/3, Illuminant.X/3); VEC3init(&Scale.v[1], Illuminant.Y/3, Illuminant.Y/3, Illuminant.Y/3); VEC3init(&Scale.v[2], Illuminant.Z/3, Illuminant.Z/3, Illuminant.Z/3); - - + + MatShaper = cmsAllocMatShaper(&Scale, Shapes, MATSHAPER_INPUT); cmsFreeGammaTriple(Shapes); return MatShaper; @@ -435,27 +648,27 @@ LPMATSHAPER cmsBuildGrayOutputMatrixShaper(cmsHPROFILE hProfile) LPGAMMATABLE GrayTRC, Shapes[3]; LPMATSHAPER MatShaper; MAT3 Scale; - + cmsTakeIluminant(&Illuminant, hProfile); - // That is a special case for non-compliant profiles. + // That is a special case for non-compliant profiles. if (cmsGetPCS(hProfile) == icSigLabData) { - + LPGAMMATABLE Shapes1[3]; GrayTRC = cmsReadICCGamma(hProfile, icSigGrayTRCTag); FromLstarToXYZ(GrayTRC, Shapes1); - if (GrayTRC == NULL) - return NULL; + if (GrayTRC == NULL) + return NULL; // Reversing must be done after curve translation Shapes[0] = cmsReverseGamma(Shapes1[0]->nEntries, Shapes1[0]); Shapes[1] = cmsReverseGamma(Shapes1[1]->nEntries, Shapes1[1]); Shapes[2] = cmsReverseGamma(Shapes1[2]->nEntries, Shapes1[2]); - + cmsFreeGammaTriple(Shapes1); } @@ -465,24 +678,24 @@ LPMATSHAPER cmsBuildGrayOutputMatrixShaper(cmsHPROFILE hProfile) GrayTRC = cmsReadICCGammaReversed(hProfile, icSigGrayTRCTag); // Y - if (GrayTRC == NULL) - return NULL; + if (GrayTRC == NULL) + return NULL; Shapes[0] = cmsDupGamma(GrayTRC); Shapes[1] = cmsDupGamma(GrayTRC); - Shapes[2] = cmsDupGamma(GrayTRC); + Shapes[2] = cmsDupGamma(GrayTRC); } - + if (!Shapes[0] || !Shapes[1] || !Shapes[2]) return NULL; - + cmsFreeGamma(GrayTRC); VEC3init(&Scale.v[0], 0, 1.0/Illuminant.Y, 0); VEC3init(&Scale.v[1], 0, 1.0/Illuminant.Y, 0); VEC3init(&Scale.v[2], 0, 1.0/Illuminant.Y, 0); - - + + MatShaper = cmsAllocMatShaper(&Scale, Shapes, MATSHAPER_OUTPUT); cmsFreeGammaTriple(Shapes); return MatShaper; @@ -504,8 +717,8 @@ LPMATSHAPER cmsBuildInputMatrixShaper(cmsHPROFILE InputProfile) // iluminant, scaled across GrayTRC if (cmsGetColorSpace(InputProfile) == icSigGrayData) - { - return cmsBuildGrayInputMatrixShaper(InputProfile); + { + return cmsBuildGrayInputMatrixShaper(InputProfile); } if (!cmsReadICCMatrixRGB2XYZ(&DoubleMat, InputProfile)) @@ -521,7 +734,7 @@ LPMATSHAPER cmsBuildInputMatrixShaper(cmsHPROFILE InputProfile) InMatSh = cmsAllocMatShaper(&DoubleMat, Shapes, MATSHAPER_INPUT); cmsFreeGammaTriple(Shapes); - + return InMatSh; } @@ -535,11 +748,11 @@ LPMATSHAPER cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile) LPGAMMATABLE InverseShapes[3]; LPMATSHAPER OutMatSh; - + if (cmsGetColorSpace(OutputProfile) == icSigGrayData) - { - return cmsBuildGrayOutputMatrixShaper(OutputProfile); + { + return cmsBuildGrayOutputMatrixShaper(OutputProfile); } @@ -549,11 +762,11 @@ LPMATSHAPER cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile) if (MAT3inverse(&DoubleMat, &DoubleInv) < 0) return NULL; - + InverseShapes[0] = cmsReadICCGammaReversed(OutputProfile, icSigRedTRCTag); InverseShapes[1] = cmsReadICCGammaReversed(OutputProfile, icSigGreenTRCTag); InverseShapes[2] = cmsReadICCGammaReversed(OutputProfile, icSigBlueTRCTag); - + if (InverseShapes[0] == NULL || InverseShapes[1] == NULL || InverseShapes[2] == NULL) return NULL; @@ -561,7 +774,7 @@ LPMATSHAPER cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile) OutMatSh = cmsAllocMatShaper(&DoubleInv, InverseShapes, MATSHAPER_OUTPUT); cmsFreeGammaTriple(InverseShapes); - + return OutMatSh; } @@ -574,8 +787,8 @@ LCMSBOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p) { MAT3 From, To, ToInv, Transfer; LPGAMMATABLE In[3], InverseOut[3]; - - + + if (!cmsReadICCMatrixRGB2XYZ(&From, p -> InputProfile)) return FALSE; @@ -584,14 +797,14 @@ LCMSBOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p) return FALSE; // invert dest - + if (MAT3inverse(&To, &ToInv) < 0) return FALSE; // Multiply - MAT3per(&Transfer, &ToInv, &From); - - + MAT3per(&Transfer, &ToInv, &From); + + // Read gamma curves In[0] = cmsReadICCGamma(p -> InputProfile, icSigRedTRCTag); @@ -600,14 +813,14 @@ LCMSBOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p) if (!In[0] || !In[1] || !In[2]) return FALSE; - + InverseOut[0] = cmsReadICCGammaReversed(p -> OutputProfile, icSigRedTRCTag); InverseOut[1] = cmsReadICCGammaReversed(p -> OutputProfile, icSigGreenTRCTag); InverseOut[2] = cmsReadICCGammaReversed(p -> OutputProfile, icSigBlueTRCTag); if (!InverseOut[0] || !InverseOut[1] || !InverseOut[2]) { - cmsFreeGammaTriple(In); + cmsFreeGammaTriple(In); return FALSE; } @@ -615,7 +828,7 @@ LCMSBOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p) cmsFreeGammaTriple(In); cmsFreeGammaTriple(InverseOut); - + return (p -> SmeltMatShaper != NULL); } @@ -628,7 +841,7 @@ LCMSBOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p) static int GetPhase(cmsHPROFILE hProfile) -{ +{ switch (cmsGetPCS(hProfile)) { case icSigXYZData: return XYZRel; @@ -664,9 +877,9 @@ void TakeConversionRoutines(_LPcmsTRANSFORM p, int DoBPC) cmsTakeMediaBlackPoint(&BlackPointOut, p -> OutputProfile); cmsReadChromaticAdaptationMatrix(&ChromaticAdaptationMatrixOut, p -> OutputProfile); - + if (p -> Preview == NULL && p ->Gamut == NULL) // Non-proofing - { + { if (p ->Intent == INTENT_PERCEPTUAL || p ->Intent == INTENT_SATURATION) { @@ -683,34 +896,34 @@ void TakeConversionRoutines(_LPcmsTRANSFORM p, int DoBPC) // Black point compensation does not apply to absolute intent - if (p ->Intent == INTENT_ABSOLUTE_COLORIMETRIC) + if (p ->Intent == INTENT_ABSOLUTE_COLORIMETRIC) DoBPC = FALSE; // Black point compensation does not apply to devicelink profiles - + if (cmsGetDeviceClass(p ->InputProfile) == icSigLinkClass) DoBPC = FALSE; if (cmsGetDeviceClass(p ->OutputProfile) == icSigLinkClass) DoBPC = FALSE; - + if (DoBPC) { - + // Detect Black points cmsDetectBlackPoint(&BlackPointIn, p->InputProfile, p->Intent, 0); - cmsDetectBlackPoint(&BlackPointOut, p->OutputProfile, p->Intent, 0); + cmsDetectBlackPoint(&BlackPointOut, p->OutputProfile, p->Intent, 0); // If equal black points, then do nothing. This often applies to BP=0 if (BlackPointIn.X == BlackPointOut.X && BlackPointIn.Y == BlackPointOut.Y && - BlackPointIn.Z == BlackPointOut.Z) + BlackPointIn.Z == BlackPointOut.Z) DoBPC = FALSE; } - + cmsChooseCnvrt(p -> Intent == INTENT_ABSOLUTE_COLORIMETRIC, p -> Phase1, @@ -734,7 +947,7 @@ void TakeConversionRoutines(_LPcmsTRANSFORM p, int DoBPC) else // Proofing { - + cmsTakeIluminant(&IlluminantProof, p -> PreviewProfile); cmsTakeMediaWhitePoint(&WhitePointProof, p -> PreviewProfile); cmsTakeMediaBlackPoint(&BlackPointProof, p -> PreviewProfile); @@ -744,19 +957,19 @@ void TakeConversionRoutines(_LPcmsTRANSFORM p, int DoBPC) cmsDetectBlackPoint(&BlackPointProof, p->PreviewProfile, p->Intent, 0); cmsDetectBlackPoint(&BlackPointIn, p->InputProfile, p->Intent, 0); - cmsDetectBlackPoint(&BlackPointOut, p->OutputProfile, p->Intent, 0); - + cmsDetectBlackPoint(&BlackPointOut, p->OutputProfile, p->Intent, 0); + // Reality check if (BlackPointIn.X == BlackPointProof.X && BlackPointIn.Y == BlackPointProof.Y && - BlackPointIn.Z == BlackPointProof.Z) + BlackPointIn.Z == BlackPointProof.Z) DoBPC = FALSE; } - + cmsChooseCnvrt(p -> Intent == INTENT_ABSOLUTE_COLORIMETRIC, @@ -855,11 +1068,43 @@ _LPcmsTRANSFORM AllocEmptyTransform(void) return p; } -// Transform is identified as device-link + +// Identify whatever a transform is to be cached + static -cmsHPROFILE CreateDeviceLinkTransform(_LPcmsTRANSFORM p) +void SetPrecalculatedTransform(_LPcmsTRANSFORM p) { + if ((p->dwOriginalFlags & cmsFLAGS_GAMUTCHECK) && p ->GamutCheck != NULL) { + + p -> xform = PrecalculatedXFORMGamutCheck; + + if (!(p->dwOriginalFlags & cmsFLAGS_NOTCACHE)) { + + ZeroMemory(p ->CacheIn, sizeof(WORD) * MAXCHANNELS); + TransformOnePixelWithGamutCheck(p, p->CacheIn, p ->CacheOut); + p ->xform = CachedXFORMGamutCheck; + } + + } + else { + + p -> xform = PrecalculatedXFORM; + + if (!(p->dwOriginalFlags & cmsFLAGS_NOTCACHE)) { + + ZeroMemory(p ->CacheIn, sizeof(WORD) * MAXCHANNELS); + cmsEvalLUT(p ->DeviceLink, p->CacheIn, p ->CacheOut); + p ->xform = CachedXFORM; + } + } +} + +// Transform is identified as device-link +static +cmsHPROFILE CreateDeviceLinkTransform(_LPcmsTRANSFORM p) +{ + if (!IsProperColorSpace(p->InputProfile, p->InputFormat, FALSE)) { cmsSignalError(LCMS_ERRC_ABORTED, "Device link is operating on wrong colorspace on input"); return NULL; @@ -893,17 +1138,17 @@ cmsHPROFILE CreateDeviceLinkTransform(_LPcmsTRANSFORM p) p -> Phase2 = -1; p -> Phase3 = -1; - _cmsSetPrecalculatedTransform(p); - + SetPrecalculatedTransform(p); + p -> EntryColorSpace = cmsGetColorSpace(p -> InputProfile); p -> ExitColorSpace = cmsGetPCS(p -> InputProfile); - + if (p ->EntryColorSpace == icSigRgbData || p ->EntryColorSpace == icSigCmyData) { - + p->DeviceLink -> CLut16params.Interp3D = cmsTetrahedralInterp16; } - + // Precalculated device-link profile is ready return (cmsHTRANSFORM) p; } @@ -915,13 +1160,13 @@ void CreateProof(_LPcmsTRANSFORM p, icTagSignature *ToTagPtr) { icTagSignature ProofTag; - + if (p -> dwOriginalFlags & cmsFLAGS_SOFTPROOFING) { // Apr-15, 2002 - Too much profiles does have bogus content // on preview tag, so I do compute it by my own. - p -> Preview = _cmsComputeSoftProofLUT(p ->PreviewProfile, p ->Intent); + p -> Preview = _cmsComputeSoftProofLUT(p ->PreviewProfile, p ->Intent); p -> Phase2 = LabRel; // That's a proofing transfor, so use second intent for output. @@ -929,7 +1174,7 @@ void CreateProof(_LPcmsTRANSFORM p, icTagSignature *ToTagPtr) *ToTagPtr = PCS2Device[p->ProofIntent]; if (p -> Preview == NULL) { - + ProofTag = Preview[p -> Intent]; if (!cmsIsTag(p ->PreviewProfile, ProofTag)) { @@ -943,7 +1188,7 @@ void CreateProof(_LPcmsTRANSFORM p, icTagSignature *ToTagPtr) p -> Preview = cmsReadICCLut(p ->PreviewProfile, ProofTag); p -> Phase2 = GetPhase(p ->PreviewProfile); - + } else { @@ -952,7 +1197,7 @@ void CreateProof(_LPcmsTRANSFORM p, icTagSignature *ToTagPtr) cmsSignalError(LCMS_ERRC_WARNING, "Sorry, the proof profile has not previewing capabilities"); } } - + } @@ -961,23 +1206,23 @@ void CreateProof(_LPcmsTRANSFORM p, icTagSignature *ToTagPtr) if ((p -> dwOriginalFlags & cmsFLAGS_GAMUTCHECK) && (p -> dwOriginalFlags & cmsFLAGS_NOTPRECALC)) { - - p -> Gamut = _cmsComputeGamutLUT(p->PreviewProfile, p ->Intent); + + p -> Gamut = _cmsComputeGamutLUT(p->PreviewProfile, p ->Intent); p -> Phase2 = LabRel; if (p -> Gamut == NULL) { - // Profile goes only in one direction... try to see + // Profile goes only in one direction... try to see // if profile has the tag, and use it, no matter it // could be bogus. This is the last chance! if (cmsIsTag(p ->PreviewProfile, icSigGamutTag)) { p -> Gamut = cmsReadICCLut(p ->PreviewProfile, icSigGamutTag); - + } else { - + // Nope, cannot be done. cmsSignalError(LCMS_ERRC_WARNING, "Sorry, the proof profile has not gamut checking capabilities"); @@ -992,13 +1237,13 @@ void CreateProof(_LPcmsTRANSFORM p, icTagSignature *ToTagPtr) // Choose the adequate transform routine static -_LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p, +_LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p, icTagSignature *FromTagPtr, icTagSignature *ToTagPtr) { - - + + // Is a named color profile? if (cmsGetDeviceClass(p->InputProfile) == icSigNamedColorClass) { @@ -1009,11 +1254,11 @@ _LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p, else { // Can we optimize matrix-shaper only transform? - if ((*FromTagPtr == 0) && - (*ToTagPtr == 0) && - (!p->PreviewProfile) && - (p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC) && - (p -> EntryColorSpace == icSigRgbData) && + if ((*FromTagPtr == 0) && + (*ToTagPtr == 0) && + (!p->PreviewProfile) && + (p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC) && + (p -> EntryColorSpace == icSigRgbData) && (p -> ExitColorSpace == icSigRgbData) && !(p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION)) { @@ -1023,7 +1268,7 @@ _LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p, if (!cmsBuildSmeltMatShaper(p)) { - cmsSignalError(LCMS_ERRC_ABORTED, "unable to smelt shaper-matrix, required tags missing"); + cmsSignalError(LCMS_ERRC_ABORTED, "unable to smelt shaper-matrix, required tags missing"); return NULL; } @@ -1040,7 +1285,7 @@ _LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p, p -> Device2PCS = cmsReadICCLut(p -> InputProfile, *FromTagPtr); if (!p -> Device2PCS) { - cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for input"); + cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for input"); return NULL; } @@ -1051,7 +1296,7 @@ _LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p, p -> InMatShaper = cmsBuildInputMatrixShaper(p -> InputProfile); if (!p ->InMatShaper) { - cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for input"); + cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for input"); return NULL; } @@ -1065,7 +1310,7 @@ _LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p, p -> ToDevice = PCStoLUT; p -> PCS2Device = cmsReadICCLut(p -> OutputProfile, *ToTagPtr); if (!p -> PCS2Device) { - cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for output"); + cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for output"); return NULL; } @@ -1076,13 +1321,13 @@ _LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p, p -> OutMatShaper = cmsBuildOutputMatrixShaper(p->OutputProfile); if (!p -> OutMatShaper) { - cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for output"); + cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for output"); return NULL; } p -> Phase3 = XYZRel; - + } - + return p; } @@ -1105,7 +1350,7 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, _LPcmsTRANSFORM p; icTagSignature FromTag; icTagSignature ToTag; - + if (nIntent < 0 || nIntent > 3 || ProofingIntent < 0 || ProofingIntent > 3) { @@ -1122,7 +1367,7 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, p -> DoGamutCheck = FALSE; p -> InputProfile = InputProfile; p -> OutputProfile = OutputProfile; - p -> PreviewProfile = ProofingProfile; + p -> PreviewProfile = ProofingProfile; p -> InputFormat = InputFormat; p -> OutputFormat = OutputFormat; p -> dwOriginalFlags = dwFlags; @@ -1144,7 +1389,7 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, // From here we need at least one input profile if (InputProfile == NULL) { - + cmsSignalError(LCMS_ERRC_ABORTED, "Input profile cannot be NULL!"); cmsDeleteTransform((cmsHTRANSFORM) p); return NULL; @@ -1156,7 +1401,7 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, return CreateDeviceLinkTransform(p); } - + if (!IsProperColorSpace(InputProfile, InputFormat, FALSE)) { cmsSignalError(LCMS_ERRC_ABORTED, "Input profile is operating on wrong colorspace"); @@ -1173,7 +1418,7 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, p ->NamedColorList = cmsAllocNamedColorList(0); cmsReadICCnamedColorList(p, InputProfile, icSigNamedColor2Tag); - + // Special case. If output profile == NULL, then the transform gives // device values from named colors. @@ -1188,18 +1433,18 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, p -> dwOriginalFlags |= cmsFLAGS_NOTPRECALC; } - + // From here we need also output profile. - if (OutputProfile == NULL) { + if (OutputProfile == NULL) { cmsSignalError(LCMS_ERRC_ABORTED, "Output profile cannot be NULL!"); cmsDeleteTransform((cmsHTRANSFORM) p); return NULL; } - + if (!IsProperColorSpace(OutputProfile, OutputFormat, FALSE)) { cmsSignalError(LCMS_ERRC_ABORTED, "Output profile is operating on wrong colorspace"); - cmsDeleteTransform((cmsHTRANSFORM) p); + cmsDeleteTransform((cmsHTRANSFORM) p); return NULL; } @@ -1232,22 +1477,22 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, } // If proofing is needed, add required tags/parameters - if (ProofingProfile) - CreateProof(p, &ToTag); - + if (ProofingProfile) + CreateProof(p, &ToTag); + if (!cmsIsTag(OutputProfile, ToTag)) { ToTag = PCS2Device[0]; - // 12-Dec-2003, Abstract profiles can be placed as output and still using AToB0 + // 12-Dec-2003, Abstract profiles can be placed as output and still using AToB0 if (cmsGetDeviceClass(OutputProfile) == icSigAbstractClass) { - + if (!cmsIsTag(OutputProfile, ToTag)) { ToTag = (icTagSignature) icSigAToB0Tag; - } + } } - + if (!cmsIsTag(OutputProfile, ToTag)) ToTag = (icTagSignature)0; } @@ -1259,8 +1504,8 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, if (p -> dwOriginalFlags & cmsFLAGS_MATRIXOUTPUT) ToTag = (icTagSignature)0; - - + + if (PickTransformRoutine(p, &FromTag, &ToTag) == NULL) { cmsDeleteTransform((cmsHTRANSFORM) p); @@ -1272,9 +1517,9 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, if (!(p -> dwOriginalFlags & cmsFLAGS_NOTPRECALC)) { - LPLUT DeviceLink; + LPLUT DeviceLink; LPLUT GamutCheck = NULL; - + if (p ->EntryColorSpace == icSigCmykData && p ->ExitColorSpace == icSigCmykData && @@ -1283,44 +1528,44 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, DeviceLink = _cmsPrecalculateBlackPreservingDeviceLink((cmsHTRANSFORM) p, dwFlags); // Cannot be done at all? - if (DeviceLink == NULL) + if (DeviceLink == NULL) DeviceLink = _cmsPrecalculateDeviceLink((cmsHTRANSFORM) p, dwFlags); - } + } else { DeviceLink = _cmsPrecalculateDeviceLink((cmsHTRANSFORM) p, dwFlags); } - - // Allow to specify cmsFLAGS_GAMUTCHECK, even if no proofing profile is given + + // Allow to specify cmsFLAGS_GAMUTCHECK, even if no proofing profile is given if ((p ->PreviewProfile != NULL) && (p -> dwOriginalFlags & cmsFLAGS_GAMUTCHECK)) { GamutCheck = _cmsPrecalculateGamutCheck((cmsHTRANSFORM) p); } // If input colorspace is Rgb, Cmy, then use tetrahedral interpolation - // for speed reasons (it only works well on spaces on Luma is diagonal, and + // for speed reasons (it only works well on spaces on Luma is diagonal, and // not if luma is in separate channel) if (p ->EntryColorSpace == icSigRgbData || p ->EntryColorSpace == icSigCmyData) { - - + + cmsCalcCLUT16ParamsEx(DeviceLink->CLut16params.nSamples, DeviceLink->CLut16params.nInputs, - DeviceLink->CLut16params.nOutputs, + DeviceLink->CLut16params.nOutputs, TRUE, &DeviceLink->CLut16params); - + } - + // If this is a 8-bit transform, optimize LUT further. - + if ((T_BYTES(InputFormat) == 1) && (T_CHANNELS(InputFormat) == 3)) { DeviceLink = _cmsBlessLUT8(DeviceLink); if (DeviceLink == NULL) return NULL; } - + p ->GamutCheck = GamutCheck; @@ -1328,7 +1573,7 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, p ->DeviceLink = DeviceLink; - if ((nIntent != INTENT_ABSOLUTE_COLORIMETRIC) && + if ((nIntent != INTENT_ABSOLUTE_COLORIMETRIC) && !(p -> dwOriginalFlags & cmsFLAGS_NOWHITEONWHITEFIXUP)) _cmsFixWhiteMisalignment(p); @@ -1346,8 +1591,8 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, } - _cmsSetPrecalculatedTransform(p); - + SetPrecalculatedTransform(p); + } @@ -1355,7 +1600,7 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, p -> FromInput = _cmsIdentifyInputFormat(p, InputFormat); p -> ToOutput = _cmsIdentifyOutputFormat(p, OutputFormat); - + return p; } @@ -1403,7 +1648,7 @@ void LCMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform) if (p ->NamedColorList) cmsFreeNamedColorList(p ->NamedColorList); if (p -> GamutCheck) - cmsFreeLUT(p -> GamutCheck); + cmsFreeLUT(p -> GamutCheck); LCMS_FREE_LOCK(&p->rwlock); @@ -1421,7 +1666,7 @@ void LCMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform, _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) (LPSTR) Transform; p -> StrideIn = p -> StrideOut = Size; - + p -> xform(p, InputBuffer, OutputBuffer, Size); } @@ -1429,26 +1674,26 @@ void LCMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform, void LCMSEXPORT cmsSetAlarmCodes(int r, int g, int b) { - _cmsAlarmR = RGB_8_TO_16(r); - _cmsAlarmG = RGB_8_TO_16(g); - _cmsAlarmB = RGB_8_TO_16(b); + AlarmR = RGB_8_TO_16(r); + AlarmG = RGB_8_TO_16(g); + AlarmB = RGB_8_TO_16(b); } void LCMSEXPORT cmsGetAlarmCodes(int *r, int *g, int *b) { - *r = RGB_16_TO_8(_cmsAlarmR); - *g = RGB_16_TO_8(_cmsAlarmG); - *b = RGB_16_TO_8(_cmsAlarmB); + *r = RGB_16_TO_8(AlarmR); + *g = RGB_16_TO_8(AlarmG); + *b = RGB_16_TO_8(AlarmB); } // Returns TRUE if the profile is implemented as matrix-shaper LCMSBOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile) -{ +{ switch (cmsGetColorSpace(hProfile)) { case icSigGrayData: - + return cmsIsTag(hProfile, icSigGrayTRCTag); case icSigRgbData: @@ -1495,20 +1740,20 @@ LCMSBOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, return (cmsTakeRenderingIntent(hProfile) == Intent); } -// Multiple profile transform. +// Multiple profile transform. static int MultiprofileSampler(register WORD In[], register WORD Out[], register LPVOID Cargo) { cmsHTRANSFORM* Transforms = (cmsHTRANSFORM*) Cargo; int i; - + cmsDoTransform(Transforms[0], In, Out, 1); for (i=1; Transforms[i]; i++) cmsDoTransform(Transforms[i], Out, Out, 1); - + return TRUE; } @@ -1538,14 +1783,14 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], cmsHTRANSFORM Transforms[257]; DWORD dwPrecalcFlags = (dwFlags|cmsFLAGS_NOTPRECALC|cmsFLAGS_NOTCACHE); DWORD FormatInput, FormatOutput; - cmsHPROFILE hLab, hXYZ, hProfile; + cmsHPROFILE hLab, hXYZ, hProfile; icColorSpaceSignature ColorSpace, CurrentColorSpace; - icColorSpaceSignature ColorSpaceIn, ColorSpaceOut; + icColorSpaceSignature ColorSpaceIn, ColorSpaceOut; LPLUT Grid; - int nGridPoints, ChannelsInput, ChannelsOutput = 3, i; - _LPcmsTRANSFORM p; + int nGridPoints, ChannelsInput, ChannelsOutput = 3, i; + _LPcmsTRANSFORM p; int nNamedColor; - + if (nProfiles > 255) { cmsSignalError(LCMS_ERRC_ABORTED, "What are you trying to do with more that 255 profiles?!?, of course aborted"); return NULL; @@ -1554,7 +1799,7 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], // There is a simple case with just two profiles, try to catch it in order of getting // black preservation to work on this function, at least with two profiles. - + if (nProfiles == 2) { icProfileClassSignature Class1 = cmsGetDeviceClass(hProfiles[0]); @@ -1562,20 +1807,20 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], // Only input, output and display are allowed - if (IsAllowedInSingleXform(Class1) && - IsAllowedInSingleXform(Class2)) + if (IsAllowedInSingleXform(Class1) && + IsAllowedInSingleXform(Class2)) return cmsCreateTransform(hProfiles[0], dwInput, hProfiles[1], dwOutput, Intent, dwFlags); } - + // Creates a phantom transform for latter filling - p = (_LPcmsTRANSFORM) cmsCreateTransform(NULL, dwInput, + p = (_LPcmsTRANSFORM) cmsCreateTransform(NULL, dwInput, NULL, dwOutput, Intent, cmsFLAGS_NULLTRANSFORM); // If user wants null one, give it if (dwFlags & cmsFLAGS_NULLTRANSFORM) return (cmsHPROFILE) p; - // Is a bunch of named color profiles? + // Is a bunch of named color profiles? nNamedColor = 0; for (i=0; i < nProfiles; i++) { if (cmsGetDeviceClass(hProfiles[i]) == icSigNamedColorClass) @@ -1618,8 +1863,8 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], // Take some info.... - p ->EntryColorSpace = CurrentColorSpace = cmsGetColorSpace(hProfiles[0]); - + p ->EntryColorSpace = CurrentColorSpace = cmsGetColorSpace(hProfiles[0]); + for (i=0; i < nProfiles; i++) { @@ -1639,99 +1884,99 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], } else { - + ColorSpaceIn = cmsGetPCS(hProfile); ColorSpaceOut = cmsGetColorSpace(hProfile); } ChannelsInput = _cmsChannelsOf(ColorSpaceIn); ChannelsOutput = _cmsChannelsOf(ColorSpaceOut); - + FormatInput = BYTES_SH(2)|CHANNELS_SH(ChannelsInput); FormatOutput = BYTES_SH(2)|CHANNELS_SH(ChannelsOutput); - + ColorSpace = ColorSpaceIn; - + if (ColorSpace == CurrentColorSpace) { - + if (lIsDeviceLink) { - Transforms[i] = cmsCreateTransform(hProfile, FormatInput, - NULL, FormatOutput, - Intent, dwPrecalcFlags); + Transforms[i] = cmsCreateTransform(hProfile, FormatInput, + NULL, FormatOutput, + Intent, dwPrecalcFlags); } else { if (lIsInput) { - Transforms[i] = cmsCreateTransform(hProfile, FormatInput, - (ColorSpaceOut == icSigLabData ? hLab : hXYZ), FormatOutput, - Intent, dwPrecalcFlags); + Transforms[i] = cmsCreateTransform(hProfile, FormatInput, + (ColorSpaceOut == icSigLabData ? hLab : hXYZ), FormatOutput, + Intent, dwPrecalcFlags); } else { - Transforms[i] = cmsCreateTransform((ColorSpaceIn == icSigLabData ? hLab : hXYZ), FormatInput, - hProfile, FormatOutput, - Intent, dwPrecalcFlags); - + Transforms[i] = cmsCreateTransform((ColorSpaceIn == icSigLabData ? hLab : hXYZ), FormatInput, + hProfile, FormatOutput, + Intent, dwPrecalcFlags); + } - } - - + } + + } else // Can come from pcs? if (CurrentColorSpace == icSigXYZData) { - Transforms[i] = cmsCreateTransform(hXYZ, FormatInput, - hProfile, FormatOutput, - Intent, dwPrecalcFlags); - + Transforms[i] = cmsCreateTransform(hXYZ, FormatInput, + hProfile, FormatOutput, + Intent, dwPrecalcFlags); + } else if (CurrentColorSpace == icSigLabData) { - Transforms[i] = cmsCreateTransform(hLab, FormatInput, - hProfile, FormatOutput, + Transforms[i] = cmsCreateTransform(hLab, FormatInput, + hProfile, FormatOutput, Intent, dwPrecalcFlags); - - } + + } else { cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateMultiprofileTransform: ColorSpace mismatch"); goto ErrorCleanup; } CurrentColorSpace = ColorSpaceOut; - + } p ->ExitColorSpace = CurrentColorSpace; - Transforms[i] = NULL; // End marker + Transforms[i] = NULL; // End marker p ->InputProfile = hProfiles[0]; p ->OutputProfile = hProfiles[nProfiles - 1]; nGridPoints = _cmsReasonableGridpointsByColorspace(p ->EntryColorSpace, dwFlags); - + ChannelsInput = _cmsChannelsOf(cmsGetColorSpace(p ->InputProfile)); - + Grid = cmsAlloc3DGrid(Grid, nGridPoints, ChannelsInput, ChannelsOutput); if (!(dwFlags & cmsFLAGS_NOPRELINEARIZATION)) _cmsComputePrelinearizationTablesFromXFORM(Transforms, nProfiles, Grid); - - // Compute device link on 16-bit basis + + // Compute device link on 16-bit basis if (!cmsSample3DGrid(Grid, MultiprofileSampler, (LPVOID) Transforms, Grid -> wFlags)) { cmsFreeLUT(Grid); goto ErrorCleanup; } - // All ok, store the newly created LUT + // All ok, store the newly created LUT p -> DeviceLink = Grid; - _cmsSetPrecalculatedTransform(p); - + SetPrecalculatedTransform(p); + for (i=nProfiles-1; i >= 0; --i) cmsDeleteTransform(Transforms[i]); @@ -1739,15 +1984,15 @@ cmsHTRANSFORM LCMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], if (hLab) cmsCloseProfile(hLab); if (hXYZ) cmsCloseProfile(hXYZ); - + if (p ->EntryColorSpace == icSigRgbData || p ->EntryColorSpace == icSigCmyData) { - + p->DeviceLink -> CLut16params.Interp3D = cmsTetrahedralInterp16; } + - - if ((Intent != INTENT_ABSOLUTE_COLORIMETRIC) && + if ((Intent != INTENT_ABSOLUTE_COLORIMETRIC) && !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP)) _cmsFixWhiteMisalignment(p); @@ -1762,14 +2007,14 @@ ErrorCleanup: } - + double LCMSEXPORT cmsSetAdaptationState(double d) { double OldVal = GlobalAdaptationState; - if (d >= 0) + if (d >= 0) GlobalAdaptationState = d; return OldVal; - + } |