Boost logo

Boost-Commit :

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


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk