// Create the ICC virtual profile for sRGB space cmsHPROFILE LCMSEXPORT cmsCreate_sRGBProfile(void) { cmsCIExyY D65; cmsCIExyYTRIPLE Rec709Primaries = { {0.6400, 0.3300, 1.0}, {0.3000, 0.6000, 1.0}, {0.1500, 0.0600, 1.0} }; LPGAMMATABLE Gamma22[3]; cmsHPROFILE hsRGB; cmsWhitePointFromTemp(6504, &D65); Gamma22[0] = Gamma22[1] = Gamma22[2] = Build_sRGBGamma(); hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma22); cmsFreeGamma(Gamma22[0]); if (hsRGB == NULL) return NULL; cmsAddTag(hsRGB, icSigDeviceMfgDescTag, (LPVOID) "(lcms internal)"); cmsAddTag(hsRGB, icSigDeviceModelDescTag, (LPVOID) "sRGB built-in"); cmsAddTag(hsRGB, icSigProfileDescriptionTag, (LPVOID) "sRGB built-in"); return hsRGB; }
// Creates a fake Lab identity. cmsHPROFILE LCMSEXPORT cmsCreateLabProfile(LPcmsCIExyY WhitePoint) { cmsHPROFILE hProfile; LPLUT Lut; hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL); if (hProfile == NULL) return NULL; cmsSetDeviceClass(hProfile, icSigAbstractClass); cmsSetColorSpace(hProfile, icSigLabData); cmsSetPCS(hProfile, icSigLabData); cmsAddTag(hProfile, icSigDeviceMfgDescTag, (LPVOID) "(lcms internal)"); cmsAddTag(hProfile, icSigProfileDescriptionTag, (LPVOID) "lcms Lab identity"); cmsAddTag(hProfile, icSigDeviceModelDescTag, (LPVOID) "Lab built-in"); // An empty LUTs is all we need Lut = Create3x3EmptyLUT(); if (Lut == NULL) { cmsCloseProfile(hProfile); return NULL; } cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigBToA0Tag, (LPVOID) Lut); cmsFreeLUT(Lut); return hProfile; }
cmsHPROFILE LCMSEXPORT cmsCreateGrayProfile(LPcmsCIExyY WhitePoint, LPGAMMATABLE TransferFunction) { cmsHPROFILE hICC; cmsCIEXYZ tmp; hICC = _cmsCreateProfilePlaceholder(); if (!hICC) // can't allocate return NULL; cmsSetDeviceClass(hICC, icSigDisplayClass); cmsSetColorSpace(hICC, icSigGrayData); cmsSetPCS(hICC, icSigXYZData); cmsSetRenderingIntent(hICC, INTENT_PERCEPTUAL); // Implement profile using following tags: // // 1 icSigProfileDescriptionTag // 2 icSigMediaWhitePointTag // 6 icSigGrayTRCTag // This conforms a standard Gray DisplayProfile // Fill-in the tags cmsAddTag(hICC, icSigDeviceMfgDescTag, (LPVOID) "(lcms internal)"); cmsAddTag(hICC, icSigProfileDescriptionTag, (LPVOID) "lcms gray virtual profile"); cmsAddTag(hICC, icSigDeviceModelDescTag, (LPVOID) "gray built-in"); if (WhitePoint) { cmsxyY2XYZ(&tmp, WhitePoint); cmsAddTag(hICC, icSigMediaWhitePointTag, (LPVOID) &tmp); } if (TransferFunction) { // In case of gamma, we must dup' the table pointer cmsAddTag(hICC, icSigGrayTRCTag, (LPVOID) TransferFunction); } return hICC; }
static cmsHPROFILE CreateNamedColorDevicelink(cmsHTRANSFORM xform) { _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform; cmsHPROFILE hICC; cmsCIEXYZ WhitePoint; int i, nColors; size_t Size; LPcmsNAMEDCOLORLIST nc2; hICC = _cmsCreateProfilePlaceholder(); if (hICC == NULL) return NULL; cmsSetRenderingIntent(hICC, v -> Intent); cmsSetDeviceClass(hICC, icSigNamedColorClass); cmsSetColorSpace(hICC, v ->ExitColorSpace); cmsSetPCS(hICC, cmsGetPCS(v ->InputProfile)); cmsTakeMediaWhitePoint(&WhitePoint, v ->InputProfile); cmsAddTag(hICC, icSigMediaWhitePointTag, &WhitePoint); cmsAddTag(hICC, icSigDeviceMfgDescTag, (LPVOID) "LittleCMS"); cmsAddTag(hICC, icSigProfileDescriptionTag, (LPVOID) "Named color Device link"); cmsAddTag(hICC, icSigDeviceModelDescTag, (LPVOID) "Named color Device link"); nColors = cmsNamedColorCount(xform); nc2 = cmsAllocNamedColorList(nColors); Size = sizeof(cmsNAMEDCOLORLIST) + (sizeof(cmsNAMEDCOLOR) * (nColors-1)); CopyMemory(nc2, v->NamedColorList, Size); nc2 ->ColorantCount = _cmsChannelsOf(v ->ExitColorSpace); for (i=0; i < nColors; i++) { cmsDoTransform(xform, &i, nc2 ->List[i].DeviceColorant, 1); } cmsAddTag(hICC, icSigNamedColor2Tag, (void*) nc2); cmsFreeNamedColorList(nc2); return hICC; }
cmsHPROFILE LCMSEXPORT cmsCreateLinearizationDeviceLink(icColorSpaceSignature ColorSpace, LPGAMMATABLE TransferFunctions[]) { cmsHPROFILE hICC; LPLUT Lut; hICC = _cmsCreateProfilePlaceholder(); if (!hICC) // can't allocate return NULL; cmsSetDeviceClass(hICC, icSigLinkClass); cmsSetColorSpace(hICC, ColorSpace); cmsSetPCS(hICC, ColorSpace); cmsSetRenderingIntent(hICC, INTENT_PERCEPTUAL); // Creates a LUT with prelinearization step only Lut = cmsAllocLUT(); if (Lut == NULL) return NULL; // Set up channels Lut ->InputChan = Lut ->OutputChan = _cmsChannelsOf(ColorSpace); // Copy tables to LUT cmsAllocLinearTable(Lut, TransferFunctions, 1); // Create tags cmsAddTag(hICC, icSigDeviceMfgDescTag, (LPVOID) "(lcms internal)"); cmsAddTag(hICC, icSigProfileDescriptionTag, (LPVOID) "lcms linearization device link"); cmsAddTag(hICC, icSigDeviceModelDescTag, (LPVOID) "linearization built-in"); cmsAddTag(hICC, icSigMediaWhitePointTag, (LPVOID) cmsD50_XYZ()); cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut); // LUT is already on virtual profile cmsFreeLUT(Lut); // Ok, done return hICC; }
void updateCriticalTags(LPLCMSICCPROFILE Icc) { LPVOID savedData = NULL; int idx; cmsCIEXYZ* dummy; MemBuffer *memBuffer = (MemBuffer*) Icc->stream; if(!memBuffer->needsUpdateCriticalTags) // Nothing to do return; idx = findTag(Icc, icSigMediaWhitePointTag); dummy = cmsD50_XYZ(); if(idx >= 0) { // There is media white point already cmsAddTag(Icc, icSigMediaWhitePointTag, dummy); // Force LCMS to read critical tags free(Icc->TagPtrs[idx]); // Get rid of dummy media white point Icc->TagPtrs[idx] = NULL; } else { cmsAddTag(Icc, icSigMediaWhitePointTag, dummy); // Force LCMS to read critical tags // Get rid of dummy media white point free(Icc->TagPtrs[Icc->TagCount-1]); Icc->TagPtrs[Icc->TagCount-1] = NULL; Icc->TagNames[Icc->TagCount-1] = 0; Icc->TagSizes[Icc->TagCount-1] = 0; Icc->TagOffsets[Icc->TagCount-1] = 0; Icc->TagCount--; } memBuffer->needsUpdateCriticalTags = FALSE; }
// Creates a fake XYZ identity cmsHPROFILE LCMSEXPORT cmsCreateXYZProfile(void) { cmsHPROFILE hProfile; LPLUT Lut; hProfile = cmsCreateRGBProfile(cmsD50_xyY(), NULL, NULL); if (hProfile == NULL) return NULL; cmsSetDeviceClass(hProfile, icSigAbstractClass); cmsSetColorSpace(hProfile, icSigXYZData); cmsSetPCS(hProfile, icSigXYZData); cmsAddTag(hProfile, icSigDeviceMfgDescTag, (LPVOID) "(lcms internal)"); cmsAddTag(hProfile, icSigProfileDescriptionTag, (LPVOID) "lcms XYZ identity"); cmsAddTag(hProfile, icSigDeviceModelDescTag, (LPVOID) "XYZ built-in"); // An empty LUTs is all we need Lut = Create3x3EmptyLUT(); if (Lut == NULL) { cmsCloseProfile(hProfile); return NULL; } cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigBToA0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigPreview0Tag, (LPVOID) Lut); cmsFreeLUT(Lut); return hProfile; }
int main(int argc, char *argv[]) { LPLUT AToB0; cmsHPROFILE hProfile; fprintf(stderr, "Creating grayer.icm..."); unlink("grayer.icm"); hProfile = cmsOpenProfileFromFile("grayer.icm", "w"); AToB0 = cmsAllocLUT(); cmsAlloc3DGrid(AToB0, GRID_POINTS, 3, 3); cmsSample3DGrid(AToB0, Forward, NULL, 0); cmsAddTag(hProfile, icSigAToB0Tag, AToB0); cmsSetColorSpace(hProfile, icSigLabData); cmsSetPCS(hProfile, icSigLabData); cmsSetDeviceClass(hProfile, icSigAbstractClass); cmsAddTag(hProfile, icSigProfileDescriptionTag, "Little cms Grayifier"); cmsAddTag(hProfile, icSigCopyrightTag, "Copyright (c) Marti Maria 2003. All rights reserved."); cmsAddTag(hProfile, icSigDeviceMfgDescTag, "Little cms"); cmsAddTag(hProfile, icSigDeviceModelDescTag, "Grayifier abstract profile"); cmsCloseProfile(hProfile); cmsFreeLUT(AToB0); fprintf(stderr, "Done.\n"); return 0; }
cmsHPROFILE LCMSEXPORT cmsCreateNULLProfile(void) { cmsHPROFILE hProfile; LPLUT Lut; LPGAMMATABLE EmptyTab; hProfile = _cmsCreateProfilePlaceholder(); if (!hProfile) // can't allocate return NULL; cmsSetDeviceClass(hProfile, icSigOutputClass); cmsSetColorSpace(hProfile, icSigGrayData); cmsSetPCS(hProfile, icSigLabData); // An empty LUTs is all we need Lut = cmsAllocLUT(); if (Lut == NULL) { cmsCloseProfile(hProfile); return NULL; } Lut -> InputChan = 3; Lut -> OutputChan = 1; EmptyTab = cmsAllocGamma(2); EmptyTab ->GammaTable[0] = 0; EmptyTab ->GammaTable[1] = 0; cmsAllocLinearTable(Lut, &EmptyTab, 2); cmsAddTag(hProfile, icSigBToA0Tag, (LPVOID) Lut); cmsFreeLUT(Lut); cmsFreeGamma(EmptyTab); return hProfile; }
cmsHPROFILE LCMSEXPORT cmsCreateInkLimitingDeviceLink(icColorSpaceSignature ColorSpace, double Limit) { cmsHPROFILE hICC; LPLUT Lut; if (ColorSpace != icSigCmykData) { cmsSignalError(LCMS_ERRC_ABORTED, "InkLimiting: Only CMYK currently supported"); return NULL; } if (Limit < 0.0 || Limit > 400) { cmsSignalError(LCMS_ERRC_WARNING, "InkLimiting: Limit should be between 0..400"); if (Limit < 0) Limit = 0; if (Limit > 400) Limit = 400; } hICC = _cmsCreateProfilePlaceholder(); if (!hICC) // can't allocate return NULL; cmsSetDeviceClass(hICC, icSigLinkClass); cmsSetColorSpace(hICC, ColorSpace); cmsSetPCS(hICC, ColorSpace); cmsSetRenderingIntent(hICC, INTENT_PERCEPTUAL); // Creates a LUT with 3D grid only Lut = cmsAllocLUT(); if (Lut == NULL) { cmsCloseProfile(hICC); return NULL; } cmsAlloc3DGrid(Lut, 17, _cmsChannelsOf(ColorSpace), _cmsChannelsOf(ColorSpace)); if (!cmsSample3DGrid(Lut, InkLimitingSampler, (LPVOID) &Limit, 0)) { // Shouldn't reach here cmsFreeLUT(Lut); cmsCloseProfile(hICC); return NULL; } // Create tags cmsAddTag(hICC, icSigDeviceMfgDescTag, (LPVOID) "(lcms internal)"); cmsAddTag(hICC, icSigProfileDescriptionTag, (LPVOID) "lcms ink limiting device link"); cmsAddTag(hICC, icSigDeviceModelDescTag, (LPVOID) "ink limiting built-in"); cmsAddTag(hICC, icSigMediaWhitePointTag, (LPVOID) cmsD50_XYZ()); cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut); // LUT is already on virtual profile cmsFreeLUT(Lut); // Ok, done return hICC; }
static BOOL CreateLUTS(LPMONITORPROFILERDATA sys, LPLUT* A2B, LPLUT* B2A) { LPLUT AToB0 = cmsAllocLUT(); LPLUT BToA0 = cmsAllocLUT(); LPGAMMATABLE LabG; cmsCIExyY xyY; cmsAlloc3DGrid(AToB0, sys->hdr.CLUTPoints, 3, 3); cmsAlloc3DGrid(BToA0, sys->hdr.CLUTPoints, 3, 3); /* cmsAllocLinearTable(AToB0, sys -> Prelinearization, 1); */ sys->ReverseTables[0] = cmsReverseGamma(4096, sys ->Prelinearization[0]); sys->ReverseTables[1] = cmsReverseGamma(4096, sys ->Prelinearization[1]); sys->ReverseTables[2] = cmsReverseGamma(4096, sys ->Prelinearization[2]); /* Prelinearization */ LabG = cmsBuildGamma(4096, 3.0); sys -> PreLab[0] = cmsJoinGammaEx(LabG, sys ->Prelinearization[0], 4096); sys -> PreLab[1] = cmsJoinGammaEx(LabG, sys ->Prelinearization[1], 4096); sys -> PreLab[2] = cmsJoinGammaEx(LabG, sys ->Prelinearization[2], 4096); sys -> PreLabRev[0] = cmsJoinGammaEx(sys ->Prelinearization[0], LabG, 4096); sys -> PreLabRev[1] = cmsJoinGammaEx(sys ->Prelinearization[1], LabG, 4096); sys -> PreLabRev[2] = cmsJoinGammaEx(sys ->Prelinearization[2], LabG, 4096); cmsFreeGamma(LabG); cmsAllocLinearTable(AToB0, sys->PreLabRev, 1); cmsAllocLinearTable(BToA0, sys->PreLab, 2); /* Set CIECAM97s parameters */ sys -> hdr.device.whitePoint.X = sys -> hdr.WhitePoint.X * 100.; sys -> hdr.device.whitePoint.Y = sys -> hdr.WhitePoint.Y * 100.; sys -> hdr.device.whitePoint.Z = sys -> hdr.WhitePoint.Z * 100.; /* Normalize White point for CIECAM97s model */ cmsXYZ2xyY(&xyY, &sys -> hdr.device.whitePoint); xyY.Y = 100.; cmsxyY2XYZ(&sys -> hdr.device.whitePoint, &xyY); sys->hdr.hDevice = cmsCIECAM97sInit(&sys->hdr.device); sys->hdr.hPCS = cmsCIECAM97sInit(&sys->hdr.PCS); cmsSample3DGrid(AToB0, RegressionSamplerA2B, sys, 0); cmsSample3DGrid(BToA0, RegressionSamplerB2A, sys, 0); cmsCIECAM97sDone(sys->hdr.hDevice); cmsCIECAM97sDone(sys->hdr.hPCS); cmsAddTag(sys->hdr.hProfile, icSigAToB0Tag, AToB0); cmsAddTag(sys->hdr.hProfile, icSigBToA0Tag, BToA0); /* This is the 0xff00 trick to map white at lattice point */ BToA0 ->Matrix.v[0].n[0] = DOUBLE_TO_FIXED((65535.0 / 65280.0)); *A2B = AToB0; *B2A = BToA0; cmsFreeGammaTriple(sys->ReverseTables); cmsFreeGammaTriple(sys->PreLab); cmsFreeGammaTriple(sys->PreLabRev); return true; }
cmsHPROFILE LCMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, DWORD dwFlags) { cmsHPROFILE hICC; _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) hTransform; LPLUT Lut; LCMSBOOL MustFreeLUT; LPcmsNAMEDCOLORLIST InputColorant = NULL; LPcmsNAMEDCOLORLIST OutputColorant = NULL; // Check if is a named color transform if (cmsGetDeviceClass(v ->InputProfile) == icSigNamedColorClass) { return CreateNamedColorDevicelink(hTransform); } if (v ->DeviceLink) { Lut = v -> DeviceLink; MustFreeLUT = FALSE; } else { Lut = _cmsPrecalculateDeviceLink(hTransform, dwFlags); if (!Lut) return NULL; MustFreeLUT = TRUE; } hICC = _cmsCreateProfilePlaceholder(); if (!hICC) { // can't allocate if (MustFreeLUT) cmsFreeLUT(Lut); return NULL; } FixColorSpaces(hICC, v -> EntryColorSpace, v -> ExitColorSpace, dwFlags); cmsSetRenderingIntent(hICC, v -> Intent); // Implement devicelink profile using following tags: // // 1 icSigProfileDescriptionTag // 2 icSigMediaWhitePointTag // 3 icSigAToB0Tag cmsAddTag(hICC, icSigDeviceMfgDescTag, (LPVOID) "LittleCMS"); cmsAddTag(hICC, icSigProfileDescriptionTag, (LPVOID) "Device link"); cmsAddTag(hICC, icSigDeviceModelDescTag, (LPVOID) "Device link"); cmsAddTag(hICC, icSigMediaWhitePointTag, (LPVOID) cmsD50_XYZ()); if (cmsGetDeviceClass(hICC) == icSigOutputClass) { cmsAddTag(hICC, icSigBToA0Tag, (LPVOID) Lut); } else cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut); // Try to read input and output colorant table if (cmsIsTag(v ->InputProfile, icSigColorantTableTag)) { // Input table can only come in this way. InputColorant = cmsReadColorantTable(v ->InputProfile, icSigColorantTableTag); } // Output is a little bit more complex. if (cmsGetDeviceClass(v ->OutputProfile) == icSigLinkClass) { // This tag may exist only on devicelink profiles. if (cmsIsTag(v ->OutputProfile, icSigColorantTableOutTag)) { OutputColorant = cmsReadColorantTable(v ->OutputProfile, icSigColorantTableOutTag); } } else { if (cmsIsTag(v ->OutputProfile, icSigColorantTableTag)) { OutputColorant = cmsReadColorantTable(v ->OutputProfile, icSigColorantTableTag); } } if (InputColorant) cmsAddTag(hICC, icSigColorantTableTag, InputColorant); if (OutputColorant) cmsAddTag(hICC, icSigColorantTableOutTag, OutputColorant); if (MustFreeLUT) cmsFreeLUT(Lut); if (InputColorant) cmsFreeNamedColorList(InputColorant); if (OutputColorant) cmsFreeNamedColorList(OutputColorant); return hICC; }
int main(int argc, char *argv[]) { int i, nargs; cmsHPROFILE Profiles[257]; cmsHPROFILE hProfile; DWORD dwFlags = 0; cmsHTRANSFORM hTransform; fprintf(stderr, "little cms device link generator - v1.7\n"); HandleSwitches(argc, argv); cmsSetErrorHandler(MyErrorHandler); nargs = (argc - xoptind); if (nargs < 1) Help(0); if (nargs > 255) FatalError("ERROR: Holy profile! what are you trying to do with so many profiles?"); for (i=0; i < nargs; i++) { Profiles[i] = OpenProfile(argv[i + xoptind]); } switch (PrecalcMode) { case 0: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; case 1: if (NumOfGridPoints > 0) dwFlags |= cmsFLAGS_GRIDPOINTS(NumOfGridPoints); break; default: FatalError("ERROR: Unknown precalculation mode '%d'", PrecalcMode); } if (BlackPointCompensation) dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; if (BlackPreservation > 0) { dwFlags |= cmsFLAGS_PRESERVEBLACK; cmsSetCMYKPreservationStrategy(BlackPreservation-1); } if (TagResult) dwFlags |= cmsFLAGS_GUESSDEVICECLASS; if (NoPrelinearization) dwFlags |= cmsFLAGS_NOPRELINEARIZATION; if (InkLimit != 400.0) { cmsHPROFILE hInkLimit = cmsCreateInkLimitingDeviceLink( cmsGetColorSpace(Profiles[nargs-1]), InkLimit); Profiles[nargs++] = hInkLimit; } if (lUse8bits) dwFlags |= cmsFLAGS_NOPRELINEARIZATION; hTransform = cmsCreateMultiprofileTransform(Profiles, nargs, 0, 0, Intent, dwFlags); if (hTransform) { size_t size = sizeof(int) + nargs * sizeof(cmsPSEQDESC); LPcmsSEQ pseq = (LPcmsSEQ) _cmsMalloc(size); ZeroMemory(pseq, size); pseq ->n = nargs; for (i=0; i < nargs; i++) { strcpy(pseq ->seq[i].Manufacturer, cmsTakeManufacturer(Profiles[i])); strcpy(pseq ->seq[1].Model, cmsTakeModel(Profiles[i])); } hProfile = cmsTransform2DeviceLink(hTransform, dwFlags); cmsAddTag(hProfile, icSigProfileDescriptionTag, (LPVOID) Description); cmsAddTag(hProfile, icSigCopyrightTag, (LPVOID) "Generated by littlecms icclink. No copyright, use freely"); cmsAddTag(hProfile, icSigProfileSequenceDescTag, (LPVOID) pseq); if (lUse8bits) _cmsSetLUTdepth(hProfile, 8); if (_cmsSaveProfile(hProfile, cOutProf)) fprintf(stderr, "Ok"); else fprintf(stderr, "Error saving file!"); cmsCloseProfile(hProfile); _cmsFree(pseq); } cmsDeleteTransform(hTransform); for (i=0; i < nargs; i++) { cmsCloseProfile(Profiles[i]); } return 0; }
BOOL cmsxMonitorProfilerDo(LPMONITORPROFILERDATA sys) { cmsCIExyY White; LPLUT AToB0, BToA0; AToB0 = BToA0 = NULL; if (!*sys -> hdr.OutputProfileFile) return false; if (sys->hdr.ReferenceSheet[0] || sys->hdr.MeasurementSheet[0]) { if (sys->hdr.printf) { sys->hdr.printf("Loading sheets..."); if (sys->hdr.ReferenceSheet[0]) sys->hdr.printf("Reference sheet: %s", sys->hdr.ReferenceSheet); if (sys->hdr.MeasurementSheet[0]) sys->hdr.printf("Measurement sheet: %s", sys->hdr.MeasurementSheet); } if (!cmsxComputeMatrixShaper(sys -> hdr.ReferenceSheet, sys -> hdr.MeasurementSheet, MEDIUM_TRANSMISSIVE, sys -> Prelinearization, &sys -> hdr.WhitePoint, &sys -> hdr.BlackPoint, &sys -> hdr.Primaries)) return false; if (sys->hdr.printf) { char Buffer[1024]; _cmsIdentifyWhitePoint(Buffer, &sys ->hdr.WhitePoint); sys->hdr.printf("%s", Buffer); sys->hdr.printf("Primaries: R:%1.2g, %1.2g G:%1.2g, %1.2g B:%1.2g, %1.2g", sys->hdr.Primaries.Red.x,sys->hdr.Primaries.Red.y, sys->hdr.Primaries.Green.x, sys->hdr.Primaries.Green.y, sys->hdr.Primaries.Blue.x, sys->hdr.Primaries.Blue.y); } } CreatePrimaryMatrices(sys); cmsXYZ2xyY(&White, &sys->hdr.WhitePoint); sys->hdr.hProfile = cmsCreateRGBProfile(&White, &sys-> hdr.Primaries, sys -> Prelinearization); cmsSetDeviceClass(sys->hdr.hProfile, sys->hdr.DeviceClass); if (sys -> hdr.lUseCIECAM97s) sys->hdr.PCSType = PT_Lab; else sys->hdr.PCSType = PT_XYZ; cmsSetPCS(sys->hdr.hProfile, _cmsICCcolorSpace(sys->hdr.PCSType)); if (sys -> hdr.lUseCIECAM97s) CreateLUTS(sys, &AToB0, &BToA0); cmsxEmbedTextualInfo(&sys ->hdr); cmsAddTag(sys->hdr.hProfile, icSigMediaWhitePointTag, &sys->hdr.WhitePoint); cmsAddTag(sys->hdr.hProfile, icSigMediaBlackPointTag, &sys->hdr.BlackPoint); if (sys->hdr.ProfileVerbosityLevel >= 2) { cmsxEmbedCharTarget(&sys ->hdr); } _cmsSaveProfile(sys->hdr.hProfile, sys->hdr.OutputProfileFile); cmsCloseProfile(sys->hdr.hProfile); sys->hdr.hProfile = NULL; if (AToB0) cmsFreeLUT(AToB0); if (BToA0) cmsFreeLUT(BToA0); if (sys ->Prelinearization[0]) cmsFreeGammaTriple(sys -> Prelinearization); return true; }
cmsHPROFILE LCMSEXPORT cmsCreateRGBProfile(LPcmsCIExyY WhitePoint, LPcmsCIExyYTRIPLE Primaries, LPGAMMATABLE TransferFunction[3]) { cmsHPROFILE hICC; cmsCIEXYZ tmp; MAT3 MColorants; cmsCIEXYZTRIPLE Colorants; cmsCIExyY MaxWhite; hICC = _cmsCreateProfilePlaceholder(); if (!hICC) // can't allocate return NULL; cmsSetDeviceClass(hICC, icSigDisplayClass); cmsSetColorSpace(hICC, icSigRgbData); cmsSetPCS(hICC, icSigXYZData); cmsSetRenderingIntent(hICC, INTENT_PERCEPTUAL); // Implement profile using following tags: // // 1 icSigProfileDescriptionTag // 2 icSigMediaWhitePointTag // 3 icSigRedColorantTag // 4 icSigGreenColorantTag // 5 icSigBlueColorantTag // 6 icSigRedTRCTag // 7 icSigGreenTRCTag // 8 icSigBlueTRCTag // This conforms a standard RGB DisplayProfile as says ICC, and then I add // 9 icSigChromaticityTag // As addendum II // Fill-in the tags cmsAddTag(hICC, icSigDeviceMfgDescTag, (LPVOID) "(lcms internal)"); cmsAddTag(hICC, icSigProfileDescriptionTag, (LPVOID) "lcms RGB virtual profile"); cmsAddTag(hICC, icSigDeviceModelDescTag, (LPVOID) "rgb built-in"); if (WhitePoint) { cmsxyY2XYZ(&tmp, WhitePoint); cmsAddTag(hICC, icSigMediaWhitePointTag, (LPVOID) &tmp); } if (WhitePoint && Primaries) { MaxWhite.x = WhitePoint -> x; MaxWhite.y = WhitePoint -> y; MaxWhite.Y = 1.0; if (!cmsBuildRGB2XYZtransferMatrix(&MColorants, &MaxWhite, Primaries)) { cmsCloseProfile(hICC); return NULL; } cmsAdaptMatrixToD50(&MColorants, &MaxWhite); Colorants.Red.X = MColorants.v[0].n[0]; Colorants.Red.Y = MColorants.v[1].n[0]; Colorants.Red.Z = MColorants.v[2].n[0]; Colorants.Green.X = MColorants.v[0].n[1]; Colorants.Green.Y = MColorants.v[1].n[1]; Colorants.Green.Z = MColorants.v[2].n[1]; Colorants.Blue.X = MColorants.v[0].n[2]; Colorants.Blue.Y = MColorants.v[1].n[2]; Colorants.Blue.Z = MColorants.v[2].n[2]; cmsAddTag(hICC, icSigRedColorantTag, (LPVOID) &Colorants.Red); cmsAddTag(hICC, icSigBlueColorantTag, (LPVOID) &Colorants.Blue); cmsAddTag(hICC, icSigGreenColorantTag, (LPVOID) &Colorants.Green); } if (TransferFunction) { // In case of gamma, we must dup' the table pointer cmsAddTag(hICC, icSigRedTRCTag, (LPVOID) TransferFunction[0]); cmsAddTag(hICC, icSigGreenTRCTag, (LPVOID) TransferFunction[1]); cmsAddTag(hICC, icSigBlueTRCTag, (LPVOID) TransferFunction[2]); } if (Primaries) { cmsAddTag(hICC, icSigChromaticityTag, (LPVOID) Primaries); } return hICC; }
cmsHPROFILE LCMSEXPORT f_cmsCreateBCHSWabstractProfile(int nLUTPoints, double Exposure, double Bright, double Contrast, double Hue, double Saturation, LPcmsCIExyY current_wp, LPcmsCIExyY destination_wp, LPGAMMATABLE Tables []) { cmsHPROFILE hICC; LPLUT Lut; BCHSWADJUSTS bchsw; cmsCIExyY WhitePnt; bchsw.Exposure = Exposure; bchsw.Brightness = Bright; bchsw.Contrast = Contrast; bchsw.Hue = Hue; bchsw.Saturation = Saturation; cmsxyY2XYZ(&bchsw.WPsrc, current_wp); cmsxyY2XYZ(&bchsw.WPdest, destination_wp); hICC = _cmsCreateProfilePlaceholder(); if (!hICC) // can't allocate return NULL; cmsSetDeviceClass(hICC, icSigAbstractClass); cmsSetColorSpace(hICC, icSigLabData); cmsSetPCS(hICC, icSigLabData); cmsSetRenderingIntent(hICC, INTENT_PERCEPTUAL); // Creates a LUT with 3D grid only Lut = cmsAllocLUT(); cmsAlloc3DGrid(Lut, nLUTPoints, 3, 3); if (Tables != NULL) cmsAllocLinearTable (Lut, Tables, 1); if (!cmsSample3DGrid(Lut, bchswSampler, (LPVOID) &bchsw, 0)) { // Shouldn't reach here cmsFreeLUT(Lut); cmsCloseProfile(hICC); return NULL; } // Create tags cmsAddTag(hICC, icSigDeviceMfgDescTag, (LPVOID) "(f-spot internal)"); cmsAddTag(hICC, icSigProfileDescriptionTag, (LPVOID) "f-spot BCHSW abstract profile"); cmsAddTag(hICC, icSigDeviceModelDescTag, (LPVOID) "BCHSW built-in"); cmsAddTag(hICC, icSigMediaWhitePointTag, (LPVOID) cmsD50_XYZ()); cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut); // LUT is already on virtual profile cmsFreeLUT(Lut); // Ok, done return hICC; }
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; }