File indexing completed on 2025-12-15 09:52:11
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_PLANAR_PIXEL_ITERATOR_HPP
0009 #define BOOST_GIL_PLANAR_PIXEL_ITERATOR_HPP
0010
0011 #include <boost/gil/pixel.hpp>
0012 #include <boost/gil/step_iterator.hpp>
0013 #include <boost/gil/detail/mp11.hpp>
0014
0015 #include <boost/iterator/iterator_facade.hpp>
0016
0017 #include <iterator>
0018 #include <type_traits>
0019
0020 namespace boost { namespace gil {
0021
0022
0023 template <typename ChannelReference, typename ColorSpace>
0024 struct planar_pixel_reference;
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 template <typename ChannelPtr, typename ColorSpace>
0043 struct planar_pixel_iterator
0044 :
0045 iterator_facade
0046 <
0047 planar_pixel_iterator<ChannelPtr, ColorSpace>,
0048 pixel<typename std::iterator_traits<ChannelPtr>::value_type,layout<ColorSpace>>,
0049 std::random_access_iterator_tag,
0050 planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference, ColorSpace> const
0051 >,
0052 detail::homogeneous_color_base
0053 <
0054 ChannelPtr,
0055 layout<ColorSpace>,
0056 mp11::mp_size<ColorSpace>::value
0057 >
0058 {
0059 private:
0060 using parent_t = iterator_facade
0061 <
0062 planar_pixel_iterator<ChannelPtr, ColorSpace>,
0063 pixel<typename std::iterator_traits<ChannelPtr>::value_type,layout<ColorSpace>>,
0064 std::random_access_iterator_tag,
0065 planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference, ColorSpace> const
0066 >;
0067
0068 using color_base_parent_t = detail::homogeneous_color_base
0069 <
0070 ChannelPtr,
0071 layout<ColorSpace>,
0072 mp11::mp_size<ColorSpace>::value
0073 >;
0074
0075 using channel_t = typename std::iterator_traits<ChannelPtr>::value_type;
0076
0077 public:
0078 using value_type = typename parent_t::value_type;
0079 using reference = typename parent_t::reference;
0080 using difference_type = typename parent_t::difference_type;
0081
0082 planar_pixel_iterator() : color_base_parent_t(0) {}
0083 planar_pixel_iterator(bool) {}
0084
0085 planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1) : color_base_parent_t(v0,v1) {}
0086 planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2) : color_base_parent_t(v0,v1,v2) {}
0087 planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2, const ChannelPtr& v3) : color_base_parent_t(v0,v1,v2,v3) {}
0088 planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2, const ChannelPtr& v3, const ChannelPtr& v4) : color_base_parent_t(v0,v1,v2,v3,v4) {}
0089
0090 template <typename IC1,typename C1>
0091 planar_pixel_iterator(const planar_pixel_iterator<IC1,C1>& ptr) : color_base_parent_t(ptr) {}
0092
0093
0094
0095
0096 template <typename P>
0097 planar_pixel_iterator(P* pix) : color_base_parent_t(pix, true) {
0098 function_requires<PixelsCompatibleConcept<P,value_type> >();
0099 }
0100
0101 struct address_of { template <typename T> T* operator()(T& t) { return &t; } };
0102 template <typename P>
0103 planar_pixel_iterator& operator=(P* pix) {
0104 function_requires<PixelsCompatibleConcept<P,value_type> >();
0105 static_transform(*pix,*this, address_of());
0106
0107
0108
0109
0110
0111 return *this;
0112 }
0113
0114
0115
0116 reference operator[](difference_type d) const { return memunit_advanced_ref(*this,d*sizeof(channel_t));}
0117
0118 reference operator->() const { return **this; }
0119
0120
0121 bool operator< (const planar_pixel_iterator& ptr) const { return gil::at_c<0>(*this)< gil::at_c<0>(ptr); }
0122 bool operator!=(const planar_pixel_iterator& ptr) const { return gil::at_c<0>(*this)!=gil::at_c<0>(ptr); }
0123 private:
0124 friend class boost::iterator_core_access;
0125
0126 void increment() { static_transform(*this,*this,detail::inc<ChannelPtr>()); }
0127 void decrement() { static_transform(*this,*this,detail::dec<ChannelPtr>()); }
0128 void advance(std::ptrdiff_t d){ static_transform(*this,*this,std::bind(detail::plus_asymmetric<ChannelPtr,std::ptrdiff_t>(),std::placeholders::_1,d)); }
0129 reference dereference() const { return this->template deref<reference>(); }
0130
0131 std::ptrdiff_t distance_to(const planar_pixel_iterator& it) const { return gil::at_c<0>(it)-gil::at_c<0>(*this); }
0132 bool equal(const planar_pixel_iterator& it) const { return gil::at_c<0>(*this)==gil::at_c<0>(it); }
0133 };
0134
0135 namespace detail {
0136 template <typename I>
0137 struct channel_iterator_is_mutable : std::true_type {};
0138
0139 template <typename I>
0140 struct channel_iterator_is_mutable<I const*> : std::false_type {};
0141
0142 }
0143
0144 template <typename IC, typename C>
0145 struct const_iterator_type<planar_pixel_iterator<IC,C> > {
0146 private:
0147 using channel_t = typename std::iterator_traits<IC>::value_type;
0148 public:
0149 using type = planar_pixel_iterator<typename channel_traits<channel_t>::const_pointer,C>;
0150 };
0151
0152
0153 template <typename IC, typename C>
0154 struct iterator_is_mutable<planar_pixel_iterator<IC,C> > : public detail::channel_iterator_is_mutable<IC> {};
0155
0156
0157
0158
0159
0160 template <typename IC, typename C, int K>
0161 struct kth_element_type<planar_pixel_iterator<IC, C>, K>
0162 {
0163 using type = IC;
0164 };
0165
0166 template <typename IC, typename C, int K>
0167 struct kth_element_reference_type<planar_pixel_iterator<IC, C>, K>
0168 : std::add_lvalue_reference<IC> {};
0169
0170 template <typename IC, typename C, int K>
0171 struct kth_element_const_reference_type<planar_pixel_iterator<IC, C>, K>
0172 : std::add_lvalue_reference<typename std::add_const<IC>::type>
0173 {};
0174
0175
0176
0177
0178
0179 template <typename IC, typename C>
0180 struct color_space_type<planar_pixel_iterator<IC,C>>
0181 {
0182 using type = C;
0183 };
0184
0185 template <typename IC, typename C>
0186 struct channel_mapping_type<planar_pixel_iterator<IC, C>>
0187 : channel_mapping_type<typename planar_pixel_iterator<IC,C>::value_type>
0188 {};
0189
0190 template <typename IC, typename C>
0191 struct is_planar<planar_pixel_iterator<IC, C>> : std::true_type {};
0192
0193 template <typename IC, typename C>
0194 struct channel_type<planar_pixel_iterator<IC, C>>
0195 {
0196 using type = typename std::iterator_traits<IC>::value_type;
0197 };
0198
0199
0200
0201
0202
0203 template <typename IC, typename C>
0204 inline auto memunit_step(planar_pixel_iterator<IC,C> const&)
0205 -> std::ptrdiff_t
0206 {
0207 return sizeof(typename std::iterator_traits<IC>::value_type);
0208 }
0209
0210 template <typename IC, typename C>
0211 inline auto memunit_distance(planar_pixel_iterator<IC,C> const& p1, planar_pixel_iterator<IC,C> const& p2)
0212 -> std::ptrdiff_t
0213 {
0214 return memunit_distance(gil::at_c<0>(p1),gil::at_c<0>(p2));
0215 }
0216
0217 template <typename IC>
0218 struct memunit_advance_fn {
0219 memunit_advance_fn(std::ptrdiff_t diff) : _diff(diff) {}
0220 IC operator()(const IC& p) const { return memunit_advanced(p,_diff); }
0221
0222 std::ptrdiff_t _diff;
0223 };
0224
0225 template <typename IC, typename C>
0226 inline void memunit_advance(planar_pixel_iterator<IC,C>& p, std::ptrdiff_t diff) {
0227 static_transform(p, p, memunit_advance_fn<IC>(diff));
0228 }
0229
0230 template <typename IC, typename C>
0231 inline auto memunit_advanced(planar_pixel_iterator<IC,C> const& p, std::ptrdiff_t diff)
0232 -> planar_pixel_iterator<IC,C>
0233 {
0234 planar_pixel_iterator<IC,C> ret=p;
0235 memunit_advance(ret, diff);
0236 return ret;
0237 }
0238
0239 template <typename ChannelPtr, typename ColorSpace>
0240 inline auto memunit_advanced_ref(planar_pixel_iterator<ChannelPtr,ColorSpace> const& ptr, std::ptrdiff_t diff)
0241 -> planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>
0242 {
0243 return planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>(ptr, diff);
0244 }
0245
0246
0247
0248
0249
0250 template <typename IC, typename C>
0251 struct dynamic_x_step_type<planar_pixel_iterator<IC,C> > {
0252 using type = memory_based_step_iterator<planar_pixel_iterator<IC,C>>;
0253 };
0254 } }
0255
0256 #endif