Esempio n. 1
0
static
void Rel2RelStepAbsCoefs(double AdaptationState,

                         LPcmsCIEXYZ BlackPointIn,
                         LPcmsCIEXYZ WhitePointIn,
                         LPcmsCIEXYZ IlluminantIn,
                         LPMAT3 ChromaticAdaptationMatrixIn,

                         LPcmsCIEXYZ BlackPointOut,
                         LPcmsCIEXYZ WhitePointOut,
                         LPcmsCIEXYZ IlluminantOut,
                         LPMAT3 ChromaticAdaptationMatrixOut,

                         LPMAT3 m, LPVEC3 of)
{
       
       VEC3 WtPtIn, WtPtInAdapted;
       VEC3 WtPtOut, WtPtOutAdapted;
       MAT3 Scale, m1, m2, m3;
       
       VEC3init(&WtPtIn, WhitePointIn->X, WhitePointIn->Y, WhitePointIn->Z);
       MAT3eval(&WtPtInAdapted, ChromaticAdaptationMatrixIn, &WtPtIn);
                  
       VEC3init(&WtPtOut, WhitePointOut->X, WhitePointOut->Y, WhitePointOut->Z);
       MAT3eval(&WtPtOutAdapted, ChromaticAdaptationMatrixOut, &WtPtOut);

       VEC3init(&Scale.v[0], WtPtInAdapted.n[0] / WtPtOutAdapted.n[0], 0, 0);
       VEC3init(&Scale.v[1], 0, WtPtInAdapted.n[1] / WtPtOutAdapted.n[1], 0);
       VEC3init(&Scale.v[2], 0, 0, WtPtInAdapted.n[2] / WtPtOutAdapted.n[2]);


       // Adaptation state

       if (AdaptationState == 1.0) {

           // Observer is fully adapted. Keep chromatic adaptation 

           CopyMemory(m, &Scale, sizeof(MAT3));

       }
       else {

            // Observer is not adapted, undo the chromatic adaptation
            m1 = *ChromaticAdaptationMatrixIn;
            MAT3inverse(&m1, &m2);
       
            MAT3per(&m3, &m2, &Scale);
            MAT3per(m, &m3, ChromaticAdaptationMatrixOut);
       }

            
       VEC3init(of, 0.0, 0.0, 0.0);
                    
}
Esempio n. 2
0
static
void ComputeChromaticAdaptation(LPMAT3 Conversion,
                                LPcmsCIEXYZ SourceWhitePoint,
                                LPcmsCIEXYZ DestWhitePoint,
                                LPMAT3 Chad)

{
      
        MAT3 Chad_Inv;
        VEC3 ConeSourceXYZ, ConeSourceRGB;
        VEC3 ConeDestXYZ, ConeDestRGB;
        MAT3 Cone, Tmp;


        Tmp = *Chad;
        MAT3inverse(&Tmp, &Chad_Inv);

        VEC3init(&ConeSourceXYZ, SourceWhitePoint -> X,
                                 SourceWhitePoint -> Y,
                                 SourceWhitePoint -> Z);

        VEC3init(&ConeDestXYZ,   DestWhitePoint -> X,
                                 DestWhitePoint -> Y,
                                 DestWhitePoint -> Z);

        MAT3eval(&ConeSourceRGB, Chad, &ConeSourceXYZ);
        MAT3eval(&ConeDestRGB,   Chad, &ConeDestXYZ);

        // Build matrix

        VEC3init(&Cone.v[0], ConeDestRGB.n[0]/ConeSourceRGB.n[0],    0.0,  0.0);
        VEC3init(&Cone.v[1], 0.0,   ConeDestRGB.n[1]/ConeSourceRGB.n[1],   0.0);
        VEC3init(&Cone.v[2], 0.0,   0.0,   ConeDestRGB.n[2]/ConeSourceRGB.n[2]);


        // Normalize
        MAT3per(&Tmp, &Cone, Chad);
        MAT3per(Conversion, &Chad_Inv, &Tmp);

}
Esempio n. 3
0
BOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt,
                                            LPcmsCIExyYTRIPLE Primrs)
{
        VEC3 WhitePoint, Coef;
        MAT3 Result, Primaries;
        double xn, yn;
        double xr, yr;
        double xg, yg;
        double xb, yb;


        xn = WhitePt -> x;
        yn = WhitePt -> y;
        xr = Primrs -> Red.x;
        yr = Primrs -> Red.y;
        xg = Primrs -> Green.x;
        yg = Primrs -> Green.y;
        xb = Primrs -> Blue.x;
        yb = Primrs -> Blue.y;


        // Build Primaries matrix

        VEC3init(&Primaries.v[0], xr,        xg,         xb);
        VEC3init(&Primaries.v[1], yr,        yg,         yb);
        VEC3init(&Primaries.v[2], (1-xr-yr), (1-xg-yg),  (1-xb-yb));


        // Result = Primaries ^ (-1) inverse matrix

        if (!MAT3inverse(&Primaries, &Result))
                        return FALSE;


        VEC3init(&WhitePoint, xn/yn, 1.0, (1.0-xn-yn)/yn);

        // Across inverse primaries ...

        MAT3eval(&Coef, &Result, &WhitePoint);

        // Give us the Coefs, then I build transformation matrix

        VEC3init(&r -> v[0], Coef.n[VX]*xr,          Coef.n[VY]*xg,          Coef.n[VZ]*xb);
        VEC3init(&r -> v[1], Coef.n[VX]*yr,          Coef.n[VY]*yg,          Coef.n[VZ]*yb);
        VEC3init(&r -> v[2], Coef.n[VX]*(1.0-xr-yr), Coef.n[VY]*(1.0-xg-yg), Coef.n[VZ]*(1.0-xb-yb));
       

        return TRUE;
}
Esempio n. 4
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 */
}
Esempio n. 5
0
BOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result, 
                                     LPcmsCIEXYZ SourceWhitePt, 
                                     LPcmsCIEXYZ Illuminant, 
                                     LPcmsCIEXYZ Value)
{
        MAT3 Bradford;
        VEC3 In, Out;
    
        // BradfordLamRiggChromaticAdaptation(&Bradford, SourceWhitePt, Illuminant);

        cmsAdaptationMatrix(&Bradford, NULL, SourceWhitePt, Illuminant);

        VEC3init(&In, Value -> X, Value -> Y, Value -> Z);
        MAT3eval(&Out, &Bradford, &In);

        Result -> X = Out.n[0];
        Result -> Y = Out.n[1];
        Result -> Z = Out.n[2];

        return TRUE;
}
Esempio n. 6
0
static
int RegressionSamplerA2B(register WORD In[], register WORD Out[], register LPVOID Cargo)
{
    cmsCIEXYZ xyz;
    cmsCIELab Lab;
    VEC3 RGB, RGBlinear, vxyz;
    LPMONITORPROFILERDATA sys = (LPMONITORPROFILERDATA) Cargo;


        RGB.n[0] = _cmsxSaturate65535To255(In[0]);
        RGB.n[1] = _cmsxSaturate65535To255(In[1]);
        RGB.n[2] = _cmsxSaturate65535To255(In[2]);

        cmsxApplyLinearizationTable(RGB.n, sys->PreLab, RGBlinear.n);
        cmsxApplyLinearizationTable(RGBlinear.n, sys->Prelinearization, RGBlinear.n);

        RGBlinear.n[0] /= 255.;
        RGBlinear.n[1] /= 255.;
        RGBlinear.n[2] /= 255.;

        MAT3eval(&vxyz, &sys->PrimariesMatrix, &RGBlinear);

        xyz.X = vxyz.n[0];
        xyz.Y = vxyz.n[1];
        xyz.Z = vxyz.n[2];

        cmsxChromaticAdaptationAndNormalization(&sys ->hdr, &xyz, false);


       /* To PCS encoding */

       cmsXYZ2Lab(NULL, &Lab, &xyz);
       cmsFloat2LabEncoded(Out, &Lab);


    return true; /* And done witch success */
}
Esempio n. 7
0
BOOL cmsxComputeMatrixShaper(const char* ReferenceSheet,
                             const char* MeasurementSheet,
                             int Medium,
                             LPGAMMATABLE TransferCurves[3],
                             LPcmsCIEXYZ WhitePoint,
                             LPcmsCIEXYZ BlackPoint,
                             LPcmsCIExyYTRIPLE Primaries)
{

    MEASUREMENT Linearized;
    cmsCIEXYZ Black, White;
    cmsCIExyYTRIPLE  PrimarySet;
    LPPATCH PatchWhite, PatchBlack;
    LPPATCH PatchRed, PatchGreen, PatchBlue;
    double Distance;

    /* Load sheets */

    if (!cmsxPCollBuildMeasurement(&Linearized,
                             ReferenceSheet,
                             MeasurementSheet,
                             PATCH_HAS_XYZ|PATCH_HAS_RGB)) return false;



    /* Any patch to deal of? */
    if (cmsxPCollCountSet(&Linearized, Linearized.Allowed) <= 0) return false;


    /* Try to see if proper primaries, white and black already present */
    PatchWhite = cmsxPCollFindWhite(&Linearized, Linearized.Allowed, &Distance);
    if (Distance != 0)
        PatchWhite = NULL;

    PatchBlack = cmsxPCollFindBlack(&Linearized, Linearized.Allowed, &Distance);
    if (Distance != 0)
        PatchBlack = NULL;

    PatchRed = cmsxPCollFindPrimary(&Linearized, Linearized.Allowed, 0, &Distance);
    if (Distance != 0)
        PatchRed = NULL;

    PatchGreen = cmsxPCollFindPrimary(&Linearized, Linearized.Allowed, 1, &Distance);
    if (Distance != 0)
        PatchGreen = NULL;

    PatchBlue = cmsxPCollFindPrimary(&Linearized, Linearized.Allowed, 2, &Distance);
    if (Distance != 0)
        PatchBlue= NULL;

    /* If we got primaries, then we can also get prelinearization */
    /* by  Levenberg-Marquardt. This applies on monitor profiles */

    if (PatchWhite && PatchRed && PatchGreen && PatchBlue) {

        /* Build matrix with primaries */

        MAT3 Mat, MatInv;
        LPSAMPLEDCURVE Xr,Yr, Xg, Yg, Xb, Yb;
        int i, nRes, cnt;

        VEC3init(&Mat.v[0], PatchRed->XYZ.X, PatchGreen->XYZ.X, PatchBlue->XYZ.X);
        VEC3init(&Mat.v[1], PatchRed->XYZ.Y, PatchGreen->XYZ.Y, PatchBlue->XYZ.Y);
        VEC3init(&Mat.v[2], PatchRed->XYZ.Z, PatchGreen->XYZ.Z, PatchBlue->XYZ.Z);

        /* Invert matrix */
        MAT3inverse(&Mat, &MatInv);

        nRes = cmsxPCollCountSet(&Linearized, Linearized.Allowed);

        Xr = cmsAllocSampledCurve(nRes);
        Yr = cmsAllocSampledCurve(nRes);
        Xg = cmsAllocSampledCurve(nRes);
        Yg = cmsAllocSampledCurve(nRes);
        Xb = cmsAllocSampledCurve(nRes);
        Yb = cmsAllocSampledCurve(nRes);

        /* Convert XYZ of all patches to RGB */
        cnt = 0;
        for (i=0; i < Linearized.nPatches; i++) {

            if (Linearized.Allowed[i]) {

                VEC3 RGBprime, XYZ;
                LPPATCH p;

                p = Linearized.Patches + i;
                XYZ.n[0] = p -> XYZ.X;
                XYZ.n[1] = p -> XYZ.Y;
                XYZ.n[2] = p -> XYZ.Z;

                MAT3eval(&RGBprime, &MatInv, &XYZ);

                Xr ->Values[cnt] = p ->Colorant.RGB[0];
                Yr ->Values[cnt] = Clip(RGBprime.n[0]);

                Xg ->Values[cnt] = p ->Colorant.RGB[1];
                Yg ->Values[cnt] = Clip(RGBprime.n[1]);

                Xb ->Values[cnt] = p ->Colorant.RGB[2];
                Yb ->Values[cnt] = Clip(RGBprime.n[2]);

                cnt++;

            }
        }

        TransferCurves[0] = cmsxEstimateGamma(Xr, Yr, 1024);
        TransferCurves[1] = cmsxEstimateGamma(Xg, Yg, 1024);
        TransferCurves[2] = cmsxEstimateGamma(Xb, Yb, 1024);

        if (WhitePoint) {

            WhitePoint->X = PatchWhite->XYZ.X;
            WhitePoint->Y= PatchWhite ->XYZ.Y;
            WhitePoint->Z= PatchWhite ->XYZ.Z;
        }

        if (BlackPoint && PatchBlack) {

            BlackPoint->X = PatchBlack ->XYZ.X;
            BlackPoint->Y = PatchBlack ->XYZ.Y;
            BlackPoint->Z = PatchBlack ->XYZ.Z;
        }

        if (Primaries) {

            cmsXYZ2xyY(&Primaries->Red,   &PatchRed ->XYZ);
            cmsXYZ2xyY(&Primaries->Green, &PatchGreen ->XYZ);
            cmsXYZ2xyY(&Primaries->Blue,  &PatchBlue ->XYZ);

        }


        cmsFreeSampledCurve(Xr);
        cmsFreeSampledCurve(Yr);
        cmsFreeSampledCurve(Xg);
        cmsFreeSampledCurve(Yg);
        cmsFreeSampledCurve(Xb);
        cmsFreeSampledCurve(Yb);

        cmsxPCollFreeMeasurements(&Linearized);

        return true;
    }




    /* Compute prelinearization */
    cmsxComputeLinearizationTables(&Linearized, PT_XYZ, TransferCurves, 1024, Medium);

    /* Linearize measurements */
    cmsxPCollLinearizePatches(&Linearized, Linearized.Allowed, TransferCurves);


    /* Endpoints */
    ComputeWhiteAndBlackPoints(&Linearized, TransferCurves, &Black, &White);

    /* Primaries */
    ComputePrimary(&Linearized, TransferCurves, 0, &PrimarySet.Red);
    ComputePrimary(&Linearized, TransferCurves, 1, &PrimarySet.Green);
    ComputePrimary(&Linearized, TransferCurves, 2, &PrimarySet.Blue);


    if (BlackPoint) {
        *BlackPoint = Black;
        Div100(BlackPoint);
    }

    if (WhitePoint) {
        *WhitePoint = White;
        Div100(WhitePoint);
    }


    if (Primaries) {
        *Primaries = PrimarySet;
    }

    cmsxPCollFreeMeasurements(&Linearized);

    return true;
}