mirror of
https://github.com/boostorg/gil.git
synced 2026-02-18 14:12:10 +00:00
* Added integer optimization for bit8 channels.
* fixed compiler error [SVN r83605]
This commit is contained in:
committed by
Stefan Seefeld
parent
5a3313d048
commit
b844bc1f85
@@ -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 @@ struct cr_t {};
|
||||
/// \}
|
||||
|
||||
/// \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 @@ GIL_DEFINE_ALL_TYPEDEFS(8, ycbcr)
|
||||
* @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 @@ struct default_color_converter_impl<ycbcr_t, rgb_t>
|
||||
, 0.0
|
||||
, 255.0
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -99,7 +150,7 @@ struct default_color_converter_impl<ycbcr_t, rgb_t>
|
||||
* @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 @@ struct default_color_converter_impl<rgb_t, ycbcr_t>
|
||||
|
||||
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
|
||||
|
||||
@@ -69,13 +69,13 @@ struct subsampled_image_deref_fn
|
||||
/// 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 );
|
||||
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 )
|
||||
return value_type( at_c<0>( *y )
|
||||
, at_c<0>( *v )
|
||||
, at_c<0>( *u )
|
||||
);
|
||||
}
|
||||
|
||||
@@ -212,7 +212,9 @@ public:
|
||||
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 @@ private:
|
||||
, 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 @@ void fill_pixels( const subsampled_image_view< Locator >& view
|
||||
/// \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
|
||||
|
||||
Reference in New Issue
Block a user