vigra - vigra/basicimage.hxx Source File

[ 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 int 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()(int dx, int dy) const
214 {
215 return *(*(y + dy) + x + dx);
216 }
217
218 pointer operator[](int 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(int 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 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> >
473 class BasicImage
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 */
526 typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser;
527
528 /** deprecated, use <TT>traverser</TT> instead
529 */
530 typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator;
531
532 /** the BasicImage's 2D random access const iterator ('const traverser')
533 */
534 typedef
535 ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
536 const_traverser;
537
538 /** deprecated, use <TT>const_traverser</TT> instead
539 */
540 typedef
541 ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
542 ConstIterator;
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 */
554 typedef typename traverser::column_iterator column_iterator;
555
556 /** the const column iterator associated with the const_traverser
557 */
558 typedef typename const_traverser::column_iterator const_column_iterator;
559
560 /** the BasicImage's difference type (argument type of image[diff])
561 */
562 typedef Diff2D difference_type;
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
571 IteratorTraits<traverser>::DefaultAccessor Accessor;
572
573 /** the BasicImage's default const accessor
574 */
575 typedef typename
576 IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor;
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 */
587 BasicImage()
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(int width, int 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(int width, int 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(int width, int 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(int width, int 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 */
756 ~BasicImage()
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(int width, int 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(int width, int 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(int width, int 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(int width, int 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 int width() const
839 {
840 return width_;
841 }
842
843 /** height of Image
844 */
845 int 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()(int dx, int 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()(int dx, int 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[](int 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[](int 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 */
943 const_traverser upperLeft() const
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 */
954 const_traverser lowerRight() const
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(int 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(int 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(int 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(int 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(int 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(int 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(int 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(int 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(int width, int height, value_type const & d, bool skipInit);
1080
1081
1082 value_type ** initLineStartArray(value_type * data, int width, int height);
1083
1084 PIXELTYPE * data_;
1085 PIXELTYPE ** lines_;
1086 int width_, height_;
1087 Alloc allocator_;
1088 LineAllocator pallocator_;
1089 };
1090
1091 template <class PIXELTYPE, class Alloc>
1092 BasicImage<PIXELTYPE, Alloc> &
1093 BasicImage<PIXELTYPE, Alloc>::operator=(const BasicImage & rhs)
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>
1115 BasicImage<PIXELTYPE, Alloc> &
1116 BasicImage<PIXELTYPE, Alloc>::operator=(value_type pixel)
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>
1127 BasicImage<PIXELTYPE, 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(int width, int 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(int width, int height, const_pointer data)
1192 {
1193 int 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
1233 BasicImage<PIXELTYPE, Alloc>::swap( BasicImage & rhs )
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
1246 BasicImage<PIXELTYPE, Alloc>::deallocate()
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, int width, int height)
1263 {
1264 value_type ** lines = pallocator_.allocate(typename Alloc::size_type(height));
1265 for(int 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,
1278 typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
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,
1389 typename BasicImage<PixelType, Alloc>::ConstAccessor>
1390 srcImageRange(BasicImage<PixelType, Alloc> const & img)
1391 {
1392 return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
1393 typename BasicImage<PixelType, Alloc>::const_traverser,
1394 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
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,
1402 typename BasicImage<PixelType, Alloc>::ConstAccessor>
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,
1410 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + roi.upperLeft(),
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,
1417 typename BasicImage<PixelType, Alloc>::ConstAccessor>
1418 srcImage(BasicImage<PixelType, Alloc> const & img)
1419 {
1420 return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1421 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
1422 img.accessor());
1423 }
1424
1425 template <class PixelType, class Alloc>
1426 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1427 typename BasicImage<PixelType, Alloc>::ConstAccessor>
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,
1433 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + ul,
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,
1440 typename BasicImage<PixelType, Alloc>::Accessor>
1441 destImageRange(BasicImage<PixelType, Alloc> & img)
1442 {
1443 return triple<typename BasicImage<PixelType, Alloc>::traverser,
1444 typename BasicImage<PixelType, Alloc>::traverser,
1445 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
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,
1453 typename BasicImage<PixelType, Alloc>::Accessor>
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,
1461 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft() + roi.upperLeft(),
1462 img.upperLeft() + roi.lowerRight(),
1463 img.accessor());
1464 }
1465
1466 template <class PixelType, class Alloc>
1467 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
1468 typename BasicImage<PixelType, Alloc>::Accessor>
1469 destImage(BasicImage<PixelType, Alloc> & img)
1470 {
1471 return pair<typename BasicImage<PixelType, Alloc>::traverser,
1472 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
1473 img.accessor());
1474 }
1475
1476 template <class PixelType, class Alloc>
1477 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
1478 typename BasicImage<PixelType, Alloc>::Accessor>
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,
1484 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft() + ul,
1485 img.accessor());
1486 }
1487
1488 template <class PixelType, class Alloc>
1489 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1490 typename BasicImage<PixelType, Alloc>::ConstAccessor>
1491 maskImage(BasicImage<PixelType, Alloc> const & img)
1492 {
1493 return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
1494 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
1495 img.accessor());
1496 }
1497
1498 template <class PixelType, class Alloc>
1499 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
1500 typename BasicImage<PixelType, Alloc>::ConstAccessor>
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,
1506 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + ul,
1507 img.accessor());
1508 }
1509
1510 } // namespace vigra
1511 #undef VIGRA_ASSERT_INSIDE
1512 #endif // VIGRA_BASICIMAGE_HXX

© 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 (Mon Nov 18 2013)