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