Example #1
0
// Approximate a blackbody illuminant based on CHAD information
static
cmsFloat64Number CHAD2Temp(const cmsMAT3* Chad)
{
    // Convert D50 across inverse CHAD to get the absolute white point
    cmsVEC3 d, s;
    cmsCIEXYZ Dest;
    cmsCIExyY DestChromaticity;
    cmsFloat64Number TempK;
    cmsMAT3 m1, m2;

    m1 = *Chad;
    if (!_cmsMAT3inverse(&m1, &m2)) return FALSE;

    s.n[VX] = cmsD50_XYZ() -> X;
    s.n[VY] = cmsD50_XYZ() -> Y;
    s.n[VZ] = cmsD50_XYZ() -> Z;

    _cmsMAT3eval(&d, &m2, &s);

    Dest.X = d.n[VX];
    Dest.Y = d.n[VY];
    Dest.Z = d.n[VZ];

    cmsXYZ2xyY(&DestChromaticity, &Dest);

    if (!cmsTempFromWhitePoint(&TempK, &DestChromaticity))
        return -1.0;

    return TempK;
}
Example #2
0
// Solve a system in the form Ax = b
cmsBool  CMSEXPORT _cmsMAT3solve(cmsVEC3* x, cmsMAT3* a, cmsVEC3* b)
{
    cmsMAT3 m, a_1;

    memmove(&m, a, sizeof(cmsMAT3));

    if (!_cmsMAT3inverse(&m, &a_1)) return FALSE;  // Singular matrix

    _cmsMAT3eval(x, &a_1, b);
    return TRUE;
}
Example #3
0
static
cmsBool ComputeChromaticAdaptation(cmsMAT3* Conversion,
                                const cmsCIEXYZ* SourceWhitePoint,
                                const cmsCIEXYZ* DestWhitePoint,
                                const cmsMAT3* Chad)

{

    cmsMAT3 Chad_Inv;
    cmsVEC3 ConeSourceXYZ, ConeSourceRGB;
    cmsVEC3 ConeDestXYZ, ConeDestRGB;
    cmsMAT3 Cone, Tmp;


    Tmp = *Chad;
    if (!_cmsMAT3inverse(&Tmp, &Chad_Inv)) return FALSE;

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

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

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

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


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

    return TRUE;
}
Example #4
0
// Build a White point, primary chromas transfer matrix from RGB to CIE XYZ
// This is just an approximation, I am not handling all the non-linear
// aspects of the RGB to XYZ process, and assumming that the gamma correction
// has transitive property in the transformation chain.
//
// the alghoritm:
//
//            - First I build the absolute conversion matrix using
//              primaries in XYZ. This matrix is next inverted
//            - Then I eval the source white point across this matrix
//              obtaining the coeficients of the transformation
//            - Then, I apply these coeficients to the original matrix
//
cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePt, const cmsCIExyYTRIPLE* Primrs)
{
    cmsVEC3 WhitePoint, Coef;
    cmsMAT3 Result, Primaries;
    cmsFloat64Number xn, yn;
    cmsFloat64Number xr, yr;
    cmsFloat64Number xg, yg;
    cmsFloat64Number 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
    _cmsVEC3init(&Primaries.v[0], xr,        xg,         xb);
    _cmsVEC3init(&Primaries.v[1], yr,        yg,         yb);
    _cmsVEC3init(&Primaries.v[2], (1-xr-yr), (1-xg-yg),  (1-xb-yb));


    // Result = Primaries ^ (-1) inverse matrix
    if (!_cmsMAT3inverse(&Primaries, &Result))
        return FALSE;


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

    // Across inverse primaries ...
    _cmsMAT3eval(&Coef, &Result, &WhitePoint);

    // Give us the Coefs, then I build transformation matrix
    _cmsVEC3init(&r -> v[0], Coef.n[VX]*xr,          Coef.n[VY]*xg,          Coef.n[VZ]*xb);
    _cmsVEC3init(&r -> v[1], Coef.n[VX]*yr,          Coef.n[VY]*yg,          Coef.n[VZ]*yb);
    _cmsVEC3init(&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 _cmsAdaptMatrixToD50(r, WhitePt);

}
Example #5
0
// Adapts a color to a given illuminant. Original color is expected to have
// a SourceWhitePt white point.
cmsBool CMSEXPORT cmsAdaptToIlluminant(cmsCIEXYZ* Result,
                                       const cmsCIEXYZ* SourceWhitePt,
                                       const cmsCIEXYZ* Illuminant,
                                       const cmsCIEXYZ* Value)
{
    cmsMAT3 Bradford;
    cmsVEC3 In, Out;

    _cmsAssert(Result != NULL);
    _cmsAssert(SourceWhitePt != NULL);
    _cmsAssert(Illuminant != NULL);
    _cmsAssert(Value != NULL);

    if (!_cmsAdaptationMatrix(&Bradford, NULL, SourceWhitePt, Illuminant)) return FALSE;

    _cmsVEC3init(&In, Value -> X, Value -> Y, Value -> Z);
    _cmsMAT3eval(&Out, &Bradford, &In);

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

    return TRUE;
}