vigra - vigra/basicimageview.hxx Source File

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