📄 cmsxform.c
字号:
if (PickTransformRoutine(p, &dwFlags, &FromTag, &ToTag) == NULL) { cmsDeleteTransform((cmsHTRANSFORM) p); return NULL; } TakeConversionRoutines(p, dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION); if (!(dwFlags & cmsFLAGS_NOTPRECALC)) { LPLUT DeviceLink; LPLUT GamutCheck = NULL; if (p ->EntryColorSpace == icSigCmykData && p ->ExitColorSpace == icSigCmykData && dwFlags & cmsFLAGS_PRESERVEBLACK) { DeviceLink = _cmsPrecalculateBlackPreservingDeviceLink((cmsHTRANSFORM) p, dwFlags); // Cannot be done at all? if (DeviceLink == NULL) DeviceLink = _cmsPrecalculateDeviceLink((cmsHTRANSFORM) p, dwFlags); } else { DeviceLink = _cmsPrecalculateDeviceLink((cmsHTRANSFORM) p, dwFlags); } if (dwFlags & 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 // not if luma is in separate channel) if (p ->EntryColorSpace == icSigRgbData || p ->EntryColorSpace == icSigCmyData) { cmsCalcCLUT16ParamsEx(DeviceLink->CLut16params.nSamples, DeviceLink->CLut16params.nInputs, 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; if (DeviceLink) { p ->DeviceLink = DeviceLink; if ((nIntent != INTENT_ABSOLUTE_COLORIMETRIC) && !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP)) _cmsFixWhiteMisalignment(p); } else { cmsSignalError(LCMS_ERRC_ABORTED, "Cannot precalculate %d->%d channels transform!", T_CHANNELS(InputFormat), T_CHANNELS(OutputFormat)); cmsDeleteTransform(p); return NULL; } SetPrecalculatedTransform(p, dwFlags); } // Re-Identify formats p -> FromInput = _cmsIdentifyInputFormat(p, InputFormat); p -> ToOutput = _cmsIdentifyOutputFormat(p, OutputFormat); return p;}// Wrapper por simpler non-proofing transforms.cmsHTRANSFORM LCMSEXPORT cmsCreateTransform(cmsHPROFILE Input, DWORD InputFormat, cmsHPROFILE Output, DWORD OutputFormat, int Intent, DWORD dwFlags){ return cmsCreateProofingTransform(Input, InputFormat, Output, OutputFormat, NULL, Intent, INTENT_ABSOLUTE_COLORIMETRIC, dwFlags);}// Profiles are *NOT* closedvoid LCMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform){ _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) (LPSTR) hTransform; if (p -> Device2PCS) cmsFreeLUT(p -> Device2PCS); if (p -> PCS2Device) cmsFreeLUT(p -> PCS2Device); if (p -> Gamut) cmsFreeLUT(p -> Gamut); if (p -> Preview) cmsFreeLUT(p -> Preview); if (p -> DeviceLink) cmsFreeLUT(p -> DeviceLink); if (p -> InMatShaper) cmsFreeMatShaper(p -> InMatShaper); if (p -> OutMatShaper) cmsFreeMatShaper(p -> OutMatShaper); if (p -> SmeltMatShaper) cmsFreeMatShaper(p -> SmeltMatShaper); if (p ->NamedColorList) cmsFreeNamedColorList(p ->NamedColorList); if (p -> GamutCheck) cmsFreeLUT(p -> GamutCheck); free((void *) p);}// Apply transform codevoid LCMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform, LPVOID InputBuffer, LPVOID OutputBuffer, unsigned int Size){ _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) (LPSTR) Transform; p -> StrideIn = p -> StrideOut = Size; p -> xform(p, InputBuffer, OutputBuffer, Size);}void LCMSEXPORT cmsSetAlarmCodes(int r, int g, int 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(AlarmR); *g = RGB_16_TO_8(AlarmG); *b = RGB_16_TO_8(AlarmB);}// Returns TRUE if the profile is implemented as matrix-shaperBOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile){ switch (cmsGetColorSpace(hProfile)) { case icSigGrayData: return cmsIsTag(hProfile, icSigGrayTRCTag); case icSigRgbData: return (cmsIsTag(hProfile, icSigRedColorantTag) && cmsIsTag(hProfile, icSigGreenColorantTag) && cmsIsTag(hProfile, icSigBlueColorantTag) && cmsIsTag(hProfile, icSigRedTRCTag) && cmsIsTag(hProfile, icSigGreenTRCTag) && cmsIsTag(hProfile, icSigBlueTRCTag)); default: return FALSE; }}BOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection){ icTagSignature* TagTable; // Device link profiles only implements the intent in header if (cmsGetDeviceClass(hProfile) != icSigLinkClass) { switch (UsedDirection) { case LCMS_USED_AS_INPUT: TagTable = Device2PCS; break; case LCMS_USED_AS_OUTPUT:TagTable = PCS2Device; break; case LCMS_USED_AS_PROOF: TagTable = Preview; break; default: cmsSignalError(LCMS_ERRC_ABORTED, "Unexpected direction (%d)", UsedDirection); return FALSE; } if (cmsIsTag(hProfile, TagTable[Intent])) return TRUE; return _cmsIsMatrixShaper(hProfile); } return (cmsTakeRenderingIntent(hProfile) == Intent);}// Multiple profile transform. staticint 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;}// A multiprofile transform does chain several profiles into a single// devicelink. It couls also be used to merge named color profiles into// a single database.cmsHTRANSFORM LCMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], int nProfiles, DWORD dwInput, DWORD dwOutput, int Intent, DWORD dwFlags){ cmsHTRANSFORM Transforms[257]; DWORD dwPrecalcFlags = (dwFlags|cmsFLAGS_NOTPRECALC|cmsFLAGS_NOTCACHE); DWORD FormatInput, FormatOutput; cmsHPROFILE hLab, hXYZ, hProfile; icColorSpaceSignature ColorSpace, CurrentColorSpace; icColorSpaceSignature ColorSpaceIn, ColorSpaceOut; LPLUT Grid; 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; } // Creates a phantom transform for latter filling 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? nNamedColor = 0; for (i=0; i < nProfiles; i++) { if (cmsGetDeviceClass(hProfiles[i]) == icSigNamedColorClass) nNamedColor++; } if (nNamedColor == nProfiles) { // Yes, only named color. Create a named color-device // and append to named color table cmsDeleteTransform((cmsHTRANSFORM) p); p = (_LPcmsTRANSFORM) cmsCreateTransform(hProfiles[0], dwInput, NULL, dwOutput, Intent, dwFlags); for (i=1; i < nProfiles; i++) { cmsReadICCnamedColorList(p, hProfiles[i], icSigNamedColor2Tag); } return p; // Ok, done so far } else if (nNamedColor > 0) { cmsDeleteTransform((cmsHTRANSFORM) p); cmsSignalError(LCMS_ERRC_ABORTED, "Could not mix named color profiles with other types in multiprofile transform"); return NULL; } // We will need a 3DCLUT for device link Grid = cmsAllocLUT(); if (!Grid) return NULL; // This one is our PCS (Always Lab) hLab = cmsCreateLabProfile(NULL); hXYZ = cmsCreateXYZProfile(); if (!hLab || !hXYZ) goto ErrorCleanup; // Take some info.... p ->EntryColorSpace = CurrentColorSpace = cmsGetColorSpace(hProfiles[0]); for (i=0; i < nProfiles; i++) { int lIsDeviceLink, lIsInput; // Check colorspace hProfile = hProfiles[i]; lIsDeviceLink = (cmsGetDeviceClass(hProfile) == icSigLinkClass); lIsInput = (CurrentColorSpace != icSigXYZData) && (CurrentColorSpace != icSigLabData); if (lIsInput) { ColorSpaceIn = cmsGetColorSpace(hProfile); ColorSpaceOut = cmsGetPCS(hProfile); } 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); } else { if (lIsInput) { 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); } } } else // Can come from pcs? if (CurrentColorSpace == icSigXYZData) { Transforms[i] = cmsCreateTransform(hXYZ, FormatInput, hProfile, FormatOutput, Intent, dwPrecalcFlags); } else if (CurrentColorSpace == icSigLabData) { 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 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 if (!cmsSample3DGrid(Grid, MultiprofileSampler, (LPVOID) Transforms, Grid -> wFlags)) { cmsFreeLUT(Grid); goto ErrorCleanup; } // All ok, store the newly created LUT p -> DeviceLink = Grid; SetPrecalculatedTransform(p, dwFlags); for (i=nProfiles-1; i >= 0; --i) cmsDeleteTransform(Transforms[i]); if (hLab) cmsCloseProfile(hLab); if (hXYZ) cmsCloseProfile(hXYZ); if ((Intent != INTENT_ABSOLUTE_COLORIMETRIC) && !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP)) _cmsFixWhiteMisalignment(p); return (cmsHTRANSFORM) p;ErrorCleanup: if (hLab) cmsCloseProfile(hLab); if (hXYZ) cmsCloseProfile(hXYZ); return NULL;} double LCMSEXPORT cmsSetAdaptationState(double d){ double OldVal = GlobalAdaptationState; if (d >= 0) GlobalAdaptationState = d; return OldVal; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -