static cmsHPROFILE OpenProfile(const char* File) { if (!File) return cmsCreate_sRGBProfile(); if (stricmp(File, "*sRGB") == 0) return cmsCreate_sRGBProfile(NULL); if (stricmp(File, "*Lab") == 0) return cmsCreateLabProfile(NULL); if (stricmp(File, "*LabD65") == 0) { cmsCIExyY D65xyY; cmsWhitePointFromTemp(6504, &D65xyY); return cmsCreateLabProfile(&D65xyY); } if (stricmp(File, "*XYZ") == 0) return cmsCreateXYZProfile(); if (stricmp(File, "*Gray22") == 0) { LPGAMMATABLE Gamma = cmsBuildGamma(256, 2.2); cmsHPROFILE hProfile = cmsCreateGrayProfile(cmsD50_xyY(), Gamma); cmsFreeGamma(Gamma); return hProfile; } return cmsOpenProfileFromFile(File, "r"); }
ScColorProfile ScLcmsColorMgmtEngineImpl::createProfile_Lab(ScColorMgmtEngine& engine) { QString internalProfilePath("memprofile://Internal Lab profile"); ScColorProfile profile = m_profileCache->profile(internalProfilePath); if (!profile.isNull()) return profile; cmsHPROFILE lcmsProf = NULL; cmsSetErrorHandler(&cmsErrorHandler); try { lcmsProf = cmsCreateLabProfile(NULL); if (lcmsProf) { ScLcmsColorProfileImpl* profData = new ScLcmsColorProfileImpl(engine, lcmsProf); profData->m_profilePath = internalProfilePath; profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData)); m_profileCache->addProfile(profile); } if (profile.isNull() && lcmsProf) { cmsCloseProfile(lcmsProf); lcmsProf = NULL; } } catch (lcmsException& e) { std::cerr << e.what() << std::endl; if (profile.isNull() && lcmsProf) cmsCloseProfile(lcmsProf); profile = ScColorProfile(); } cmsSetErrorHandler(NULL); return profile; }
// Compute K -> L* relationship. Flags may include black point compensation. In this case, // the relationship is assumed from the profile with BPC to a black point zero. static LPGAMMATABLE ComputeKToLstar(cmsHPROFILE hProfile, int nPoints, int Intent, DWORD dwFlags) { LPGAMMATABLE out; int i; WORD cmyk[4], wLab[3]; cmsHPROFILE hLab = cmsCreateLabProfile(NULL); cmsHTRANSFORM xform = cmsCreateTransform(hProfile, TYPE_CMYK_16, hLab, TYPE_Lab_16, Intent, (dwFlags|cmsFLAGS_NOTPRECALC)); out = cmsAllocGamma(nPoints); for (i=0; i < nPoints; i++) { cmyk[0] = 0; cmyk[1] = 0; cmyk[2] = 0; cmyk[3] = _cmsQuantizeVal(i, nPoints); cmsDoTransform(xform, cmyk, wLab, 1); out->GammaTable[i] = (WORD) (0xFFFF - wLab[0]); } cmsDeleteTransform(xform); cmsCloseProfile(hLab); return out; }
static PyObject * createProfile(PyObject *self, PyObject *args) { char *sColorSpace; cmsHPROFILE hProfile; int iColorTemp = 0; LPcmsCIExyY whitePoint = NULL; LCMSBOOL result; if (!PyArg_ParseTuple(args, "s|i:createProfile", &sColorSpace, &iColorTemp)) return NULL; cmsErrorAction(LCMS_ERROR_IGNORE); if (strcmp(sColorSpace, "LAB") == 0) { if (iColorTemp > 0) { result = cmsWhitePointFromTemp(iColorTemp, whitePoint); if (!result) { PyErr_SetString(PyExc_ValueError,"ERROR: Could not calculate "\ "white point from color temperature provided, must be "\ "integer in degrees Kelvin"); return NULL; } hProfile = cmsCreateLabProfile(whitePoint); } else hProfile = cmsCreateLabProfile(NULL); } else if (strcmp(sColorSpace, "XYZ") == 0) hProfile = cmsCreateXYZProfile(); else if (strcmp(sColorSpace, "sRGB") == 0) hProfile = cmsCreate_sRGBProfile(); else hProfile = NULL; if (!hProfile) { PyErr_SetString(PyExc_ValueError, "failed to create requested color space"); return NULL; } return cms_profile_new(hProfile); }
static int BlackPointUsingPerceptualBlack(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, DWORD dwFlags) { cmsHTRANSFORM hPercLab2CMYK, hRelColCMYK2Lab; cmsHPROFILE hLab; cmsCIELab LabIn, LabOut; WORD CMYK[MAXCHANNELS]; cmsCIEXYZ BlackXYZ, MediaWhite; if (!cmsIsIntentSupported(hProfile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) { BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; return 0; } hLab = cmsCreateLabProfile(NULL); hPercLab2CMYK = cmsCreateTransform(hLab, TYPE_Lab_DBL, hProfile, TYPE_CMYK_16, INTENT_PERCEPTUAL, cmsFLAGS_NOTPRECALC); hRelColCMYK2Lab = cmsCreateTransform(hProfile, TYPE_CMYK_16, hLab, TYPE_Lab_DBL, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOTPRECALC); LabIn.L = LabIn.a = LabIn.b = 0; cmsDoTransform(hPercLab2CMYK, &LabIn, CMYK, 1); cmsDoTransform(hRelColCMYK2Lab, CMYK, &LabOut, 1); if (LabOut.L > 50) LabOut.L = 50; LabOut.a = LabOut.b = 0; cmsDeleteTransform(hPercLab2CMYK); cmsDeleteTransform(hRelColCMYK2Lab); cmsCloseProfile(hLab); cmsLab2XYZ(NULL, &BlackXYZ, &LabOut); if (!(dwFlags & LCMS_BPFLAGS_D50_ADAPTED)){ cmsTakeMediaWhitePoint(&MediaWhite, hProfile); cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &BlackXYZ); } else *BlackPoint = BlackXYZ; return 1; }
static cmsHPROFILE OpenProfile(const char* File) { cmsHPROFILE h; if (!File) return cmsCreate_sRGBProfile(); if (stricmp(File, "*Lab") == 0) return cmsCreateLabProfile(NULL); if (stricmp(File, "*XYZ") == 0) return cmsCreateXYZProfile(); if (stricmp(File, "*srgb") == 0) return cmsCreate_sRGBProfile(); if (stricmp(File, "*Gray22") == 0) { LPGAMMATABLE Gamma = cmsBuildGamma(256, 2.2); cmsHPROFILE hProfile = cmsCreateGrayProfile(cmsD50_xyY(), Gamma); cmsFreeGamma(Gamma); return hProfile; } if (stricmp(File, "*Lin2222") == 0) { LPGAMMATABLE Gamma = cmsBuildGamma(256, 2.2); LPGAMMATABLE Gamma4[4]; cmsHPROFILE hProfile; Gamma4[0] = Gamma4[1] = Gamma4[2] = Gamma4[3] = Gamma; hProfile = cmsCreateLinearizationDeviceLink(icSigCmykData, Gamma4); cmsFreeGamma(Gamma); return hProfile; } h = cmsOpenProfileFromFile(File, "r"); if (cmsGetDeviceClass(h) == icSigNamedColorClass) FatalError("ERROR: Cannot make devicelink of named color profiles!"); return h; }
static PyObject * pycms_CreateLabProfile(PyObject *self, PyObject *args) { cmsHPROFILE hProfile; cmsErrorAction(LCMS_ERROR_IGNORE); hProfile = cmsCreateLabProfile(NULL); if(hProfile==NULL) { Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("O", PyCObject_FromVoidPtr((void *)hProfile, (void *)cmsCloseProfile)); }
static void InitCargo(LPCARGO Cargo) { Cargo -> hLab = cmsCreateLabProfile(NULL); Cargo -> hRGB = CreateRGBSpace(); Cargo->Lab2RGB = cmsCreateTransform(Cargo->hLab, TYPE_Lab_16, Cargo ->hRGB, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOTPRECALC); Cargo->RGB2Lab = cmsCreateTransform(Cargo ->hRGB, TYPE_RGB_16, Cargo ->hLab, TYPE_Lab_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOTPRECALC); }
/****************************************************************************** * CreateMultiProfileTransform [MSCMS.@] * * Create a color transform from an array of color profiles. * * PARAMS * profiles [I] Array of color profiles. * nprofiles [I] Number of color profiles. * intents [I] Array of rendering intents. * flags [I] Flags. * cmm [I] Profile to take the CMM from. * * RETURNS * Success: Handle to a transform. * Failure: NULL */ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofiles, PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm ) { HTRANSFORM ret = NULL; #ifdef HAVE_LCMS cmsHPROFILE *cmsprofiles, cmsconvert = NULL; struct transform transform; struct profile *profile0, *profile1; DWORD in_format, out_format; TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n", profiles, nprofiles, intents, nintents, flags, cmm ); if (!profiles || !nprofiles || !intents) return NULL; if (nprofiles > 2) { FIXME("more than 2 profiles not supported\n"); return NULL; } profile0 = grab_profile( profiles[0] ); if (!profile0) return NULL; profile1 = grab_profile( profiles[1] ); if (!profile1) { release_profile( profile0 ); return NULL; } in_format = from_profile( profiles[0] ); out_format = from_profile( profiles[nprofiles - 1] ); if (in_format != out_format) { /* insert a conversion profile for pairings that lcms doesn't handle */ if (out_format == TYPE_RGB_16) cmsconvert = cmsCreate_sRGBProfile(); if (out_format == TYPE_Lab_16) cmsconvert = cmsCreateLabProfile( NULL ); } cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE) ); if (cmsprofiles) { cmsprofiles[0] = profile0->cmsprofile; if (cmsconvert) { cmsprofiles[1] = cmsconvert; cmsprofiles[2] = profile1->cmsprofile; nprofiles++; } else { cmsprofiles[1] = profile1->cmsprofile; } transform.cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 ); HeapFree( GetProcessHeap(), 0, cmsprofiles ); ret = create_transform( &transform ); } release_profile( profile0 ); release_profile( profile1 ); #endif /* HAVE_LCMS */ return ret; }
static int BlackPointAsDarkerColorant(cmsHPROFILE hInput, int Intent, LPcmsCIEXYZ BlackPoint, DWORD dwFlags) { WORD *Black, *White; cmsHTRANSFORM xform; icColorSpaceSignature Space; int nChannels; DWORD dwFormat; cmsHPROFILE hLab; cmsCIELab Lab; cmsCIEXYZ BlackXYZ, MediaWhite; // If the profile does not support input direction, assume Black point 0 if (!cmsIsIntentSupported(hInput, Intent, LCMS_USED_AS_INPUT)) { BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; return 0; } // Try to get black by using black colorant Space = cmsGetColorSpace(hInput); if (!_cmsEndPointsBySpace(Space, &White, &Black, &nChannels)) { BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; return 0; } dwFormat = CHANNELS_SH(nChannels)|BYTES_SH(2); hLab = cmsCreateLabProfile(NULL); xform = cmsCreateTransform(hInput, dwFormat, hLab, TYPE_Lab_DBL, Intent, cmsFLAGS_NOTPRECALC); cmsDoTransform(xform, Black, &Lab, 1); // Force it to be neutral, clip to max. L* of 50 Lab.a = Lab.b = 0; if (Lab.L > 50) Lab.L = 50; cmsCloseProfile(hLab); cmsDeleteTransform(xform); cmsLab2XYZ(NULL, &BlackXYZ, &Lab); if (Intent == INTENT_ABSOLUTE_COLORIMETRIC) { *BlackPoint = BlackXYZ; } else { if (!(dwFlags & LCMS_BPFLAGS_D50_ADAPTED)) { cmsTakeMediaWhitePoint(&MediaWhite, hInput); cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &BlackXYZ); } else *BlackPoint = BlackXYZ; } return 1; }
LPLUT _cmsComputeSoftProofLUT(cmsHPROFILE hProfile, int nIntent) { cmsHPROFILE hLab; LPLUT SoftProof; DWORD dwFormat; GAMUTCHAIN Chain; int nErrState; LPGAMMATABLE Trans[3]; // LUTs are never abs. colorimetric, is the transform who // is responsible of generating white point displacement if (nIntent == INTENT_ABSOLUTE_COLORIMETRIC) nIntent = INTENT_RELATIVE_COLORIMETRIC; ZeroMemory(&Chain, sizeof(GAMUTCHAIN)); hLab = cmsCreateLabProfile(NULL); // ONLY 4 channels dwFormat = (CHANNELS_SH(4)|BYTES_SH(2)); // Safeguard against early abortion nErrState = cmsErrorAction(LCMS_ERROR_IGNORE); // Does create the first step Chain.hForward = cmsCreateTransform(hLab, TYPE_Lab_16, hProfile, dwFormat, nIntent, cmsFLAGS_NOTPRECALC); // Does create the last step Chain.hReverse = cmsCreateTransform(hProfile, dwFormat, hLab, TYPE_Lab_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOTPRECALC); // Restores error handler previous state cmsErrorAction(nErrState); // All ok? if (Chain.hForward && Chain.hReverse) { // This is Lab -> Lab, so 33 point should hold anything SoftProof = cmsAllocLUT(); SoftProof = cmsAlloc3DGrid(SoftProof, 33, 3, 3); CreateLabPrelinearization(Trans); cmsAllocLinearTable(SoftProof, Trans, 1); cmsFreeGammaTriple(Trans); cmsSample3DGrid(SoftProof, SoftProofSampler, (LPVOID) &Chain, SoftProof->wFlags); } else SoftProof = NULL; // Didn't work... // Free all needed stuff. if (Chain.hForward) cmsDeleteTransform(Chain.hForward); if (Chain.hReverse) cmsDeleteTransform(Chain.hReverse); cmsCloseProfile(hLab); return SoftProof; }
static LPLUT ComputeGamutWithInput(cmsHPROFILE hInput, cmsHPROFILE hProfile, int Intent) { cmsHPROFILE hLab; LPLUT Gamut; DWORD dwFormat; GAMUTCHAIN Chain; int nErrState, nChannels, nGridpoints; LPGAMMATABLE Trans[3]; icColorSpaceSignature ColorSpace; ZeroMemory(&Chain, sizeof(GAMUTCHAIN)); hLab = cmsCreateLabProfile(NULL); // Safeguard against early abortion nErrState = cmsErrorAction(LCMS_ERROR_IGNORE); // The figure of merit. On matrix-shaper profiles, should be almost zero as // the conversion is pretty exact. On LUT based profiles, different resolutions // of input and output CLUT may result in differences. if (!cmsIsIntentSupported(hProfile, Intent, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(hProfile, Intent, LCMS_USED_AS_OUTPUT)) Chain.Thereshold = 1.0; else Chain.Thereshold = ERR_THERESHOLD; ColorSpace = cmsGetColorSpace(hProfile); // If input profile specified, create a transform from such profile to Lab if (hInput != NULL) { nChannels = _cmsChannelsOf(ColorSpace); nGridpoints = _cmsReasonableGridpointsByColorspace(ColorSpace, cmsFLAGS_HIGHRESPRECALC); dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2)); Chain.hInput = cmsCreateTransform(hInput, dwFormat, hLab, TYPE_Lab_16, Intent, cmsFLAGS_NOTPRECALC); } else { // Input transform=NULL (Lab) Used to compute the gamut tag // This table will take 53 points to give some accurancy, // 53 * 53 * 53 * 2 = 291K nChannels = 3; // For Lab nGridpoints = 53; Chain.hInput = NULL; dwFormat = (CHANNELS_SH(_cmsChannelsOf(ColorSpace))|BYTES_SH(2)); } // Does create the forward step Chain.hForward = cmsCreateTransform(hLab, TYPE_Lab_16, hProfile, dwFormat, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOTPRECALC); // Does create the backwards step Chain.hReverse = cmsCreateTransform(hProfile, dwFormat, hLab, TYPE_Lab_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOTPRECALC); // Restores error handler previous state cmsErrorAction(nErrState); // All ok? if (Chain.hForward && Chain.hReverse) { // Go on, try to compute gamut LUT from PCS. // This consist on a single channel containing // dE when doing a transform back and forth on // the colorimetric intent. Gamut = cmsAllocLUT(); Gamut = cmsAlloc3DGrid(Gamut, nGridpoints, nChannels, 1); // If no input, then this is a gamut tag operated by Lab, // so include pertinent prelinearization if (hInput == NULL) { CreateLabPrelinearization(Trans); cmsAllocLinearTable(Gamut, Trans, 1); cmsFreeGammaTriple(Trans); } cmsSample3DGrid(Gamut, GamutSampler, (LPVOID) &Chain, Gamut ->wFlags); } else Gamut = NULL; // Didn't work... // Free all needed stuff. if (Chain.hInput) cmsDeleteTransform(Chain.hInput); if (Chain.hForward) cmsDeleteTransform(Chain.hForward); if (Chain.hReverse) cmsDeleteTransform(Chain.hReverse); cmsCloseProfile(hLab); // And return computed hull return Gamut; }
int main(int argc, char *argv[]) { LPLUT AToB0, BToA0; LPGAMMATABLE PreLinear[3]; LPGAMMATABLE Lin; CARGO Cargo; cmsHPROFILE hProfile; cmsCIEXYZ wp; fprintf(stderr, "Creating lcmscmy.icm..."); wp.X = 55.6549; wp.Y = 59.0485; wp.Z = 72.5494; cmsXYZ2xyY(&Cus, &wp); InitCargo(&Cargo); hProfile = cmsCreateLabProfile(&Cus); // Create linearization Lin = CreateLinear(); PreLinear[0] = Lin; PreLinear[1] = Lin; PreLinear[2] = Lin; AToB0 = cmsAllocLUT(); BToA0 = cmsAllocLUT(); cmsAlloc3DGrid(AToB0, 33, 3, 3); cmsAlloc3DGrid(BToA0, 33, 3, 3); cmsSample3DGrid(AToB0, Reverse, &Cargo, 0); cmsSample3DGrid(BToA0, Forward, &Cargo, 0); cmsAllocLinearTable(AToB0, PreLinear, 1); cmsAllocLinearTable(BToA0, PreLinear, 2); cmsAddTag(hProfile, icSigAToB0Tag, AToB0); cmsAddTag(hProfile, icSigBToA0Tag, BToA0); cmsSetColorSpace(hProfile, icSigCmyData); cmsAddTag(hProfile, icSigProfileDescriptionTag, "Little cms CMY mixing"); cmsAddTag(hProfile, icSigCopyrightTag, "Copyright (c) Marti Maria, 2002. All rights reserved."); cmsAddTag(hProfile, icSigDeviceMfgDescTag, "Little cms"); cmsAddTag(hProfile, icSigDeviceModelDescTag, "CMY mixing"); _cmsSaveProfile(hProfile, "lcmscmy.icm"); cmsFreeGamma(Lin); cmsFreeLUT(AToB0); cmsFreeLUT(BToA0); cmsCloseProfile(hProfile); FreeCargo(&Cargo); fprintf(stderr, "Done.\n"); return 0; }
static void OpenTransforms(void) { DWORD dwIn, dwOut, dwFlags; dwFlags = 0; if (lIsDeviceLink) { hInput = cmsOpenProfileFromFile(cInProf, "r"); hOutput = NULL; InputColorSpace = cmsGetColorSpace(hInput); OutputColorSpace = cmsGetPCS(hInput); } else { hInput = OpenStockProfile(cInProf); hOutput = OpenStockProfile(cOutProf); hProof = NULL; if (cProofing != NULL) { hProof = OpenStockProfile(cProofing); dwFlags |= cmsFLAGS_SOFTPROOFING; } InputColorSpace = cmsGetColorSpace(hInput); OutputColorSpace = cmsGetColorSpace(hOutput); if (cmsGetDeviceClass(hInput) == icSigLinkClass || cmsGetDeviceClass(hOutput) == icSigLinkClass) FatalError("Use %cl flag for devicelink profiles!\n", SW); } hXYZ = cmsCreateXYZProfile(); hLab = cmsCreateLabProfile(NULL); if (Verbose) { printf("From: %s\n", cmsTakeProductName(hInput)); printf("Desc: %s\n", cmsTakeProductDesc(hInput)); if (hOutput) printf("To : %s\n\n", cmsTakeProductName(hOutput)); } dwIn = BYTES_SH(2) | CHANNELS_SH(_cmsChannelsOf(InputColorSpace)); dwOut = BYTES_SH(2) | CHANNELS_SH(_cmsChannelsOf(OutputColorSpace)); switch (PrecalcMode) { case 0: dwFlags |= cmsFLAGS_NOTPRECALC; break; case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; case 3: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; case 1: break; default: FatalError("Unknown precalculation mode '%d'", PrecalcMode); } if (BlackPointCompensation) dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; if (GamutCheck) { if (hProof == NULL) FatalError("I need proofing profile -p for gamut checking!"); cmsSetAlarmCodes(0xFF, 0xFF, 0xFF); dwFlags |= cmsFLAGS_GAMUTCHECK; } if (cmsGetDeviceClass(hInput) == icSigNamedColorClass) { dwIn = TYPE_NAMED_COLOR_INDEX; } hTrans = cmsCreateProofingTransform(hInput, dwIn, hOutput, dwOut, hProof, Intent, ProofingIntent, dwFlags); hTransXYZ = NULL; hTransLab = NULL; if (hOutput && Verbose) { hTransXYZ = cmsCreateTransform(hInput, dwIn, hXYZ, TYPE_XYZ_16, Intent, cmsFLAGS_NOTPRECALC); hTransLab = cmsCreateTransform(hInput, dwIn, hLab, TYPE_Lab_16, Intent, cmsFLAGS_NOTPRECALC); } }