/// \brief Compute a 3x3 matrix which maps colors from white point white1 to /// white point white2 /// /// Uses linearized Bradford adaptation matrix to compute a mapping from /// colors measured with one white point (white1) to another (white2). public static DNGMatrix3x3 MapWhiteMatrix(DNGxyCoord white1, DNGxyCoord white2) { // Use the linearized Bradford adaptation matrix. DNGMatrix3x3 Mb = new DNGMatrix3x3(0.8951, 0.2664, -0.1614, -0.7502, 1.7135, 0.0367, 0.0389, -0.0685, 1.0296); DNGVector w1 = Mb * white1.XYtoXYZ(); DNGVector w2 = Mb * white2.XYtoXYZ(); // Negative white coordinates are kind of meaningless. w1[0] = Math.Max(w1[0], 0.0); w1[1] = Math.Max(w1[1], 0.0); w1[2] = Math.Max(w1[2], 0.0); w2[0] = Math.Max(w2[0], 0.0); w2[1] = Math.Max(w2[1], 0.0); w2[2] = Math.Max(w2[2], 0.0); // Limit scaling to something reasonable. DNGMatrix3x3 A = new DNGMatrix3x3(); A[0, 0] = DNGUtils.Pin(0.1, w1[0] > 0.0 ? w2[0] / w1[0] : 10.0, 10.0); A[1, 1] = DNGUtils.Pin(0.1, w1[1] > 0.0 ? w2[1] / w1[1] : 10.0, 10.0); A[2, 2] = DNGUtils.Pin(0.1, w1[2] > 0.0 ? w2[2] / w1[2] : 10.0, 10.0); DNGMatrix3x3 B = new DNGMatrix3x3(Mb.Invert() * A * Mb); return(B); }
public DNGVector3 XYtoXYZ() { DNGxyCoord temp = new DNGxyCoord(this); // Restrict xy coord to someplace inside the range of real xy coordinates. // This prevents math from doing strange things when users specify // extreme temperature/tint coordinates. temp.x = DNGUtils.Pin(0.000001, temp.x, 0.999999); temp.y = DNGUtils.Pin(0.000001, temp.y, 0.999999); if (temp.x + temp.y > 0.999999) { double scale = 0.999999 / (temp.x + temp.y); temp.x *= scale; temp.y *= scale; } return(new DNGVector3(temp.x / temp.y, 1.0, (1.0 - temp.x - temp.y) / temp.y)); }