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