00001
00024 #ifndef _FUNCTORACCESSOR_H
00025 #define _FUNCTORACCESSOR_H
00026
00027 #include <vigra/numerictraits.hxx>
00028
00029 namespace vigra_ext {
00030
00031
00040 template <class Functor, class Accessor>
00041 class ReadFunctorAccessor
00042 {
00043 public:
00044 typedef typename Functor::result_type value_type;
00045 ReadFunctorAccessor(Functor f, Accessor a)
00046 : m_f(f), m_a(a)
00047 {
00048 }
00049
00057 template <typename ITERATOR_, typename DIFFERENCE_>
00058 typename Functor::result_type operator()(ITERATOR_ const & i, DIFFERENCE_ d) const
00059 {
00060 return m_f(m_a(i,d));
00061 }
00062
00065 template <class ITERATOR>
00066 typename Functor::result_type operator()(ITERATOR const & i) const {
00067 return m_f(m_a(i)); }
00068
00069
00070 protected:
00071 Functor m_f;
00072 Accessor m_a;
00073 };
00074
00083 template <class Functor, class Accessor, class ValueType>
00084 class WriteFunctorAccessor
00085 {
00086 public:
00087
00088 typedef ValueType value_type;
00089
00090 WriteFunctorAccessor(Functor f, Accessor a)
00091 : m_f(f), m_a(a)
00092 {
00093 }
00094
00097 template <class Value, class ITERATOR>
00098 void set(Value const & v, ITERATOR const & i) const
00099 {
00100 m_a.set(m_f(v), i);
00101 }
00102
00105 template <class Value, class ITERATOR_, class DIFFERENCE_>
00106 void set(Value const & v, ITERATOR_ const & i, DIFFERENCE_ d) const
00107 {
00108 m_a.set(m_f(v),i,d);
00109 }
00110
00111 Functor m_f;
00112 Accessor m_a;
00113 };
00114
00115
00116
00145 template <class Iter1, class Acc1, class Iter2, class Acc2>
00146 class SplitVector2Accessor
00147 {
00148 public:
00151 typedef vigra::TinyVector<typename Acc1::value_type, 2> value_type;
00152 typedef typename value_type::value_type component_type;
00153
00156 SplitVector2Accessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
00157 : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
00158 {}
00159
00161 template <class V, class ITERATOR>
00162 void setComponent( V const & value, ITERATOR const & i, int idx ) const
00163 {
00164 switch (idx) {
00165 case 0:
00166 a1_.set(value, i1_, *i);
00167 break;
00168 case 1:
00169 a2_.set(value, i2_, *i);
00170 break;
00171 default:
00172 vigra_fail("too many components in input value");
00173 }
00174 }
00175
00177 template <class ITERATOR>
00178 unsigned int size(ITERATOR const & i) const
00179 {
00180 return 2;
00181 }
00182
00183 Iter1 i1_;
00184 Acc1 a1_;
00185 Iter2 i2_;
00186 Acc2 a2_;
00187 };
00188
00199 template <class Iter1, class Acc1, class Iter2, class Acc2, int SIZE>
00200 class SplitVectorNAccessor
00201 {
00202 public:
00205 typedef vigra::TinyVector<typename Acc1::value_type, SIZE> value_type;
00206 typedef typename value_type::value_type component_type;
00207
00210 SplitVectorNAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
00211 : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
00212 {}
00213
00215 template <class V, class ITERATOR>
00216 void setComponent( V const & value, ITERATOR const & i, int idx ) const
00217 {
00218 if ( idx < SIZE - 1 ) {
00219 a1_.setComponent(value, i1_, *i, idx);
00220 } else if ( idx == SIZE - 1 ) {
00221 a2_.set(value, i2_, *i);
00222 } else {
00223 vigra_fail("too many components in input value");
00224 }
00225 }
00226
00228 template <class ITERATOR>
00229 unsigned int size(ITERATOR const & i) const
00230 {
00231 return SIZE;
00232 }
00233
00234 Iter1 i1_;
00235 Acc1 a1_;
00236 Iter2 i2_;
00237 Acc2 a2_;
00238 };
00239
00245 template <class Iter1, class Acc1, class Iter2, class Acc2>
00246 class MergeScalarScalar2VectorAccessor
00247 {
00248 public:
00251 typedef vigra::TinyVector<typename Acc1::value_type, 2> value_type;
00252 typedef typename value_type::value_type component_type;
00253
00256 MergeScalarScalar2VectorAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
00257 : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
00258 {}
00259
00262 template <class DIFFERENCE_>
00263 value_type operator()(DIFFERENCE_ const & d) const
00264 {
00265 return value_type(a1_(i1_, d), a2_(i2_, d));
00266 }
00267
00269 template <class ITERATOR>
00270 component_type getComponent(ITERATOR const & i, int idx) const
00271 {
00272 switch (idx) {
00273 case 0:
00274 return a1_( i1_, *i );
00275 case 1:
00276 return a2_( i2_, *i );
00277 default:
00278 vigra_fail("too many components in input value");
00279
00280 exit(1);
00281 }
00282 }
00283
00285 template <class ITERATOR, class DIFFERENCE_>
00286 component_type const & getComponent(ITERATOR const & i, DIFFERENCE_ const & d, int idx) const
00287 {
00288 i += d;
00289 switch (idx) {
00290 case 0:
00291 return a1_.getComponent(i1_, *i, idx);
00292 case 1:
00293 return a2_.getComponent(i2_, *i, idx);
00294 default:
00295 vigra_fail("too many components in input value");
00296 }
00297 }
00298
00300 template <class ITERATOR>
00301 unsigned int size(ITERATOR const & i) const
00302 {
00303 return 2;
00304 }
00305
00306 Iter1 i1_;
00307 Acc1 a1_;
00308 Iter2 i2_;
00309 Acc2 a2_;
00310 };
00311
00312
00321 template <class Iter1, class Acc1, class Iter2, class Acc2, int SIZE>
00322 class MergeVectorScalar2VectorAccessor
00323 {
00324 public:
00327 typedef typename Acc1::value_type image1_type;
00328 typedef typename Acc2::value_type image2_type;
00329
00330 typedef typename image1_type::value_type component_type;
00331
00332 typedef vigra::TinyVector<component_type, SIZE> value_type;
00333
00336 MergeVectorScalar2VectorAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
00337 : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
00338 {}
00339
00342 template <class DIFFERENCE_>
00343 value_type operator()(DIFFERENCE_ const & d) const
00344 {
00345 value_type ret;
00346 typename value_type::iterator it = ret.begin();
00347 const image1_type & i1 = a1_(i1_, d);
00348 for ( typename image1_type::const_iterator it1 = i1.begin();
00349 it1 != i1.end(); ++it1 )
00350 {
00351 *it = *it1;
00352 it++;
00353 }
00354 *it = a2_(i2_, d);
00355 return ret;
00356 }
00357
00359 template <class ITERATOR>
00360 component_type getComponent(ITERATOR const & i, int idx) const
00361 {
00362 if ( idx < SIZE - 1 ) {
00363 return a1_.getComponent(i1_, *i, idx);
00364 } else if ( idx == SIZE - 1 ) {
00365 return a2_(i2_, *i);
00366 } else {
00367 vigra_fail("too many components in input value");
00368
00369
00370
00371 throw 0;
00372 }
00373 }
00374
00376 template <class ITERATOR, class DIFFERENCE_>
00377 component_type const getComponent(ITERATOR i, DIFFERENCE_ const & d, int idx) const
00378 {
00379 i += d;
00380 if ( idx < SIZE - 1 ) {
00381 return a1_.getComponent(i1_, *i, idx);
00382 } else if ( idx == SIZE - 1 ) {
00383 return a2_(i2_, *i);
00384 } else {
00385 vigra_fail("too many components in input value");
00386
00387
00388
00389 throw 0;
00390 }
00391 }
00392
00393
00395 template <class ITERATOR>
00396 unsigned int size(ITERATOR const & i) const
00397 {
00398 return SIZE;
00399 }
00400
00401 Iter1 i1_;
00402 Acc1 a1_;
00403 Iter2 i2_;
00404 Acc2 a2_;
00405 };
00406
00407
00440 template <class Iter1, class Acc1, class Iter2, class Acc2, int SIZE>
00441 class ImageSplittingAccessor
00442 {
00443 public:
00445 typedef typename Acc1::value_type image_type1;
00446
00448 typedef typename Acc2::value_type image_type2;
00449
00451
00452
00455 ImageSplittingAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
00456 : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
00457 {}
00458
00465 template <class V, class ITERATOR>
00466 void setComponent(V const & value, ITERATOR const & i, int idx) const
00467 {
00468 setComponentIsScalar(value, i, idx,
00469 vigra::NumericTraits<image_type1>::isScalar() );
00470 }
00471
00472
00473 #if 0
00474
00484 template <class V, class ITERATOR>
00485 void setVector2VectorVector(V const & value, ITERATOR const & i) const
00486 {
00487
00488 image_type1 & v1 = a1_(i);
00489 image_type2 & v2 = a2_(i2_, i - i1_);
00490
00491
00492
00493 typename V::iterator vIt = value.begin();
00494 typename image_type1::iterator v1It = v1.begin();
00495 while ( v1It != v1.end() && vIt != value.end()) {
00496 *v1It = detail::RequiresExplicitCast<VALUETYPE>::cast(*vIt);
00497 ++v1It;
00498 ++vIt;
00499 }
00500
00501 typename image_type2::iterator v2It = v2.begin();
00502 while ( v2It != v1.end() && vIt != value.end()) {
00503 *v2It = detail::RequiresExplicitCast<VALUETYPE>::cast(*vIt);
00504 ++v2It;
00505 ++vIt;
00506 }
00507
00508
00509
00510 for (int i=0; i < value.size(); i++) {
00511 if (i <
00512
00513 *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
00514
00520 template <class V, class ITERATOR, class DIFFERENCE_>
00521 void set(V const & value, ITERATOR const & i, DIFFERENCE_ const & diff) const
00522 {
00523 i[diff]= detail::RequiresExplicitCast<VALUETYPE>::cast(value);
00524 }
00525
00526 #endif
00527
00528 protected:
00530 template <class V, class ITERATOR>
00531 void setComponentIsScalar(V const & value, ITERATOR const & i, int idx,
00532 vigra::VigraTrueType) const
00533 {
00534 setComponentScalarIsScalar(value, i, idx,
00535 vigra::NumericTraits<image_type2>::isScalar() );
00536 }
00537
00539 template <class V, class ITERATOR>
00540 void setComponentIsScalar(V const & value, ITERATOR const & i, int idx,
00541 vigra::VigraFalseType) const
00542 {
00543 setComponentVectorIsScalar(value, i, idx,
00544 vigra::NumericTraits<image_type2>::isScalar() );
00545 }
00546
00548 template <class V, class ITERATOR>
00549 void setComponentScalarIsScalar(V const & value, ITERATOR const & i, int idx,
00550 vigra::VigraTrueType) const
00551 {
00552 switch (idx) {
00553 case 0:
00554 a1_.set(value, i);
00555 break;
00556 case 1:
00557 a2_.set(value, i2_, i - i1_);
00558 break;
00559 default:
00560 vigra_fail("too many components in input value");
00561 }
00562 }
00563
00565 template <class V, class ITERATOR>
00566 void setComponentScalarIsVector(V const & value, ITERATOR const & i, int idx,
00567 vigra::VigraTrueType) const
00568 {
00569 vigra_fail("vector -> scalar, vector accessor not implemented");
00570 }
00571
00573 template <class V, class ITERATOR>
00574 void setComponentVectorIsScalar(V const & value, ITERATOR const & i, int idx,
00575 vigra::VigraTrueType) const
00576 {
00577 image_type1 & v1 = a1_(i);
00578 typename image_type1::size_type s1 = v1.size();
00579 if (idx < s1) {
00580 a1_.setComponent(value, i, idx);
00581 } else if ( idx == s1) {
00582 a2_.set(value, i2_, i - i1_);
00583 } else {
00584 vigra_fail("too many components in input value");
00585 }
00586 }
00587
00589 template <class V, class ITERATOR>
00590 void setComponentVectorIsVector(V const & value, ITERATOR const & i, int idx,
00591 vigra::VigraTrueType) const
00592 {
00593 vigra_fail("vector -> vector, vector accessor not implemented");
00594 }
00595
00596 Iter1 i1_;
00597 Acc1 a1_;
00598 Iter2 i2_;
00599 Acc2 a2_;
00600 };
00601
00603 template <class T>
00604 struct Multiply
00605 {
00606 typedef T result_type;
00607
00608 Multiply(T factor)
00609 : m_factor(factor)
00610 {}
00611
00612 template <class PixelType>
00613 PixelType operator()(PixelType const& v) const
00614 {
00615 return vigra::NumericTraits<result_type>::fromRealPromote(v * m_factor);
00616 }
00617
00618 T m_factor;
00619 };
00620
00621 }
00622
00623
00624
00625 #endif // _FUNCTORACCESSOR_H