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

basicimageview.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_BASICIMAGEVIEW_HXX
37 #define VIGRA_BASICIMAGEVIEW_HXX
38 
39 #include "imageiterator.hxx"
40 #include "initimage.hxx"
41 
42 // Bounds checking Macro used if VIGRA_CHECK_BOUNDS is defined.
43 #ifdef VIGRA_CHECK_BOUNDS
44 #define VIGRA_ASSERT_INSIDE(diff) \
45  vigra_precondition(this->isInside(diff), "Index out of bounds")
46 #else
47 #define VIGRA_ASSERT_INSIDE(diff)
48 #endif
49 
50 
51 namespace vigra {
52 
53 
54 /********************************************************/
55 /* */
56 /* BasicImageView */
57 /* */
58 /********************************************************/
59 
60 /** \brief BasicImage using foreign memory.
61 
62  This class provides the same interface as \ref vigra::BasicImage
63  (with the exception of <tt>resize()</tt>) but the image's
64  memory is provided from the outside instead of allocated internally.
65 
66  A <tt>BasicImageView</tt> can also be created from a
67  \ref vigra::MultiArrayView with the appropriate shape -- see
68  \ref MultiArrayToImage.
69 
70  <b>\#include</b> <<a href="basicimageview_8hxx-source.html">vigra/basicimageview.hxx</a>>
71 
72  Namespace: vigra
73 */
74 template <class PIXELTYPE>
76 {
77  public:
78 
79  /** the BasicImageView's pixel type
80  */
81  typedef PIXELTYPE value_type;
82 
83  /** the BasicImageView's pixel type
84  */
85  typedef PIXELTYPE PixelType;
86 
87  /** the BasicImageView's reference type (i.e. the
88  return type of image[diff] and image(dx,dy))
89  */
90  typedef PIXELTYPE & reference;
91 
92  /** the BasicImageView's const reference type (i.e. the
93  return type of image[diff] and image(dx,dy) when image is const)
94  */
95  typedef PIXELTYPE const & const_reference;
96 
97  /** the BasicImageView's pointer type
98  */
99  typedef PIXELTYPE * pointer;
100 
101  /** the BasicImageView's const pointer type
102  */
103  typedef PIXELTYPE const * const_pointer;
104 
105  /** the BasicImageView's 1D random access iterator
106  (note: lower case 'iterator' is a STL compatible 1D random
107  access iterator, don't confuse with capitalized Iterator)
108  */
109  typedef PIXELTYPE * iterator;
110 
111  /** deprecated, use <TT>iterator</TT> instead
112  */
113  typedef PIXELTYPE * ScanOrderIterator;
114 
115  /** the BasicImageView's 1D random access const iterator
116  (note: lower case 'const_iterator' is a STL compatible 1D
117  random access const iterator)
118  */
119  typedef PIXELTYPE const * const_iterator;
120 
121  /** deprecated, use <TT>const_iterator</TT> instead
122  */
123  typedef PIXELTYPE const * ConstScanOrderIterator;
124 
125  /** the BasicImageView's 2D random access iterator ('traverser')
126  */
128 
129  /** deprecated, use <TT>traverser</TT> instead
130  */
132 
133  /** the BasicImageView's 2D random access const iterator ('const traverser')
134  */
136 
137  /** deprecated, use <TT>const_traverser</TT> instead
138  */
140 
141  /** the row iterator associated with the traverser
142  */
144 
145  /** the const row iterator associated with the const_traverser
146  */
148 
149  /** the column iterator associated with the traverser
150  */
152 
153  /** the const column iterator associated with the const_traverser
154  */
156 
157  /** the BasicImageView's difference type (argument type of image[diff])
158  */
160 
161  /** the BasicImageView's size type (result type of image.size())
162  */
163  typedef Size2D size_type;
164 
165  /** the BasicImageView's default accessor
166  */
167  typedef typename
169 
170  /** the BasicImageView's default const accessor
171  */
172  typedef typename
174 
175  /** construct image of size 0x0
176  */
178  : data_(0),
179  width_(0),
180  height_(0),
181  stride_(0)
182  {}
183 
184  /** construct view of size w x h
185  */
186  BasicImageView(const_pointer data, int w, int h, int stride = 0)
187  : data_(const_cast<pointer>(data)),
188  width_(w),
189  height_(h),
190  stride_(stride == 0 ? w : stride)
191  {}
192 
193  /** construct view of size size.x x size.y
194  */
196  : data_(const_cast<pointer>(data)),
197  width_(size.x),
198  height_(size.y),
199  stride_(stride == 0 ? size.x : stride)
200  {}
201 
202  /** set Image with const value
203  */
204  BasicImageView & init(value_type const & pixel)
205  {
206  initImage(upperLeft(), lowerRight(), accessor(), pixel);
207 
208  return *this;
209  }
210 
211  /** width of Image
212  */
213  int width() const
214  {
215  return width_;
216  }
217 
218  /** height of Image
219  */
220  int height() const
221  {
222  return height_;
223  }
224 
225  /** stride of Image.
226  Memory offset between the start of two successive rows.
227  */
228  int stride() const
229  {
230  return stride_;
231  }
232 
233  /** size of Image
234  */
235  size_type size() const
236  {
237  return size_type(width(), height());
238  }
239 
240  /** test whether a given coordinate is inside the image
241  */
242  bool isInside(difference_type const & d) const
243  {
244  return d.x >= 0 && d.y >= 0 &&
245  d.x < width() && d.y < height();
246  }
247 
248  /** access pixel at given location. <br>
249  usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
250  */
252  {
253  VIGRA_ASSERT_INSIDE(d);
254  return data_[d.y*stride_ + d.x];
255  }
256 
257  /** read pixel at given location. <br>
258  usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
259  */
261  {
262  VIGRA_ASSERT_INSIDE(difference_type(d));
263  return data_[d.y*stride_ + d.x];
264  }
265 
266  /** access pixel at given location. <br>
267  usage: <TT> value_type value = image(1,2) </TT>
268  */
269  reference operator()(int dx, int dy)
270  {
271  VIGRA_ASSERT_INSIDE(difference_type(dx,dy));
272  return data_[dy*stride_ + dx];
273  }
274 
275  /** read pixel at given location. <br>
276  usage: <TT> value_type value = image(1,2) </TT>
277  */
278  const_reference operator()(int dx, int dy) const
279  {
280  VIGRA_ASSERT_INSIDE(difference_type(dx, dy));
281  return data_[dy*stride_ + dx];
282  }
283 
284  /** access pixel at given location.
285  Note that the 'x' index is the trailing index. <br>
286  usage: <TT> value_type value = image[2][1] </TT>
287  */
289  {
290  VIGRA_ASSERT_INSIDE(difference_type(0, dy));
291  return data_ + dy*stride_;
292  }
293 
294  /** read pixel at given location.
295  Note that the 'x' index is the trailing index. <br>
296  usage: <TT> value_type value = image[2][1] </TT>
297  */
298  const_pointer operator[](int dy) const
299  {
300  VIGRA_ASSERT_INSIDE(difference_type(0,dy));
301  return data_ + dy*stride_;
302  }
303 
304  /** init 2D random access iterator poining to upper left pixel
305  */
307  {
308  return traverser(data_, stride_);
309  }
310 
311  /** init 2D random access iterator poining to
312  pixel(width, height), i.e. one pixel right and below lower right
313  corner of the image as is common in C/C++.
314  */
316  {
317  return upperLeft() + size();
318  }
319 
320  /** init 2D random access const iterator poining to upper left pixel
321  */
323  {
324  return const_traverser(data_, stride_);
325  }
326 
327  /** init 2D random access const iterator poining to
328  pixel(width, height), i.e. one pixel right and below lower right
329  corner of the image as is common in C/C++.
330  */
332  {
333  return upperLeft() + size();
334  }
335 
336  /** init 1D random access iterator pointing to first pixel.
337  Note: Only works if stride equals width.
338  */
340  {
341  vigra_precondition(stride_ == width_,
342  "BasicImageView::begin(): "
343  "can only create scan order iterator if width() == stride().");
344  return data_;
345  }
346 
347  /** init 1D random access iterator pointing past the end.
348  Note: Only works if stride equals width.
349  */
351  {
352  vigra_precondition(stride_ == width_,
353  "BasicImageView::end(): "
354  "can only create scan order iterator if width() == stride().");
355  return data_ + width() * height();
356  }
357 
358  /** init 1D random access const iterator pointing to first pixel.
359  Note: Only works if stride equals width.
360  */
362  {
363  vigra_precondition(stride_ == width_,
364  "BasicImageView::begin(): "
365  "can only create scan order iterator if width() == stride().");
366  return data_;
367  }
368 
369  /** init 1D random access const iterator pointing past the end.
370  Note: Only works if stride equals width.
371  */
373  {
374  vigra_precondition(stride_ == width_,
375  "BasicImageView::end(): "
376  "can only create scan order iterator if width() == stride().");
377  return data_ + width() * height();
378  }
379 
380  /** init 1D random access iterator pointing to first pixel of row \a y
381  */
383  {
384  return data_ + stride_ * y;
385  }
386 
387  /** init 1D random access iterator pointing past the end of row \a y
388  */
390  {
391  return rowBegin(y) + width();
392  }
393 
394  /** init 1D random access const iterator pointing to first pixel of row \a y
395  */
397  {
398  return data_ + stride_ * y;
399  }
400 
401  /** init 1D random access const iterator pointing past the end of row \a y
402  */
404  {
405  return rowBegin(y) + width();
406  }
407 
408  /** init 1D random access iterator pointing to first pixel of column \a x
409  */
411  {
412  typedef typename column_iterator::BaseType Iter;
413  return column_iterator(Iter(data_ + x, stride_));
414  }
415 
416  /** init 1D random access iterator pointing past the end of column \a x
417  */
419  {
420  return columnBegin(x) + height();
421  }
422 
423  /** init 1D random access const iterator pointing to first pixel of column \a x
424  */
426  {
427  typedef typename const_column_iterator::BaseType Iter;
428  return const_column_iterator(Iter(data_ + x, stride_));
429  }
430 
431  /** init 1D random access const iterator pointing past the end of column \a x
432  */
434  {
435  return columnBegin(x) + height();
436  }
437 
438  /** get a pointer to the internal data
439  */
441  {
442  return data_;
443  }
444 
445  /** return default accessor
446  */
448  {
449  return Accessor();
450  }
451 
452  /** return default const accessor
453  */
455  {
456  return ConstAccessor();
457  }
458 
459  private:
460 
461  pointer data_;
462  int width_, height_, stride_;
463 };
464 
465 
466 /********************************************************/
467 /* */
468 /* argument object factories */
469 /* */
470 /********************************************************/
471 
472 template <class PixelType, class Accessor>
473 inline triple<typename BasicImageView<PixelType>::const_traverser,
474  typename BasicImageView<PixelType>::const_traverser, Accessor>
475 srcImageRange(BasicImageView<PixelType> const & img, Accessor a)
476 {
477  return triple<typename BasicImageView<PixelType>::const_traverser,
478  typename BasicImageView<PixelType>::const_traverser,
479  Accessor>(img.upperLeft(),
480  img.lowerRight(),
481  a);
482 }
483 
484 template <class PixelType, class Accessor>
485 inline triple<typename BasicImageView<PixelType>::const_traverser,
486  typename BasicImageView<PixelType>::const_traverser, Accessor>
487 srcImageRange(BasicImageView<PixelType> const & img, Rect2D const & roi, Accessor a)
488 {
489  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
490  roi.right() <= img.width() && roi.bottom() <= img.height(),
491  "srcImageRange(): ROI rectangle outside image.");
492  return triple<typename BasicImageView<PixelType>::const_traverser,
493  typename BasicImageView<PixelType>::const_traverser,
494  Accessor>(img.upperLeft() + roi.upperLeft(),
495  img.upperLeft() + roi.lowerRight(),
496  a);
497 }
498 
499 template <class PixelType, class Accessor>
500 inline pair<typename BasicImageView<PixelType>::const_traverser, Accessor>
501 srcImage(BasicImageView<PixelType> const & img, Accessor a)
502 {
503  return pair<typename BasicImageView<PixelType>::const_traverser,
504  Accessor>(img.upperLeft(), a);
505 }
506 
507 template <class PixelType, class Accessor>
508 inline pair<typename BasicImageView<PixelType>::const_traverser, Accessor>
509 srcImage(BasicImageView<PixelType> const & img, Point2D const & ul, Accessor a)
510 {
511  vigra_precondition(img.isInside(ul),
512  "srcImage(): ROI rectangle outside image.");
513  return pair<typename BasicImageView<PixelType>::const_traverser,
514  Accessor>(img.upperLeft() + ul, a);
515 }
516 
517 template <class PixelType, class Accessor>
518 inline triple<typename BasicImageView<PixelType>::traverser,
519  typename BasicImageView<PixelType>::traverser, Accessor>
520 destImageRange(BasicImageView<PixelType> & img, Accessor a)
521 {
522  return triple<typename BasicImageView<PixelType>::traverser,
523  typename BasicImageView<PixelType>::traverser,
524  Accessor>(img.upperLeft(),
525  img.lowerRight(),
526  a);
527 }
528 
529 template <class PixelType, class Accessor>
530 inline triple<typename BasicImageView<PixelType>::traverser,
531  typename BasicImageView<PixelType>::traverser, Accessor>
532 destImageRange(BasicImageView<PixelType> & img, Rect2D const & roi, Accessor a)
533 {
534  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
535  roi.right() <= img.width() && roi.bottom() <= img.height(),
536  "destImageRange(): ROI rectangle outside image.");
537  return triple<typename BasicImageView<PixelType>::traverser,
538  typename BasicImageView<PixelType>::traverser,
539  Accessor>(img.upperLeft() + roi.upperLeft(),
540  img.upperLeft() + roi.lowerRight(),
541  a);
542 }
543 
544 template <class PixelType, class Accessor>
545 inline pair<typename BasicImageView<PixelType>::traverser, Accessor>
546 destImage(BasicImageView<PixelType> & img, Accessor a)
547 {
548  return pair<typename BasicImageView<PixelType>::traverser,
549  Accessor>(img.upperLeft(), a);
550 }
551 
552 template <class PixelType, class Accessor>
553 inline pair<typename BasicImageView<PixelType>::traverser, Accessor>
554 destImage(BasicImageView<PixelType> & img, Point2D const & ul, Accessor a)
555 {
556  vigra_precondition(img.isInside(ul),
557  "destImage(): ROI rectangle outside image.");
558  return pair<typename BasicImageView<PixelType>::traverser,
559  Accessor>(img.upperLeft() + ul, a);
560 }
561 
562 template <class PixelType, class Accessor>
563 inline pair<typename BasicImageView<PixelType>::const_traverser, Accessor>
564 maskImage(BasicImageView<PixelType> const & img, Accessor a)
565 {
566  return pair<typename BasicImageView<PixelType>::const_traverser,
567  Accessor>(img.upperLeft(), a);
568 }
569 
570 template <class PixelType, class Accessor>
571 inline pair<typename BasicImageView<PixelType>::const_traverser, Accessor>
572 maskImage(BasicImageView<PixelType> const & img, Point2D const & ul, Accessor a)
573 {
574  vigra_precondition(img.isInside(ul),
575  "maskImage(): ROI rectangle outside image.");
576  return pair<typename BasicImageView<PixelType>::const_traverser,
577  Accessor>(img.upperLeft() + ul, a);
578 }
579 
580 /****************************************************************/
581 
582 template <class PixelType>
583 inline triple<typename BasicImageView<PixelType>::const_traverser,
584  typename BasicImageView<PixelType>::const_traverser,
585  typename BasicImageView<PixelType>::ConstAccessor>
586 srcImageRange(BasicImageView<PixelType> const & img)
587 {
588  return triple<typename BasicImageView<PixelType>::const_traverser,
589  typename BasicImageView<PixelType>::const_traverser,
590  typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft(),
591  img.lowerRight(),
592  img.accessor());
593 }
594 
595 template <class PixelType>
596 inline triple<typename BasicImageView<PixelType>::const_traverser,
597  typename BasicImageView<PixelType>::const_traverser,
598  typename BasicImageView<PixelType>::ConstAccessor>
599 srcImageRange(BasicImageView<PixelType> const & img, Rect2D const & roi)
600 {
601  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
602  roi.right() <= img.width() && roi.bottom() <= img.height(),
603  "srcImageRange(): ROI rectangle outside image.");
604  return triple<typename BasicImageView<PixelType>::const_traverser,
605  typename BasicImageView<PixelType>::const_traverser,
606  typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft() + roi.upperLeft(),
607  img.upperLeft() + roi.lowerRight(),
608  img.accessor());
609 }
610 
611 template <class PixelType>
612 inline pair< typename BasicImageView<PixelType>::const_traverser,
613  typename BasicImageView<PixelType>::ConstAccessor>
614 srcImage(BasicImageView<PixelType> const & img)
615 {
616  return pair<typename BasicImageView<PixelType>::const_traverser,
617  typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft(),
618  img.accessor());
619 }
620 
621 template <class PixelType>
622 inline pair< typename BasicImageView<PixelType>::const_traverser,
623  typename BasicImageView<PixelType>::ConstAccessor>
624 srcImage(BasicImageView<PixelType> const & img, Point2D const & ul)
625 {
626  vigra_precondition(img.isInside(ul),
627  "srcImage(): ROI rectangle outside image.");
628  return pair<typename BasicImageView<PixelType>::const_traverser,
629  typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft() + ul,
630  img.accessor());
631 }
632 
633 template <class PixelType>
634 inline triple< typename BasicImageView<PixelType>::traverser,
635  typename BasicImageView<PixelType>::traverser,
636  typename BasicImageView<PixelType>::Accessor>
637 destImageRange(BasicImageView<PixelType> & img)
638 {
639  return triple<typename BasicImageView<PixelType>::traverser,
640  typename BasicImageView<PixelType>::traverser,
641  typename BasicImageView<PixelType>::Accessor>(img.upperLeft(),
642  img.lowerRight(),
643  img.accessor());
644 }
645 
646 template <class PixelType>
647 inline triple< typename BasicImageView<PixelType>::traverser,
648  typename BasicImageView<PixelType>::traverser,
649  typename BasicImageView<PixelType>::Accessor>
650 destImageRange(BasicImageView<PixelType> & img, Rect2D const & roi)
651 {
652  vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
653  roi.right() <= img.width() && roi.bottom() <= img.height(),
654  "destImageRange(): ROI rectangle outside image.");
655  return triple<typename BasicImageView<PixelType>::traverser,
656  typename BasicImageView<PixelType>::traverser,
657  typename BasicImageView<PixelType>::Accessor>(img.upperLeft() + roi.upperLeft(),
658  img.upperLeft() + roi.lowerRight(),
659  img.accessor());
660 }
661 
662 template <class PixelType>
663 inline pair< typename BasicImageView<PixelType>::traverser,
664  typename BasicImageView<PixelType>::Accessor>
665 destImage(BasicImageView<PixelType> & img)
666 {
667  return pair<typename BasicImageView<PixelType>::traverser,
668  typename BasicImageView<PixelType>::Accessor>(img.upperLeft(),
669  img.accessor());
670 }
671 
672 template <class PixelType>
673 inline pair< typename BasicImageView<PixelType>::traverser,
674  typename BasicImageView<PixelType>::Accessor>
675 destImage(BasicImageView<PixelType> & img, Point2D const & ul)
676 {
677  vigra_precondition(img.isInside(ul),
678  "destImage(): ROI rectangle outside image.");
679  return pair<typename BasicImageView<PixelType>::traverser,
680  typename BasicImageView<PixelType>::Accessor>(img.upperLeft() + ul,
681  img.accessor());
682 }
683 
684 template <class PixelType>
685 inline pair< typename BasicImageView<PixelType>::const_traverser,
686  typename BasicImageView<PixelType>::ConstAccessor>
687 maskImage(BasicImageView<PixelType> const & img)
688 {
689  return pair<typename BasicImageView<PixelType>::const_traverser,
690  typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft(),
691  img.accessor());
692 }
693 
694 template <class PixelType>
695 inline pair< typename BasicImageView<PixelType>::const_traverser,
696  typename BasicImageView<PixelType>::ConstAccessor>
697 maskImage(BasicImageView<PixelType> const & img, Point2D const & ul)
698 {
699  vigra_precondition(img.isInside(ul),
700  "maskImage(): ROI rectangle outside image.");
701  return pair<typename BasicImageView<PixelType>::const_traverser,
702  typename BasicImageView<PixelType>::ConstAccessor>(img.upperLeft() + ul,
703  img.accessor());
704 }
705 
706 } // namespace vigra
707 #undef VIGRA_ASSERT_INSIDE
708 #endif /* VIGRA_BASICIMAGEVIEW_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.7.1 (Wed Mar 12 2014)