dng_xy_coord dng_color_spec::NeutralToXY (const dng_vector &neutral) { const uint32 kMaxPasses = 30; if (fChannels == 1) { return PCStoXY (); } dng_xy_coord last = D50_xy_coord (); for (uint32 pass = 0; pass < kMaxPasses; pass++) { dng_matrix xyzToCamera = FindXYZtoCamera (last); dng_xy_coord next = XYZtoXY (Invert (xyzToCamera) * neutral); if (Abs_real64 (next.x - last.x) + Abs_real64 (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; }
dng_xy_coord XYZtoXY (const dng_vector_3 &coord) { real64 X = coord [0]; real64 Y = coord [1]; real64 Z = coord [2]; real64 total = X + Y + Z; if (total > 0.0) { return dng_xy_coord (X / total, Y / total); } return D50_xy_coord (); }
dng_xy_coord PCStoXY () { return D50_xy_coord (); }