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

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