📄 cmsxform.c
字号:
else return (Space == _cmsLCMScolorSpace(cmsGetColorSpace(hProfile)));}// Auxiliary: allocate transform struct and set to defaultsstatic_LPcmsTRANSFORM AllocEmptyTransform(void){ // Allocate needed memory _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) malloc(sizeof(_cmsTRANSFORM)); if (!p) { cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateTransform: malloc() failed"); return NULL; } ZeroMemory(p, sizeof(_cmsTRANSFORM)); // Initialize default methods p -> xform = NULL; p -> Intent = INTENT_PERCEPTUAL; p -> ProofIntent = INTENT_ABSOLUTE_COLORIMETRIC; p -> DoGamutCheck = FALSE; p -> InputProfile = NULL; p -> OutputProfile = NULL; p -> PreviewProfile = NULL; p -> Preview = NULL; p -> Gamut = NULL; p -> DeviceLink = NULL; p -> InMatShaper = NULL; p -> OutMatShaper = NULL; p -> SmeltMatShaper = NULL; p -> NamedColorList = NULL; p -> EntryColorSpace = (icColorSpaceSignature) 0; p -> ExitColorSpace = (icColorSpaceSignature) 0; p -> AdaptationState = GlobalAdaptationState; return p;}// Identify whatever a transform is to be cachedstaticvoid SetPrecalculatedTransform(_LPcmsTRANSFORM p, DWORD dwFlags){ if (dwFlags & cmsFLAGS_GAMUTCHECK && p ->GamutCheck != NULL) { p -> xform = PrecalculatedXFORMGamutCheck; if (!(dwFlags & cmsFLAGS_NOTCACHE)) { ZeroMemory(p ->CacheIn, sizeof(WORD) * MAXCHANNELS); TransformOnePixelWithGamutCheck(p, p->CacheIn, p ->CacheOut); p ->xform = CachedXFORMGamutCheck; } } else { p -> xform = PrecalculatedXFORM; if (!(dwFlags & cmsFLAGS_NOTCACHE)) { ZeroMemory(p ->CacheIn, sizeof(WORD) * MAXCHANNELS); cmsEvalLUT(p ->DeviceLink, p->CacheIn, p ->CacheOut); p ->xform = CachedXFORM; } }}// Transform is identified as device-linkstatic cmsHPROFILE CreateDeviceLinkTransform(_LPcmsTRANSFORM p, DWORD dwFlags){ if (!IsProperColorSpace(p->InputProfile, p->InputFormat, FALSE)) { cmsSignalError(LCMS_ERRC_ABORTED, "Device link is operating on wrong colorspace on input"); return NULL; } if (!IsProperColorSpace(p->InputProfile, p->OutputFormat, TRUE)) { cmsSignalError(LCMS_ERRC_ABORTED, "Device link is operating on wrong colorspace on output"); return NULL; } // Device link does only have AToB0Tag (ICC-Spec 1998/09) p->DeviceLink = cmsReadICCLut(p->InputProfile, icSigAToB0Tag); if (!p->DeviceLink) { cmsSignalError(LCMS_ERRC_ABORTED, "Noncompliant device-link profile"); cmsDeleteTransform((cmsHTRANSFORM) p); return NULL; } if (p ->PreviewProfile != NULL) { cmsSignalError(LCMS_ERRC_WARNING, "Proofing not supported on device link transforms"); } if (p ->OutputProfile != NULL) { cmsSignalError(LCMS_ERRC_WARNING, "Output profile should be NULL, since this is a device-link transform"); } p -> Phase1 = -1; p -> Phase2 = -1; p -> Phase3 = -1; SetPrecalculatedTransform(p, dwFlags); 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;}// Transform that includes proofingstaticvoid CreateProof(_LPcmsTRANSFORM p, DWORD dwFlags, icTagSignature *ToTagPtr){ icTagSignature ProofTag; if (dwFlags & 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 -> Phase2 = LabRel; // That's a proofing transfor, so use second intent for output. *ToTagPtr = PCS2Device[p->ProofIntent]; if (p -> Preview == NULL) { ProofTag = Preview[p -> Intent]; if (!cmsIsTag(p ->PreviewProfile, ProofTag)) { ProofTag = Preview[0]; if (!cmsIsTag(p ->PreviewProfile, ProofTag)) ProofTag = (icTagSignature)0; } if (ProofTag) { p -> Preview = cmsReadICCLut(p ->PreviewProfile, ProofTag); p -> Phase2 = GetPhase(p ->PreviewProfile); } else { p -> Preview = NULL; p ->PreviewProfile = NULL; cmsSignalError(LCMS_ERRC_WARNING, "Sorry, the proof profile has not previewing capabilities"); } } } // Aug-31, 2001 - Too much profiles does have bogus content // on gamut tag, so I do compute it by my own. if ((dwFlags & cmsFLAGS_GAMUTCHECK) && (dwFlags & cmsFLAGS_NOTPRECALC)) { p -> Gamut = _cmsComputeGamutLUT(p->PreviewProfile, p ->Intent); p -> Phase2 = LabRel; if (p -> Gamut == NULL) { // 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"); p -> Gamut = NULL; } } }}// Choose the adequate transform routinestatic_LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p, LPDWORD dwFlagsPtr, icTagSignature *FromTagPtr, icTagSignature *ToTagPtr){ // Is a named color profile? if (cmsGetDeviceClass(p->InputProfile) == icSigNamedColorClass) { // Yes, and used as input p ->FromDevice = NC2toPCS; } else { // Can we optimize matrix-shaper only transform? if (*FromTagPtr == 0 && *ToTagPtr == 0 && !p->PreviewProfile && p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC && (p -> EntryColorSpace == icSigRgbData) && (p -> ExitColorSpace == icSigRgbData) && !((*dwFlagsPtr) & cmsFLAGS_BLACKPOINTCOMPENSATION)) { // Yes... try to smelt matrix-shapers p -> xform = MatrixShaperXFORM; *dwFlagsPtr |= cmsFLAGS_NOTPRECALC; if (!cmsBuildSmeltMatShaper(p)) { cmsSignalError(LCMS_ERRC_ABORTED, "unable to smelt shaper-matrix, required tags missing"); return NULL; } p -> Phase1 = p -> Phase3 = XYZRel; return p; } // No, is a transform involving LUT if (*FromTagPtr != 0) { p -> FromDevice = LUTtoPCS; p -> Device2PCS = cmsReadICCLut(p -> InputProfile, *FromTagPtr); if (!p -> Device2PCS) { cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for input"); return NULL; } } else { p -> FromDevice = ShaperMatrixToPCS; p -> InMatShaper = cmsBuildInputMatrixShaper(p -> InputProfile); if (!p ->InMatShaper) { cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for input"); return NULL; } p -> Phase1 = XYZRel; } } if (*ToTagPtr != 0) { p -> ToDevice = PCStoLUT; p -> PCS2Device = cmsReadICCLut(p -> OutputProfile, *ToTagPtr); if (!p -> PCS2Device) { cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for output"); return NULL; } } else { p -> ToDevice = PCStoShaperMatrix; p -> OutMatShaper = cmsBuildOutputMatrixShaper(p->OutputProfile); if (!p -> OutMatShaper) { cmsSignalError(LCMS_ERRC_ABORTED, "profile is unsuitable for output"); return NULL; } p -> Phase3 = XYZRel; } return p;}// Create a transform.cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, DWORD InputFormat, cmsHPROFILE OutputProfile, DWORD OutputFormat, cmsHPROFILE ProofingProfile, int nIntent, int ProofingIntent, DWORD dwFlags){ _LPcmsTRANSFORM p; icTagSignature FromTag; icTagSignature ToTag; if (nIntent < 0 || nIntent > 3 || ProofingIntent < 0 || ProofingIntent > 3) { cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateTransform: intent mismatch"); return NULL; } p = AllocEmptyTransform(); if (p == NULL) return NULL; p -> xform = NormalXFORM; p -> Intent = nIntent; p -> ProofIntent = ProofingIntent; p -> DoGamutCheck = FALSE; p -> InputProfile = InputProfile; p -> OutputProfile = OutputProfile; p -> PreviewProfile = ProofingProfile; p -> InputFormat = InputFormat; p -> OutputFormat = OutputFormat; p -> lInputV4Lab = p ->lOutputV4Lab = FALSE; p -> FromInput = _cmsIdentifyInputFormat(p, InputFormat); p -> ToOutput = _cmsIdentifyOutputFormat(p, OutputFormat); // Null transform can be done without profiles if ((dwFlags & cmsFLAGS_NULLTRANSFORM) || ((InputProfile == NULL) && (OutputProfile == NULL))) { p -> xform = NullXFORM; return (cmsHTRANSFORM) p; } // 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; } // Device link are means to store precalculated transform grids. if (cmsGetDeviceClass(InputProfile) == icSigLinkClass) { return CreateDeviceLinkTransform(p, dwFlags); } if (!IsProperColorSpace(InputProfile, InputFormat, FALSE)) { cmsSignalError(LCMS_ERRC_ABORTED, "Input profile is operating on wrong colorspace"); cmsDeleteTransform((cmsHTRANSFORM) p); return NULL; } p ->EntryColorSpace = cmsGetColorSpace(InputProfile); // Oct-21-2002: Added named color transforms if (cmsGetDeviceClass(InputProfile) == icSigNamedColorClass) { if (p ->NamedColorList == NULL) p ->NamedColorList = cmsAllocNamedColorList(0); cmsReadICCnamedColorList(p, InputProfile, icSigNamedColor2Tag); // Special case. If output profile == NULL, then the transform gives // device values from named colors. if (OutputProfile == NULL) { p ->ExitColorSpace = p -> EntryColorSpace; p ->xform = NC2deviceXform; return (cmsHTRANSFORM) p; } // Named color doesn't precalc anything dwFlags |= cmsFLAGS_NOTPRECALC; } // From here we need also output profile. 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); return NULL; } p -> ExitColorSpace = cmsGetColorSpace(OutputProfile); // Named color only on input if (cmsGetDeviceClass(OutputProfile) == icSigNamedColorClass) { cmsSignalError(LCMS_ERRC_ABORTED, "Named color profiles are not supported as output"); cmsDeleteTransform((cmsHTRANSFORM) p); return NULL; } p -> Phase1 = GetPhase(InputProfile); p -> Phase2 = -1; p -> Phase3 = GetPhase(OutputProfile); // Try to locate a LUT FromTag = Device2PCS[nIntent]; ToTag = PCS2Device[nIntent]; if (!cmsIsTag(InputProfile, FromTag)) { FromTag = Device2PCS[0]; if (!cmsIsTag(InputProfile, FromTag)) { FromTag = (icTagSignature)0; } } // If proofing is needed, add required tags/parameters if (ProofingProfile) CreateProof(p, dwFlags, &ToTag); if (!cmsIsTag(OutputProfile, ToTag)) { ToTag = PCS2Device[0]; // 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; } if (dwFlags& cmsFLAGS_MATRIXINPUT) FromTag = (icTagSignature)0; if (dwFlags & cmsFLAGS_MATRIXOUTPUT) ToTag = (icTagSignature)0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -