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