1/*
2 Copyright 2005-2007 Adobe Systems Incorporated
3
4 Use, modification and distribution are subject to the Boost Software License,
5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7
8 See http://opensource.adobe.com/gil for most recent version including documentation.
9*/
10/*************************************************************************************************/
11
12#ifndef GIL_ITERATOR_FROM_2D_H
13#define GIL_ITERATOR_FROM_2D_H
14
15////////////////////////////////////////////////////////////////////////////////////////
16/// \file
17/// \brief pixel step iterator, pixel image iterator and pixel dereference iterator
18/// \author Lubomir Bourdev and Hailin Jin \n
19/// Adobe Systems Incorporated
20/// \date 2005-2007 \n Last updated on September 18, 2007
21///
22////////////////////////////////////////////////////////////////////////////////////////
23
24#include <cassert>
25#include <boost/iterator/iterator_facade.hpp>
26#include "gil_concept.hpp"
27#include "gil_config.hpp"
28#include "pixel_iterator.hpp"
29#include "locator.hpp"
30
31namespace boost { namespace gil {
32
33////////////////////////////////////////////////////////////////////////////////////////
34///
35/// ITERATOR FROM 2D ADAPTOR
36///
37////////////////////////////////////////////////////////////////////////////////////////
38
39
40/// \defgroup PixelIteratorModelFromLocator iterator_from_2d
41/// \ingroup PixelIteratorModel
42/// \brief An iterator over two-dimensional locator. Useful for iterating over the pixels of an image view. Models PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept
43
44
45/// \ingroup PixelIteratorModelFromLocator PixelBasedModel
46/// \brief Provides 1D random-access navigation to the pixels of the image. Models: PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept
47///
48/// Pixels are traversed from the top to the bottom row and from the left to the right
49/// within each row
50
51template <typename Loc2> // Models PixelLocatorConcept
52class iterator_from_2d : public iterator_facade<iterator_from_2d<Loc2>,
53 typename Loc2::value_type,
54 std::random_access_iterator_tag,
55 typename Loc2::reference,
56 typename Loc2::coord_t> {
57 GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept)
58public:
59 typedef iterator_facade<iterator_from_2d<Loc2>,
60 typename Loc2::value_type,
61 std::random_access_iterator_tag,
62 typename Loc2::reference,
63 typename Loc2::coord_t> parent_t;
64 typedef typename parent_t::reference reference;
65 typedef typename parent_t::difference_type difference_type;
66 typedef typename Loc2::x_iterator x_iterator;
67 typedef typename Loc2::point_t point_t;
68
69 std::ptrdiff_t width() const { return _width; } // number of pixels per image row
70 std::ptrdiff_t x_pos() const { return _coords.x; } // current x position
71 std::ptrdiff_t y_pos() const { return _coords.y; } // current y position
72
73 /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
74 /// We require our own reference because it is registered in iterator_traits
75 reference operator[](difference_type d) const { return *(*this+d); }
76
77 bool is_1d_traversable() const { return _p.is_1d_traversable(width()); } // is there no gap at the end of each row?
78 x_iterator& x() { return _p.x(); }
79
80 iterator_from_2d(){}
81 iterator_from_2d(const Loc2& p, std::ptrdiff_t width, std::ptrdiff_t x=0, std::ptrdiff_t y=0) : _coords(x,y), _width(width), _p(p) {}
82 iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
83 template <typename Loc> iterator_from_2d(const iterator_from_2d<Loc>& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
84
85private:
86 template <typename Loc> friend class iterator_from_2d;
87 friend class boost::iterator_core_access;
88 reference dereference() const { return *_p; }
89 void increment() {
90 ++_coords.x;
91 ++_p.x();
92 if (_coords.x>=_width) {
93 _coords.x=0;
94 ++_coords.y;
95 _p+=point_t(-_width,1);
96 }
97 }
98 void decrement() {
99 --_coords.x;
100 --_p.x();
101 if (_coords.x<0) {
102 _coords.x=_width-1;
103 --_coords.y;
104 _p+=point_t(_width,-1);
105 }
106 }
107
108 GIL_FORCEINLINE void advance(difference_type d) {
109 if (_width==0) return; // unfortunately we need to check for that. Default-constructed images have width of 0 and the code below will throw if executed.
110 point_t delta;
111 if (_coords.x+d>=0) { // not going back to a previous row?
112 delta.x=(_coords.x+(std::ptrdiff_t)d)%_width - _coords.x;
113 delta.y=(_coords.x+(std::ptrdiff_t)d)/_width;
114 } else {
115 delta.x=(_coords.x+(std::ptrdiff_t)d*(1-_width))%_width -_coords.x;
116 delta.y=-(_width-_coords.x-(std::ptrdiff_t)d-1)/_width;
117 }
118 _p+=delta;
119 _coords.x+=delta.x;
120 _coords.y+=delta.y;
121 }
122
123 difference_type distance_to(const iterator_from_2d& it) const {
124 if (_width==0) return 0;
125 return (it.y_pos()-_coords.y)*_width + (it.x_pos()-_coords.x);
126 }
127
128 bool equal(const iterator_from_2d& it) const {
129 assert(_width==it.width()); // they must belong to the same image
130 return _coords==it._coords && _p==it._p;
131 }
132
133 point2<std::ptrdiff_t> _coords;
134 std::ptrdiff_t _width;
135 Loc2 _p;
136};
137
138template <typename Loc> // Models PixelLocatorConcept
139struct const_iterator_type<iterator_from_2d<Loc> > {
140 typedef iterator_from_2d<typename Loc::const_t> type;
141};
142
143template <typename Loc> // Models PixelLocatorConcept
144struct iterator_is_mutable<iterator_from_2d<Loc> > : public iterator_is_mutable<typename Loc::x_iterator> {};
145
146
147/////////////////////////////
148// HasDynamicXStepTypeConcept
149/////////////////////////////
150
151template <typename Loc>
152struct dynamic_x_step_type<iterator_from_2d<Loc> > {
153 typedef iterator_from_2d<typename dynamic_x_step_type<Loc>::type> type;
154};
155
156
157/////////////////////////////
158// PixelBasedConcept
159/////////////////////////////
160
161template <typename Loc> // Models PixelLocatorConcept
162struct color_space_type<iterator_from_2d<Loc> > : public color_space_type<Loc> {};
163
164template <typename Loc> // Models PixelLocatorConcept
165struct channel_mapping_type<iterator_from_2d<Loc> > : public channel_mapping_type<Loc> {};
166
167template <typename Loc> // Models PixelLocatorConcept
168struct is_planar<iterator_from_2d<Loc> > : public is_planar<Loc> {};
169
170template <typename Loc> // Models PixelLocatorConcept
171struct channel_type<iterator_from_2d<Loc> > : public channel_type<Loc> {};
172
173} } // namespace boost::gil
174
175#endif
176

source code of boost/boost/gil/iterator_from_2d.hpp