summaryrefslogtreecommitdiff
path: root/boost/gil/extension/toolbox/color_spaces/xyz.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/gil/extension/toolbox/color_spaces/xyz.hpp')
-rw-r--r--boost/gil/extension/toolbox/color_spaces/xyz.hpp157
1 files changed, 157 insertions, 0 deletions
diff --git a/boost/gil/extension/toolbox/color_spaces/xyz.hpp b/boost/gil/extension/toolbox/color_spaces/xyz.hpp
new file mode 100644
index 0000000000..a9973adf82
--- /dev/null
+++ b/boost/gil/extension/toolbox/color_spaces/xyz.hpp
@@ -0,0 +1,157 @@
+/*
+ Copyright 2012 Chung-Lin Wen, Davide Anastasia
+ Use, modification and distribution are subject to the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+*/
+
+/*************************************************************************************************/
+
+#ifndef BOOST_GIL_EXTENSION_TOOLBOX_COLOR_SPACES_XYZ_HPP
+#define BOOST_GIL_EXTENSION_TOOLBOX_COLOR_SPACES_XYZ_HPP
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file xyz.hpp
+/// \brief Support for CIE XYZ color space
+/// \author Chung-Lin Wen, Davide Anastasia \n
+///
+/// \date 2012 \n
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include <boost/gil/typedefs.hpp>
+
+namespace boost{ namespace gil {
+
+/// \addtogroup ColorNameModel
+/// \{
+namespace xyz_color_space
+{
+/// \brief x Color Component
+struct x_t {};
+/// \brief y Color Component
+struct y_t {};
+/// \brief z Color Component
+struct z_t {};
+}
+/// \}
+
+/// \ingroup ColorSpaceModel
+typedef mpl::vector3< xyz_color_space::x_t
+ , xyz_color_space::y_t
+ , xyz_color_space::z_t
+ > xyz_t;
+
+/// \ingroup LayoutModel
+typedef layout<xyz_t> xyz_layout_t;
+
+GIL_DEFINE_ALL_TYPEDEFS(32f, float32_t, xyz)
+
+/// \ingroup ColorConvert
+/// \brief RGB to XYZ
+/// <a href="http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html">Link</a>
+/// \note rgb_t is assumed to be sRGB D65
+template <>
+struct default_color_converter_impl< rgb_t, xyz_t >
+{
+private:
+ BOOST_FORCEINLINE
+ float32_t inverse_companding(float32_t sample) const
+ {
+ if ( sample > 0.04045f )
+ {
+ return powf((( sample + 0.055f ) / 1.055f ), 2.4f);
+ }
+ else
+ {
+ return ( sample / 12.92f );
+ }
+ }
+
+public:
+ template <typename P1, typename P2>
+ void operator()( const P1& src, P2& dst ) const
+ {
+ using namespace xyz_color_space;
+
+ float32_t red(
+ inverse_companding(
+ channel_convert<float32_t>(get_color(src, red_t()))));
+ float32_t green(
+ inverse_companding(
+ channel_convert<float32_t>(get_color(src, green_t()))));
+ float32_t blue(
+ inverse_companding(
+ channel_convert<float32_t>(get_color(src, blue_t()))));
+
+ get_color( dst, x_t() ) =
+ red * 0.4124564f +
+ green * 0.3575761f +
+ blue * 0.1804375f;
+ get_color( dst, y_t() ) =
+ red * 0.2126729f +
+ green * 0.7151522f +
+ blue * 0.0721750f;
+ get_color( dst, z_t() ) =
+ red * 0.0193339f +
+ green * 0.1191920f +
+ blue * 0.9503041f;
+ }
+};
+
+/// \ingroup ColorConvert
+/// \brief XYZ to RGB
+template <>
+struct default_color_converter_impl<xyz_t,rgb_t>
+{
+private:
+ BOOST_FORCEINLINE
+ float32_t companding(float32_t sample) const
+ {
+ if ( sample > 0.0031308f )
+ {
+ return ( 1.055f * powf( sample, 1.f/2.4f ) - 0.055f );
+ }
+ else
+ {
+ return ( 12.92f * sample );
+ }
+ }
+
+public:
+ template <typename P1, typename P2>
+ void operator()( const P1& src, P2& dst) const
+ {
+ using namespace xyz_color_space;
+
+ // Note: ideally channel_convert should be compiled out, because xyz_t
+ // is float32_t natively only
+ float32_t x( channel_convert<float32_t>( get_color( src, x_t() ) ) );
+ float32_t y( channel_convert<float32_t>( get_color( src, y_t() ) ) );
+ float32_t z( channel_convert<float32_t>( get_color( src, z_t() ) ) );
+
+ get_color(dst,red_t()) =
+ channel_convert<typename color_element_type<P2, red_t>::type>(
+ companding( x * 3.2404542f +
+ y * -1.5371385f +
+ z * -0.4985314f )
+ );
+ get_color(dst,green_t()) =
+ channel_convert<typename color_element_type<P2, green_t>::type>(
+ companding( x * -0.9692660f +
+ y * 1.8760108f +
+ z * 0.0415560f )
+ );
+ get_color(dst,blue_t()) =
+ channel_convert<typename color_element_type<P2, blue_t>::type>(
+ companding( x * 0.0556434f +
+ y * -0.2040259f +
+ z * 1.0572252f )
+ );
+ }
+};
+
+} // namespace gil
+} // namespace boost
+
+#endif // BOOST_GIL_EXTENSION_TOOLBOX_COLOR_SPACES_XYZ_HPP