[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
vigra/basicimage.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_BASICIMAGE_HXX 00037 #define VIGRA_BASICIMAGE_HXX 00038 00039 #include <memory> 00040 #include <algorithm> 00041 #include "utilities.hxx" 00042 #include "iteratortraits.hxx" 00043 #include "accessor.hxx" 00044 #include "memory.hxx" 00045 00046 // Bounds checking Macro used if VIGRA_CHECK_BOUNDS is defined. 00047 #ifdef VIGRA_CHECK_BOUNDS 00048 #define VIGRA_ASSERT_INSIDE(diff) \ 00049 vigra_precondition(this->isInside(diff), "Index out of bounds") 00050 #else 00051 #define VIGRA_ASSERT_INSIDE(diff) 00052 #endif 00053 00054 namespace vigra { 00055 00056 template <class IMAGEITERATOR> 00057 class LineBasedColumnIteratorPolicy 00058 { 00059 public: 00060 typedef IMAGEITERATOR ImageIterator; 00061 typedef typename IMAGEITERATOR::LineStartIterator LineStartIterator; 00062 typedef typename IMAGEITERATOR::value_type value_type; 00063 typedef typename IMAGEITERATOR::difference_type::MoveY 00064 difference_type; 00065 typedef typename IMAGEITERATOR::reference reference; 00066 typedef typename IMAGEITERATOR::index_reference index_reference; 00067 typedef typename IMAGEITERATOR::pointer pointer; 00068 typedef std::random_access_iterator_tag iterator_category; 00069 00070 00071 struct BaseType 00072 { 00073 explicit BaseType(LineStartIterator c = LineStartIterator(), 00074 difference_type o = 0) 00075 : line_start_(c), offset_(o) 00076 {} 00077 00078 LineStartIterator line_start_; 00079 difference_type offset_; 00080 }; 00081 00082 static void initialize(BaseType &) {} 00083 00084 static reference dereference(BaseType const & d) 00085 { return const_cast<reference>(*(*d.line_start_ + d.offset_)); } 00086 00087 static index_reference dereference(BaseType const & d, difference_type n) 00088 { 00089 return const_cast<index_reference>(*(d.line_start_[n] + d.offset_)); 00090 } 00091 00092 static bool equal(BaseType const & d1, BaseType const & d2) 00093 { return d1.line_start_ == d2.line_start_; } 00094 00095 static bool less(BaseType const & d1, BaseType const & d2) 00096 { return d1.line_start_ < d2.line_start_; } 00097 00098 static difference_type difference(BaseType const & d1, BaseType const & d2) 00099 { return d1.line_start_ - d2.line_start_; } 00100 00101 static void increment(BaseType & d) 00102 { ++d.line_start_; } 00103 00104 static void decrement(BaseType & d) 00105 { --d.line_start_; } 00106 00107 static void advance(BaseType & d, difference_type n) 00108 { d.line_start_ += n; } 00109 }; 00110 00111 /********************************************************/ 00112 /* */ 00113 /* BasicImageIterator */ 00114 /* */ 00115 /********************************************************/ 00116 00117 /** Implementation of the standard image iterator for \ref vigra::BasicImage. 00118 See \ref vigra::ImageIterator for documentation. 00119 00120 <b>\#include</b> <vigra/basicimage.hxx> 00121 Namespace: vigra 00122 */ 00123 template <class IMAGEITERATOR, class PIXELTYPE, 00124 class REFERENCE, class POINTER, class LINESTARTITERATOR> 00125 class BasicImageIteratorBase 00126 { 00127 public: 00128 typedef BasicImageIteratorBase<IMAGEITERATOR, 00129 PIXELTYPE, REFERENCE, POINTER, LINESTARTITERATOR> self_type; 00130 00131 typedef LINESTARTITERATOR LineStartIterator; 00132 typedef PIXELTYPE value_type; 00133 typedef PIXELTYPE PixelType; 00134 typedef REFERENCE reference; 00135 typedef REFERENCE index_reference; 00136 typedef POINTER pointer; 00137 typedef Diff2D difference_type; 00138 typedef image_traverser_tag iterator_category; 00139 typedef POINTER row_iterator; 00140 typedef IteratorAdaptor<LineBasedColumnIteratorPolicy<IMAGEITERATOR> > 00141 column_iterator; 00142 00143 typedef int MoveX; 00144 typedef LINESTARTITERATOR MoveY; 00145 00146 MoveX x; 00147 MoveY y; 00148 00149 IMAGEITERATOR & operator+=(difference_type const & s) 00150 { 00151 x += s.x; 00152 y += s.y; 00153 return static_cast<IMAGEITERATOR &>(*this); 00154 } 00155 00156 IMAGEITERATOR & operator-=(difference_type const & s) 00157 { 00158 x -= s.x; 00159 y -= s.y; 00160 return static_cast<IMAGEITERATOR &>(*this); 00161 } 00162 00163 IMAGEITERATOR operator+(difference_type const & s) const 00164 { 00165 IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this)); 00166 00167 ret += s; 00168 00169 return ret; 00170 } 00171 00172 IMAGEITERATOR operator-(difference_type const & s) const 00173 { 00174 IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this)); 00175 00176 ret -= s; 00177 00178 return ret; 00179 } 00180 00181 difference_type operator-(BasicImageIteratorBase const & rhs) const 00182 { 00183 return difference_type(difference_type::MoveX(x - rhs.x), 00184 difference_type::MoveY(y - rhs.y)); 00185 } 00186 00187 bool operator==(BasicImageIteratorBase const & rhs) const 00188 { 00189 return (x == rhs.x) && (y == rhs.y); 00190 } 00191 00192 bool operator!=(BasicImageIteratorBase const & rhs) const 00193 { 00194 return (x != rhs.x) || (y != rhs.y); 00195 } 00196 00197 reference operator*() const 00198 { 00199 return *(*y + x ); 00200 } 00201 00202 pointer operator->() const 00203 { 00204 return *y + x; 00205 } 00206 00207 index_reference operator[](difference_type const & d) const 00208 { 00209 return *(*(y + d.y) + x + d.x); 00210 } 00211 00212 index_reference operator()(int dx, int dy) const 00213 { 00214 return *(*(y + dy) + x + dx); 00215 } 00216 00217 pointer operator[](int dy) const 00218 { 00219 return y[dy] + x; 00220 } 00221 00222 row_iterator rowIterator() const 00223 { return *y + x; } 00224 00225 column_iterator columnIterator() const 00226 { 00227 typedef typename column_iterator::BaseType Iter; 00228 return column_iterator(Iter(y, x)); 00229 } 00230 00231 protected: 00232 BasicImageIteratorBase(LINESTARTITERATOR const & line) 00233 : x(0), 00234 y(line) 00235 {} 00236 00237 BasicImageIteratorBase(int ix, LINESTARTITERATOR const & line) 00238 : x(ix), 00239 y(line) 00240 {} 00241 00242 BasicImageIteratorBase() 00243 : x(0), 00244 y(0) 00245 {} 00246 }; 00247 00248 /********************************************************/ 00249 /* */ 00250 /* BasicImageIterator */ 00251 /* */ 00252 /********************************************************/ 00253 00254 /** Implementation of the standard image iterator for \ref vigra::BasicImage. 00255 See \ref vigra::ImageIterator for documentation. 00256 00257 <b>\#include</b> <vigra/basicimage.hxx> 00258 Namespace: vigra 00259 */ 00260 template <class PIXELTYPE, class ITERATOR> 00261 class BasicImageIterator 00262 : public BasicImageIteratorBase<BasicImageIterator<PIXELTYPE, ITERATOR>, 00263 PIXELTYPE, PIXELTYPE &, PIXELTYPE *, ITERATOR> 00264 { 00265 public: 00266 00267 typedef BasicImageIteratorBase<BasicImageIterator, PIXELTYPE, 00268 PIXELTYPE &, PIXELTYPE *, ITERATOR> Base; 00269 00270 00271 BasicImageIterator(ITERATOR line) 00272 : Base(line) 00273 {} 00274 00275 BasicImageIterator() 00276 : Base() 00277 {} 00278 }; 00279 00280 /********************************************************/ 00281 /* */ 00282 /* ConstBasicImageIterator */ 00283 /* */ 00284 /********************************************************/ 00285 00286 /** Implementation of the standard const image iterator for \ref vigra::BasicImage. 00287 See \ref vigra::ConstImageIterator for documentation. 00288 00289 <b>\#include</b> <vigra/basicimage.hxx> 00290 Namespace: vigra 00291 */ 00292 template <class PIXELTYPE, class ITERATOR> 00293 class ConstBasicImageIterator 00294 : public BasicImageIteratorBase<ConstBasicImageIterator<PIXELTYPE, ITERATOR>, 00295 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR> 00296 { 00297 public: 00298 00299 typedef BasicImageIteratorBase<ConstBasicImageIterator, 00300 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR> Base; 00301 00302 00303 ConstBasicImageIterator(ITERATOR line) 00304 : Base(line) 00305 {} 00306 00307 ConstBasicImageIterator(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs) 00308 : Base(rhs.x, rhs.y) 00309 {} 00310 00311 ConstBasicImageIterator() 00312 : Base() 00313 {} 00314 00315 ConstBasicImageIterator & 00316 operator=(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs) 00317 { 00318 Base::x = rhs.x; 00319 Base::y = rhs.y; 00320 return *this; 00321 } 00322 00323 }; 00324 00325 /********************************************************/ 00326 /* */ 00327 /* definition of iterator traits */ 00328 /* */ 00329 /********************************************************/ 00330 00331 00332 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION 00333 00334 template <class T> 00335 struct IteratorTraits<BasicImageIterator<T, T**> > 00336 : public IteratorTraitsBase<BasicImageIterator<T, T**> > 00337 { 00338 typedef BasicImageIterator<T, T**> mutable_iterator; 00339 typedef ConstBasicImageIterator<T, T**> const_iterator; 00340 typedef typename AccessorTraits<T>::default_accessor DefaultAccessor; 00341 typedef DefaultAccessor default_accessor; 00342 typedef VigraTrueType hasConstantStrides; 00343 }; 00344 00345 template <class T> 00346 struct IteratorTraits<ConstBasicImageIterator<T, T**> > 00347 : public IteratorTraitsBase<ConstBasicImageIterator<T, T**> > 00348 { 00349 typedef BasicImageIterator<T, T**> mutable_iterator; 00350 typedef ConstBasicImageIterator<T, T**> const_iterator; 00351 typedef typename AccessorTraits<T>::default_const_accessor DefaultAccessor; 00352 typedef DefaultAccessor default_accessor; 00353 typedef VigraTrueType hasConstantStrides; 00354 }; 00355 00356 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION 00357 00358 #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \ 00359 template <> \ 00360 struct IteratorTraits<BasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00361 : public IteratorTraitsBase<BasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00362 { \ 00363 typedef BasicImageIterator<VALUETYPE, VALUETYPE**> mutable_iterator; \ 00364 typedef ConstBasicImageIterator<VALUETYPE, VALUETYPE**> const_iterator; \ 00365 typedef typename AccessorTraits<VALUETYPE >::default_accessor DefaultAccessor; \ 00366 typedef DefaultAccessor default_accessor; \ 00367 typedef VigraTrueType hasConstantStrides; \ 00368 }; \ 00369 \ 00370 template <> \ 00371 struct IteratorTraits<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00372 : public IteratorTraitsBase<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00373 { \ 00374 typedef BasicImageIterator<VALUETYPE, VALUETYPE**> mutable_iterator; \ 00375 typedef ConstBasicImageIterator<VALUETYPE, VALUETYPE**> const_iterator; \ 00376 typedef typename AccessorTraits<VALUETYPE >::default_const_accessor DefaultAccessor; \ 00377 typedef DefaultAccessor default_accessor; \ 00378 typedef VigraTrueType hasConstantStrides; \ 00379 }; 00380 00381 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>) 00382 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>) 00383 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned short>) 00384 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>) 00385 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned int>) 00386 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>) 00387 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>) 00388 00389 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2> 00390 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00391 #undef VIGRA_PIXELTYPE 00392 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3> 00393 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00394 #undef VIGRA_PIXELTYPE 00395 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4> 00396 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00397 #undef VIGRA_PIXELTYPE 00398 #define VIGRA_PIXELTYPE TinyVector<short, 2> 00399 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00400 #undef VIGRA_PIXELTYPE 00401 #define VIGRA_PIXELTYPE TinyVector<short, 3> 00402 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00403 #undef VIGRA_PIXELTYPE 00404 #define VIGRA_PIXELTYPE TinyVector<short, 4> 00405 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00406 #undef VIGRA_PIXELTYPE 00407 #define VIGRA_PIXELTYPE TinyVector<unsigned short, 2> 00408 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00409 #undef VIGRA_PIXELTYPE 00410 #define VIGRA_PIXELTYPE TinyVector<unsigned short, 3> 00411 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00412 #undef VIGRA_PIXELTYPE 00413 #define VIGRA_PIXELTYPE TinyVector<unsigned short, 4> 00414 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00415 #undef VIGRA_PIXELTYPE 00416 #define VIGRA_PIXELTYPE TinyVector<int, 2> 00417 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00418 #undef VIGRA_PIXELTYPE 00419 #define VIGRA_PIXELTYPE TinyVector<int, 3> 00420 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00421 #undef VIGRA_PIXELTYPE 00422 #define VIGRA_PIXELTYPE TinyVector<int, 4> 00423 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00424 #undef VIGRA_PIXELTYPE 00425 #define VIGRA_PIXELTYPE TinyVector<unsigned int, 2> 00426 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00427 #undef VIGRA_PIXELTYPE 00428 #define VIGRA_PIXELTYPE TinyVector<unsigned int, 3> 00429 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00430 #undef VIGRA_PIXELTYPE 00431 #define VIGRA_PIXELTYPE TinyVector<unsigned int, 4> 00432 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00433 #undef VIGRA_PIXELTYPE 00434 #define VIGRA_PIXELTYPE TinyVector<float, 2> 00435 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00436 #undef VIGRA_PIXELTYPE 00437 #define VIGRA_PIXELTYPE TinyVector<float, 3> 00438 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00439 #undef VIGRA_PIXELTYPE 00440 #define VIGRA_PIXELTYPE TinyVector<float, 4> 00441 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00442 #undef VIGRA_PIXELTYPE 00443 #define VIGRA_PIXELTYPE TinyVector<double, 2> 00444 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00445 #undef VIGRA_PIXELTYPE 00446 #define VIGRA_PIXELTYPE TinyVector<double, 3> 00447 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00448 #undef VIGRA_PIXELTYPE 00449 #define VIGRA_PIXELTYPE TinyVector<double, 4> 00450 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00451 #undef VIGRA_PIXELTYPE 00452 00453 #undef VIGRA_DEFINE_ITERATORTRAITS 00454 00455 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 00456 00457 /********************************************************/ 00458 /* */ 00459 /* BasicImage */ 00460 /* */ 00461 /********************************************************/ 00462 00463 /** \brief Fundamental class template for images. 00464 00465 A customized memory allocator can be specified as a templated argument 00466 and passed in the constructor. 00467 00468 <b>\#include</b> <vigra/basicimage.hxx> 00469 00470 Namespace: vigra 00471 */ 00472 template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> > 00473 class BasicImage 00474 { 00475 public: 00476 00477 /** the BasicImage's pixel type 00478 */ 00479 typedef PIXELTYPE value_type; 00480 00481 /** the BasicImage's pixel type 00482 */ 00483 typedef PIXELTYPE PixelType; 00484 00485 /** the BasicImage's reference type (i.e. the 00486 return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>) 00487 */ 00488 typedef PIXELTYPE & reference; 00489 00490 /** the BasicImage's const reference type (i.e. the 00491 return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT> 00492 when <TT>image</TT> is const) 00493 */ 00494 typedef PIXELTYPE const & const_reference; 00495 00496 /** the BasicImage's pointer type 00497 */ 00498 typedef PIXELTYPE * pointer; 00499 00500 /** the BasicImage's const pointer type 00501 */ 00502 typedef PIXELTYPE const * const_pointer; 00503 00504 /** the BasicImage's 1D random access iterator 00505 (note: lower case 'iterator' is a STL compatible 1D random 00506 access iterator, don't confuse with capitalized Iterator) 00507 */ 00508 typedef PIXELTYPE * iterator; 00509 00510 /** deprecated, use <TT>iterator</TT> instead 00511 */ 00512 typedef PIXELTYPE * ScanOrderIterator; 00513 00514 /** the BasicImage's 1D random access const iterator 00515 (note: lower case 'const_iterator' is a STL compatible 1D 00516 random access const iterator) 00517 */ 00518 typedef PIXELTYPE const * const_iterator; 00519 00520 /** deprecated, use <TT>const_iterator</TT> instead 00521 */ 00522 typedef PIXELTYPE const * ConstScanOrderIterator; 00523 00524 /** the BasicImage's 2D random access iterator ('traverser') 00525 */ 00526 typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser; 00527 00528 /** deprecated, use <TT>traverser</TT> instead 00529 */ 00530 typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator; 00531 00532 /** the BasicImage's 2D random access const iterator ('const traverser') 00533 */ 00534 typedef 00535 ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **> 00536 const_traverser; 00537 00538 /** deprecated, use <TT>const_traverser</TT> instead 00539 */ 00540 typedef 00541 ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **> 00542 ConstIterator; 00543 00544 /** the row iterator associated with the traverser 00545 */ 00546 typedef typename traverser::row_iterator row_iterator; 00547 00548 /** the const row iterator associated with the const_traverser 00549 */ 00550 typedef typename const_traverser::row_iterator const_row_iterator; 00551 00552 /** the column iterator associated with the traverser 00553 */ 00554 typedef typename traverser::column_iterator column_iterator; 00555 00556 /** the const column iterator associated with the const_traverser 00557 */ 00558 typedef typename const_traverser::column_iterator const_column_iterator; 00559 00560 /** the BasicImage's difference type (argument type of image[diff]) 00561 */ 00562 typedef Diff2D difference_type; 00563 00564 /** the BasicImage's size type (result type of image.size()) 00565 */ 00566 typedef Size2D size_type; 00567 00568 /** the BasicImage's default accessor 00569 */ 00570 typedef typename 00571 IteratorTraits<traverser>::DefaultAccessor Accessor; 00572 00573 /** the BasicImage's default const accessor 00574 */ 00575 typedef typename 00576 IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor; 00577 00578 /** the BasicImage's allocator (default: std::allocator<value_type>) 00579 */ 00580 typedef Alloc allocator_type; 00581 00582 typedef Alloc Allocator; 00583 typedef typename Alloc::template rebind<PIXELTYPE *>::other LineAllocator; 00584 00585 /** construct image of size 0x0 00586 */ 00587 BasicImage() 00588 : data_(0), 00589 width_(0), 00590 height_(0) 00591 {} 00592 00593 /** construct image of size 0x0, use the specified allocator. 00594 */ 00595 explicit BasicImage(Alloc const & alloc) 00596 : data_(0), 00597 width_(0), 00598 height_(0), 00599 allocator_(alloc), 00600 pallocator_(alloc) 00601 {} 00602 00603 /** construct image of size width x height, use the specified allocator. 00604 */ 00605 BasicImage(int width, int height, Alloc const & alloc = Alloc()) 00606 : data_(0), 00607 width_(0), 00608 height_(0), 00609 allocator_(alloc), 00610 pallocator_(alloc) 00611 { 00612 vigra_precondition((width >= 0) && (height >= 0), 00613 "BasicImage::BasicImage(int width, int height): " 00614 "width and height must be >= 0.\n"); 00615 00616 resize(width, height, value_type()); 00617 } 00618 00619 /** construct image of size size.x x size.y, use the specified allocator. 00620 */ 00621 explicit BasicImage(difference_type const & size, Alloc const & alloc = Alloc()) 00622 : data_(0), 00623 width_(0), 00624 height_(0), 00625 allocator_(alloc), 00626 pallocator_(alloc) 00627 { 00628 vigra_precondition((size.x >= 0) && (size.y >= 0), 00629 "BasicImage::BasicImage(Diff2D size): " 00630 "size.x and size.y must be >= 0.\n"); 00631 00632 resize(size.x, size.y, value_type()); 00633 } 00634 00635 /** construct image of size width*height and initialize every 00636 pixel with the value \a d (use this constructor, if 00637 value_type doesn't have a default constructor). 00638 Use the specified allocator. 00639 */ 00640 BasicImage(int width, int height, value_type const & d, Alloc const & alloc = Alloc()) 00641 : data_(0), 00642 width_(0), 00643 height_(0), 00644 allocator_(alloc), 00645 pallocator_(alloc) 00646 { 00647 vigra_precondition((width >= 0) && (height >= 0), 00648 "BasicImage::BasicImage(int width, int height, value_type const & ): " 00649 "width and height must be >= 0.\n"); 00650 00651 resize(width, height, d); 00652 } 00653 00654 /** construct image of size width*height and try to skip initialization 00655 of the memory (see BasicImage::resize for details). 00656 Use the specified allocator. 00657 */ 00658 BasicImage(int width, int height, SkipInitializationTag, Alloc const & alloc = Alloc()) 00659 : data_(0), 00660 width_(0), 00661 height_(0), 00662 allocator_(alloc), 00663 pallocator_(alloc) 00664 { 00665 vigra_precondition((width >= 0) && (height >= 0), 00666 "BasicImage::BasicImage(int width, int height, value_type const & ): " 00667 "width and height must be >= 0.\n"); 00668 00669 resize(width, height, SkipInitialization); 00670 } 00671 00672 /** construct image of size size.x x size.y and initialize 00673 every pixel with given data (use this constructor, if 00674 value_type doesn't have a default constructor). Use the specified allocator. 00675 */ 00676 explicit BasicImage(difference_type const & size, value_type const & d, Alloc const & alloc = Alloc()) 00677 : data_(0), 00678 width_(0), 00679 height_(0), 00680 allocator_(alloc), 00681 pallocator_(alloc) 00682 { 00683 vigra_precondition((size.x >= 0) && (size.y >= 0), 00684 "BasicImage::BasicImage(Diff2D const & size, value_type const & v): " 00685 "size.x and size.y must be >= 0.\n"); 00686 00687 resize(size.x, size.y, d); 00688 } 00689 00690 /** construct image of size size.x x size.y and try to skip initialization 00691 of the memory (see BasicImage::resize for details). Use the specified allocator. 00692 */ 00693 explicit BasicImage(difference_type const & size, SkipInitializationTag, Alloc const & alloc = Alloc()) 00694 : data_(0), 00695 width_(0), 00696 height_(0), 00697 allocator_(alloc), 00698 pallocator_(alloc) 00699 { 00700 vigra_precondition((size.x >= 0) && (size.y >= 0), 00701 "BasicImage::BasicImage(Diff2D const & size, value_type const & v): " 00702 "size.x and size.y must be >= 0.\n"); 00703 00704 resize(size.x, size.y, SkipInitialization); 00705 } 00706 00707 00708 /** construct image of size width*height and copy the data from the 00709 given C-style array \a d. Use the specified allocator. 00710 */ 00711 BasicImage(int width, int height, const_pointer d, Alloc const & alloc = Alloc()) 00712 : data_(0), 00713 width_(0), 00714 height_(0), 00715 allocator_(alloc), 00716 pallocator_(alloc) 00717 { 00718 vigra_precondition((width >= 0) && (height >= 0), 00719 "BasicImage::BasicImage(int width, int height, const_pointer ): " 00720 "width and height must be >= 0.\n"); 00721 00722 resizeCopy(width, height, d); 00723 } 00724 00725 /** construct image of size size.x x size.y and copy the data from the 00726 given C-style array. Use the specified allocator. 00727 */ 00728 explicit BasicImage(difference_type const & size, const_pointer d, Alloc const & alloc = Alloc()) 00729 : data_(0), 00730 width_(0), 00731 height_(0), 00732 allocator_(alloc), 00733 pallocator_(alloc) 00734 { 00735 vigra_precondition((size.x >= 0) && (size.y >= 0), 00736 "BasicImage::BasicImage(Diff2D const & size, const_pointer): " 00737 "size.x and size.y must be >= 0.\n"); 00738 00739 resizeCopy(size.x, size.y, d); 00740 } 00741 00742 /** copy rhs image 00743 */ 00744 BasicImage(const BasicImage & rhs) 00745 : data_(0), 00746 width_(0), 00747 height_(0), 00748 allocator_(rhs.allocator_), 00749 pallocator_(rhs.pallocator_) 00750 { 00751 resizeCopy(rhs); 00752 } 00753 00754 /** destructor 00755 */ 00756 ~BasicImage() 00757 { 00758 deallocate(); 00759 } 00760 00761 /** copy rhs image (image is resized if necessary) 00762 */ 00763 BasicImage & operator=(const BasicImage & rhs); 00764 00765 /** \deprecated set Image with const value 00766 */ 00767 BasicImage & operator=(value_type pixel); 00768 00769 /** set Image with const value 00770 */ 00771 BasicImage & init(value_type const & pixel); 00772 00773 /** reset image to specified size (dimensions must not be negative) 00774 (old data are kept if new size matches old size) 00775 */ 00776 void resize(int width, int height) 00777 { 00778 if(width != width_ || height != height_) 00779 resize(width, height, value_type()); 00780 } 00781 00782 /** reset image to specified size (dimensions must not be negative) 00783 (old data are kept if new size matches old size) 00784 */ 00785 void resize(difference_type const & size) 00786 { 00787 if(size.x != width_ || size.y != height_) 00788 { 00789 resize(size.x, size.y, value_type()); 00790 } 00791 } 00792 00793 /** reset image to specified size and initialize it with 00794 given data (use this if value_type doesn't have a default 00795 constructor, dimensions must not be negative, 00796 old data are kept if new size matches old size) 00797 */ 00798 void resize(int width, int height, value_type const & d) 00799 { 00800 resizeImpl(width, height, d, false); 00801 } 00802 00803 /** reset image to specified size and skip initialization 00804 if possible (use this if <tt>value_type</tt> is a built-in type 00805 or <tt>TinyVector<builtin>&</tt> and the data is 00806 immediately overridden afterwards). If <tt>value_type</tt> requires 00807 initialization, <tt>SkipInitialization</tt> is ignored. 00808 00809 Usage: 00810 \code 00811 image.resize(new_width, new_height, SkipInitialization); 00812 \endcode 00813 */ 00814 void resize(int width, int height, SkipInitializationTag) 00815 { 00816 resizeImpl(width, height, NumericTraits<value_type>::zero(), 00817 CanSkipInitialization<value_type>::value); 00818 } 00819 00820 /** resize image to given size and initialize by copying data 00821 from the C-style array \a data. 00822 */ 00823 void resizeCopy(int width, int height, const_pointer data); 00824 00825 /** resize image to size of other image and copy its data 00826 */ 00827 void resizeCopy(const BasicImage & rhs) 00828 { 00829 resizeCopy(rhs.width(), rhs.height(), rhs.data_); 00830 } 00831 00832 /** swap the internal data with the rhs image in constant time 00833 */ 00834 void swap( BasicImage & rhs ); 00835 00836 /** width of Image 00837 */ 00838 int width() const 00839 { 00840 return width_; 00841 } 00842 00843 /** height of Image 00844 */ 00845 int height() const 00846 { 00847 return height_; 00848 } 00849 00850 /** size of Image 00851 */ 00852 size_type size() const 00853 { 00854 return size_type(width(), height()); 00855 } 00856 00857 /** test whether a given coordinate is inside the image 00858 */ 00859 bool isInside(difference_type const & d) const 00860 { 00861 return d.x >= 0 && d.y >= 0 && 00862 d.x < width() && d.y < height(); 00863 } 00864 00865 /** access pixel at given location. <br> 00866 usage: <TT> value_type value = image[Diff2D(1,2)] </TT> 00867 */ 00868 reference operator[](difference_type const & d) 00869 { 00870 VIGRA_ASSERT_INSIDE(d); 00871 return lines_[d.y][d.x]; 00872 } 00873 00874 /** read pixel at given location. <br> 00875 usage: <TT> value_type value = image[Diff2D(1,2)] </TT> 00876 */ 00877 const_reference operator[](difference_type const & d) const 00878 { 00879 VIGRA_ASSERT_INSIDE(d); 00880 return lines_[d.y][d.x]; 00881 } 00882 00883 /** access pixel at given location. <br> 00884 usage: <TT> value_type value = image(1,2) </TT> 00885 */ 00886 reference operator()(int dx, int dy) 00887 { 00888 VIGRA_ASSERT_INSIDE(difference_type(dx,dy)); 00889 return lines_[dy][dx]; 00890 } 00891 00892 /** read pixel at given location. <br> 00893 usage: <TT> value_type value = image(1,2) </TT> 00894 */ 00895 const_reference operator()(int dx, int dy) const 00896 { 00897 VIGRA_ASSERT_INSIDE(difference_type(dx,dy)); 00898 return lines_[dy][dx]; 00899 } 00900 00901 /** access pixel at given location. 00902 Note that the 'x' index is the trailing index. <br> 00903 usage: <TT> value_type value = image[2][1] </TT> 00904 */ 00905 pointer operator[](int dy) 00906 { 00907 VIGRA_ASSERT_INSIDE(difference_type(0,dy)); 00908 return lines_[dy]; 00909 } 00910 00911 /** read pixel at given location. 00912 Note that the 'x' index is the trailing index. <br> 00913 usage: <TT> value_type value = image[2][1] </TT> 00914 */ 00915 const_pointer operator[](int dy) const 00916 { 00917 VIGRA_ASSERT_INSIDE(difference_type(0,dy)); 00918 return lines_[dy]; 00919 } 00920 00921 /** init 2D random access iterator pointing to upper left pixel 00922 */ 00923 traverser upperLeft() 00924 { 00925 vigra_precondition(data_ != 0, 00926 "BasicImage::upperLeft(): image must have non-zero size."); 00927 return traverser(lines_); 00928 } 00929 00930 /** init 2D random access iterator pointing to 00931 pixel(width, height), i.e. one pixel right and below lower right 00932 corner of the image as is common in C/C++. 00933 */ 00934 traverser lowerRight() 00935 { 00936 vigra_precondition(data_ != 0, 00937 "BasicImage::lowerRight(): image must have non-zero size."); 00938 return upperLeft() + size(); 00939 } 00940 00941 /** init 2D random access const iterator pointing to upper left pixel 00942 */ 00943 const_traverser upperLeft() const 00944 { 00945 vigra_precondition(data_ != 0, 00946 "BasicImage::upperLeft(): image must have non-zero size."); 00947 return const_traverser(const_cast<PIXELTYPE **>(lines_)); 00948 } 00949 00950 /** init 2D random access const iterator pointing to 00951 pixel(width, height), i.e. one pixel right and below lower right 00952 corner of the image as is common in C/C++. 00953 */ 00954 const_traverser lowerRight() const 00955 { 00956 vigra_precondition(data_ != 0, 00957 "BasicImage::lowerRight(): image must have non-zero size."); 00958 return upperLeft() + size(); 00959 } 00960 00961 /** init 1D random access iterator pointing to first pixel 00962 */ 00963 iterator begin() 00964 { 00965 vigra_precondition(data_ != 0, 00966 "BasicImage::begin(): image must have non-zero size."); 00967 return data_; 00968 } 00969 00970 /** init 1D random access iterator pointing past the end 00971 */ 00972 iterator end() 00973 { 00974 vigra_precondition(data_ != 0, 00975 "BasicImage::end(): image must have non-zero size."); 00976 return data_ + width() * height(); 00977 } 00978 00979 /** init 1D random access const iterator pointing to first pixel 00980 */ 00981 const_iterator begin() const 00982 { 00983 vigra_precondition(data_ != 0, 00984 "BasicImage::begin(): image must have non-zero size."); 00985 return data_; 00986 } 00987 00988 /** init 1D random access const iterator pointing past the end 00989 */ 00990 const_iterator end() const 00991 { 00992 vigra_precondition(data_ != 0, 00993 "BasicImage::end(): image must have non-zero size."); 00994 return data_ + width() * height(); 00995 } 00996 00997 /** init 1D random access iterator pointing to first pixel of row \a y 00998 */ 00999 row_iterator rowBegin(int y) 01000 { 01001 return lines_[y]; 01002 } 01003 01004 /** init 1D random access iterator pointing past the end of row \a y 01005 */ 01006 row_iterator rowEnd(int y) 01007 { 01008 return rowBegin(y) + width(); 01009 } 01010 01011 /** init 1D random access const iterator pointing to first pixel of row \a y 01012 */ 01013 const_row_iterator rowBegin(int y) const 01014 { 01015 return lines_[y]; 01016 } 01017 01018 /** init 1D random access const iterator pointing past the end of row \a y 01019 */ 01020 const_row_iterator rowEnd(int y) const 01021 { 01022 return rowBegin(y) + width(); 01023 } 01024 01025 /** init 1D random access iterator pointing to first pixel of column \a x 01026 */ 01027 column_iterator columnBegin(int x) 01028 { 01029 typedef typename column_iterator::BaseType Iter; 01030 return column_iterator(Iter(lines_, x)); 01031 } 01032 01033 /** init 1D random access iterator pointing past the end of column \a x 01034 */ 01035 column_iterator columnEnd(int x) 01036 { 01037 return columnBegin(x) + height(); 01038 } 01039 01040 /** init 1D random access const iterator pointing to first pixel of column \a x 01041 */ 01042 const_column_iterator columnBegin(int x) const 01043 { 01044 typedef typename const_column_iterator::BaseType Iter; 01045 return const_column_iterator(Iter(lines_, x)); 01046 } 01047 01048 /** init 1D random access const iterator pointing past the end of column \a x 01049 */ 01050 const_column_iterator columnEnd(int x) const 01051 { 01052 return columnBegin(x) + height(); 01053 } 01054 01055 /** get a pointer to the internal data 01056 */ 01057 const_pointer data() const 01058 { 01059 return data_; 01060 } 01061 01062 /** return default accessor 01063 */ 01064 Accessor accessor() 01065 { 01066 return Accessor(); 01067 } 01068 01069 /** return default const accessor 01070 */ 01071 ConstAccessor accessor() const 01072 { 01073 return ConstAccessor(); 01074 } 01075 01076 private: 01077 01078 void deallocate(); 01079 void resizeImpl(int width, int height, value_type const & d, bool skipInit); 01080 01081 01082 value_type ** initLineStartArray(value_type * data, int width, int height); 01083 01084 PIXELTYPE * data_; 01085 PIXELTYPE ** lines_; 01086 int width_, height_; 01087 Alloc allocator_; 01088 LineAllocator pallocator_; 01089 }; 01090 01091 template <class PIXELTYPE, class Alloc> 01092 BasicImage<PIXELTYPE, Alloc> & 01093 BasicImage<PIXELTYPE, Alloc>::operator=(const BasicImage & rhs) 01094 { 01095 if(this != &rhs) 01096 { 01097 if((width() != rhs.width()) || 01098 (height() != rhs.height())) 01099 { 01100 resizeCopy(rhs); 01101 } 01102 else 01103 { 01104 ConstScanOrderIterator is = rhs.begin(); 01105 ConstScanOrderIterator iend = rhs.end(); 01106 ScanOrderIterator id = begin(); 01107 01108 for(; is != iend; ++is, ++id) *id = *is; 01109 } 01110 } 01111 return *this; 01112 } 01113 01114 template <class PIXELTYPE, class Alloc> 01115 BasicImage<PIXELTYPE, Alloc> & 01116 BasicImage<PIXELTYPE, Alloc>::operator=(value_type pixel) 01117 { 01118 ScanOrderIterator i = begin(); 01119 ScanOrderIterator iend = end(); 01120 01121 for(; i != iend; ++i) *i = pixel; 01122 01123 return *this; 01124 } 01125 01126 template <class PIXELTYPE, class Alloc> 01127 BasicImage<PIXELTYPE, Alloc> & 01128 BasicImage<PIXELTYPE, Alloc>::init(value_type const & pixel) 01129 { 01130 ScanOrderIterator i = begin(); 01131 ScanOrderIterator iend = end(); 01132 01133 for(; i != iend; ++i) *i = pixel; 01134 01135 return *this; 01136 } 01137 01138 template <class PIXELTYPE, class Alloc> 01139 void 01140 BasicImage<PIXELTYPE, Alloc>::resizeImpl(int width, int height, value_type const & d, bool skipInit) 01141 { 01142 vigra_precondition((width >= 0) && (height >= 0), 01143 "BasicImage::resize(int width, int height, value_type const &): " 01144 "width and height must be >= 0.\n"); 01145 vigra_precondition(width * height >= 0, 01146 "BasicImage::resize(int width, int height, value_type const &): " 01147 "width * height too large (integer overflow -> negative).\n"); 01148 01149 if (width_ != width || height_ != height) // change size? 01150 { 01151 value_type * newdata = 0; 01152 value_type ** newlines = 0; 01153 if(width*height > 0) 01154 { 01155 if (width*height != width_*height_) // different sizes, must reallocate 01156 { 01157 newdata = allocator_.allocate(typename Alloc::size_type(width*height)); 01158 if(!skipInit) 01159 std::uninitialized_fill_n(newdata, width*height, d); 01160 newlines = initLineStartArray(newdata, width, height); 01161 deallocate(); 01162 } 01163 else // need only to reshape 01164 { 01165 newdata = data_; 01166 if(!skipInit) 01167 std::fill_n(newdata, width*height, d); 01168 newlines = initLineStartArray(newdata, width, height); 01169 pallocator_.deallocate(lines_, typename Alloc::size_type(height_)); 01170 } 01171 } 01172 else 01173 { 01174 deallocate(); 01175 } 01176 01177 data_ = newdata; 01178 lines_ = newlines; 01179 width_ = width; 01180 height_ = height; 01181 } 01182 else if(width*height > 0 && !skipInit) // keep size, re-init data 01183 { 01184 std::fill_n(data_, width*height, d); 01185 } 01186 } 01187 01188 01189 template <class PIXELTYPE, class Alloc> 01190 void 01191 BasicImage<PIXELTYPE, Alloc>::resizeCopy(int width, int height, const_pointer data) 01192 { 01193 int newsize = width*height; 01194 if (width_ != width || height_ != height) // change size? 01195 { 01196 value_type * newdata = 0; 01197 value_type ** newlines = 0; 01198 if(newsize > 0) 01199 { 01200 if (newsize != width_*height_) // different sizes, must reallocate 01201 { 01202 newdata = allocator_.allocate(typename Alloc::size_type(newsize)); 01203 std::uninitialized_copy(data, data + newsize, newdata); 01204 newlines = initLineStartArray(newdata, width, height); 01205 deallocate(); 01206 } 01207 else // need only to reshape 01208 { 01209 newdata = data_; 01210 std::copy(data, data + newsize, newdata); 01211 newlines = initLineStartArray(newdata, width, height); 01212 pallocator_.deallocate(lines_, typename Alloc::size_type(height_)); 01213 } 01214 } 01215 else 01216 { 01217 deallocate(); 01218 } 01219 01220 data_ = newdata; 01221 lines_ = newlines; 01222 width_ = width; 01223 height_ = height; 01224 } 01225 else if(newsize > 0) // keep size, copy data 01226 { 01227 std::copy(data, data + newsize, data_); 01228 } 01229 } 01230 01231 template <class PIXELTYPE, class Alloc> 01232 void 01233 BasicImage<PIXELTYPE, Alloc>::swap( BasicImage & rhs ) 01234 { 01235 if (&rhs!=this) 01236 { 01237 std::swap( data_, rhs.data_ ); 01238 std::swap( lines_, rhs.lines_ ); 01239 std::swap( width_, rhs.width_ ); 01240 std::swap( height_, rhs.height_ ); 01241 } 01242 } 01243 01244 template <class PIXELTYPE, class Alloc> 01245 void 01246 BasicImage<PIXELTYPE, Alloc>::deallocate() 01247 { 01248 if(data_) 01249 { 01250 ScanOrderIterator i = begin(); 01251 ScanOrderIterator iend = end(); 01252 01253 for(; i != iend; ++i) (*i).~PIXELTYPE(); 01254 01255 allocator_.deallocate(data_, typename Alloc::size_type(width()*height())); 01256 pallocator_.deallocate(lines_, typename Alloc::size_type(height_)); 01257 } 01258 } 01259 01260 template <class PIXELTYPE, class Alloc> 01261 PIXELTYPE ** 01262 BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, int width, int height) 01263 { 01264 value_type ** lines = pallocator_.allocate(typename Alloc::size_type(height)); 01265 for(int y=0; y<height; ++y) 01266 lines[y] = data + y*width; 01267 return lines; 01268 } 01269 01270 /********************************************************/ 01271 /* */ 01272 /* argument object factories */ 01273 /* */ 01274 /********************************************************/ 01275 01276 template <class PixelType, class Accessor, class Alloc> 01277 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01278 typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01279 srcImageRange(BasicImage<PixelType, Alloc> const & img, Accessor a) 01280 { 01281 return triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01282 typename BasicImage<PixelType, Alloc>::const_traverser, 01283 Accessor>(img.upperLeft(), 01284 img.lowerRight(), 01285 a); 01286 } 01287 01288 template <class PixelType, class Accessor, class Alloc> 01289 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01290 typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01291 srcImageRange(BasicImage<PixelType, Alloc> const & img, Rect2D const & roi, Accessor a) 01292 { 01293 vigra_precondition(roi.left() >= 0 && roi.top() >= 0 && 01294 roi.right() <= img.width() && roi.bottom() <= img.height(), 01295 "srcImageRange(): ROI rectangle outside image."); 01296 return triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01297 typename BasicImage<PixelType, Alloc>::const_traverser, 01298 Accessor>(img.upperLeft() + roi.upperLeft(), 01299 img.upperLeft() + roi.lowerRight(), 01300 a); 01301 } 01302 01303 template <class PixelType, class Accessor, class Alloc> 01304 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01305 srcImage(BasicImage<PixelType, Alloc> const & img, Accessor a) 01306 { 01307 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01308 Accessor>(img.upperLeft(), a); 01309 } 01310 01311 template <class PixelType, class Accessor, class Alloc> 01312 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01313 srcImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul, Accessor a) 01314 { 01315 vigra_precondition(img.isInside(ul), 01316 "srcImage(): ROI rectangle outside image."); 01317 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01318 Accessor>(img.upperLeft() + ul, a); 01319 } 01320 01321 template <class PixelType, class Accessor, class Alloc> 01322 inline triple<typename BasicImage<PixelType, Alloc>::traverser, 01323 typename BasicImage<PixelType, Alloc>::traverser, Accessor> 01324 destImageRange(BasicImage<PixelType, Alloc> & img, Accessor a) 01325 { 01326 return triple<typename BasicImage<PixelType, Alloc>::traverser, 01327 typename BasicImage<PixelType, Alloc>::traverser, 01328 Accessor>(img.upperLeft(), 01329 img.lowerRight(), 01330 a); 01331 } 01332 01333 template <class PixelType, class Accessor, class Alloc> 01334 inline triple<typename BasicImage<PixelType, Alloc>::traverser, 01335 typename BasicImage<PixelType, Alloc>::traverser, Accessor> 01336 destImageRange(BasicImage<PixelType, Alloc> & img, Rect2D const & roi, Accessor a) 01337 { 01338 vigra_precondition(roi.left() >= 0 && roi.top() >= 0 && 01339 roi.right() <= img.width() && roi.bottom() <= img.height(), 01340 "destImageRange(): ROI rectangle outside image."); 01341 return triple<typename BasicImage<PixelType, Alloc>::traverser, 01342 typename BasicImage<PixelType, Alloc>::traverser, 01343 Accessor>(img.upperLeft() + roi.upperLeft(), 01344 img.upperLeft() + roi.lowerRight(), 01345 a); 01346 } 01347 01348 template <class PixelType, class Accessor, class Alloc> 01349 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor> 01350 destImage(BasicImage<PixelType, Alloc> & img, Accessor a) 01351 { 01352 return pair<typename BasicImage<PixelType, Alloc>::traverser, 01353 Accessor>(img.upperLeft(), a); 01354 } 01355 01356 template <class PixelType, class Accessor, class Alloc> 01357 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor> 01358 destImage(BasicImage<PixelType, Alloc> & img, Point2D const & ul, Accessor a) 01359 { 01360 vigra_precondition(img.isInside(ul), 01361 "destImage(): ROI rectangle outside image."); 01362 return pair<typename BasicImage<PixelType, Alloc>::traverser, 01363 Accessor>(img.upperLeft() + ul, a); 01364 } 01365 01366 template <class PixelType, class Accessor, class Alloc> 01367 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01368 maskImage(BasicImage<PixelType, Alloc> const & img, Accessor a) 01369 { 01370 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01371 Accessor>(img.upperLeft(), a); 01372 } 01373 01374 template <class PixelType, class Accessor, class Alloc> 01375 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01376 maskImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul, Accessor a) 01377 { 01378 vigra_precondition(img.isInside(ul), 01379 "maskImage(): ROI rectangle outside image."); 01380 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01381 Accessor>(img.upperLeft() + ul, a); 01382 } 01383 01384 /****************************************************************/ 01385 01386 template <class PixelType, class Alloc> 01387 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01388 typename BasicImage<PixelType, Alloc>::const_traverser, 01389 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01390 srcImageRange(BasicImage<PixelType, Alloc> const & img) 01391 { 01392 return triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01393 typename BasicImage<PixelType, Alloc>::const_traverser, 01394 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(), 01395 img.lowerRight(), 01396 img.accessor()); 01397 } 01398 01399 template <class PixelType, class Alloc> 01400 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01401 typename BasicImage<PixelType, Alloc>::const_traverser, 01402 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01403 srcImageRange(BasicImage<PixelType, Alloc> const & img, Rect2D const & roi) 01404 { 01405 vigra_precondition(roi.left() >= 0 && roi.top() >= 0 && 01406 roi.right() <= img.width() && roi.bottom() <= img.height(), 01407 "srcImageRange(): ROI rectangle outside image."); 01408 return triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01409 typename BasicImage<PixelType, Alloc>::const_traverser, 01410 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + roi.upperLeft(), 01411 img.upperLeft() + roi.lowerRight(), 01412 img.accessor()); 01413 } 01414 01415 template <class PixelType, class Alloc> 01416 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser, 01417 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01418 srcImage(BasicImage<PixelType, Alloc> const & img) 01419 { 01420 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01421 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(), 01422 img.accessor()); 01423 } 01424 01425 template <class PixelType, class Alloc> 01426 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser, 01427 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01428 srcImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul) 01429 { 01430 vigra_precondition(img.isInside(ul), 01431 "srcImage(): ROI rectangle outside image."); 01432 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01433 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + ul, 01434 img.accessor()); 01435 } 01436 01437 template <class PixelType, class Alloc> 01438 inline triple< typename BasicImage<PixelType, Alloc>::traverser, 01439 typename BasicImage<PixelType, Alloc>::traverser, 01440 typename BasicImage<PixelType, Alloc>::Accessor> 01441 destImageRange(BasicImage<PixelType, Alloc> & img) 01442 { 01443 return triple<typename BasicImage<PixelType, Alloc>::traverser, 01444 typename BasicImage<PixelType, Alloc>::traverser, 01445 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(), 01446 img.lowerRight(), 01447 img.accessor()); 01448 } 01449 01450 template <class PixelType, class Alloc> 01451 inline triple< typename BasicImage<PixelType, Alloc>::traverser, 01452 typename BasicImage<PixelType, Alloc>::traverser, 01453 typename BasicImage<PixelType, Alloc>::Accessor> 01454 destImageRange(BasicImage<PixelType, Alloc> & img, Rect2D const & roi) 01455 { 01456 vigra_precondition(roi.left() >= 0 && roi.top() >= 0 && 01457 roi.right() <= img.width() && roi.bottom() <= img.height(), 01458 "destImageRange(): ROI rectangle outside image."); 01459 return triple<typename BasicImage<PixelType, Alloc>::traverser, 01460 typename BasicImage<PixelType, Alloc>::traverser, 01461 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft() + roi.upperLeft(), 01462 img.upperLeft() + roi.lowerRight(), 01463 img.accessor()); 01464 } 01465 01466 template <class PixelType, class Alloc> 01467 inline pair< typename BasicImage<PixelType, Alloc>::traverser, 01468 typename BasicImage<PixelType, Alloc>::Accessor> 01469 destImage(BasicImage<PixelType, Alloc> & img) 01470 { 01471 return pair<typename BasicImage<PixelType, Alloc>::traverser, 01472 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(), 01473 img.accessor()); 01474 } 01475 01476 template <class PixelType, class Alloc> 01477 inline pair< typename BasicImage<PixelType, Alloc>::traverser, 01478 typename BasicImage<PixelType, Alloc>::Accessor> 01479 destImage(BasicImage<PixelType, Alloc> & img, Point2D const & ul) 01480 { 01481 vigra_precondition(img.isInside(ul), 01482 "destImage(): ROI rectangle outside image."); 01483 return pair<typename BasicImage<PixelType, Alloc>::traverser, 01484 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft() + ul, 01485 img.accessor()); 01486 } 01487 01488 template <class PixelType, class Alloc> 01489 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser, 01490 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01491 maskImage(BasicImage<PixelType, Alloc> const & img) 01492 { 01493 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01494 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(), 01495 img.accessor()); 01496 } 01497 01498 template <class PixelType, class Alloc> 01499 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser, 01500 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01501 maskImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul) 01502 { 01503 vigra_precondition(img.isInside(ul), 01504 "maskImage(): ROI rectangle outside image."); 01505 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01506 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + ul, 01507 img.accessor()); 01508 } 01509 01510 } // namespace vigra 01511 #undef VIGRA_ASSERT_INSIDE 01512 #endif // VIGRA_BASICIMAGE_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|