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_COMPOSITEITERATOR_HXX
25cdf0e10cSrcweir #define INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <sal/types.h>
28cdf0e10cSrcweir #include <osl/diagnose.h>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <basebmp/nonstandarditerator.hxx>
31cdf0e10cSrcweir #include <vigra/tuple.hxx>
32cdf0e10cSrcweir #include <vigra/iteratortraits.hxx>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir 
35cdf0e10cSrcweir namespace basebmp
36cdf0e10cSrcweir {
37cdf0e10cSrcweir 
38cdf0e10cSrcweir namespace detail
39cdf0e10cSrcweir {
40cdf0e10cSrcweir     template< typename T1, typename T2 > class ArithmeticProxy
41cdf0e10cSrcweir     {
42cdf0e10cSrcweir     public:
ArithmeticProxy(T1 & val1,T2 & val2)43cdf0e10cSrcweir         ArithmeticProxy(T1& val1, T2& val2) :
44cdf0e10cSrcweir             mpVal1( &val1 ),
45cdf0e10cSrcweir             mpVal2( &val2 )
46cdf0e10cSrcweir         {}
47cdf0e10cSrcweir 
operator ++()48cdf0e10cSrcweir         void operator++() { ++(*mpVal1); ++(*mpVal2); }
operator ++(int)49cdf0e10cSrcweir         void operator++(int) { (*mpVal1)++; (*mpVal2)++; }
operator --()50cdf0e10cSrcweir         void operator--() { --(*mpVal1); --(*mpVal2); }
operator --(int)51cdf0e10cSrcweir         void operator--(int) { (*mpVal1)--; (*mpVal2)--; }
operator +=(int d)52cdf0e10cSrcweir         void operator+=(int d) {*mpVal1+=d; *mpVal2+=d; }
operator -=(int d)53cdf0e10cSrcweir         void operator-=(int d) {*mpVal1-=d; *mpVal2-=d; }
54cdf0e10cSrcweir 
operator ==(ArithmeticProxy const & rhs) const55cdf0e10cSrcweir         bool operator==(ArithmeticProxy const & rhs) const
56cdf0e10cSrcweir         { return *mpVal1==*rhs.mpVal1 && *mpVal2==*rhs.mpVal2; }
57cdf0e10cSrcweir 
operator !=(ArithmeticProxy const & rhs) const58cdf0e10cSrcweir         bool operator!=(ArithmeticProxy const & rhs) const
59cdf0e10cSrcweir         { return *mpVal1!=*rhs.mpVal1 || *mpVal2!=*rhs.mpVal2; }
60cdf0e10cSrcweir 
operator <(ArithmeticProxy const & rhs) const61cdf0e10cSrcweir         bool operator<(ArithmeticProxy const & rhs) const
62cdf0e10cSrcweir         { return *mpVal1<*rhs.mpVal1 && *mpVal2<*rhs.mpVal2; }
63cdf0e10cSrcweir 
operator <=(ArithmeticProxy const & rhs) const64cdf0e10cSrcweir         bool operator<=(ArithmeticProxy const & rhs) const
65cdf0e10cSrcweir         { return *mpVal1<=*rhs.mpVal1 && *mpVal2<=*rhs.mpVal2; }
66cdf0e10cSrcweir 
operator >(ArithmeticProxy const & rhs) const67cdf0e10cSrcweir         bool operator>(ArithmeticProxy const & rhs) const
68cdf0e10cSrcweir         { return *mpVal1>*rhs.mpVal1 && *mpVal2>*rhs.mpVal2; }
69cdf0e10cSrcweir 
operator >=(ArithmeticProxy const & rhs) const70cdf0e10cSrcweir         bool operator>=(ArithmeticProxy const & rhs) const
71cdf0e10cSrcweir         { return *mpVal1>=*rhs.mpVal1 && *mpVal2>=*rhs.mpVal2; }
72cdf0e10cSrcweir 
operator -(ArithmeticProxy const & rhs) const73cdf0e10cSrcweir         int operator-(ArithmeticProxy const & rhs) const
74cdf0e10cSrcweir         { return *mpVal1 - *rhs.mpVal1; }
75cdf0e10cSrcweir 
76cdf0e10cSrcweir     private:
77cdf0e10cSrcweir         T1* mpVal1;
78cdf0e10cSrcweir         T2* mpVal2;
79cdf0e10cSrcweir     };
80cdf0e10cSrcweir 
81cdf0e10cSrcweir     template< typename Iterator1,
82cdf0e10cSrcweir               typename Iterator2,
83cdf0e10cSrcweir               typename ValueType,
84cdf0e10cSrcweir               typename DifferenceType,
85cdf0e10cSrcweir               typename IteratorCategory,
86cdf0e10cSrcweir               class Derived >
87cdf0e10cSrcweir     class CompositeIteratorBase : public NonStandardIterator
88cdf0e10cSrcweir     {
89cdf0e10cSrcweir     public:
90cdf0e10cSrcweir         typedef Iterator1        iterator1_type;
91cdf0e10cSrcweir         typedef Iterator2        iterator2_type;
92cdf0e10cSrcweir         typedef ValueType        value_type;
93cdf0e10cSrcweir         typedef DifferenceType   difference_type;
94cdf0e10cSrcweir         typedef IteratorCategory iterator_category;
95cdf0e10cSrcweir 
96cdf0e10cSrcweir     protected:
97cdf0e10cSrcweir         iterator1_type maIter1;
98cdf0e10cSrcweir         iterator2_type maIter2;
99cdf0e10cSrcweir 
100cdf0e10cSrcweir     private:
equal(CompositeIteratorBase const & rhs) const101cdf0e10cSrcweir         bool equal(CompositeIteratorBase const & rhs) const
102cdf0e10cSrcweir         {
103cdf0e10cSrcweir             return (maIter1 == rhs.maIter1) && (maIter2 == rhs.maIter2);
104cdf0e10cSrcweir         }
105cdf0e10cSrcweir 
106cdf0e10cSrcweir     public:
CompositeIteratorBase()107cdf0e10cSrcweir         CompositeIteratorBase() :
108cdf0e10cSrcweir             maIter1(),
109cdf0e10cSrcweir             maIter2()
110cdf0e10cSrcweir         {}
111cdf0e10cSrcweir 
CompositeIteratorBase(const iterator1_type & rIter1,const iterator2_type & rIter2)112cdf0e10cSrcweir         CompositeIteratorBase( const iterator1_type& rIter1, const iterator2_type& rIter2 ) :
113cdf0e10cSrcweir             maIter1( rIter1 ),
114cdf0e10cSrcweir             maIter2( rIter2 )
115cdf0e10cSrcweir         {}
116cdf0e10cSrcweir 
operator ==(Derived const & rhs) const117cdf0e10cSrcweir         bool operator==(Derived const & rhs) const
118cdf0e10cSrcweir         {
119cdf0e10cSrcweir             return equal(rhs);
120cdf0e10cSrcweir         }
121cdf0e10cSrcweir 
operator !=(Derived const & rhs) const122cdf0e10cSrcweir         bool operator!=(Derived const & rhs) const
123cdf0e10cSrcweir         {
124cdf0e10cSrcweir             return !equal(rhs);
125cdf0e10cSrcweir         }
126cdf0e10cSrcweir 
operator -(Derived const & rhs) const127cdf0e10cSrcweir         difference_type operator-(Derived const & rhs) const
128cdf0e10cSrcweir         {
129cdf0e10cSrcweir             OSL_ASSERT( maIter1 - rhs.maIter1 == maIter2 - rhs.maIter2 );
130cdf0e10cSrcweir             return maIter1 - rhs.maIter1;
131cdf0e10cSrcweir         }
132cdf0e10cSrcweir 
operator +=(difference_type const & s)133cdf0e10cSrcweir         Derived & operator+=(difference_type const & s)
134cdf0e10cSrcweir         {
135cdf0e10cSrcweir             maIter1 += s;
136cdf0e10cSrcweir             maIter2 += s;
137cdf0e10cSrcweir             return static_cast<Derived&>(*this);
138cdf0e10cSrcweir         }
139cdf0e10cSrcweir 
operator -=(difference_type const & s)140cdf0e10cSrcweir         Derived & operator-=(difference_type const & s)
141cdf0e10cSrcweir         {
142cdf0e10cSrcweir             maIter1 -= s;
143cdf0e10cSrcweir             maIter2 -= s;
144cdf0e10cSrcweir             return static_cast<Derived&>(*this);
145cdf0e10cSrcweir         }
146cdf0e10cSrcweir 
operator +(difference_type const & s) const147cdf0e10cSrcweir         Derived operator+(difference_type const & s) const
148cdf0e10cSrcweir         {
149cdf0e10cSrcweir             Derived ret(static_cast<Derived const&>(*this));
150cdf0e10cSrcweir             ret += s;
151cdf0e10cSrcweir             return ret;
152cdf0e10cSrcweir         }
153cdf0e10cSrcweir 
operator -(difference_type const & s) const154cdf0e10cSrcweir         Derived operator-(difference_type const & s) const
155cdf0e10cSrcweir         {
156cdf0e10cSrcweir             Derived ret(static_cast<Derived const&>(*this));
157cdf0e10cSrcweir             ret -= s;
158cdf0e10cSrcweir             return ret;
159cdf0e10cSrcweir         }
160cdf0e10cSrcweir 
operator ++()161cdf0e10cSrcweir         Derived& operator++()
162cdf0e10cSrcweir         {
163cdf0e10cSrcweir             ++maIter1;
164cdf0e10cSrcweir             ++maIter2;
165cdf0e10cSrcweir             return static_cast<Derived&>(*this);
166cdf0e10cSrcweir         }
167cdf0e10cSrcweir 
operator --()168cdf0e10cSrcweir         Derived& operator--()
169cdf0e10cSrcweir         {
170cdf0e10cSrcweir             --maIter1;
171cdf0e10cSrcweir             --maIter2;
172cdf0e10cSrcweir             return static_cast<Derived&>(*this);
173cdf0e10cSrcweir         }
174cdf0e10cSrcweir 
operator ++(int)175cdf0e10cSrcweir         Derived operator++(int)
176cdf0e10cSrcweir         {
177cdf0e10cSrcweir             Derived ret(static_cast<Derived const&>(*this));
178cdf0e10cSrcweir             ++maIter1;
179cdf0e10cSrcweir             ++maIter2;
180cdf0e10cSrcweir             return ret;
181cdf0e10cSrcweir         }
182cdf0e10cSrcweir 
operator --(int)183cdf0e10cSrcweir         Derived operator--(int)
184cdf0e10cSrcweir         {
185cdf0e10cSrcweir             Derived ret(static_cast<Derived const&>(*this));
186cdf0e10cSrcweir             --maIter1;
187cdf0e10cSrcweir             --maIter2;
188cdf0e10cSrcweir             return ret;
189cdf0e10cSrcweir         }
190cdf0e10cSrcweir 
get() const191cdf0e10cSrcweir         value_type get() const
192cdf0e10cSrcweir         {
193cdf0e10cSrcweir             return value_type(maIter1.get(),
194cdf0e10cSrcweir                               maIter2.get());
195cdf0e10cSrcweir         }
196cdf0e10cSrcweir 
get(difference_type const & d) const197cdf0e10cSrcweir         value_type get(difference_type const & d) const
198cdf0e10cSrcweir         {
199cdf0e10cSrcweir             return value_type(maIter1.get(d),
200cdf0e10cSrcweir                               maIter2.get(d));
201cdf0e10cSrcweir         }
202cdf0e10cSrcweir 
set(value_type v) const203cdf0e10cSrcweir         void set( value_type v ) const
204cdf0e10cSrcweir         {
205cdf0e10cSrcweir             maIter1.set(v);
206cdf0e10cSrcweir             maIter2.set(v);
207cdf0e10cSrcweir         }
208cdf0e10cSrcweir 
set(value_type v,difference_type const & d) const209cdf0e10cSrcweir         void set( value_type v, difference_type const & d ) const
210cdf0e10cSrcweir         {
211cdf0e10cSrcweir             maIter1.set(v,d);
212cdf0e10cSrcweir             maIter2.set(v,d);
213cdf0e10cSrcweir         }
214cdf0e10cSrcweir 
first() const215cdf0e10cSrcweir         const iterator1_type& first() const { return maIter1; }
first()216cdf0e10cSrcweir         iterator1_type& first() { return maIter1; }
217cdf0e10cSrcweir 
second() const218cdf0e10cSrcweir         const iterator2_type& second() const { return maIter2; }
second()219cdf0e10cSrcweir         iterator2_type& second() { return maIter2; }
220cdf0e10cSrcweir     };
221cdf0e10cSrcweir }
222cdf0e10cSrcweir 
223cdf0e10cSrcweir /** Provide the composition of two 1D image iterators
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     Use this template to compose two iterators into one (e.g. image
226cdf0e10cSrcweir     and mask). Operations are transitive, e.g. operator== only returns
227cdf0e10cSrcweir     true, if both wrapped iterator operator== have yielded true.
228cdf0e10cSrcweir 
229cdf0e10cSrcweir     Note that both iterators must have compatible difference types. To
230cdf0e10cSrcweir     avoid funny effects, iterator ranges given by a CompositeIterator
231cdf0e10cSrcweir     should consist of wrapped iterators of similar range
232cdf0e10cSrcweir  */
233cdf0e10cSrcweir template< typename Iterator1,
234cdf0e10cSrcweir           typename Iterator2,
235cdf0e10cSrcweir           typename ValueType,
236cdf0e10cSrcweir           typename DifferenceType,
237cdf0e10cSrcweir           typename IteratorCategory >
238cdf0e10cSrcweir class CompositeIterator1D :
239cdf0e10cSrcweir     public detail::CompositeIteratorBase< Iterator1,
240cdf0e10cSrcweir                                           Iterator2,
241cdf0e10cSrcweir                                           ValueType,
242cdf0e10cSrcweir                                           DifferenceType,
243cdf0e10cSrcweir                                           IteratorCategory,
244cdf0e10cSrcweir                                           CompositeIterator1D<Iterator1,
245cdf0e10cSrcweir                                                               Iterator2,
246cdf0e10cSrcweir                                                               ValueType,
247cdf0e10cSrcweir                                                               DifferenceType,
248cdf0e10cSrcweir                                                               IteratorCategory> >
249cdf0e10cSrcweir {
250cdf0e10cSrcweir     typedef detail::CompositeIteratorBase< Iterator1,
251cdf0e10cSrcweir                                            Iterator2,
252cdf0e10cSrcweir                                            ValueType,
253cdf0e10cSrcweir                                            DifferenceType,
254cdf0e10cSrcweir                                            IteratorCategory,
255cdf0e10cSrcweir                                            CompositeIterator1D<Iterator1,
256cdf0e10cSrcweir                                                                Iterator2,
257cdf0e10cSrcweir                                                                ValueType,
258cdf0e10cSrcweir                                                                DifferenceType,
259cdf0e10cSrcweir                                                                IteratorCategory> > base_type;
260cdf0e10cSrcweir public:
CompositeIterator1D()261cdf0e10cSrcweir     CompositeIterator1D() :
262cdf0e10cSrcweir         base_type()
263cdf0e10cSrcweir     {}
264cdf0e10cSrcweir 
CompositeIterator1D(const Iterator1 & rIter1,const Iterator2 & rIter2)265cdf0e10cSrcweir     CompositeIterator1D( const Iterator1& rIter1,
266cdf0e10cSrcweir                          const Iterator2& rIter2 ) :
267cdf0e10cSrcweir         base_type( rIter1, rIter2 )
268cdf0e10cSrcweir     {}
269cdf0e10cSrcweir };
270cdf0e10cSrcweir 
271cdf0e10cSrcweir /** Provide the composition of two 2D image iterators
272cdf0e10cSrcweir 
273cdf0e10cSrcweir     Use this template to compose two iterators into one (e.g. image
274cdf0e10cSrcweir     and mask). Operations are transitive, e.g. operator== only returns
275cdf0e10cSrcweir     true, if both wrapped iterator operator== have yielded true.
276cdf0e10cSrcweir 
277cdf0e10cSrcweir     Note that both iterators must have compatible difference types. To
278cdf0e10cSrcweir     avoid funny effects, iterator ranges given by a CompositeIterator
279cdf0e10cSrcweir     should consist of wrapped iterators of similar range
280cdf0e10cSrcweir  */
281cdf0e10cSrcweir template< typename Iterator1, typename Iterator2 > class CompositeIterator2D :
282cdf0e10cSrcweir     public detail::CompositeIteratorBase< Iterator1,
283cdf0e10cSrcweir                                           Iterator2,
284cdf0e10cSrcweir                                           std::pair<
285cdf0e10cSrcweir                                                 typename vigra::IteratorTraits<Iterator1>::value_type,
286cdf0e10cSrcweir                                                 typename vigra::IteratorTraits<Iterator2>::value_type >,
287cdf0e10cSrcweir                                           typename vigra::IteratorTraits<Iterator1>::difference_type,
288cdf0e10cSrcweir                                           typename vigra::IteratorTraits<Iterator1>::iterator_category,
289cdf0e10cSrcweir                                           CompositeIterator2D<Iterator1, Iterator2> >
290cdf0e10cSrcweir {
291cdf0e10cSrcweir     typedef detail::CompositeIteratorBase< Iterator1,
292cdf0e10cSrcweir                                            Iterator2,
293cdf0e10cSrcweir                                            std::pair<
294cdf0e10cSrcweir                                                 typename vigra::IteratorTraits<Iterator1>::value_type,
295cdf0e10cSrcweir                                                 typename vigra::IteratorTraits<Iterator2>::value_type >,
296cdf0e10cSrcweir                                            typename vigra::IteratorTraits<Iterator1>::difference_type,
297cdf0e10cSrcweir                                            typename vigra::IteratorTraits<Iterator1>::iterator_category,
298cdf0e10cSrcweir                                            CompositeIterator2D<Iterator1, Iterator2> > base_type;
299cdf0e10cSrcweir public:
300cdf0e10cSrcweir     typedef CompositeIterator1D< typename Iterator1::row_iterator,
301cdf0e10cSrcweir                                  typename Iterator2::row_iterator,
302cdf0e10cSrcweir                                  typename base_type::value_type,
303cdf0e10cSrcweir                                  int,
304cdf0e10cSrcweir                                  typename base_type::iterator_category >  row_iterator;
305cdf0e10cSrcweir     typedef CompositeIterator1D< typename Iterator1::column_iterator,
306cdf0e10cSrcweir                                  typename Iterator2::column_iterator,
307cdf0e10cSrcweir                                  typename base_type::value_type,
308cdf0e10cSrcweir                                  int,
309cdf0e10cSrcweir                                  typename base_type::iterator_category >  column_iterator;
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     typedef detail::ArithmeticProxy< typename Iterator1::MoveX,
312cdf0e10cSrcweir                                      typename Iterator2::MoveX >            MoveX;
313cdf0e10cSrcweir     typedef detail::ArithmeticProxy< typename Iterator1::MoveY,
314cdf0e10cSrcweir                                      typename Iterator2::MoveY >            MoveY;
315cdf0e10cSrcweir 
316cdf0e10cSrcweir     MoveX x;
317cdf0e10cSrcweir     MoveY y;
318cdf0e10cSrcweir 
CompositeIterator2D()319cdf0e10cSrcweir     CompositeIterator2D() :
320cdf0e10cSrcweir         base_type(),
321cdf0e10cSrcweir         x(this->maIter1.x,this->maIter2.x),
322cdf0e10cSrcweir         y(this->maIter1.y,this->maIter2.y)
323cdf0e10cSrcweir     {}
324cdf0e10cSrcweir 
CompositeIterator2D(const Iterator1 & rIter1,const Iterator2 & rIter2)325cdf0e10cSrcweir     CompositeIterator2D( const Iterator1& rIter1, const Iterator2& rIter2 ) :
326cdf0e10cSrcweir         base_type( rIter1, rIter2 ),
327cdf0e10cSrcweir         x(this->maIter1.x,this->maIter2.x),
328cdf0e10cSrcweir         y(this->maIter1.y,this->maIter2.y)
329cdf0e10cSrcweir     {}
330cdf0e10cSrcweir 
CompositeIterator2D(const CompositeIterator2D & rOld)331cdf0e10cSrcweir     CompositeIterator2D( const CompositeIterator2D& rOld ) :
332cdf0e10cSrcweir         base_type(rOld),
333cdf0e10cSrcweir         x(this->maIter1.x,this->maIter2.x),
334cdf0e10cSrcweir         y(this->maIter1.y,this->maIter2.y)
335cdf0e10cSrcweir     {}
336cdf0e10cSrcweir 
operator =(const CompositeIterator2D & rNew)337cdf0e10cSrcweir     CompositeIterator2D& operator=( const CompositeIterator2D& rNew )
338cdf0e10cSrcweir     {
339cdf0e10cSrcweir         this->maIter1 = rNew.maIter1;
340cdf0e10cSrcweir         this->maIter2 = rNew.maIter2;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir         x = MoveX(this->maIter1.x,
343cdf0e10cSrcweir                   this->maIter2.x);
344cdf0e10cSrcweir         y = MoveY(this->maIter1.y,
345cdf0e10cSrcweir                   this->maIter2.y);
346cdf0e10cSrcweir     }
347cdf0e10cSrcweir 
rowIterator() const348cdf0e10cSrcweir     row_iterator rowIterator() const
349cdf0e10cSrcweir     {
350cdf0e10cSrcweir         return row_iterator(this->maIter1.rowIterator(),
351cdf0e10cSrcweir                             this->maIter2.rowIterator());
352cdf0e10cSrcweir     }
353cdf0e10cSrcweir 
columnIterator() const354cdf0e10cSrcweir     column_iterator columnIterator() const
355cdf0e10cSrcweir     {
356cdf0e10cSrcweir         return column_iterator(this->maIter1.columnIterator(),
357cdf0e10cSrcweir                                this->maIter2.columnIterator());
358cdf0e10cSrcweir     }
359cdf0e10cSrcweir };
360cdf0e10cSrcweir 
361cdf0e10cSrcweir } // namespace basebmp
362cdf0e10cSrcweir 
363cdf0e10cSrcweir #endif /* INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX */
364