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

basicimage.hxx |

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>
126 class BasicImageIteratorBase
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;
141 typedef IteratorAdaptor<LineBasedColumnIteratorPolicy<IMAGEITERATOR> >
142 column_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
243 BasicImageIteratorBase()
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>
262 class BasicImageIterator
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>
294 class ConstBasicImageIterator
295 : public BasicImageIteratorBase<ConstBasicImageIterator<PIXELTYPE, ITERATOR>,
296 PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR>
297 {
298 public:
299
300 typedef BasicImageIteratorBase<ConstBasicImageIterator,
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 <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> >
475 class BasicImage
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 */
528 typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser;
529
530 /** deprecated, use <TT>traverser</TT> instead
531 */
532 typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator;
533
534 /** the BasicImage's 2D random access const iterator ('const traverser')
535 */
536 typedef
537 ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
538 const_traverser;
539
540 /** deprecated, use <TT>const_traverser</TT> instead
541 */
542 typedef
543 ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
544 ConstIterator;
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 */
556 typedef typename traverser::column_iterator column_iterator;
557
558 /** the const column iterator associated with the const_traverser
559 */
560 typedef typename const_traverser::column_iterator const_column_iterator;
561
562 /** the BasicImage's difference type (argument type of image[diff])
563 */
564 typedef Diff2D difference_type;
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
573 IteratorTraits<traverser>::DefaultAccessor Accessor;
574
575 /** the BasicImage's default const accessor
576 */
577 typedef typename
578 IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor;
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 */
589 BasicImage()
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 */
758 ~BasicImage()
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 */
769 BasicImage & operator=(value_type pixel);
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 */
870 reference operator[](difference_type const & d)
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 */
879 const_reference operator[](difference_type const & d) const
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 */
925 traverser upperLeft()
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 */
936 traverser lowerRight()
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 */
945 const_traverser upperLeft() const
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 */
956 const_traverser lowerRight() const
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 */
965 iterator begin()
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 */
974 iterator end()
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 */
983 const_iterator begin() const
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 */
992 const_iterator end() const
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 */
1059 const_pointer data() const
1060 {
1061 return data_;
1062 }
1063
1064 /** return default accessor
1065 */
1066 Accessor accessor()
1067 {
1068 return Accessor();
1069 }
1070
1071 /** return default const accessor
1072 */
1073 ConstAccessor accessor() const
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> &
1095 BasicImage<PIXELTYPE, Alloc>::operator=(const BasicImage & rhs)
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>
1117 BasicImage<PIXELTYPE, Alloc> &
1118 BasicImage<PIXELTYPE, Alloc>::operator=(value_type pixel)
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>
1129 BasicImage<PIXELTYPE, Alloc> &
1130 BasicImage<PIXELTYPE, Alloc>::init(value_type const & pixel)
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
1235 BasicImage<PIXELTYPE, Alloc>::swap( BasicImage & rhs )
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
1248 BasicImage<PIXELTYPE, Alloc>::deallocate()
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
vigra::BasicImage::end
iterator end()
Definition: basicimage.hxx:974
vigra::BasicImage::begin
iterator begin()
Definition: basicimage.hxx:965
vigra::Diff2D::MoveY
int MoveY
Definition: diff2d.hxx:229
vigra::BasicImage::ConstIterator
ConstBasicImageIterator< PIXELTYPE, PIXELTYPE ** > ConstIterator
Definition: basicimage.hxx:544
vigra::BasicImage::const_column_iterator
const_traverser::column_iterator const_column_iterator
Definition: basicimage.hxx:560
vigra::IteratorTraits
Export associated information for each image iterator.
Definition: iteratortraits.hxx:109
vigra::BasicImage::rowEnd
row_iterator rowEnd(std::ptrdiff_t y)
Definition: basicimage.hxx:1008
vigra::BasicImage::accessor
Accessor accessor()
Definition: basicimage.hxx:1066
vigra::BasicImage::begin
const_iterator begin() const
Definition: basicimage.hxx:983
vigra::BasicImage::end
const_iterator end() const
Definition: basicimage.hxx:992
vigra::BasicImage::reference
PIXELTYPE & reference
Definition: basicimage.hxx:490
vigra::BasicImage::operator()
const_reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy) const
Definition: basicimage.hxx:897
vigra::Diff2D::y
int y
Definition: diff2d.hxx:392
vigra::BasicImage::size
size_type size() const
Definition: basicimage.hxx:854
vigra::BasicImage::BasicImage
BasicImage(difference_type const &size, SkipInitializationTag, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:695
vigra::BasicImage::Accessor
IteratorTraits< traverser >::DefaultAccessor Accessor
Definition: basicimage.hxx:573
vigra::BasicImage::operator[]
const_pointer operator[](std::ptrdiff_t dy) const
Definition: basicimage.hxx:917
vigra::BasicImage::BasicImage
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, value_type const &d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:642
vigra::BasicImage::init
BasicImage & init(value_type const &pixel)
Definition: basicimage.hxx:1130
vigra::Diff2D::x
int x
Definition: diff2d.hxx:385
vigra::BasicImage::operator[]
const_reference operator[](difference_type const &d) const
Definition: basicimage.hxx:879
vigra::BasicImage::const_reference
PIXELTYPE const & const_reference
Definition: basicimage.hxx:496
vigra::BasicImage::BasicImage
BasicImage(difference_type const &size, const_pointer d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:730
vigra::BasicImage::columnEnd
column_iterator columnEnd(std::ptrdiff_t x)
Definition: basicimage.hxx:1037
vigra::BasicImage::BasicImage
BasicImage()
Definition: basicimage.hxx:589
vigra::Diff2D
Two dimensional difference vector.
Definition: diff2d.hxx:185
vigra::BasicImage::resize
void resize(std::ptrdiff_t width, std::ptrdiff_t height, SkipInitializationTag)
Definition: basicimage.hxx:816
vigra::BasicImage::pointer
PIXELTYPE * pointer
Definition: basicimage.hxx:500
vigra::BasicImage::column_iterator
traverser::column_iterator column_iterator
Definition: basicimage.hxx:556
vigra::BasicImage::ConstScanOrderIterator
PIXELTYPE const * ConstScanOrderIterator
Definition: basicimage.hxx:524
vigra::BasicImage::height
std::ptrdiff_t height() const
Definition: basicimage.hxx:847
vigra::BasicImage::traverser
BasicImageIterator< PIXELTYPE, PIXELTYPE ** > traverser
Definition: basicimage.hxx:528
vigra::Size2D
Two dimensional size object.
Definition: diff2d.hxx:482
vigra::BasicImage::BasicImage
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, SkipInitializationTag, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:660
vigra::BasicImage::BasicImage
BasicImage(const BasicImage &rhs)
Definition: basicimage.hxx:746
vigra::BasicImageIterator
Definition: basicimage.hxx:262
vigra::BasicImage::columnBegin
column_iterator columnBegin(std::ptrdiff_t x)
Definition: basicimage.hxx:1029
vigra::BasicImage::rowEnd
const_row_iterator rowEnd(std::ptrdiff_t y) const
Definition: basicimage.hxx:1022
vigra::BasicImage::columnEnd
const_column_iterator columnEnd(std::ptrdiff_t x) const
Definition: basicimage.hxx:1052
vigra::BasicImage::Iterator
BasicImageIterator< PIXELTYPE, PIXELTYPE ** > Iterator
Definition: basicimage.hxx:532
vigra::BasicImage::BasicImage
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:607
vigra::BasicImage::const_pointer
PIXELTYPE const * const_pointer
Definition: basicimage.hxx:504
vigra::BasicImage::columnBegin
const_column_iterator columnBegin(std::ptrdiff_t x) const
Definition: basicimage.hxx:1044
vigra::BasicImage::swap
void swap(BasicImage &rhs)
Definition: basicimage.hxx:1235
vigra::BasicImage::allocator_type
Alloc allocator_type
Definition: basicimage.hxx:582
vigra::BasicImageIteratorBase
Definition: basicimage.hxx:126
vigra::BasicImage::BasicImage
BasicImage(difference_type const &size, value_type const &d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:678
vigra::Diff2D::MoveX
int MoveX
Definition: diff2d.hxx:226
vigra::BasicImage::operator()
reference operator()(std::ptrdiff_t dx, std::ptrdiff_t dy)
Definition: basicimage.hxx:888
vigra::BasicImage::data
const_pointer data() const
Definition: basicimage.hxx:1059
vigra::BasicImage::operator[]
pointer operator[](std::ptrdiff_t dy)
Definition: basicimage.hxx:907
vigra::BasicImage::isInside
bool isInside(difference_type const &d) const
Definition: basicimage.hxx:861
vigra::BasicImage::const_row_iterator
const_traverser::row_iterator const_row_iterator
Definition: basicimage.hxx:552
vigra::BasicImage::const_iterator
PIXELTYPE const * const_iterator
Definition: basicimage.hxx:520
utilities.hxx
vigra::BasicImage::size_type
Size2D size_type
Definition: basicimage.hxx:568
vigra::TinyVector< double, 2 >
vigra::BasicImage::ConstAccessor
IteratorTraits< const_traverser >::DefaultAccessor ConstAccessor
Definition: basicimage.hxx:578
vigra::BasicImage::resize
void resize(std::ptrdiff_t width, std::ptrdiff_t height, value_type const &d)
Definition: basicimage.hxx:800
vigra::BasicImage::lowerRight
traverser lowerRight()
Definition: basicimage.hxx:936
vigra::BasicImage::PixelType
PIXELTYPE PixelType
Definition: basicimage.hxx:485
vigra::BasicImage::const_traverser
ConstBasicImageIterator< PIXELTYPE, PIXELTYPE ** > const_traverser
Definition: basicimage.hxx:538
vigra::BasicImage::lowerRight
const_traverser lowerRight() const
Definition: basicimage.hxx:956
vigra::BasicImage::BasicImage
BasicImage(difference_type const &size, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:623
vigra::BasicImage
Fundamental class template for images.
Definition: basicimage.hxx:475
vigra::BasicImage::ScanOrderIterator
PIXELTYPE * ScanOrderIterator
Definition: basicimage.hxx:514
vigra::BasicImage::BasicImage
BasicImage(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer d, Alloc const &alloc=Alloc())
Definition: basicimage.hxx:713
vigra::ConstBasicImageIterator
Definition: basicimage.hxx:294
vigra::BasicImage::resize
void resize(std::ptrdiff_t width, std::ptrdiff_t height)
Definition: basicimage.hxx:778
vigra::BasicImage::resizeCopy
void resizeCopy(std::ptrdiff_t width, std::ptrdiff_t height, const_pointer data)
Definition: basicimage.hxx:1193
vigra::BasicImage::rowBegin
row_iterator rowBegin(std::ptrdiff_t y)
Definition: basicimage.hxx:1001
vigra::BasicImage::row_iterator
traverser::row_iterator row_iterator
Definition: basicimage.hxx:548
vigra::BasicImage::operator[]
reference operator[](difference_type const &d)
Definition: basicimage.hxx:870
vigra::BasicImage::~BasicImage
~BasicImage()
Definition: basicimage.hxx:758
vigra::BasicImage::resizeCopy
void resizeCopy(const BasicImage &rhs)
Definition: basicimage.hxx:829
vigra::BasicImage::difference_type
Diff2D difference_type
Definition: basicimage.hxx:564
vigra::StandardAccessor
Encapsulate access to the values an iterator points to.
Definition: accessor.hxx:133
vigra::IteratorAdaptor
Quickly create 1-dimensional iterator adapters.
Definition: iteratoradapter.hxx:147
vigra::BasicImage::width
std::ptrdiff_t width() const
Definition: basicimage.hxx:840
vigra::BasicImage::operator=
BasicImage & operator=(const BasicImage &rhs)
Definition: basicimage.hxx:1095
vigra::BasicImage::resize
void resize(difference_type const &size)
Definition: basicimage.hxx:787
vigra::BasicImage::BasicImage
BasicImage(Alloc const &alloc)
Definition: basicimage.hxx:597
vigra::BasicImage::accessor
ConstAccessor accessor() const
Definition: basicimage.hxx:1073
vigra::BasicImage::upperLeft
const_traverser upperLeft() const
Definition: basicimage.hxx:945
vigra::BasicImage::value_type
PIXELTYPE value_type
Definition: basicimage.hxx:481
vigra::BasicImage::upperLeft
traverser upperLeft()
Definition: basicimage.hxx:925
vigra::BasicImage::iterator
PIXELTYPE * iterator
Definition: basicimage.hxx:510
vigra::BasicImage::rowBegin
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)