diff --git a/src/color/ucs.hpp b/src/color/ucs.hpp new file mode 100644 index 0000000..5fbeb5b --- /dev/null +++ b/src/color/ucs.hpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_COLOR_UCS_HPP +#define ANTKEEPER_COLOR_UCS_HPP + +#include "math/math.hpp" + +namespace color { + +/// Functions which operate in the CIE 1960 UCS colorspace. +namespace ucs { + +/** + * Transforms a CIE 1960 UCS color into the CIE xyY colorspace. + * + * @param uv CIE 1960 UCS color coordinates. + * @param luminance Luminance or `Y` value of the resulting xyY color. + * @return CIE xyY color. + */ +template +math::vector3 to_xyy(const math::vector2& uv, T luminance); + +template +math::vector3 to_xyy(const math::vector2& uv, T luminance); +{ + const T inverse_denom = 1.0 / (2.0 * uv[0] - 8.0 * uv[1] + 4.0); + + return math::vector3 + { + (3.0 * uv[0]) * inverse_denom, + (2.0 * uv[1]) * inverse_denom, + luminance + }; +} + +} // namespace ucs +} // namespace color + +#endif // ANTKEEPER_COLOR_UCS_HPP diff --git a/src/color/xyy.hpp b/src/color/xyy.hpp new file mode 100644 index 0000000..a133df6 --- /dev/null +++ b/src/color/xyy.hpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_COLOR_XYY_HPP +#define ANTKEEPER_COLOR_XYY_HPP + +#include "math/math.hpp" + +namespace color { + +/// Functions which operate in the CIE xyY colorspace. +namespace xyy { + +/** + * Returns the luminance of a CIE xyY color. + * + * @param x CIE xyY color. + * @return return Luminance of @p x. + */ +template +T luminance(const math::vector3& x); + +/** + * Transforms a CIE xyY color into the CIE 1960 UCS colorspace. + * + * @param x CIE xyY color. + * @return CIE 1960 UCS color. + */ +template +math::vector2 to_ucs(const math::vector3& x); + +/** + * Transforms a CIE xyY color into the CIE XYZ colorspace. + * + * @param x CIE xyY color. + * @return CIE XYZ color. + */ +template +math::vector3 to_xyz(const math::vector3& x); + +template +inline T luminance(const math::vector3& x) +{ + return x[2]; +} + +template +math::vector2 to_ucs(const math::vector3& x) +{ + const T inverse_denom = 1.0 / (-2.0 * x[0] + 12.0 * x[1] + 3.0); + + return math::vector2 + { + (4.0 * x[0]) * inverse_denom, + (6.0 * x[1]) * inverse_denom + }; +} + +template +math::vector3 to_xyz(const math::vector3& x) +{ + return math::vector3 + { + (x[0] * x[2]) / x[1], + x[2], + ((1.0 - x[0] - x[1]) * x[2]) / x[1] + }; +} + +} // namespace xyy +} // namespace color + +#endif // ANTKEEPER_COLOR_XYY_HPP diff --git a/src/color/xyz.hpp b/src/color/xyz.hpp index 1c79531..6d4350f 100644 --- a/src/color/xyz.hpp +++ b/src/color/xyz.hpp @@ -54,6 +54,15 @@ math::vector3 to_acescg(const math::vector3& x); template math::vector3 to_srgb(const math::vector3& x); +/** + * Transforms a CIE XYZ color into the CIE xyY colorspace. + * + * @param x CIE XYZ color. + * @return CIE xyY color. + */ +template +math::vector3 to_xyy(const math::vector3& x); + template inline T luminance(const math::vector3& x) { @@ -86,6 +95,19 @@ math::vector3 to_srgb(const math::vector3& x) return xyz_to_srgb * x; } +template +math::vector3 to_xyy(const math::vector3& x) +{ + const T sum = x[0] + x[1] + x[2]; + + return math::vector3 + { + x[0] / sum + x[1] / sum, + x[1] + }; +} + } // namespace xyz } // namespace color