TuttleOFX  1
gil_extensions.hpp
Go to the documentation of this file.
00001 /*
00002     Copyright 2010 Christian Henning, Andreas Pokorny, Lubomir Bourdev
00003     Use, modification and distribution are subject to the Boost Software License,
00004     Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
00005     http://www.boost.org/LICENSE_1_0.txt).
00006 */
00007 
00008 /*************************************************************************************************/
00009 
00010 #ifndef BOOST_GIL_EXTENSION_TOOLBOX_GIL_EXTENSIONS_HPP_INCLUDED
00011 #define BOOST_GIL_EXTENSION_TOOLBOX_GIL_EXTENSIONS_HPP_INCLUDED
00012 
00013 ////////////////////////////////////////////////////////////////////////////////////////
00014 /// \file
00015 /// \brief Definitions of is_bit_aligned, is_homogeneous, and is_similar metafunctions and
00016 ///        some other goodies.
00017 /// \author Christian Henning, Andreas Pokorny, Lubomir Bourdev \n
00018 ///
00019 /// \date   2008 \n
00020 ///
00021 ////////////////////////////////////////////////////////////////////////////////////////
00022 
00023 #include <boost/gil/gil_all.hpp>
00024 #include <boost/mpl/if.hpp>
00025 
00026 #include <boost/gil/extension/toolbox/dynamic_images.hpp>
00027 
00028 namespace boost { namespace gil {
00029 
00030 /// is_bit_aligned metafunctions
00031 /// \brief Determines whether the given type is bit_aligned.
00032 
00033 template< typename PixelRef >
00034 struct is_bit_aligned : mpl::false_{};
00035 
00036 template <typename B, typename C, typename L, bool M>  
00037 struct is_bit_aligned<bit_aligned_pixel_reference<B,C,L,M> > : mpl::true_{};
00038 
00039 template <typename B, typename C, typename L, bool M>  
00040 struct is_bit_aligned<const bit_aligned_pixel_reference<B,C,L,M> > : mpl::true_{};
00041 
00042 template <typename B, typename C, typename L>  
00043 struct is_bit_aligned<packed_pixel<B,C,L> > : mpl::true_{};
00044 
00045 template <typename B, typename C, typename L>  
00046 struct is_bit_aligned<const packed_pixel<B,C,L> > : mpl::true_{};
00047 
00048 
00049 /// is_similar metafunctions
00050 /// \brief Determines if two pixel types are similar.
00051 
00052 template< typename A, typename B >
00053 struct is_similar : mpl::false_ {};
00054 
00055 template<typename A>
00056 struct is_similar< A, A > : mpl::true_ {};
00057 
00058 template<typename B,int I, int S, bool M, int I2>
00059 struct is_similar< packed_channel_reference< B,  I, S, M >
00060                  , packed_channel_reference< B, I2, S, M >
00061                  > : mpl::true_ {};
00062 
00063 /// is_homogeneous metafunctions
00064 /// \brief Determines if a pixel types are homogeneous.
00065 
00066 template<typename C,typename CMP, int Next, int Last> struct is_homogeneous_impl;
00067 
00068 template<typename C,typename CMP, int Last>
00069 struct is_homogeneous_impl<C,CMP,Last,Last> : mpl::true_{};
00070 
00071 template<typename C,typename CMP, int Next, int Last>
00072 struct is_homogeneous_impl : mpl::and_< is_homogeneous_impl< C, CMP,Next + 1, Last >
00073                                       , is_same< CMP, typename mpl::at_c<C,Next>::type
00074                                       > > {};
00075 
00076 template < typename P > struct is_homogeneous : mpl::false_ {};
00077 
00078 // pixel
00079 template < typename C, typename L > struct is_homogeneous< pixel<C,L> > : mpl::true_ {};
00080 template < typename C, typename L > struct is_homogeneous<const pixel<C,L> > : mpl::true_ {};
00081 template < typename C, typename L > struct is_homogeneous< pixel<C,L>& > : mpl::true_ {};
00082 template < typename C, typename L > struct is_homogeneous<const pixel<C,L>& > : mpl::true_ {};
00083 
00084 // planar pixel reference
00085 template <typename Channel, typename ColorSpace>
00086 struct is_homogeneous< planar_pixel_reference< Channel, ColorSpace > > : mpl::true_ {};
00087 template <typename Channel, typename ColorSpace>
00088 struct is_homogeneous< const planar_pixel_reference< Channel, ColorSpace > > : mpl::true_ {};
00089 
00090 template<typename C,typename CMP, int I,int Last>
00091 struct is_homogeneous_impl_p {};
00092 
00093 // for packed_pixel
00094 template <typename B, typename C, typename L >
00095 struct is_homogeneous<packed_pixel< B, C, L > > 
00096         : is_homogeneous_impl_p< C 
00097                            , typename mpl::at_c< C, 0 >::type
00098                            , 1
00099                            , mpl::size< C >::type::value
00100                            > {};
00101 
00102 template< typename B
00103         , typename C
00104         , typename L
00105         >  
00106 struct is_homogeneous< const packed_pixel< B, C, L > > 
00107         : is_homogeneous_impl_p< C
00108                                , typename mpl::at_c<C,0>::type
00109                                , 1
00110                                , mpl::size< C >::type::value
00111                                > {};
00112 
00113 // for bit_aligned_pixel_reference
00114 template <typename B, typename C, typename L, bool M>  
00115 struct is_homogeneous<bit_aligned_pixel_reference<B,C,L,M> > 
00116         : is_homogeneous_impl<C,typename mpl::at_c<C,0>::type,1,mpl::size<C>::type::value>
00117 {};
00118 
00119 template <typename B, typename C, typename L, bool M>  
00120 struct is_homogeneous<const bit_aligned_pixel_reference<B,C,L,M> > 
00121         : is_homogeneous_impl<C,typename mpl::at_c<C,0>::type,1,mpl::size<C>::type::value>
00122 {};
00123 
00124 //////////////////////
00125 /// other goodies
00126 
00127 /// get_num_bits metafunctions
00128 /// \brief Determines the numbers of bits for the given channel type.
00129 
00130 template <typename T>
00131 struct get_num_bits;
00132 
00133 template< typename B, int I, int S, bool M >
00134 struct get_num_bits< packed_channel_reference< B, I, S, M > >
00135 {
00136     BOOST_STATIC_CONSTANT( int, value = S );
00137 };
00138 
00139 template<typename B,int I, int S, bool M>
00140 struct get_num_bits< const packed_channel_reference< B, I, S, M > >
00141 {
00142     BOOST_STATIC_CONSTANT( int, value = S );
00143 };
00144 
00145 
00146 /// channel_type metafunction
00147 /// \brief Generates the channel type for 
00148 
00149 
00150 template <typename B, typename C, typename L, bool M>  
00151 struct gen_chan_ref
00152 {
00153         typedef packed_dynamic_channel_reference< B
00154                                                 , mpl::at_c< C, 0 >::type::value
00155                                                 , M
00156                                                 > type;
00157 };
00158 
00159 
00160 //! This implementation works for bit_algined_pixel_reference 
00161 //! with a homogeneous channel layout. 
00162 //! The result type will be a packed_dynamic_channel_reference, since the 
00163 //! offset info will be missing. 
00164 
00165 // bit_aligned_pixel_reference
00166 template <typename B, typename C, typename L, bool M>  
00167 struct channel_type< bit_aligned_pixel_reference<B,C,L,M> > 
00168         : lazy_enable_if< is_homogeneous< bit_aligned_pixel_reference< B, C, L, M > >
00169                     , gen_chan_ref< B, C, L, M >
00170                             > {};
00171 
00172 template <typename B, typename C, typename L, bool M>  
00173 struct channel_type<const bit_aligned_pixel_reference<B,C,L,M> > 
00174         : lazy_enable_if< is_homogeneous< bit_aligned_pixel_reference< B, C, L, M > >
00175                         , gen_chan_ref< B, C, L, M >
00176                             > {};
00177 
00178 template <typename B, typename C, typename L>  
00179 struct gen_chan_ref_p
00180 {
00181         typedef packed_dynamic_channel_reference< B
00182                                                 , get_num_bits< typename mpl::at_c<C,0>::type>::value
00183                                                 , true
00184                                                 > type;
00185 };
00186 
00187 // packed_pixel
00188 template < typename BitField
00189          , typename ChannelRefVec
00190          , typename Layout
00191          >
00192 struct channel_type< packed_pixel< BitField
00193                                  , ChannelRefVec
00194                                  , Layout
00195                                  >
00196                    > : lazy_enable_if< is_homogeneous< packed_pixel< BitField
00197                                                                    , ChannelRefVec
00198                                                                    , Layout
00199                                                                    >
00200                                                      >
00201                                      , gen_chan_ref_p< BitField
00202                                                      , ChannelRefVec
00203                                                      , Layout
00204                                                      >
00205                                              > {};
00206 
00207 template <typename B, typename C, typename L>  
00208 struct channel_type< const packed_pixel< B, C, L > > 
00209         : lazy_enable_if< is_homogeneous<packed_pixel< B, C, L > >
00210                         , gen_chan_ref_p< B, C, L >
00211                             >
00212 {};
00213 
00214 template<>
00215 struct channel_type< any_image_pixel_t >
00216 {
00217     typedef any_image_channel_t type;
00218 };
00219 
00220 template<>
00221 struct color_space_type< any_image_pixel_t >
00222 {
00223     typedef any_image_color_space_t type;
00224 };
00225 
00226 /// get_pixel_type metafunction
00227 /// \brief Depending on Image this function generates either 
00228 ///        the pixel type or the reference type in case
00229 ///        the image is bit_aligned.
00230 template< typename View >
00231 struct get_pixel_type : mpl::if_< typename is_bit_aligned< typename View::value_type >::type
00232                                 , typename View::reference
00233                                 , typename View::value_type
00234                                 > {};
00235 
00236 template< typename ImageViewTypes >
00237 struct get_pixel_type< any_image_view< ImageViewTypes > >
00238 {
00239     typedef any_image_pixel_t type;
00240 };
00241 
00242 namespace detail {
00243 
00244 /// - performance specialization double
00245 /// - to eliminate compiler warning 4244
00246 template <typename GrayChannelValue>
00247 struct rgb_to_luminance_fn< double, double, double, GrayChannelValue >
00248 {
00249     GrayChannelValue operator()( const double& red
00250                                , const double& green
00251                                , const double& blue    ) const
00252    {
00253       return channel_convert<GrayChannelValue>( red * 0.30 + green * 0.59 + blue * 0.11 );
00254    }
00255 };
00256 
00257 } // namespace detail
00258 
00259 /// This one is missing in gil ( color_convert.hpp ).
00260 template <>
00261 struct default_color_converter_impl<gray_t,rgba_t>
00262 {
00263     template <typename P1, typename P2>
00264     void operator()(const P1& src, P2& dst) const
00265     {
00266         get_color(dst,red_t())  =
00267             channel_convert<typename color_element_type<P2, red_t  >::type>(get_color(src,gray_color_t()));
00268         get_color(dst,green_t())=
00269             channel_convert<typename color_element_type<P2, green_t>::type>(get_color(src,gray_color_t()));
00270         get_color(dst,blue_t()) =
00271             channel_convert<typename color_element_type<P2, blue_t >::type>(get_color(src,gray_color_t()));
00272 
00273         typedef typename channel_type< P2 >::type channel_t;
00274         get_color(dst,alpha_t()) = channel_traits< channel_t >::max_value();
00275     }
00276 };
00277 
00278 } // namespace gil
00279 } // namespace boost
00280 
00281 #endif // BOOST_GIL_EXTENSION_TOOLBOX_GIL_EXTENSIONS_HPP_INCLUDED