2 Copyright 2005-2007 Adobe Systems Incorporated
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).
8 See http://opensource.adobe.com/gil for most recent version including documentation.
10 /*************************************************************************************************/
12 #ifndef GIL_ITERATOR_FROM_2D_H
13 #define GIL_ITERATOR_FROM_2D_H
15 ////////////////////////////////////////////////////////////////////////////////////////
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
22 ////////////////////////////////////////////////////////////////////////////////////////
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"
31 namespace boost
{ namespace gil
{
33 ////////////////////////////////////////////////////////////////////////////////////////
35 /// ITERATOR FROM 2D ADAPTOR
37 ////////////////////////////////////////////////////////////////////////////////////////
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
45 /// \ingroup PixelIteratorModelFromLocator PixelBasedModel
46 /// \brief Provides 1D random-access navigation to the pixels of the image. Models: PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept
48 /// Pixels are traversed from the top to the bottom row and from the left to the right
51 template <typename Loc2
> // Models PixelLocatorConcept
52 class iterator_from_2d
: public iterator_facade
<iterator_from_2d
<Loc2
>,
53 typename
Loc2::value_type
,
54 random_access_traversal_tag
,
55 typename
Loc2::reference
,
56 typename
Loc2::coord_t
> {
57 GIL_CLASS_REQUIRE(Loc2
, boost::gil
, PixelLocatorConcept
)
59 typedef iterator_facade
<iterator_from_2d
<Loc2
>,
60 typename
Loc2::value_type
,
61 random_access_traversal_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
;
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
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
); }
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(); }
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
) {}
86 template <typename Loc
> friend class iterator_from_2d
;
87 friend class boost::iterator_core_access
;
88 reference
dereference() const { return *_p
; }
92 if (_coords
.x
>=_width
) {
95 _p
+=point_t(-_width
,1);
104 _p
+=point_t(_width
,-1);
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.
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
;
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
;
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
);
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
;
133 point2
<std::ptrdiff_t> _coords
;
134 std::ptrdiff_t _width
;
138 template <typename Loc
> // Models PixelLocatorConcept
139 struct const_iterator_type
<iterator_from_2d
<Loc
> > {
140 typedef iterator_from_2d
<typename
Loc::const_t
> type
;
143 template <typename Loc
> // Models PixelLocatorConcept
144 struct iterator_is_mutable
<iterator_from_2d
<Loc
> > : public iterator_is_mutable
<typename
Loc::x_iterator
> {};
147 /////////////////////////////
148 // HasDynamicXStepTypeConcept
149 /////////////////////////////
151 template <typename Loc
>
152 struct dynamic_x_step_type
<iterator_from_2d
<Loc
> > {
153 typedef iterator_from_2d
<typename dynamic_x_step_type
<Loc
>::type
> type
;
157 /////////////////////////////
159 /////////////////////////////
161 template <typename Loc
> // Models PixelLocatorConcept
162 struct color_space_type
<iterator_from_2d
<Loc
> > : public color_space_type
<Loc
> {};
164 template <typename Loc
> // Models PixelLocatorConcept
165 struct channel_mapping_type
<iterator_from_2d
<Loc
> > : public channel_mapping_type
<Loc
> {};
167 template <typename Loc
> // Models PixelLocatorConcept
168 struct is_planar
<iterator_from_2d
<Loc
> > : public is_planar
<Loc
> {};
170 template <typename Loc
> // Models PixelLocatorConcept
171 struct channel_type
<iterator_from_2d
<Loc
> > : public channel_type
<Loc
> {};
173 } } // namespace boost::gil