Esempio n. 1
0
        /// \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);
        }
Esempio n. 2
0
        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));
        }