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

details vigra/accessor.hxx VIGRA

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