File indexing completed on 2024-11-15 09:12:37
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_BIT_ALIGNED_PIXEL_ITERATOR_HPP
0009 #define BOOST_GIL_BIT_ALIGNED_PIXEL_ITERATOR_HPP
0010
0011 #include <boost/gil/bit_aligned_pixel_reference.hpp>
0012 #include <boost/gil/pixel_iterator.hpp>
0013
0014 #include <boost/config.hpp>
0015 #include <boost/iterator/iterator_facade.hpp>
0016
0017 #include <functional>
0018 #include <type_traits>
0019
0020 namespace boost { namespace gil {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 template <typename NonAlignedPixelReference>
0037 struct bit_aligned_pixel_iterator : public iterator_facade<bit_aligned_pixel_iterator<NonAlignedPixelReference>,
0038 typename NonAlignedPixelReference::value_type,
0039 std::random_access_iterator_tag,
0040 const NonAlignedPixelReference,
0041 typename NonAlignedPixelReference::bit_range_t::difference_type> {
0042 private:
0043 using parent_t = iterator_facade<bit_aligned_pixel_iterator<NonAlignedPixelReference>,
0044 typename NonAlignedPixelReference::value_type,
0045 std::random_access_iterator_tag,
0046 const NonAlignedPixelReference,
0047 typename NonAlignedPixelReference::bit_range_t::difference_type>;
0048 template <typename Ref> friend struct bit_aligned_pixel_iterator;
0049
0050 using bit_range_t = typename NonAlignedPixelReference::bit_range_t;
0051 public:
0052 using difference_type = typename parent_t::difference_type;
0053 using reference = typename parent_t::reference;
0054
0055 bit_aligned_pixel_iterator() {}
0056 bit_aligned_pixel_iterator(const bit_aligned_pixel_iterator& p) : _bit_range(p._bit_range) {}
0057 bit_aligned_pixel_iterator& operator=(const bit_aligned_pixel_iterator& p) { _bit_range=p._bit_range; return *this; }
0058
0059 template <typename Ref> bit_aligned_pixel_iterator(const bit_aligned_pixel_iterator<Ref>& p) : _bit_range(p._bit_range) {}
0060
0061 bit_aligned_pixel_iterator(reference* ref) : _bit_range(ref->bit_range()) {}
0062 explicit bit_aligned_pixel_iterator(typename bit_range_t::byte_t* data, int bit_offset=0) : _bit_range(data,bit_offset) {}
0063
0064
0065
0066 auto operator[](difference_type d) const -> reference { bit_aligned_pixel_iterator it=*this; it.advance(d); return *it; }
0067
0068 auto operator->() const -> reference { return **this; }
0069 auto bit_range() const -> bit_range_t const& { return _bit_range; }
0070 auto bit_range() -> bit_range_t& { return _bit_range; }
0071 private:
0072 bit_range_t _bit_range;
0073 static constexpr int bit_size = NonAlignedPixelReference::bit_size;
0074
0075 friend class boost::iterator_core_access;
0076 auto dereference() const -> reference { return NonAlignedPixelReference(_bit_range); }
0077 void increment() { ++_bit_range; }
0078 void decrement() { --_bit_range; }
0079 void advance(difference_type d) { _bit_range.bit_advance(d*bit_size); }
0080
0081 auto distance_to(bit_aligned_pixel_iterator const& it) const -> difference_type { return _bit_range.bit_distance_to(it._bit_range) / bit_size; }
0082 bool equal(const bit_aligned_pixel_iterator& it) const { return _bit_range==it._bit_range; }
0083 };
0084
0085 template <typename NonAlignedPixelReference>
0086 struct const_iterator_type<bit_aligned_pixel_iterator<NonAlignedPixelReference>>
0087 {
0088 using type =
0089 bit_aligned_pixel_iterator<typename NonAlignedPixelReference::const_reference>;
0090 };
0091
0092 template <typename NonAlignedPixelReference>
0093 struct iterator_is_mutable<bit_aligned_pixel_iterator<NonAlignedPixelReference>>
0094 : std::integral_constant<bool, NonAlignedPixelReference::is_mutable>
0095 {};
0096
0097 template <typename NonAlignedPixelReference>
0098 struct is_iterator_adaptor<bit_aligned_pixel_iterator<NonAlignedPixelReference>>
0099 : std::false_type
0100 {};
0101
0102
0103
0104
0105
0106 template <typename NonAlignedPixelReference>
0107 struct color_space_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public color_space_type<NonAlignedPixelReference> {};
0108
0109 template <typename NonAlignedPixelReference>
0110 struct channel_mapping_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public channel_mapping_type<NonAlignedPixelReference> {};
0111
0112 template <typename NonAlignedPixelReference>
0113 struct is_planar<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public is_planar<NonAlignedPixelReference> {};
0114
0115
0116
0117
0118
0119 template <typename NonAlignedPixelReference>
0120 struct byte_to_memunit<bit_aligned_pixel_iterator<NonAlignedPixelReference>>
0121 : std::integral_constant<int, 8>
0122 {};
0123
0124 template <typename NonAlignedPixelReference>
0125 inline auto memunit_step(const bit_aligned_pixel_iterator<NonAlignedPixelReference>&) -> std::ptrdiff_t
0126 {
0127 return NonAlignedPixelReference::bit_size;
0128 }
0129
0130 template <typename NonAlignedPixelReference>
0131 inline auto memunit_distance(bit_aligned_pixel_iterator<NonAlignedPixelReference> const& p1, bit_aligned_pixel_iterator<NonAlignedPixelReference> const& p2) -> std::ptrdiff_t
0132 {
0133 return (p2.bit_range().current_byte() - p1.bit_range().current_byte())*8 + p2.bit_range().bit_offset() - p1.bit_range().bit_offset();
0134 }
0135
0136 template <typename NonAlignedPixelReference>
0137 inline void memunit_advance(bit_aligned_pixel_iterator<NonAlignedPixelReference>& p, std::ptrdiff_t diff) {
0138 p.bit_range().bit_advance(diff);
0139 }
0140
0141 template <typename NonAlignedPixelReference>
0142 inline auto memunit_advanced(bit_aligned_pixel_iterator<NonAlignedPixelReference> const& p, std::ptrdiff_t diff) -> bit_aligned_pixel_iterator<NonAlignedPixelReference> {
0143 bit_aligned_pixel_iterator<NonAlignedPixelReference> ret=p;
0144 memunit_advance(ret, diff);
0145 return ret;
0146 }
0147
0148 template <typename NonAlignedPixelReference> inline
0149 auto memunit_advanced_ref(bit_aligned_pixel_iterator<NonAlignedPixelReference> it, std::ptrdiff_t diff) -> NonAlignedPixelReference
0150 {
0151 return *memunit_advanced(it,diff);
0152 }
0153
0154
0155
0156
0157 template <typename NonAlignedPixelReference>
0158 struct dynamic_x_step_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > {
0159 using type = memory_based_step_iterator<bit_aligned_pixel_iterator<NonAlignedPixelReference> >;
0160 };
0161
0162
0163
0164
0165
0166 template <typename B, typename C, typename L, bool M>
0167 struct iterator_type_from_pixel<const bit_aligned_pixel_reference<B,C,L,M>,false,false,false>
0168 {
0169 using type = bit_aligned_pixel_iterator<bit_aligned_pixel_reference<B,C,L,false>> ;
0170 };
0171
0172 template <typename B, typename C, typename L, bool M>
0173 struct iterator_type_from_pixel<const bit_aligned_pixel_reference<B,C,L,M>,false,false,true>
0174 {
0175 using type = bit_aligned_pixel_iterator<bit_aligned_pixel_reference<B,C,L,true>>;
0176 };
0177
0178 template <typename B, typename C, typename L, bool M, bool IsPlanar, bool IsStep, bool IsMutable>
0179 struct iterator_type_from_pixel<bit_aligned_pixel_reference<B,C,L,M>,IsPlanar,IsStep,IsMutable>
0180 : public iterator_type_from_pixel<const bit_aligned_pixel_reference<B,C,L,M>,IsPlanar,IsStep,IsMutable> {};
0181
0182 } }
0183
0184 namespace std {
0185
0186
0187
0188 template <typename NonAlignedPixelReference>
0189 auto uninitialized_copy(boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> first,
0190 boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> last,
0191 boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference> dst)
0192 -> boost::gil::bit_aligned_pixel_iterator<NonAlignedPixelReference>
0193 {
0194 return std::copy(first,last,dst);
0195 }
0196
0197 }
0198
0199 #endif