[ 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 
276  BasicImageIterator()
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 
308  ConstBasicImageIterator(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs)
309  : Base(rhs.x, rhs.y)
310  {}
311 
312  ConstBasicImageIterator()
313  : Base()
314  {}
315 
316  ConstBasicImageIterator &
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  A customized memory allocator can be specified as a templated argument
467  and passed in the constructor.
468 
469  <b>\#include</b> <vigra/basicimage.hxx> <br/>
470  Namespace: vigra
471 */
472 template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> >
474 {
475  public:
476 
477  /** the BasicImage's pixel type
478  */
479  typedef PIXELTYPE value_type;
480 
481  /** the BasicImage's pixel type
482  */
483  typedef PIXELTYPE PixelType;
484 
485  /** the BasicImage's reference type (i.e. the
486  return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>)
487  */
488  typedef PIXELTYPE & reference;
489 
490  /** the BasicImage's const reference type (i.e. the
491  return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>
492  when <TT>image</TT> is const)
493  */
494  typedef PIXELTYPE const & const_reference;
495 
496  /** the BasicImage's pointer type
497  */
498  typedef PIXELTYPE * pointer;
499 
500  /** the BasicImage's const pointer type
501  */
502  typedef PIXELTYPE const * const_pointer;
503 
504  /** the BasicImage's 1D random access iterator
505  (note: lower case 'iterator' is a STL compatible 1D random
506  access iterator, don't confuse with capitalized Iterator)
507  */
508  typedef PIXELTYPE * iterator;
509 
510  /** deprecated, use <TT>iterator</TT> instead
511  */
512  typedef PIXELTYPE * ScanOrderIterator;
513 
514  /** the BasicImage's 1D random access const iterator
515  (note: lower case 'const_iterator' is a STL compatible 1D
516  random access const iterator)
517  */
518  typedef PIXELTYPE const * const_iterator;
519 
520  /** deprecated, use <TT>const_iterator</TT> instead
521  */
522  typedef PIXELTYPE const * ConstScanOrderIterator;
523 
524  /** the BasicImage's 2D random access iterator ('traverser')
525  */
527 
528  /** deprecated, use <TT>traverser</TT> instead
529  */
531 
532  /** the BasicImage's 2D random access const iterator ('const traverser')
533  */
534  typedef
537 
538  /** deprecated, use <TT>const_traverser</TT> instead
539  */
540  typedef
543 
544  /** the row iterator associated with the traverser
545  */
546  typedef typename traverser::row_iterator row_iterator;
547 
548  /** the const row iterator associated with the const_traverser
549  */
550  typedef typename const_traverser::row_iterator const_row_iterator;
551 
552  /** the column iterator associated with the traverser
553  */
555 
556  /** the const column iterator associated with the const_traverser
557  */
559 
560  /** the BasicImage's difference type (argument type of image[diff])
561  */
563 
564  /** the BasicImage's size type (result type of image.size())
565  */
566  typedef Size2D size_type;
567 
568  /** the BasicImage's default accessor
569  */
570  typedef typename
572 
573  /** the BasicImage's default const accessor
574  */
575  typedef typename
577 
578  /** the BasicImage's allocator (default: std::allocator<value_type>)
579  */
580  typedef Alloc allocator_type;
581 
582  typedef Alloc Allocator;
583  typedef typename Alloc::template rebind<PIXELTYPE *>::other LineAllocator;
584 
585  /** construct image of size 0x0
586  */
588  : data_(0),
589  width_(0),
590  height_(0)
591  {}
592 
593  /** construct image of size 0x0, use the specified allocator.
594  */
595  explicit BasicImage(Alloc const & alloc)
596  : data_(0),
597  width_(0),
598  height_(0),
599  allocator_(alloc),
600  pallocator_(alloc)
601  {}
602 
603  /** construct image of size width x height, use the specified allocator.
604  */
605  BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, Alloc const & alloc = Alloc())
606  : data_(0),
607  width_(0),
608  height_(0),
609  allocator_(alloc),
610  pallocator_(alloc)
611  {
612  vigra_precondition((width >= 0) && (height >= 0),
613  "BasicImage::BasicImage(int width, int height): "
614  "width and height must be >= 0.\n");
615 
616  resize(width, height, value_type());
617  }
618 
619  /** construct image of size size.x x size.y, use the specified allocator.
620  */
621  explicit BasicImage(difference_type const & size, Alloc const & alloc = Alloc())
622  : data_(0),
623  width_(0),
624  height_(0),
625  allocator_(alloc),
626  pallocator_(alloc)
627  {
628  vigra_precondition((size.x >= 0) && (size.y >= 0),
629  "BasicImage::BasicImage(Diff2D size): "
630  "size.x and size.y must be >= 0.\n");
631 
632  resize(size.x, size.y, value_type());
633  }
634 
635  /** construct image of size width*height and initialize every
636  pixel with the value \a d (use this constructor, if
637  value_type doesn't have a default constructor).
638  Use the specified allocator.
639  */
640  BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, value_type const & d, Alloc const & alloc = Alloc())
641  : data_(0),
642  width_(0),
643  height_(0),
644  allocator_(alloc),
645  pallocator_(alloc)
646  {
647  vigra_precondition((width >= 0) && (height >= 0),
648  "BasicImage::BasicImage(int width, int height, value_type const & ): "
649  "width and height must be >= 0.\n");
650 
651  resize(width, height, d);
652  }
653 
654  /** construct image of size width*height and try to skip initialization
655  of the memory (see BasicImage::resize for details).
656  Use the specified allocator.
657  */
658  BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, SkipInitializationTag, Alloc const & alloc = Alloc())
659  : data_(0),
660  width_(0),
661  height_(0),
662  allocator_(alloc),
663  pallocator_(alloc)
664  {
665  vigra_precondition((width >= 0) && (height >= 0),
666  "BasicImage::BasicImage(int width, int height, value_type const & ): "
667  "width and height must be >= 0.\n");
668 
669  resize(width, height, SkipInitialization);
670  }
671 
672  /** construct image of size size.x x size.y and initialize
673  every pixel with given data (use this constructor, if
674  value_type doesn't have a default constructor). Use the specified allocator.
675  */
676  explicit BasicImage(difference_type const & size, value_type const & d, Alloc const & alloc = Alloc())
677  : data_(0),
678  width_(0),
679  height_(0),
680  allocator_(alloc),
681  pallocator_(alloc)
682  {
683  vigra_precondition((size.x >= 0) && (size.y >= 0),
684  "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
685  "size.x and size.y must be >= 0.\n");
686 
687  resize(size.x, size.y, d);
688  }
689 
690  /** construct image of size size.x x size.y and try to skip initialization
691  of the memory (see BasicImage::resize for details). Use the specified allocator.
692  */
693  explicit BasicImage(difference_type const & size, SkipInitializationTag, Alloc const & alloc = Alloc())
694  : data_(0),
695  width_(0),
696  height_(0),
697  allocator_(alloc),
698  pallocator_(alloc)
699  {
700  vigra_precondition((size.x >= 0) && (size.y >= 0),
701  "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
702  "size.x and size.y must be >= 0.\n");
703 
704  resize(size.x, size.y, SkipInitialization);
705  }
706 
707 
708  /** construct image of size width*height and copy the data from the
709  given C-style array \a d. Use the specified allocator.
710  */
711  BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer d, Alloc const & alloc = Alloc())
712  : data_(0),
713  width_(0),
714  height_(0),
715  allocator_(alloc),
716  pallocator_(alloc)
717  {
718  vigra_precondition((width >= 0) && (height >= 0),
719  "BasicImage::BasicImage(int width, int height, const_pointer ): "
720  "width and height must be >= 0.\n");
721 
722  resizeCopy(width, height, d);
723  }
724 
725  /** construct image of size size.x x size.y and copy the data from the
726  given C-style array. Use the specified allocator.
727  */
728  explicit BasicImage(difference_type const & size, const_pointer d, Alloc const & alloc = Alloc())
729  : data_(0),
730  width_(0),
731  height_(0),
732  allocator_(alloc),
733  pallocator_(alloc)
734  {
735  vigra_precondition((size.x >= 0) && (size.y >= 0),
736  "BasicImage::BasicImage(Diff2D const & size, const_pointer): "
737  "size.x and size.y must be >= 0.\n");
738 
739  resizeCopy(size.x, size.y, d);
740  }
741 
742  /** copy rhs image
743  */
744  BasicImage(const BasicImage & rhs)
745  : data_(0),
746  width_(0),
747  height_(0),
748  allocator_(rhs.allocator_),
749  pallocator_(rhs.pallocator_)
750  {
751  resizeCopy(rhs);
752  }
753 
754  /** destructor
755  */
757  {
758  deallocate();
759  }
760 
761  /** copy rhs image (image is resized if necessary)
762  */
763  BasicImage & operator=(const BasicImage & rhs);
764 
765  /** \deprecated set Image with const value
766  */
767  BasicImage & operator=(value_type pixel);
768 
769  /** set Image with const value
770  */
771  BasicImage & init(value_type const & pixel);
772 
773  /** reset image to specified size (dimensions must not be negative)
774  (old data are kept if new size matches old size)
775  */
776  void resize(std::ptrdiff_t width, std::ptrdiff_t height)
777  {
778  if(width != width_ || height != height_)
779  resize(width, height, value_type());
780  }
781 
782  /** reset image to specified size (dimensions must not be negative)
783  (old data are kept if new size matches old size)
784  */
785  void resize(difference_type const & size)
786  {
787  if(size.x != width_ || size.y != height_)
788  {
789  resize(size.x, size.y, value_type());
790  }
791  }
792 
793  /** reset image to specified size and initialize it with
794  given data (use this if value_type doesn't have a default
795  constructor, dimensions must not be negative,
796  old data are kept if new size matches old size)
797  */
798  void resize(std::ptrdiff_t width, std::ptrdiff_t height, value_type const & d)
799  {
800  resizeImpl(width, height, d, false);
801  }
802 
803  /** reset image to specified size and skip initialization
804  if possible (use this if <tt>value_type</tt> is a built-in type
805  or <tt>TinyVector&lt;builtin&gt&</tt> and the data is
806  immediately overridden afterwards). If <tt>value_type</tt> requires
807  initialization, <tt>SkipInitialization</tt> is ignored.
808 
809  Usage:
810  \code
811  image.resize(new_width, new_height, SkipInitialization);
812  \endcode
813  */
814  void resize(std::ptrdiff_t width, std::ptrdiff_t height, SkipInitializationTag)
815  {
816  resizeImpl(width, height, NumericTraits<value_type>::zero(),
817  CanSkipInitialization<value_type>::value);
818  }
819 
820  /** resize image to given size and initialize by copying data
821  from the C-style array \a data.
822  */
823  void resizeCopy(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer data);
824 
825  /** resize image to size of other image and copy its data
826  */
827  void resizeCopy(const BasicImage & rhs)
828  {
829  resizeCopy(rhs.width(), rhs.height(), rhs.data_);
830  }
831 
832  /** swap the internal data with the rhs image in constant time
833  */
834  void swap( BasicImage & rhs );
835 
836  /** width of Image
837  */
838  std::ptrdiff_t width() const
839  {
840  return width_;
841  }
842 
843  /** height of Image
844  */
845  std::ptrdiff_t height() const
846  {
847  return height_;
848  }
849 
850  /** size of Image
851  */
852  size_type size() const
853  {
854  return size_type(width(), height());
855  }
856 
857  /** test whether a given coordinate is inside the image
858  */
859  bool isInside(difference_type const & d) const
860  {
861  return d.x >= 0 && d.y >= 0 &&
862  d.x < width() && d.y < height();
863  }
864 
865  /** access pixel at given location. <br>
866  usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
867  */
868  reference operator[](difference_type const & d)
869  {
870  VIGRA_ASSERT_INSIDE(d);
871  return lines_[d.y][d.x];
872  }
873 
874  /** read pixel at given location. <br>
875  usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
876  */
877  const_reference operator[](difference_type const & d) const
878  {
879  VIGRA_ASSERT_INSIDE(d);
880  return lines_[d.y][d.x];
881  }
882 
883  /** access pixel at given location. <br>
884  usage: <TT> value_type value = image(1,2) </TT>
885  */
886  reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy)
887  {
888  VIGRA_ASSERT_INSIDE(difference_type(dx,dy));
889  return lines_[dy][dx];
890  }
891 
892  /** read pixel at given location. <br>
893  usage: <TT> value_type value = image(1,2) </TT>
894  */
895  const_reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy) const
896  {
897  VIGRA_ASSERT_INSIDE(difference_type(dx,dy));
898  return lines_[dy][dx];
899  }
900 
901  /** access pixel at given location.
902  Note that the 'x' index is the trailing index. <br>
903  usage: <TT> value_type value = image[2][1] </TT>
904  */
905  pointer operator[](std::ptrdiff_t dy)
906  {
907  VIGRA_ASSERT_INSIDE(difference_type(0,dy));
908  return lines_[dy];
909  }
910 
911  /** read pixel at given location.
912  Note that the 'x' index is the trailing index. <br>
913  usage: <TT> value_type value = image[2][1] </TT>
914  */
915  const_pointer operator[](std::ptrdiff_t dy) const
916  {
917  VIGRA_ASSERT_INSIDE(difference_type(0,dy));
918  return lines_[dy];
919  }
920 
921  /** init 2D random access iterator pointing to upper left pixel
922  */
923  traverser upperLeft()
924  {
925  vigra_precondition(data_ != 0,
926  "BasicImage::upperLeft(): image must have non-zero size.");
927  return traverser(lines_);
928  }
929 
930  /** init 2D random access iterator pointing to
931  pixel(width, height), i.e. one pixel right and below lower right
932  corner of the image as is common in C/C++.
933  */
934  traverser lowerRight()
935  {
936  vigra_precondition(data_ != 0,
937  "BasicImage::lowerRight(): image must have non-zero size.");
938  return upperLeft() + size();
939  }
940 
941  /** init 2D random access const iterator pointing to upper left pixel
942  */
944  {
945  vigra_precondition(data_ != 0,
946  "BasicImage::upperLeft(): image must have non-zero size.");
947  return const_traverser(const_cast<PIXELTYPE **>(lines_));
948  }
949 
950  /** init 2D random access const iterator pointing to
951  pixel(width, height), i.e. one pixel right and below lower right
952  corner of the image as is common in C/C++.
953  */
955  {
956  vigra_precondition(data_ != 0,
957  "BasicImage::lowerRight(): image must have non-zero size.");
958  return upperLeft() + size();
959  }
960 
961  /** init 1D random access iterator pointing to first pixel
962  */
963  iterator begin()
964  {
965  vigra_precondition(data_ != 0,
966  "BasicImage::begin(): image must have non-zero size.");
967  return data_;
968  }
969 
970  /** init 1D random access iterator pointing past the end
971  */
972  iterator end()
973  {
974  vigra_precondition(data_ != 0,
975  "BasicImage::end(): image must have non-zero size.");
976  return data_ + width() * height();
977  }
978 
979  /** init 1D random access const iterator pointing to first pixel
980  */
981  const_iterator begin() const
982  {
983  vigra_precondition(data_ != 0,
984  "BasicImage::begin(): image must have non-zero size.");
985  return data_;
986  }
987 
988  /** init 1D random access const iterator pointing past the end
989  */
990  const_iterator end() const
991  {
992  vigra_precondition(data_ != 0,
993  "BasicImage::end(): image must have non-zero size.");
994  return data_ + width() * height();
995  }
996 
997  /** init 1D random access iterator pointing to first pixel of row \a y
998  */
999  row_iterator rowBegin(std::ptrdiff_t y)
1000  {
1001  return lines_[y];
1002  }
1003 
1004  /** init 1D random access iterator pointing past the end of row \a y
1005  */
1006  row_iterator rowEnd(std::ptrdiff_t y)
1007  {
1008  return rowBegin(y) + width();
1009  }
1010 
1011  /** init 1D random access const iterator pointing to first pixel of row \a y
1012  */
1013  const_row_iterator rowBegin(std::ptrdiff_t y) const
1014  {
1015  return lines_[y];
1016  }
1017 
1018  /** init 1D random access const iterator pointing past the end of row \a y
1019  */
1020  const_row_iterator rowEnd(std::ptrdiff_t y) const
1021  {
1022  return rowBegin(y) + width();
1023  }
1024 
1025  /** init 1D random access iterator pointing to first pixel of column \a x
1026  */
1027  column_iterator columnBegin(std::ptrdiff_t x)
1028  {
1029  typedef typename column_iterator::BaseType Iter;
1030  return column_iterator(Iter(lines_, x));
1031  }
1032 
1033  /** init 1D random access iterator pointing past the end of column \a x
1034  */
1035  column_iterator columnEnd(std::ptrdiff_t x)
1036  {
1037  return columnBegin(x) + height();
1038  }
1039 
1040  /** init 1D random access const iterator pointing to first pixel of column \a x
1041  */
1042  const_column_iterator columnBegin(std::ptrdiff_t x) const
1043  {
1044  typedef typename const_column_iterator::BaseType Iter;
1045  return const_column_iterator(Iter(lines_, x));
1046  }
1047 
1048  /** init 1D random access const iterator pointing past the end of column \a x
1049  */
1050  const_column_iterator columnEnd(std::ptrdiff_t x) const
1051  {
1052  return columnBegin(x) + height();
1053  }
1054 
1055  /** get a pointer to the internal data
1056  */
1057  const_pointer data() const
1058  {
1059  return data_;
1060  }
1061 
1062  /** return default accessor
1063  */
1064  Accessor accessor()
1065  {
1066  return Accessor();
1067  }
1068 
1069  /** return default const accessor
1070  */
1071  ConstAccessor accessor() const
1072  {
1073  return ConstAccessor();
1074  }
1075 
1076  private:
1077 
1078  void deallocate();
1079  void resizeImpl(std::ptrdiff_t width, std::ptrdiff_t height, value_type const & d, bool skipInit);
1080 
1081 
1082  value_type ** initLineStartArray(value_type * data, std::ptrdiff_t width, std::ptrdiff_t height);
1083 
1084  PIXELTYPE * data_;
1085  PIXELTYPE ** lines_;
1086  std::ptrdiff_t width_, height_;
1087  Alloc allocator_;
1088  LineAllocator pallocator_;
1089 };
1090 
1091 template <class PIXELTYPE, class Alloc>
1094 {
1095  if(this != &rhs)
1096  {
1097  if((width() != rhs.width()) ||
1098  (height() != rhs.height()))
1099  {
1100  resizeCopy(rhs);
1101  }
1102  else
1103  {
1104  ConstScanOrderIterator is = rhs.begin();
1105  ConstScanOrderIterator iend = rhs.end();
1106  ScanOrderIterator id = begin();
1107 
1108  for(; is != iend; ++is, ++id) *id = *is;
1109  }
1110  }
1111  return *this;
1112 }
1113 
1114 template <class PIXELTYPE, class Alloc>
1117 {
1118  ScanOrderIterator i = begin();
1119  ScanOrderIterator iend = end();
1120 
1121  for(; i != iend; ++i) *i = pixel;
1122 
1123  return *this;
1124 }
1125 
1126 template <class PIXELTYPE, class Alloc>
1128 BasicImage<PIXELTYPE, Alloc>::init(value_type const & pixel)
1129 {
1130  ScanOrderIterator i = begin();
1131  ScanOrderIterator iend = end();
1132 
1133  for(; i != iend; ++i) *i = pixel;
1134 
1135  return *this;
1136 }
1137 
1138 template <class PIXELTYPE, class Alloc>
1139 void
1140 BasicImage<PIXELTYPE, Alloc>::resizeImpl(std::ptrdiff_t width, std::ptrdiff_t height, value_type const & d, bool skipInit)
1141 {
1142  vigra_precondition((width >= 0) && (height >= 0),
1143  "BasicImage::resize(int width, int height, value_type const &): "
1144  "width and height must be >= 0.\n");
1145  vigra_precondition(width * height >= 0,
1146  "BasicImage::resize(int width, int height, value_type const &): "
1147  "width * height too large (integer overflow -> negative).\n");
1148 
1149  if (width_ != width || height_ != height) // change size?
1150  {
1151  value_type * newdata = 0;
1152  value_type ** newlines = 0;
1153  if(width*height > 0)
1154  {
1155  if (width*height != width_*height_) // different sizes, must reallocate
1156  {
1157  newdata = allocator_.allocate(typename Alloc::size_type(width*height));
1158  if(!skipInit)
1159  std::uninitialized_fill_n(newdata, width*height, d);
1160  newlines = initLineStartArray(newdata, width, height);
1161  deallocate();
1162  }
1163  else // need only to reshape
1164  {
1165  newdata = data_;
1166  if(!skipInit)
1167  std::fill_n(newdata, width*height, d);
1168  newlines = initLineStartArray(newdata, width, height);
1169  pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
1170  }
1171  }
1172  else
1173  {
1174  deallocate();
1175  }
1176 
1177  data_ = newdata;
1178  lines_ = newlines;
1179  width_ = width;
1180  height_ = height;
1181  }
1182  else if(width*height > 0 && !skipInit) // keep size, re-init data
1183  {
1184  std::fill_n(data_, width*height, d);
1185  }
1186 }
1187 
1188 
1189 template <class PIXELTYPE, class Alloc>
1190 void
1191 BasicImage<PIXELTYPE, Alloc>::resizeCopy(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer data)
1192 {
1193  std::ptrdiff_t newsize = width*height;
1194  if (width_ != width || height_ != height) // change size?
1195  {
1196  value_type * newdata = 0;
1197  value_type ** newlines = 0;
1198  if(newsize > 0)
1199  {
1200  if (newsize != width_*height_) // different sizes, must reallocate
1201  {
1202  newdata = allocator_.allocate(typename Alloc::size_type(newsize));
1203  std::uninitialized_copy(data, data + newsize, newdata);
1204  newlines = initLineStartArray(newdata, width, height);
1205  deallocate();
1206  }
1207  else // need only to reshape
1208  {
1209  newdata = data_;
1210  std::copy(data, data + newsize, newdata);
1211  newlines = initLineStartArray(newdata, width, height);
1212  pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
1213  }
1214  }
1215  else
1216  {
1217  deallocate();
1218  }
1219 
1220  data_ = newdata;
1221  lines_ = newlines;
1222  width_ = width;
1223  height_ = height;
1224  }
1225  else if(newsize > 0) // keep size, copy data
1226  {
1227  std::copy(data, data + newsize, data_);
1228  }
1229 }
1230 
1231 template <class PIXELTYPE, class Alloc>
1232 void
1234 {
1235  if (&rhs!=this)
1236  {
1237  std::swap( data_, rhs.data_ );
1238  std::swap( lines_, rhs.lines_ );
1239  std::swap( width_, rhs.width_ );
1240  std::swap( height_, rhs.height_ );
1241  }
1242 }
1243 
1244 template <class PIXELTYPE, class Alloc>
1245 void
1247 {
1248  if(data_)
1249  {
1250  ScanOrderIterator i = begin();
1251  ScanOrderIterator iend = end();
1252 
1253  for(; i != iend; ++i) (*i).~PIXELTYPE();
1254 
1255  allocator_.deallocate(data_, typename Alloc::size_type(width()*height()));
1256  pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
1257  }
1258 }
1259 
1260 template <class PIXELTYPE, class Alloc>
1261 PIXELTYPE **
1262 BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, std::ptrdiff_t width, std::ptrdiff_t height)
1263 {
1264  value_type ** lines = pallocator_.allocate(typename Alloc::size_type(height));
1265  for(std::ptrdiff_t y=0; y<height; ++y)
1266  lines[y] = data + y*width;
1267  return lines;
1268 }
1269 
1270 /********************************************************/
1271 /* */
1272 /* argument object factories */
1273 /* */
1274 /********************************************************/
1275 
1276 template <class PixelType, class Accessor, class Alloc>
1277 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1279 srcImageRange(BasicImage<PixelType, Alloc> const & img, Accessor a)
1280 {
1281  return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1282  typename BasicImage<PixelType, Alloc>::const_traverser,
1283  Accessor>(img.upperLeft(),
1284  img.lowerRight(),
1285  a);
1286 }
1287 
1288 template <class PixelType, class Accessor, class Alloc>
1289 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1290  typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1291 srcImageRange(BasicImage<PixelType, Alloc> const & img, Rect2D const & roi, Accessor a)
1292 {
1293  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
1294  roi.right() <= img.width() && roi.bottom() <= img.height(),
1295  "srcImageRange(): ROI rectangle outside image.");
1296  return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1297  typename BasicImage<PixelType, Alloc>::const_traverser,
1298  Accessor>(img.upperLeft() + roi.upperLeft(),
1299  img.upperLeft() + roi.lowerRight(),
1300  a);
1301 }
1302 
1303 template <class PixelType, class Accessor, class Alloc>
1304 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1305 srcImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
1306 {
1307  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1308  Accessor>(img.upperLeft(), a);
1309 }
1310 
1311 template <class PixelType, class Accessor, class Alloc>
1312 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1313 srcImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul, Accessor a)
1314 {
1315  vigra_precondition(img.isInside(ul),
1316  "srcImage(): ROI rectangle outside image.");
1317  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1318  Accessor>(img.upperLeft() + ul, a);
1319 }
1320 
1321 template <class PixelType, class Accessor, class Alloc>
1322 inline triple<typename BasicImage<PixelType, Alloc>::traverser,
1323  typename BasicImage<PixelType, Alloc>::traverser, Accessor>
1324 destImageRange(BasicImage<PixelType, Alloc> & img, Accessor a)
1325 {
1326  return triple<typename BasicImage<PixelType, Alloc>::traverser,
1327  typename BasicImage<PixelType, Alloc>::traverser,
1328  Accessor>(img.upperLeft(),
1329  img.lowerRight(),
1330  a);
1331 }
1332 
1333 template <class PixelType, class Accessor, class Alloc>
1334 inline triple<typename BasicImage<PixelType, Alloc>::traverser,
1335  typename BasicImage<PixelType, Alloc>::traverser, Accessor>
1336 destImageRange(BasicImage<PixelType, Alloc> & img, Rect2D const & roi, Accessor a)
1337 {
1338  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
1339  roi.right() <= img.width() && roi.bottom() <= img.height(),
1340  "destImageRange(): ROI rectangle outside image.");
1341  return triple<typename BasicImage<PixelType, Alloc>::traverser,
1342  typename BasicImage<PixelType, Alloc>::traverser,
1343  Accessor>(img.upperLeft() + roi.upperLeft(),
1344  img.upperLeft() + roi.lowerRight(),
1345  a);
1346 }
1347 
1348 template <class PixelType, class Accessor, class Alloc>
1349 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
1350 destImage(BasicImage<PixelType, Alloc> & img, Accessor a)
1351 {
1352  return pair<typename BasicImage<PixelType, Alloc>::traverser,
1353  Accessor>(img.upperLeft(), a);
1354 }
1355 
1356 template <class PixelType, class Accessor, class Alloc>
1357 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
1358 destImage(BasicImage<PixelType, Alloc> & img, Point2D const & ul, Accessor a)
1359 {
1360  vigra_precondition(img.isInside(ul),
1361  "destImage(): ROI rectangle outside image.");
1362  return pair<typename BasicImage<PixelType, Alloc>::traverser,
1363  Accessor>(img.upperLeft() + ul, a);
1364 }
1365 
1366 template <class PixelType, class Accessor, class Alloc>
1367 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1368 maskImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
1369 {
1370  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1371  Accessor>(img.upperLeft(), a);
1372 }
1373 
1374 template <class PixelType, class Accessor, class Alloc>
1375 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
1376 maskImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul, Accessor a)
1377 {
1378  vigra_precondition(img.isInside(ul),
1379  "maskImage(): ROI rectangle outside image.");
1380  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1381  Accessor>(img.upperLeft() + ul, a);
1382 }
1383 
1384 /****************************************************************/
1385 
1386 template <class PixelType, class Alloc>
1387 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1388  typename BasicImage<PixelType, Alloc>::const_traverser,
1390 srcImageRange(BasicImage<PixelType, Alloc> const & img)
1391 {
1392  return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1393  typename BasicImage<PixelType, Alloc>::const_traverser,
1395  img.lowerRight(),
1396  img.accessor());
1397 }
1398 
1399 template <class PixelType, class Alloc>
1400 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1401  typename BasicImage<PixelType, Alloc>::const_traverser,
1403 srcImageRange(BasicImage<PixelType, Alloc> const & img, Rect2D const & roi)
1404 {
1405  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
1406  roi.right() <= img.width() && roi.bottom() <= img.height(),
1407  "srcImageRange(): ROI rectangle outside image.");
1408  return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1409  typename BasicImage<PixelType, Alloc>::const_traverser,
1411  img.upperLeft() + roi.lowerRight(),
1412  img.accessor());
1413 }
1414 
1415 template <class PixelType, class Alloc>
1416 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1418 srcImage(BasicImage<PixelType, Alloc> const & img)
1419 {
1420  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1422  img.accessor());
1423 }
1424 
1425 template <class PixelType, class Alloc>
1426 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1428 srcImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul)
1429 {
1430  vigra_precondition(img.isInside(ul),
1431  "srcImage(): ROI rectangle outside image.");
1432  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1434  img.accessor());
1435 }
1436 
1437 template <class PixelType, class Alloc>
1438 inline triple< typename BasicImage<PixelType, Alloc>::traverser,
1439  typename BasicImage<PixelType, Alloc>::traverser,
1441 destImageRange(BasicImage<PixelType, Alloc> & img)
1442 {
1443  return triple<typename BasicImage<PixelType, Alloc>::traverser,
1444  typename BasicImage<PixelType, Alloc>::traverser,
1446  img.lowerRight(),
1447  img.accessor());
1448 }
1449 
1450 template <class PixelType, class Alloc>
1451 inline triple< typename BasicImage<PixelType, Alloc>::traverser,
1452  typename BasicImage<PixelType, Alloc>::traverser,
1454 destImageRange(BasicImage<PixelType, Alloc> & img, Rect2D const & roi)
1455 {
1456  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
1457  roi.right() <= img.width() && roi.bottom() <= img.height(),
1458  "destImageRange(): ROI rectangle outside image.");
1459  return triple<typename BasicImage<PixelType, Alloc>::traverser,
1460  typename BasicImage<PixelType, Alloc>::traverser,
1462  img.upperLeft() + roi.lowerRight(),
1463  img.accessor());
1464 }
1465 
1466 template <class PixelType, class Alloc>
1467 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
1469 destImage(BasicImage<PixelType, Alloc> & img)
1470 {
1471  return pair<typename BasicImage<PixelType, Alloc>::traverser,
1473  img.accessor());
1474 }
1475 
1476 template <class PixelType, class Alloc>
1477 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
1479 destImage(BasicImage<PixelType, Alloc> & img, Point2D const & ul)
1480 {
1481  vigra_precondition(img.isInside(ul),
1482  "destImage(): ROI rectangle outside image.");
1483  return pair<typename BasicImage<PixelType, Alloc>::traverser,
1485  img.accessor());
1486 }
1487 
1488 template <class PixelType, class Alloc>
1489 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1491 maskImage(BasicImage<PixelType, Alloc> const & img)
1492 {
1493  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1495  img.accessor());
1496 }
1497 
1498 template <class PixelType, class Alloc>
1499 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1501 maskImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul)
1502 {
1503  vigra_precondition(img.isInside(ul),
1504  "maskImage(): ROI rectangle outside image.");
1505  return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1507  img.accessor());
1508 }
1509 
1510 } // namespace vigra
1511 #undef VIGRA_ASSERT_INSIDE
1512 #endif // VIGRA_BASICIMAGE_HXX
iterator end()
Definition: basicimage.hxx:972
iterator begin()
Definition: basicimage.hxx:963
int MoveY
Definition: diff2d.hxx:229
int left() const
Definition: diff2d.hxx:974
ConstBasicImageIterator< PIXELTYPE, PIXELTYPE ** > ConstIterator
Definition: basicimage.hxx:542
const_traverser::column_iterator const_column_iterator
Definition: basicimage.hxx:558
Export associated information for each image iterator.
Definition: iteratortraits.hxx:109
row_iterator rowEnd(std::ptrdiff_t y)
Definition: basicimage.hxx:1006
Accessor accessor()
Definition: basicimage.hxx:1064
const_iterator begin() const
Definition: basicimage.hxx:981
const_iterator end() const
Definition: basicimage.hxx:990
PIXELTYPE & reference
Definition: basicimage.hxx:488
const_reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy) const
Definition: basicimage.hxx:895
int y
Definition: diff2d.hxx:392
Diff2D operator-(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:711
size_type size() const
Definition: basicimage.hxx:852
BasicImage(difference_type const &size, SkipInitializationTag, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:693
IteratorTraits< traverser >::DefaultAccessor Accessor
Definition: basicimage.hxx:571
const_pointer operator[](std::ptrdiff_t dy) const
Definition: basicimage.hxx:915
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, value_type const &d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:640
int right() const
Definition: diff2d.hxx:989
BasicImage & init(value_type const &pixel)
Definition: basicimage.hxx:1128
int x
Definition: diff2d.hxx:385
const_reference operator[](difference_type const &d) const
Definition: basicimage.hxx:877
PIXELTYPE const & const_reference
Definition: basicimage.hxx:494
BasicImage(difference_type const &size, const_pointer d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:728
column_iterator columnEnd(std::ptrdiff_t x)
Definition: basicimage.hxx:1035
Diff2D operator+(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:739
BasicImage()
Definition: basicimage.hxx:587
Two dimensional difference vector.
Definition: diff2d.hxx:185
void resize(std::ptrdiff_t width, std::ptrdiff_t height, SkipInitializationTag)
Definition: basicimage.hxx:814
int top() const
Definition: diff2d.hxx:981
PIXELTYPE * pointer
Definition: basicimage.hxx:498
traverser::column_iterator column_iterator
Definition: basicimage.hxx:554
PIXELTYPE const * ConstScanOrderIterator
Definition: basicimage.hxx:522
Definition: accessor.hxx:43
std::ptrdiff_t height() const
Definition: basicimage.hxx:845
FFTWComplex< R > & operator-=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
subtract-assignment
Definition: fftw3.hxx:867
BasicImageIterator< PIXELTYPE, PIXELTYPE ** > traverser
Definition: basicimage.hxx:526
Two dimensional size object.
Definition: diff2d.hxx:482
Point2D const & upperLeft() const
Definition: diff2d.hxx:911
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, SkipInitializationTag, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:658
Two dimensional point or position.
Definition: diff2d.hxx:592
BasicImage(const BasicImage &rhs)
Definition: basicimage.hxx:744
Definition: basicimage.hxx:262
column_iterator columnBegin(std::ptrdiff_t x)
Definition: basicimage.hxx:1027
const_row_iterator rowEnd(std::ptrdiff_t y) const
Definition: basicimage.hxx:1020
const_column_iterator columnEnd(std::ptrdiff_t x) const
Definition: basicimage.hxx:1050
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
BasicImageIterator< PIXELTYPE, PIXELTYPE ** > Iterator
Definition: basicimage.hxx:530
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:605
PIXELTYPE const * const_pointer
Definition: basicimage.hxx:502
const_column_iterator columnBegin(std::ptrdiff_t x) const
Definition: basicimage.hxx:1042
void swap(BasicImage &rhs)
Definition: basicimage.hxx:1233
Alloc allocator_type
Definition: basicimage.hxx:580
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
Definition: basicimage.hxx:126
BasicImage(difference_type const &size, value_type const &d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:676
int MoveX
Definition: diff2d.hxx:226
int bottom() const
Definition: diff2d.hxx:997
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy)
Definition: basicimage.hxx:886
const_pointer data() const
Definition: basicimage.hxx:1057
pointer operator[](std::ptrdiff_t dy)
Definition: basicimage.hxx:905
bool isInside(difference_type const &d) const
Definition: basicimage.hxx:859
const_traverser::row_iterator const_row_iterator
Definition: basicimage.hxx:550
PIXELTYPE const * const_iterator
Definition: basicimage.hxx:518
Size2D size_type
Definition: basicimage.hxx:566
IteratorTraits< const_traverser >::DefaultAccessor ConstAccessor
Definition: basicimage.hxx:576
void resize(std::ptrdiff_t width, std::ptrdiff_t height, value_type const &d)
Definition: basicimage.hxx:798
traverser lowerRight()
Definition: basicimage.hxx:934
PIXELTYPE PixelType
Definition: basicimage.hxx:483
ConstBasicImageIterator< PIXELTYPE, PIXELTYPE ** > const_traverser
Definition: basicimage.hxx:536
const_traverser lowerRight() const
Definition: basicimage.hxx:954
BasicImage(difference_type const &size, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:621
Fundamental class template for images.
Definition: basicimage.hxx:473
PIXELTYPE * ScanOrderIterator
Definition: basicimage.hxx:512
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:711
Two dimensional rectangle.
Definition: diff2d.hxx:872
Definition: basicimage.hxx:294
Encapsulate read access to the values an iterator points to.
Definition: accessor.hxx:269
void resize(std::ptrdiff_t width, std::ptrdiff_t height)
Definition: basicimage.hxx:776
void resizeCopy(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer data)
Definition: basicimage.hxx:1191
row_iterator rowBegin(std::ptrdiff_t y)
Definition: basicimage.hxx:999
traverser::row_iterator row_iterator
Definition: basicimage.hxx:546
reference operator[](difference_type const &d)
Definition: basicimage.hxx:868
~BasicImage()
Definition: basicimage.hxx:756
void resizeCopy(const BasicImage &rhs)
Definition: basicimage.hxx:827
Diff2D difference_type
Definition: basicimage.hxx:562
Class for a single RGB value.
Definition: accessor.hxx:938
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:838
BasicImage & operator=(const BasicImage &rhs)
Definition: basicimage.hxx:1093
void resize(difference_type const &size)
Definition: basicimage.hxx:785
BasicImage(Alloc const &alloc)
Definition: basicimage.hxx:595
ConstAccessor accessor() const
Definition: basicimage.hxx:1071
const_traverser upperLeft() const
Definition: basicimage.hxx:943
PIXELTYPE value_type
Definition: basicimage.hxx:479
traverser upperLeft()
Definition: basicimage.hxx:923
Point2D const & lowerRight() const
Definition: diff2d.hxx:919
PIXELTYPE * iterator
Definition: basicimage.hxx:508
const_row_iterator rowBegin(std::ptrdiff_t y) const
Definition: basicimage.hxx:1013

© 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.10.0