metafunctions.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003    
00004     Use, modification and distribution are subject to the Boost Software License,
00005     Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
00006     http://www.boost.org/LICENSE_1_0.txt).
00007 
00008     See http://opensource.adobe.com/gil for most recent version including documentation.
00009 */
00010 
00011 /*************************************************************************************************/
00012 
00013 #ifndef GIL_METAFUNCTIONS_HPP
00014 #define GIL_METAFUNCTIONS_HPP
00015 
00025 
00026 #include <iterator>
00027 #include <boost/mpl/accumulate.hpp>
00028 #include <boost/mpl/back.hpp>
00029 #include <boost/mpl/bool.hpp>
00030 #include <boost/mpl/if.hpp>
00031 #include <boost/mpl/pop_back.hpp>
00032 #include <boost/mpl/push_back.hpp>
00033 #include <boost/mpl/transform.hpp>
00034 #include <boost/mpl/vector.hpp>
00035 #include <boost/type_traits.hpp>
00036 #include "gil_config.hpp"
00037 #include "gil_concept.hpp"
00038 #include "channel.hpp"
00039 
00040 namespace boost { namespace gil {
00041 
00042 // forward declarations
00043 template <typename T, typename L> struct pixel;
00044 template <typename BitField,typename ChannelRefVec,typename Layout> struct packed_pixel;
00045 template <typename T, typename C> struct planar_pixel_reference;
00046 template <typename IC, typename C> struct planar_pixel_iterator;
00047 template <typename I> class memory_based_step_iterator;
00048 template <typename I> class memory_based_2d_locator;
00049 template <typename L> class image_view;
00050 template <typename Pixel, bool IsPlanar, typename Alloc> class image;
00051 template <typename T> struct channel_type;
00052 template <typename T> struct color_space_type;
00053 template <typename T> struct channel_mapping_type;
00054 template <typename It> struct is_iterator_adaptor;
00055 template <typename It> struct iterator_adaptor_get_base;
00056 template <typename BitField, typename ChannelBitSizes, typename Layout, bool IsMutable> struct bit_aligned_pixel_reference;
00057 
00064 
00065 
00072 
00076 template <typename PixelRef>        struct pixel_reference_is_basic                     : public mpl::false_ {};
00077 template <typename T,  typename L>  struct pixel_reference_is_basic<      pixel<T,L>&>  : public mpl::true_ {};
00078 template <typename T,  typename L>  struct pixel_reference_is_basic<const pixel<T,L>&>  : public mpl::true_ {};
00079 template <typename TR, typename Cs> struct pixel_reference_is_basic<planar_pixel_reference<TR,Cs> > : public mpl::true_ {};
00080 template <typename TR, typename Cs> struct pixel_reference_is_basic<const planar_pixel_reference<TR,Cs> > : public mpl::true_ {};
00081 
00082 
00086 template <typename Iterator>
00087 struct iterator_is_basic : public mpl::false_ {};
00088 template <typename T, typename L>  // mutable   interleaved
00089 struct iterator_is_basic<      pixel<T,L>*      > : public mpl::true_ {};
00090 template <typename T, typename L>  // immutable interleaved
00091 struct iterator_is_basic<const pixel<T,L>*      > : public mpl::true_ {};
00092 template <typename T, typename Cs>  // mutable   planar
00093 struct iterator_is_basic<planar_pixel_iterator<      T*,Cs> > : public mpl::true_ {};
00094 template <typename T, typename Cs>    // immutable planar
00095 struct iterator_is_basic<planar_pixel_iterator<const T*,Cs> > : public mpl::true_ {};
00096 template <typename T, typename L>  // mutable   interleaved step
00097 struct iterator_is_basic<memory_based_step_iterator<      pixel<T,L>*> > : public mpl::true_ {};
00098 template <typename T, typename L>  // immutable interleaved step
00099 struct iterator_is_basic<memory_based_step_iterator<const pixel<T,L>*> > : public mpl::true_ {};
00100 template <typename T, typename Cs>  // mutable   planar step
00101 struct iterator_is_basic<memory_based_step_iterator<planar_pixel_iterator<      T*,Cs> > > : public mpl::true_ {};
00102 template <typename T, typename Cs>    // immutable planar step
00103 struct iterator_is_basic<memory_based_step_iterator<planar_pixel_iterator<const T*,Cs> > > : public mpl::true_ {};
00104 
00105 
00108 template <typename Loc> struct locator_is_basic : public mpl::false_ {};
00109 template <typename Iterator> struct locator_is_basic<memory_based_2d_locator<memory_based_step_iterator<Iterator> > > : public iterator_is_basic<Iterator> {};
00110 
00113 template <typename View> struct view_is_basic : public mpl::false_ {};
00114 template <typename Loc> struct view_is_basic<image_view<Loc> > : public locator_is_basic<Loc> {};
00115 
00118 template <typename Img> struct image_is_basic : public mpl::false_ {};
00119 template <typename Pixel, bool IsPlanar, typename Alloc> struct image_is_basic<image<Pixel,IsPlanar,Alloc> > : public mpl::true_ {};
00120 
00121 
00125 
00126 template <typename I> struct iterator_is_step;
00127 namespace detail {
00128     template <typename It, bool IsBase, bool EqualsStepType> struct iterator_is_step_impl;
00129     // iterator that has the same type as its dynamic_x_step_type must be a step iterator
00130     template <typename It, bool IsBase> struct iterator_is_step_impl<It,IsBase,true> : public mpl::true_{};
00131 
00132     // base iterator can never be a step iterator
00133     template <typename It> struct iterator_is_step_impl<It,true,false> : public mpl::false_{};
00134 
00135     // for an iterator adaptor, see if its base is step
00136     template <typename It> struct iterator_is_step_impl<It,false,false> 
00137         : public iterator_is_step<typename iterator_adaptor_get_base<It>::type>{};
00138 }
00139 
00142 template <typename I> struct iterator_is_step 
00143     : public detail::iterator_is_step_impl<I, 
00144         !is_iterator_adaptor<I>::type::value,
00145         is_same<I,typename dynamic_x_step_type<I>::type>::value >{};
00146 
00149 template <typename L> struct locator_is_step_in_x : public iterator_is_step<typename L::x_iterator> {}; 
00150 
00153 template <typename L> struct locator_is_step_in_y : public iterator_is_step<typename L::y_iterator> {}; 
00154 
00157 template <typename V> struct view_is_step_in_x : public locator_is_step_in_x<typename V::xy_locator> {}; 
00158 
00161 template <typename V> struct view_is_step_in_y : public locator_is_step_in_y<typename V::xy_locator> {}; 
00162 
00165 template <typename PixelReference>
00166 struct pixel_reference_is_proxy
00167     : public mpl::not_<is_same<typename remove_const_and_reference<PixelReference>::type,
00168                                typename remove_const_and_reference<PixelReference>::type::value_type> > {};
00169 
00172 template <typename Pixel>
00173 struct pixel_is_reference : public mpl::or_<is_reference<Pixel>, pixel_reference_is_proxy<Pixel> > {};
00174 
00178 
00183 template <typename R> struct pixel_reference_is_mutable : public mpl::bool_<remove_reference<R>::type::is_mutable> {};
00184 template <typename R> struct pixel_reference_is_mutable<const R&>
00185     : public mpl::and_<pixel_reference_is_proxy<R>, pixel_reference_is_mutable<R> > {};
00186 
00189 template <typename L> struct locator_is_mutable : public iterator_is_mutable<typename L::x_iterator> {};
00192 template <typename V> struct view_is_mutable : public iterator_is_mutable<typename V::x_iterator> {};
00193 
00194 
00201 
00205 
00209 
00213 
00216 template <typename T, typename L, bool IsPlanar=false, bool IsMutable=true> struct pixel_reference_type{};
00217 template <typename T, typename L> struct pixel_reference_type<T,L,false,true > { typedef pixel<T,L>& type; };
00218 template <typename T, typename L> struct pixel_reference_type<T,L,false,false> { typedef const pixel<T,L>& type; };
00219 template <typename T, typename L> struct pixel_reference_type<T,L,true,true> { typedef const planar_pixel_reference<typename channel_traits<T>::reference,typename color_space_type<L>::type> type; };       // TODO: Assert M=identity
00220 template <typename T, typename L> struct pixel_reference_type<T,L,true,false> { typedef const planar_pixel_reference<typename channel_traits<T>::const_reference,typename color_space_type<L>::type> type; };// TODO: Assert M=identity
00221 
00224 template <typename Pixel, bool IsPlanar=false, bool IsStep=false, bool IsMutable=true> struct iterator_type_from_pixel{};
00225 template <typename Pixel> struct iterator_type_from_pixel<Pixel,false,false,true > { typedef Pixel* type; };
00226 template <typename Pixel> struct iterator_type_from_pixel<Pixel,false,false,false> { typedef const Pixel* type; };
00227 template <typename Pixel> struct iterator_type_from_pixel<Pixel,true,false,true> { 
00228     typedef planar_pixel_iterator<typename channel_traits<typename channel_type<Pixel>::type>::pointer,typename color_space_type<Pixel>::type> type; 
00229 };
00230 template <typename Pixel> struct iterator_type_from_pixel<Pixel,true,false,false> { 
00231     typedef planar_pixel_iterator<typename channel_traits<typename channel_type<Pixel>::type>::const_pointer,typename color_space_type<Pixel>::type> type; 
00232 };
00233 template <typename Pixel, bool IsPlanar, bool IsMutable> struct iterator_type_from_pixel<Pixel,IsPlanar,true,IsMutable> { 
00234     typedef memory_based_step_iterator<typename iterator_type_from_pixel<Pixel,IsPlanar,false,IsMutable>::type> type; 
00235 };
00236 
00239 template <typename T, typename L, bool IsPlanar=false, bool IsStep=false, bool IsMutable=true> struct iterator_type{};
00240 template <typename T, typename L> struct iterator_type<T,L,false,false,true > { typedef pixel<T,L>* type; };
00241 template <typename T, typename L> struct iterator_type<T,L,false,false,false> { typedef const pixel<T,L>* type; };
00242 template <typename T, typename L> struct iterator_type<T,L,true,false,true> { typedef planar_pixel_iterator<T*,typename L::color_space_t> type; };               // TODO: Assert M=identity
00243 template <typename T, typename L> struct iterator_type<T,L,true,false,false> { typedef planar_pixel_iterator<const T*,typename L::color_space_t> type; };        // TODO: Assert M=identity
00244 template <typename T, typename L, bool IsPlanar, bool IsMutable> struct iterator_type<T,L,IsPlanar,true,IsMutable> { 
00245     typedef memory_based_step_iterator<typename iterator_type<T,L,IsPlanar,false,IsMutable>::type> type; 
00246 };
00247 
00250 template <typename XIterator> 
00251 struct type_from_x_iterator {
00252     typedef memory_based_step_iterator<XIterator>    step_iterator_t;
00253     typedef memory_based_2d_locator<step_iterator_t> xy_locator_t;
00254     typedef image_view<xy_locator_t>                     view_t;
00255 };
00256 
00257 namespace detail {
00258     template <typename BitField, typename FirstBit, typename NumBits>
00259     struct packed_channel_reference_type {
00260         typedef const packed_channel_reference<BitField,FirstBit::value,NumBits::value,true> type;
00261     };
00262 
00263     template <typename BitField, typename ChannelBitSizesVector>
00264     class packed_channel_references_vector_type {
00265         // If ChannelBitSizesVector is mpl::vector<int,7,7,2>
00266         // Then first_bits_vector will be mpl::vector<int,0,7,14,16>
00267         typedef typename mpl::accumulate<ChannelBitSizesVector, mpl::vector1<mpl::int_<0> >, 
00268             mpl::push_back<mpl::_1, mpl::plus<mpl::back<mpl::_1>, mpl::_2> > >::type first_bits_vector;
00269     public:
00270         typedef typename mpl::transform<typename mpl::pop_back<first_bits_vector>::type, ChannelBitSizesVector,
00271                packed_channel_reference_type<BitField, mpl::_1,mpl::_2> >::type type;
00272     };
00273 
00274 }
00275 
00284 template <typename BitField, typename ChannelBitSizeVector, typename Layout>
00285 struct packed_pixel_type {
00286     typedef packed_pixel<BitField, typename detail::packed_channel_references_vector_type<BitField,ChannelBitSizeVector>::type, Layout> type;
00287 };
00288 
00297 
00300 template <typename BitField, typename ChannelBitSizeVector, typename Layout, typename Alloc=std::allocator<unsigned char> >
00301 struct packed_image_type {
00302     typedef image<typename packed_pixel_type<BitField,ChannelBitSizeVector,Layout>::type,false,Alloc> type;
00303 };
00304 
00307 template <typename BitField, unsigned Size1, typename Layout, typename Alloc=std::allocator<unsigned char> >
00308 struct packed_image1_type : public packed_image_type<BitField, mpl::vector1_c<unsigned, Size1>, Layout, Alloc> {};
00309 
00312 template <typename BitField, unsigned Size1, unsigned Size2, typename Layout, typename Alloc=std::allocator<unsigned char> >
00313 struct packed_image2_type : public packed_image_type<BitField, mpl::vector2_c<unsigned, Size1, Size2>, Layout, Alloc> {};
00314 
00317 template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, typename Layout, typename Alloc=std::allocator<unsigned char> >
00318 struct packed_image3_type : public packed_image_type<BitField, mpl::vector3_c<unsigned, Size1, Size2, Size3>, Layout, Alloc> {};
00319 
00322 template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, typename Layout, typename Alloc=std::allocator<unsigned char> >
00323 struct packed_image4_type : public packed_image_type<BitField, mpl::vector4_c<unsigned, Size1, Size2, Size3, Size4>, Layout, Alloc> {};
00324 
00327 template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, typename Layout, typename Alloc=std::allocator<unsigned char> >
00328 struct packed_image5_type : public packed_image_type<BitField, mpl::vector5_c<unsigned, Size1, Size2, Size3, Size4, Size5>, Layout, Alloc> {};
00329 
00330 
00336 
00337 template <typename ChannelBitSizeVector, typename Layout, typename Alloc=std::allocator<unsigned char> >
00338 struct bit_aligned_image_type {
00339 private:
00340     BOOST_STATIC_CONSTANT(int, bit_size = (mpl::accumulate<ChannelBitSizeVector, mpl::int_<0>, mpl::plus<mpl::_1, mpl::_2> >::type::value));
00341     typedef typename detail::min_fast_uint<bit_size+7>::type                        bitfield_t;  
00342     typedef const bit_aligned_pixel_reference<bitfield_t, ChannelBitSizeVector, Layout, true> bit_alignedref_t;
00343 public:
00344     typedef image<bit_alignedref_t,false,Alloc> type;
00345 };
00346 
00349 template <unsigned Size1, typename Layout, typename Alloc=std::allocator<unsigned char> >
00350 struct bit_aligned_image1_type : public bit_aligned_image_type<mpl::vector1_c<unsigned, Size1>, Layout, Alloc> {};
00351 
00354 template <unsigned Size1, unsigned Size2, typename Layout, typename Alloc=std::allocator<unsigned char> >
00355 struct bit_aligned_image2_type : public bit_aligned_image_type<mpl::vector2_c<unsigned, Size1, Size2>, Layout, Alloc> {};
00356 
00359 template <unsigned Size1, unsigned Size2, unsigned Size3, typename Layout, typename Alloc=std::allocator<unsigned char> >
00360 struct bit_aligned_image3_type : public bit_aligned_image_type<mpl::vector3_c<unsigned, Size1, Size2, Size3>, Layout, Alloc> {};
00361 
00364 template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, typename Layout, typename Alloc=std::allocator<unsigned char> >
00365 struct bit_aligned_image4_type : public bit_aligned_image_type<mpl::vector4_c<unsigned, Size1, Size2, Size3, Size4>, Layout, Alloc> {};
00366 
00369 template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, typename Layout, typename Alloc=std::allocator<unsigned char> >
00370 struct bit_aligned_image5_type : public bit_aligned_image_type<mpl::vector5_c<unsigned, Size1, Size2, Size3, Size4, Size5>, Layout, Alloc> {};
00371 
00372 
00373 
00376 template <typename Channel, typename Layout> 
00377 struct pixel_value_type {
00378     typedef pixel<Channel,Layout> type;     // by default use gil::pixel. Specializations are provided for 
00379 };
00380 
00381 // Specializations for packed channels
00382 template <typename BitField, int NumBits, bool IsMutable, typename Layout> 
00383 struct pixel_value_type<      packed_dynamic_channel_reference<BitField,NumBits,IsMutable>,Layout> :
00384     public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
00385 template <typename BitField, int NumBits, bool IsMutable, typename Layout> 
00386 struct pixel_value_type<const packed_dynamic_channel_reference<BitField,NumBits,IsMutable>,Layout> :
00387     public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
00388 
00389 template <typename BitField, int FirstBit, int NumBits, bool IsMutable, typename Layout> 
00390 struct pixel_value_type<      packed_channel_reference<BitField,FirstBit,NumBits,IsMutable>,Layout> :
00391     public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
00392 template <typename BitField, int FirstBit, int NumBits, bool IsMutable, typename Layout> 
00393 struct pixel_value_type<const packed_channel_reference<BitField,FirstBit,NumBits,IsMutable>,Layout> :
00394     public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
00395 
00396 template <int NumBits, typename Layout> 
00397 struct pixel_value_type<packed_channel_value<NumBits>,Layout> :
00398     public packed_pixel_type<typename detail::min_fast_uint<NumBits>::type, mpl::vector1_c<unsigned,NumBits>, Layout> {};
00399 
00400 
00403 template <typename T, typename L, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true> 
00404 struct locator_type {
00405     typedef typename type_from_x_iterator<typename iterator_type<T,L,IsPlanar,IsStepX,IsMutable>::type>::xy_locator_type type;
00406 };
00407 
00410 template <typename T, typename L, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true> 
00411 struct view_type {
00412     typedef typename type_from_x_iterator<typename iterator_type<T,L,IsPlanar,IsStepX,IsMutable>::type>::view_t type;
00413 };
00414 
00417 template <typename T, typename L, bool IsPlanar=false, typename Alloc=std::allocator<unsigned char> > 
00418 struct image_type {
00419     typedef image<pixel<T,L>, IsPlanar, Alloc> type;
00420 };
00421 
00424 template <typename Pixel, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true> 
00425 struct view_type_from_pixel {
00426     typedef typename type_from_x_iterator<typename iterator_type_from_pixel<Pixel,IsPlanar,IsStepX,IsMutable>::type>::view_t type;
00427 };
00428 
00429 
00433 template <typename Ref, typename T=use_default, typename L=use_default, typename IsPlanar=use_default, typename IsMutable=use_default>
00434 class derived_pixel_reference_type {
00435     typedef typename remove_reference<Ref>::type pixel_t;
00436     typedef typename  mpl::if_<is_same<T, use_default>, typename channel_type<pixel_t>::type,     T >::type channel_t;
00437     typedef typename  mpl::if_<is_same<L, use_default>, 
00438         layout<typename color_space_type<pixel_t>::type, typename channel_mapping_type<pixel_t>::type>, L>::type           layout_t;
00439     static const bool mut   =mpl::if_<is_same<IsMutable,use_default>, pixel_reference_is_mutable<Ref>, IsMutable>::type::value;
00440     static const bool planar=mpl::if_<is_same<IsPlanar,use_default>,  is_planar<pixel_t>,  IsPlanar>::type::value;
00441 public:
00442     typedef typename pixel_reference_type<channel_t, layout_t, planar, mut>::type type;
00443 };
00444 
00448 template <typename Iterator, typename T=use_default, typename L=use_default, typename IsPlanar=use_default, typename IsStep=use_default, typename IsMutable=use_default>
00449 class derived_iterator_type {
00450     typedef typename  mpl::if_<is_same<T ,use_default>, typename channel_type<Iterator>::type,     T >::type channel_t;
00451     typedef typename  mpl::if_<is_same<L,use_default>, 
00452         layout<typename color_space_type<Iterator>::type, typename channel_mapping_type<Iterator>::type>, L>::type layout_t;
00453 
00454     static const bool mut   =mpl::if_<is_same<IsMutable,use_default>, iterator_is_mutable<Iterator>, IsMutable>::type::value;
00455     static const bool planar=mpl::if_<is_same<IsPlanar,use_default>,         is_planar<Iterator>,  IsPlanar>::type::value;
00456     static const bool step  =mpl::if_<is_same<IsStep  ,use_default>,  iterator_is_step<Iterator>,    IsStep>::type::value;
00457 public:
00458     typedef typename iterator_type<channel_t, layout_t, planar, step, mut>::type type;
00459 };
00460 
00464 template <typename View, typename T=use_default, typename L=use_default, typename IsPlanar=use_default, typename StepX=use_default, typename IsMutable=use_default>
00465 class derived_view_type {
00466     typedef typename  mpl::if_<is_same<T ,use_default>, typename channel_type<View>::type, T>::type channel_t;
00467     typedef typename  mpl::if_<is_same<L,use_default>, 
00468         layout<typename color_space_type<View>::type, typename channel_mapping_type<View>::type>, L>::type layout_t;
00469     static const bool mut   =mpl::if_<is_same<IsMutable,use_default>, view_is_mutable<View>, IsMutable>::type::value;
00470     static const bool planar=mpl::if_<is_same<IsPlanar,use_default>,  is_planar<View>,  IsPlanar>::type::value;
00471     static const bool step  =mpl::if_<is_same<StepX ,use_default>,  view_is_step_in_x<View>,StepX>::type::value;
00472 public:
00473     typedef typename view_type<channel_t, layout_t, planar, step, mut>::type type;
00474 };
00475 
00479 template <typename Image, typename T=use_default, typename L=use_default, typename IsPlanar=use_default>
00480 class derived_image_type {
00481     typedef typename  mpl::if_<is_same<T ,use_default>, typename channel_type<Image>::type,     T >::type channel_t;
00482     typedef typename  mpl::if_<is_same<L,use_default>, 
00483         layout<typename color_space_type<Image>::type, typename channel_mapping_type<Image>::type>, L>::type layout_t;
00484     static const bool planar=mpl::if_<is_same<IsPlanar,use_default>,  is_planar<Image>,  IsPlanar>::type::value;
00485 public:
00486     typedef typename image_type<channel_t, layout_t, planar>::type type;
00487 };
00488 
00489 
00490 
00491 
00492 } }  // namespace boost::gil
00493 
00494 #endif

Generated on Sat May 2 13:50:14 2009 for Generic Image Library by  doxygen 1.5.6