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