VIGRA - VIGRA: vigra/accessor.hxx Source File

[ 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)