Modules | Alphabetical List | Class List | Directories | File List | File Members | GIL Home Page # 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 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     typedef const bit_aligned_pixel_reference<ChannelBitSizeVector, Layout, true> bit_alignedref_t;
    00341 public:
    00342     typedef image<bit_alignedref_t,false,Alloc> type;
    00343 };
    00344
    00347 template <unsigned Size1, typename Layout, typename Alloc=std::allocator<unsigned char> >
    00348 struct bit_aligned_image1_type : public bit_aligned_image_type<mpl::vector1_c<unsigned, Size1>, Layout, Alloc> {};
    00349
    00352 template <unsigned Size1, unsigned Size2, typename Layout, typename Alloc=std::allocator<unsigned char> >
    00353 struct bit_aligned_image2_type : public bit_aligned_image_type<mpl::vector2_c<unsigned, Size1, Size2>, Layout, Alloc> {};
    00354
    00357 template <unsigned Size1, unsigned Size2, unsigned Size3, typename Layout, typename Alloc=std::allocator<unsigned char> >
    00358 struct bit_aligned_image3_type : public bit_aligned_image_type<mpl::vector3_c<unsigned, Size1, Size2, Size3>, Layout, Alloc> {};
    00359
    00362 template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, typename Layout, typename Alloc=std::allocator<unsigned char> >
    00363 struct bit_aligned_image4_type : public bit_aligned_image_type<mpl::vector4_c<unsigned, Size1, Size2, Size3, Size4>, Layout, Alloc> {};
    00364
    00367 template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, typename Layout, typename Alloc=std::allocator<unsigned char> >
    00368 struct bit_aligned_image5_type : public bit_aligned_image_type<mpl::vector5_c<unsigned, Size1, Size2, Size3, Size4, Size5>, Layout, Alloc> {};
    00369
    00370
    00371
    00374 template <typename Channel, typename Layout>
    00375 struct pixel_value_type {
    00376     typedef pixel<Channel,Layout> type;     // by default use gil::pixel. Specializations are provided for
    00377 };
    00378
    00379 // Specializations for packed channels
    00380 template <typename BitField, int NumBits, bool IsMutable, typename Layout>
    00381 struct pixel_value_type<      packed_dynamic_channel_reference<BitField,NumBits,IsMutable>,Layout> :
    00382     public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
    00383 template <typename BitField, int NumBits, bool IsMutable, typename Layout>
    00384 struct pixel_value_type<const packed_dynamic_channel_reference<BitField,NumBits,IsMutable>,Layout> :
    00385     public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
    00386
    00387 template <typename BitField, int FirstBit, int NumBits, bool IsMutable, typename Layout>
    00388 struct pixel_value_type<      packed_channel_reference<BitField,FirstBit,NumBits,IsMutable>,Layout> :
    00389     public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
    00390 template <typename BitField, int FirstBit, int NumBits, bool IsMutable, typename Layout>
    00391 struct pixel_value_type<const packed_channel_reference<BitField,FirstBit,NumBits,IsMutable>,Layout> :
    00392     public packed_pixel_type<BitField, mpl::vector1_c<unsigned,NumBits>, Layout> {};
    00393
    00394 template <int NumBits, typename Layout>
    00395 struct pixel_value_type<packed_channel_value<NumBits>,Layout> :
    00396     public packed_pixel_type<typename detail::min_fast_uint<NumBits>::type, mpl::vector1_c<unsigned,NumBits>, Layout> {};
    00397
    00398
    00401 template <typename T, typename L, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true>
    00402 struct locator_type {
    00403     typedef typename type_from_x_iterator<typename iterator_type<T,L,IsPlanar,IsStepX,IsMutable>::type>::xy_locator_type type;
    00404 };
    00405
    00408 template <typename T, typename L, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true>
    00409 struct view_type {
    00410     typedef typename type_from_x_iterator<typename iterator_type<T,L,IsPlanar,IsStepX,IsMutable>::type>::view_t type;
    00411 };
    00412
    00415 template <typename T, typename L, bool IsPlanar=false, typename Alloc=std::allocator<unsigned char> >
    00416 struct image_type {
    00417     typedef image<pixel<T,L>, IsPlanar, Alloc> type;
    00418 };
    00419
    00422 template <typename Pixel, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true>
    00423 struct view_type_from_pixel {
    00424     typedef typename type_from_x_iterator<typename iterator_type_from_pixel<Pixel,IsPlanar,IsStepX,IsMutable>::type>::view_t type;
    00425 };
    00426
    00427
    00431 template <typename Ref, typename T=use_default, typename L=use_default, typename IsPlanar=use_default, typename IsMutable=use_default>
    00432 class derived_pixel_reference_type {
    00433     typedef typename remove_reference<Ref>::type pixel_t;
    00434     typedef typename  mpl::if_<is_same<T, use_default>, typename channel_type<pixel_t>::type,     T >::type channel_t;
    00435     typedef typename  mpl::if_<is_same<L, use_default>,
    00436         layout<typename color_space_type<pixel_t>::type, typename channel_mapping_type<pixel_t>::type>, L>::type           layout_t;
    00437     static const bool mut   =mpl::if_<is_same<IsMutable,use_default>, pixel_reference_is_mutable<Ref>, IsMutable>::type::value;
    00438     static const bool planar=mpl::if_<is_same<IsPlanar,use_default>,  is_planar<pixel_t>,  IsPlanar>::type::value;
    00439 public:
    00440     typedef typename pixel_reference_type<channel_t, layout_t, planar, mut>::type type;
    00441 };
    00442
    00446 template <typename Iterator, typename T=use_default, typename L=use_default, typename IsPlanar=use_default, typename IsStep=use_default, typename IsMutable=use_default>
    00447 class derived_iterator_type {
    00448     typedef typename  mpl::if_<is_same<T ,use_default>, typename channel_type<Iterator>::type,     T >::type channel_t;
    00449     typedef typename  mpl::if_<is_same<L,use_default>,
    00450         layout<typename color_space_type<Iterator>::type, typename channel_mapping_type<Iterator>::type>, L>::type layout_t;
    00451
    00452     static const bool mut   =mpl::if_<is_same<IsMutable,use_default>, iterator_is_mutable<Iterator>, IsMutable>::type::value;
    00453     static const bool planar=mpl::if_<is_same<IsPlanar,use_default>,         is_planar<Iterator>,  IsPlanar>::type::value;
    00454     static const bool step  =mpl::if_<is_same<IsStep  ,use_default>,  iterator_is_step<Iterator>,    IsStep>::type::value;
    00455 public:
    00456     typedef typename iterator_type<channel_t, layout_t, planar, step, mut>::type type;
    00457 };
    00458
    00462 template <typename View, typename T=use_default, typename L=use_default, typename IsPlanar=use_default, typename StepX=use_default, typename IsMutable=use_default>
    00463 class derived_view_type {
    00464     typedef typename  mpl::if_<is_same<T ,use_default>, typename channel_type<View>::type, T>::type channel_t;
    00465     typedef typename  mpl::if_<is_same<L,use_default>,
    00466         layout<typename color_space_type<View>::type, typename channel_mapping_type<View>::type>, L>::type layout_t;
    00467     static const bool mut   =mpl::if_<is_same<IsMutable,use_default>, view_is_mutable<View>, IsMutable>::type::value;
    00468     static const bool planar=mpl::if_<is_same<IsPlanar,use_default>,  is_planar<View>,  IsPlanar>::type::value;
    00469     static const bool step  =mpl::if_<is_same<StepX ,use_default>,  view_is_step_in_x<View>,StepX>::type::value;
    00470 public:
    00471     typedef typename view_type<channel_t, layout_t, planar, step, mut>::type type;
    00472 };
    00473
    00477 template <typename Image, typename T=use_default, typename L=use_default, typename IsPlanar=use_default>
    00478 class derived_image_type {
    00479     typedef typename  mpl::if_<is_same<T ,use_default>, typename channel_type<Image>::type,     T >::type channel_t;
    00480     typedef typename  mpl::if_<is_same<L,use_default>,
    00481         layout<typename color_space_type<Image>::type, typename channel_mapping_type<Image>::type>, L>::type layout_t;
    00482     static const bool planar=mpl::if_<is_same<IsPlanar,use_default>,  is_planar<Image>,  IsPlanar>::type::value;
    00483 public:
    00484     typedef typename image_type<channel_t, layout_t, planar>::type type;
    00485 };
    00486
    00487
    00488
    00489
    00490 } }  // namespace boost::gil
    00491
    00492 #endif