[ 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 
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  */
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_)
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  */
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_p