00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef GIL_PLANAR_PTR_H
00010 #define GIL_PLANAR_PTR_H
00011
00020
00021 #include <cassert>
00022 #include <iterator>
00023 #include "gil_config.hpp"
00024
00025 ADOBE_GIL_NAMESPACE_BEGIN
00026
00027
00037
00040 template <typename IC, typename C> struct planar_ptr {};
00041
00042 namespace detail {template <typename T, typename C> struct color_base;}
00045 template <typename IC, typename C>
00046 struct planar_ptr_base : public boost::iterator_facade<planar_ptr<IC,C>,
00047 pixel<typename std::iterator_traits<IC>::value_type,C>,
00048 boost::random_access_traversal_tag,
00049 planar_ref<typename std::iterator_traits<IC>::reference,C> >,
00050 public detail::color_base<IC,C> {
00051 typedef boost::iterator_facade<planar_ptr<IC,C>,
00052 pixel<typename std::iterator_traits<IC>::value_type,C>,
00053 boost::random_access_traversal_tag,
00054 planar_ref<typename std::iterator_traits<IC>::reference,C> > parent_t;
00055 typedef std::random_access_iterator_tag iterator_category;
00056 typedef detail::color_base<IC,C> color_base_parent_t;
00057 typedef pixel<typename std::iterator_traits<IC>::value_type,C> pixel_t;
00058 typedef typename parent_t::reference reference;
00059 typedef typename parent_t::difference_type difference_type;
00060 typedef C color_space_t;
00061 typedef typename std::iterator_traits<IC>::value_type channel_t;
00062 static const int num_channels=color_space_t::num_channels;
00063
00064 planar_ptr_base() {}
00065
00066 planar_ptr_base(const IC& v0, const IC& v1, const IC& v2) : color_base_parent_t(v0,v1,v2) {}
00067 planar_ptr_base(const IC& v0, const IC& v1, const IC& v2, const IC& v3) : color_base_parent_t(v0,v1,v2,v3) {}
00068
00069 template <typename IC1,typename C1> planar_ptr_base(const planar_ptr_base<IC1,C1>& ptr) : color_base_parent_t(ptr) {}
00070
00073 reference operator[](difference_type d) const { return byte_advanced_ref(*this,d*sizeof(channel_t));}
00074
00075 IC& channel_ptr(std::size_t i) { return detail::nth_channel_accessor<C>()(*this,i); }
00076 const IC& channel_ptr(std::size_t i) const { return detail::nth_channel_accessor<C>()(*this,i); }
00077
00078 template <int N> IC& channel() { return detail::channel_accessor<C,N>()(*this);}
00079 template <int N> IC const& channel() const { return detail::channel_accessor<C,N>()(*this);}
00080 template <int N> IC& semantic_channel() { return detail::channel_accessor<typename C::base,N>()(*this);}
00081 template <int N> IC const& semantic_channel() const { return detail::channel_accessor<typename C::base,N>()(*this);}
00082
00083 reference operator->() const { return **this; }
00084
00085 bool operator< (const planar_ptr_base& ptr) const { return channel<0>()< ptr.channel<0>(); }
00086 bool operator!=(const planar_ptr_base& ptr) const { return channel<0>()!=ptr.channel<0>(); }
00087 private:
00088 friend class boost::iterator_core_access;
00089
00090 void increment() { transform_channels(*this,*this,adobe::inc<IC>()); }
00091 void decrement() { transform_channels(*this,*this,adobe::dec<IC>()); }
00092 void advance(ptrdiff_t d) { transform_channels(*this,*this,std::bind2nd(adobe::plus_asymmetric<IC,ptrdiff_t>(),d)); }
00093
00094 ptrdiff_t distance_to(const planar_ptr_base& it) const { return it.channel<0>()-channel<0>(); }
00095 bool equal(const planar_ptr_base& it) const { return channel<0>()==it.channel<0>(); }
00096 };
00097
00098
00099 ADOBE_GIL_NAMESPACE_END
00100
00101 #endif