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