$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r83605 - in trunk/boost/gil/extension/toolbox: color_spaces image_types
From: chhenning_at_[hidden]
Date: 2013-03-27 14:55:33
Author: chhenning
Date: 2013-03-27 14:55:31 EDT (Wed, 27 Mar 2013)
New Revision: 83605
URL: http://svn.boost.org/trac/boost/changeset/83605
Log:
* Added integer optimization for bit8 channels.
* fixed compiler error
Text files modified: 
   trunk/boost/gil/extension/toolbox/color_spaces/ycbcr.hpp           |    66 ++++++++++++++++--                      
   trunk/boost/gil/extension/toolbox/image_types/subsampled_image.hpp |   139 ++++++++++++++++++++------------------- 
   2 files changed, 128 insertions(+), 77 deletions(-)
Modified: trunk/boost/gil/extension/toolbox/color_spaces/ycbcr.hpp
==============================================================================
--- trunk/boost/gil/extension/toolbox/color_spaces/ycbcr.hpp	(original)
+++ trunk/boost/gil/extension/toolbox/color_spaces/ycbcr.hpp	2013-03-27 14:55:31 EDT (Wed, 27 Mar 2013)
@@ -25,6 +25,8 @@
 #include <boost/mpl/vector_c.hpp>
 #include <boost/gil/gil_all.hpp>
 
+#include <boost/gil/extension/toolbox/metafunctions/get_num_bits.hpp>
+
 namespace boost{ namespace gil {
 
 /// \addtogroup ColorNameModel
@@ -41,13 +43,13 @@
 /// \}
 
 /// \ingroup ColorSpaceModel
-typedef boost::mpl::vector3<ycbcr_color_space::y_t, ycbcr_color_space::cb_t, ycbcr_color_space::cr_t> ycbcr_t;
+typedef boost::mpl::vector3<ycbcr_color_space::y_t, ycbcr_color_space::cb_t, ycbcr_color_space::cr_t> ycbcr_601__t;
 
 /// \ingroup LayoutModel
-typedef boost::gil::layout<ycbcr_t> ycbcr_layout_t;
+typedef boost::gil::layout<ycbcr_601__t> ycbcr_601__layout_t;
 
 //The channel depth is ALWAYS 8bits ofr YCbCr!
-GIL_DEFINE_ALL_TYPEDEFS(8,  ycbcr)
+GIL_DEFINE_ALL_TYPEDEFS(8,  ycbcr_601_)
 
 /*
  * Source: http://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion
@@ -58,12 +60,61 @@
 * @brief Convert YCbCr ITU.BT-601 to RGB.
 */
 template<>
-struct default_color_converter_impl<ycbcr_t, rgb_t>
+struct default_color_converter_impl<ycbcr_601__t, rgb_t>
 {
         // Note: the RGB_t channels range can be set later on by the users. We dont want to cast to bits8 or anything here.
         template < typename SRCP, typename DSTP >
         void operator()( const SRCP& src, DSTP& dst ) const
         {
+        typedef channel_type< DSTP >::type dst_channel_t;
+        convert( src, dst
+               , boost::is_same< mpl::int_<8>::type, mpl::int_<8>::type >::type()
+               );
+	}
+
+private:
+
+    // optimization for bit8 channels
+    template< typename Src_Pixel
+            , typename Dst_Pixel
+            >
+    void convert( const Src_Pixel& src
+                ,       Dst_Pixel& dst
+                , mpl::true_ // is 8 bit channel
+                ) const
+    {
+		using namespace boost::algorithm;
+        using namespace boost::gil::ycbcr_color_space;
+
+        typedef channel_type< Src_Pixel >::type src_channel_t;
+        typedef channel_type< Dst_Pixel >::type dst_channel_t;
+
+		src_channel_t y  = channel_convert<src_channel_t>( get_color(src,  y_t()));
+		src_channel_t cb = channel_convert<src_channel_t>( get_color(src, cb_t()));
+		src_channel_t cr = channel_convert<src_channel_t>( get_color(src, cr_t()));
+
+		// The intermediate results of the formulas require at least 16bits of precission.
+		boost::int_fast16_t c = y  - 16;
+		boost::int_fast16_t d = cb - 128;
+		boost::int_fast16_t e = cr - 128;
+		boost::int_fast16_t red   = clamp((( 298 * c + 409 * e + 128) >> 8), 0, 255);
+		boost::int_fast16_t green = clamp((( 298 * c - 100 * d - 208 * e + 128) >> 8), 0, 255);
+		boost::int_fast16_t blue  = clamp((( 298 * c + 516 * d + 128) >> 8), 0, 255);
+
+		get_color( dst,  red_t() )  = (dst_channel_t) red;
+		get_color( dst, green_t() ) = (dst_channel_t) green;
+		get_color( dst,  blue_t() ) = (dst_channel_t) blue;
+    }
+
+
+    template< typename Src_Pixel
+            , typename Dst_Pixel
+            >
+    void convert( const Src_Pixel& s
+                ,       Dst_Pixel& d
+                , mpl::false_ // is 8 bit channel
+                ) const
+    {
         using namespace boost::algorithm;
         using namespace boost::gil::ycbcr_color_space;
 
@@ -87,7 +138,7 @@
                                                          , 0.0
                                                          , 255.0
                                                          );
-	}
+    }
 };
 
 /*
@@ -99,7 +150,7 @@
 * @brief Convert RGB to YCbCr ITU.BT-601.
 */
 template<>
-struct default_color_converter_impl<rgb_t, ycbcr_t>
+struct default_color_converter_impl<rgb_t, ycbcr_601__t>
 {
         template < typename SRCP, typename DSTP >
         void operator()( const SRCP& src, DSTP& dst ) const
@@ -120,12 +171,11 @@
 
                 get_color( dst,  y_t() ) = (dst_channel_t)  y;
                 get_color( dst, cb_t() ) = (dst_channel_t) cb;
-		get_color( dst, cr_t() ) = (dst_channel_t) cr;
+		get_color( dst, cr_t() ) = (dst_channel_t) cr;  
         }
 };
 
 } // namespace gil
-
 } // namespace boost
 
 #endif
Modified: trunk/boost/gil/extension/toolbox/image_types/subsampled_image.hpp
==============================================================================
--- trunk/boost/gil/extension/toolbox/image_types/subsampled_image.hpp	(original)
+++ trunk/boost/gil/extension/toolbox/image_types/subsampled_image.hpp	2013-03-27 14:55:31 EDT (Wed, 27 Mar 2013)
@@ -69,13 +69,13 @@
     /// operator()
     typename result_type operator()( const point_t& p ) const
     {
-        auto y = *_y_locator.xy_at( p );
-        auto v = *_v_locator.xy_at( p.x / _ux_ssfactor, p.y / _uy_ssfactor );
-        auto u = *_u_locator.xy_at( p.x / _vx_ssfactor, p.y / _vy_ssfactor );
-
-        return value_type( at_c<0>( y )
-                         , at_c<0>( v )
-                         , at_c<0>( u )
+        plane_locator_t y = _y_locator.xy_at( p );
+        plane_locator_t v = _v_locator.xy_at( p.x / _ux_ssfactor, p.y / _uy_ssfactor );
+        plane_locator_t u = _u_locator.xy_at( p.x / _vx_ssfactor, p.y / _vy_ssfactor );
+
+        return value_type( at_c<0>( *y )
+                         , at_c<0>( *v )
+                         , at_c<0>( *u )
                          );
     }
 
@@ -212,7 +212,9 @@
     typedef typename plane_view_t::locator plane_locator_t;
 
     typedef typename view_type_from_pixel< Pixel >::type pixel_view_t;
-    typedef typename subsampled_image_locator< typename pixel_view_t::locator >::type locator_t;
+    typedef typename pixel_view_t::locator pixel_locator_t;
+
+    typedef typename subsampled_image_locator< pixel_locator_t >::type locator_t;
 
     typedef typename plane_image_t::coord_t x_coord_t;
     typedef typename plane_image_t::coord_t y_coord_t;
@@ -254,7 +256,7 @@
              , const std::size_t uy_ssfactor
              )
     {
-        typedef subsampled_image_deref_fn< locator_t > defer_fn_t;
+        typedef subsampled_image_deref_fn< pixel_locator_t > defer_fn_t;
 
         defer_fn_t deref_fn( view( _y_plane ).xy_at( 0, 0 )
                            , view( _v_plane ).xy_at( 0, 0 )
@@ -328,67 +330,66 @@
 /// \ingroup ImageViewConstructors
 /// \brief Creates a subsampled view from a raw memory
 /////////////////////////////////////////////////////////////////////////////////////////
-//template< typename Pixel >
-//typename subsampled_image< Pixel >::view_t subsampled_view( std::size_t    y_width
-//                                                          , std::size_t    y_height
-//                                                          , unsigned char* y_base
-//                                                          , std::size_t    vx_ssfactor = 2
-//                                                          , std::size_t    vy_ssfactor = 2
-//                                                          , std::size_t    ux_ssfactor = 2
-//                                                          , std::size_t    uy_ssfactor = 2
-//                                                          )
-//{
-//    std::size_t y_channel_size = 1;
-//    std::size_t u_channel_size = 1;
-//
-//    unsigned char* u_base = y_base + ( y_width  * y_height * y_channel_size );
-//    unsigned char* v_base = u_base + ( y_width / ux_ssfactor ) * ( y_height / uy_ssfactor ) * u_channel_size;
-//
-//    typedef subsampled_image< Pixel >::plane_view_t plane_view_t;
-//
-//    plane_view_t y_plane = interleaved_view( y_width
-//                                           , y_height
-//                                           , (plane_view_t::value_type*) y_base // pixels
-//                                           , y_width                            // rowsize_in_bytes
-//                                           );
-//
-//    plane_view_t v_plane = interleaved_view( y_width  / vx_ssfactor 
-//                                           , y_height / vy_ssfactor
-//                                           , (plane_view_t::value_type*) v_base // pixels
-//                                           , y_width                            // rowsize_in_bytes
-//                                           );
-//
-//    plane_view_t u_plane = interleaved_view( y_width  / ux_ssfactor
-//                                           , y_height / uy_ssfactor
-//                                           , (plane_view_t::value_type*) u_base // pixels
-//                                           , y_width                            // rowsize_in_bytes
-//                                           );
-//
-//    typedef subsampled_image_deref_fn< subsampled_image< Pixel >::locator_t > defer_fn_t;
-//    defer_fn_t deref_fn( y_plane.xy_at( 0, 0 )
-//                       , v_plane.xy_at( 0, 0 )
-//                       , u_plane.xy_at( 0, 0 )
-//                       , vx_ssfactor
-//                       , vy_ssfactor
-//                       , ux_ssfactor
-//                       , uy_ssfactor
-//                       );
-//    
-//
-//    typedef subsampled_image< Pixel >::locator_t locator_t;
-//    locator_t locator( point_t( 0, 0 ) // p
-//                     , point_t( 1, 1 ) // step
-//                     , deref_fn
-//                     );
-//
-//    typedef subsampled_image< Pixel >::view_t view_t;
-//    return view_t( point_t(               y_width,               y_height )
-//                 , point_t( y_width / vx_ssfactor, y_height / vy_ssfactor )
-//                 , point_t( y_width / ux_ssfactor, y_height / uy_ssfactor )
-//                 , locator
-//                 );
-//}
+template< typename Pixel >
+typename subsampled_image< Pixel >::view_t subsampled_view( std::size_t    y_width
+                                                          , std::size_t    y_height
+                                                          , unsigned char* y_base
+                                                          , std::size_t    vx_ssfactor = 2
+                                                          , std::size_t    vy_ssfactor = 2
+                                                          , std::size_t    ux_ssfactor = 2
+                                                          , std::size_t    uy_ssfactor = 2
+                                                          )
+{
+    std::size_t y_channel_size = 1;
+    std::size_t u_channel_size = 1;
+
+    unsigned char* u_base = y_base + ( y_width  * y_height * y_channel_size );
+    unsigned char* v_base = u_base + ( y_width / ux_ssfactor ) * ( y_height / uy_ssfactor ) * u_channel_size;
 
+    typedef subsampled_image< Pixel >::plane_view_t plane_view_t;
+
+    plane_view_t y_plane = interleaved_view( y_width
+                                           , y_height
+                                           , (plane_view_t::value_type*) y_base // pixels
+                                           , y_width                            // rowsize_in_bytes
+                                           );
+
+    plane_view_t v_plane = interleaved_view( y_width  / vx_ssfactor 
+                                           , y_height / vy_ssfactor
+                                           , (plane_view_t::value_type*) v_base // pixels
+                                           , y_width                            // rowsize_in_bytes
+                                           );
+
+    plane_view_t u_plane = interleaved_view( y_width  / ux_ssfactor
+                                           , y_height / uy_ssfactor
+                                           , (plane_view_t::value_type*) u_base // pixels
+                                           , y_width                            // rowsize_in_bytes
+                                           );
+
+    typedef subsampled_image_deref_fn< typename subsampled_image< Pixel >::pixel_locator_t > defer_fn_t;
+    defer_fn_t deref_fn( y_plane.xy_at( 0, 0 )
+                       , v_plane.xy_at( 0, 0 )
+                       , u_plane.xy_at( 0, 0 )
+                       , vx_ssfactor
+                       , vy_ssfactor
+                       , ux_ssfactor
+                       , uy_ssfactor
+                       );
+    
+
+    typedef subsampled_image< Pixel >::locator_t locator_t;
+    locator_t locator( point_t( 0, 0 ) // p
+                     , point_t( 1, 1 ) // step
+                     , deref_fn
+                     );
+
+    typedef subsampled_image< Pixel >::view_t view_t;
+    return view_t( point_t(               y_width,               y_height )
+                 , point_t( y_width / vx_ssfactor, y_height / vy_ssfactor )
+                 , point_t( y_width / ux_ssfactor, y_height / uy_ssfactor )
+                 , locator
+                 );
+}
 
 } // namespace gil
 } // namespace boost