[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
vigra/basicimage.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_BASICIMAGE_HXX 00024 #define VIGRA_BASICIMAGE_HXX 00025 00026 #include <memory> 00027 #include <algorithm> 00028 #include "vigra/utilities.hxx" 00029 #include "vigra/iteratortraits.hxx" 00030 #include "vigra/accessor.hxx" 00031 00032 namespace vigra { 00033 00034 template <class IMAGEITERATOR> 00035 class LineBasedColumnIteratorPolicy 00036 { 00037 public: 00038 typedef IMAGEITERATOR ImageIterator; 00039 typedef typename IMAGEITERATOR::LineStartIterator LineStartIterator; 00040 typedef typename IMAGEITERATOR::value_type value_type; 00041 typedef typename IMAGEITERATOR::difference_type::MoveY 00042 difference_type; 00043 typedef typename IMAGEITERATOR::reference reference; 00044 typedef typename IMAGEITERATOR::index_reference index_reference; 00045 typedef typename IMAGEITERATOR::pointer pointer; 00046 typedef std::random_access_iterator_tag iterator_category; 00047 00048 00049 struct BaseType 00050 { 00051 explicit BaseType(LineStartIterator c = LineStartIterator(), 00052 difference_type o = 0) 00053 : line_start_(c), offset_(o) 00054 {} 00055 00056 LineStartIterator line_start_; 00057 difference_type offset_; 00058 }; 00059 00060 static void initialize(BaseType &) {} 00061 00062 static reference dereference(BaseType const & d) 00063 { return const_cast<reference>(*(*d.line_start_ + d.offset_)); } 00064 00065 static index_reference dereference(BaseType const & d, difference_type n) 00066 { 00067 return const_cast<index_reference>(*(d.line_start_[n] + d.offset_)); 00068 } 00069 00070 static bool equal(BaseType const & d1, BaseType const & d2) 00071 { return d1.line_start_ == d2.line_start_; } 00072 00073 static bool less(BaseType const & d1, BaseType const & d2) 00074 { return d1.line_start_ < d2.line_start_; } 00075 00076 static difference_type difference(BaseType const & d1, BaseType const & d2) 00077 { return d1.line_start_ - d2.line_start_; } 00078 00079 static void increment(BaseType & d) 00080 { ++d.line_start_; } 00081 00082 static void decrement(BaseType & d) 00083 { --d.line_start_; } 00084 00085 static void advance(BaseType & d, difference_type n) 00086 { d.line_start_ += n; } 00087 }; 00088 00089 /********************************************************/ 00090 /* */ 00091 /* BasicImageIterator */ 00092 /* */ 00093 /********************************************************/ 00094 00095 /** Implementation of the standard image iterator for \ref vigra::BasicImage. 00096 See \ref vigra::ImageIterator for documentation. 00097 00098 <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>" 00099 Namespace: vigra 00100 */ 00101 template <class IMAGEITERATOR, class PIXELTYPE, 00102 class REFERENCE, class POINTER, class LINESTARTITERATOR> 00103 class BasicImageIteratorBase 00104 { 00105 public: 00106 typedef BasicImageIteratorBase<IMAGEITERATOR, 00107 PIXELTYPE, REFERENCE, POINTER, LINESTARTITERATOR> self_type; 00108 00109 typedef LINESTARTITERATOR LineStartIterator; 00110 typedef PIXELTYPE value_type; 00111 typedef PIXELTYPE PixelType; 00112 typedef REFERENCE reference; 00113 typedef REFERENCE index_reference; 00114 typedef POINTER pointer; 00115 typedef Diff2D difference_type; 00116 typedef image_traverser_tag iterator_category; 00117 typedef POINTER row_iterator; 00118 typedef IteratorAdaptor<LineBasedColumnIteratorPolicy<IMAGEITERATOR> > 00119 column_iterator; 00120 00121 typedef int MoveX; 00122 typedef LINESTARTITERATOR MoveY; 00123 00124 MoveX x; 00125 MoveY y; 00126 00127 IMAGEITERATOR & operator+=(difference_type const & s) 00128 { 00129 x += s.x; 00130 y += s.y; 00131 return static_cast<IMAGEITERATOR &>(*this); 00132 } 00133 00134 IMAGEITERATOR & operator-=(difference_type const & s) 00135 { 00136 x -= s.x; 00137 y -= s.y; 00138 return static_cast<IMAGEITERATOR &>(*this); 00139 } 00140 00141 IMAGEITERATOR operator+(difference_type const & s) const 00142 { 00143 IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this)); 00144 00145 ret += s; 00146 00147 return ret; 00148 } 00149 00150 IMAGEITERATOR operator-(difference_type const & s) const 00151 { 00152 IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this)); 00153 00154 ret -= s; 00155 00156 return ret; 00157 } 00158 00159 difference_type operator-(BasicImageIteratorBase const & rhs) const 00160 { 00161 return difference_type(x - rhs.x, y - rhs.y); 00162 } 00163 00164 bool operator==(BasicImageIteratorBase const & rhs) const 00165 { 00166 return (x == rhs.x) && (y == rhs.y); 00167 } 00168 00169 bool operator!=(BasicImageIteratorBase const & rhs) const 00170 { 00171 return (x != rhs.x) || (y != rhs.y); 00172 } 00173 00174 reference operator*() const 00175 { 00176 return *(*y + x ); 00177 } 00178 00179 pointer operator->() const 00180 { 00181 return *y + x; 00182 } 00183 00184 index_reference operator[](difference_type const & d) const 00185 { 00186 return *(*(y + d.y) + x + d.x); 00187 } 00188 00189 index_reference operator()(int dx, int dy) const 00190 { 00191 return *(*(y + dy) + x + dx); 00192 } 00193 00194 pointer operator[](int dy) const 00195 { 00196 return y[dy] + x; 00197 } 00198 00199 row_iterator rowIterator() const 00200 { return *y + x; } 00201 00202 column_iterator columnIterator() const 00203 { 00204 typedef typename column_iterator::BaseType Iter; 00205 return column_iterator(Iter(y, x)); 00206 } 00207 00208 protected: 00209 BasicImageIteratorBase(LINESTARTITERATOR const & line) 00210 : x(0), 00211 y(line) 00212 {} 00213 00214 BasicImageIteratorBase(int ix, LINESTARTITERATOR const & line) 00215 : x(ix), 00216 y(line) 00217 {} 00218 00219 BasicImageIteratorBase() 00220 : x(0), 00221 y(0) 00222 {} 00223 }; 00224 00225 /********************************************************/ 00226 /* */ 00227 /* BasicImageIterator */ 00228 /* */ 00229 /********************************************************/ 00230 00231 /** Implementation of the standard image iterator for \ref vigra::BasicImage. 00232 See \ref vigra::ImageIterator for documentation. 00233 00234 <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>" 00235 Namespace: vigra 00236 */ 00237 template <class PIXELTYPE, class ITERATOR> 00238 class BasicImageIterator 00239 : public BasicImageIteratorBase<BasicImageIterator<PIXELTYPE, ITERATOR>, 00240 PIXELTYPE, PIXELTYPE &, PIXELTYPE *, ITERATOR> 00241 { 00242 public: 00243 00244 typedef BasicImageIteratorBase<BasicImageIterator, PIXELTYPE, 00245 PIXELTYPE &, PIXELTYPE *, ITERATOR> Base; 00246 00247 00248 BasicImageIterator(ITERATOR line) 00249 : Base(line) 00250 {} 00251 00252 BasicImageIterator() 00253 : Base() 00254 {} 00255 }; 00256 00257 /********************************************************/ 00258 /* */ 00259 /* ConstBasicImageIterator */ 00260 /* */ 00261 /********************************************************/ 00262 00263 /** Implementation of the standard const image iterator for \ref vigra::BasicImage. 00264 See \ref vigra::ConstImageIterator for documentation. 00265 00266 <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>" 00267 Namespace: vigra 00268 */ 00269 template <class PIXELTYPE, class ITERATOR> 00270 class ConstBasicImageIterator 00271 : public BasicImageIteratorBase<ConstBasicImageIterator<PIXELTYPE, ITERATOR>, 00272 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR> 00273 { 00274 public: 00275 00276 typedef BasicImageIteratorBase<ConstBasicImageIterator, 00277 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR> Base; 00278 00279 00280 ConstBasicImageIterator(ITERATOR line) 00281 : Base(line) 00282 {} 00283 00284 ConstBasicImageIterator(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs) 00285 : Base(rhs.x, rhs.y) 00286 {} 00287 00288 ConstBasicImageIterator() 00289 : Base() 00290 {} 00291 00292 ConstBasicImageIterator & 00293 operator=(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs) 00294 { 00295 Base::x = rhs.x; 00296 Base::y = rhs.y; 00297 return *this; 00298 } 00299 00300 }; 00301 00302 /********************************************************/ 00303 /* */ 00304 /* definition of iterator traits */ 00305 /* */ 00306 /********************************************************/ 00307 00308 00309 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION 00310 00311 template <class T> 00312 struct IteratorTraits<BasicImageIterator<T, T**> > 00313 : public IteratorTraitsBase<BasicImageIterator<T, T**> > 00314 { 00315 typedef typename AccessorTraits<T>::default_accessor DefaultAccessor; 00316 typedef DefaultAccessor default_accessor; 00317 }; 00318 00319 template <class T> 00320 struct IteratorTraits<ConstBasicImageIterator<T, T**> > 00321 : public IteratorTraitsBase<ConstBasicImageIterator<T, T**> > 00322 { 00323 typedef typename AccessorTraits<T>::default_const_accessor DefaultAccessor; 00324 typedef DefaultAccessor default_accessor; 00325 }; 00326 00327 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION 00328 00329 #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \ 00330 template <> \ 00331 struct IteratorTraits<BasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00332 : public IteratorTraitsBase<BasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00333 { \ 00334 typedef typename AccessorTraits<VALUETYPE >::default_accessor DefaultAccessor; \ 00335 typedef DefaultAccessor default_accessor; \ 00336 }; \ 00337 \ 00338 template <> \ 00339 struct IteratorTraits<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00340 : public IteratorTraitsBase<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00341 { \ 00342 typedef typename AccessorTraits<VALUETYPE >::default_const_accessor DefaultAccessor; \ 00343 typedef DefaultAccessor default_accessor; \ 00344 }; 00345 00346 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>) 00347 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>) 00348 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>) 00349 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>) 00350 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>) 00351 00352 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2> 00353 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00354 #undef VIGRA_PIXELTYPE 00355 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3> 00356 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00357 #undef VIGRA_PIXELTYPE 00358 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4> 00359 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00360 #undef VIGRA_PIXELTYPE 00361 #define VIGRA_PIXELTYPE TinyVector<short, 2> 00362 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00363 #undef VIGRA_PIXELTYPE 00364 #define VIGRA_PIXELTYPE TinyVector<short, 3> 00365 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00366 #undef VIGRA_PIXELTYPE 00367 #define VIGRA_PIXELTYPE TinyVector<short, 4> 00368 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00369 #undef VIGRA_PIXELTYPE 00370 #define VIGRA_PIXELTYPE TinyVector<int, 2> 00371 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00372 #undef VIGRA_PIXELTYPE 00373 #define VIGRA_PIXELTYPE TinyVector<int, 3> 00374 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00375 #undef VIGRA_PIXELTYPE 00376 #define VIGRA_PIXELTYPE TinyVector<int, 4> 00377 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00378 #undef VIGRA_PIXELTYPE 00379 #define VIGRA_PIXELTYPE TinyVector<float, 2> 00380 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00381 #undef VIGRA_PIXELTYPE 00382 #define VIGRA_PIXELTYPE TinyVector<float, 3> 00383 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00384 #undef VIGRA_PIXELTYPE 00385 #define VIGRA_PIXELTYPE TinyVector<float, 4> 00386 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00387 #undef VIGRA_PIXELTYPE 00388 #define VIGRA_PIXELTYPE TinyVector<double, 2> 00389 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00390 #undef VIGRA_PIXELTYPE 00391 #define VIGRA_PIXELTYPE TinyVector<double, 3> 00392 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00393 #undef VIGRA_PIXELTYPE 00394 #define VIGRA_PIXELTYPE TinyVector<double, 4> 00395 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00396 #undef VIGRA_PIXELTYPE 00397 00398 #undef VIGRA_DEFINE_ITERATORTRAITS 00399 00400 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 00401 00402 /********************************************************/ 00403 /* */ 00404 /* BasicImage */ 00405 /* */ 00406 /********************************************************/ 00407 00408 /** \brief Fundamental class template for images. 00409 00410 A customized memory allocator can be specified as a templated argument 00411 ans passed in the constructor. 00412 00413 <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>" 00414 00415 Namespace: vigra 00416 */ 00417 template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> > 00418 class BasicImage 00419 { 00420 public: 00421 00422 /** the BasicImage's pixel type 00423 */ 00424 typedef PIXELTYPE value_type; 00425 00426 /** the BasicImage's pixel type 00427 */ 00428 typedef PIXELTYPE PixelType; 00429 00430 /** the BasicImage's reference type (i.e. the 00431 return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>) 00432 */ 00433 typedef PIXELTYPE & reference; 00434 00435 /** the BasicImage's const reference type (i.e. the 00436 return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT> 00437 when <TT>image</TT> is const) 00438 */ 00439 typedef PIXELTYPE const & const_reference; 00440 00441 /** the BasicImage's pointer type 00442 */ 00443 typedef PIXELTYPE * pointer; 00444 00445 /** the BasicImage's const pointer type 00446 */ 00447 typedef PIXELTYPE const * const_pointer; 00448 00449 /** the BasicImage's 1D random access iterator 00450 (note: lower case 'iterator' is a STL compatible 1D random 00451 access iterator, don't confuse with capitalized Iterator) 00452 */ 00453 typedef PIXELTYPE * iterator; 00454 00455 /** deprecated, use <TT>iterator</TT> instead 00456 */ 00457 typedef PIXELTYPE * ScanOrderIterator; 00458 00459 /** the BasicImage's 1D random access const iterator 00460 (note: lower case 'const_iterator' is a STL compatible 1D 00461 random access const iterator) 00462 */ 00463 typedef PIXELTYPE const * const_iterator; 00464 00465 /** deprecated, use <TT>const_iterator</TT> instead 00466 */ 00467 typedef PIXELTYPE const * ConstScanOrderIterator; 00468 00469 /** the BasicImage's 2D random access iterator ('traverser') 00470 */ 00471 typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser; 00472 00473 /** deprecated, use <TT>traverser</TT> instead 00474 */ 00475 typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator; 00476 00477 /** the BasicImage's 2D random access const iterator ('const traverser') 00478 */ 00479 typedef 00480 ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **> 00481 const_traverser; 00482 00483 /** deprecated, use <TT>const_traverser</TT> instead 00484 */ 00485 typedef 00486 ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **> 00487 ConstIterator; 00488 00489 /** the BasicImage's difference type (argument type of image[diff]) 00490 */ 00491 typedef Diff2D difference_type; 00492 00493 /** the BasicImage's size type (result type of image.size()) 00494 */ 00495 typedef Size2D size_type; 00496 00497 /** the BasicImage's default accessor 00498 */ 00499 typedef typename 00500 IteratorTraits<traverser>::DefaultAccessor Accessor; 00501 00502 /** the BasicImage's default const accessor 00503 */ 00504 typedef typename 00505 IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor; 00506 00507 /** the BasicImage's allocator (default: std::allocator<value_type>) 00508 */ 00509 typedef Alloc allocator_type; 00510 00511 typedef Alloc Allocator; 00512 typedef typename Alloc::template rebind<PIXELTYPE *>::other LineAllocator; 00513 00514 /** construct image of size 0x0 00515 */ 00516 BasicImage() 00517 : data_(0), 00518 width_(0), 00519 height_(0) 00520 {} 00521 00522 /** construct image of size 0x0, use the specified allocator. 00523 */ 00524 explicit BasicImage(Alloc const & alloc) 00525 : data_(0), 00526 width_(0), 00527 height_(0), 00528 allocator_(alloc), 00529 pallocator_(alloc) 00530 {} 00531 00532 /** construct image of size width x height, use the specified allocator. 00533 */ 00534 BasicImage(int width, int height, Alloc const & alloc = Alloc()) 00535 : data_(0), 00536 width_(0), 00537 height_(0), 00538 allocator_(alloc), 00539 pallocator_(alloc) 00540 { 00541 vigra_precondition((width >= 0) && (height >= 0), 00542 "BasicImage::BasicImage(int width, int height): " 00543 "width and height must be >= 0.\n"); 00544 00545 resize(width, height, value_type()); 00546 } 00547 00548 /** construct image of size size.x x size.y, use the specified allocator. 00549 */ 00550 explicit BasicImage(difference_type const & size, Alloc const & alloc = Alloc()) 00551 : data_(0), 00552 width_(0), 00553 height_(0), 00554 allocator_(alloc), 00555 pallocator_(alloc) 00556 { 00557 vigra_precondition((size.x >= 0) && (size.y >= 0), 00558 "BasicImage::BasicImage(Diff2D size): " 00559 "size.x and size.y must be >= 0.\n"); 00560 00561 resize(size.x, size.y, value_type()); 00562 } 00563 00564 /** construct image of size width*height and initialize every 00565 pixel with the value \a d (use this constructor, if 00566 value_type doesn't have a default constructor). 00567 Use the specified allocator. 00568 */ 00569 BasicImage(int width, int height, value_type const & d, Alloc const & alloc = Alloc()) 00570 : data_(0), 00571 width_(0), 00572 height_(0), 00573 allocator_(alloc), 00574 pallocator_(alloc) 00575 { 00576 vigra_precondition((width >= 0) && (height >= 0), 00577 "BasicImage::BasicImage(int width, int height, value_type const & ): " 00578 "width and height must be >= 0.\n"); 00579 00580 resize(width, height, d); 00581 } 00582 00583 /** construct image of size size.x x size.y and initialize 00584 every pixel with given data (use this constructor, if 00585 value_type doesn't have a default constructor). Use the specified allocator. 00586 */ 00587 explicit BasicImage(difference_type const & size, value_type const & d, Alloc const & alloc = Alloc()) 00588 : data_(0), 00589 width_(0), 00590 height_(0), 00591 allocator_(alloc), 00592 pallocator_(alloc) 00593 { 00594 vigra_precondition((size.x >= 0) && (size.y >= 0), 00595 "BasicImage::BasicImage(Diff2D const & size, value_type const & v): " 00596 "size.x and size.y must be >= 0.\n"); 00597 00598 resize(size.x, size.y, d); 00599 } 00600 00601 00602 /** construct image of size width*height and copy the data from the 00603 given C-style array \a d. Use the specified allocator. 00604 */ 00605 BasicImage(int width, int height, const_pointer d, 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, const_pointer ): " 00614 "width and height must be >= 0.\n"); 00615 00616 resizeCopy(width, height, d); 00617 } 00618 00619 /** construct image of size size.x x size.y and copy the data from the 00620 given C-style array. Use the specified allocator. 00621 */ 00622 explicit BasicImage(difference_type const & size, const_pointer d, Alloc const & alloc = Alloc()) 00623 : data_(0), 00624 width_(0), 00625 height_(0), 00626 allocator_(alloc), 00627 pallocator_(alloc) 00628 { 00629 vigra_precondition((size.x >= 0) && (size.y >= 0), 00630 "BasicImage::BasicImage(Diff2D const & size, const_pointer): " 00631 "size.x and size.y must be >= 0.\n"); 00632 00633 resizeCopy(size.x, size.y, d); 00634 } 00635 00636 /** copy rhs image 00637 */ 00638 BasicImage(const BasicImage & rhs) 00639 : data_(0), 00640 width_(0), 00641 height_(0), 00642 allocator_(rhs.allocator_), 00643 pallocator_(rhs.pallocator_) 00644 { 00645 resizeCopy(rhs); 00646 } 00647 00648 /** destructor 00649 */ 00650 ~BasicImage() 00651 { 00652 deallocate(); 00653 } 00654 00655 /** copy rhs image (image is resized if necessary) 00656 */ 00657 BasicImage & operator=(const BasicImage & rhs); 00658 00659 /** \deprecated set Image with const value 00660 */ 00661 BasicImage & operator=(value_type pixel); 00662 00663 /** set Image with const value 00664 */ 00665 BasicImage & init(value_type const & pixel); 00666 00667 /** reset image to specified size (dimensions must not be negative) 00668 (old data are kept if new size matches old size) 00669 */ 00670 void resize(int width, int height) 00671 { 00672 if(width != width_ || height != height_) 00673 resize(width, height, value_type()); 00674 } 00675 00676 /** reset image to specified size (dimensions must not be negative) 00677 (old data are kept if new size matches old size) 00678 */ 00679 void resize(difference_type const & size) 00680 { 00681 if(size.x != width_ || size.y != height_) 00682 { 00683 resize(size.x, size.y, value_type()); 00684 } 00685 } 00686 00687 /** reset image to specified size and initialize it with 00688 given data (use this if value_type doesn't have a default 00689 constructor, dimensions must not be negative, 00690 old data are kept if new size matches old size) 00691 */ 00692 void resize(int width, int height, value_type const & d); 00693 00694 /** resize image to given size and initialize by copying data 00695 from the C-style arra \a data. 00696 */ 00697 void resizeCopy(int width, int height, const_pointer data); 00698 00699 /** resize image to size of other image and copy it's data 00700 */ 00701 void resizeCopy(const BasicImage & rhs) 00702 { 00703 resizeCopy(rhs.width(), rhs.height(), rhs.data_); 00704 } 00705 00706 /** swap the internal data with the rhs image in constant time 00707 */ 00708 void swap( BasicImage & rhs ); 00709 00710 /** width of Image 00711 */ 00712 int width() const 00713 { 00714 return width_; 00715 } 00716 00717 /** height of Image 00718 */ 00719 int height() const 00720 { 00721 return height_; 00722 } 00723 00724 /** size of Image 00725 */ 00726 size_type size() const 00727 { 00728 return size_type(width(), height()); 00729 } 00730 00731 /** test whether a given coordinate is inside the image 00732 */ 00733 bool isInside(difference_type const & d) const 00734 { 00735 return d.x >= 0 && d.y >= 0 && 00736 d.x < width() && d.y < height(); 00737 } 00738 00739 /** access pixel at given location. <br> 00740 usage: <TT> value_type value = image[Diff2D(1,2)] </TT> 00741 */ 00742 reference operator[](difference_type const & d) 00743 { 00744 return lines_[d.y][d.x]; 00745 } 00746 00747 /** read pixel at given location. <br> 00748 usage: <TT> value_type value = image[Diff2D(1,2)] </TT> 00749 */ 00750 const_reference operator[](difference_type const & d) const 00751 { 00752 return lines_[d.y][d.x]; 00753 } 00754 00755 /** access pixel at given location. <br> 00756 usage: <TT> value_type value = image(1,2) </TT> 00757 */ 00758 reference operator()(int dx, int dy) 00759 { 00760 return lines_[dy][dx]; 00761 } 00762 00763 /** read pixel at given location. <br> 00764 usage: <TT> value_type value = image(1,2) </TT> 00765 */ 00766 const_reference operator()(int dx, int dy) const 00767 { 00768 return lines_[dy][dx]; 00769 } 00770 00771 /** access pixel at given location. 00772 Note that the 'x' index is the trailing index. <br> 00773 usage: <TT> value_type value = image[2][1] </TT> 00774 */ 00775 pointer operator[](int dy) 00776 { 00777 return lines_[dy]; 00778 } 00779 00780 /** read pixel at given location. 00781 Note that the 'x' index is the trailing index. <br> 00782 usage: <TT> value_type value = image[2][1] </TT> 00783 */ 00784 const_pointer operator[](int dy) const 00785 { 00786 return lines_[dy]; 00787 } 00788 00789 /** init 2D random access iterator poining to upper left pixel 00790 */ 00791 traverser upperLeft() 00792 { 00793 vigra_precondition(data_ != 0, 00794 "BasicImage::upperLeft(): image must have non-zero size."); 00795 return traverser(lines_); 00796 } 00797 00798 /** init 2D random access iterator poining to 00799 pixel(width, height), i.e. one pixel right and below lower right 00800 corner of the image as is common in C/C++. 00801 */ 00802 traverser lowerRight() 00803 { 00804 vigra_precondition(data_ != 0, 00805 "BasicImage::lowerRight(): image must have non-zero size."); 00806 return upperLeft() + size(); 00807 } 00808 00809 /** init 2D random access const iterator poining to upper left pixel 00810 */ 00811 const_traverser upperLeft() const 00812 { 00813 vigra_precondition(data_ != 0, 00814 "BasicImage::upperLeft(): image must have non-zero size."); 00815 return const_traverser(const_cast<PIXELTYPE **>(lines_)); 00816 } 00817 00818 /** init 2D random access const iterator poining to 00819 pixel(width, height), i.e. one pixel right and below lower right 00820 corner of the image as is common in C/C++. 00821 */ 00822 const_traverser lowerRight() const 00823 { 00824 vigra_precondition(data_ != 0, 00825 "BasicImage::lowerRight(): image must have non-zero size."); 00826 return upperLeft() + size(); 00827 } 00828 00829 /** init 1D random access iterator pointing to first pixel 00830 */ 00831 iterator begin() 00832 { 00833 vigra_precondition(data_ != 0, 00834 "BasicImage::begin(): image must have non-zero size."); 00835 return data_; 00836 } 00837 00838 /** init 1D random access iterator pointing past the end 00839 */ 00840 iterator end() 00841 { 00842 vigra_precondition(data_ != 0, 00843 "BasicImage::end(): image must have non-zero size."); 00844 return data_ + width() * height(); 00845 } 00846 00847 /** init 1D random access const iterator pointing to first pixel 00848 */ 00849 const_iterator begin() const 00850 { 00851 vigra_precondition(data_ != 0, 00852 "BasicImage::begin(): image must have non-zero size."); 00853 return data_; 00854 } 00855 00856 /** init 1D random access const iterator pointing past the end 00857 */ 00858 const_iterator end() const 00859 { 00860 vigra_precondition(data_ != 0, 00861 "BasicImage::end(): image must have non-zero size."); 00862 return data_ + width() * height(); 00863 } 00864 00865 /** return default accessor 00866 */ 00867 Accessor accessor() 00868 { 00869 return Accessor(); 00870 } 00871 00872 /** return default const accessor 00873 */ 00874 ConstAccessor accessor() const 00875 { 00876 return ConstAccessor(); 00877 } 00878 00879 private: 00880 00881 void deallocate(); 00882 00883 value_type ** initLineStartArray(value_type * data, int width, int height); 00884 00885 PIXELTYPE * data_; 00886 PIXELTYPE ** lines_; 00887 int width_, height_; 00888 Alloc allocator_; 00889 LineAllocator pallocator_; 00890 }; 00891 00892 template <class PIXELTYPE, class Alloc> 00893 BasicImage<PIXELTYPE, Alloc> & 00894 BasicImage<PIXELTYPE, Alloc>::operator=(const BasicImage<PIXELTYPE, Alloc> & rhs) 00895 { 00896 if(this != &rhs) 00897 { 00898 if((width() != rhs.width()) || 00899 (height() != rhs.height())) 00900 { 00901 resizeCopy(rhs); 00902 } 00903 else 00904 { 00905 ConstScanOrderIterator is = rhs.begin(); 00906 ConstScanOrderIterator iend = rhs.end(); 00907 ScanOrderIterator id = begin(); 00908 00909 for(; is != iend; ++is, ++id) *id = *is; 00910 } 00911 } 00912 return *this; 00913 } 00914 00915 template <class PIXELTYPE, class Alloc> 00916 BasicImage<PIXELTYPE, Alloc> & 00917 BasicImage<PIXELTYPE, Alloc>::operator=(value_type pixel) 00918 { 00919 ScanOrderIterator i = begin(); 00920 ScanOrderIterator iend = end(); 00921 00922 for(; i != iend; ++i) *i = pixel; 00923 00924 return *this; 00925 } 00926 00927 template <class PIXELTYPE, class Alloc> 00928 BasicImage<PIXELTYPE, Alloc> & 00929 BasicImage<PIXELTYPE, Alloc>::init(value_type const & pixel) 00930 { 00931 ScanOrderIterator i = begin(); 00932 ScanOrderIterator iend = end(); 00933 00934 for(; i != iend; ++i) *i = pixel; 00935 00936 return *this; 00937 } 00938 00939 template <class PIXELTYPE, class Alloc> 00940 void 00941 BasicImage<PIXELTYPE, Alloc>::resize(int width, int height, value_type const & d) 00942 { 00943 vigra_precondition((width >= 0) && (height >= 0), 00944 "BasicImage::resize(int width, int height, value_type const &): " 00945 "width and height must be >= 0.\n"); 00946 00947 if (width_ != width || height_ != height) // change size? 00948 { 00949 value_type * newdata = 0; 00950 value_type ** newlines = 0; 00951 if(width*height > 0) 00952 { 00953 if (width*height != width_*height_) // different sizes, must reallocate 00954 { 00955 newdata = allocator_.allocate(width*height); 00956 std::uninitialized_fill_n(newdata, width*height, d); 00957 newlines = initLineStartArray(newdata, width, height); 00958 deallocate(); 00959 } 00960 else // need only to reshape 00961 { 00962 newdata = data_; 00963 std::fill_n(newdata, width*height, d); 00964 newlines = initLineStartArray(newdata, width, height); 00965 pallocator_.deallocate(lines_, height_); 00966 } 00967 } 00968 else 00969 { 00970 deallocate(); 00971 } 00972 00973 data_ = newdata; 00974 lines_ = newlines; 00975 width_ = width; 00976 height_ = height; 00977 } 00978 else if(width*height > 0) // keep size, re-init data 00979 { 00980 std::fill_n(data_, width*height, d); 00981 } 00982 } 00983 00984 00985 template <class PIXELTYPE, class Alloc> 00986 void 00987 BasicImage<PIXELTYPE, Alloc>::resizeCopy(int width, int height, const_pointer data) 00988 { 00989 int newsize = width*height; 00990 if (width_ != width || height_ != height) // change size? 00991 { 00992 value_type * newdata = 0; 00993 value_type ** newlines = 0; 00994 if(newsize > 0) 00995 { 00996 if (newsize != width_*height_) // different sizes, must reallocate 00997 { 00998 newdata = allocator_.allocate(newsize); 00999 std::uninitialized_copy(data, data + newsize, newdata); 01000 newlines = initLineStartArray(newdata, width, height); 01001 deallocate(); 01002 } 01003 else // need only to reshape 01004 { 01005 newdata = data_; 01006 std::copy(data, data + newsize, newdata); 01007 newlines = initLineStartArray(newdata, width, height); 01008 pallocator_.deallocate(lines_, height_); 01009 } 01010 } 01011 else 01012 { 01013 deallocate(); 01014 } 01015 01016 data_ = newdata; 01017 lines_ = newlines; 01018 width_ = width; 01019 height_ = height; 01020 } 01021 else if(newsize > 0) // keep size, copy data 01022 { 01023 std::copy(data, data + newsize, data_); 01024 } 01025 } 01026 01027 template <class PIXELTYPE, class Alloc> 01028 void 01029 BasicImage<PIXELTYPE, Alloc>::swap( BasicImage<PIXELTYPE, Alloc>& rhs ) 01030 { 01031 if (&rhs!=this) 01032 { 01033 std::swap( data_, rhs.data_ ); 01034 std::swap( lines_, rhs.lines_ ); 01035 std::swap( width_, rhs.width_ ); 01036 std::swap( height_, rhs.height_ ); 01037 } 01038 } 01039 01040 template <class PIXELTYPE, class Alloc> 01041 void 01042 BasicImage<PIXELTYPE, Alloc>::deallocate() 01043 { 01044 if(data_) 01045 { 01046 ScanOrderIterator i = begin(); 01047 ScanOrderIterator iend = end(); 01048 01049 for(; i != iend; ++i) (*i).~PIXELTYPE(); 01050 01051 allocator_.deallocate(data_, width()*height()); 01052 pallocator_.deallocate(lines_, height_); 01053 } 01054 } 01055 01056 template <class PIXELTYPE, class Alloc> 01057 PIXELTYPE ** 01058 BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, int width, int height) 01059 { 01060 value_type ** lines = pallocator_.allocate(height); 01061 for(int y=0; y<height; ++y) 01062 lines[y] = data + y*width; 01063 return lines; 01064 } 01065 01066 /********************************************************/ 01067 /* */ 01068 /* argument object factories */ 01069 /* */ 01070 /********************************************************/ 01071 01072 template <class PixelType, class Accessor, class Alloc> 01073 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01074 typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01075 srcImageRange(BasicImage<PixelType, Alloc> const & img, Accessor a) 01076 { 01077 return triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01078 typename BasicImage<PixelType, Alloc>::const_traverser, 01079 Accessor>(img.upperLeft(), 01080 img.lowerRight(), 01081 a); 01082 } 01083 01084 template <class PixelType, class Accessor, class Alloc> 01085 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01086 srcImage(BasicImage<PixelType, Alloc> const & img, Accessor a) 01087 { 01088 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01089 Accessor>(img.upperLeft(), a); 01090 } 01091 01092 template <class PixelType, class Accessor, class Alloc> 01093 inline triple<typename BasicImage<PixelType, Alloc>::traverser, 01094 typename BasicImage<PixelType, Alloc>::traverser, Accessor> 01095 destImageRange(BasicImage<PixelType, Alloc> & img, Accessor a) 01096 { 01097 return triple<typename BasicImage<PixelType, Alloc>::traverser, 01098 typename BasicImage<PixelType, Alloc>::traverser, 01099 Accessor>(img.upperLeft(), 01100 img.lowerRight(), 01101 a); 01102 } 01103 01104 template <class PixelType, class Accessor, class Alloc> 01105 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor> 01106 destImage(BasicImage<PixelType, Alloc> & img, Accessor a) 01107 { 01108 return pair<typename BasicImage<PixelType, Alloc>::traverser, 01109 Accessor>(img.upperLeft(), a); 01110 } 01111 01112 template <class PixelType, class Accessor, class Alloc> 01113 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01114 maskImage(BasicImage<PixelType, Alloc> const & img, Accessor a) 01115 { 01116 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01117 Accessor>(img.upperLeft(), a); 01118 } 01119 01120 /****************************************************************/ 01121 01122 template <class PixelType, class Alloc> 01123 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01124 typename BasicImage<PixelType, Alloc>::const_traverser, 01125 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01126 srcImageRange(BasicImage<PixelType, Alloc> const & img) 01127 { 01128 return triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01129 typename BasicImage<PixelType, Alloc>::const_traverser, 01130 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(), 01131 img.lowerRight(), 01132 img.accessor()); 01133 } 01134 01135 template <class PixelType, class Alloc> 01136 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser, 01137 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01138 srcImage(BasicImage<PixelType, Alloc> const & img) 01139 { 01140 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01141 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(), 01142 img.accessor()); 01143 } 01144 01145 template <class PixelType, class Alloc> 01146 inline triple< typename BasicImage<PixelType, Alloc>::traverser, 01147 typename BasicImage<PixelType, Alloc>::traverser, 01148 typename BasicImage<PixelType, Alloc>::Accessor> 01149 destImageRange(BasicImage<PixelType, Alloc> & img) 01150 { 01151 return triple<typename BasicImage<PixelType, Alloc>::traverser, 01152 typename BasicImage<PixelType, Alloc>::traverser, 01153 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(), 01154 img.lowerRight(), 01155 img.accessor()); 01156 } 01157 01158 template <class PixelType, class Alloc> 01159 inline pair< typename BasicImage<PixelType, Alloc>::traverser, 01160 typename BasicImage<PixelType, Alloc>::Accessor> 01161 destImage(BasicImage<PixelType, Alloc> & img) 01162 { 01163 return pair<typename BasicImage<PixelType, Alloc>::traverser, 01164 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(), 01165 img.accessor()); 01166 } 01167 01168 template <class PixelType, class Alloc> 01169 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser, 01170 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01171 maskImage(BasicImage<PixelType, Alloc> const & img) 01172 { 01173 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01174 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(), 01175 img.accessor()); 01176 } 01177 01178 } // namespace vigra 01179 01180 #endif // VIGRA_BASICIMAGE_HXX
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|