1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef INCLUDED_BASEBMP_PIXELITERATOR_HXX
29 #define INCLUDED_BASEBMP_PIXELITERATOR_HXX
30 
31 #include <basebmp/metafunctions.hxx>
32 #include <basebmp/stridedarrayiterator.hxx>
33 
34 #include <vigra/metaprogramming.hxx>
35 #include <vigra/diff2d.hxx>
36 
37 namespace basebmp
38 {
39 
40 template< typename Valuetype > class PixelColumnIterator
41 {
42 public:
43     typedef Valuetype                           value_type;
44     typedef Valuetype&                          reference;
45     typedef reference                           index_reference;
46     typedef Valuetype*                          pointer;
47     typedef int                                 difference_type;
48     typedef image_traverser_tag                 iterator_category;
49 
50     typedef StridedArrayIterator< value_type >  MoveY;
51 
52 private:
53     MoveY           y;
54 
55     bool equal( PixelColumnIterator const & rhs ) const
56     {
57         return rhs.y == y;
58     }
59 
60     bool less( PixelColumnIterator const & rhs ) const
61     {
62         return y < rhs.y;
63     }
64 
65 public:
66     PixelColumnIterator() :
67         y(0)
68     {}
69 
70     explicit PixelColumnIterator( const MoveY& pos ) :
71         y(pos)
72     {}
73 
74     PixelColumnIterator( const MoveY& pos, int x ) :
75         y(pos,x)
76     {}
77 
78     PixelColumnIterator& operator+=( difference_type d )
79     {
80         y += d;
81         return *this;
82     }
83 
84     PixelColumnIterator& operator-=( difference_type d )
85     {
86         y -= d;
87         return *this;
88     }
89 
90     PixelColumnIterator operator+( difference_type d )
91     {
92         PixelColumnIterator res(*this);
93         res += d;
94         return res;
95     }
96 
97     PixelColumnIterator operator-( difference_type d )
98     {
99         PixelColumnIterator res(*this);
100         res -= d;
101         return res;
102     }
103 
104     PixelColumnIterator& operator++()
105     {
106         ++y;
107         return *this;
108     }
109 
110     PixelColumnIterator& operator--()
111     {
112         --y;
113         return *this;
114     }
115 
116     PixelColumnIterator operator++(int)
117     {
118         PixelColumnIterator res(*this);
119         ++y;
120         return res;
121     }
122 
123     PixelColumnIterator operator--(int)
124     {
125         PixelColumnIterator res(*this);
126         --y;
127         return res;
128     }
129 
130     bool operator==(PixelColumnIterator const & rhs) const
131     {
132         return equal( rhs );
133     }
134 
135     bool operator!=(PixelColumnIterator const & rhs) const
136     {
137         return !equal( rhs );
138     }
139 
140     bool operator<(PixelColumnIterator const & rhs) const
141     {
142         return less(rhs);
143     }
144 
145     bool operator<=(PixelColumnIterator const & rhs) const
146     {
147         return !rhs.less(*this);
148     }
149 
150     bool operator>(PixelColumnIterator const & rhs) const
151     {
152         return rhs.less(*this);
153     }
154 
155     bool operator>=(PixelColumnIterator const & rhs) const
156     {
157         return !less(rhs);
158     }
159 
160     difference_type operator-(PixelColumnIterator const & rhs) const
161     {
162         return y - rhs.y;
163     }
164 
165     value_type get() const
166     {
167         return *y();
168     }
169 
170     value_type get(difference_type d) const
171     {
172         return *y(d);
173     }
174 
175     void set( value_type v ) const
176     {
177         *y() = v;
178     }
179 
180     void set( value_type v, difference_type d ) const
181     {
182         *y(d) = v;
183     }
184 
185     reference operator*() const
186     {
187         return *y();
188     }
189 
190     pointer operator->() const
191     {
192         return y();
193     }
194 
195     reference operator[](difference_type d) const
196     {
197         return *y(d);
198     }
199 
200     reference operator()(int dy) const
201     {
202         return *y(dy);
203     }
204 };
205 
206 template< typename Valuetype > class PixelIterator
207 {
208 public:
209     typedef Valuetype                          value_type;
210     typedef Valuetype&                         reference;
211     typedef reference                          index_reference;
212     typedef Valuetype*                         pointer;
213     typedef vigra::Diff2D                      difference_type;
214     typedef image_traverser_tag                iterator_category;
215     typedef pointer                            row_iterator;
216     typedef PixelColumnIterator<value_type>    column_iterator;
217 
218     typedef int                                MoveX;
219     typedef StridedArrayIterator< value_type > MoveY;
220 
221     // TODO(F2): direction of iteration (ImageIterator can be made to
222     // run backwards)
223 
224 private:
225     bool equal(PixelIterator const & rhs) const
226     {
227         return (x == rhs.x) && (y == rhs.y);
228     }
229 
230     pointer current() const
231     {
232         return y() + x;
233     }
234 
235     pointer current(int dx, int dy) const
236     {
237         return y(dy) + x+dx;
238     }
239 
240 public:
241     PixelIterator() :
242         x(0),
243         y(0)
244     {}
245 
246     PixelIterator(pointer base, int ystride) :
247         x(0),
248         y(ystride,base)
249     {}
250 
251     bool operator==(PixelIterator const & rhs) const
252     {
253         return equal(rhs);
254     }
255 
256     bool operator!=(PixelIterator const & rhs) const
257     {
258         return !equal(rhs);
259     }
260 
261     difference_type operator-(PixelIterator const & rhs) const
262     {
263         return difference_type(x - rhs.x, y - rhs.y);
264     }
265 
266     MoveX x;
267     MoveY y;
268 
269     PixelIterator & operator+=(difference_type const & s)
270     {
271         x += s.x;
272         y += s.y;
273         return *this;
274     }
275 
276     PixelIterator & operator-=(difference_type const & s)
277     {
278         x -= s.x;
279         y -= s.y;
280         return *this;
281     }
282 
283     PixelIterator operator+(difference_type const & s) const
284     {
285         PixelIterator ret(*this);
286         ret += s;
287         return ret;
288     }
289 
290     PixelIterator operator-(difference_type const & s) const
291     {
292         PixelIterator ret(*this);
293         ret -= s;
294         return ret;
295     }
296 
297     row_iterator rowIterator() const
298     {
299         return row_iterator(y()+x);
300     }
301 
302     column_iterator columnIterator() const
303     {
304         return column_iterator(y,x);
305     }
306 
307     value_type get() const
308     {
309         return *current();
310     }
311 
312     value_type get(difference_type const & d) const
313     {
314         return *current(d.y, d.x);
315     }
316 
317     void set( value_type v ) const
318     {
319         *current() = v;
320     }
321 
322     void set( value_type v, difference_type const & d ) const
323     {
324         *current(d.y,d.x) = v;
325     }
326 
327     reference operator*() const
328     {
329         return *current();
330     }
331 
332     pointer operator->() const
333     {
334         return current();
335     }
336 
337     reference operator[]( const vigra::Diff2D& d ) const
338     {
339         return *current(d.x,d.y);
340     }
341 
342     reference operator()(int dx, int dy) const
343     {
344         return *current(dx,dy);
345     }
346 
347     pointer operator[](int dy) const
348     {
349         return y(dy) + x;
350     }
351 };
352 
353 } // namespace basebmp
354 
355 #endif /* INCLUDED_BASEBMP_PIXELITERATOR_HXX */
356