[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

accessor.hxx
1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 #ifndef VIGRA_ACCESSOR_HXX
37 #define VIGRA_ACCESSOR_HXX
38 
39 #include "metaprogramming.hxx"
40 #include "numerictraits.hxx"
41 #include "tuple.hxx"
42 
43 namespace vigra {
44 
45 /** \addtogroup DataAccessors Data Accessors
46 
47  Basic templates to encapsulate access to the data of an iterator.
48 
49  Data accessors are used to allow for flexible access to the data
50  an iterator points to. When we access the data directly, we
51  are bound to what <TT>operator*()</TT> returns, if this method exists at
52  all. Encapsulating access in an accessor enables a better
53  decoupling of data structures and algorithms.
54  <a href="http://hci.iwr.uni-heidelberg.de/vigra/doc/vigra/documents/DataAccessors.ps">This paper</a> contains
55  a detailed description of the concept. Here is a brief list of the basic
56  accessor requirements:
57 <p>
58 <table border=2 cellspacing=0 cellpadding=2 width="100%">
59 <tr><th>
60  Operation
61  </th><th>
62  Result
63  </th><th>
64  Semantics
65  </th>
66 </tr>
67 <tr>
68  <td><tt>accessor(iter)</tt></td><td>convertible to <br><tt>Iterator::value_type const &</tt></td>
69  <td>read data at the current position of the iterator</td>
70 </tr>
71 <tr>
72  <td><tt>accessor(iter, index)</tt></td><td>convertible to <br><tt>Accessor::value_type const &</tt></td>
73  <td>read data at offset <tt>index</tt> relative to iterator's current position
74  (random-access iterator only)</td>
75 </tr>
76 <tr>
77  <td><tt>accessor.set(value, iter)</tt></td><td><tt>void</tt></td>
78  <td>write data <tt>value</tt> at the current position of the iterator (mutable iterator only)</td>
79 </tr>
80 <tr>
81  <td><tt>accessor.set(value, iter, index)</tt></td><td><tt>void</tt></td>
82  <td>write data <tt>value</tt> at offset <tt>index</tt> relative to iterator's current position
83  (mutable random-access iterator only)</td>
84 </tr>
85 <tr><td colspan=2>
86  <tt>Accessor::value_type</tt></td>
87  <td>type of the data field the accessor refers to</td>
88 </tr>
89 <tr><td colspan=3>
90  <tt>iter</tt> is an iterator<br>
91  <tt>index</tt> has the iterator's index type (<tt>Iterator::difference_type</tt>)<br>
92  <tt>value</tt> is convertible to <tt>Accessor::value_type const &</tt>
93  </td>
94 </tr>
95 </table>
96 </p>
97 
98  The template <tt>AccessorTraits<T></tt> can be used to find the default accessor
99  associated with the type <tt>T</tt>, e.g.
100 
101  \code
102  typedef typename AccessorTraits<typename Image::value_type>::default_accessor Accessor;
103  typedef typename AccessorTraits<typename Image::value_type>::default_const_accessor ConstAccessor;
104  \endcode
105 */
106 //@{
107 
108 /********************************************************/
109 /* */
110 /* StandardAccessor */
111 /* */
112 /********************************************************/
113 
114 /** \brief Encapsulate access to the values an iterator points to.
115 
116  StandardAccessor is a trivial accessor that simply encapsulates
117  the iterator's operator*() and operator[]() in its
118  read and write functions. It passes its arguments <em>by reference</em>.
119  If you want to return items by value, you
120  must use StandardValueAccessor instead of StandardAccessor.
121  Both accessors have different optimization properties --
122  StandardAccessor is usually faster for compound pixel types,
123  while StandardValueAccessor is faster for the built-in types.
124 
125  When a floating point number is assigned by means of an accessor
126  with integral value_type, the value is rounded and clipped as approriate.
127 
128  <b>\#include</b> <<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>><br>
129  Namespace: vigra
130 */
131 template <class VALUETYPE>
133 {
134  public:
135  /** the value_type
136  */
137  typedef VALUETYPE value_type;
138 
139  /** read the current data item
140  */
141  template <class ITERATOR>
142  VALUETYPE const & operator()(ITERATOR const & i) const { return *i; }
143 
144  VALUETYPE const & operator()(VALUETYPE const * i) const { return *i; }
145 
146  /** read the data item at an offset (can be 1D or 2D or higher order difference).
147  */
148  template <class ITERATOR, class DIFFERENCE>
149  VALUETYPE const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
150  {
151  return i[diff];
152  }
153 
154  /** Write the current data item. The type <TT>V</TT> of the passed
155  in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
156  In case of a conversion floating point -> intergral this includes rounding and clipping.
157  */
158  template <class V, class ITERATOR>
159  void set(V const & value, ITERATOR const & i) const
160  { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
161 
162  /* This overload is needed to make the accessor work with a std::back_inserter */
163  template <class V, class ITERATOR>
164  void set(V const & value, ITERATOR & i) const
165  { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
166 
167  /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
168  The type <TT>V</TT> of the passed
169  in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
170  In case of a conversion floating point -> intergral this includes rounding and clipping.
171  */
172  template <class V, class ITERATOR, class DIFFERENCE>
173  void set(V const & value, ITERATOR const & i, DIFFERENCE const & diff) const
174  {
175  i[diff]= detail::RequiresExplicitCast<VALUETYPE>::cast(value);
176  }
177 };
178 
179 /** \brief Encapsulate access to the values an iterator points to.
180 
181  StandardValueAccessor is a trivial accessor that simply encapsulates
182  the iterator's operator*() and operator[]() in its
183  read and write functions. It passes its arguments <em>by value</em>.
184  If the iterator returns its items by reference (such as \ref vigra::ImageIterator),
185  you can also use StandardAccessor.
186  These accessors have different optimization properties --
187  StandardAccessor is usually faster for compound pixel types,
188  while StandardValueAccessor is faster for the built-in types.
189 
190  When a floating point number is assigned by means of an accessor
191  with integral value_type, the value is rounded and clipped as approriate.
192 
193  <b>\#include</b> <<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>><br>
194  Namespace: vigra
195 */
196 template <class VALUETYPE>
198 {
199  public:
200  /** the value_type
201  */
202  typedef VALUETYPE value_type;
203 
204  /** Read the current data item. The type <TT>ITERATOR::reference</TT>
205  is automatically converted to <TT>VALUETYPE</TT>.
206  In case of a conversion floating point -> intergral this includes rounding and clipping.
207  */
208  template <class ITERATOR>
209  VALUETYPE operator()(ITERATOR const & i) const
210  { return detail::RequiresExplicitCast<VALUETYPE>::cast(*i); }
211 
212  /** Read the data item at an offset (can be 1D or 2D or higher order difference).
213  The type <TT>ITERATOR::index_reference</TT>
214  is automatically converted to <TT>VALUETYPE</TT>.
215  In case of a conversion floating point -> intergral this includes rounding and clipping.
216  */
217  template <class ITERATOR, class DIFFERENCE>
218  VALUETYPE operator()(ITERATOR const & i, DIFFERENCE const & diff) const
219  {
220  return detail::RequiresExplicitCast<VALUETYPE>::cast(i[diff]);
221  }
222  /** Write the current data item. The type <TT>V</TT> of the passed
223  in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
224  In case of a conversion floating point -> intergral this includes rounding and clipping.
225  */
226  template <class V, class ITERATOR>
227  void set(V value, ITERATOR const & i) const
228  { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
229 
230  /* This overload is needed to make the accessor work with a std::back_inserter */
231  template <class V, class ITERATOR>
232  void set(V value, ITERATOR & i) const
233  { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
234 
235  /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
236  The type <TT>V</TT> of the passed
237  in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
238  In case of a conversion floating point -> intergral this includes rounding and clipping.
239  */
240  template <class V, class ITERATOR, class DIFFERENCE>
241  void set(V value, ITERATOR const & i, DIFFERENCE const & diff) const
242  {
243  i[diff]= detail::RequiresExplicitCast<VALUETYPE>::cast(value);
244  }
245 };
246 
247 /********************************************************/
248 /* */
249 /* StandardConstAccessor */
250 /* */
251 /********************************************************/
252 
253 /** \brief Encapsulate read access to the values an iterator points to.
254 
255  StandardConstAccessor is a trivial accessor that simply encapsulates
256  the iterator's operator*() and operator[]() in its
257  read functions. It passes its arguments <em>by reference</em>.
258  If the iterator returns its items by value (such as \ref vigra::CoordinateIterator), you
259  must use StandardConstValueAccessor instead of StandardConstAccessor.
260  Both accessors also have different optimization properties --
261  StandardConstAccessor is usually faster for compound pixel types,
262  while StandardConstValueAccessor is faster for the built-in types.
263 
264  <b>\#include</b> <<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>><br>
265  Namespace: vigra
266 */
267 template <class VALUETYPE>
269 {
270  public:
271  typedef VALUETYPE value_type;
272 
273  /** read the current data item
274  */
275  template <class ITERATOR>
276  VALUETYPE const & operator()(ITERATOR const & i) const
277  { return *i; }
278 
279  /** read the data item at an offset (can be 1D or 2D or higher order difference).
280  */
281  template <class ITERATOR, class DIFFERENCE>
282  VALUETYPE const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
283  {
284  return i[diff];
285  }
286 };
287 
288 /** \brief Encapsulate access to the values an iterator points to.
289 
290  StandardConstValueAccessor is a trivial accessor that simply encapsulates
291  the iterator's operator*() and operator[]() in its
292  read functions. It passes its arguments <em>by value</em>.
293  If the iterator returns its items by reference (such as \ref vigra::ConstImageIterator),
294  you can also use StandardConstAccessor.
295  These accessors have different optimization properties --
296  StandardConstAccessor is usually faster for compound pixel types,
297  while StandardConstValueAccessor is faster for the built-in types.
298 
299  When an iterator passes a floating point number to an accessor
300  with integral value_type, the value is rounded and clipped as approriate.
301 
302  <b>\#include</b> <<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>><br>
303  Namespace: vigra
304 */
305 template <class VALUETYPE>
307 {
308  public:
309  typedef VALUETYPE value_type;
310 
311  /** Read the current data item. The type <TT>ITERATOR::reference</TT>
312  is automatically converted to <TT>VALUETYPE</TT>.
313  In case of a conversion floating point -> intergral this includes rounding and clipping.
314  */
315  template <class ITERATOR>
316  VALUETYPE operator()(ITERATOR const & i) const
317  { return detail::RequiresExplicitCast<VALUETYPE>::cast(*i); }
318 
319  /** Read the data item at an offset (can be 1D or 2D or higher order difference).
320  The type <TT>ITERATOR::index_reference</TT>
321  is automatically converted to <TT>VALUETYPE</TT>.
322  In case of a conversion floating point -> intergral this includes rounding and clipping.
323  */
324  template <class ITERATOR, class DIFFERENCE>
325  VALUETYPE operator()(ITERATOR const & i, DIFFERENCE const & diff) const
326  {
327  return detail::RequiresExplicitCast<VALUETYPE>::cast(i[diff]);
328  }
329 };
330 
331 /********************************************************/
332 /* */
333 /* VectorComponentAccessor */
334 /* */
335 /********************************************************/
336 
337 /** \brief Accessor for one component of a vector.
338 
339  This accessor allows to select a single component (a single 'band')
340  of a vector valued pixel type. The pixel type must support
341  <TT>operator[]</TT>. The index of the component to be selected
342  is passed in the constructor. The accessor returns its items
343  <em>by reference</em>. If you want to pass/return items by value,
344  use VectorComponentValueAccessor. If a floating point number
345  is assigned by means of an accessor with integral value_type, the
346  value is rounded and clipped as appropriate.
347 
348  <b>Usage:</b>
349 
350  \code
351  vigra::BRGBImage image(w,h);
352 
353  // init red channel with 255
354  initImage(destImageRange(image,
355  VectorComponentAccessor<vigra::BRGBImage::value_type>(0)),
356  255);
357  \endcode
358 
359  <b>\#include</b> <<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>><br>
360  Namespace: vigra
361 
362 */
363 template <class VECTORTYPE>
365 {
366  int index_;
367  public:
368  /** the value_type
369  */
370  typedef typename VECTORTYPE::value_type value_type;
371 
372  /** determine the component to be accessed
373  */
375  : index_(index)
376  {}
377 
378  /** read the current data item
379  */
380  template <class ITERATOR>
381  value_type const & operator()(ITERATOR const & i) const
382  { return (*i)[index_]; }
383 
384  /** read the data item at an offset (can be 1D or 2D or higher order difference).
385  */
386  template <class ITERATOR, class DIFFERENCE>
387  value_type const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
388  {
389  return i[diff][index_];
390  }
391 
392  /** Write the current data item. The type <TT>V</TT> of the passed
393  in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
394  In case of a conversion floating point -> intergral this includes rounding and clipping.
395  */
396  template <class V, class ITERATOR>
397  void set(V const & value, ITERATOR const & i) const
398  {
399  (*i)[index_] = detail::RequiresExplicitCast<value_type>::cast(value);
400  }
401 
402  /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
403  The type <TT>V</TT> of the passed
404  in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
405  In case of a conversion floating point -> intergral this includes rounding and clipping.
406  */
407  template <class V, class ITERATOR, class DIFFERENCE>
408  void set(V const & value, ITERATOR const & i, DIFFERENCE const & diff) const
409  {
410  i[diff][index_]= detail::RequiresExplicitCast<value_type>::cast(value);
411  }
412 
413  /** Reset the index to the given number.
414  */
415  void setIndex(int i)
416  {
417  index_ = i;
418  }
419 };
420 
421 /** \brief Accessor for one component of a vector.
422 
423  This accessor allows to select a single component (a single 'band')
424  of a vector valued pixel type. The pixel type must support
425  <TT>operator[]</TT>. The index of the component to be selected
426  is passed in the constructor. The accessor returns its items
427  <em>by value</em>. If you want to pass/return items by reference,
428  use VectorComponentAccessor. If a floating point number
429  is assigned by means of an accessor with integral value_type, the
430  value is rounded and clipped as appropriate.
431 
432  <b>Usage:</b>
433 
434  \code
435  vigra::BRGBImage image(w,h);
436 
437  // init red channel with 255
438  initImage(destImageRange(image,
439  VectorComponentValueAccessor<vigra::BRGBImage::value_type>(0)),
440  255);
441  \endcode
442 
443  <b>\#include</b> <<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>><br>
444  Namespace: vigra
445 
446 */
447 template <class VECTORTYPE>
449 {
450  int index_;
451  public:
452  /** the value_type
453  */
454  typedef typename VECTORTYPE::value_type value_type;
455 
456  /** determine the component to be accessed
457  */
459  : index_(index)
460  {}
461 
462  /** Read the current data item.
463  The type <TT>ITERATOR::index_reference::value_type</TT>
464  is automatically converted to <TT>value_type</TT>.
465  In case of a conversion floating point -> intergral this includes rounding and clipping.
466  */
467  template <class ITERATOR>
468  value_type operator()(ITERATOR const & i) const
469  { return detail::RequiresExplicitCast<value_type>::cast((*i)[index_]); }
470 
471  /** Read the data item at an offset (can be 1D or 2D or higher order difference).
472  The type <TT>ITERATOR::index_reference::value_type</TT>
473  is automatically converted to <TT>value_type</TT>.
474  In case of a conversion floating point -> intergral this includes rounding and clipping.
475  */
476  template <class ITERATOR, class DIFFERENCE>
477  value_type operator()(ITERATOR const & i, DIFFERENCE const & diff) const
478  {
479  return detail::RequiresExplicitCast<value_type>::cast(i[diff][index_]);
480  }
481 
482  /** Write the current data item. The type <TT>V</TT> of the passed
483  in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
484  In case of a conversion floating point -> intergral this includes rounding and clipping.
485  */
486  template <class V, class ITERATOR>
487  void set(V value, ITERATOR const & i) const
488  {
489  (*i)[index_] = detail::RequiresExplicitCast<value_type>::cast(value);
490  }
491 
492  /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
493  The type <TT>V</TT> of the passed
494  in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
495  In case of a conversion floating point -> intergral this includes rounding and clipping.
496  */
497  template <class V, class ITERATOR, class DIFFERENCE>
498  void set(V value, ITERATOR const & i, DIFFERENCE const & diff) const
499  {
500  i[diff][index_]= detail::RequiresExplicitCast<value_type>::cast(value);
501  }
502 
503  /** Reset the index to the given number.
504  */
505  void setIndex(int i)
506  {
507  index_ = i;
508  }
509 };
510 
511 /********************************************************/
512 /* */
513 /* VectorElementAccessor */
514 /* */
515 /********************************************************/
516 
517 /** \brief Accessor for one component of a vector.
518 
519  This works like VectorComponentAccessor, only the template paramters differ:
520  Here, we need a vector accessor type , wheras VectorComponentAccessor requires a vector type.
521 
522  <b>Usage:</b>
523 
524  \code
525  vigra::BRGBImage image(w,h);
526 
527  // init red channel with 255
528  initImage(destImageRange(image,
529  VectorElementAccessor<vigra::BRGBImage::Accessor>(0)),
530  255);
531  \endcode
532 
533  <b>\#include</b> <<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>><br>
534  Namespace: vigra
535 
536 */
537 template <class ACCESSOR>
539 {
540  int index_;
541  ACCESSOR a_;
542  public:
543  /** the value_type
544  */
545  typedef typename ACCESSOR::component_type value_type;
546 
547  /** determine the component to be accessed
548  */
549  VectorElementAccessor(int index, ACCESSOR a = ACCESSOR())
550  : index_(index),
551  a_(a)
552  {}
553 
554  /** read the current data item
555  */
556  template <class ITERATOR>
557  value_type const & operator()(ITERATOR const & i) const
558  { return a_.getComponent(i, index_); }
559 
560  /** read the data item at an offset (can be 1D or 2D or higher order difference).
561  */
562  template <class ITERATOR, class DIFFERENCE>
563  value_type const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
564  {
565  return a_.getComponent(i, diff, index_);
566  }
567 
568  /** Write the current data item. The type <TT>V</TT> of the passed
569  in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
570  In case of a conversion floating point -> intergral this includes rounding and clipping.
571  */
572  template <class V, class ITERATOR>
573  void set(V const & value, ITERATOR const & i) const
574  {
575  a_.setComponent(detail::RequiresExplicitCast<value_type>::cast(value), i, index_);
576  }
577 
578  /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
579  The type <TT>V</TT> of the passed
580  in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
581  In case of a conversion floating point -> intergral this includes rounding and clipping.
582  */
583  template <class V, class ITERATOR, class DIFFERENCE>
584  void set(V const & value, ITERATOR const & i, DIFFERENCE const & diff) const
585  {
586  a_.setComponent(detail::RequiresExplicitCast<value_type>::cast(value), i, diff, index_);
587  }
588 
589  /** Reset the index to the given number.
590  */
591  void setIndex(int i)
592  {
593  index_ = i;
594  }
595 };
596 
597 /********************************************************/
598 /* */
599 /* SequenceAccessor */
600 /* */
601 /********************************************************/
602 
603 /** \brief Accessor for items that are STL compatible sequences.
604 
605  It encapsulates access to the sequences' begin() and end()
606  functions.
607 
608  <b>Usage:</b>
609 
610  <b>\#include</b> <<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>><br>
611  Namespace: vigra
612 
613  \code
614  typedef std::list<std::list<int> > ListOfLists;
615 
616  ListOfLists ll;
617  ...
618 
619  typedef vigra::SequenceAccessor<ListOfLists::value_type> ListOfListsAccessor;
620  ListOfListsAccessor a;
621  for(ListOfLists::iterator li = ll.begin(); li != ll.end(); ++li)
622  {
623  for(ListOfListsAccessor::iterator i = a.begin(li); i != a.end(li); ++i)
624  {
625  *i = 10;
626  }
627  }
628  \endcode
629 */
630 template <class SEQUENCE>
632 : public StandardAccessor<SEQUENCE>
633 {
634  public:
635  /** the sequence's value_type
636  */
637  typedef typename SEQUENCE::value_type component_type;
638 
639 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
640  typedef typename
641  If<typename TypeTraits<SEQUENCE>::isConst,
642  typename SEQUENCE::const_iterator,
643  typename SEQUENCE::iterator>::type
644  iterator;
645 #else
646  /** the sequence's iterator type
647  */
648  typedef typename SEQUENCE::iterator iterator;
649 #endif
650 
651  /** get begin iterator for sequence at given iterator position
652  */
653  template <class ITERATOR>
654  iterator begin(ITERATOR const & i) const
655  {
656  return (*i).begin();
657  }
658 
659  /** get end iterator for sequence at given iterator position
660  */
661  template <class ITERATOR>
662  iterator end(ITERATOR const & i) const
663  {
664  return (*i).end();
665  }
666 
667  /** get begin iterator for sequence at an offset
668  of given iterator position
669  */
670  template <class ITERATOR, class DIFFERENCE>
671  iterator begin(ITERATOR const & i, DIFFERENCE const & diff) const
672  {
673  return i[diff].begin();
674  }
675 
676  /** get end iterator for sequence at a 2D difference vector
677  of given iterator position
678  */
679  template <class ITERATOR, class DIFFERENCE>
680  iterator end(ITERATOR const & i, DIFFERENCE const & diff) const
681  {
682  return i[diff].end();
683  }
684 
685  /** get size of sequence at given iterator position
686  */
687  template <class ITERATOR>
688  unsigned int size(ITERATOR const & i) const { return (*i).size(); }
689 
690  /** get size of sequence at 2D difference vector of given iterator position
691  */
692  template <class ITERATOR, class DIFFERENCE>
693  unsigned int size(ITERATOR const & i, DIFFERENCE const & diff) const
694  { return i[diff].size(); }
695 };
696 
697 /********************************************************/
698 /* */
699 /* VectorAccessor */
700 /* */
701 /********************************************************/
702 
703 /** \brief Accessor for items that are STL compatible vectors.
704 
705  It encapsulates access to a vector's access functionality.
706 
707  <b> Usage:</b>
708 
709  <b>\#include</b> <<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>><br>
710  Namespace: vigra
711 
712  The accessor has two modes of operation:
713 
714  <ol>
715  <li> Access the vector's iterator via the <TT>begin()</TT> and <TT>end()</TT>
716  functions:
717 
718  \code
719  typedef std::list<std::vector<int> > ListOfVectors;
720 
721  ListOfVectors ll;
722  ...
723 
724  typedef vigra::SequenceAccessor<ListOfVectors::value_type> ListOfVectorsAccessor;
725  ListOfVectorsAccessor a;
726  for(ListOfVectors::iterator li = ll.begin(); li != ll.end(); ++li)
727  {
728  for(ListOfVectorsAccessor::iterator i = a.begin(li); i != a.end(li); ++i)
729  {
730  *i = 10;
731  }
732  }
733  \endcode
734  <li> Access the vector's components via an index (internally calls
735  the vector's <TT>operator[]</TT> ):
736  \code
737  typedef std::list<std::vector<int> > ListOfVectors;
738 
739  ListOfVectors ll;
740  ...
741 
742  typedef vigra::SequenceAccessor<ListOfVectors::value_type> ListOfVectorsAccessor;
743  ListOfVectorsAccessor a;
744  for(ListOfVectors::iterator li = ll.begin(); li != ll.end(); ++li)
745  {
746  for(int i = 0; i != a.size(li); ++i)
747  {
748  a.setComponent(10, li, i);
749  }
750  }
751  \endcode
752  </ol>
753 
754  <b> Required Interface:</b>
755 
756  \code
757  VECTOR v;
758  VECTOR::iterator i;
759  value_type d;
760  int index;
761 
762  d = v[index];
763  v[index] = d;
764  i = v.begin();
765  i = v.end();
766  v.size();
767  \endcode
768 */
769 template <class VECTOR>
771 : public SequenceAccessor<VECTOR>
772 {
773  public:
774  /** the vector's value_type
775  */
776  typedef typename VECTOR::value_type component_type;
777 
778  /** the vector element accessor associated with this vector accessor
779  (see \ref VectorElementAccessor)
780  */
782 
783  /** Read the component data at given vector index
784  at given iterator position
785  */
786  template <class ITERATOR>
787  component_type const & getComponent(ITERATOR const & i, int idx) const
788  {
789  return (*i)[idx];
790  }
791 
792  /** Set the component data at given vector index
793  at given iterator position. The type <TT>V</TT> of the passed
794  in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
795  In case of a conversion floating point -> intergral this includes rounding and clipping.
796  */
797  template <class V, class ITERATOR>
798  void setComponent(V const & value, ITERATOR const & i, int idx) const
799  {
800  (*i)[idx] = detail::RequiresExplicitCast<component_type>::cast(value);
801  }
802 
803  /** Read the component data at given vector index
804  at an offset of given iterator position
805  */
806  template <class ITERATOR, class DIFFERENCE>
807  component_type const & getComponent(ITERATOR const & i, DIFFERENCE const & diff, int idx) const
808  {
809  return i[diff][idx];
810  }
811 
812  /** Set the component data at given vector index
813  at an offset of given iterator position. The type <TT>V</TT> of the passed
814  in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
815  In case of a conversion floating point -> intergral this includes rounding and clipping.
816  */
817  template <class V, class ITERATOR, class DIFFERENCE>
818  void
819  setComponent(V const & value, ITERATOR const & i, DIFFERENCE const & diff, int idx) const
820  {
821  i[diff][idx] = detail::RequiresExplicitCast<component_type>::cast(value);
822  }
823 };
824 
825 
826 /********************************************************/
827 /* */
828 /* MultiImageAccessor2 */
829 /* */
830 /********************************************************/
831 
832 /** \brief Access two images simultaneously.
833 
834  This accessor is used when two images need to be treated as one
835  because an algorithm accepts only one image. For example,
836  \ref seededRegionGrowing() uses only one image two calculate
837  the cost for aggregating each pixel into a region. Somtimes, we
838  need more information to calcuate this cost, for example gray value
839  and local gradient magnitude. These values can be stored in two images,
840  which appear as only one when we pass a <TT>MultiImageAccessor2</TT> to
841  the lagorithms. Of course, the cost functor must accept a <TT>pair</TT>
842  of values for this to work. Instead of an actual image iterator, we
843  pass a <a href="CoordinateIterator.html">CoordinateIterator</a> which
844  selects the right pixels form both images.
845 
846  <b> Usage:</b>
847 
848  <b>\#include</b> <<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>><br>
849  Namespace: vigra
850 
851  \code
852  using namespace vigra;
853 
854  FImage gray_values(w,h), gradient_magnitude(w,h);
855  IImage seeds(w,h), labels(w,h);
856 
857  seededRegionGrowing(
858  srcIterRange(CoordinateIterator(), CoordinateIterator(w,h),
859  MultiImageAccessor2<FImage::iterator, FImage::Accessor,
860  FImage::iterator, FImage::Accessor>
861  (gray_values.upperLeft(), gray_values.accessor(),
862  gradient_magnitude.upperLeft(), gradient_magnitude.accessor())),
863  srcImage(seeds),
864  destImage(labels),
865  SomeCostFunctor());
866  \endcode
867 */
868 
869 template <class Iter1, class Acc1, class Iter2, class Acc2>
871 {
872  public:
873  /** The accessors value_type: construct a pair that contains
874  the corresponding image values.
875  */
876  typedef pair<typename Acc1::value_type, typename Acc2::value_type>
878 
879  /** Construct from two image iterators and associated accessors.
880  */
881  MultiImageAccessor2(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
882  : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
883  {}
884 
885  /** read the current data item
886  */
887  template <class DIFFERENCE>
888  value_type operator()(DIFFERENCE const & d) const
889  {
890  return std::make_pair(a1_(i1_, d), a2_(i2_, d));
891  }
892 
893  /** read the data item at an offset
894  */
895  template <class DIFFERENCE1, class DIFFERENCE2>
896  value_type operator()(DIFFERENCE1 d1, DIFFERENCE2 const & d2) const
897  {
898  d1 += d2;
899  return std::make_pair(a1_(i1_, d1), a2_(i2_, d1));
900  }
901 
902  private:
903  Iter1 i1_;
904  Acc1 a1_;
905  Iter2 i2_;
906  Acc2 a2_;
907 };
908 
909 //@}
910 
911 template <class T>
912 struct AccessorTraits
913 {
914  typedef StandardAccessor<T> default_accessor;
915  typedef StandardConstAccessor<T> default_const_accessor;
916 };
917 
918 #define VIGRA_DEFINE_ACCESSOR_TRAITS(VALUE, ACCESSOR, CONST_ACCESSOR) \
919  template <> \
920  struct AccessorTraits<VALUE > \
921  { \
922  typedef ACCESSOR<VALUE > default_accessor; \
923  typedef CONST_ACCESSOR<VALUE > default_const_accessor; \
924  };
925 
926 VIGRA_DEFINE_ACCESSOR_TRAITS(signed char, StandardValueAccessor, StandardConstValueAccessor)
927 VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned char, StandardValueAccessor, StandardConstValueAccessor)
928 VIGRA_DEFINE_ACCESSOR_TRAITS(short, StandardValueAccessor, StandardConstValueAccessor)
929 VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned short, StandardValueAccessor, StandardConstValueAccessor)
930 VIGRA_DEFINE_ACCESSOR_TRAITS(int, StandardValueAccessor, StandardConstValueAccessor)
931 VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned int, StandardValueAccessor, StandardConstValueAccessor)
932 VIGRA_DEFINE_ACCESSOR_TRAITS(long, StandardValueAccessor, StandardConstValueAccessor)
933 VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned long, StandardValueAccessor, StandardConstValueAccessor)
934 VIGRA_DEFINE_ACCESSOR_TRAITS(float, StandardValueAccessor, StandardConstValueAccessor)
935 VIGRA_DEFINE_ACCESSOR_TRAITS(double, StandardValueAccessor, StandardConstValueAccessor)
936 
937 template <class T, unsigned int RED_IDX, unsigned int GREEN_IDX, unsigned int BLUE_IDX> class RGBValue;
938 template <class T> class RGBAccessor;
939 template <class T, int SIZE> class TinyVector;
940 
941 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
942 
943 template <class T, unsigned int RED_IDX, unsigned int GREEN_IDX, unsigned int BLUE_IDX>
944 struct AccessorTraits<RGBValue<T, RED_IDX, GREEN_IDX, BLUE_IDX> >
945 {
946  typedef RGBAccessor<RGBValue<T, RED_IDX, GREEN_IDX, BLUE_IDX> > default_accessor;
947  typedef RGBAccessor<RGBValue<T, RED_IDX, GREEN_IDX, BLUE_IDX> > default_const_accessor;
948 };
949 
950 template <class T, int SIZE>
951 struct AccessorTraits<TinyVector<T, SIZE> >
952 {
953  typedef VectorAccessor<TinyVector<T, SIZE> > default_accessor;
954  typedef VectorAccessor<TinyVector<T, SIZE> > default_const_accessor;
955 };
956 
957 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
958 
959 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned char>, RGBAccessor, RGBAccessor)
960 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<signed char>, RGBAccessor, RGBAccessor)
961 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<short>, RGBAccessor, RGBAccessor)
962 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned short>, RGBAccessor, RGBAccessor)
963 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<int>, RGBAccessor, RGBAccessor)
964 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned int>, RGBAccessor, RGBAccessor)
965 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<long>, RGBAccessor, RGBAccessor)
966 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned long>, RGBAccessor, RGBAccessor)
967 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<float>, RGBAccessor, RGBAccessor)
968 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<double>, RGBAccessor, RGBAccessor)
969 
970 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
971 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
972 #undef VIGRA_PIXELTYPE
973 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
974 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
975 #undef VIGRA_PIXELTYPE
976 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
977 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
978 #undef VIGRA_PIXELTYPE
979 #define VIGRA_PIXELTYPE TinyVector<short, 2>
980 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
981 #undef VIGRA_PIXELTYPE
982 #define VIGRA_PIXELTYPE TinyVector<short, 3>
983 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
984 #undef VIGRA_PIXELTYPE
985 #define VIGRA_PIXELTYPE TinyVector<short, 4>
986 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
987 #undef VIGRA_PIXELTYPE
988 #define VIGRA_PIXELTYPE TinyVector<int, 2>
989 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
990 #undef VIGRA_PIXELTYPE
991 #define VIGRA_PIXELTYPE TinyVector<int, 3>
992 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
993 #undef VIGRA_PIXELTYPE
994 #define VIGRA_PIXELTYPE TinyVector<int, 4>
995 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
996 #undef VIGRA_PIXELTYPE
997 #define VIGRA_PIXELTYPE TinyVector<float, 2>
998 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
999 #undef VIGRA_PIXELTYPE
1000 #define VIGRA_PIXELTYPE TinyVector<float, 3>
1001 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
1002 #undef VIGRA_PIXELTYPE
1003 #define VIGRA_PIXELTYPE TinyVector<float, 4>
1004 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
1005 #undef VIGRA_PIXELTYPE
1006 #define VIGRA_PIXELTYPE TinyVector<double, 2>
1007 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
1008 #undef VIGRA_PIXELTYPE
1009 #define VIGRA_PIXELTYPE TinyVector<double, 3>
1010 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
1011 #undef VIGRA_PIXELTYPE
1012 #define VIGRA_PIXELTYPE TinyVector<double, 4>
1013 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
1014 #undef VIGRA_PIXELTYPE
1015 
1016 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1017 
1018 #undef VIGRA_DEFINE_ACCESSOR_TRAITS
1019 
1020 } // namespace vigra
1021 
1022 #endif // VIGRA_ACCESSOR_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.7.1 (Wed Mar 12 2014)