TuttleOFX
1
|
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