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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.9.0 (Tue Nov 6 2012)