Esempio n. 1
0
        /// Return the XY value to use for SetWhiteXY for a given camera color
        /// space coordinate as the white point.
        /// \param neutral A camera color space value to use for white point.
        /// Components range from 0.0 to 1.0 and should be normalized such that
        /// the largest value is 1.0 .
        /// \retval White point in XY space that makes neutral map to this
        /// XY value as closely as possible.
        public DNGxyCoord NeutralToXY(DNGVector neutral)
        {
            const uint kMaxPasses = 30;

            if (fChannels == 1)
            {
                return(DNGxyCoord.PCStoXY);
            }

            DNGxyCoord last = DNGxyCoord.D50;

            for (uint pass = 0; pass < kMaxPasses; pass++)
            {
                DNGMatrix nullMat     = null;
                DNGMatrix xyzToCamera = FindXYZtoCamera(last, ref nullMat, ref nullMat, ref nullMat);

                DNGMatrix  inv  = xyzToCamera.Invert();
                DNGVector  vec  = inv * neutral;
                DNGVector3 vec3 = new DNGVector3(vec);

                DNGxyCoord next = DNGxyCoord.XYZtoXY(new DNGVector3(xyzToCamera.Invert() * neutral));

                if (Math.Abs(next.X - last.X) +
                    Math.Abs(next.Y - last.Y) < 0.0000001)
                {
                    return(next);
                }

                // If we reach the limit without converging, we are most likely
                // in a two value oscillation.  So take the average of the last
                // two estimates and give up.
                if (pass == kMaxPasses - 1)
                {
                    next.X = (last.X + next.X) * 0.5;
                    next.Y = (last.Y + next.Y) * 0.5;
                }
                last = next;
            }
            return(last);
        }
        public DNGColorSpace(DNGMatrix3x3 toPCS)
        {
            // The matrix values are often rounded, so adjust to
            // get them to convert device white exactly to the PCS.
            DNGVector W1 = toPCS * new DNGVector3(1.0, 1.0, 1.0);
            DNGVector W2 = DNGxyCoord.PCStoXYZ;

            double s0 = W2[0] / W1[0];
            double s1 = W2[1] / W1[1];
            double s2 = W2[2] / W1[2];

            DNGMatrix3x3 S = new DNGMatrix3x3(s0, 0, 0,
                                              0, s1, 0,
                                              0, 0, s2);

            mToPCS = S * toPCS;

            // Find reverse matrix.
            mFromPCS = mToPCS.Invert();
        }