1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef INCLUDED_BASEBMP_PIXELITERATOR_HXX
25 #define INCLUDED_BASEBMP_PIXELITERATOR_HXX
26 
27 #include <basebmp/metafunctions.hxx>
28 #include <basebmp/stridedarrayiterator.hxx>
29 
30 #include <vigra/metaprogramming.hxx>
31 #include <vigra/diff2d.hxx>
32 
33 namespace basebmp
34 {
35 
36 template< typename Valuetype > class PixelColumnIterator
37 {
38 public:
39     typedef Valuetype                           value_type;
40     typedef Valuetype&                          reference;
41     typedef reference                           index_reference;
42     typedef Valuetype*                          pointer;
43     typedef int                                 difference_type;
44     typedef image_traverser_tag                 iterator_category;
45 
46     typedef StridedArrayIterator< value_type >  MoveY;
47 
48 private:
49     MoveY           y;
50 
equal(PixelColumnIterator const & rhs) const51     bool equal( PixelColumnIterator const & rhs ) const
52     {
53         return rhs.y == y;
54     }
55 
less(PixelColumnIterator const & rhs) const56     bool less( PixelColumnIterator const & rhs ) const
57     {
58         return y < rhs.y;
59     }
60 
61 public:
PixelColumnIterator()62     PixelColumnIterator() :
63         y(0)
64     {}
65 
PixelColumnIterator(const MoveY & pos)66     explicit PixelColumnIterator( const MoveY& pos ) :
67         y(pos)
68     {}
69 
PixelColumnIterator(const MoveY & pos,int x)70     PixelColumnIterator( const MoveY& pos, int x ) :
71         y(pos,x)
72     {}
73 
operator +=(difference_type d)74     PixelColumnIterator& operator+=( difference_type d )
75     {
76         y += d;
77         return *this;
78     }
79 
operator -=(difference_type d)80     PixelColumnIterator& operator-=( difference_type d )
81     {
82         y -= d;
83         return *this;
84     }
85 
operator +(difference_type d)86     PixelColumnIterator operator+( difference_type d )
87     {
88         PixelColumnIterator res(*this);
89         res += d;
90         return res;
91     }
92 
operator -(difference_type d)93     PixelColumnIterator operator-( difference_type d )
94     {
95         PixelColumnIterator res(*this);
96         res -= d;
97         return res;
98     }
99 
operator ++()100     PixelColumnIterator& operator++()
101     {
102         ++y;
103         return *this;
104     }
105 
operator --()106     PixelColumnIterator& operator--()
107     {
108         --y;
109         return *this;
110     }
111 
operator ++(int)112     PixelColumnIterator operator++(int)
113     {
114         PixelColumnIterator res(*this);
115         ++y;
116         return res;
117     }
118 
operator --(int)119     PixelColumnIterator operator--(int)
120     {
121         PixelColumnIterator res(*this);
122         --y;
123         return res;
124     }
125 
operator ==(PixelColumnIterator const & rhs) const126     bool operator==(PixelColumnIterator const & rhs) const
127     {
128         return equal( rhs );
129     }
130 
operator !=(PixelColumnIterator const & rhs) const131     bool operator!=(PixelColumnIterator const & rhs) const
132     {
133         return !equal( rhs );
134     }
135 
operator <(PixelColumnIterator const & rhs) const136     bool operator<(PixelColumnIterator const & rhs) const
137     {
138         return less(rhs);
139     }
140 
operator <=(PixelColumnIterator const & rhs) const141     bool operator<=(PixelColumnIterator const & rhs) const
142     {
143         return !rhs.less(*this);
144     }
145 
operator >(PixelColumnIterator const & rhs) const146     bool operator>(PixelColumnIterator const & rhs) const
147     {
148         return rhs.less(*this);
149     }
150 
operator >=(PixelColumnIterator const & rhs) const151     bool operator>=(PixelColumnIterator const & rhs) const
152     {
153         return !less(rhs);
154     }
155 
operator -(PixelColumnIterator const & rhs) const156     difference_type operator-(PixelColumnIterator const & rhs) const
157     {
158         return y - rhs.y;
159     }
160 
get() const161     value_type get() const
162     {
163         return *y();
164     }
165 
get(difference_type d) const166     value_type get(difference_type d) const
167     {
168         return *y(d);
169     }
170 
set(value_type v) const171     void set( value_type v ) const
172     {
173         *y() = v;
174     }
175 
set(value_type v,difference_type d) const176     void set( value_type v, difference_type d ) const
177     {
178         *y(d) = v;
179     }
180 
operator *() const181     reference operator*() const
182     {
183         return *y();
184     }
185 
operator ->() const186     pointer operator->() const
187     {
188         return y();
189     }
190 
operator [](difference_type d) const191     reference operator[](difference_type d) const
192     {
193         return *y(d);
194     }
195 
operator ()(int dy) const196     reference operator()(int dy) const
197     {
198         return *y(dy);
199     }
200 };
201 
202 template< typename Valuetype > class PixelIterator
203 {
204 public:
205     typedef Valuetype                          value_type;
206     typedef Valuetype&                         reference;
207     typedef reference                          index_reference;
208     typedef Valuetype*                         pointer;
209     typedef vigra::Diff2D                      difference_type;
210     typedef image_traverser_tag                iterator_category;
211     typedef pointer                            row_iterator;
212     typedef PixelColumnIterator<value_type>    column_iterator;
213 
214     typedef int                                MoveX;
215     typedef StridedArrayIterator< value_type > MoveY;
216 
217     // TODO(F2): direction of iteration (ImageIterator can be made to
218     // run backwards)
219 
220 private:
equal(PixelIterator const & rhs) const221     bool equal(PixelIterator const & rhs) const
222     {
223         return (x == rhs.x) && (y == rhs.y);
224     }
225 
current() const226     pointer current() const
227     {
228         return y() + x;
229     }
230 
current(int dx,int dy) const231     pointer current(int dx, int dy) const
232     {
233         return y(dy) + x+dx;
234     }
235 
236 public:
PixelIterator()237     PixelIterator() :
238         x(0),
239         y(0)
240     {}
241 
PixelIterator(pointer base,int ystride)242     PixelIterator(pointer base, int ystride) :
243         x(0),
244         y(ystride,base)
245     {}
246 
operator ==(PixelIterator const & rhs) const247     bool operator==(PixelIterator const & rhs) const
248     {
249         return equal(rhs);
250     }
251 
operator !=(PixelIterator const & rhs) const252     bool operator!=(PixelIterator const & rhs) const
253     {
254         return !equal(rhs);
255     }
256 
operator -(PixelIterator const & rhs) const257     difference_type operator-(PixelIterator const & rhs) const
258     {
259         return difference_type(x - rhs.x, y - rhs.y);
260     }
261 
262     MoveX x;
263     MoveY y;
264 
operator +=(difference_type const & s)265     PixelIterator & operator+=(difference_type const & s)
266     {
267         x += s.x;
268         y += s.y;
269         return *this;
270     }
271 
operator -=(difference_type const & s)272     PixelIterator & operator-=(difference_type const & s)
273     {
274         x -= s.x;
275         y -= s.y;
276         return *this;
277     }
278 
operator +(difference_type const & s) const279     PixelIterator operator+(difference_type const & s) const
280     {
281         PixelIterator ret(*this);
282         ret += s;
283         return ret;
284     }
285 
operator -(difference_type const & s) const286     PixelIterator operator-(difference_type const & s) const
287     {
288         PixelIterator ret(*this);
289         ret -= s;
290         return ret;
291     }
292 
rowIterator() const293     row_iterator rowIterator() const
294     {
295         return row_iterator(y()+x);
296     }
297 
columnIterator() const298     column_iterator columnIterator() const
299     {
300         return column_iterator(y,x);
301     }
302 
get() const303     value_type get() const
304     {
305         return *current();
306     }
307 
get(difference_type const & d) const308     value_type get(difference_type const & d) const
309     {
310         return *current(d.y, d.x);
311     }
312 
set(value_type v) const313     void set( value_type v ) const
314     {
315         *current() = v;
316     }
317 
set(value_type v,difference_type const & d) const318     void set( value_type v, difference_type const & d ) const
319     {
320         *current(d.y,d.x) = v;
321     }
322 
operator *() const323     reference operator*() const
324     {
325         return *current();
326     }
327 
operator ->() const328     pointer operator->() const
329     {
330         return current();
331     }
332 
operator [](const vigra::Diff2D & d) const333     reference operator[]( const vigra::Diff2D& d ) const
334     {
335         return *current(d.x,d.y);
336     }
337 
operator ()(int dx,int dy) const338     reference operator()(int dx, int dy) const
339     {
340         return *current(dx,dy);
341     }
342 
operator [](int dy) const343     pointer operator[](int dy) const
344     {
345         return y(dy) + x;
346     }
347 };
348 
349 } // namespace basebmp
350 
351 #endif /* INCLUDED_BASEBMP_PIXELITERATOR_HXX */
352