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

vigra/accessor.hxx

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