[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

basicimage.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 #ifndef VIGRA_BASICIMAGE_HXX
37 #define VIGRA_BASICIMAGE_HXX
38 
39 #include <memory>
40 #include <algorithm>
41 #include "utilities.hxx"
42 #include "iteratortraits.hxx"
43 #include "accessor.hxx"
44 #include "memory.hxx"
45 #include "basicimageview.hxx"
46 
47 // Bounds checking Macro used if VIGRA_CHECK_BOUNDS is defined.
48 #ifdef VIGRA_CHECK_BOUNDS
49 #define VIGRA_ASSERT_INSIDE(diff) \
50  vigra_precondition(this->isInside(diff), "Index out of bounds")
51 #else
52 #define VIGRA_ASSERT_INSIDE(diff)
53 #endif
54 
55 namespace vigra {
56 
57 template <class IMAGEITERATOR>
58 class LineBasedColumnIteratorPolicy
59 {
60  public:
61  typedef IMAGEITERATOR ImageIterator;
62  typedef typename IMAGEITERATOR::LineStartIterator LineStartIterator;
63  typedef typename IMAGEITERATOR::value_type value_type;
64  typedef typename IMAGEITERATOR::difference_type::MoveY
65  difference_type;
66  typedef typename IMAGEITERATOR::reference reference;
67  typedef typename IMAGEITERATOR::index_reference index_reference;
68  typedef typename IMAGEITERATOR::pointer pointer;
69  typedef std::random_access_iterator_tag iterator_category;
70 
71 
72  struct BaseType
73  {
74  explicit BaseType(LineStartIterator c = LineStartIterator(),
75  difference_type o = 0)
76  : line_start_(c), offset_(o)
77  {}
78 
79  LineStartIterator line_start_;
80  difference_type offset_;
81  };
82 
83  static void initialize(BaseType &) {}
84 
85  static reference dereference(BaseType const & d)
86  { return const_cast<reference>(*(*d.line_start_ + d.offset_)); }
87 
88  static index_reference dereference(BaseType const & d, difference_type n)
89  {
90  return const_cast<index_reference>(*(d.line_start_[n] + d.offset_));
91  }
92 
93  static bool equal(BaseType const & d1, BaseType const & d2)
94  { return d1.line_start_ == d2.line_start_; }
95 
96  static bool less(BaseType const & d1, BaseType const & d2)
97  { return d1.line_start_ < d2.line_start_; }
98 
99  static difference_type difference(BaseType const & d1, BaseType const & d2)
100  { return d1.line_start_ - d2.line_start_; }
101 
102  static void increment(BaseType & d)
103  { ++d.line_start_; }
104 
105  static void decrement(BaseType & d)
106  { --d.line_start_; }
107 
108  static void advance(BaseType & d, difference_type n)
109  { d.line_start_ += n; }
110 };
111 
112 /********************************************************/
113 /* */
114 /* BasicImageIterator */
115 /* */
116 /********************************************************/
117 
118 /** Implementation of the standard image iterator for \ref vigra::BasicImage.
119  See \ref vigra::ImageIterator for documentation.
120 
121  <b>\#include</b> <vigra/basicimage.hxx> <br/>
122  Namespace: vigra
123 */
124 template <class IMAGEITERATOR, class PIXELTYPE,
125  class REFERENCE, class POINTER, class LINESTARTITERATOR>
127 {
128  public:
129  typedef BasicImageIteratorBase<IMAGEITERATOR,
130  PIXELTYPE, REFERENCE, POINTER, LINESTARTITERATOR> self_type;
131 
132  typedef LINESTARTITERATOR LineStartIterator;
133  typedef PIXELTYPE value_type;
134  typedef PIXELTYPE PixelType;
135  typedef REFERENCE reference;
136  typedef REFERENCE index_reference;
137  typedef POINTER pointer;
138  typedef Diff2D difference_type;
139  typedef image_traverser_tag iterator_category;
140  typedef POINTER row_iterator;
143 
144  typedef std::ptrdiff_t MoveX;
145  typedef LINESTARTITERATOR MoveY;
146 
147  MoveX x;
148  MoveY y;
149 
150  IMAGEITERATOR & operator+=(difference_type const & s)
151  {
152  x += s.x;
153  y += s.y;
154  return static_cast<IMAGEITERATOR &>(*this);
155  }
156 
157  IMAGEITERATOR & operator-=(difference_type const & s)
158  {
159  x -= s.x;
160  y -= s.y;
161  return static_cast<IMAGEITERATOR &>(*this);
162  }
163 
164  IMAGEITERATOR operator+(difference_type const & s) const
165  {
166  IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
167 
168  ret += s;
169 
170  return ret;
171  }
172 
173  IMAGEITERATOR operator-(difference_type const & s) const
174  {
175  IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
176 
177  ret -= s;
178 
179  return ret;
180  }
181 
182  difference_type operator-(BasicImageIteratorBase const & rhs) const
183  {
184  return difference_type(difference_type::MoveX(x - rhs.x),
185  difference_type::MoveY(y - rhs.y));
186  }
187 
188  bool operator==(BasicImageIteratorBase const & rhs) const
189  {
190  return (x == rhs.x) && (y == rhs.y);
191  }
192 
193  bool operator!=(BasicImageIteratorBase const & rhs) const
194  {
195  return (x != rhs.x) || (y != rhs.y);
196  }
197 
198  reference operator*() const
199  {
200  return *(*y + x );
201  }
202 
203  pointer operator->() const
204  {
205  return *y + x;
206  }
207 
208  index_reference operator[](difference_type const & d) const
209  {
210  return *(*(y + d.y) + x + d.x);
211  }
212 
213  index_reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy) const
214  {
215  return *(*(y + dy) + x + dx);
216  }
217 
218  pointer operator[](std::ptrdiff_t dy) const
219  {
220  return y[dy] + x;
221  }
222 
223  row_iterator rowIterator() const
224  { return *y + x; }
225 
226  column_iterator columnIterator() const
227  {
228  typedef typename column_iterator::BaseType Iter;
229  return column_iterator(Iter(y, x));
230  }
231 
232  protected:
233  BasicImageIteratorBase(LINESTARTITERATOR const & line)
234  : x(0),
235  y(line)
236  {}
237 
238  BasicImageIteratorBase(std::ptrdiff_t ix, LINESTARTITERATOR const & line)
239  : x(ix),
240  y(line)
241  {}
242 
244  : x(0),
245  y(0)
246  {}
247 };
248 
249 /********************************************************/
250 /* */
251 /* BasicImageIterator */
252 /* */
253 /********************************************************/
254 
255 /** Implementation of the standard image iterator for \ref vigra::BasicImage.
256  See \ref vigra::ImageIterator for documentation.
257 
258  <b>\#include</b> <vigra/basicimage.hxx> <br/>
259  Namespace: vigra
260 */
261 template <class PIXELTYPE, class ITERATOR>
263 : public BasicImageIteratorBase<BasicImageIterator<PIXELTYPE, ITERATOR>,
264  PIXELTYPE, PIXELTYPE &, PIXELTYPE *, ITERATOR>
265 {
266  public:
267 
268  typedef BasicImageIteratorBase<BasicImageIterator, PIXELTYPE,
269  PIXELTYPE &, PIXELTYPE *, ITERATOR> Base;
270 
271 
272  BasicImageIterator(ITERATOR line)
273  : Base(line)
274  {}
275 
277  : Base()
278  {}
279 };
280 
281 /********************************************************/
282 /* */
283 /* ConstBasicImageIterator */
284 /* */
285 /********************************************************/
286 
287 /** Implementation of the standard const image iterator for \ref vigra::BasicImage.
288  See \ref vigra::ConstImageIterator for documentation.
289 
290  <b>\#include</b> <vigra/basicimage.hxx> <br/>
291  Namespace: vigra
292 */
293 template <class PIXELTYPE, class ITERATOR>
295 : public BasicImageIteratorBase<ConstBasicImageIterator<PIXELTYPE, ITERATOR>,
296  PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR>
297 {
298  public:
299 
301  PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR> Base;
302 
303 
304  ConstBasicImageIterator(ITERATOR line)
305  : Base(line)
306  {}
307 
309  : Base(rhs.x, rhs.y)
310  {}
311 
313  : Base()
314  {}
315 
317  operator=(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs)
318  {
319  Base::x = rhs.x;
320  Base::y = rhs.y;
321  return *this;
322  }
323 
324 };
325 
326 /********************************************************/
327 /* */
328 /* definition of iterator traits */
329 /* */
330 /********************************************************/
331 
332 
333 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
334 
335 template <class T>
336 struct IteratorTraits<BasicImageIterator<T, T**> >
337 : public IteratorTraitsBase<BasicImageIterator<T, T**> >
338 {
339  typedef BasicImageIterator<T, T**> mutable_iterator;
340  typedef ConstBasicImageIterator<T, T**> const_iterator;
341  typedef typename AccessorTraits<T>::default_accessor DefaultAccessor;
342  typedef DefaultAccessor default_accessor;
343  typedef VigraTrueType hasConstantStrides;
344 };
345 
346 template <class T>
347 struct IteratorTraits<ConstBasicImageIterator<T, T**> >
348 : public IteratorTraitsBase<ConstBasicImageIterator<T, T**> >
349 {
350  typedef BasicImageIterator<T, T**> mutable_iterator;
351  typedef ConstBasicImageIterator<T, T**> const_iterator;
352  typedef typename AccessorTraits<T>::default_const_accessor DefaultAccessor;
353  typedef DefaultAccessor default_accessor;
354  typedef VigraTrueType hasConstantStrides;
355 };
356 
357 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
358 
359 #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \
360  template <> \
361  struct IteratorTraits<BasicImageIterator<VALUETYPE, VALUETYPE **> > \
362  : public IteratorTraitsBase<BasicImageIterator<VALUETYPE, VALUETYPE **> > \
363  { \
364  typedef BasicImageIterator<VALUETYPE, VALUETYPE**> mutable_iterator; \
365  typedef ConstBasicImageIterator<VALUETYPE, VALUETYPE**> const_iterator; \
366  typedef typename AccessorTraits<VALUETYPE >::default_accessor DefaultAccessor; \
367  typedef DefaultAccessor default_accessor; \
368  typedef VigraTrueType hasConstantStrides; \
369  }; \
370  \
371  template <> \
372  struct IteratorTraits<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \
373  : public IteratorTraitsBase<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \
374  { \
375  typedef BasicImageIterator<VALUETYPE, VALUETYPE**> mutable_iterator; \
376  typedef ConstBasicImageIterator<VALUETYPE, VALUETYPE**> const_iterator; \
377  typedef typename AccessorTraits<VALUETYPE >::default_const_accessor DefaultAccessor; \
378  typedef DefaultAccessor default_accessor; \
379  typedef VigraTrueType hasConstantStrides; \
380  };
381 
382 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>)
383 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>)
384 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned short>)
385 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>)
386 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned int>)
387 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>)
388 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>)
389 
390 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
391 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
392 #undef VIGRA_PIXELTYPE
393 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
394 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
395 #undef VIGRA_PIXELTYPE
396 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
397 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
398 #undef VIGRA_PIXELTYPE
399 #define VIGRA_PIXELTYPE TinyVector<short, 2>
400 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
401 #undef VIGRA_PIXELTYPE
402 #define VIGRA_PIXELTYPE TinyVector<short, 3>
403 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
404 #undef VIGRA_PIXELTYPE
405 #define VIGRA_PIXELTYPE TinyVector<short, 4>
406 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
407 #undef VIGRA_PIXELTYPE
408 #define VIGRA_PIXELTYPE TinyVector<unsigned short, 2>
409 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
410 #undef VIGRA_PIXELTYPE
411 #define VIGRA_PIXELTYPE TinyVector<unsigned short, 3>
412 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
413 #undef VIGRA_PIXELTYPE
414 #define VIGRA_PIXELTYPE TinyVector<unsigned short, 4>
415 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
416 #undef VIGRA_PIXELTYPE
417 #define VIGRA_PIXELTYPE TinyVector<int, 2>
418 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
419 #undef VIGRA_PIXELTYPE
420 #define VIGRA_PIXELTYPE TinyVector<int, 3>
421 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
422 #undef VIGRA_PIXELTYPE
423 #define VIGRA_PIXELTYPE TinyVector<int, 4>
424 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
425 #undef VIGRA_PIXELTYPE
426 #define VIGRA_PIXELTYPE TinyVector<unsigned int, 2>
427 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
428 #undef VIGRA_PIXELTYPE
429 #define VIGRA_PIXELTYPE TinyVector<unsigned int, 3>
430 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
431 #undef VIGRA_PIXELTYPE
432 #define VIGRA_PIXELTYPE TinyVector<unsigned int, 4>
433 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
434 #undef VIGRA_PIXELTYPE
435 #define VIGRA_PIXELTYPE TinyVector<float, 2>
436 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
437 #undef VIGRA_PIXELTYPE
438 #define VIGRA_PIXELTYPE TinyVector<float, 3>
439 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
440 #undef VIGRA_PIXELTYPE
441 #define VIGRA_PIXELTYPE TinyVector<float, 4>
442 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
443 #undef VIGRA_PIXELTYPE
444 #define VIGRA_PIXELTYPE TinyVector<double, 2>
445 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
446 #undef VIGRA_PIXELTYPE
447 #define VIGRA_PIXELTYPE TinyVector<double, 3>
448 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
449 #undef VIGRA_PIXELTYPE
450 #define VIGRA_PIXELTYPE TinyVector<double, 4>
451 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
452 #undef VIGRA_PIXELTYPE
453 
454 #undef VIGRA_DEFINE_ITERATORTRAITS
455 
456 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
457 
458 /********************************************************/
459 /* */
460 /* BasicImage */
461 /* */
462 /********************************************************/
463 
464 /** \brief Fundamental class template for images.
465 
466  <b>deprecated</b>, use \ref vigra::MultiArray instead
467 
468  A customized memory allocator can be specified as a templated argument
469  and passed in the constructor.
470 
471  <b>\#include</b> <vigra/basicimage.hxx> <br/>
472  Namespace: vigra
473 */
474 template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> >
476 {
477  public:
478 
479  /** the BasicImage's pixel type
480  */
481  typedef PIXELTYPE value_type;
482 
483  /** the BasicImage's pixel type
484  */
485  typedef PIXELTYPE PixelType;
486 
487  /** the BasicImage's reference type (i.e. the
488  return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>)
489  */
490  typedef PIXELTYPE & reference;
491 
492  /** the BasicImage's const reference type (i.e. the
493  return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>
494  when <TT>image</TT> is const)
495  */
496  typedef PIXELTYPE const & const_reference;
497 
498  /** the BasicImage's pointer type
499  */
500  typedef PIXELTYPE * pointer;
501 
502  /** the BasicImage's const pointer type
503  */
504  typedef PIXELTYPE const * const_pointer;
505 
506  /** the BasicImage's 1D random access iterator
507  (note: lower case 'iterator' is a STL compatible 1D random
508  access iterator, don't confuse with capitalized Iterator)
509  */
510  typedef PIXELTYPE * iterator;
511 
512  /** deprecated, use <TT>iterator</TT> instead
513  */
514  typedef PIXELTYPE * ScanOrderIterator;
515 
516  /** the BasicImage's 1D random access const iterator
517  (note: lower case 'const_iterator' is a STL compatible 1D
518  random access const iterator)
519  */
520  typedef PIXELTYPE const * const_iterator;
521 
522  /** deprecated, use <TT>const_iterator</TT> instead
523  */
524  typedef PIXELTYPE const * ConstScanOrderIterator;
525 
526  /** the BasicImage's 2D random access iterator ('traverser')
527  */
529 
530  /** deprecated, use <TT>traverser</TT> instead
531  */
533 
534  /** the BasicImage's 2D random access const iterator ('const traverser')
535  */
536  typedef
539 
540  /** deprecated, use <TT>const_traverser</TT> instead
541  */
542  typedef
545 
546  /** the row iterator associated with the traverser
547  */
548  typedef typename traverser::row_iterator row_iterator;
549 
550  /** the const row iterator associated with the const_traverser
551  */
552  typedef typename const_traverser::row_iterator const_row_iterator;
553 
554  /** the column iterator associated with the traverser
555  */
557 
558  /** the const column iterator associated with the const_traverser
559  */
561 
562  /** the BasicImage's difference type (argument type of image[diff])
563  */
565 
566  /** the BasicImage's size type (result type of image.size())
567  */
568  typedef Size2D size_type;
569 
570  /** the BasicImage's default accessor
571  */
572  typedef typename
574 
575  /** the BasicImage's default const accessor
576  */
577  typedef typename
579 
580  /** the BasicImage's allocator (default: std::allocator<value_type>)
581  */
582  typedef Alloc allocator_type;
583 
584  typedef Alloc Allocator;
585  typedef typename Alloc::template rebind<PIXELTYPE *>::other LineAllocator;
586 
587  /** construct image of size 0x0
588  */
590  : data_(0),
591  width_(0),
592  height_(0)
593  {}
594 
595  /** construct image of size 0x0, use the specified allocator.
596  */
597  explicit BasicImage(Alloc const & alloc)
598  : data_(0),
599  width_(0),
600  height_(0),
601  allocator_(alloc),
602  pallocator_(alloc)
603  {}
604 
605  /** construct image of size width x height, use the specified allocator.
606  */
607  BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, Alloc const & alloc = Alloc())
608  : data_(0),
609  width_(0),
610  height_(0),
611  allocator_(alloc),
612  pallocator_(alloc)
613  {
614  vigra_precondition((width >= 0) && (height >= 0),
615  "BasicImage::BasicImage(int width, int height): "
616  "width and height must be >= 0.\n");
617 
618  resize(width, height, value_type());
619  }
620 
621  /** construct image of size size.x x size.y, use the specified allocator.
622  */
623  explicit BasicImage(difference_type const & size, Alloc const & alloc = Alloc())
624  : data_(0),
625  width_(0),
626  height_(0),
627  allocator_(alloc),
628  pallocator_(alloc)
629  {
630  vigra_precondition((size.x >= 0) && (size.y >= 0),
631  "BasicImage::BasicImage(Diff2D size): "
632  "size.x and size.y must be >= 0.\n");
633 
634  resize(size.x, size.y, value_type());
635  }
636 
637  /** construct image of size width*height and initialize every
638  pixel with the value \a d (use this constructor, if
639  value_type doesn't have a default constructor).
640  Use the specified allocator.
641  */
642  BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, value_type const & d, Alloc const & alloc = Alloc())
643  : data_(0),
644  width_(0),
645  height_(0),
646  allocator_(alloc),
647  pallocator_(alloc)
648  {
649  vigra_precondition((width >= 0) && (height >= 0),
650  "BasicImage::BasicImage(int width, int height, value_type const & ): "
651  "width and height must be >= 0.\n");
652 
653  resize(width, height, d);
654  }
655 
656  /** construct image of size width*height and try to skip initialization
657  of the memory (see BasicImage::resize for details).
658  Use the specified allocator.
659  */
660  BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, SkipInitializationTag, Alloc const & alloc = Alloc())
661  : data_(0),
662  width_(0),
663  height_(0),
664  allocator_(alloc),
665  pallocator_(alloc)
666  {
667  vigra_precondition((width >= 0) && (height >= 0),
668  "BasicImage::BasicImage(int width, int height, value_type const & ): "
669  "width and height must be >= 0.\n");
670 
671  resize(width, height, SkipInitialization);
672  }
673 
674  /** construct image of size size.x x size.y and initialize
675  every pixel with given data (use this constructor, if
676  value_type doesn't have a default constructor). Use the specified allocator.
677  */
678  explicit BasicImage(difference_type const & size, value_type const & d, Alloc const & alloc = Alloc())
679  : data_(0),
680  width_(0),
681  height_(0),
682  allocator_(alloc),
683  pallocator_(alloc)
684  {
685  vigra_precondition((size.x >= 0) && (size.y >= 0),
686  "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
687  "size.x and size.y must be >= 0.\n");
688 
689  resize(size.x, size.y, d);
690  }
691 
692  /** construct image of size size.x x size.y and try to skip initialization
693  of the memory (see BasicImage::resize for details). Use the specified allocator.
694  */
695  explicit BasicImage(difference_type const & size, SkipInitializationTag, Alloc const & alloc = Alloc())
696  : data_(0),
697  width_(0),
698  height_(0),
699  allocator_(alloc),
700  pallocator_(alloc)
701  {
702  vigra_precondition((size.x >= 0) && (size.y >= 0),
703  "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
704  "size.x and size.y must be >= 0.\n");
705 
706  resize(size.x, size.y, SkipInitialization);
707  }
708 
709 
710  /** construct image of size width*height and copy the data from the
711  given C-style array \a d. Use the specified allocator.
712  */
713  BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer d, Alloc const & alloc = Alloc())
714  : data_(0),
715  width_(0),
716  height_(0),
717  allocator_(alloc),
718  pallocator_(alloc)
719  {
720  vigra_precondition((width >= 0) && (height >= 0),
721  "BasicImage::BasicImage(int width, int height, const_pointer ): "
722  "width and height must be >= 0.\n");
723 
724  resizeCopy(width, height, d);
725  }
726 
727  /** construct image of size size.x x size.y and copy the data from the
728  given C-style array. Use the specified allocator.
729  */
730  explicit BasicImage(difference_type const & size, const_pointer d, Alloc const & alloc = Alloc())
731  : data_(0),
732  width_(0),
733  height_(0),
734  allocator_(alloc),
735  pallocator_(alloc)
736  {
737  vigra_precondition((size.x >= 0) && (size.y >= 0),
738  "BasicImage::BasicImage(Diff2D const & size, const_pointer): "
739  "size.x and size.y must be >= 0.\n");
740 
741  resizeCopy(size.x, size.y, d);
742  }
743 
744  /** copy rhs image
745  */
746  BasicImage(const BasicImage & rhs)
747  : data_(0),
748  width_(0),
749  height_(0),
750  allocator_(rhs.allocator_),
751  pallocator_(rhs.pallocator_)
752  {
753  resizeCopy(rhs);
754  }
755 
756  /** destructor
757  */
759  {
760  deallocate();
761  }
762 
763  /** copy rhs image (image is resized if necessary)
764  */
765  BasicImage & operator=(const BasicImage & rhs);
766 
767  /** \deprecated set Image with const value
768  */
770 
771  /** set Image with const value
772  */
773  BasicImage & init(value_type const & pixel);
774 
775  /** reset image to specified size (dimensions must not be negative)
776  (old data are kept if new size matches old size)
777  */
778  void resize(std::ptrdiff_t width, std::ptrdiff_t height)
779  {
780  if(width != width_ || height != height_)
781  resize(width, height, value_type());
782  }
783 
784  /** reset image to specified size (dimensions must not be negative)
785  (old data are kept if new size matches old size)
786  */
787  void resize(difference_type const & size)
788  {
789  if(size.x != width_ || size.y != height_)
790  {
791  resize(size.x, size.y, value_type());
792  }
793  }
794 
795  /** reset image to specified size and initialize it with
796  given data (use this if value_type doesn't have a default
797  constructor, dimensions must not be negative,
798  old data are kept if new size matches old size)
799  */
800  void resize(std::ptrdiff_t width, std::ptrdiff_t height, value_type const & d)
801  {
802  resizeImpl(width, height, d, false);
803  }
804 
805  /** reset image to specified size and skip initialization
806  if possible (use this if <tt>value_type</tt> is a built-in type
807  or <tt>TinyVector&lt;builtin&gt&</tt> and the data is
808  immediately overridden afterwards). If <tt>value_type</tt> requires
809  initialization, <tt>SkipInitialization</tt> is ignored.
810 
811  Usage:
812  \code
813  image.resize(new_width, new_height, SkipInitialization);
814  \endcode
815  */
816  void resize(std::ptrdiff_t width, std::ptrdiff_t height, SkipInitializationTag)
817  {
818  resizeImpl(width, height, NumericTraits<value_type>::zero(),
819  CanSkipInitialization<value_type>::value);
820  }
821 
822  /** resize image to given size and initialize by copying data
823  from the C-style array \a data.
824  */
825  void resizeCopy(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer data);
826 
827  /** resize image to size of other image and copy its data
828  */
829  void resizeCopy(const BasicImage & rhs)
830  {
831  resizeCopy(rhs.width(), rhs.height(), rhs.data_);
832  }
833 
834  /** swap the internal data with the rhs image in constant time
835  */
836  void swap( BasicImage & rhs );
837 
838  /** width of Image
839  */
840  std::ptrdiff_t width() const
841  {
842  return width_;
843  }
844 
845  /** height of Image
846  */
847  std::ptrdiff_t height() const
848  {
849  return height_;
850  }
851 
852  /** size of Image
853  */
854  size_type size() const
855  {
856  return size_type(width(), height());
857  }
858 
859  /** test whether a given coordinate is inside the image
860  */
861  bool isInside(difference_type const & d) const
862  {
863  return d.x >= 0 && d.y >= 0 &&
864  d.x < width() && d.y < height();
865  }
866 
867  /** access pixel at given location. <br>
868  usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
869  */
871  {
872  VIGRA_ASSERT_INSIDE(d);
873  return lines_[d.y][d.x];
874  }
875 
876  /** read pixel at given location. <br>
877  usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
878  */
880  {
881  VIGRA_ASSERT_INSIDE(d);
882  return lines_[d.y][d.x];
883  }
884 
885  /** access pixel at given location. <br>
886  usage: <TT> value_type value = image(1,2) </TT>
887  */
888  reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy)
889  {
890  VIGRA_ASSERT_INSIDE(difference_type(dx,dy));
891  return lines_[dy][dx];
892  }
893 
894  /** read pixel at given location. <br>
895  usage: <TT> value_type value = image(1,2) </TT>
896  */
897  const_reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy) const
898  {
899  VIGRA_ASSERT_INSIDE(difference_type(dx,dy));
900  return lines_[dy][dx];
901  }
902 
903  /** access pixel at given location.
904  Note that the 'x' index is the trailing index. <br>
905  usage: <TT> value_type value = image[2][1] </TT>
906  */
907  pointer operator[](std::ptrdiff_t dy)
908  {
909  VIGRA_ASSERT_INSIDE(difference_type(0,dy));
910  return lines_[dy];
911  }
912 
913  /** read pixel at given location.
914  Note that the 'x' index is the trailing index. <br>
915  usage: <TT> value_type value = image[2][1] </TT>
916  */
917  const_pointer operator[](std::ptrdiff_t dy) const
918  {
919  VIGRA_ASSERT_INSIDE(difference_type(0,dy));
920  return lines_[dy];
921  }
922 
923  /** init 2D random access iterator pointing to upper left pixel
924  */
926  {
927  vigra_precondition(data_ != 0,
928  "BasicImage::upperLeft(): image must have non-zero size.");
929  return traverser(lines_);
930  }
931 
932  /** init 2D random access iterator pointing to
933  pixel(width, height), i.e. one pixel right and below lower right
934  corner of the image as is common in C/C++.
935  */
937  {
938  vigra_precondition(data_ != 0,
939  "BasicImage::lowerRight(): image must have non-zero size.");
940  return upperLeft() + size();
941  }
942 
943  /** init 2D random access const iterator pointing to upper left pixel
944  */
946  {
947  vigra_precondition(data_ != 0,
948  "BasicImage::upperLeft(): image must have non-zero size.");
949  return const_traverser(const_cast<PIXELTYPE **>(lines_));
950  }
951 
952  /** init 2D random access const iterator pointing to
953  pixel(width, height), i.e. one pixel right and below lower right
954  corner of the image as is common in C/C++.
955  */
957  {
958  vigra_precondition(data_ != 0,
959  "BasicImage::lowerRight(): image must have non-zero size.");
960  return upperLeft() + size();
961  }
962 
963  /** init 1D random access iterator pointing to first pixel
964  */
966  {
967  vigra_precondition(data_ != 0,
968  "BasicImage::begin(): image must have non-zero size.");
969  return data_;
970  }
971 
972  /** init 1D random access iterator pointing past the end
973  */
975  {
976  vigra_precondition(data_ != 0,
977  "BasicImage::end(): image must have non-zero size.");
978  return data_ + width() * height();
979  }
980 
981  /** init 1D random access const iterator pointing to first pixel
982  */
984  {
985  vigra_precondition(data_ != 0,
986  "BasicImage::begin(): image must have non-zero size.");
987  return data_;
988  }
989 
990  /** init 1D random access const iterator pointing past the end
991  */
993  {
994  vigra_precondition(data_ != 0,
995  "BasicImage::end(): image must have non-zero size.");
996  return data_ + width() * height();
997  }
998 
999  /** init 1D random access iterator pointing to first pixel of row \a y
1000  */
1001  row_iterator rowBegin(std::ptrdiff_t y)
1002  {
1003  return lines_[y];
1004  }
1005 
1006  /** init 1D random access iterator pointing past the end of row \a y
1007  */
1008  row_iterator rowEnd(std::ptrdiff_t y)
1009  {
1010  return rowBegin(y) + width();
1011  }
1012 
1013  /** init 1D random access const iterator pointing to first pixel of row \a y
1014  */
1015  const_row_iterator rowBegin(std::ptrdiff_t y) const
1016  {
1017  return lines_[y];
1018  }
1019 
1020  /** init 1D random access const iterator pointing past the end of row \a y
1021  */
1022  const_row_iterator rowEnd(std::ptrdiff_t y) const
1023  {
1024  return rowBegin(y) + width();
1025  }
1026 
1027  /** init 1D random access iterator pointing to first pixel of column \a x
1028  */
1029  column_iterator columnBegin(std::ptrdiff_t x)
1030  {
1031  typedef typename column_iterator::BaseType Iter;
1032  return column_iterator(Iter(lines_, x));
1033  }
1034 
1035  /** init 1D random access iterator pointing past the end of column \a x
1036  */
1037  column_iterator columnEnd(std::ptrdiff_t x)
1038  {
1039  return columnBegin(x) + height();
1040  }
1041 
1042  /** init 1D random access const iterator pointing to first pixel of column \a x
1043  */
1044  const_column_iterator columnBegin(std::ptrdiff_t x) const
1045  {
1046  typedef typename const_column_iterator::BaseType Iter;
1047  return const_column_iterator(Iter(lines_, x));
1048  }
1049 
1050  /** init 1D random access const iterator pointing past the end of column \a x
1051  */
1052  const_column_iterator columnEnd(std::ptrdiff_t x) const
1053  {
1054  return columnBegin(x) + height();
1055  }
1056 
1057  /** get a pointer to the internal data
1058  */
1060  {
1061  return data_;
1062  }
1063 
1064  /** return default accessor
1065  */
1067  {
1068  return Accessor();
1069  }
1070 
1071  /** return default const accessor
1072  */
1074  {
1075  return ConstAccessor();
1076  }
1077 
1078  private:
1079 
1080  void deallocate();
1081  void resizeImpl(std::ptrdiff_t width, std::ptrdiff_t height, value_type const & d, bool skipInit);
1082 
1083 
1084  value_type ** initLineStartArray(value_type * data, std::ptrdiff_t width, std::ptrdiff_t height);
1085 
1086  PIXELTYPE * data_;
1087  PIXELTYPE ** lines_;
1088  std::ptrdiff_t width_, height_;
1089  Alloc allocator_;
1090  LineAllocator pallocator_;
1091 };
1092 
1093 template <class PIXELTYPE, class Alloc>
1094 BasicImage<PIXELTYPE, Alloc> &
1096 {
1097  if(this != &rhs)
1098  {
1099  if((width() != rhs.width()) ||
1100  (height() != rhs.height()))
1101  {
1102  resizeCopy(rhs);
1103  }
1104  else
1105  {
1106  ConstScanOrderIterator is = rhs.begin();
1107  ConstScanOrderIterator iend = rhs.end();
1108  ScanOrderIterator id = begin();
1109 
1110  for(; is != iend; ++is, ++id) *id = *is;
1111  }
1112  }
1113  return *this;
1114 }
1115 
1116 template <class PIXELTYPE, class Alloc>
1119 {
1120  ScanOrderIterator i = begin();
1121  ScanOrderIterator iend = end();
1122 
1123  for(; i != iend; ++i) *i = pixel;
1124 
1125  return *this;
1126 }
1127 
1128 template <class PIXELTYPE, class Alloc>
1131 {
1132  ScanOrderIterator i = begin();
1133  ScanOrderIterator iend = end();
1134 
1135  for(; i != iend; ++i) *i = pixel;
1136 
1137  return *this;
1138 }
1139 
1140 template <class PIXELTYPE, class Alloc>
1141 void
1142 BasicImage<PIXELTYPE, Alloc>::resizeImpl(std::ptrdiff_t width, std::ptrdiff_t height, value_type const & d, bool skipInit)
1143 {
1144  vigra_precondition((width >= 0) && (height >= 0),
1145  "BasicImage::resize(int width, int height, value_type const &): "
1146  "width and height must be >= 0.\n");
1147  vigra_precondition(width * height >= 0,
1148  "BasicImage::resize(int width, int height, value_type const &): "
1149  "width * height too large (integer overflow -> negative).\n");
1150 
1151  if (width_ != width || height_ != height) // change size?
1152  {
1153  value_type * newdata = 0;
1154  value_type ** newlines = 0;
1155  if(width*height > 0)
1156  {
1157  if (width*height != width_*height_) // different sizes, must reallocate
1158  {
1159  newdata = allocator_.allocate(typename Alloc::size_type(width*height));
1160  if(!skipInit)
1161  std::uninitialized_fill_n(newdata, width*height, d);
1162  newlines = initLineStartArray(newdata, width, height);
1163  deallocate();
1164  }
1165  else // need only to reshape
1166  {
1167  newdata = data_;
1168  if(!skipInit)
1169  std::fill_n(newdata, width*height, d);
1170  newlines = initLineStartArray(newdata, width, height);
1171  pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
1172  }
1173  }
1174  else
1175  {
1176  deallocate();
1177  }
1178 
1179  data_ = newdata;
1180  lines_ = newlines;
1181  width_ = width;
1182  height_ = height;
1183  }
1184  else if(width*height > 0 && !skipInit) // keep size, re-init data
1185  {
1186  std::fill_n(data_, width*height, d);
1187  }
1188 }
1189 
1190 
1191 template <class PIXELTYPE, class Alloc>
1192 void
1193 BasicImage<PIXELTYPE, Alloc>::resizeCopy(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer data)
1194 {
1195  std::ptrdiff_t newsize = width*height;
1196  if (width_ != width || height_ != height) // change size?
1197  {
1198  value_type * newdata = 0;
1199  value_type ** newlines = 0;
1200  if(newsize > 0)
1201  {
1202  if (newsize != width_*height_) // different sizes, must reallocate
1203  {
1204  newdata = allocator_.allocate(typename Alloc::size_type(newsize));
1205  std::uninitialized_copy(data, data + newsize, newdata);
1206  newlines = initLineStartArray(newdata, width, height);
1207  deallocate();
1208  }
1209  else // need only to reshape
1210  {
1211  newdata = data_;
1212  std::copy(data, data + newsize, newdata);
1213  newlines = initLineStartArray(newdata, width, height);
1214  pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
1215  }
1216  }
1217  else
1218  {
1219  deallocate();
1220  }
1221 
1222  data_ = newdata;
1223  lines_ = newlines;
1224  width_ = width;
1225  height_ = height;
1226  }
1227  else if(newsize > 0) // keep size, copy data
1228  {
1229  std::copy(data, data + newsize, data_);
1230  }
1231 }
1232 
1233 template <class PIXELTYPE, class Alloc>
1234 void
1236 {
1237  if (&rhs!=this)
1238  {
1239  std::swap( data_, rhs.data_ );
1240  std::swap( lines_, rhs.lines_ );
1241  std::swap( width_, rhs.width_ );
1242  std::swap( height_, rhs.height_ );
1243  }
1244 }
1245 
1246 template <class PIXELTYPE, class Alloc>
1247 void
1249 {
1250  if(data_)
1251  {
1252  ScanOrderIterator i = begin();
1253  ScanOrderIterator iend = end();
1254 
1255  for(; i != iend; ++i) (*i).~PIXELTYPE();
1256 
1257  allocator_.deallocate(data_, typename Alloc::size_type(width()*height()));
1258  pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
1259  }
1260 }
1261 
1262 template <class PIXELTYPE, class Alloc>
1263 PIXELTYPE **
1264 BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, std::ptrdiff_t width, std::ptrdiff_t height)
1265 {
1266  value_type ** lines = pallocator_.allocate(typename Alloc::size_type(height));
1267  for(std::ptrdiff_t y=0; y<height; ++y)
1268  lines[y] = data + y*width;
1269  return lines;
1270 }
1271 
1272 /********************************************************/
1273 /* */
1274 /* argument object factories */
1275 /* */
1276 /********************************************************/
1277 
1278 template <class PixelType, class Accessor, class Alloc>
1279 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1280  typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1281 srcImageRange(BasicImage<PixelType, Alloc> const & img, Accessor a)
1282 {
1283  return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1284  typename BasicImage<PixelType, Alloc>::const_traverser,
1285  Accessor>(img.upperLeft(),
1286  img.lowerRight(),
1287  a);
1288 }
1289 
1290 template <class PixelType, class Accessor, class Alloc>
1291 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1292  typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1293 srcImageRange(BasicImage<PixelType, Alloc> const & img, Rect2D const & roi, Accessor a)
1294 {
1295  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
1296  roi.right() <= img.width() && roi.bottom() <= img.height(),
1297  "srcImageRange(): ROI rectangle outside image.");
1298  return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1299  typename BasicImage<PixelType, Alloc>::const_traverser,
1300  Accessor>(img.upperLeft() + roi.upperLeft(),
1301  img.upperLeft() + roi.lowerRight(),
1302  a);
1303 }
1304 
1305 template <class PixelType, class Accessor, class Alloc>
1306 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1307 srcImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
1308 {
1309  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1310  Accessor>(img.upperLeft(), a);
1311 }
1312 
1313 template <class PixelType, class Accessor, class Alloc>
1314 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1315 srcImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul, Accessor a)
1316 {
1317  vigra_precondition(img.isInside(ul),
1318  "srcImage(): ROI rectangle outside image.");
1319  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1320  Accessor>(img.upperLeft() + ul, a);
1321 }
1322 
1323 template <class PixelType, class Accessor, class Alloc>
1324 inline triple<typename BasicImage<PixelType, Alloc>::traverser,
1325  typename BasicImage<PixelType, Alloc>::traverser, Accessor>
1326 destImageRange(BasicImage<PixelType, Alloc> & img, Accessor a)
1327 {
1328  return triple<typename BasicImage<PixelType, Alloc>::traverser,
1329  typename BasicImage<PixelType, Alloc>::traverser,
1330  Accessor>(img.upperLeft(),
1331  img.lowerRight(),
1332  a);
1333 }
1334 
1335 template <class PixelType, class Accessor, class Alloc>
1336 inline triple<typename BasicImage<PixelType, Alloc>::traverser,
1337  typename BasicImage<PixelType, Alloc>::traverser, Accessor>
1338 destImageRange(BasicImage<PixelType, Alloc> & img, Rect2D const & roi, Accessor a)
1339 {
1340  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
1341  roi.right() <= img.width() && roi.bottom() <= img.height(),
1342  "destImageRange(): ROI rectangle outside image.");
1343  return triple<typename BasicImage<PixelType, Alloc>::traverser,
1344  typename BasicImage<PixelType, Alloc>::traverser,
1345  Accessor>(img.upperLeft() + roi.upperLeft(),
1346  img.upperLeft() + roi.lowerRight(),
1347  a);
1348 }
1349 
1350 template <class PixelType, class Accessor, class Alloc>
1351 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
1352 destImage(BasicImage<PixelType, Alloc> & img, Accessor a)
1353 {
1354  return pair<typename BasicImage<PixelType, Alloc>::traverser,
1355  Accessor>(img.upperLeft(), a);
1356 }
1357 
1358 template <class PixelType, class Accessor, class Alloc>
1359 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
1360 destImage(BasicImage<PixelType, Alloc> & img, Point2D const & ul, Accessor a)
1361 {
1362  vigra_precondition(img.isInside(ul),
1363  "destImage(): ROI rectangle outside image.");
1364  return pair<typename BasicImage<PixelType, Alloc>::traverser,
1365  Accessor>(img.upperLeft() + ul, a);
1366 }
1367 
1368 template <class PixelType, class Accessor, class Alloc>
1369 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1370 maskImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
1371 {
1372  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1373  Accessor>(img.upperLeft(), a);
1374 }
1375 
1376 template <class PixelType, class Accessor, class Alloc>
1377 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1378 maskImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul, Accessor a)
1379 {
1380  vigra_precondition(img.isInside(ul),
1381  "maskImage(): ROI rectangle outside image.");
1382  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1383  Accessor>(img.upperLeft() + ul, a);
1384 }
1385 
1386 /****************************************************************/
1387 
1388 template <class PixelType, class Alloc>
1389 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1390  typename BasicImage<PixelType, Alloc>::const_traverser,
1391  typename BasicImage<PixelType, Alloc>::ConstAccessor>
1392 srcImageRange(BasicImage<PixelType, Alloc> const & img)
1393 {
1394  return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1395  typename BasicImage<PixelType, Alloc>::const_traverser,
1396  typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
1397  img.lowerRight(),
1398  img.accessor());
1399 }
1400 
1401 template <class PixelType, class Alloc>
1402 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1403  typename BasicImage<PixelType, Alloc>::const_traverser,
1404  typename BasicImage<PixelType, Alloc>::ConstAccessor>
1405 srcImageRange(BasicImage<PixelType, Alloc> const & img, Rect2D const & roi)
1406 {
1407  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
1408  roi.right() <= img.width() && roi.bottom() <= img.height(),
1409  "srcImageRange(): ROI rectangle outside image.");
1410  return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1411  typename BasicImage<PixelType, Alloc>::const_traverser,
1412  typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + roi.upperLeft(),
1413  img.upperLeft() + roi.lowerRight(),
1414  img.accessor());
1415 }
1416 
1417 template <class PixelType, class Alloc>
1418 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1419  typename BasicImage<PixelType, Alloc>::ConstAccessor>
1420 srcImage(BasicImage<PixelType, Alloc> const & img)
1421 {
1422  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1423  typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
1424  img.accessor());
1425 }
1426 
1427 template <class PixelType, class Alloc>
1428 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1429  typename BasicImage<PixelType, Alloc>::ConstAccessor>
1430 srcImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul)
1431 {
1432  vigra_precondition(img.isInside(ul),
1433  "srcImage(): ROI rectangle outside image.");
1434  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1435  typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + ul,
1436  img.accessor());
1437 }
1438 
1439 template <class PixelType, class Alloc>
1440 inline triple< typename BasicImage<PixelType, Alloc>::traverser,
1441  typename BasicImage<PixelType, Alloc>::traverser,
1442  typename BasicImage<PixelType, Alloc>::Accessor>
1443 destImageRange(BasicImage<PixelType, Alloc> & img)
1444 {
1445  return triple<typename BasicImage<PixelType, Alloc>::traverser,
1446  typename BasicImage<PixelType, Alloc>::traverser,
1447  typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
1448  img.lowerRight(),
1449  img.accessor());
1450 }
1451 
1452 template <class PixelType, class Alloc>
1453 inline triple< typename BasicImage<PixelType, Alloc>::traverser,
1454  typename BasicImage<PixelType, Alloc>::traverser,
1455  typename BasicImage<PixelType, Alloc>::Accessor>
1456 destImageRange(BasicImage<PixelType, Alloc> & img, Rect2D const & roi)
1457 {
1458  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
1459  roi.right() <= img.width() && roi.bottom() <= img.height(),
1460  "destImageRange(): ROI rectangle outside image.");
1461  return triple<typename BasicImage<PixelType, Alloc>::traverser,
1462  typename BasicImage<PixelType, Alloc>::traverser,
1463  typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft() + roi.upperLeft(),
1464  img.upperLeft() + roi.lowerRight(),
1465  img.accessor());
1466 }
1467 
1468 template <class PixelType, class Alloc>
1469 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
1470  typename BasicImage<PixelType, Alloc>::Accessor>
1471 destImage(BasicImage<PixelType, Alloc> & img)
1472 {
1473  return pair<typename BasicImage<PixelType, Alloc>::traverser,
1474  typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
1475  img.accessor());
1476 }
1477 
1478 template <class PixelType, class Alloc>
1479 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
1480  typename BasicImage<PixelType, Alloc>::Accessor>
1481 destImage(BasicImage<PixelType, Alloc> & img, Point2D const & ul)
1482 {
1483  vigra_precondition(img.isInside(ul),
1484  "destImage(): ROI rectangle outside image.");
1485  return pair<typename BasicImage<PixelType, Alloc>::traverser,
1486  typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft() + ul,
1487  img.accessor());
1488 }
1489 
1490 template <class PixelType, class Alloc>
1491 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1492  typename BasicImage<PixelType, Alloc>::ConstAccessor>
1493 maskImage(BasicImage<PixelType, Alloc> const & img)
1494 {
1495  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1496  typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
1497  img.accessor());
1498 }
1499 
1500 template <class PixelType, class Alloc>
1501 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1502  typename BasicImage<PixelType, Alloc>::ConstAccessor>
1503 maskImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul)
1504 {
1505  vigra_precondition(img.isInside(ul),
1506  "maskImage(): ROI rectangle outside image.");
1507  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1508  typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + ul,
1509  img.accessor());
1510 }
1511 
1512 } // namespace vigra
1513 #undef VIGRA_ASSERT_INSIDE
1514 #endif // VIGRA_BASICIMAGE_HXX
iterator end()
Definition: basicimage.hxx:974
iterator begin()
Definition: basicimage.hxx:965
int MoveY
Definition: diff2d.hxx:229
ConstBasicImageIterator< PIXELTYPE, PIXELTYPE ** > ConstIterator
Definition: basicimage.hxx:544
const_traverser::column_iterator const_column_iterator
Definition: basicimage.hxx:560
Export associated information for each image iterator.
Definition: iteratortraits.hxx:109
row_iterator rowEnd(std::ptrdiff_t y)
Definition: basicimage.hxx:1008
Accessor accessor()
Definition: basicimage.hxx:1066
const_iterator begin() const
Definition: basicimage.hxx:983
const_iterator end() const
Definition: basicimage.hxx:992
PIXELTYPE & reference
Definition: basicimage.hxx:490
const_reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy) const
Definition: basicimage.hxx:897
int y
Definition: diff2d.hxx:392
size_type size() const
Definition: basicimage.hxx:854
BasicImage(difference_type const &size, SkipInitializationTag, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:695
IteratorTraits< traverser >::DefaultAccessor Accessor
Definition: basicimage.hxx:573
const_pointer operator[](std::ptrdiff_t dy) const
Definition: basicimage.hxx:917
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, value_type const &d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:642
BasicImage & init(value_type const &pixel)
Definition: basicimage.hxx:1130
int x
Definition: diff2d.hxx:385
const_reference operator[](difference_type const &d) const
Definition: basicimage.hxx:879
PIXELTYPE const & const_reference
Definition: basicimage.hxx:496
BasicImage(difference_type const &size, const_pointer d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:730
column_iterator columnEnd(std::ptrdiff_t x)
Definition: basicimage.hxx:1037
BasicImage()
Definition: basicimage.hxx:589
Two dimensional difference vector.
Definition: diff2d.hxx:185
void resize(std::ptrdiff_t width, std::ptrdiff_t height, SkipInitializationTag)
Definition: basicimage.hxx:816
PIXELTYPE * pointer
Definition: basicimage.hxx:500
traverser::column_iterator column_iterator
Definition: basicimage.hxx:556
PIXELTYPE const * ConstScanOrderIterator
Definition: basicimage.hxx:524
std::ptrdiff_t height() const
Definition: basicimage.hxx:847
BasicImageIterator< PIXELTYPE, PIXELTYPE ** > traverser
Definition: basicimage.hxx:528
Two dimensional size object.
Definition: diff2d.hxx:482
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, SkipInitializationTag, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:660
BasicImage(const BasicImage &rhs)
Definition: basicimage.hxx:746
Definition: basicimage.hxx:262
column_iterator columnBegin(std::ptrdiff_t x)
Definition: basicimage.hxx:1029
const_row_iterator rowEnd(std::ptrdiff_t y) const
Definition: basicimage.hxx:1022
const_column_iterator columnEnd(std::ptrdiff_t x) const
Definition: basicimage.hxx:1052
BasicImageIterator< PIXELTYPE, PIXELTYPE ** > Iterator
Definition: basicimage.hxx:532
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:607
PIXELTYPE const * const_pointer
Definition: basicimage.hxx:504
const_column_iterator columnBegin(std::ptrdiff_t x) const
Definition: basicimage.hxx:1044
void swap(BasicImage &rhs)
Definition: basicimage.hxx:1235
Alloc allocator_type
Definition: basicimage.hxx:582
Definition: basicimage.hxx:126
BasicImage(difference_type const &size, value_type const &d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:678
int MoveX
Definition: diff2d.hxx:226
reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy)
Definition: basicimage.hxx:888
const_pointer data() const
Definition: basicimage.hxx:1059
pointer operator[](std::ptrdiff_t dy)
Definition: basicimage.hxx:907
bool isInside(difference_type const &d) const
Definition: basicimage.hxx:861
const_traverser::row_iterator const_row_iterator
Definition: basicimage.hxx:552
PIXELTYPE const * const_iterator
Definition: basicimage.hxx:520
Size2D size_type
Definition: basicimage.hxx:568
IteratorTraits< const_traverser >::DefaultAccessor ConstAccessor
Definition: basicimage.hxx:578
void resize(std::ptrdiff_t width, std::ptrdiff_t height, value_type const &d)
Definition: basicimage.hxx:800
traverser lowerRight()
Definition: basicimage.hxx:936
PIXELTYPE PixelType
Definition: basicimage.hxx:485
ConstBasicImageIterator< PIXELTYPE, PIXELTYPE ** > const_traverser
Definition: basicimage.hxx:538
const_traverser lowerRight() const
Definition: basicimage.hxx:956
BasicImage(difference_type const &size, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:623
Fundamental class template for images.
Definition: basicimage.hxx:475
PIXELTYPE * ScanOrderIterator
Definition: basicimage.hxx:514
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:713
Definition: basicimage.hxx:294
void resize(std::ptrdiff_t width, std::ptrdiff_t height)
Definition: basicimage.hxx:778
void resizeCopy(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer data)
Definition: basicimage.hxx:1193
row_iterator rowBegin(std::ptrdiff_t y)
Definition: basicimage.hxx:1001
traverser::row_iterator row_iterator
Definition: basicimage.hxx:548
reference operator[](difference_type const &d)
Definition: basicimage.hxx:870
~BasicImage()
Definition: basicimage.hxx:758
void resizeCopy(const BasicImage &rhs)
Definition: basicimage.hxx:829
Diff2D difference_type
Definition: basicimage.hxx:564
Encapsulate access to the values an iterator points to.
Definition: accessor.hxx:133
Quickly create 1-dimensional iterator adapters.
Definition: iteratoradapter.hxx:147
std::ptrdiff_t width() const
Definition: basicimage.hxx:840
BasicImage & operator=(const BasicImage &rhs)
Definition: basicimage.hxx:1095
void resize(difference_type const &size)
Definition: basicimage.hxx:787
BasicImage(Alloc const &alloc)
Definition: basicimage.hxx:597
ConstAccessor accessor() const
Definition: basicimage.hxx:1073
const_traverser upperLeft() const
Definition: basicimage.hxx:945
PIXELTYPE value_type
Definition: basicimage.hxx:481
traverser upperLeft()
Definition: basicimage.hxx:925
PIXELTYPE * iterator
Definition: basicimage.hxx:510
const_row_iterator rowBegin(std::ptrdiff_t y) const
Definition: basicimage.hxx:1015

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)