[ 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.3, Aug 18 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 typedef VigraTrueType hasConstantStrides; 00318 }; 00319 00320 template <class T> 00321 struct IteratorTraits<ConstBasicImageIterator<T, T**> > 00322 : public IteratorTraitsBase<ConstBasicImageIterator<T, T**> > 00323 { 00324 typedef typename AccessorTraits<T>::default_const_accessor DefaultAccessor; 00325 typedef DefaultAccessor default_accessor; 00326 typedef VigraTrueType hasConstantStrides; 00327 }; 00328 00329 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION 00330 00331 #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \ 00332 template <> \ 00333 struct IteratorTraits<BasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00334 : public IteratorTraitsBase<BasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00335 { \ 00336 typedef typename AccessorTraits<VALUETYPE >::default_accessor DefaultAccessor; \ 00337 typedef DefaultAccessor default_accessor; \ 00338 typedef VigraTrueType hasConstantStrides; \ 00339 }; \ 00340 \ 00341 template <> \ 00342 struct IteratorTraits<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00343 : public IteratorTraitsBase<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \ 00344 { \ 00345 typedef typename AccessorTraits<VALUETYPE >::default_const_accessor DefaultAccessor; \ 00346 typedef DefaultAccessor default_accessor; \ 00347 typedef VigraTrueType hasConstantStrides; \ 00348 }; 00349 00350 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>) 00351 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>) 00352 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>) 00353 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>) 00354 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>) 00355 00356 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2> 00357 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00358 #undef VIGRA_PIXELTYPE 00359 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3> 00360 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00361 #undef VIGRA_PIXELTYPE 00362 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4> 00363 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00364 #undef VIGRA_PIXELTYPE 00365 #define VIGRA_PIXELTYPE TinyVector<short, 2> 00366 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00367 #undef VIGRA_PIXELTYPE 00368 #define VIGRA_PIXELTYPE TinyVector<short, 3> 00369 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00370 #undef VIGRA_PIXELTYPE 00371 #define VIGRA_PIXELTYPE TinyVector<short, 4> 00372 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00373 #undef VIGRA_PIXELTYPE 00374 #define VIGRA_PIXELTYPE TinyVector<int, 2> 00375 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00376 #undef VIGRA_PIXELTYPE 00377 #define VIGRA_PIXELTYPE TinyVector<int, 3> 00378 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00379 #undef VIGRA_PIXELTYPE 00380 #define VIGRA_PIXELTYPE TinyVector<int, 4> 00381 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00382 #undef VIGRA_PIXELTYPE 00383 #define VIGRA_PIXELTYPE TinyVector<float, 2> 00384 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00385 #undef VIGRA_PIXELTYPE 00386 #define VIGRA_PIXELTYPE TinyVector<float, 3> 00387 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00388 #undef VIGRA_PIXELTYPE 00389 #define VIGRA_PIXELTYPE TinyVector<float, 4> 00390 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00391 #undef VIGRA_PIXELTYPE 00392 #define VIGRA_PIXELTYPE TinyVector<double, 2> 00393 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00394 #undef VIGRA_PIXELTYPE 00395 #define VIGRA_PIXELTYPE TinyVector<double, 3> 00396 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00397 #undef VIGRA_PIXELTYPE 00398 #define VIGRA_PIXELTYPE TinyVector<double, 4> 00399 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE) 00400 #undef VIGRA_PIXELTYPE 00401 00402 #undef VIGRA_DEFINE_ITERATORTRAITS 00403 00404 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 00405 00406 /********************************************************/ 00407 /* */ 00408 /* BasicImage */ 00409 /* */ 00410 /********************************************************/ 00411 00412 /** \brief Fundamental class template for images. 00413 00414 A customized memory allocator can be specified as a templated argument 00415 ans passed in the constructor. 00416 00417 <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>" 00418 00419 Namespace: vigra 00420 */ 00421 template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> > 00422 class BasicImage 00423 { 00424 public: 00425 00426 /** the BasicImage's pixel type 00427 */ 00428 typedef PIXELTYPE value_type; 00429 00430 /** the BasicImage's pixel type 00431 */ 00432 typedef PIXELTYPE PixelType; 00433 00434 /** the BasicImage's reference type (i.e. the 00435 return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>) 00436 */ 00437 typedef PIXELTYPE & reference; 00438 00439 /** the BasicImage's const reference type (i.e. the 00440 return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT> 00441 when <TT>image</TT> is const) 00442 */ 00443 typedef PIXELTYPE const & const_reference; 00444 00445 /** the BasicImage's pointer type 00446 */ 00447 typedef PIXELTYPE * pointer; 00448 00449 /** the BasicImage's const pointer type 00450 */ 00451 typedef PIXELTYPE const * const_pointer; 00452 00453 /** the BasicImage's 1D random access iterator 00454 (note: lower case 'iterator' is a STL compatible 1D random 00455 access iterator, don't confuse with capitalized Iterator) 00456 */ 00457 typedef PIXELTYPE * iterator; 00458 00459 /** deprecated, use <TT>iterator</TT> instead 00460 */ 00461 typedef PIXELTYPE * ScanOrderIterator; 00462 00463 /** the BasicImage's 1D random access const iterator 00464 (note: lower case 'const_iterator' is a STL compatible 1D 00465 random access const iterator) 00466 */ 00467 typedef PIXELTYPE const * const_iterator; 00468 00469 /** deprecated, use <TT>const_iterator</TT> instead 00470 */ 00471 typedef PIXELTYPE const * ConstScanOrderIterator; 00472 00473 /** the BasicImage's 2D random access iterator ('traverser') 00474 */ 00475 typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser; 00476 00477 /** deprecated, use <TT>traverser</TT> instead 00478 */ 00479 typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator; 00480 00481 /** the BasicImage's 2D random access const iterator ('const traverser') 00482 */ 00483 typedef 00484 ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **> 00485 const_traverser; 00486 00487 /** deprecated, use <TT>const_traverser</TT> instead 00488 */ 00489 typedef 00490 ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **> 00491 ConstIterator; 00492 00493 /** the BasicImage's difference type (argument type of image[diff]) 00494 */ 00495 typedef Diff2D difference_type; 00496 00497 /** the BasicImage's size type (result type of image.size()) 00498 */ 00499 typedef Size2D size_type; 00500 00501 /** the BasicImage's default accessor 00502 */ 00503 typedef typename 00504 IteratorTraits<traverser>::DefaultAccessor Accessor; 00505 00506 /** the BasicImage's default const accessor 00507 */ 00508 typedef typename 00509 IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor; 00510 00511 /** the BasicImage's allocator (default: std::allocator<value_type>) 00512 */ 00513 typedef Alloc allocator_type; 00514 00515 typedef Alloc Allocator; 00516 typedef typename Alloc::template rebind<PIXELTYPE *>::other LineAllocator; 00517 00518 /** construct image of size 0x0 00519 */ 00520 BasicImage() 00521 : data_(0), 00522 width_(0), 00523 height_(0) 00524 {} 00525 00526 /** construct image of size 0x0, use the specified allocator. 00527 */ 00528 explicit BasicImage(Alloc const & alloc) 00529 : data_(0), 00530 width_(0), 00531 height_(0), 00532 allocator_(alloc), 00533 pallocator_(alloc) 00534 {} 00535 00536 /** construct image of size width x height, use the specified allocator. 00537 */ 00538 BasicImage(int width, int height, Alloc const & alloc = Alloc()) 00539 : data_(0), 00540 width_(0), 00541 height_(0), 00542 allocator_(alloc), 00543 pallocator_(alloc) 00544 { 00545 vigra_precondition((width >= 0) && (height >= 0), 00546 "BasicImage::BasicImage(int width, int height): " 00547 "width and height must be >= 0.\n"); 00548 00549 resize(width, height, value_type()); 00550 } 00551 00552 /** construct image of size size.x x size.y, use the specified allocator. 00553 */ 00554 explicit BasicImage(difference_type const & size, Alloc const & alloc = Alloc()) 00555 : data_(0), 00556 width_(0), 00557 height_(0), 00558 allocator_(alloc), 00559 pallocator_(alloc) 00560 { 00561 vigra_precondition((size.x >= 0) && (size.y >= 0), 00562 "BasicImage::BasicImage(Diff2D size): " 00563 "size.x and size.y must be >= 0.\n"); 00564 00565 resize(size.x, size.y, value_type()); 00566 } 00567 00568 /** construct image of size width*height and initialize every 00569 pixel with the value \a d (use this constructor, if 00570 value_type doesn't have a default constructor). 00571 Use the specified allocator. 00572 */ 00573 BasicImage(int width, int height, value_type const & d, Alloc const & alloc = Alloc()) 00574 : data_(0), 00575 width_(0), 00576 height_(0), 00577 allocator_(alloc), 00578 pallocator_(alloc) 00579 { 00580 vigra_precondition((width >= 0) && (height >= 0), 00581 "BasicImage::BasicImage(int width, int height, value_type const & ): " 00582 "width and height must be >= 0.\n"); 00583 00584 resize(width, height, d); 00585 } 00586 00587 /** construct image of size size.x x size.y and initialize 00588 every pixel with given data (use this constructor, if 00589 value_type doesn't have a default constructor). Use the specified allocator. 00590 */ 00591 explicit BasicImage(difference_type const & size, value_type const & d, Alloc const & alloc = Alloc()) 00592 : data_(0), 00593 width_(0), 00594 height_(0), 00595 allocator_(alloc), 00596 pallocator_(alloc) 00597 { 00598 vigra_precondition((size.x >= 0) && (size.y >= 0), 00599 "BasicImage::BasicImage(Diff2D const & size, value_type const & v): " 00600 "size.x and size.y must be >= 0.\n"); 00601 00602 resize(size.x, size.y, d); 00603 } 00604 00605 00606 /** construct image of size width*height and copy the data from the 00607 given C-style array \a d. Use the specified allocator. 00608 */ 00609 BasicImage(int width, int height, const_pointer d, Alloc const & alloc = Alloc()) 00610 : data_(0), 00611 width_(0), 00612 height_(0), 00613 allocator_(alloc), 00614 pallocator_(alloc) 00615 { 00616 vigra_precondition((width >= 0) && (height >= 0), 00617 "BasicImage::BasicImage(int width, int height, const_pointer ): " 00618 "width and height must be >= 0.\n"); 00619 00620 resizeCopy(width, height, d); 00621 } 00622 00623 /** construct image of size size.x x size.y and copy the data from the 00624 given C-style array. Use the specified allocator. 00625 */ 00626 explicit BasicImage(difference_type const & size, const_pointer d, Alloc const & alloc = Alloc()) 00627 : data_(0), 00628 width_(0), 00629 height_(0), 00630 allocator_(alloc), 00631 pallocator_(alloc) 00632 { 00633 vigra_precondition((size.x >= 0) && (size.y >= 0), 00634 "BasicImage::BasicImage(Diff2D const & size, const_pointer): " 00635 "size.x and size.y must be >= 0.\n"); 00636 00637 resizeCopy(size.x, size.y, d); 00638 } 00639 00640 /** copy rhs image 00641 */ 00642 BasicImage(const BasicImage & rhs) 00643 : data_(0), 00644 width_(0), 00645 height_(0), 00646 allocator_(rhs.allocator_), 00647 pallocator_(rhs.pallocator_) 00648 { 00649 resizeCopy(rhs); 00650 } 00651 00652 /** destructor 00653 */ 00654 ~BasicImage() 00655 { 00656 deallocate(); 00657 } 00658 00659 /** copy rhs image (image is resized if necessary) 00660 */ 00661 BasicImage & operator=(const BasicImage & rhs); 00662 00663 /** \deprecated set Image with const value 00664 */ 00665 BasicImage & operator=(value_type pixel); 00666 00667 /** set Image with const value 00668 */ 00669 BasicImage & init(value_type const & pixel); 00670 00671 /** reset image to specified size (dimensions must not be negative) 00672 (old data are kept if new size matches old size) 00673 */ 00674 void resize(int width, int height) 00675 { 00676 if(width != width_ || height != height_) 00677 resize(width, height, value_type()); 00678 } 00679 00680 /** reset image to specified size (dimensions must not be negative) 00681 (old data are kept if new size matches old size) 00682 */ 00683 void resize(difference_type const & size) 00684 { 00685 if(size.x != width_ || size.y != height_) 00686 { 00687 resize(size.x, size.y, value_type()); 00688 } 00689 } 00690 00691 /** reset image to specified size and initialize it with 00692 given data (use this if value_type doesn't have a default 00693 constructor, dimensions must not be negative, 00694 old data are kept if new size matches old size) 00695 */ 00696 void resize(int width, int height, value_type const & d); 00697 00698 /** resize image to given size and initialize by copying data 00699 from the C-style arra \a data. 00700 */ 00701 void resizeCopy(int width, int height, const_pointer data); 00702 00703 /** resize image to size of other image and copy it's data 00704 */ 00705 void resizeCopy(const BasicImage & rhs) 00706 { 00707 resizeCopy(rhs.width(), rhs.height(), rhs.data_); 00708 } 00709 00710 /** swap the internal data with the rhs image in constant time 00711 */ 00712 void swap( BasicImage & rhs ); 00713 00714 /** width of Image 00715 */ 00716 int width() const 00717 { 00718 return width_; 00719 } 00720 00721 /** height of Image 00722 */ 00723 int height() const 00724 { 00725 return height_; 00726 } 00727 00728 /** size of Image 00729 */ 00730 size_type size() const 00731 { 00732 return size_type(width(), height()); 00733 } 00734 00735 /** test whether a given coordinate is inside the image 00736 */ 00737 bool isInside(difference_type const & d) const 00738 { 00739 return d.x >= 0 && d.y >= 0 && 00740 d.x < width() && d.y < height(); 00741 } 00742 00743 /** access pixel at given location. <br> 00744 usage: <TT> value_type value = image[Diff2D(1,2)] </TT> 00745 */ 00746 reference operator[](difference_type const & d) 00747 { 00748 return lines_[d.y][d.x]; 00749 } 00750 00751 /** read pixel at given location. <br> 00752 usage: <TT> value_type value = image[Diff2D(1,2)] </TT> 00753 */ 00754 const_reference operator[](difference_type const & d) const 00755 { 00756 return lines_[d.y][d.x]; 00757 } 00758 00759 /** access pixel at given location. <br> 00760 usage: <TT> value_type value = image(1,2) </TT> 00761 */ 00762 reference operator()(int dx, int dy) 00763 { 00764 return lines_[dy][dx]; 00765 } 00766 00767 /** read pixel at given location. <br> 00768 usage: <TT> value_type value = image(1,2) </TT> 00769 */ 00770 const_reference operator()(int dx, int dy) const 00771 { 00772 return lines_[dy][dx]; 00773 } 00774 00775 /** access pixel at given location. 00776 Note that the 'x' index is the trailing index. <br> 00777 usage: <TT> value_type value = image[2][1] </TT> 00778 */ 00779 pointer operator[](int dy) 00780 { 00781 return lines_[dy]; 00782 } 00783 00784 /** read pixel at given location. 00785 Note that the 'x' index is the trailing index. <br> 00786 usage: <TT> value_type value = image[2][1] </TT> 00787 */ 00788 const_pointer operator[](int dy) const 00789 { 00790 return lines_[dy]; 00791 } 00792 00793 /** init 2D random access iterator poining to upper left pixel 00794 */ 00795 traverser upperLeft() 00796 { 00797 vigra_precondition(data_ != 0, 00798 "BasicImage::upperLeft(): image must have non-zero size."); 00799 return traverser(lines_); 00800 } 00801 00802 /** init 2D random access iterator poining to 00803 pixel(width, height), i.e. one pixel right and below lower right 00804 corner of the image as is common in C/C++. 00805 */ 00806 traverser lowerRight() 00807 { 00808 vigra_precondition(data_ != 0, 00809 "BasicImage::lowerRight(): image must have non-zero size."); 00810 return upperLeft() + size(); 00811 } 00812 00813 /** init 2D random access const iterator poining to upper left pixel 00814 */ 00815 const_traverser upperLeft() const 00816 { 00817 vigra_precondition(data_ != 0, 00818 "BasicImage::upperLeft(): image must have non-zero size."); 00819 return const_traverser(const_cast<PIXELTYPE **>(lines_)); 00820 } 00821 00822 /** init 2D random access const iterator poining to 00823 pixel(width, height), i.e. one pixel right and below lower right 00824 corner of the image as is common in C/C++. 00825 */ 00826 const_traverser lowerRight() const 00827 { 00828 vigra_precondition(data_ != 0, 00829 "BasicImage::lowerRight(): image must have non-zero size."); 00830 return upperLeft() + size(); 00831 } 00832 00833 /** init 1D random access iterator pointing to first pixel 00834 */ 00835 iterator begin() 00836 { 00837 vigra_precondition(data_ != 0, 00838 "BasicImage::begin(): image must have non-zero size."); 00839 return data_; 00840 } 00841 00842 /** init 1D random access iterator pointing past the end 00843 */ 00844 iterator end() 00845 { 00846 vigra_precondition(data_ != 0, 00847 "BasicImage::end(): image must have non-zero size."); 00848 return data_ + width() * height(); 00849 } 00850 00851 /** init 1D random access const iterator pointing to first pixel 00852 */ 00853 const_iterator begin() const 00854 { 00855 vigra_precondition(data_ != 0, 00856 "BasicImage::begin(): image must have non-zero size."); 00857 return data_; 00858 } 00859 00860 /** init 1D random access const iterator pointing past the end 00861 */ 00862 const_iterator end() const 00863 { 00864 vigra_precondition(data_ != 0, 00865 "BasicImage::end(): image must have non-zero size."); 00866 return data_ + width() * height(); 00867 } 00868 00869 /** return default accessor 00870 */ 00871 Accessor accessor() 00872 { 00873 return Accessor(); 00874 } 00875 00876 /** return default const accessor 00877 */ 00878 ConstAccessor accessor() const 00879 { 00880 return ConstAccessor(); 00881 } 00882 00883 private: 00884 00885 void deallocate(); 00886 00887 value_type ** initLineStartArray(value_type * data, int width, int height); 00888 00889 PIXELTYPE * data_; 00890 PIXELTYPE ** lines_; 00891 int width_, height_; 00892 Alloc allocator_; 00893 LineAllocator pallocator_; 00894 }; 00895 00896 template <class PIXELTYPE, class Alloc> 00897 BasicImage<PIXELTYPE, Alloc> & 00898 BasicImage<PIXELTYPE, Alloc>::operator=(const BasicImage<PIXELTYPE, Alloc> & rhs) 00899 { 00900 if(this != &rhs) 00901 { 00902 if((width() != rhs.width()) || 00903 (height() != rhs.height())) 00904 { 00905 resizeCopy(rhs); 00906 } 00907 else 00908 { 00909 ConstScanOrderIterator is = rhs.begin(); 00910 ConstScanOrderIterator iend = rhs.end(); 00911 ScanOrderIterator id = begin(); 00912 00913 for(; is != iend; ++is, ++id) *id = *is; 00914 } 00915 } 00916 return *this; 00917 } 00918 00919 template <class PIXELTYPE, class Alloc> 00920 BasicImage<PIXELTYPE, Alloc> & 00921 BasicImage<PIXELTYPE, Alloc>::operator=(value_type pixel) 00922 { 00923 ScanOrderIterator i = begin(); 00924 ScanOrderIterator iend = end(); 00925 00926 for(; i != iend; ++i) *i = pixel; 00927 00928 return *this; 00929 } 00930 00931 template <class PIXELTYPE, class Alloc> 00932 BasicImage<PIXELTYPE, Alloc> & 00933 BasicImage<PIXELTYPE, Alloc>::init(value_type const & pixel) 00934 { 00935 ScanOrderIterator i = begin(); 00936 ScanOrderIterator iend = end(); 00937 00938 for(; i != iend; ++i) *i = pixel; 00939 00940 return *this; 00941 } 00942 00943 template <class PIXELTYPE, class Alloc> 00944 void 00945 BasicImage<PIXELTYPE, Alloc>::resize(int width, int height, value_type const & d) 00946 { 00947 vigra_precondition((width >= 0) && (height >= 0), 00948 "BasicImage::resize(int width, int height, value_type const &): " 00949 "width and height must be >= 0.\n"); 00950 00951 if (width_ != width || height_ != height) // change size? 00952 { 00953 value_type * newdata = 0; 00954 value_type ** newlines = 0; 00955 if(width*height > 0) 00956 { 00957 if (width*height != width_*height_) // different sizes, must reallocate 00958 { 00959 newdata = allocator_.allocate(width*height); 00960 std::uninitialized_fill_n(newdata, width*height, d); 00961 newlines = initLineStartArray(newdata, width, height); 00962 deallocate(); 00963 } 00964 else // need only to reshape 00965 { 00966 newdata = data_; 00967 std::fill_n(newdata, width*height, d); 00968 newlines = initLineStartArray(newdata, width, height); 00969 pallocator_.deallocate(lines_, height_); 00970 } 00971 } 00972 else 00973 { 00974 deallocate(); 00975 } 00976 00977 data_ = newdata; 00978 lines_ = newlines; 00979 width_ = width; 00980 height_ = height; 00981 } 00982 else if(width*height > 0) // keep size, re-init data 00983 { 00984 std::fill_n(data_, width*height, d); 00985 } 00986 } 00987 00988 00989 template <class PIXELTYPE, class Alloc> 00990 void 00991 BasicImage<PIXELTYPE, Alloc>::resizeCopy(int width, int height, const_pointer data) 00992 { 00993 int newsize = width*height; 00994 if (width_ != width || height_ != height) // change size? 00995 { 00996 value_type * newdata = 0; 00997 value_type ** newlines = 0; 00998 if(newsize > 0) 00999 { 01000 if (newsize != width_*height_) // different sizes, must reallocate 01001 { 01002 newdata = allocator_.allocate(newsize); 01003 std::uninitialized_copy(data, data + newsize, newdata); 01004 newlines = initLineStartArray(newdata, width, height); 01005 deallocate(); 01006 } 01007 else // need only to reshape 01008 { 01009 newdata = data_; 01010 std::copy(data, data + newsize, newdata); 01011 newlines = initLineStartArray(newdata, width, height); 01012 pallocator_.deallocate(lines_, height_); 01013 } 01014 } 01015 else 01016 { 01017 deallocate(); 01018 } 01019 01020 data_ = newdata; 01021 lines_ = newlines; 01022 width_ = width; 01023 height_ = height; 01024 } 01025 else if(newsize > 0) // keep size, copy data 01026 { 01027 std::copy(data, data + newsize, data_); 01028 } 01029 } 01030 01031 template <class PIXELTYPE, class Alloc> 01032 void 01033 BasicImage<PIXELTYPE, Alloc>::swap( BasicImage<PIXELTYPE, Alloc>& rhs ) 01034 { 01035 if (&rhs!=this) 01036 { 01037 std::swap( data_, rhs.data_ ); 01038 std::swap( lines_, rhs.lines_ ); 01039 std::swap( width_, rhs.width_ ); 01040 std::swap( height_, rhs.height_ ); 01041 } 01042 } 01043 01044 template <class PIXELTYPE, class Alloc> 01045 void 01046 BasicImage<PIXELTYPE, Alloc>::deallocate() 01047 { 01048 if(data_) 01049 { 01050 ScanOrderIterator i = begin(); 01051 ScanOrderIterator iend = end(); 01052 01053 for(; i != iend; ++i) (*i).~PIXELTYPE(); 01054 01055 allocator_.deallocate(data_, width()*height()); 01056 pallocator_.deallocate(lines_, height_); 01057 } 01058 } 01059 01060 template <class PIXELTYPE, class Alloc> 01061 PIXELTYPE ** 01062 BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, int width, int height) 01063 { 01064 value_type ** lines = pallocator_.allocate(height); 01065 for(int y=0; y<height; ++y) 01066 lines[y] = data + y*width; 01067 return lines; 01068 } 01069 01070 /********************************************************/ 01071 /* */ 01072 /* argument object factories */ 01073 /* */ 01074 /********************************************************/ 01075 01076 template <class PixelType, class Accessor, class Alloc> 01077 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01078 typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01079 srcImageRange(BasicImage<PixelType, Alloc> const & img, Accessor a) 01080 { 01081 return triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01082 typename BasicImage<PixelType, Alloc>::const_traverser, 01083 Accessor>(img.upperLeft(), 01084 img.lowerRight(), 01085 a); 01086 } 01087 01088 template <class PixelType, class Accessor, class Alloc> 01089 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01090 srcImage(BasicImage<PixelType, Alloc> const & img, Accessor a) 01091 { 01092 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01093 Accessor>(img.upperLeft(), a); 01094 } 01095 01096 template <class PixelType, class Accessor, class Alloc> 01097 inline triple<typename BasicImage<PixelType, Alloc>::traverser, 01098 typename BasicImage<PixelType, Alloc>::traverser, Accessor> 01099 destImageRange(BasicImage<PixelType, Alloc> & img, Accessor a) 01100 { 01101 return triple<typename BasicImage<PixelType, Alloc>::traverser, 01102 typename BasicImage<PixelType, Alloc>::traverser, 01103 Accessor>(img.upperLeft(), 01104 img.lowerRight(), 01105 a); 01106 } 01107 01108 template <class PixelType, class Accessor, class Alloc> 01109 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor> 01110 destImage(BasicImage<PixelType, Alloc> & img, Accessor a) 01111 { 01112 return pair<typename BasicImage<PixelType, Alloc>::traverser, 01113 Accessor>(img.upperLeft(), a); 01114 } 01115 01116 template <class PixelType, class Accessor, class Alloc> 01117 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor> 01118 maskImage(BasicImage<PixelType, Alloc> const & img, Accessor a) 01119 { 01120 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01121 Accessor>(img.upperLeft(), a); 01122 } 01123 01124 /****************************************************************/ 01125 01126 template <class PixelType, class Alloc> 01127 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01128 typename BasicImage<PixelType, Alloc>::const_traverser, 01129 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01130 srcImageRange(BasicImage<PixelType, Alloc> const & img) 01131 { 01132 return triple<typename BasicImage<PixelType, Alloc>::const_traverser, 01133 typename BasicImage<PixelType, Alloc>::const_traverser, 01134 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(), 01135 img.lowerRight(), 01136 img.accessor()); 01137 } 01138 01139 template <class PixelType, class Alloc> 01140 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser, 01141 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01142 srcImage(BasicImage<PixelType, Alloc> const & img) 01143 { 01144 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01145 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(), 01146 img.accessor()); 01147 } 01148 01149 template <class PixelType, class Alloc> 01150 inline triple< typename BasicImage<PixelType, Alloc>::traverser, 01151 typename BasicImage<PixelType, Alloc>::traverser, 01152 typename BasicImage<PixelType, Alloc>::Accessor> 01153 destImageRange(BasicImage<PixelType, Alloc> & img) 01154 { 01155 return triple<typename BasicImage<PixelType, Alloc>::traverser, 01156 typename BasicImage<PixelType, Alloc>::traverser, 01157 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(), 01158 img.lowerRight(), 01159 img.accessor()); 01160 } 01161 01162 template <class PixelType, class Alloc> 01163 inline pair< typename BasicImage<PixelType, Alloc>::traverser, 01164 typename BasicImage<PixelType, Alloc>::Accessor> 01165 destImage(BasicImage<PixelType, Alloc> & img) 01166 { 01167 return pair<typename BasicImage<PixelType, Alloc>::traverser, 01168 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(), 01169 img.accessor()); 01170 } 01171 01172 template <class PixelType, class Alloc> 01173 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser, 01174 typename BasicImage<PixelType, Alloc>::ConstAccessor> 01175 maskImage(BasicImage<PixelType, Alloc> const & img) 01176 { 01177 return pair<typename BasicImage<PixelType, Alloc>::const_traverser, 01178 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(), 01179 img.accessor()); 01180 } 01181 01182 } // namespace vigra 01183 01184 #endif // VIGRA_BASICIMAGE_HXX
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|