Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FunctorAccessor.h
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
24 #ifndef _FUNCTORACCESSOR_H
25 #define _FUNCTORACCESSOR_H
26 
27 #include <vigra/numerictraits.hxx>
28 
29 namespace vigra_ext {
30 
31 
40 template <class Functor, class Accessor>
42 {
43  public:
44  typedef typename Functor::result_type value_type;
45  ReadFunctorAccessor(Functor f, Accessor a)
46  : m_f(f), m_a(a)
47  {
48  }
49 
57  template <typename ITERATOR_, typename DIFFERENCE_>
58  typename Functor::result_type operator()(ITERATOR_ const & i, DIFFERENCE_ d) const
59  {
60  return m_f(m_a(i,d));
61  }
62 
65  template <class ITERATOR>
66  typename Functor::result_type operator()(ITERATOR const & i) const {
67  return m_f(m_a(i)); }
68 
69 
70 protected:
71  Functor m_f;
72  Accessor m_a;
73 };
74 
83 template <class Functor, class Accessor, class ValueType>
85 {
86 public:
87 
88  typedef ValueType value_type;
89 
90  WriteFunctorAccessor(Functor f, Accessor a)
91  : m_f(f), m_a(a)
92  {
93  }
94 
97  template <class Value, class ITERATOR>
98  void set(Value const & v, ITERATOR const & i) const
99  {
100  m_a.set(m_f(v), i);
101  }
102 
105  template <class Value, class ITERATOR_, class DIFFERENCE_>
106  void set(Value const & v, ITERATOR_ const & i, DIFFERENCE_ d) const
107  {
108  m_a.set(m_f(v),i,d);
109  }
110 
111  Functor m_f;
112  Accessor m_a;
113 };
114 
115 
116 
145 template <class Iter1, class Acc1, class Iter2, class Acc2>
147 {
148 public:
151  typedef vigra::TinyVector<typename Acc1::value_type, 2> value_type;
152  typedef typename value_type::value_type component_type;
153 
156  SplitVector2Accessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
157  : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
158  {}
159 
161  template <class V, class ITERATOR>
162  void setComponent( V const & value, ITERATOR const & i, int idx ) const
163  {
164  switch (idx) {
165  case 0:
166  a1_.set(value, i1_, *i);
167  break;
168  case 1:
169  a2_.set(value, i2_, *i);
170  break;
171  default:
172  vigra_fail("too many components in input value");
173  }
174  }
175 
177  template <class ITERATOR>
178  unsigned int size(ITERATOR const & i) const
179  {
180  return 2;
181  }
182 
183  Iter1 i1_;
184  Acc1 a1_;
185  Iter2 i2_;
186  Acc2 a2_;
187 };
188 
199 template <class Iter1, class Acc1, class Iter2, class Acc2, int SIZE>
201 {
202 public:
205  typedef vigra::TinyVector<typename Acc1::value_type, SIZE> value_type;
206  typedef typename value_type::value_type component_type;
207 
210  SplitVectorNAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
211  : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
212  {}
213 
215  template <class V, class ITERATOR>
216  void setComponent( V const & value, ITERATOR const & i, int idx ) const
217  {
218  if ( idx < SIZE - 1 ) {
219  a1_.setComponent(value, i1_, *i, idx);
220  } else if ( idx == SIZE - 1 ) {
221  a2_.set(value, i2_, *i);
222  } else {
223  vigra_fail("too many components in input value");
224  }
225  }
226 
228  template <class ITERATOR>
229  unsigned int size(ITERATOR const & i) const
230  {
231  return SIZE;
232  }
233 
234  Iter1 i1_;
235  Acc1 a1_;
236  Iter2 i2_;
237  Acc2 a2_;
238 };
239 
245 template <class Iter1, class Acc1, class Iter2, class Acc2>
247 {
248 public:
251  typedef vigra::TinyVector<typename Acc1::value_type, 2> value_type;
252  typedef typename value_type::value_type component_type;
253 
256  MergeScalarScalar2VectorAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
257  : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
258  {}
259 
262  template <class DIFFERENCE_>
263  value_type operator()(DIFFERENCE_ const & d) const
264  {
265  return value_type(a1_(i1_, d), a2_(i2_, d));
266  }
267 
269  template <class ITERATOR>
270  component_type getComponent(ITERATOR const & i, int idx) const
271  {
272  switch (idx) {
273  case 0:
274  return a1_( i1_, *i );
275  case 1:
276  return a2_( i2_, *i );
277  default:
278  vigra_fail("too many components in input value");
279  // never reached, but here to silence compiler
280  exit(1);
281  }
282  }
283 
285  template <class ITERATOR, class DIFFERENCE_>
286  component_type const & getComponent(ITERATOR const & i, DIFFERENCE_ const & d, int idx) const
287  {
288  i += d;
289  switch (idx) {
290  case 0:
291  return a1_.getComponent(i1_, *i, idx);
292  case 1:
293  return a2_.getComponent(i2_, *i, idx);
294  default:
295  vigra_fail("too many components in input value");
296  }
297  }
298 
300  template <class ITERATOR>
301  unsigned int size(ITERATOR const & i) const
302  {
303  return 2;
304  }
305 
306  Iter1 i1_;
307  Acc1 a1_;
308  Iter2 i2_;
309  Acc2 a2_;
310 };
311 
312 
321 template <class Iter1, class Acc1, class Iter2, class Acc2, int SIZE>
323 {
324 public:
327  typedef typename Acc1::value_type image1_type;
328  typedef typename Acc2::value_type image2_type;
329 
330  typedef typename image1_type::value_type component_type;
331 
332  typedef vigra::TinyVector<component_type, SIZE> value_type;
333 
336  MergeVectorScalar2VectorAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
337  : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
338  {}
339 
342  template <class DIFFERENCE_>
343  value_type operator()(DIFFERENCE_ const & d) const
344  {
345  value_type ret;
346  typename value_type::iterator it = ret.begin();
347  const image1_type & i1 = a1_(i1_, d);
348  for ( typename image1_type::const_iterator it1 = i1.begin();
349  it1 != i1.end(); ++it1 )
350  {
351  *it = *it1;
352  it++;
353  }
354  *it = a2_(i2_, d);
355  return ret;
356  }
357 
359  template <class ITERATOR>
360  component_type getComponent(ITERATOR const & i, int idx) const
361  {
362  if ( idx < SIZE - 1 ) {
363  return a1_.getComponent(i1_, *i, idx);
364  } else if ( idx == SIZE - 1 ) {
365  return a2_(i2_, *i);
366  } else {
367  vigra_fail("too many components in input value");
368  // just to silence the compiler warning. this is
369  // never reached, since vigra_fail will always
370  // throw an exception.
371  throw 0;
372  }
373  }
374 
376  template <class ITERATOR, class DIFFERENCE_>
377  component_type const getComponent(ITERATOR i, DIFFERENCE_ const & d, int idx) const
378  {
379  i += d;
380  if ( idx < SIZE - 1 ) {
381  return a1_.getComponent(i1_, *i, idx);
382  } else if ( idx == SIZE - 1 ) {
383  return a2_(i2_, *i);
384  } else {
385  vigra_fail("too many components in input value");
386  // just to silence the compiler warning. this is
387  // never reached, since vigra_fail will always
388  // throw an exception.
389  throw 0;
390  }
391  }
392 
393 
395  template <class ITERATOR>
396  unsigned int size(ITERATOR const & i) const
397  {
398  return SIZE;
399  }
400 
401  Iter1 i1_;
402  Acc1 a1_;
403  Iter2 i2_;
404  Acc2 a2_;
405 };
406 
407 
440 template <class Iter1, class Acc1, class Iter2, class Acc2, int SIZE>
442 {
443 public:
445  typedef typename Acc1::value_type image_type1;
446 
448  typedef typename Acc2::value_type image_type2;
449 
451  // typedef image_type1 value_type;
452 
455  ImageSplittingAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
456  : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
457  {}
458 
465  template <class V, class ITERATOR>
466  void setComponent(V const & value, ITERATOR const & i, int idx) const
467  {
468  setComponentIsScalar(value, i, idx,
469  vigra::NumericTraits<image_type1>::isScalar() );
470  }
471 
472 
473 #if 0
474 
484  template <class V, class ITERATOR>
485  void setVector2VectorVector(V const & value, ITERATOR const & i) const
486  {
487  // get pixels at current position indicated by iterator
488  image_type1 & v1 = a1_(i);
489  image_type2 & v2 = a2_(i2_, i - i1_);
490  // TODO: check if the size of both images is correct
491 
492  // copy into first image
493  typename V::iterator vIt = value.begin();
494  typename image_type1::iterator v1It = v1.begin();
495  while ( v1It != v1.end() && vIt != value.end()) {
496  *v1It = detail::RequiresExplicitCast<VALUETYPE>::cast(*vIt);
497  ++v1It;
498  ++vIt;
499  }
500  // copy rest into second image
501  typename image_type2::iterator v2It = v2.begin();
502  while ( v2It != v1.end() && vIt != value.end()) {
503  *v2It = detail::RequiresExplicitCast<VALUETYPE>::cast(*vIt);
504  ++v2It;
505  ++vIt;
506  }
507 
508 
509 
510  for (int i=0; i < value.size(); i++) {
511  if (i <
512 
513  *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
514 
520  template <class V, class ITERATOR, class DIFFERENCE_>
521  void set(V const & value, ITERATOR const & i, DIFFERENCE_ const & diff) const
522  {
523  i[diff]= detail::RequiresExplicitCast<VALUETYPE>::cast(value);
524  }
525 
526 #endif
527 
528 protected:
530  template <class V, class ITERATOR>
531  void setComponentIsScalar(V const & value, ITERATOR const & i, int idx,
532  vigra::VigraTrueType) const
533  {
534  setComponentScalarIsScalar(value, i, idx,
535  vigra::NumericTraits<image_type2>::isScalar() );
536  }
537 
539  template <class V, class ITERATOR>
540  void setComponentIsScalar(V const & value, ITERATOR const & i, int idx,
541  vigra::VigraFalseType) const
542  {
543  setComponentVectorIsScalar(value, i, idx,
544  vigra::NumericTraits<image_type2>::isScalar() );
545  }
546 
548  template <class V, class ITERATOR>
549  void setComponentScalarIsScalar(V const & value, ITERATOR const & i, int idx,
550  vigra::VigraTrueType) const
551  {
552  switch (idx) {
553  case 0:
554  a1_.set(value, i);
555  break;
556  case 1:
557  a2_.set(value, i2_, i - i1_);
558  break;
559  default:
560  vigra_fail("too many components in input value");
561  }
562  }
563 
565  template <class V, class ITERATOR>
566  void setComponentScalarIsVector(V const & value, ITERATOR const & i, int idx,
567  vigra::VigraTrueType) const
568  {
569  vigra_fail("vector -> scalar, vector accessor not implemented");
570  }
571 
573  template <class V, class ITERATOR>
574  void setComponentVectorIsScalar(V const & value, ITERATOR const & i, int idx,
575  vigra::VigraTrueType) const
576  {
577  image_type1 & v1 = a1_(i);
578  typename image_type1::size_type s1 = v1.size();
579  if (idx < s1) {
580  a1_.setComponent(value, i, idx);
581  } else if ( idx == s1) {
582  a2_.set(value, i2_, i - i1_);
583  } else {
584  vigra_fail("too many components in input value");
585  }
586  }
587 
589  template <class V, class ITERATOR>
590  void setComponentVectorIsVector(V const & value, ITERATOR const & i, int idx,
591  vigra::VigraTrueType) const
592  {
593  vigra_fail("vector -> vector, vector accessor not implemented");
594  }
595 
596  Iter1 i1_;
597  Acc1 a1_;
598  Iter2 i2_;
599  Acc2 a2_;
600 };
601 
603 template <class T>
604 struct Multiply
605 {
606  typedef T result_type;
607 
608  Multiply(T factor)
609  : m_factor(factor)
610  {}
611 
612  template <class PixelType>
613  PixelType operator()(PixelType const& v) const
614  {
615  return vigra::NumericTraits<result_type>::fromRealPromote(v * m_factor);
616  }
617 
619 };
620 
621 } // namespace
622 
623 
624 
625 #endif // _FUNCTORACCESSOR_H
void setComponentScalarIsVector(V const &value, ITERATOR const &i, int idx, vigra::VigraTrueType) const
if scalar &amp; vector image
component_type getComponent(ITERATOR const &i, int idx) const
read one component
Functor::result_type operator()(ITERATOR_ const &i, DIFFERENCE_ d) const
Get functor result template &lt;class A, class B&gt; void function(A a, B b) { };
vigra::TinyVector< typename Acc1::value_type, SIZE > value_type
the vector&#39;s value_type
vigra::TinyVector< typename Acc1::value_type, 2 > value_type
the vector&#39;s value_type
MergeScalarScalar2VectorAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
Construct from two image iterators and associated accessors.
merge two scalar images into a vector image.
unsigned int size(ITERATOR const &i) const
return the size (Number of Bands)
component_type const getComponent(ITERATOR i, DIFFERENCE_ const &d, int idx) const
read one component, with offset
void setComponentScalarIsScalar(V const &value, ITERATOR const &i, int idx, vigra::VigraTrueType) const
if scalar &amp; scalar image
Acc1::value_type image_type1
value type of image 1
void setComponent(V const &value, ITERATOR const &i, int idx) const
vector &amp; scalar image
This class can be used to apply a function when writing to an image.
unsigned int size(ITERATOR const &i) const
return the size (Number of Bands)
MergeVectorScalar2VectorAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
Construct from two image iterators and associated accessors.
merge a vector and a scalar image into a vector image.
void setComponentVectorIsVector(V const &value, ITERATOR const &i, int idx, vigra::VigraTrueType) const
if vector &amp; vector image
void setComponentIsScalar(V const &value, ITERATOR const &i, int idx, vigra::VigraFalseType) const
if first dest image is vector image
PixelType operator()(PixelType const &v) const
void set(Value const &v, ITERATOR_ const &i, DIFFERENCE_ d) const
Set functor result.
define a write only accessor for a virtual Image&lt;TinyVector&lt;Acc1::value_type&gt;, 2&gt; image...
vigra::TinyVector< typename Acc1::value_type, 2 > value_type
the vector&#39;s value_type
component_type getComponent(ITERATOR const &i, int idx) const
read one component
value_type::value_type component_type
void setComponentVectorIsScalar(V const &value, ITERATOR const &i, int idx, vigra::VigraTrueType) const
if vector &amp; scalar image
value_type operator()(DIFFERENCE_ const &d) const
read the current data item
split a vector image into a vector and a scalar image
SplitVectorNAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
Construct from two image iterators and associated accessors.
unsigned int size(ITERATOR const &i) const
return the size (Number of Bands)
component_type const & getComponent(ITERATOR const &i, DIFFERENCE_ const &d, int idx) const
read one component, with offset
unsigned int size(ITERATOR const &i) const
return the size (Number of Bands)
Acc2::value_type image_type2
value type of image 2
ImageSplittingAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
Construct from two image iterators and associated accessors.
This class can be used to apply a function when reading the input image.
An accessor to encapsulate write access to a multiband image, and move divide it into two images...
void setComponent(V const &value, ITERATOR const &i, int idx) const
write value V into the two images.
Acc1::value_type image1_type
the vector&#39;s value_type
ReadFunctorAccessor(Functor f, Accessor a)
Functor::result_type value_type
value_type::value_type component_type
value_type operator()(DIFFERENCE_ const &d) const
read the current data item
WriteFunctorAccessor(Functor f, Accessor a)
SplitVector2Accessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
Construct from two image iterators and associated accessors.
vigra::TinyVector< component_type, SIZE > value_type
Functor::result_type operator()(ITERATOR const &i) const
Get functor result.
void set(Value const &v, ITERATOR const &i) const
Set functor result.
void setComponent(V const &value, ITERATOR const &i, int idx) const
scalar &amp; scalar image
void setComponentIsScalar(V const &value, ITERATOR const &i, int idx, vigra::VigraTrueType) const
if first dest image is scalar
a sample functor that can be used to multiply pixel values with a constant