/* Copyright 2008 Christian Henning, Andreas Pokorny, Lubomir Bourdev 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_IO_DETAIL_GIL_EXTENSIONS_HPP_INCLUDED #define BOOST_GIL_EXTENSION_IO_DETAIL_GIL_EXTENSIONS_HPP_INCLUDED //////////////////////////////////////////////////////////////////////////////////////// /// \file /// \brief Definitions of is_bit_aligned, is_homogeneous, and is_similar metafunctions and /// some other goodies. /// \author Christian Henning, Andreas Pokorny, Lubomir Bourdev \n /// /// \date 2008 \n /// //////////////////////////////////////////////////////////////////////////////////////// #include #include #include "dynamic_io_new.hpp" namespace boost { namespace gil { /// is_bit_aligned metafunctions /// \brief Determines whether the given type is bit_aligned. template< typename PixelRef > struct is_bit_aligned : mpl::false_{}; template struct is_bit_aligned > : mpl::true_{}; template struct is_bit_aligned > : mpl::true_{}; template struct is_bit_aligned > : mpl::true_{}; template struct is_bit_aligned > : mpl::true_{}; /// is_similar metafunctions /// \brief Determines if two pixel types are similar. template< typename A, typename B > struct is_similar : mpl::false_ {}; template struct is_similar< A, A > : mpl::true_ {}; template struct is_similar< packed_channel_reference< B, I, S, M > , packed_channel_reference< B, I2, S, M > > : mpl::true_ {}; /// is_homogeneous metafunctions /// \brief Determines if a pixel types are homogeneous. template struct is_homogeneous_impl; template struct is_homogeneous_impl : mpl::true_{}; template struct is_homogeneous_impl : mpl::and_< is_homogeneous_impl< C, CMP,Next + 1, Last > , is_same< CMP, typename mpl::at_c::type > > {}; template < typename P > struct is_homogeneous : mpl::false_ {}; // pixel template < typename C, typename L > struct is_homogeneous< pixel > : mpl::true_ {}; template < typename C, typename L > struct is_homogeneous > : mpl::true_ {}; template < typename C, typename L > struct is_homogeneous< pixel& > : mpl::true_ {}; template < typename C, typename L > struct is_homogeneous& > : mpl::true_ {}; // planar pixel reference template struct is_homogeneous< planar_pixel_reference< Channel, ColorSpace > > : mpl::true_ {}; template struct is_homogeneous< const planar_pixel_reference< Channel, ColorSpace > > : mpl::true_ {}; template struct is_homogeneous_impl_p {}; // for packed_pixel template struct is_homogeneous > : is_homogeneous_impl_p< C , typename mpl::at_c< C, 0 >::type , 1 , mpl::size< C >::type::value > {}; template< typename B , typename C , typename L > struct is_homogeneous< const packed_pixel< B, C, L > > : is_homogeneous_impl_p< C , typename mpl::at_c::type , 1 , mpl::size< C >::type::value > {}; // for bit_aligned_pixel_reference template struct is_homogeneous > : is_homogeneous_impl::type,1,mpl::size::type::value> {}; template struct is_homogeneous > : is_homogeneous_impl::type,1,mpl::size::type::value> {}; ////////////////////// /// other goodies /// get_num_bits metafunctions /// \brief Determines the numbers of bits for the given channel type. template struct get_num_bits; template< typename B, int I, int S, bool M > struct get_num_bits< packed_channel_reference< B, I, S, M > > { BOOST_STATIC_CONSTANT( int, value = S ); }; template struct get_num_bits< const packed_channel_reference< B, I, S, M > > { BOOST_STATIC_CONSTANT( int, value = S ); }; /// channel_type metafunction /// \brief Generates the channel type for template struct gen_chan_ref { typedef packed_dynamic_channel_reference< B , mpl::at_c< C, 0 >::type::value , M > type; }; //! This implementation works for bit_algined_pixel_reference //! with a homegeneous channel layout. //! The result type will be a packed_dynamic_channel_reference, since the //! offset info will be missing. // bit_aligned_pixel_reference template struct channel_type< bit_aligned_pixel_reference > : lazy_enable_if< is_homogeneous< bit_aligned_pixel_reference< B, C, L, M > > , gen_chan_ref< B, C, L, M > > {}; template struct channel_type > : lazy_enable_if< is_homogeneous< bit_aligned_pixel_reference< B, C, L, M > > , gen_chan_ref< B, C, L, M > > {}; template struct gen_chan_ref_p { typedef packed_dynamic_channel_reference< B , get_num_bits< typename mpl::at_c::type>::value , true > type; }; // packed_pixel template < typename BitField , typename ChannelRefVec , typename Layout > struct channel_type< packed_pixel< BitField , ChannelRefVec , Layout > > : lazy_enable_if< is_homogeneous< packed_pixel< BitField , ChannelRefVec , Layout > > , gen_chan_ref_p< BitField , ChannelRefVec , Layout > > {}; template struct channel_type< const packed_pixel< B, C, L > > : lazy_enable_if< is_homogeneous > , gen_chan_ref_p< B, C, L > > {}; template<> struct channel_type< any_image_pixel_t > { typedef any_image_channel_t type; }; template<> struct color_space_type< any_image_pixel_t > { typedef any_image_color_space_t type; }; /// get_pixel_type metafunction /// \brief Depending on Image this function generates either /// the pixel type or the reference type in case /// the image is bit_aligned. template< typename View > struct get_pixel_type : mpl::if_< typename is_bit_aligned< typename View::value_type >::type , typename View::reference , typename View::value_type > {}; template< typename ImageViewTypes > struct get_pixel_type< any_image_view< ImageViewTypes > > { typedef any_image_pixel_t type; }; namespace detail { /// - performance specialization double /// - to eliminate compiler warning 4244 template struct rgb_to_luminance_fn< double, double, double, GrayChannelValue > { GrayChannelValue operator()( const double& red , const double& green , const double& blue ) const { return channel_convert( red * 0.30 + green * 0.59 + blue * 0.11 ); } }; } // namespace detail /// This one is missing in gil ( color_convert.hpp ). template <> struct default_color_converter_impl { template void operator()(const P1& src, P2& dst) const { get_color(dst,red_t()) = channel_convert::type>(get_color(src,gray_color_t())); get_color(dst,green_t())= channel_convert::type>(get_color(src,gray_color_t())); get_color(dst,blue_t()) = channel_convert::type>(get_color(src,gray_color_t())); typedef typename channel_type< P2 >::type channel_t; get_color(dst,alpha_t()) = channel_traits< channel_t >::max_value(); } }; } // namespace gil } // namespace boost #endif // BOOST_GIL_EXTENSION_IO_DETAIL_GIL_EXTENSIONS_HPP_INCLUDED