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

details vigra/accessor.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
00005 /*                                                                      */
00006 /*    This file is part of the VIGRA computer vision library.           */
00007 /*    ( Version 1.3.3, Aug 18 2005 )                                    */
00008 /*    You may use, modify, and distribute this software according       */
00009 /*    to the terms stated in the LICENSE file included in               */
00010 /*    the VIGRA distribution.                                           */
00011 /*                                                                      */
00012 /*    The VIGRA Website is                                              */
00013 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
00014 /*    Please direct questions, bug reports, and contributions to        */
00015 /*        koethe@informatik.uni-hamburg.de                              */
00016 /*                                                                      */
00017 /*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
00018 /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
00019 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
00020 /*                                                                      */
00021 /************************************************************************/
00022 
00023 #ifndef VIGRA_ACCESSOR_HXX
00024 #define VIGRA_ACCESSOR_HXX
00025 
00026 #include "vigra/metaprogramming.hxx"
00027 #include "vigra/numerictraits.hxx"
00028 #include "vigra/tuple.hxx"
00029 
00030 namespace vigra {
00031 
00032 /** \addtogroup DataAccessors Data Accessors
00033 
00034     Basic templates to encapsulate access to the data of an iterator.
00035 
00036     Data accessors are used to allow for flexible access to the data
00037     an interator points to. When we access the data directly, we
00038     are bound to what <TT>operator*()</TT> returns, if this method exists at
00039     all. Encapsulating access in an accessor enables a better
00040     decoupling of data structures and algorithms.
00041     <a href="documents/DataAccessors.ps">This paper</a> contains
00042     a detailed description of the concept. Here is a brief list of the basic
00043     accessor requirements:
00044 <p>
00045 <table border=2 cellspacing=0 cellpadding=2 width="100%">
00046 <tr><td>
00047     \htmlonly
00048     <th>
00049     \endhtmlonly
00050     Operation
00051     \htmlonly
00052     </th><th>
00053     \endhtmlonly
00054     Result
00055     \htmlonly
00056     </th><th>
00057     \endhtmlonly
00058     Semantics
00059     \htmlonly
00060     </th>
00061     \endhtmlonly
00062 </td></tr>
00063 <tr>
00064     <td><tt>accessor(iter)</tt></td><td>convertible to <br><tt>Iterator::value_type const &</tt></td>
00065     <td>read data at the current position of the iterator</td>
00066 </tr>
00067 <tr>
00068     <td><tt>accessor(iter, index)</tt></td><td>convertible to <br><tt>Accessor::value_type const &</tt></td>
00069     <td>read data at offset <tt>index</tt> relative to iterator's current position
00070     (random-access iterator only)</td>
00071 </tr>
00072 <tr>
00073     <td><tt>accessor.set(value, iter)</tt></td><td><tt>void</tt></td>
00074     <td>write data <tt>value</tt> at the current position of the iterator (mutable iterator only)</td>
00075 </tr>
00076 <tr>
00077     <td><tt>accessor.set(value, iter, index)</tt></td><td><tt>void</tt></td>
00078     <td>write data <tt>value</tt> at offset <tt>index</tt> relative to iterator's current position
00079     (mutable random-access iterator only)</td>
00080 </tr>
00081 <tr>
00082     <td>
00083     \htmlonly
00084     <td colspan=2>
00085     \endhtmlonly
00086     <tt>Accessor::value_type</tt></td>
00087     <td>type of the data field the accessor refers to</td>
00088 </tr>
00089 <tr>
00090     <td>
00091     \htmlonly
00092     <td colspan=3>
00093     \endhtmlonly
00094         <tt>iter</tt> is an iterator<br>
00095         <tt>index</tt> has the iterator's index type (<tt>Iterator::difference_type</tt>)<br>
00096         <tt>value</tt> is convertible to <tt>Accessor::value_type const &</tt>
00097     </td>
00098 </tr>
00099 </table>
00100 </p>
00101 
00102     The template <tt>AccessorTraits&lt;T&gt;</tt> can be used to find the default accessor
00103     associated with the type <tt>T</tt>, e.g.
00104     
00105     \code
00106     typedef typename AccessorTraits<typename Image::value_type>::default_accessor       Accessor;
00107     typedef typename AccessorTraits<typename Image::value_type>::default_const_accessor ConstAccessor;
00108     \endcode
00109 */
00110 //@{
00111 
00112 /********************************************************/
00113 /*                                                      */
00114 /*                     StandardAccessor                 */
00115 /*                                                      */
00116 /********************************************************/
00117 
00118 /** \brief Encapsulate access to the values an iterator points to.
00119 
00120     StandardAccessor is a trivial accessor that simply encapsulates
00121     the iterator's operator*() and operator[]() in its
00122     read and write functions. It passes its arguments <em>by reference</em>.
00123     If you want to return items by value, you
00124     must use StandardValueAccessor instead of StandardAccessor.
00125     Both accessors have different optimization properties --
00126     StandardAccessor is usually faster for compound pixel types,
00127     while StandardValueAccessor is faster for the built-in types.
00128 
00129     When a floating point number is assigned by means of an accessor
00130     with integral value_type, the value is rounded and clipped as approriate.
00131 
00132     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"<br>
00133     Namespace: vigra
00134 */
00135 template <class VALUETYPE>
00136 class StandardAccessor
00137 {
00138   public:
00139         /** the value_type
00140         */
00141     typedef VALUETYPE value_type;
00142 
00143         /** read the current data item
00144         */
00145     template <class ITERATOR>
00146     VALUETYPE const & operator()(ITERATOR const & i) const { return *i; }
00147 
00148     VALUETYPE const & operator()(VALUETYPE const * i) const { return *i; }
00149 
00150         /** read the data item at an offset (can be 1D or 2D or higher order difference).
00151         */
00152     template <class ITERATOR, class DIFFERENCE>
00153     VALUETYPE const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
00154     {
00155         return i[diff];
00156     }
00157 
00158         /** Write the current data item. The type <TT>V</TT> of the passed
00159             in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
00160             In case of a conversion floating point -> intergral this includes rounding and clipping.
00161         */
00162     template <class V, class ITERATOR>
00163     void set(V const & value, ITERATOR const & i) const
00164     { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
00165 
00166         /* This overload is needed to make the accessor work with a std::back_inserter */
00167     template <class V, class ITERATOR>
00168     void set(V const & value, ITERATOR & i) const
00169     { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
00170 
00171         /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
00172             The type <TT>V</TT> of the passed
00173             in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
00174             In case of a conversion floating point -> intergral this includes rounding and clipping.
00175         */
00176     template <class V, class ITERATOR, class DIFFERENCE>
00177     void set(V const & value, ITERATOR const & i, DIFFERENCE const & diff) const
00178     {
00179         i[diff]= detail::RequiresExplicitCast<VALUETYPE>::cast(value);
00180     }
00181 };
00182 
00183 /** \brief Encapsulate access to the values an iterator points to.
00184 
00185     StandardValueAccessor is a trivial accessor that simply encapsulates
00186     the iterator's operator*() and operator[]() in its
00187     read and write functions. It passes its arguments <em>by value</em>.
00188     If the iterator returns its items by reference (such as \ref vigra::ImageIterator),
00189     you can also use StandardAccessor.
00190     These accessors have different optimization properties --
00191     StandardAccessor is usually faster for compound pixel types,
00192     while StandardValueAccessor is faster for the built-in types.
00193 
00194     When a floating point number is assigned by means of an accessor
00195     with integral value_type, the value is rounded and clipped as approriate.
00196 
00197     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"<br>
00198     Namespace: vigra
00199 */
00200 template <class VALUETYPE>
00201 class StandardValueAccessor
00202 {
00203   public:
00204         /** the value_type
00205         */
00206     typedef VALUETYPE value_type;
00207 
00208         /** Read the current data item. The type <TT>ITERATOR::reference</TT>
00209             is automatically converted to <TT>VALUETYPE</TT>.
00210             In case of a conversion floating point -> intergral this includes rounding and clipping.
00211         */
00212     template <class ITERATOR>
00213     VALUETYPE operator()(ITERATOR const & i) const
00214         { return detail::RequiresExplicitCast<VALUETYPE>::cast(*i); }
00215 
00216         /** Read the data item at an offset (can be 1D or 2D or higher order difference).
00217             The type <TT>ITERATOR::index_reference</TT>
00218             is automatically converted to <TT>VALUETYPE</TT>.
00219             In case of a conversion floating point -> intergral this includes rounding and clipping.
00220         */
00221     template <class ITERATOR, class DIFFERENCE>
00222     VALUETYPE operator()(ITERATOR const & i, DIFFERENCE const & diff) const
00223     {
00224         return detail::RequiresExplicitCast<VALUETYPE>::cast(i[diff]);
00225     }
00226         /** Write the current data item. The type <TT>V</TT> of the passed
00227             in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
00228             In case of a conversion floating point -> intergral this includes rounding and clipping.
00229         */
00230     template <class V, class ITERATOR>
00231     void set(V value, ITERATOR const & i) const
00232         { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
00233 
00234         /* This overload is needed to make the accessor work with a std::back_inserter */
00235     template <class V, class ITERATOR>
00236     void set(V value, ITERATOR & i) const
00237         { *i = detail::RequiresExplicitCast<VALUETYPE>::cast(value); }
00238 
00239         /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
00240             The type <TT>V</TT> of the passed
00241             in <TT>value</TT> is automatically converted to <TT>VALUETYPE</TT>.
00242             In case of a conversion floating point -> intergral this includes rounding and clipping.
00243         */
00244     template <class V, class ITERATOR, class DIFFERENCE>
00245     void set(V value, ITERATOR const & i, DIFFERENCE const & diff) const
00246     {
00247         i[diff]= detail::RequiresExplicitCast<VALUETYPE>::cast(value);
00248     }
00249 };
00250 
00251 /********************************************************/
00252 /*                                                      */
00253 /*                StandardConstAccessor                 */
00254 /*                                                      */
00255 /********************************************************/
00256 
00257 /** \brief Encapsulate read access to the values an iterator points to.
00258 
00259     StandardConstAccessor is a trivial accessor that simply encapsulates
00260     the iterator's operator*() and operator[]() in its
00261     read functions. It passes its arguments <em>by reference</em>.
00262     If the iterator returns its items by value (such as \ref vigra::CoordinateIterator), you
00263     must use StandardConstValueAccessor instead of StandardConstAccessor.
00264     Both accessors also have different optimization properties --
00265     StandardConstAccessor is usually faster for compound pixel types,
00266     while StandardConstValueAccessor is faster for the built-in types.
00267 
00268     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"<br>
00269     Namespace: vigra
00270 */
00271 template <class VALUETYPE>
00272 class StandardConstAccessor
00273 {
00274   public:
00275     typedef VALUETYPE value_type;
00276 
00277         /** read the current data item
00278         */
00279     template <class ITERATOR>
00280     VALUETYPE const & operator()(ITERATOR const & i) const
00281         { return *i; }
00282 
00283         /** read the data item at an offset (can be 1D or 2D or higher order difference).
00284         */
00285     template <class ITERATOR, class DIFFERENCE>
00286     VALUETYPE const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
00287     {
00288         return i[diff];
00289     }
00290 };
00291 
00292 /** \brief Encapsulate access to the values an iterator points to.
00293 
00294     StandardConstValueAccessor is a trivial accessor that simply encapsulates
00295     the iterator's operator*() and operator[]() in its
00296     read functions. It passes its arguments <em>by value</em>.
00297     If the iterator returns its items by reference (such as \ref vigra::ConstImageIterator),
00298     you can also use StandardConstAccessor.
00299     These accessors have different optimization properties --
00300     StandardConstAccessor is usually faster for compound pixel types,
00301     while StandardConstValueAccessor is faster for the built-in types.
00302 
00303     When an iterator passes a floating point number to an accessor
00304     with integral value_type, the value is rounded and clipped as approriate.
00305 
00306     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"<br>
00307     Namespace: vigra
00308 */
00309 template <class VALUETYPE>
00310 class StandardConstValueAccessor
00311 {
00312   public:
00313     typedef VALUETYPE value_type;
00314 
00315         /** Read the current data item. The type <TT>ITERATOR::reference</TT>
00316             is automatically converted to <TT>VALUETYPE</TT>.
00317             In case of a conversion floating point -> intergral this includes rounding and clipping.
00318         */
00319     template <class ITERATOR>
00320     VALUETYPE operator()(ITERATOR const & i) const
00321         { return detail::RequiresExplicitCast<VALUETYPE>::cast(*i); }
00322 
00323         /** Read the data item at an offset (can be 1D or 2D or higher order difference).
00324             The type <TT>ITERATOR::index_reference</TT>
00325             is automatically converted to <TT>VALUETYPE</TT>.
00326             In case of a conversion floating point -> intergral this includes rounding and clipping.
00327         */
00328     template <class ITERATOR, class DIFFERENCE>
00329     VALUETYPE operator()(ITERATOR const & i, DIFFERENCE const & diff) const
00330     {
00331         return detail::RequiresExplicitCast<VALUETYPE>::cast(i[diff]);
00332     }
00333 };
00334 
00335 /********************************************************/
00336 /*                                                      */
00337 /*                 VectorComponentAccessor              */
00338 /*                                                      */
00339 /********************************************************/
00340 
00341 /** \brief Accessor for one component of a vector.
00342 
00343     This accessor allows to select a single component (a single 'band')
00344     of a vector valued pixel type. The pixel type must support
00345     <TT>operator[]</TT>. The index of the component to be selected
00346     is passed in the constructor. The accessor returns its items
00347     <em>by reference</em>. If you want to pass/return items by value,
00348     use VectorComponentValueAccessor. If a floating point number
00349     is assigned by means of an accessor with integral value_type, the
00350     value is rounded and clipped as appropriate.
00351 
00352     <b>Usage:</b>
00353 
00354     \code
00355     vigra::BRGBImage image(w,h);
00356 
00357     // init red channel with 255
00358     initImage(destImageRange(image,
00359                              VectorComponentAccessor<vigra::BRGBImage::value_type>(0)),
00360               255);
00361     \endcode
00362 
00363     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"<br>
00364     Namespace: vigra
00365 
00366 */
00367 template <class VECTORTYPE>
00368 class VectorComponentAccessor
00369 {
00370     int index_;
00371   public:
00372         /** the value_type
00373         */
00374     typedef typename VECTORTYPE::value_type value_type;
00375 
00376         /** determine the component to be accessed
00377         */
00378     VectorComponentAccessor(int index)
00379     : index_(index)
00380     {}
00381 
00382         /** read the current data item
00383         */
00384     template <class ITERATOR>
00385     value_type const & operator()(ITERATOR const & i) const
00386         { return (*i)[index_]; }
00387 
00388         /** read the data item at an offset (can be 1D or 2D or higher order difference).
00389         */
00390     template <class ITERATOR, class DIFFERENCE>
00391     value_type const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
00392     {
00393         return i[diff][index_];
00394     }
00395 
00396         /** Write the current data item. The type <TT>V</TT> of the passed
00397             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
00398             In case of a conversion floating point -> intergral this includes rounding and clipping.
00399         */
00400     template <class V, class ITERATOR>
00401     void set(V const & value, ITERATOR const & i) const
00402     {
00403         (*i)[index_] = detail::RequiresExplicitCast<value_type>::cast(value);
00404     }
00405 
00406         /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
00407             The type <TT>V</TT> of the passed
00408             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
00409             In case of a conversion floating point -> intergral this includes rounding and clipping.
00410         */
00411     template <class V, class ITERATOR, class DIFFERENCE>
00412     void set(V const & value, ITERATOR const & i, DIFFERENCE const & diff) const 
00413     { 
00414         i[diff][index_]= detail::RequiresExplicitCast<value_type>::cast(value); 
00415     }
00416     
00417         /** Reset the index to the given number.
00418         */
00419     void setIndex(int i)
00420     {
00421         index_ = i;
00422     }
00423 };
00424 
00425 /** \brief Accessor for one component of a vector.
00426 
00427     This accessor allows to select a single component (a single 'band')
00428     of a vector valued pixel type. The pixel type must support
00429     <TT>operator[]</TT>. The index of the component to be selected
00430     is passed in the constructor. The accessor returns its items
00431     <em>by value</em>. If you want to pass/return items by reference,
00432     use VectorComponentAccessor. If a floating point number
00433     is assigned by means of an accessor with integral value_type, the
00434     value is rounded and clipped as appropriate.
00435 
00436     <b>Usage:</b>
00437 
00438     \code
00439     vigra::BRGBImage image(w,h);
00440 
00441     // init red channel with 255
00442     initImage(destImageRange(image,
00443                              VectorComponentValueAccessor<vigra::BRGBImage::value_type>(0)),
00444               255);
00445     \endcode
00446 
00447     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"<br>
00448     Namespace: vigra
00449 
00450 */
00451 template <class VECTORTYPE>
00452 class VectorComponentValueAccessor
00453 {
00454     int index_;
00455   public:
00456         /** the value_type
00457         */
00458     typedef typename VECTORTYPE::value_type value_type;
00459 
00460         /** determine the component to be accessed
00461         */
00462     VectorComponentValueAccessor(int index)
00463     : index_(index)
00464     {}
00465 
00466         /** Read the current data item.
00467             The type <TT>ITERATOR::index_reference::value_type</TT>
00468             is automatically converted to <TT>value_type</TT>.
00469             In case of a conversion floating point -> intergral this includes rounding and clipping.
00470         */
00471     template <class ITERATOR>
00472     value_type operator()(ITERATOR const & i) const
00473         { return detail::RequiresExplicitCast<value_type>::cast((*i)[index_]); }
00474 
00475         /** Read the data item at an offset (can be 1D or 2D or higher order difference).
00476             The type <TT>ITERATOR::index_reference::value_type</TT>
00477             is automatically converted to <TT>value_type</TT>.
00478             In case of a conversion floating point -> intergral this includes rounding and clipping.
00479         */
00480     template <class ITERATOR, class DIFFERENCE>
00481     value_type operator()(ITERATOR const & i, DIFFERENCE const & diff) const
00482     { 
00483         return detail::RequiresExplicitCast<value_type>::cast(i[diff][index_]); 
00484     }
00485     
00486         /** Write the current data item. The type <TT>V</TT> of the passed
00487             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
00488             In case of a conversion floating point -> intergral this includes rounding and clipping.
00489         */
00490     template <class V, class ITERATOR>
00491     void set(V value, ITERATOR const & i) const 
00492     { 
00493         (*i)[index_] = detail::RequiresExplicitCast<value_type>::cast(value); 
00494     }
00495     
00496         /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
00497             The type <TT>V</TT> of the passed
00498             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
00499             In case of a conversion floating point -> intergral this includes rounding and clipping.
00500         */
00501     template <class V, class ITERATOR, class DIFFERENCE>
00502     void set(V value, ITERATOR const & i, DIFFERENCE const & diff) const 
00503     { 
00504         i[diff][index_]= detail::RequiresExplicitCast<value_type>::cast(value); 
00505     }
00506     
00507         /** Reset the index to the given number.
00508         */
00509     void setIndex(int i)
00510     {
00511         index_ = i;
00512     }
00513 };
00514 
00515 /********************************************************/
00516 /*                                                      */
00517 /*                   VectorElementAccessor              */
00518 /*                                                      */
00519 /********************************************************/
00520 
00521 /** \brief Accessor for one component of a vector.
00522 
00523     This works like VectorComponentAccessor, only the template paramters differ: 
00524     Here, we need a vector accessor type , wheras VectorComponentAccessor requires a vector type.
00525 
00526     <b>Usage:</b>
00527     
00528     \code
00529     vigra::BRGBImage image(w,h);
00530     
00531     // init red channel with 255
00532     initImage(destImageRange(image, 
00533                              VectorElementAccessor<vigra::BRGBImage::Accessor>(0)),
00534               255);
00535     \endcode
00536     
00537     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"<br>
00538     Namespace: vigra
00539     
00540 */
00541 template <class ACCESSOR>
00542 class VectorElementAccessor
00543 {
00544     int index_;
00545     ACCESSOR a_;
00546   public:
00547         /** the value_type
00548         */
00549     typedef typename ACCESSOR::component_type value_type;
00550     
00551         /** determine the component to be accessed
00552         */
00553     VectorElementAccessor(int index, ACCESSOR a = ACCESSOR())
00554     : index_(index),
00555       a_(a)
00556     {}
00557     
00558         /** read the current data item
00559         */
00560     template <class ITERATOR>
00561     value_type const & operator()(ITERATOR const & i) const 
00562         { return a_.getComponent(i, index_); }
00563     
00564         /** read the data item at an offset (can be 1D or 2D or higher order difference).
00565         */
00566     template <class ITERATOR, class DIFFERENCE>
00567     value_type const & operator()(ITERATOR const & i, DIFFERENCE const & diff) const
00568     { 
00569         return a_.getComponent(i, diff, index_); 
00570     }
00571     
00572         /** Write the current data item. The type <TT>V</TT> of the passed
00573             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
00574             In case of a conversion floating point -> intergral this includes rounding and clipping.
00575         */
00576     template <class V, class ITERATOR>
00577     void set(V const & value, ITERATOR const & i) const 
00578     { 
00579         a_.setComponent(detail::RequiresExplicitCast<value_type>::cast(value), i, index_); 
00580     }
00581 
00582         /** Write the data item at an offset (can be 1D or 2D or higher order difference)..
00583             The type <TT>V</TT> of the passed
00584             in <TT>value</TT> is automatically converted to <TT>value_type</TT>.
00585             In case of a conversion floating point -> intergral this includes rounding and clipping.
00586         */
00587     template <class V, class ITERATOR, class DIFFERENCE>
00588     void set(V const & value, ITERATOR const & i, DIFFERENCE const & diff) const 
00589     { 
00590        a_.setComponent(detail::RequiresExplicitCast<value_type>::cast(value), i, diff, index_); 
00591     }
00592     
00593         /** Reset the index to the given number.
00594         */
00595     void setIndex(int i)
00596     {
00597         index_ = i;
00598     }
00599 };
00600 
00601 /********************************************************/
00602 /*                                                      */
00603 /*                    SequenceAccessor                  */
00604 /*                                                      */
00605 /********************************************************/
00606 
00607 /** \brief Accessor for items that are STL compatible sequences.
00608 
00609     It encapsulates access to the sequences' begin() and end()
00610     functions.
00611 
00612     <b>Usage:</b>
00613 
00614     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"<br>
00615     Namespace: vigra
00616 
00617     \code
00618     typedef std::list<std::list<int> > ListOfLists;
00619 
00620     ListOfLists ll;
00621     ...
00622 
00623     typedef vigra::SequenceAccessor<ListOfLists::value_type> ListOfListsAccessor;
00624     ListOfListsAccessor a;
00625     for(ListOfLists::iterator li = ll.begin(); li != ll.end(); ++li)
00626     {
00627         for(ListOfListsAccessor::iterator i = a.begin(li); i != a.end(li); ++i)
00628         {
00629             *i = 10;
00630         }
00631     }
00632     \endcode
00633 */
00634 template <class SEQUENCE>
00635 class SequenceAccessor
00636 : public StandardAccessor<SEQUENCE>
00637 {
00638   public:
00639         /** the sequence's value_type
00640         */
00641     typedef typename SEQUENCE::value_type component_type;
00642 
00643 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
00644     typedef typename
00645             If<typename TypeTraits<SEQUENCE>::isConst,
00646                typename SEQUENCE::const_iterator,
00647                typename SEQUENCE::iterator>::type 
00648             iterator;
00649 #else
00650         /** the sequence's iterator type
00651         */
00652     typedef typename SEQUENCE::iterator iterator;
00653 #endif
00654 
00655         /** get begin iterator for sequence at given iterator position
00656         */
00657     template <class ITERATOR>
00658     iterator begin(ITERATOR const & i) const
00659     {
00660         return (*i).begin();
00661     }
00662 
00663         /** get end iterator for sequence at given iterator position
00664         */
00665     template <class ITERATOR>
00666     iterator end(ITERATOR const & i)  const
00667     {
00668          return (*i).end();
00669     }
00670 
00671         /** get begin iterator for sequence at an offset
00672             of given iterator position
00673         */
00674     template <class ITERATOR, class DIFFERENCE>
00675     iterator begin(ITERATOR const & i, DIFFERENCE const & diff)  const
00676     {
00677         return i[diff].begin();
00678     }
00679 
00680         /** get end iterator for sequence at a 2D difference vector
00681             of given iterator position
00682         */
00683     template <class ITERATOR, class DIFFERENCE>
00684     iterator end(ITERATOR const & i, DIFFERENCE const & diff)  const
00685     {
00686         return i[diff].end();
00687     }
00688 
00689         /** get size of sequence at given iterator position
00690         */
00691     template <class ITERATOR>
00692     unsigned int size(ITERATOR const & i) const { return (*i).size(); }
00693 
00694         /** get size of sequence at 2D difference vector of given iterator position
00695         */
00696     template <class ITERATOR, class DIFFERENCE>
00697     unsigned int size(ITERATOR const & i, DIFFERENCE const & diff) const
00698     { return i[diff].size(); }
00699 };
00700 
00701 /********************************************************/
00702 /*                                                      */
00703 /*                     VectorAccessor                   */
00704 /*                                                      */
00705 /********************************************************/
00706 
00707 /** \brief Accessor for items that are STL compatible vectors.
00708 
00709     It encapsulates access to a vector's access functionality.
00710 
00711     <b> Usage:</b>
00712 
00713     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"<br>
00714     Namespace: vigra
00715 
00716     The accessor has two modes of operation:
00717 
00718     <ol>
00719     <li> Access the vector's iterator via the <TT>begin()</TT> and <TT>end()</TT>
00720     functions:
00721 
00722     \code
00723     typedef std::list<std::vector<int> > ListOfVectors;
00724 
00725     ListOfVectors ll;
00726     ...
00727 
00728     typedef vigra::SequenceAccessor<ListOfVectors::value_type> ListOfVectorsAccessor;
00729     ListOfVectorsAccessor a;
00730     for(ListOfVectors::iterator li = ll.begin(); li != ll.end(); ++li)
00731     {
00732         for(ListOfVectorsAccessor::iterator i = a.begin(li); i != a.end(li); ++i)
00733         {
00734             *i = 10;
00735         }
00736     }
00737     \endcode
00738     <li> Access the vector's components via an index (internally calls
00739     the vector's <TT>operator[]</TT> ):
00740     \code
00741     typedef std::list<std::vector<int> > ListOfVectors;
00742 
00743     ListOfVectors ll;
00744     ...
00745 
00746     typedef vigra::SequenceAccessor<ListOfVectors::value_type> ListOfVectorsAccessor;
00747     ListOfVectorsAccessor a;
00748     for(ListOfVectors::iterator li = ll.begin(); li != ll.end(); ++li)
00749     {
00750         for(int i = 0; i != a.size(li); ++i)
00751         {
00752             a.setComponent(10, li, i);
00753         }
00754     }
00755     \endcode
00756     </ol>
00757 
00758     <b> Required Interface:</b>
00759 
00760     \code
00761     VECTOR v;
00762     VECTOR::iterator i;
00763     value_type d;
00764     int index;
00765 
00766     d = v[index];
00767     v[index] = d;
00768     i = v.begin();
00769     i = v.end();
00770     v.size();
00771     \endcode
00772 */
00773 template <class VECTOR>
00774 class VectorAccessor
00775 : public SequenceAccessor<VECTOR>
00776 {
00777   public:
00778         /** the vector's value_type
00779         */
00780     typedef typename VECTOR::value_type component_type;
00781 
00782         /** Read the component data at given vector index
00783             at given iterator position
00784         */
00785     template <class ITERATOR>
00786     component_type const & getComponent(ITERATOR const & i, int idx) const
00787     {
00788         return (*i)[idx];
00789     }
00790 
00791         /** Set the component data at given vector index
00792             at given iterator position. The type <TT>V</TT> of the passed
00793             in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
00794             In case of a conversion floating point -> intergral this includes rounding and clipping.
00795         */
00796     template <class V, class ITERATOR>
00797     void setComponent(V const & value, ITERATOR const & i, int idx) const
00798     {
00799         (*i)[idx] = detail::RequiresExplicitCast<component_type>::cast(value);
00800     }
00801 
00802         /** Read the component data at given vector index
00803             at an offset of given iterator position
00804         */
00805     template <class ITERATOR, class DIFFERENCE>
00806     component_type const & getComponent(ITERATOR const & i, DIFFERENCE const & diff, int idx) const
00807     {
00808         return i[diff][idx];
00809     }
00810 
00811     /** Set the component data at given vector index
00812         at an offset of given iterator position. The type <TT>V</TT> of the passed
00813         in <TT>value</TT> is automatically converted to <TT>component_type</TT>.
00814             In case of a conversion floating point -> intergral this includes rounding and clipping.
00815     */
00816     template <class V, class ITERATOR, class DIFFERENCE>
00817     void
00818     setComponent(V const & value, ITERATOR const & i, DIFFERENCE const & diff, int idx) const
00819     {
00820         i[diff][idx] = detail::RequiresExplicitCast<component_type>::cast(value);
00821     }
00822 };
00823 
00824 
00825 /********************************************************/
00826 /*                                                      */
00827 /*                 MultiImageAccessor2                  */
00828 /*                                                      */
00829 /********************************************************/
00830 
00831 /** \brief Access two images simultaneously.
00832 
00833     This accessor is used when two images need to be treated as one
00834     because an algorithm accepts only one image. For example,
00835     \ref seededRegionGrowing() uses only one image two calculate
00836     the cost for aggregating each pixel into a region. Somtimes, we
00837     need more information to calcuate this cost, for example gray value
00838     and local gradient magnitude. These values can be stored in two images,
00839     which appear as only one when we pass a <TT>MultiImageAccessor2</TT> to
00840     the lagorithms. Of course, the cost functor must accept a <TT>pair</TT>
00841     of values for this to work. Instead of an actual image iterator, we
00842     pass a <a href="CoordinateIterator.html">CoordinateIterator</a> which
00843     selects the right pixels form both images.
00844 
00845     <b> Usage:</b>
00846 
00847     <b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hxx</a>"<br>
00848     Namespace: vigra
00849 
00850     \code
00851     using namespace vigra;
00852 
00853     FImage gray_values(w,h), gradient_magnitude(w,h);
00854     IImage seeds(w,h), labels(w,h);
00855 
00856     seededRegionGrowing(
00857         srcIterRange(CoordinateIterator(), CoordinateIterator(w,h),
00858            MultiImageAccessor2<FImage::iterator, FImage::Accessor,
00859                                FImage::iterator, FImage::Accessor>
00860                               (gray_values.upperLeft(), gray_values.accessor(),
00861                                gradient_magnitude.upperLeft(), gradient_magnitude.accessor())),
00862         srcImage(seeds),
00863         destImage(labels),
00864         SomeCostFunctor());
00865     \endcode
00866 */
00867 
00868 template <class Iter1, class Acc1, class Iter2, class Acc2>
00869 class MultiImageAccessor2
00870 {
00871   public:
00872         /** The accessors value_type: construct a pair that contains
00873             the corresponding image values.
00874         */
00875     typedef pair<typename Acc1::value_type, typename Acc2::value_type>
00876             value_type;
00877 
00878         /** Construct from two image iterators and associated accessors.
00879         */
00880     MultiImageAccessor2(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2)
00881     : i1_(i1), a1_(a1), i2_(i2), a2_(a2)
00882     {}
00883 
00884         /** read the current data item
00885         */
00886     template <class DIFFERENCE>
00887     value_type operator()(DIFFERENCE const & d) const
00888     {
00889         return std::make_pair(a1_(i1_, d), a2_(i2_, d));
00890     }
00891 
00892         /** read the data item at an offset
00893         */
00894     template <class DIFFERENCE1, class DIFFERENCE2>
00895     value_type operator()(DIFFERENCE1 d1, DIFFERENCE2 const & d2) const
00896     {
00897         d1 += d2;
00898         return std::make_pair(a1_(i1_, d1), a2_(i2_, d1));
00899     }
00900 
00901   private:
00902     Iter1 i1_;
00903     Acc1 a1_;
00904     Iter2 i2_;
00905     Acc2 a2_;
00906 };
00907 
00908 //@}
00909 
00910 template <class T>
00911 struct AccessorTraits
00912 {
00913     typedef StandardAccessor<T>        default_accessor;
00914     typedef StandardConstAccessor<T>   default_const_accessor;
00915 };
00916 
00917 #define VIGRA_DEFINE_ACCESSOR_TRAITS(VALUE, ACCESSOR, CONST_ACCESSOR) \
00918     template <> \
00919     struct AccessorTraits<VALUE > \
00920     { \
00921         typedef ACCESSOR<VALUE >         default_accessor; \
00922         typedef CONST_ACCESSOR<VALUE >   default_const_accessor; \
00923     };
00924 
00925 VIGRA_DEFINE_ACCESSOR_TRAITS(signed char, StandardValueAccessor, StandardConstValueAccessor)
00926 VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned char, StandardValueAccessor, StandardConstValueAccessor)
00927 VIGRA_DEFINE_ACCESSOR_TRAITS(short, StandardValueAccessor, StandardConstValueAccessor)
00928 VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned short, StandardValueAccessor, StandardConstValueAccessor)
00929 VIGRA_DEFINE_ACCESSOR_TRAITS(int, StandardValueAccessor, StandardConstValueAccessor)
00930 VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned int, StandardValueAccessor, StandardConstValueAccessor)
00931 VIGRA_DEFINE_ACCESSOR_TRAITS(long, StandardValueAccessor, StandardConstValueAccessor)
00932 VIGRA_DEFINE_ACCESSOR_TRAITS(unsigned long, StandardValueAccessor, StandardConstValueAccessor)
00933 VIGRA_DEFINE_ACCESSOR_TRAITS(float, StandardValueAccessor, StandardConstValueAccessor)
00934 VIGRA_DEFINE_ACCESSOR_TRAITS(double, StandardValueAccessor, StandardConstValueAccessor)
00935 
00936 template <class T> class RGBValue;
00937 template <class T> class RGBAccessor;
00938 template <class T, int SIZE> class TinyVector;
00939 
00940 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
00941 
00942 template <class T>
00943 struct AccessorTraits<RGBValue<T> >
00944 {
00945     typedef RGBAccessor<RGBValue<T> >   default_accessor;
00946     typedef RGBAccessor<RGBValue<T> >   default_const_accessor;
00947 };
00948 
00949 template <class T, int SIZE>
00950 struct AccessorTraits<TinyVector<T, SIZE> >
00951 {
00952     typedef VectorAccessor<TinyVector<T, SIZE> >   default_accessor;
00953     typedef VectorAccessor<TinyVector<T, SIZE> >   default_const_accessor;
00954 };
00955 
00956 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
00957 
00958 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned char>, RGBAccessor, RGBAccessor)
00959 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<signed char>, RGBAccessor, RGBAccessor)
00960 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<short>, RGBAccessor, RGBAccessor)
00961 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned short>, RGBAccessor, RGBAccessor)
00962 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<int>, RGBAccessor, RGBAccessor)
00963 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned int>, RGBAccessor, RGBAccessor)
00964 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<long>, RGBAccessor, RGBAccessor)
00965 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<unsigned long>, RGBAccessor, RGBAccessor)
00966 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<float>, RGBAccessor, RGBAccessor)
00967 VIGRA_DEFINE_ACCESSOR_TRAITS(RGBValue<double>, RGBAccessor, RGBAccessor)
00968 
00969 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
00970 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
00971 #undef VIGRA_PIXELTYPE
00972 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
00973 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
00974 #undef VIGRA_PIXELTYPE
00975 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
00976 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
00977 #undef VIGRA_PIXELTYPE
00978 #define VIGRA_PIXELTYPE TinyVector<short, 2>
00979 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
00980 #undef VIGRA_PIXELTYPE
00981 #define VIGRA_PIXELTYPE TinyVector<short, 3>
00982 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
00983 #undef VIGRA_PIXELTYPE
00984 #define VIGRA_PIXELTYPE TinyVector<short, 4>
00985 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
00986 #undef VIGRA_PIXELTYPE
00987 #define VIGRA_PIXELTYPE TinyVector<int, 2>
00988 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
00989 #undef VIGRA_PIXELTYPE
00990 #define VIGRA_PIXELTYPE TinyVector<int, 3>
00991 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
00992 #undef VIGRA_PIXELTYPE
00993 #define VIGRA_PIXELTYPE TinyVector<int, 4>
00994 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
00995 #undef VIGRA_PIXELTYPE
00996 #define VIGRA_PIXELTYPE TinyVector<float, 2>
00997 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
00998 #undef VIGRA_PIXELTYPE
00999 #define VIGRA_PIXELTYPE TinyVector<float, 3>
01000 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
01001 #undef VIGRA_PIXELTYPE
01002 #define VIGRA_PIXELTYPE TinyVector<float, 4>
01003 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
01004 #undef VIGRA_PIXELTYPE
01005 #define VIGRA_PIXELTYPE TinyVector<double, 2>
01006 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
01007 #undef VIGRA_PIXELTYPE
01008 #define VIGRA_PIXELTYPE TinyVector<double, 3>
01009 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
01010 #undef VIGRA_PIXELTYPE
01011 #define VIGRA_PIXELTYPE TinyVector<double, 4>
01012 VIGRA_DEFINE_ACCESSOR_TRAITS(VIGRA_PIXELTYPE, VectorAccessor, VectorAccessor)
01013 #undef VIGRA_PIXELTYPE
01014 
01015 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
01016 
01017 #undef VIGRA_DEFINE_ACCESSOR_TRAITS
01018 
01019 } // namespace vigra
01020 
01021 #endif // VIGRA_ACCESSOR_HXX

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.3.3 (18 Aug 2005)