diff --git a/src/Magnum/Math/Color.h b/src/Magnum/Math/Color.h index 660259a0d..2feec3fb3 100644 --- a/src/Magnum/Math/Color.h +++ b/src/Magnum/Math/Color.h @@ -406,7 +406,7 @@ template class Color3: public Vector3 { * 0.0557 & -0.2040 & 1.0570 * \end{bmatrix} \begin{bmatrix} X \\ Y \\ Z \end{bmatrix} * @f] - * @see @ref toXyz(), @ref toSrgb() + * @see @ref toXyz(), @ref toSrgb(), @ref xyYToXyz() */ static Color3 fromXyz(const Vector3& xyz) { return Implementation::fromXyz(xyz); @@ -572,7 +572,7 @@ template class Color3: public Vector3 { * Please note that @ref x(), @ref y() and @ref z() *do not* correspond * to primaries in CIE XYZ color space, but are rather aliases to * @ref r(), @ref g() and @ref b(). - * @see @ref fromXyz(), @ref fromSrgb() + * @see @ref fromXyz(), @ref fromSrgb(), @ref xyzToXyY() */ Vector3 toXyz() const { return Implementation::toXyz(*this); @@ -786,7 +786,7 @@ class Color4: public Vector4 { * * Applies transformation matrix, returning the input in linear RGB * color space. See @ref Color3::fromXyz() for more information. - * @see @ref toXyz(), @ref toSrgbAlpha() + * @see @ref toXyz(), @ref toSrgbAlpha(), @ref xyYToXyz() */ static Color4 fromXyz(const Vector3 xyz, T a = Implementation::fullChannel()) { return {Implementation::fromXyz(xyz), a}; @@ -944,7 +944,7 @@ class Color4: public Vector4 { * Please note that @ref xyz(), @ref x(), @ref y() and @ref z() *do not* * correspond to primaries in CIE XYZ color space, but are rather * aliases to @ref rgb(), @ref r(), @ref g() and @ref b(). - * @see @ref fromXyz() + * @see @ref fromXyz(), @ref xyzToXyY() */ Vector3 toXyz() const { return Implementation::toXyz(rgb()); @@ -962,6 +962,36 @@ class Color4: public Vector4 { MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(4, Color4) }; +/** @relatesalso Color3 +@brief Convert color from CIE xyY representation to CIE XYZ + +@f[ + \begin{array}{rcl} + X & = & \dfrac{Y}{y}x \\ + Z & = & \dfrac{Y}{y}(1 - x - y) + \end{array} +@f] +@see @ref xyzToXyY(), @ref Color3::fromXyz(), @ref Color3::toXyz() +*/ +template inline Vector3 xyYToXyz(const Vector3& xyY) { + return {xyY[0]*xyY[2]/xyY[1], xyY[2], (T(1) - xyY[0] - xyY[1])*xyY[2]/xyY[1]}; +} + +/** @relatesalso Color3 +@brief Convert color from CIE XYZ representation to CIE xyY + +@f[ + \begin{array}{rcl} + x & = & \dfrac{X}{X + Y + Z} \\ + y & = & \dfrac{Y}{X + Y + Z} + \end{array} +@f] +@see @ref xyYToXyz(), @ref Color3::fromXyz(), @ref Color3::toXyz() +*/ +template inline Vector3 xyzToXyY(const Vector3& xyz) { + return {xyz.xy()/xyz.sum(), xyz.y()}; +} + #ifndef DOXYGEN_GENERATING_OUTPUT MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(4, Color4) #endif diff --git a/src/Magnum/Math/Test/ColorTest.cpp b/src/Magnum/Math/Test/ColorTest.cpp index 0268e2dd0..5813a6def 100644 --- a/src/Magnum/Math/Test/ColorTest.cpp +++ b/src/Magnum/Math/Test/ColorTest.cpp @@ -99,6 +99,7 @@ struct ColorTest: Corrade::TestSuite::Tester { void xyz(); void fromXyzDefaultAlpha(); + void xyY(); void swizzleType(); void debug(); @@ -150,6 +151,7 @@ ColorTest::ColorTest() { &ColorTest::xyz, &ColorTest::fromXyzDefaultAlpha, + &ColorTest::xyY, &ColorTest::swizzleType, &ColorTest::debug, @@ -749,6 +751,15 @@ void ColorTest::fromXyzDefaultAlpha() { (Math::Color4{52883, 22095, 339, 65535})); } +void ColorTest::xyY() { + /* Verified using http://www.easyrgb.com/index.php?X=CALC */ + Vector3 xyz{0.454279f, 0.413092f, 0.0607124f}; + Vector3 xyY{0.489481f, 0.445102f, 0.413092f}; + + CORRADE_COMPARE(xyzToXyY(xyz), xyY); + CORRADE_COMPARE(xyYToXyz(xyY), xyz); +} + void ColorTest::swizzleType() { constexpr Color3 origColor3; constexpr Color4ub origColor4;