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