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