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

© Ullrich Köthe (koethe@informatik.uni-hamburg.de) Cognitive Systems Group, University of Hamburg, Germany | html generated using doxygen and Python VIGRA 1.3.2 (27 Jan 2005)