FunctorAccessor.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
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             // never reached, but here to silence compiler
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             // just to silence the compiler warning. this is
00369             // never reached, since vigra_fail will always
00370             // throw an exception.
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             // just to silence the compiler warning. this is
00387             // never reached, since vigra_fail will always
00388             // throw an exception.
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     //    typedef image_type1 value_type;
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         // get pixels at current position indicated by iterator
00488         image_type1 & v1 = a1_(i);
00489         image_type2 & v2 = a2_(i2_, i - i1_);
00490         // TODO: check if the size of both images is correct
00491 
00492         // copy into first image
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         // copy rest into second image
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 }  // namespace
00622 
00623 
00624 
00625 #endif // _FUNCTORACCESSOR_H

Generated on 26 Oct 2014 for Hugintrunk by  doxygen 1.4.7