Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
// Simplified version of multiprofile transform creator
// Flags are removed from arguments. 
// Gamut checking and named color profiles are not supported.
// WARNING: I/O pixel formats should be specified for the created transform later by caller.
cmsHTRANSFORM cmmCreateMultiprofileTransform(cmsHPROFILE hProfiles[], int nProfiles, int Intent) 
{   
  DWORD inFmt, outFmt;
  cmsHPROFILE hTargetProfile, hProfile;   
  icColorSpaceSignature csIn, csOut;   

  LPLUT Grid = NULL;
  int nGridPoints, nInChannels, nOutChannels = 3, i = 0;

  _LPcmsTRANSFORM p; // Resulting transform        

  cmsHTRANSFORM transforms[255]; // Cannot merge more than 255 profiles
  ZeroMemory(transforms, sizeof(transforms));
  if (nProfiles > 255) {
    return NULL; // Too many profiles
  }

  // Check if there are any named color profiles
  for (i=0; i < nProfiles; i++) {
    if (cmsGetDeviceClass(hProfiles[i]) == icSigNamedColorClass ||
        cmsGetDeviceClass(hProfiles[i]) == icSigLinkClass) {
      return NULL; // Unsupported named color and device link profiles
    }
  }

  // Create a placeholder transform with dummy I/O formats to place LUT in it
  p = (_LPcmsTRANSFORM) 
    cmsCreateTransform(NULL, TYPE_RGB_8, NULL, TYPE_RGB_8, Intent, cmsFLAGS_NULLTRANSFORM);

  p->EntryColorSpace = cmsGetColorSpace(hProfiles[0]);    

  // Gater information about first input profile
  hProfile = hProfiles[0];
  csIn = cmsGetColorSpace(hProfile);
  nInChannels  = _cmsChannelsOf(csIn);
  inFmt = BYTES_SH(2) | CHANNELS_SH(nInChannels);

  // Create a sequence
  for (i=1; i < nProfiles; i++) {
    // Gather output parameters
    hTargetProfile = hProfiles[i];
    csOut = cmsGetColorSpace(hTargetProfile);
    nOutChannels = _cmsChannelsOf(csOut);               
    outFmt = BYTES_SH(2)|CHANNELS_SH(nOutChannels);
        
    transforms[i-1] = 
      cmsCreateTransform(
        hProfile, inFmt, 
        hTargetProfile, outFmt, 
        Intent, cmsFLAGS_NOTPRECALC | cmsFLAGS_NOTCACHE
      );           
    
    if(transforms[i-1] == NULL)
      CLEANUP_AND_RETURN(NULL); // Incompatible profiles?

    // Assign output parameters to input
    hProfile = hTargetProfile;
    csIn = csOut;
    nInChannels = nOutChannels;               
    inFmt = outFmt;
  }

  p->ExitColorSpace = csOut;
  transforms[i] = NULL; // End marker 

  p->InputProfile  = hProfiles[0];
  p->OutputProfile = hProfiles[nProfiles-1];

  nGridPoints = _cmsReasonableGridpointsByColorspace(p->EntryColorSpace, 0);
   
  nInChannels  = _cmsChannelsOf(cmsGetColorSpace(p->InputProfile));

  // Create 3DCLUT
  if (! (Grid = cmsAllocLUT())) 
    CLEANUP_AND_RETURN(NULL);

  Grid = cmsAlloc3DGrid(Grid, nGridPoints, nInChannels, nOutChannels);

  _cmsComputePrelinearizationTablesFromXFORM(transforms, nProfiles-1, Grid);
      
  // Compute device link on 16-bit basis                
  if (!cmsSample3DGrid(Grid, cmmMultiprofileSampler, (LPVOID) transforms, Grid -> wFlags)) 
    CLEANUP_AND_RETURN(NULL);
  
  // Put the new LUT into resulting transform
  p->DeviceLink = Grid;
  // Set transform method
  p->xform = cmmPrecalculatedXformImpl;

  // Commented out since it is not clear if it is correct or not
  // Sequential transforms gives same result as multiprofile with this call commented out
  /*  
  if(Intent != INTENT_ABSOLUTE_COLORIMETRIC)
      _cmsFixWhiteMisalignment(p);
  */

  // Don't clean LUT
  Grid = NULL;

  CLEANUP_AND_RETURN((cmsHTRANSFORM) p);
}
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;
}
Ejemplo n.º 4
0
void LCMSEXPORT cmsEvalLUT(LPLUT Lut, WORD In[], WORD Out[])
{
       register unsigned int i;
       WORD StageABC[MAXCHANNELS], StageLMN[MAXCHANNELS];

        
       // Try to speedup things on plain devicelinks       
       if (Lut ->wFlags == LUT_HAS3DGRID) {

            Lut ->CLut16params.Interp3D(In, Out, Lut -> T, &Lut -> CLut16params);
            return;
       }
       

       // Nope, evaluate whole LUT

       for (i=0; i < Lut -> InputChan; i++)
                            StageABC[i] = In[i];

       
       if (Lut ->wFlags & LUT_V4_OUTPUT_EMULATE_V2) {
           
           // Clamp Lab to avoid overflow
           if (StageABC[0] > 0xFF00)
               StageABC[0] = 0xFF00;

           StageABC[0] = (WORD) FROM_V2_TO_V4(StageABC[0]);
           StageABC[1] = (WORD) FROM_V2_TO_V4(StageABC[1]);
           StageABC[2] = (WORD) FROM_V2_TO_V4(StageABC[2]);
           
       }

       if (Lut ->wFlags & LUT_V2_OUTPUT_EMULATE_V4) {
           
           StageABC[0] = (WORD) FROM_V4_TO_V2(StageABC[0]);
           StageABC[1] = (WORD) FROM_V4_TO_V2(StageABC[1]);
           StageABC[2] = (WORD) FROM_V4_TO_V2(StageABC[2]);           
       }


       // Matrix handling. 

       if (Lut -> wFlags & LUT_HASMATRIX) {

              WVEC3 InVect, OutVect;
              
              // In LUT8 here comes the special gray axis fixup

              if (Lut ->FixGrayAxes) {

                  StageABC[1] = _cmsClampWord(StageABC[1] - 128);
                  StageABC[2] = _cmsClampWord(StageABC[2] - 128);
              }

              // Matrix 

              InVect.n[VX] = ToFixedDomain(StageABC[0]);
              InVect.n[VY] = ToFixedDomain(StageABC[1]);
              InVect.n[VZ] = ToFixedDomain(StageABC[2]);
              

              MAT3evalW(&OutVect, &Lut -> Matrix, &InVect);

              // PCS in 1Fixed15 format, adjusting

              StageABC[0] = _cmsClampWord(FromFixedDomain(OutVect.n[VX]));
              StageABC[1] = _cmsClampWord(FromFixedDomain(OutVect.n[VY]));
              StageABC[2] = _cmsClampWord(FromFixedDomain(OutVect.n[VZ]));
       }
       

       // First linearization

       if (Lut -> wFlags & LUT_HASTL1)
       {
              for (i=0; i < Lut -> InputChan; i++)
                     StageABC[i] = cmsLinearInterpLUT16(StageABC[i],
                                                   Lut -> L1[i],
                                                   &Lut -> In16params);
       }


       //  Mat3, Ofs3, L3 processing
             
       if (Lut ->wFlags & LUT_HASMATRIX3) {

              WVEC3 InVect, OutVect;

              InVect.n[VX] = ToFixedDomain(StageABC[0]);
              InVect.n[VY] = ToFixedDomain(StageABC[1]);
              InVect.n[VZ] = ToFixedDomain(StageABC[2]);

              MAT3evalW(&OutVect, &Lut -> Mat3, &InVect);              

              OutVect.n[VX] += Lut ->Ofs3.n[VX];
              OutVect.n[VY] += Lut ->Ofs3.n[VY];
              OutVect.n[VZ] += Lut ->Ofs3.n[VZ];

              StageABC[0] = _cmsClampWord(FromFixedDomain(OutVect.n[VX]));
              StageABC[1] = _cmsClampWord(FromFixedDomain(OutVect.n[VY]));
              StageABC[2] = _cmsClampWord(FromFixedDomain(OutVect.n[VZ]));

       }
       
       if (Lut ->wFlags & LUT_HASTL3) {

             for (i=0; i < Lut -> InputChan; i++)
                     StageABC[i] = cmsLinearInterpLUT16(StageABC[i],
                                                   Lut -> L3[i],
                                                   &Lut -> L3params);

       }



       if (Lut -> wFlags & LUT_HAS3DGRID) {

           if (!Lut->CLut16params.Interp3D)
               cmsAlloc3DGrid(Lut, 33, Lut->InputChan, Lut->OutputChan);

            Lut ->CLut16params.Interp3D(StageABC, StageLMN, Lut -> T, &Lut -> CLut16params);

       }
       else
       {              

              for (i=0; i < Lut -> InputChan; i++)
                            StageLMN[i] = StageABC[i];

       }


       // Mat4, Ofs4, L4 processing
     
       if (Lut ->wFlags & LUT_HASTL4) {

            for (i=0; i < Lut -> OutputChan; i++)
                     StageLMN[i] = cmsLinearInterpLUT16(StageLMN[i],
                                                   Lut -> L4[i],
                                                   &Lut -> L4params);
       }
        
       if (Lut ->wFlags & LUT_HASMATRIX4) {

              WVEC3 InVect, OutVect;

              InVect.n[VX] = ToFixedDomain(StageLMN[0]);
              InVect.n[VY] = ToFixedDomain(StageLMN[1]);
              InVect.n[VZ] = ToFixedDomain(StageLMN[2]);

              MAT3evalW(&OutVect, &Lut -> Mat4, &InVect);              

              OutVect.n[VX] += Lut ->Ofs4.n[VX];
              OutVect.n[VY] += Lut ->Ofs4.n[VY];
              OutVect.n[VZ] += Lut ->Ofs4.n[VZ];

              StageLMN[0] = _cmsClampWord(FromFixedDomain(OutVect.n[VX]));
              StageLMN[1] = _cmsClampWord(FromFixedDomain(OutVect.n[VY]));
              StageLMN[2] = _cmsClampWord(FromFixedDomain(OutVect.n[VZ]));

       }

       // Last linearitzation

       if (Lut -> wFlags & LUT_HASTL2)
       {
              for (i=0; i < Lut -> OutputChan; i++)
                     Out[i] = cmsLinearInterpLUT16(StageLMN[i],
                                                   Lut -> L2[i],
                                                   &Lut -> Out16params);
       }
       else
       {
       for (i=0; i < Lut -> OutputChan; i++)
              Out[i] = StageLMN[i];
       }

       

       if (Lut ->wFlags & LUT_V4_INPUT_EMULATE_V2) {
           
           Out[0] = (WORD) FROM_V4_TO_V2(Out[0]);
           Out[1] = (WORD) FROM_V4_TO_V2(Out[1]);
           Out[2] = (WORD) FROM_V4_TO_V2(Out[2]);
           
       }

       if (Lut ->wFlags & LUT_V2_INPUT_EMULATE_V4) {
           
           Out[0] = (WORD) FROM_V2_TO_V4(Out[0]);
           Out[1] = (WORD) FROM_V2_TO_V4(Out[1]);
           Out[2] = (WORD) FROM_V2_TO_V4(Out[2]);           
       }
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}