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