Ejemplo n.º 1
0
static
int bchswSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
{
    cmsCIELab LabIn, LabOut;
    cmsCIELCh LChIn, LChOut;
    cmsCIEXYZ XYZ;
    LPBCHSWADJUSTS bchsw = (LPBCHSWADJUSTS) Cargo;


    cmsLabEncoded2Float(&LabIn, In);


    cmsLab2LCh(&LChIn, &LabIn);

    // Do some adjusts on LCh

    LChOut.L = LChIn.L * bchsw ->Contrast + bchsw ->Brightness;
    LChOut.C = LChIn.C + bchsw -> Saturation;
    LChOut.h = LChIn.h + bchsw -> Hue;


    cmsLCh2Lab(&LabOut, &LChOut);

    // Move white point in Lab

    cmsLab2XYZ(&bchsw ->WPsrc,  &XYZ, &LabOut);
    cmsXYZ2Lab(&bchsw ->WPdest, &LabOut, &XYZ);

    // Back to encoded

    cmsFloat2LabEncoded(Out, &LabOut);

    return TRUE;
}
static
int bchswSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
{
    cmsCIELab LabIn, LabOut;
    cmsCIELCh LChIn, LChOut;
    cmsCIEXYZ XYZ;
    double l;
    double power;
    gboolean shift;

    LPBCHSWADJUSTS bchsw = (LPBCHSWADJUSTS) Cargo;    

    cmsLabEncoded2Float(&LabIn, In);
         // Move white point in Lab

    cmsLab2XYZ(&bchsw ->WPsrc,  &XYZ, &LabIn);
    cmsXYZ2Lab(&bchsw ->WPdest, &LabIn, &XYZ);

    shift = (LabIn.L > 0.5);
    l = LabIn.L / 100;
    if (shift)
	    l = 1.0 - l;

    if (l < 0.0)
	    l = 0.0;

    if (bchsw->Contrast < 0)
	    power = 1.0 + bchsw->Contrast;
    else
	    power = (bchsw->Contrast == 1.0) ? 127 : 1.0 / (1.0 - bchsw->Contrast);
	    
    l = 0.5 * pow (l * 2.0 , power);

    if (shift)
	    l = 1.0 - l;

    LabIn.L = l * 100;

    cmsLab2LCh(&LChIn, &LabIn);

    // Do some adjusts on LCh
    
    LChOut.L = LChIn.L * bchsw ->Exposure + bchsw ->Brightness;

    LChOut.C = MAX (0, LChIn.C + bchsw ->Saturation);
    LChOut.h = LChIn.h + bchsw ->Hue;
    
    cmsLCh2Lab(&LabOut, &LChOut);

    // Back to encoded

    cmsFloat2LabEncoded(Out, &LabOut);
    

    return TRUE;
}
Ejemplo n.º 3
0
static
int PCS2ITU(register cmsUInt16Number In[], register cmsUInt16Number Out[], register void*  Cargo)
{      
	cmsCIELab Lab;

	cmsLabEncoded2Float(&Lab, In);    
	cmsDesaturateLab(&Lab, 85, -85, 125, -75);    // This function does the necessary gamut remapping  
	Lab2ITU(&Lab, Out);
	return TRUE;
}
Ejemplo n.º 4
0
// Evaluates the CLUT part of a LUT (4 -> 3 only)
static
void EvalLUTdoubleKLab(LPLUT Lut, const VEC3* In, WORD FixedK, LPcmsCIELab Out)
{
    WORD wIn[4], wOut[3];

    wIn[0] = (WORD) floor(In ->n[0] * 65535.0 + 0.5);
    wIn[1] = (WORD) floor(In ->n[1] * 65535.0 + 0.5);
    wIn[2] = (WORD) floor(In ->n[2] * 65535.0 + 0.5);
    wIn[3] = FixedK;

    cmsEvalLUT(Lut, wIn, wOut);     
	cmsLabEncoded2Float(Out, wOut);
}
Ejemplo n.º 5
0
static
int Forward(register WORD In[], register WORD Out[], register LPVOID Cargo)
{
    cmsCIELab Lab;



    cmsLabEncoded2Float(&Lab, In);
    Lab.a = Lab.b = 0;
    cmsFloat2LabEncoded(Out, &Lab);

    return TRUE;
}
Ejemplo n.º 6
0
static
int RegressionSamplerB2A(register WORD In[], register WORD Out[], register LPVOID Cargo)
{
    cmsCIELab Lab;
    cmsCIEXYZ xyz;
    VEC3 vxyz, RGB;
    /* cmsJCh JCh; */
    WORD Lin[3], Llab[3];
    LPMONITORPROFILERDATA sys = (LPMONITORPROFILERDATA) Cargo;
    double L;


        /* Pass L back to 0..0xff00 domain */

        L = (double) (In[0] * 65280.0) / 65535.0;
        In[0] =  (WORD) floor(L + .5);


      /* To float values */
      cmsLabEncoded2Float(&Lab, In);
      cmsLab2XYZ(NULL, &xyz, &Lab);


      cmsxChromaticAdaptationAndNormalization(&sys ->hdr, &xyz, true);
      vxyz.n[0] = xyz.X;
      vxyz.n[1] = xyz.Y;
      vxyz.n[2] = xyz.Z;

      MAT3eval(&RGB, &sys-> PrimariesMatrixRev, &vxyz);

      /* Clamp RGB */
      ClampRGB(&RGB);

      /* Encode output */
      Lin[0] = (WORD) ((double) RGB.n[0] * 65535. + .5);
      Lin[1] = (WORD) ((double) RGB.n[1] * 65535. + .5);
      Lin[2] = (WORD) ((double) RGB.n[2] * 65535. + .5);

      cmsxApplyLinearizationGamma(Lin, sys ->ReverseTables, Llab);
      cmsxApplyLinearizationGamma(Llab, sys ->PreLabRev, Out);


    return true; /* And done witch success */
}
Ejemplo n.º 7
0
LCMSAPI double LCMSEXPORT cmsEvalLUTreverse(LPLUT Lut, WORD Target[], WORD Result[], LPWORD Hint)
{
    int      i;
    double     error, LastError = 1E20;
    cmsCIELab  fx, Goal;
    VEC3       tmp, tmp2, x;
    MAT3       Jacobian;
    WORD       FixedK;
    WORD       LastResult[4];
    
        
    // This is our Lab goal
    cmsLabEncoded2Float(&Goal, Target);
    
    // Special case for CMYK->Lab 

    if (Lut ->InputChan == 4)
            FixedK = Target[3];
    else
            FixedK = 0;
        
    
    // Take the hint as starting point if specified

    if (Hint == NULL) {

        // Begin at any point, we choose 1/3 of neutral CMY gray

        x.n[0] = x.n[1] = x.n[2] = 0.3;

    }
    else {

        FromEncoded(&x, Hint);
    }
    

    // Iterate
    
    for (i = 0; i < INVERSION_MAX_ITERATIONS; i++) {

        // Get beginning fx
        EvalLUTdoubleKLab(Lut, &x, FixedK, &fx);
    
        // Compute error
        error = cmsDeltaE(&fx, &Goal);
                        
        // If not convergent, return last safe value
        if (error >= LastError) 
            break;

        // Keep latest values
        LastError = error;

        ToEncoded(LastResult, &x);
        LastResult[3] = FixedK;
                
        // Obtain slope
        ComputeJacobianLab(Lut, &Jacobian, &x, FixedK);

		// Solve system
		tmp2.n[0] = fx.L - Goal.L;
		tmp2.n[1] = fx.a - Goal.a;
		tmp2.n[2] = fx.b - Goal.b;

		if (!MAT3solve(&tmp, &Jacobian, &tmp2))
			break;
		
       	// Move our guess
		x.n[0] -= tmp.n[0];
	    x.n[1] -= tmp.n[1];
		x.n[2] -= tmp.n[2];
               
        // Some clipping....
        VEC3saturate(&x);                
    }

    Result[0] = LastResult[0];
    Result[1] = LastResult[1];
    Result[2] = LastResult[2];
    Result[3] = LastResult[3];

    return LastError;    
    
}
Ejemplo n.º 8
0
static
int GamutSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
{
    LPGAMUTCHAIN t = (LPGAMUTCHAIN) Cargo;
    WORD Proof[MAXCHANNELS], Check[MAXCHANNELS];
    WORD Proof2[MAXCHANNELS], Check2[MAXCHANNELS];
    cmsCIELab LabIn1, LabOut1;  
    cmsCIELab LabIn2, LabOut2;  
    double dE1, dE2, ErrorRatio;
    
    // Assume in-gamut by default.
    dE1 = 0.;
    dE2 = 0;
    ErrorRatio = 1.0;
    

    // Any input space? I can use In[] no matter channels 
    // because is just one pixel

    if (t -> hInput != NULL) cmsDoTransform(t -> hInput, In, In, 1);

    // converts from PCS to colorant. This always
    // does return in-gamut values, 
    cmsDoTransform(t -> hForward, In, Proof, 1);
    
    // Now, do the inverse, from colorant to PCS.
    cmsDoTransform(t -> hReverse, Proof, Check, 1);
    
    
    // Try again, but this time taking Check as input
    cmsDoTransform(t -> hForward, Check, Proof2,  1);
    cmsDoTransform(t -> hReverse, Proof2, Check2, 1);
    
    
    
    // Does the transform returns out-of-gamut?
    if (Check[0] == 0xFFFF && 
        Check[1] == 0xFFFF && 
        Check[2] == 0xFFFF) 
        
        Out[0] = 0xFF00;            // Out of gamut!
    else {
        
        // Transport encoded values
        cmsLabEncoded2Float(&LabIn1,  In);
        cmsLabEncoded2Float(&LabOut1, Check);
        
        // Take difference of direct value
        dE1 = cmsDeltaE(&LabIn1, &LabOut1);        
                
        cmsLabEncoded2Float(&LabIn2,  Check);
        cmsLabEncoded2Float(&LabOut2, Check2);
        
        // Take difference of converted value
        dE2 = cmsDeltaE(&LabIn2, &LabOut2);                 
               
        
        // if dE1 is small and dE2 is small, value is likely to be in gamut
        if (dE1 < t->Thereshold && dE2 < t->Thereshold) 
            Out[0] = 0;
        else
            // if dE1 is small and dE2 is big, undefined. Assume in gamut
            if (dE1 < t->Thereshold && dE2 > t->Thereshold)
                Out[0] = 0;
            else
                // dE1 is big and dE2 is small, clearly out of gamut
                if (dE1 > t->Thereshold && dE2 < t->Thereshold)
                    Out[0] = (WORD) _cmsQuickFloor((dE1 - t->Thereshold) + .5);
                else  {
                    
                    // dE1 is big and dE2 is also big, could be due to perceptual mapping
                    // so take error ratio
                    if (dE2 == 0.0)
                        ErrorRatio = dE1;
                    else
                        ErrorRatio = dE1 / dE2;
                    
                    if (ErrorRatio > t->Thereshold) 
                        Out[0] = (WORD)  _cmsQuickFloor((ErrorRatio - t->Thereshold) + .5);
                    else
                        Out[0] = 0;
                }
            
    }    
    
    return TRUE;
}
Ejemplo n.º 9
0
static
void PrintResults(WORD Encoded[], icColorSpaceSignature ColorSpace)
{
    int i;

    switch (ColorSpace) {

    case icSigXYZData:
                    cmsXYZEncoded2Float(&xyz, Encoded);
                    PrintCooked("X", xyz.X * 100.); 
                    PrintCooked("Y", xyz.Y * 100.); 
                    PrintCooked("Z", xyz.Z * 100.);
                    break;

    case icSigLabData:
                    cmsLabEncoded2Float(&Lab, Encoded);
                    PrintCooked("L*", Lab.L); 
                    PrintCooked("a*", Lab.a); 
                    PrintCooked("b*", Lab.b);
                    break;

    case icSigLuvData:
                    PrintOne("L", Encoded[0]); 
                    PrintOne("u", Encoded[1]); 
                    PrintOne("v", Encoded[2]);
                    break;

    case icSigYCbCrData:
                    PrintOne("Y", Encoded[0]); 
                    PrintOne("Cb", Encoded[1]); 
                    PrintOne("Cr", Encoded[2]);
                    break;


    case icSigYxyData:
                    PrintOne("Y", Encoded[0]); 
                    PrintOne("x", Encoded[1]); 
                    PrintOne("y", Encoded[2]);
                    break;

    case icSigRgbData:
                    PrintOne("R", Encoded[0]); 
                    PrintOne("G", Encoded[1]); 
                    PrintOne("B", Encoded[2]);
                    break;

    case icSigGrayData:
                    PrintOne("G", Encoded[0]); 
                    break;

    case icSigHsvData:
                    PrintOne("H", Encoded[0]); 
                    PrintOne("s", Encoded[1]); 
                    PrintOne("v", Encoded[2]);
                    break;

    case icSigHlsData:
                    PrintOne("H", Encoded[0]); 
                    PrintOne("l", Encoded[1]); 
                    PrintOne("s", Encoded[2]);
                    break;

    case icSigCmykData:
                    Print100("C", Encoded[0]); 
                    Print100("M", Encoded[1]); 
                    Print100("Y", Encoded[2]); 
                    Print100("K", Encoded[3]);
                    break;

    case icSigCmyData:                        
                    Print100("C", Encoded[0]); 
                    Print100("M", Encoded[1]); 
                    Print100("Y", Encoded[2]); 
                    break;

    case icSigHexachromeData:
    case icSig6colorData:
                            
                    Print100("C", Encoded[0]); 
                    Print100("M", Encoded[1]); 
                    Print100("Y", Encoded[2]); 
                    Print100("K", Encoded[3]); 
                    Print100("c", Encoded[1]); 
                    Print100("m", Encoded[2]); 
                    break;

    default:

        for (i=0; i < _cmsChannelsOf(OutputColorSpace); i++) {
        
            char Buffer[10];
            sprintf(Buffer, "CHAN%d", i + 1);
            PrintOne(Buffer, Encoded[i]);           
        }   
    }



}