static void HandleSwitches(int argc, char *argv[]) { int s; while ((s = xgetopt(argc, argv, "bBC:c:d:D:eEgGI:i:L:l:m:M:nNO:o:p:P:QqSsT:t:V:v:WwxX!:")) != EOF) { switch (s){ case '!': IncludePart = xoptarg; break; case 'b': case 'B': BlackPointCompensation = TRUE; break; case 'c': case 'C': PrecalcMode = atoi(xoptarg); if (PrecalcMode < 0 || PrecalcMode > 3) FatalError("Unknown precalc mode '%d'", PrecalcMode); break; case 'd': case 'D': { cmsFloat64Number ObserverAdaptationState = atof(xoptarg); if (ObserverAdaptationState < 0 || ObserverAdaptationState > 1.0) FatalError("Adaptation states should be between 0 and 1"); cmsSetAdaptationState(ObserverAdaptationState); } break; case 'e': case 'E': lIsFloat = FALSE; break; case 'g': case 'G': GamutCheck = TRUE; break; case 'i': case 'I': if (lIsDeviceLink) FatalError("icctrans: Device-link already specified"); cInProf = xoptarg; break; case 'l': case 'L': cInProf = xoptarg; lIsDeviceLink = TRUE; break; // No extra intents for proofing case 'm': case 'M': ProofingIntent = atoi(xoptarg); if (ProofingIntent > 3) FatalError("Unknown Proofing Intent '%d'", ProofingIntent); break; // For compatibility case 'n': case 'N': Verbose = 0; break; // Output profile case 'o': case 'O': if (lIsDeviceLink) FatalError("icctrans: Device-link already specified"); cOutProf = xoptarg; break; // Proofing profile case 'p': case 'P': cProofing = xoptarg; break; // Quantize (get rid of decimals) case 'q': case 'Q': lQuantize = TRUE; break; // Inhibit unbounded mode case 's': case 'S': lUnbounded = FALSE; break; // The intent case 't': case 'T': Intent = atoi(xoptarg); break; // Verbosity level case 'V': case 'v': Verbose = atoi(xoptarg); if (Verbose < 0 || Verbose > 3) { FatalError("Unknown verbosity level '%d'", Verbose); } break; // Wide (16 bits) case 'W': case 'w': Width16 = TRUE; break; // Hexadecimal case 'x': case 'X': InHexa = TRUE; break; default: FatalError("Unknown option - run without args to see valid ones.\n"); } } // If output CGATS involved, switch to float if ((argc - xoptind) > 2) { lIsFloat = TRUE; } }
static int TransformImage(TIFF* in, TIFF* out, const char *cDefInpProf, const char *cOutProf) { cmsHPROFILE hIn, hOut, hProof, hInkLimit = NULL; cmsHTRANSFORM xform; DWORD wInput, wOutput; int OutputColorSpace; int bps = (Width16 ? 2 : 1); DWORD dwFlags = 0; int nPlanes; // Observer adaptation state (only meaningful on absolute colorimetric intent) cmsSetAdaptationState(ObserverAdaptationState); if (EmbedProfile && cOutProf) DoEmbedProfile(out, cOutProf); if (BlackWhiteCompensation) dwFlags |= cmsFLAGS_WHITEBLACKCOMPENSATION; if (PreserveBlack) { dwFlags |= cmsFLAGS_PRESERVEBLACK; if (PrecalcMode == 0) PrecalcMode = 1; } 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 (GamutCheck) dwFlags |= cmsFLAGS_GAMUTCHECK; hProof = NULL; hOut = NULL; if (lIsDeviceLink) { hIn = cmsOpenProfileFromFile(cDefInpProf, "r"); } else { hIn = GetTIFFProfile(in); if (hIn == NULL) hIn = OpenStockProfile(cDefInpProf); hOut = OpenStockProfile(cOutProf); if (cProofing != NULL) { hProof = OpenStockProfile(cProofing); dwFlags |= cmsFLAGS_SOFTPROOFING; } } // Take input color space wInput = GetInputPixelType(in); // Assure both, input profile and input TIFF are on same colorspace if (_cmsLCMScolorSpace(cmsGetColorSpace(hIn)) != (int) T_COLORSPACE(wInput)) FatalError("Input profile is not operating in proper color space"); if (!lIsDeviceLink) OutputColorSpace = _cmsLCMScolorSpace(cmsGetColorSpace(hOut)); else OutputColorSpace = _cmsLCMScolorSpace(cmsGetPCS(hIn)); wOutput = ComputeOutputFormatDescriptor(wInput, OutputColorSpace, bps); WriteOutputTags(out, OutputColorSpace, bps); CopyOtherTags(in, out); // Ink limit if (InkLimit != 400.0 && (OutputColorSpace == PT_CMYK || OutputColorSpace == PT_CMY)) { cmsHPROFILE hProfiles[10]; int nProfiles = 0; hInkLimit = cmsCreateInkLimitingDeviceLink(cmsGetColorSpace(hOut), InkLimit); hProfiles[nProfiles++] = hIn; if (hProof) { hProfiles[nProfiles++] = hProof; hProfiles[nProfiles++] = hProof; } hProfiles[nProfiles++] = hOut; hProfiles[nProfiles++] = hInkLimit; xform = cmsCreateMultiprofileTransform(hProfiles, nProfiles, wInput, wOutput, Intent, dwFlags); } else { xform = cmsCreateProofingTransform(hIn, wInput, hOut, wOutput, hProof, Intent, ProofingIntent, dwFlags); } // Planar stuff if (T_PLANAR(wInput)) nPlanes = T_CHANNELS(wInput) + T_EXTRA(wInput); else nPlanes = 1; // TIFF Lab of 8 bits need special handling if (wInput == TYPE_Lab_8 && !InputLabUsingICC && cInpProf != NULL && stricmp(cInpProf, "*Lab") == 0) { cmsSetUserFormatters(xform, TYPE_Lab_8, UnrollTIFFLab8, TYPE_Lab_8, NULL); } if (wOutput == TYPE_Lab_8 && cOutProf != NULL && stricmp(cOutProf, "*Lab") == 0) { cmsSetUserFormatters(xform, TYPE_Lab_8, NULL, TYPE_Lab_8, PackTIFFLab8); } // Handle tile by tile or strip by strip if (TIFFIsTiled(in)) { TileBasedXform(xform, in, out, nPlanes); } else { StripBasedXform(xform, in, out, nPlanes); } cmsDeleteTransform(xform); cmsCloseProfile(hIn); cmsCloseProfile(hOut); if (hInkLimit) cmsCloseProfile(hInkLimit); if (hProof) cmsCloseProfile(hProof); TIFFWriteDirectory(out); return 1; }
static int TransformImage(char *cDefInpProf, char *cOutProf) { cmsHPROFILE hIn, hOut, hProof; cmsHTRANSFORM xform; cmsUInt32Number wInput, wOutput; int OutputColorSpace; cmsUInt32Number dwFlags = 0; cmsUInt32Number EmbedLen; cmsUInt8Number* EmbedBuffer; cmsSetAdaptationState(ObserverAdaptationState); if (BlackPointCompensation) { dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; } switch (PrecalcMode) { case 0: dwFlags |= cmsFLAGS_NOOPTIMIZE; break; case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; case 3: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; default:; } if (GamutCheck) { dwFlags |= cmsFLAGS_GAMUTCHECK; cmsSetAlarmCodes(Alarm); } // Take input color space wInput = GetInputPixelType(); if (lIsDeviceLink) { hIn = cmsOpenProfileFromFile(cDefInpProf, "r"); hOut = NULL; hProof = NULL; } else { if (!IgnoreEmbedded && read_icc_profile(&Decompressor, &EmbedBuffer, &EmbedLen)) { hIn = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen); if (Verbose) { fprintf(stdout, " (Embedded profile found)\n"); PrintProfileInformation(hIn); fflush(stdout); } if (hIn != NULL && SaveEmbedded != NULL) SaveMemoryBlock(EmbedBuffer, EmbedLen, SaveEmbedded); free(EmbedBuffer); } else { // Default for ITU/Fax if (cDefInpProf == NULL && T_COLORSPACE(wInput) == PT_Lab) cDefInpProf = "*Lab"; if (cDefInpProf != NULL && cmsstrcasecmp(cDefInpProf, "*lab") == 0) hIn = CreateITU2PCS_ICC(); else hIn = OpenStockProfile(0, cDefInpProf); } if (cOutProf != NULL && cmsstrcasecmp(cOutProf, "*lab") == 0) hOut = CreatePCS2ITU_ICC(); else hOut = OpenStockProfile(0, cOutProf); hProof = NULL; if (cProofing != NULL) { hProof = OpenStockProfile(0, cProofing); if (hProof == NULL) { FatalError("Proofing profile couldn't be read."); } dwFlags |= cmsFLAGS_SOFTPROOFING; } } if (!hIn) FatalError("Input profile couldn't be read."); if (!hOut) FatalError("Output profile couldn't be read."); // Assure both, input profile and input JPEG are on same colorspace if (cmsGetColorSpace(hIn) != _cmsICCcolorSpace(T_COLORSPACE(wInput))) FatalError("Input profile is not operating in proper color space"); // Output colorspace is given by output profile if (lIsDeviceLink) { OutputColorSpace = GetDevicelinkColorSpace(hIn); } else { OutputColorSpace = GetProfileColorSpace(hOut); } jpeg_copy_critical_parameters(&Decompressor, &Compressor); WriteOutputFields(OutputColorSpace); wOutput = ComputeOutputFormatDescriptor(wInput, OutputColorSpace); xform = cmsCreateProofingTransform(hIn, wInput, hOut, wOutput, hProof, Intent, ProofingIntent, dwFlags); if (xform == NULL) FatalError("Cannot transform by using the profiles"); DoTransform(xform, OutputColorSpace); jcopy_markers_execute(&Decompressor, &Compressor); cmsDeleteTransform(xform); cmsCloseProfile(hIn); cmsCloseProfile(hOut); if (hProof) cmsCloseProfile(hProof); return 1; }
int main(int argc, char *argv[]) { int i, nargs, rc; cmsHPROFILE Profiles[257]; cmsHPROFILE hProfile; cmsUInt32Number dwFlags; cmsHTRANSFORM hTransform = NULL; // Here we are fprintf(stderr, "little cms ICC device link generator - v2.2 [LittleCMS %2.2f]\n", LCMS_VERSION / 1000.0); fflush(stderr); // Initialize InitUtils("linkicc"); rc = 0; // Get the options HandleSwitches(argc, argv); // How many profiles to link? nargs = (argc - xoptind); if (nargs < 1) return Help(0); if (nargs > 255) { FatalError("Holy profile! what are you trying to do with so many profiles!?"); goto Cleanup; } // Open all profiles memset(Profiles, 0, sizeof(Profiles)); for (i=0; i < nargs; i++) { Profiles[i] = OpenStockProfile(0, argv[i + xoptind]); if (Profiles[i] == NULL) goto Cleanup; if (Verbose >= 1) { PrintProfileInformation(Profiles[i]); } } // Ink limiting if (InkLimit != 400.0) { cmsColorSpaceSignature EndingColorSpace = cmsGetColorSpace(Profiles[nargs-1]); Profiles[nargs++] = cmsCreateInkLimitingDeviceLink(EndingColorSpace, InkLimit); } // Set the flags dwFlags = cmsFLAGS_KEEP_SEQUENCE; 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("Unknown precalculation mode '%d'", PrecalcMode); goto Cleanup; } } if (BlackPointCompensation) dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; if (TagResult) dwFlags |= cmsFLAGS_GUESSDEVICECLASS; if (KeepLinearization) dwFlags |= cmsFLAGS_CLUT_PRE_LINEARIZATION|cmsFLAGS_CLUT_POST_LINEARIZATION; if (lUse8bits) dwFlags |= cmsFLAGS_8BITS_DEVICELINK; cmsSetAdaptationState(ObserverAdaptationState); // Create the color transform. Specify 0 for the format is safe as the transform // is intended to be used only for the devicelink. hTransform = cmsCreateMultiprofileTransform(Profiles, nargs, 0, 0, Intent, dwFlags|cmsFLAGS_NOOPTIMIZE); if (hTransform == NULL) { FatalError("Transform creation failed"); goto Cleanup; } hProfile = cmsTransform2DeviceLink(hTransform, Version, dwFlags); if (hProfile == NULL) { FatalError("Devicelink creation failed"); goto Cleanup; } SetTextTags(hProfile); cmsSetHeaderRenderingIntent(hProfile, Intent); if (cmsSaveProfileToFile(hProfile, cOutProf)) { if (Verbose > 0) fprintf(stderr, "Ok"); } else FatalError("Error saving file!"); cmsCloseProfile(hProfile); Cleanup: if (hTransform != NULL) cmsDeleteTransform(hTransform); for (i=0; i < nargs; i++) { if (Profiles[i] != NULL) cmsCloseProfile(Profiles[i]); } return rc; }