1 #ifndef VIGRA_IMAGEHIERARCHY_HXX
2 #define VIGRA_IMAGEHIERARCHY_HXX
3 
4 #include "vigra/stdimage.hxx"
5 #include "vigra/stdimagefunctions.hxx"
6 #include "vigra/imageiterator.hxx"
7 #include "vigra/accessor.hxx"
8 #include "vigra/utilities.hxx"
9 #include "boost/smart_ptr.hpp"
10 #include "boost/static_assert.hpp"
11 
12 namespace vigra {
13 
14 typedef float GrayValue;
15 
16 /** Stellt ein Pixel dar, also ein Einband, Zweiband, Dreiband oder Vierband Pixel, also je nachdem um was es
17 * fuer ein Pixel handelt, soviele Eintraege enthaelt auch der Vectorproxy, also z.B. ein Vierband-Pixel als
18 * VectorProxy hat vier Eintraege
19 */
20 class ConstVectorProxy
21 {
22   public:
23     typedef GrayValue value_type;
24     typedef GrayValue const * iterator;
25     typedef GrayValue const * const_iterator;
26 
ConstVectorProxy()27     ConstVectorProxy()
28     : data_(0), size_(0)
29     {}
30 
ConstVectorProxy(GrayValue const * data,int size)31     ConstVectorProxy(GrayValue const * data, int size)
32     : data_(const_cast<value_type *>(data)), size_(size)
33     {}
34 
ConstVectorProxy(value_type const & f)35     ConstVectorProxy(value_type const & f)
36     : data_(const_cast<value_type *>(&f)), size_(1)
37     {}
38 
39 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION                                      ////AEND_1////////
40     template <int N>
ConstVectorProxy(TinyVector<value_type,N> const & v)41     ConstVectorProxy(TinyVector<value_type, N> const & v)
42     : data_(const_cast<TinyVector<value_type, N> &>(v).begin()), size_(N)
43     {}
44 #else
ConstVectorProxy(TinyVector<value_type,2> const & v)45     ConstVectorProxy(TinyVector<value_type, 2> const & v)
46     : data_(const_cast<TinyVector<value_type, 2> &>(v).begin()), size_(2)
47     {}
48 
ConstVectorProxy(TinyVector<value_type,3> const & v)49     ConstVectorProxy(TinyVector<value_type, 3> const & v)
50     : data_(const_cast<TinyVector<value_type, 3> &>(v).begin()), size_(3)
51     {}
52 
ConstVectorProxy(TinyVector<value_type,4> const & v)53     ConstVectorProxy(TinyVector<value_type, 4> const & v)
54     : data_(const_cast<TinyVector<value_type, 4> &>(v).begin()), size_(4)
55     {}
56 #endif                                                            //////AEND_1//////////////
57 
reset(ConstVectorProxy const & v)58     void reset(ConstVectorProxy const & v)
59     {
60         data_ = v.data_;
61         size_ = v.size_;
62     }
63 
reset(value_type const & f)64     void reset(value_type const & f)
65     {
66         data_ = const_cast<value_type *>(&f);
67         size_ = 1;
68     }
69 
70 
71 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION                                  /////////////AEND_2//////////
72     template <int N>
reset(TinyVector<value_type,N> const & v)73     void reset(TinyVector<value_type, N> const & v)
74     {
75         data_ = const_cast<TinyVector<value_type, N> &>(v).begin();
76         size_ = N;
77     }
78 #else
reset(TinyVector<value_type,2> const & v)79     void reset(TinyVector<value_type, 2> const & v)
80     {
81         data_ = const_cast<TinyVector<value_type, 2> &>(v).begin();
82         size_ = 2;
83     }
84 
reset(TinyVector<value_type,3> const & v)85     void reset(TinyVector<value_type, 3> const & v)
86     {
87         data_ = const_cast<TinyVector<value_type, 3> &>(v).begin();
88         size_ = 3;
89     }
90 
reset(TinyVector<value_type,4> const & v)91     void reset(TinyVector<value_type, 4> const & v)
92     {
93         data_ = const_cast<TinyVector<value_type, 4> &>(v).begin();
94         size_ = 4;
95     }
96 #endif                                                                      /////////////AEND_2//////////
97 
resize(int new_size)98     void resize(int new_size)
99         { size_ = new_size; }
100 
begin()101     iterator begin()
102         { return data_; }
103 
end()104     iterator end()
105         { return data_ + size_; }
106 
begin() const107     const_iterator begin() const
108         { return data_; }
109 
end() const110     const_iterator end() const
111         { return data_ + size_; }
112 
operator [](int i) const113     value_type const & operator[](int i) const
114         { return data_[i]; }
115 
size() const116     int size() const
117         { return size_; }
118 
operator value_type() const119     operator value_type() const
120     {
121         vigra_precondition(size_ == 1,
122             "ConstVectorProxy::operator value_type(): vector must have size 1.");
123         return *data_;
124     }
125 
126 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION                          ///////////AEND_3///////////
127     template <int N>
operator TinyVector<value_type,N>() const128     operator TinyVector<value_type, N>() const
129     {
130         vigra_precondition(size_ == N,
131             "ConstVectorProxy::operator TinyVector(): size mismatch.");
132         TinyVector<value_type, N> res;
133         res.init(begin(), end());
134         return res;
135     }
136 #else
operator TinyVector<value_type,2>() const137     operator TinyVector<value_type, 2>() const
138     {
139         vigra_precondition(size_ == 2,
140             "ConstVectorProxy::operator TinyVector(): size mismatch.");
141         TinyVector<value_type, 2> res;
142         res.init(begin(), end());
143         return res;
144     }
operator TinyVector<value_type,3>() const145     operator TinyVector<value_type, 3>() const
146     {
147         vigra_precondition(size_ == 3,
148             "ConstVectorProxy::operator TinyVector(): size mismatch.");
149         TinyVector<value_type, 3> res;
150         res.init(begin(), end());
151         return res;
152     }
operator TinyVector<value_type,4>() const153     operator TinyVector<value_type, 4>() const
154     {
155         vigra_precondition(size_ == 4,
156             "ConstVectorProxy::operator TinyVector(): size mismatch.");
157         TinyVector<value_type, 4> res;
158         res.init(begin(), end());
159         return res;
160     }
161 #endif                                                             ///////////AEND_3///////////
162 
operator RGBValue<value_type>() const163     operator RGBValue<value_type>() const
164     {
165         vigra_precondition(size_ == 3,
166             "ConstVectorProxy::operator RGBValue(): size mismatch.");
167         return RGBValue<value_type>(begin(), end());
168     }
169 
operator ==(ConstVectorProxy const & o) const170     bool operator==(ConstVectorProxy const & o) const
171     {
172         if(size() != o.size())
173             return false;
174         for(int i=0; i<size(); ++i)
175             if ((*this)[i] != o[i])
176                 return false;
177         return true;
178     }
179 
operator !=(ConstVectorProxy const & o) const180     bool operator!=(ConstVectorProxy const & o) const
181     {
182         return !(*this == o);
183     }
184 
185   protected:
186 
187     ConstVectorProxy & operator=(ConstVectorProxy const & v);
188 
189     ConstVectorProxy & operator=(value_type const & f);
190 
191     template <int N>
192     ConstVectorProxy & operator=(TinyVector<value_type, N> const & v);
193 
194     value_type * data_;
195     int size_;
196 };
197 
198 /** Stellt ein Pixel dar, also ein Einband, Zweiband, Dreiband oder Vierband Pixel, also je nachdem um was es
199 * fuer ein Pixel handelt, soviele Eintraege enthaelt auch der Vectorproxy, also z.B. ein Vierband-Pixel als
200 * VectorProxy hat vier Eintraege
201 */
202 class VectorProxy
203 : public ConstVectorProxy
204 {
205   public:
206 
207     typedef GrayValue * iterator;
208     typedef GrayValue const * const_iterator;
209 
VectorProxy()210     VectorProxy()
211     {}
212 
VectorProxy(GrayValue const * data,int size)213     VectorProxy(GrayValue const * data, int size)
214     : ConstVectorProxy(data, size)
215     {}
216 
VectorProxy(value_type const & f)217     VectorProxy(value_type const & f)
218     : ConstVectorProxy(f)
219     {}
220 
221 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION                                      ////AEND_1////////
222     template <int N>
VectorProxy(TinyVector<value_type,N> const & v)223     VectorProxy(TinyVector<value_type, N> const & v)
224     : ConstVectorProxy(v)
225     {}
226 #else
VectorProxy(TinyVector<value_type,2> const & v)227     VectorProxy(TinyVector<value_type, 2> const & v)
228     : ConstVectorProxy(v)
229     {}
230 
VectorProxy(TinyVector<value_type,3> const & v)231     VectorProxy(TinyVector<value_type, 3> const & v)
232     : ConstVectorProxy(v)
233     {}
234 
VectorProxy(TinyVector<value_type,4> const & v)235     VectorProxy(TinyVector<value_type, 4> const & v)
236     : ConstVectorProxy(v)
237     {}
238 #endif                                                                          //////AEND_1//////////////
239 
240 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION                            /////////AEND_4////////////
241     template <int N>
operator =(TinyVector<value_type,N> const & v)242     VectorProxy & operator=(TinyVector<value_type, N> const & v)
243     {
244         vigra_precondition(size_ == N,
245            "VectorProxy::operator=(): size mismatch.");
246         for(int i=0; i<N; ++i)
247             data_[i] = v[i];
248         return *this;
249     }
250 #else
operator =(TinyVector<value_type,2> const & v)251     VectorProxy & operator=(TinyVector<value_type, 2> const & v)
252     {
253         vigra_precondition(size_ == 2,
254            "VectorProxy::operator=(): size mismatch.");
255         for(int i=0; i<2; ++i)
256             data_[i] = v[i];
257         return *this;
258     }
259 
operator =(TinyVector<value_type,3> const & v)260     VectorProxy & operator=(TinyVector<value_type, 3> const & v)
261     {
262         vigra_precondition(size_ == 3,
263            "VectorProxy::operator=(): size mismatch.");
264         for(int i=0; i<3; ++i)
265             data_[i] = v[i];
266         return *this;
267     }
268 
operator =(TinyVector<value_type,4> const & v)269     VectorProxy & operator=(TinyVector<value_type, 4> const & v)
270     {
271         vigra_precondition(size_ == 4,
272            "VectorProxy::operator=(): size mismatch.");
273         for(int i=0; i<4; ++i)
274             data_[i] = v[i];
275         return *this;
276     }
277 
278 #endif                                                              /////////AEND_4////////////
279 
operator =(value_type const & v)280     VectorProxy & operator=(value_type const & v)
281     {
282         vigra_precondition(size_ == 1,
283            "VectorProxy::operator=(): size mismatch.");
284         data_[0] = v;
285         return *this;
286     }
287 
operator =(VectorProxy const & v)288     VectorProxy & operator=(VectorProxy const & v)
289     {
290         vigra_precondition(size_ == v.size(),
291            "VectorProxy::operator=(): size mismatch.");
292         for(int i=0; i<size_; ++i)
293             data_[i] = v[i];
294         return *this;
295     }
296 
operator =(ConstVectorProxy const & v)297     VectorProxy & operator=(ConstVectorProxy const & v)
298     {
299         vigra_precondition(size_ == v.size(),
300            "VectorProxy::operator=(): size mismatch.");
301         for(int i=0; i<size_; ++i)
302             data_[i] = v[i];
303         return *this;
304     }
305 
begin()306     iterator begin()
307         { return data_; }
308 
end()309     iterator end()
310         { return data_ + size_; }
311 
begin() const312     const_iterator begin() const
313         { return data_; }
314 
end() const315     const_iterator end() const
316         { return data_ + size_; }
317 
operator [](int i)318     value_type & operator[](int i)
319         { return data_[i]; }
320 
operator [](int i) const321     value_type const & operator[](int i) const
322         { return data_[i]; }
323 
324 };
325 
326 template <int N>
operator ==(TinyVector<GrayValue,N> const & l,ConstVectorProxy const & r)327 inline bool operator==(TinyVector<GrayValue, N> const & l, ConstVectorProxy const & r)
328 {
329     return r == l;
330 }
331 
332 template <class IMAGEITERATOR>
333 class MultibandRowColumnIteratorPolicy
334 {
335   public:
336     typedef IMAGEITERATOR                            ImageIterator;
337     typedef typename ImageIterator::value_type       value_type;
338     typedef int                                      difference_type;
339     typedef typename ImageIterator::reference        reference;
340     typedef typename ImageIterator::index_reference  index_reference;
341     typedef typename ImageIterator::pointer          pointer;
342     typedef std::random_access_iterator_tag          iterator_category;
343 
344 
345     struct BaseType
346     {
BaseTypevigra::MultibandRowColumnIteratorPolicy::BaseType347         explicit BaseType(pointer c = 0, difference_type o = 0, difference_type s = 0)
348         : current_(c), offset_(o), size_(s)
349         {}
350 
351         pointer current_;
352         difference_type offset_, size_;
353     };
354 
initialize(BaseType & d)355     static void initialize(BaseType & d) {}
356 
dereference(BaseType const & d)357     static reference dereference(BaseType const & d)
358         { return reference(d.current_, d.size_); }
359 
dereference(BaseType const & d,difference_type n)360     static index_reference dereference(BaseType const & d, difference_type n)
361     {
362         return index_reference(d.current_+n*d.offset_, d.size_);
363     }
364 
equal(BaseType const & d1,BaseType const & d2)365     static bool equal(BaseType const & d1, BaseType const & d2)
366         { return d1.current_ == d2.current_; }
367 
less(BaseType const & d1,BaseType const & d2)368     static bool less(BaseType const & d1, BaseType const & d2)
369         { return d1.current_ < d2.current_; }
370 
difference(BaseType const & d1,BaseType const & d2)371     static difference_type difference(BaseType const & d1, BaseType const & d2)
372         { return (d1.current_ - d2.current_) / d1.offset_; }
373 
increment(BaseType & d)374     static void increment(BaseType & d)
375         { d.current_ += d.offset_; }
376 
decrement(BaseType & d)377     static void decrement(BaseType & d)
378         { d.current_ -= d.offset_; }
379 
advance(BaseType & d,difference_type n)380     static void advance(BaseType & d, difference_type n)
381         { d.current_ += d.offset_*n; }
382 };
383 
384 template <class PIXELTYPE, class ITERATOR>
385 class VariableBandsIteratorBase
386 {
387   protected:
388 
389     PIXELTYPE * data_;
390     int width_, bands_, size_;
391 
VariableBandsIteratorBase(PIXELTYPE * data,int width,int bands,int size)392     VariableBandsIteratorBase(PIXELTYPE * data, int width, int bands, int size)
393     : data_(data), width_(width), bands_(bands), size_(size), x(0), y(0)
394     {}
395 
VariableBandsIteratorBase()396     VariableBandsIteratorBase()
397     : data_(0), width_(0), bands_(0), size_(0), x(0), y(0)
398     {}
399 
get()400     PIXELTYPE * get()
401         { return data_ + ((y * width_) + x)*bands_; }
402 
get() const403     PIXELTYPE const * get() const
404         { return data_ + ((y * width_) + x)*bands_; }
405 
get(int const & dx,int const & dy)406     PIXELTYPE * get(int const & dx, int const & dy)
407         { return data_ + ((dy + y) * width_ + dx + x)*bands_; }
408 
get(int const & dx,int const & dy) const409     PIXELTYPE const * get(int const & dx, int const & dy) const
410         { return data_ + ((dy + y) * width_ + dx + x)*bands_; }
411 
412   public:
413 
414     typedef int MoveX;
415     typedef int MoveY;
416 
417     int x, y;                                    //////////////////////Hier sind die x und y des VariableBandsIterator
418 
operator ==(VariableBandsIteratorBase const & rhs) const419     bool operator==(VariableBandsIteratorBase const & rhs) const
420     {
421         return (x == rhs.x) && (y == rhs.y);
422     }
423 
operator !=(VariableBandsIteratorBase const & rhs) const424     bool operator!=(VariableBandsIteratorBase const & rhs) const
425     {
426         return (x != rhs.x) || (y != rhs.y);
427     }
428 
operator -(VariableBandsIteratorBase const & rhs) const429     Diff2D operator-(VariableBandsIteratorBase const & rhs) const
430     {
431         return Diff2D(x - rhs.x, y - rhs.y);
432     }
433 
operator +=(Diff2D const & s)434     ITERATOR & operator+=(Diff2D const & s)
435     {
436         x += s.x;
437         y += s.y;
438         return (ITERATOR &)*this;
439     }
440 
operator -=(Diff2D const & s)441     ITERATOR & operator-=(Diff2D const & s)
442     {
443         x -= s.x;
444         y -= s.y;
445         return (ITERATOR &)*this;
446     }
447 };
448 
449 /** 2D Iterator ueber ein VariableBandsImage
450 */
451 struct VariableBandsIterator
452 : public VariableBandsIteratorBase<GrayValue, VariableBandsIterator>
453 {
454   public:
455 
456     typedef VectorProxy          value_type;
457     typedef VectorProxy          PixelType;
458     typedef VectorProxy          reference;
459     typedef VectorProxy          index_reference;
460     typedef GrayValue *          pointer;
461     typedef Diff2D               difference_type;
462     typedef image_traverser_tag  iterator_category;
463     typedef IteratorAdaptor<MultibandRowColumnIteratorPolicy<VariableBandsIterator> >
464         row_iterator;
465     typedef IteratorAdaptor<MultibandRowColumnIteratorPolicy<VariableBandsIterator> >
466         column_iterator;
467 
468 
VariableBandsIteratorvigra::VariableBandsIterator469     VariableBandsIterator(GrayValue * data, int width, int bands, int size)
470     : VariableBandsIteratorBase<GrayValue, VariableBandsIterator>(data, width, bands, size)
471     {}
472 
VariableBandsIteratorvigra::VariableBandsIterator473     VariableBandsIterator()
474     {}
475 
operator +vigra::VariableBandsIterator476     VariableBandsIterator operator+(Diff2D const & s)
477     {
478         VariableBandsIterator res(*this);
479         res += s;
480         return res;
481     }
482 
operator -vigra::VariableBandsIterator483     VariableBandsIterator operator-(Diff2D const & s)          //////////////////////////////hier die minus-Funktion
484     {
485         VariableBandsIterator res(*this);
486         res -= s;
487         return res;
488     }
489 
operator ->vigra::VariableBandsIterator490     pointer operator->() const
491     {
492         return const_cast<pointer>(get());
493     }
494 
operator *vigra::VariableBandsIterator495     reference operator*() const
496     {
497         return reference(get(), size_);
498     }
499 
operator []vigra::VariableBandsIterator500     index_reference operator[](Diff2D const & dist) const
501     {
502         return index_reference(get(dist.x, dist.y), size_);
503     }
504 
operator []vigra::VariableBandsIterator505     row_iterator operator[](int dy) const
506     {
507         return row_iterator(
508             row_iterator::BaseType(const_cast<pointer>(get(0, dy)), bands_, size_));
509     }
510 
operator ()vigra::VariableBandsIterator511     index_reference operator()(int const & dx, int const & dy) const
512     {
513         return index_reference(get(dx, dy), size_);
514     }
515 
rowIteratorvigra::VariableBandsIterator516     row_iterator rowIterator() const
517     {
518         return row_iterator(
519             row_iterator::BaseType(const_cast<pointer>(get()), bands_, size_));
520     }
521 
columnIteratorvigra::VariableBandsIterator522     column_iterator columnIterator() const
523     {
524         return column_iterator(
525             column_iterator::BaseType(const_cast<pointer>(get()), width_*bands_, size_));
526     }
527 };
528 
529 /** 2D Iterator ueber ein VariableBandsImage
530 */
531 struct ConstVariableBandsIterator
532 : public VariableBandsIteratorBase<GrayValue, ConstVariableBandsIterator>
533 {
534   public:
535 
536     typedef ConstVectorProxy          value_type;
537     typedef ConstVectorProxy          PixelType;
538     typedef ConstVectorProxy          reference;
539     typedef ConstVectorProxy          index_reference;
540     typedef GrayValue const *         pointer;
541     typedef Diff2D               difference_type;
542     typedef image_traverser_tag  iterator_category;
543     typedef IteratorAdaptor<MultibandRowColumnIteratorPolicy<ConstVariableBandsIterator> >
544         row_iterator;
545     typedef IteratorAdaptor<MultibandRowColumnIteratorPolicy<ConstVariableBandsIterator> >
546         column_iterator;
547 
ConstVariableBandsIteratorvigra::ConstVariableBandsIterator548     ConstVariableBandsIterator(GrayValue const * data, int width, int bands, int size)
549     : VariableBandsIteratorBase<GrayValue, ConstVariableBandsIterator>(
550         const_cast<GrayValue *>(data), width, bands, size)
551     {}
552 
ConstVariableBandsIteratorvigra::ConstVariableBandsIterator553     ConstVariableBandsIterator()
554     {}
555 
operator +vigra::ConstVariableBandsIterator556     ConstVariableBandsIterator operator+(Diff2D const & s)
557     {
558         ConstVariableBandsIterator res(*this);
559         res += s;
560         return res;
561     }
562 
operator -vigra::ConstVariableBandsIterator563     ConstVariableBandsIterator operator-(Diff2D const & s)
564     {
565         ConstVariableBandsIterator res(*this);
566         res -= s;
567         return res;
568     }
569 
operator ->vigra::ConstVariableBandsIterator570     pointer operator->() const
571     {
572         return get();
573     }
574 
operator *vigra::ConstVariableBandsIterator575     reference operator*() const
576     {
577         return reference(get(), size_);
578     }
579 
operator []vigra::ConstVariableBandsIterator580     index_reference operator[](Diff2D const & dist) const
581     {
582         return index_reference(get(dist.x, dist.y), size_);
583     }
584 
operator []vigra::ConstVariableBandsIterator585     row_iterator operator[](int dy) const
586     {
587         return row_iterator(row_iterator::BaseType(get(0, dy), bands_, size_));
588     }
589 
operator ()vigra::ConstVariableBandsIterator590     index_reference operator()(int const & dx, int const & dy) const
591     {
592         return index_reference(get(dx, dy), size_);
593     }
594 
rowIteratorvigra::ConstVariableBandsIterator595     row_iterator rowIterator() const
596     {
597         return row_iterator(row_iterator::BaseType(get(), bands_, size_));
598     }
599 
columnIteratorvigra::ConstVariableBandsIterator600     column_iterator columnIterator() const
601     {
602         return column_iterator(column_iterator::BaseType(get(), width_*bands_, size_));
603     }
604 };
605 
606 /** Policyklasse des ScanOrderIterators, sie implementiert die Besonderheiten des Durchlaufs ueber eine 2D - Sequenz ,
607 * wobei die Besonderheiten letzendlich auf Durchlauf einer 1D - Sequenz zurueckgefuehrt werden. ScanOrderIteratorPolicy
608 * ist dazu da um spaeter (z.B. in VariableBandsImage) als Templateparameter an den "Interface" IteratorAdaptor
609 * uebergeben zu werden und dann durch  typedef IteratorAdaptor<ScanOrderIteratorPolicy<VariableBandsIterator>> ScanOrderIterator
610 * den gewoehnte ScanOrderIterator zu sehen bekommen!!! (IteratorAdapter ist die stellt die Schnittstelle zu Verfuegung
611 * um Mehrdimensionale Sequenzen als eine 1D-Sequenz zu behandeln).
612 */
613 template <class ImageIterator>
614 class ScanOrderIteratorPolicy
615 {
616 public:
617 
618 /** Hilfsstruktur, stellt den zugrundeliegenden BaseType zur Verfuegung, speichert in sich den Anfang und das
619 * Ende einer 2D-Sequenz (Matrix), die width Membervariable speichert die Anzahl der Elemente, die zum Anfang der
620 * der Initialisation(Konstruieren eines ROI-Objektes) da waren, also die Spaltenzahl(RegionOfInteress) wird zu
621 * Erzeugungszeit festgelegt
622 */
623 struct ROI
624 {
ROIvigra::ScanOrderIteratorPolicy::ROI625     ROI(ImageIterator ul, ImageIterator lr)
626     : current(ul), lowerRight(lr), width(lr.x-ul.x)  // initialisiert den Zeiger current zunaechst mit der linken oberen Ecke, den lowerRight entsprechend mit lowerRight Ecke
627     {}
628 
ROIvigra::ScanOrderIteratorPolicy::ROI629     ROI()
630     : width(0) // die Zeiger werden auf null gesetzt => VORSICHT NULLPOINTER !!! die Matrix ist leer => keine Spalten => width = 0
631     {}
632 
633     ImageIterator current, lowerRight;                                           //der "Anfangsiterator" wird current genannt weil ueber ihn wird entschieden die aktuelle Position des Iterators daher nach ist der Name upperLeft nicht zutreffend, lowerRight bezeichnet wie gewoent das Ende der Sequenz, die in diesem Fall, der Matrix entspricht daher auch der Name
634     int width;                                                                   // speichert Anzahl der Spalten in der Matrix
635 };
636 
637      typedef ROI                                         BaseType;
638      typedef typename ImageIterator::value_type          value_type;        // the adpator's value type
639      typedef typename ImageIterator::reference           reference;         // the adpator's reference type (result of '*iter')
640      typedef typename ImageIterator::index_reference     index_reference;   // the adpator's index_reference type (result of 'iter[n]')
641      typedef typename ImageIterator::pointer             pointer;           // the adpator's pointer type (result of 'iter.operator->()')
642      typedef std::random_access_iterator_tag             iterator_category; // the adpator's iterator category
643      typedef int                                         difference_type;   // the adpator's difference type (result of 'iter1 - iter2', argument of 'iter[
644 
initialize(BaseType & d)645      static void initialize(BaseType & d) {}
646 
647      /** Liefert den aktuell referenzierten Objekt.
648      */
dereference(ROI const & r)649      static reference dereference(ROI const & r)
650      {
651          return *r.current;
652      }
653 
654      /** Verschiebt seine aktuelle Position um n Schritte und liefert dann den aktuell referenzierten Objekt.
655      */
dereference(ROI r,difference_type n)656      static index_reference dereference(ROI r, difference_type n)
657      {
658          advance(r,n);
659          return *r.current;
660      }
661 
662      /** Haben zwei BaseType, die gleiche aktuelle Zeigerposition so sind sie aequivalent
663      */
equal(ROI const & l,ROI const & r)664      static bool equal(ROI const & l, ROI const & r)
665      {
666          return l.current == r.current;
667      }
668 
669      /** Ist der d1 < d2, d.h. in der Matrix d1 steht hoeher als d2 oder stehen sie in der gleichen Zeile
670      * und d1 befindet sich links von d2, so wird true zurueckgeliefert
671      */
less(BaseType const & d1,BaseType const & d2)672      static bool less(BaseType const & d1, BaseType const & d2)
673      {
674          return d1.current.y == d2.current.y ?
675                      d1.current.x < d2.current.x :
676                      d1.current.y < d2.current.y;
677      }
678 
679      /** Liefert die Anzahl der Schritte der einer BaseType (d1) braucht um seine aktuelle Position
680      * auf die des anderen (d2) zu veraendern. Dabei ist die Anordnungsposition von d1 und d2 egal, also
681      * es kann auch ein negativer Wert zurueckgeliefert werden.
682      */
difference(BaseType const & d1,BaseType const & d2)683      static difference_type difference(BaseType const & d1, BaseType const & d2)
684      {
685          return d1.current.x - d2.current.x + d1.width*(d1.current.y - d2.current.y);
686      }
687 
688      /** Inkrementiert die aktuelle Position des ScanOrderIterators, unter Beruecksichtigung
689      * des Falles, dass aktuelle Position am rechten Rande der Matrix ist
690      */
increment(ROI & r)691      static void increment(ROI & r)
692      {
693          ++r.current.x;
694          if(r.current.x == r.lowerRight.x)
695          {
696              r.current.x -= r.width;
697              ++r.current.y;
698          }
699      }
700 
701      /** Dekrementiert die aktuelle Position des ScanOrderIterators, unter Beruecksichtigung
702      * des Falles, dass aktuelle Position am linken Rande der Matrix ist
703      */
decrement(ROI & r)704      static void decrement(ROI & r)
705      {
706          --r.current.x;
707          if(r.current.x + r.width == r.lowerRight.x)
708          {
709              r.current.x += r.width;
710              --r.current.y;
711          }
712      }
713 
714      /** verschiebt den Iterator um n Stellen wobei n kann durchaus neagtiv
715      * sein, das entspricht dan der Verschiebung nach links.
716      * Precondition : r und n muessen gueltige Werte besitzen, insbesondere soll geachtet werden, dass
717      * n <= width*"height" ist !!!
718      */
advance(ROI & r,difference_type n)719      static void advance(ROI & r, difference_type n) //n kann aber Diff2D sein; sollte es nicht int sein
720      {
721          if(n>0)                                        //ist n positiv so wird so wird die aktuelle Zeigerposition nach "rechts" verschoben
722          {
723              difference_type dy = (n) / r.width;        // dabei ist dy der Wert um den der Zeiger "in einer Matrix" nach unten verschoben werden soll
724              difference_type dx = (n) % r.width;        // entsprechend ist dx um den der Zeiger nach rechts verschoben werden soll, wobei dx kann ueber die MAtrix hinausragen
725              if(dx >= r.lowerRight.x - r.current.x)     // laeuft dx ueber die "Matrix" hinaus so werden dx und dy korrigiert
726              {
727                  ++dy;                                  // der y-Wert wird einfach erhoeht
728                  dx -= r.width;                       // und es wird dann um Anzahl der Zeilenelemente nach LINKS (zurueck) gelaufen
729              }
730              r.current.x += dx;                         // jetzt enthalten dx und dy korrekte Werte bezueglich denen kann die
731              r.current.y += dy;                         // aktuelle Zeigerposition verschoben werden
732          }
733          else if(n < 0)                                 // ist n negativ so wird die aktuelle Zeigerposition nach "links" verschoben
734          {
735              n = -n;                                    // laesst sich mit positiver Zahl leichter rechnen
736              difference_type dy = n / r.width;          // dabei ist dy der Wert um den der Zeiger "in einer Matrix" nach "oben" verschoben werden soll
737              difference_type dx = n % r.width;          // entsprechend ist dx um den der Zeiger nach "links" verschoben werden soll, wobei dx kann ueber die Matrix hinausragen
738 
739              if((r.current.x - r.lowerRight.x) + r.width < dx)// laeuft dx ueber die Kante (r.lowerRight.x - width)(entspricht der upperLeft.x in der Matrix)
740              {
741                                                         // dx und dy beduerfen die Korrektur weil es durchaus sein kann dass dx < width ist, aber es kann nicht so viele Schritte nach links gegangen werden
742                     ++dy;                               // so werden die Differenzen um die die aktuelle Position veraendert werden soll korrigiert
743                     dx -= r.width;
744              }
745              r.current.x -= dx;                         // jetzt enthalten dx und dy korrekte Werte bezueglich denen kann die
746              r.current.y -= dy;                         // aktuelle Zeigerposition verschoben werden
747 
748          }
749 
750      }
751 };// end of ScanOrderIteratorPolicy
752 
753 
754 template <class T>
755 struct BandsForPixelType;
756 
757 template <>
758 struct BandsForPixelType<GrayValue>
759     { static const int bands = 1; };
760 
761 template <>
762 struct BandsForPixelType<RGBValue<GrayValue> >
763     { static const int bands = 3; };
764 
765 template <>
766 struct BandsForPixelType<TinyVector<GrayValue, 2> >
767     { static const int bands = 2; };
768 
769 template <>
770 struct BandsForPixelType<TinyVector<GrayValue, 3> >
771     { static const int bands = 3; };
772 
773 template <>
774 struct BandsForPixelType<TinyVector<GrayValue, 4> >
775     { static const int bands = 4; };
776 
777 /** VaribleBandsImage stellt die Basis fuer die ganze Imagehierarchie, alle anderen ImageKlassen erben von ihr.
778 * Also, SingleBandImage, GrayImage, FixedBansImage usw. sind von VariableBandsImage abgeleitet.
779 */
780 class VariableBandsImage
781 {
782 
783   public:
784     typedef VectorProxy                                                             value_type;
785     typedef VectorProxy                                                             PixelType;
786     typedef ConstVectorProxy                                                        ConstPixelType;
787     typedef VectorProxy                                                             reference;
788     typedef ConstVectorProxy                                                        const_reference;
789     typedef GrayValue *                                                             pointer;
790     typedef GrayValue const *                                                       const_pointer;
791     typedef IteratorAdaptor<ScanOrderIteratorPolicy<VariableBandsIterator> >        iterator;
792     typedef IteratorAdaptor<ScanOrderIteratorPolicy<VariableBandsIterator> >        ScanOrderIterator;
793     typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstVariableBandsIterator> >   const_iterator;
794     typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstVariableBandsIterator> >   ConstScanOrderIterator;
795     typedef VariableBandsIterator                                                   traverser;
796     typedef VariableBandsIterator                                                   Iterator;
797     typedef ConstVariableBandsIterator                                              const_traverser;
798     typedef ConstVariableBandsIterator                                              ConstIterator;
799     typedef Diff2D                                                                  difference_type;
800     typedef Diff2D                                                                  size_type;
801     typedef StandardValueAccessor<PixelType>                                        Accessor;
802     typedef StandardConstValueAccessor<ConstPixelType>                              ConstAccessor;
803     typedef VariableBandsImage                                                      CloneType;
804 
~VariableBandsImage()805     virtual ~VariableBandsImage() {}
806 
807     /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
808     *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
809     *   mit der Groesse und Pixelinitialisierung der ROI
810     */
811     virtual CloneType * clone() const = 0;
812 
813     /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer
814     *   auf das aufrufende Objekt zurueckgeliefert.
815     *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
816     *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
817     *   dabei ist an der shallowCopy genau so die ROI gesetzt.
818     */
819     virtual VariableBandsImage * shallowCopy() const = 0;
820 
821     /** Liefert die Breite der ROI !!! Nicht des Bildes
822     */
width() const823     int width() const
824         { return roiLR_.x - roiUL_.x; }
825 
826     /** Liefert die Hoehe der ROI !!! Nicht des Bildes
827     */
height() const828     int height() const
829         { return roiLR_.y - roiUL_.y; }
830 
831     /** Liefert die Groesse der ROI !!! Nicht des Bildes
832     */
size() const833     Diff2D size() const
834         { return roiLR_ - roiUL_; }
835 
836     /** Liefert die Groesse des Bildes !!! Nicht der ROI
837     */
actualSize() const838     Diff2D actualSize() const
839         { return actualLR_; }
840 
841     /** Liefert die Breite des Bildes !!! Nicht der ROI
842     */
actualWidth() const843     int actualWidth() const
844         { return actualSize().x; }
845 
846     /** Liefert die Hoehe des Bildes !!! Nicht der ROI
847     */
actualHeight() const848     int actualHeight() const
849         { return actualSize().y; }
850 
851     /** Liefert Anzahl der Baender eines Pixels des Bildes !!! Es unterscheidet
852     * sich von bands nur fuer SelectBandImage, sonst ist immer actualBands_ == bands_
853     * erfuelt.
854     */
actualBands() const855     int actualBands() const
856         { return actualBands_; }
857 
858     /** Liefert Anzahl der Baender eines Pixels der ROI !!! Es unterscheidet
859     * sich von actualBands nur fuer SelectBandImage, sonst ist immer actualBands_ == bands_
860     * erfuelt. Fuer SelectBandImage ist bands_ gleich 1, da die ROI auf ein
861     * Band gesetzt ist.
862     */
bands() const863     int bands() const
864         { return bands_; }
865 
866     /** Liefert die linke obere Ecke der ROI.
867     */
roiUpperLeft() const868     Diff2D roiUpperLeft() const
869         { return roiUL_; }
870 
871     /** Liefert den 1D-iterator auf linke obere Ecke der ROI
872     */
begin()873     ScanOrderIterator begin()
874     {
875         return ScanOrderIterator(ScanOrderIteratorPolicy<Iterator>::ROI(upperLeft(), lowerRight()));
876     }
877 
878     /** Liefert den 1D-iterator hinter der rechten unteren Ecke der ROI
879     */
end()880     ScanOrderIterator end()
881     {
882         return begin() + width()*height();
883     }
884 
885     /** Liefert den ConstIterator auf linke obere Ecke der ROI
886     */
begin() const887     ConstScanOrderIterator begin() const
888     {
889         return ConstScanOrderIterator(ScanOrderIteratorPolicy<ConstIterator>::ROI(upperLeft(), lowerRight()));
890     }
891 
892     /** Liefert den ConstIterator hinter der rechten unteren Ecke der ROI
893     */
end() const894     ConstScanOrderIterator end() const
895     {
896         return begin() + width()*height();
897     }
898 
899     /** fuellt das komplette Image mit einem Pixel aus, also hinterher haben alle Pixel die gleiche "Farbe",
900     * die hier uebergeben wurde
901     */
init(ConstPixelType const & pixel)902     VariableBandsImage & init(ConstPixelType const & pixel)
903     {
904         initImage(upperLeft(), lowerRight(), accessor(), pixel);
905 
906         return *this;
907     }
908 
909     /** Setzt die ROI (Region of interess) auf dem aufrufendem Bild
910     */
setROI(Diff2D const & ul,Diff2D const & new_size)911     virtual void setROI(Diff2D const & ul, Diff2D const & new_size)             // setROI -methode mit Argumenten Diff2D upperLeft und Diff2D size
912     {
913         Diff2D new_ul = roiUL_ + ul;
914         Diff2D new_lr;
915         new_lr.x = new_size.x > 0 ?
916                         new_ul.x + new_size.x :
917                         roiLR_.x + new_size.x;
918         new_lr.y = new_size.y > 0 ?
919                         new_ul.y + new_size.y :
920                         roiLR_.y + new_size.y;
921 
922         vigra_precondition(new_ul.x >= 0 && new_ul.x < actualWidth() &&
923                            new_ul.y >= 0 && new_ul.y < actualHeight(),
924             "Image::setROI(): new upper left outside of image.");
925         vigra_precondition(new_lr.x > 0 && new_lr.x <= actualWidth() &&
926                            new_lr.y > 0 && new_lr.y <= actualHeight(),
927             "Image::setROI(): new lower right outside of image.");
928         vigra_precondition(new_ul.x < new_lr.x,
929             "Image::setROI(): upper left isn't to the left of lower right.");
930         vigra_precondition(new_ul.y < new_lr.y,
931             "Image::setROI(): upper left isn't above lower right.");
932 
933         roiUL_ = new_ul;
934         roiLR_ = new_lr;
935     }
936 
937     /** hebt die ROI wieder auf.
938     */
resetROI()939     virtual void resetROI()
940     {
941         roiUL_ = Diff2D(0,0);
942         roiLR_ = actualLR_;
943     }
944 
945     /** Stellt den gewohnten Operatrot
946     */
operator [](Diff2D const & c)947     PixelType operator[](Diff2D const & c)
948         { return PixelType(get(c.x, c.y), bands_); }
949 
operator ()(int x,int y)950     PixelType operator()(int x, int y)
951         { return PixelType(get(x,y), bands_); }
952 
operator [](Diff2D const & c) const953     ConstPixelType operator[](Diff2D const & c) const
954         { return ConstPixelType(get(c.x, c.y), bands_); }
955 
operator ()(int x,int y) const956     ConstPixelType operator()(int x, int y) const
957         { return ConstPixelType(get(x,y), bands_); }
958 
operator [](int dy)959     ScanOrderIterator operator[](int dy)
960         { return begin()+dy*width(); }
961 
operator [](int dy) const962     ConstScanOrderIterator operator[](int dy) const
963         { return begin()+dy*width(); }
964 
upperLeft()965     Iterator upperLeft()
966         { return Iterator(get(0,0), actualWidth(), actualBands_, bands_); }
967 
lowerRight()968     Iterator lowerRight()
969         { return upperLeft() + size(); }
970 
upperLeft() const971     ConstIterator upperLeft() const
972         { return ConstIterator(get(0,0), actualWidth(), actualBands_, bands_); }
973 
lowerRight() const974     ConstIterator lowerRight() const
975         { return upperLeft() + size(); }
976 
accessor()977     Accessor accessor()
978         { return Accessor(); }
979 
accessor() const980     ConstAccessor accessor() const
981         { return ConstAccessor(); }
982 
983     /** Gibt an ob es ein Punkt mit Koordinaten (Diff2D) innerhalb des ganzen Bildes existiert
984     */
isInside(Diff2D const & d) const985     bool isInside(Diff2D const & d) const
986     {
987         return d.x >= 0 && d.y >= 0 &&
988                d.x < actualWidth() && d.y < actualHeight();
989     }
990     /** Gibt an ob es ein Punkt mit Koordinaten (Diff2D) innerhalb der ROI existiert
991     */
isInsideROI(Diff2D const & d) const992     bool isInsideROI(Diff2D const & d) const
993     {
994         return d.x >= roiUL_.x  && d.y >= roiUL_.y &&
995                d.x < roiLR_.x && d.y < roiLR_.y;
996     }
997 
998   protected:
VariableBandsImage()999     VariableBandsImage()
1000     : data_(0)
1001     {}
1002 
VariableBandsImage(VariableBandsImage const & s)1003     VariableBandsImage(VariableBandsImage const & s)
1004     : roiUL_(s.roiUL_), roiLR_(s.roiLR_), actualLR_(s.actualLR_),
1005       bands_(s.bands_), actualBands_(s.actualBands_),
1006       data_(s.data_)
1007     {}
1008 
operator =(VariableBandsImage const & s)1009     VariableBandsImage & operator=(VariableBandsImage const & s)
1010     {
1011         roiUL_ = s.roiUL_;
1012         roiLR_ = s.roiLR_;
1013         actualLR_ = s.actualLR_;
1014         bands_ = s.bands_;
1015         actualBands_ = s.actualBands_;
1016         data_ = s.data_;
1017         return *this;
1018     }
1019 
1020     /** Initialisiert die Membervariablen des Images
1021     */
initAdministrationData(GrayValue * data,Diff2D const & actualLR,int actualBands)1022     void initAdministrationData(GrayValue * data, Diff2D const & actualLR, int actualBands)
1023     {
1024         initAdministrationData(data, actualLR, actualBands, actualBands);
1025     }
1026 
1027     /** Initialisiert die Membervariablen des Images
1028     */
initAdministrationData(GrayValue * data,Diff2D const & actualLR,int actualBands,int bands)1029     void initAdministrationData(GrayValue * data, Diff2D const & actualLR, int actualBands, int bands)
1030     {
1031         roiUL_ = Diff2D(0,0);
1032         roiLR_ = actualLR;
1033         actualLR_ = actualLR;
1034         bands_ = bands;
1035         actualBands_ = actualBands;
1036         data_ = data;
1037     }
1038 
1039     /** Liefert den Zeiger auf GrayValue
1040     */
getDataPtr(GrayValue * p)1041     static GrayValue * getDataPtr(GrayValue * p)
1042         { return p; }
1043 
1044     /** Liefert den Zeiger auf GrayValue,
1045     */
1046     template <class T>
getDataPtr(T * p)1047     static GrayValue * getDataPtr(T * p)
1048     {
1049         BOOST_STATIC_ASSERT( sizeof(T) ==
1050                BandsForPixelType<T>::bands*sizeof(GrayValue) );
1051         return &(*p)[0];
1052     }
1053 
1054     /** Liefert Zeiger auf GrayValue (float) zu einem bestimmten Punkt im Bilde
1055     */
get(int dx,int dy)1056     GrayValue * get(int dx, int dy)
1057         { return data_ + ((roiUL_.y + dy) * actualWidth() + roiUL_.x + dx)*actualBands_; }
1058 
1059     /** Liefert ConstZeiger auf GrayValue (float) zu einem bestimmten Punkt im Bilde
1060     */
get(int dx,int dy) const1061     GrayValue const * get(int dx, int dy) const
1062         { return data_ + ((roiUL_.y + dy) * actualWidth() + roiUL_.x + dx)*actualBands_; }
1063 
1064     Diff2D roiUL_, roiLR_, actualLR_;// roiUL_ - ist der Abstand von der linken oberen Ecke des Images bis zur linken oberen Ecke von ROI
1065     int bands_, actualBands_;
1066     GrayValue * data_;// GrayValue ist float
1067 };
1068 
1069 class SelectBandImage;
1070 
1071 template <class IMAGE, class ACCESSOR = typename IMAGE::Accessor>
1072 class FixedBandsImage
1073 : public VariableBandsImage
1074 {
1075   public:
1076 
1077     typedef IMAGE                                                   InnerImage;
1078     typedef typename ACCESSOR::value_type                           value_type;
1079     typedef value_type                                              PixelType;
1080     typedef value_type                                              ConstPixelType;
1081     typedef value_type &                                            reference;
1082     typedef value_type const &                                      const_reference;
1083     typedef value_type *                                            pointer;
1084     typedef value_type const *                                      const_pointer;
1085     typedef typename IMAGE::Iterator                                traverser;
1086     typedef typename IMAGE::Iterator                                Iterator;           //2D Iterator !!! Soll deprecated werden, wurde in traverser umbenannt
1087     typedef typename InnerImage::ConstIterator                           const_traverser;
1088     typedef typename InnerImage::ConstIterator                           ConstIterator;      //2D ConstIterator !!! Soll deprecated werden, wurde in const_traverser umbenannt
1089     typedef IteratorAdaptor<ScanOrderIteratorPolicy<Iterator> >     ScanOrderIterator;
1090     typedef ScanOrderIterator                                       iterator;           //1D Iterator entspricht den ScanOrderIterator
1091     typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstIterator> > ConstScanOrderIterator;
1092     typedef ConstScanOrderIterator                                  const_iterator;     //1D ConstIterator entspricht den ConstScanOrderIterator
1093     typedef Diff2D                                                  difference_type;
1094     typedef Diff2D                                                  size_type;
1095     typedef ACCESSOR                                                Accessor;
1096     typedef ACCESSOR                                                ConstAccessor;
1097 
1098 #ifndef NO_COVARIANT_RETURN_TYPES                                              ///////////////AEND_6///////////
1099     typedef FixedBandsImage CloneType;
1100 #else
1101     typedef VariableBandsImage CloneType;
1102 #endif                                                                      ///////////////AEND_6///////////
1103 
1104     friend class SelectBandImage;
1105     /**  DefaultKonstruktor
1106     */
FixedBandsImage()1107     FixedBandsImage()
1108     : VariableBandsImage(),
1109       image_(new InnerImage(0,0))
1110     {
1111         initAdministrationData(getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
1112     }
1113 
FixedBandsImage(int w,int h)1114     FixedBandsImage(int w, int h)
1115     : VariableBandsImage(),
1116       image_(new InnerImage(w,h))
1117     {
1118         initAdministrationData(getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
1119     }
1120 
1121     /** Konstruktor, erzeugt ein FixedBandsImage mit width, height, und Pixel_value
1122     */
FixedBandsImage(int w,int h,PixelType pixel_value)1123     FixedBandsImage(int w, int h, PixelType pixel_value)
1124     : VariableBandsImage(),
1125       image_(new InnerImage(w,h, pixel_value))
1126     {
1127         initAdministrationData(getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
1128     }
1129 
FixedBandsImage(Diff2D const & s)1130     FixedBandsImage(Diff2D const & s)
1131     : VariableBandsImage(),
1132       image_(new InnerImage(s))
1133     {
1134         initAdministrationData(getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
1135     }
1136 
FixedBandsImage(FixedBandsImage const & s)1137     FixedBandsImage(FixedBandsImage const & s)
1138     : VariableBandsImage(s),
1139       image_(s.image_)
1140     {}
1141 
FixedBandsImage(InnerImage * i)1142     FixedBandsImage(InnerImage * i)
1143     : VariableBandsImage(),
1144       image_(i)
1145     {
1146         initAdministrationData(getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
1147     }
1148 
operator =(FixedBandsImage const & s)1149     FixedBandsImage & operator=(FixedBandsImage const & s)
1150     {
1151         if(this != &s)
1152         {
1153             image_ = s.image_;
1154             VariableBandsImage::operator=(s);
1155         }
1156         return *this;
1157     }
1158 
1159     /** Destructor ist leer, weil es wird nur shared_ptr image_, als Klassenvariable angelegt und shared_ptr verwaltet
1160     * selber Referenzen und gibt den Speicherplatz frei
1161     */
~FixedBandsImage()1162     virtual ~FixedBandsImage()
1163         {}
1164 
1165     /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
1166     *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
1167     *   mit der Groesse und Pixelinitialisierung der ROI
1168     */
clone() const1169     virtual CloneType * clone() const
1170     {
1171         InnerImage * newimg = new InnerImage(size());
1172         copyImage(srcIterRange(upperLeft(), lowerRight()), destImage(*newimg));
1173         return new FixedBandsImage(newimg);
1174     }
1175 
1176     /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer
1177     *   auf das aufrufende Objekt zurueckgeliefert.
1178     *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
1179     *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
1180     *   dabei ist an der shallowCopy genau so die ROI gesetzt.
1181     */
shallowCopy() const1182     virtual FixedBandsImage * shallowCopy() const
1183     {
1184         return new FixedBandsImage(*this);
1185     }
1186 
operator [](Diff2D const & c)1187     PixelType & operator[](Diff2D const & c)
1188         { return image_->operator[](c+roiUL_); }
1189 
operator [](Diff2D const & c) const1190     PixelType const & operator[](Diff2D const & c) const
1191         { return image_->operator[](c+roiUL_); }
1192 
operator ()(int x,int y)1193     PixelType & operator()(int x, int y)
1194         { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
1195 
operator ()(int x,int y) const1196     PixelType const & operator()(int x, int y) const
1197         { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
1198 
operator [](int c)1199     PixelType * operator[](int c)
1200         { return image_->operator[](c+roiUL_.y) + roiUL_.x; }
1201 
operator [](int c) const1202     PixelType  const * operator[](int c) const
1203         { return image_->operator[](c+roiUL_.y) + roiUL_.x; }
1204 
upperLeft()1205     Iterator upperLeft()
1206         { return image_->upperLeft()+roiUL_; }
1207 
lowerRight()1208     Iterator lowerRight()
1209         { return upperLeft()+size(); }
1210 
upperLeft() const1211     ConstIterator upperLeft() const
1212         { return image_->upperLeft()+roiUL_; }
1213 
lowerRight() const1214     ConstIterator lowerRight() const
1215         { return upperLeft()+size(); }
1216 
begin()1217     iterator begin()
1218         { return ScanOrderIterator(ScanOrderIteratorPolicy<Iterator>::ROI(upperLeft(), lowerRight())); }
1219 
end()1220     iterator end()
1221         { return begin() + width()*height(); }
1222 
begin() const1223     const_iterator begin() const
1224         { return ConstScanOrderIterator(ScanOrderIteratorPolicy<ConstIterator>::ROI(upperLeft(), lowerRight())); }
1225 
end() const1226     const_iterator end() const
1227         { return begin() + width()*height(); }
1228 
accessor()1229     Accessor accessor()
1230         { return Accessor(); }
1231 
accessor() const1232     ConstAccessor accessor() const
1233         { return ConstAccessor(); }
1234 
1235   protected:
1236     boost::shared_ptr<InnerImage> image_;                                   // shared_ptr verwaltet selber Referenzen und gibt den Speicherplatz frei
1237 
1238 };
1239 
1240 template <class IMAGE>
1241 class FixedRGBImage : public FixedBandsImage<IMAGE, VectorAccessor<TinyVector<GrayValue, 3> > >
1242 {
1243   public:
1244 
1245     typedef
1246         FixedBandsImage<IMAGE, VectorAccessor<TinyVector<GrayValue, 3> > >  BaseType;
1247 
1248     typedef IMAGE                                                           InnerImage;
1249     typedef typename IMAGE::value_type                                      value_type;
1250     typedef value_type                                                      PixelType;
1251     typedef value_type                                                      ConstPixelType;
1252     typedef value_type &                                                    reference;
1253     typedef value_type const &                                              const_reference;
1254     typedef value_type *                                                    pointer;
1255     typedef value_type const *                                              const_pointer;
1256     typedef typename IMAGE::Iterator                                        traverser;
1257     typedef typename IMAGE::Iterator                                        Iterator;           //2D Iterator !!! Soll deprecated werden, wurde in traverser umbenannt
1258     typedef typename IMAGE::ConstIterator                                   const_traverser;
1259     typedef typename IMAGE::ConstIterator                                   ConstIterator;      //2D ConstIterator !!! Soll deprecated werden, wurde in const_traverser umbenannt
1260     typedef IteratorAdaptor<ScanOrderIteratorPolicy<Iterator> >             ScanOrderIterator;
1261     typedef ScanOrderIterator                                               iterator;           //1D Iterator entspricht den ScanOrderIterator
1262     typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstIterator> >        ConstScanOrderIterator;
1263     typedef ConstScanOrderIterator                                          const_iterator;     //1D ConstIterator entspricht den ConstScanOrderIterator
1264 
1265     typedef Diff2D                                                          difference_type;
1266     typedef Diff2D                                                          size_type;
1267     typedef typename IMAGE::Accessor                                        Accessor;
1268     typedef typename IMAGE::ConstAccessor                                   ConstAccessor;
1269 #ifndef NO_COVARIANT_RETURN_TYPES                                               ///////////////AEND_7////////////
1270     typedef FixedRGBImage CloneType;
1271 #else
1272     typedef typename BaseType::CloneType CloneType;
1273 #endif                                                                       ///////////////AEND_7////////////
1274     friend class SelectBandImage;
1275 
FixedRGBImage()1276     FixedRGBImage()
1277     {}
1278 
FixedRGBImage(int w,int h)1279     FixedRGBImage(int w, int h)
1280     : BaseType(w, h)
1281     {}
1282 
FixedRGBImage(int w,int h,PixelType pix_type)1283     FixedRGBImage(int w, int h, PixelType pix_type)
1284     : BaseType(w, h, pix_type)
1285     {}
1286 
FixedRGBImage(Diff2D const & s)1287     FixedRGBImage(Diff2D const & s)
1288     : BaseType(s)
1289     {}
1290 
FixedRGBImage(FixedRGBImage const & s)1291     FixedRGBImage(FixedRGBImage const & s)
1292     : BaseType(s)
1293     {}
1294 
FixedRGBImage(InnerImage * i)1295     FixedRGBImage(InnerImage * i)
1296     : BaseType(i)
1297     {}
1298 
operator =(FixedRGBImage const & s)1299     FixedRGBImage & operator=(FixedRGBImage const & s)
1300     {
1301         BaseType::operator=(s);
1302         return *this;
1303     }
1304 
1305     /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
1306     *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
1307     *   mit der Groesse und Pixelinitialisierung der ROI
1308     */
clone() const1309     virtual CloneType * clone() const
1310     {
1311         InnerImage * newimg = new InnerImage(size());
1312         copyImage(srcIterRange(upperLeft(), lowerRight()), destImage(*newimg));
1313         return new FixedRGBImage(newimg);
1314     }
1315 
1316     /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer
1317     *   auf das aufrufende Objekt zurueckgeliefert.
1318     *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
1319     *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
1320     *   dabei ist an der shallowCopy genau so die ROI gesetzt.
1321     */
shallowCopy() const1322     virtual FixedRGBImage * shallowCopy() const
1323     {
1324         return new FixedRGBImage(*this);
1325     }
1326 
operator [](Diff2D const & c)1327     PixelType & operator[](Diff2D const & c)
1328         { return image_->operator[](c+roiUL_); }
1329 
operator [](Diff2D const & c) const1330     PixelType const & operator[](Diff2D const & c) const
1331         { return image_->operator[](c+roiUL_); }
1332 
operator ()(int x,int y)1333     PixelType & operator()(int x, int y)
1334         { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
1335 
operator ()(int x,int y) const1336     PixelType const & operator()(int x, int y) const
1337         { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
1338 
operator [](int c)1339     PixelType * operator[](int c)
1340         { return image_->operator[](c+roiUL_.y) + roiUL_.x; }
1341 
operator [](int c) const1342     PixelType  const * operator[](int c) const
1343         { return image_->operator[](c+roiUL_.y) + roiUL_.x; }
1344 
upperLeft()1345     Iterator upperLeft()
1346         { return image_->upperLeft()+roiUL_; }
1347 
lowerRight()1348     Iterator lowerRight()
1349         { return upperLeft()+size(); }
1350 
upperLeft() const1351     ConstIterator upperLeft() const
1352         { return image_->upperLeft()+roiUL_; }
1353 
lowerRight() const1354     ConstIterator lowerRight() const
1355         { return upperLeft()+size(); }
1356 
begin()1357     iterator begin()
1358         { return ScanOrderIterator(ScanOrderIteratorPolicy<Iterator>::ROI(upperLeft(), lowerRight())); }
1359 
end()1360     iterator end()
1361         { return begin() + width()*height(); }
1362 
begin() const1363     const_iterator begin() const
1364         { return ConstScanOrderIterator(ScanOrderIteratorPolicy<ConstIterator>::ROI(upperLeft(), lowerRight())); }
1365 
end() const1366     const_iterator end() const
1367         { return begin() + width()*height(); }
1368 
accessor()1369     Accessor accessor()
1370         { return Accessor(); }
1371 
accessor() const1372     ConstAccessor accessor() const
1373         {return ConstAccessor(); }
1374 
1375 
1376 };
1377 
1378 typedef FixedBandsImage<BasicImage<TinyVector<GrayValue, 2> > > Vector2Image;
1379 typedef FixedRGBImage<BasicImage<RGBValue<GrayValue> > > RGBImage;
1380 typedef RGBImage::BaseType Vector3Image;
1381 typedef FixedBandsImage<BasicImage<TinyVector<GrayValue, 4> > > Vector4Image;
1382 
1383 template <class PIXELTYPE>
1384 class ConstSelectBandIterator
1385 : public VariableBandsIteratorBase<PIXELTYPE, ConstSelectBandIterator<PIXELTYPE> >
1386 {
1387   public:
1388 
1389     typedef PIXELTYPE          value_type;
1390     typedef PIXELTYPE          PixelType;
1391     typedef PIXELTYPE const &  reference;
1392     typedef PIXELTYPE const &  index_reference;
1393     typedef PIXELTYPE const *  pointer;
1394     typedef Diff2D             difference_type;
1395     typedef image_traverser_tag  iterator_category;
1396     typedef IteratorAdaptor<ContigousMemoryColumnIteratorPolicy<ConstSelectBandIterator> >
1397         row_iterator;
1398     typedef IteratorAdaptor<ContigousMemoryColumnIteratorPolicy<ConstSelectBandIterator> >
1399         column_iterator;
1400 
ConstSelectBandIterator(PIXELTYPE const * data,int width,int bands)1401     ConstSelectBandIterator(PIXELTYPE const * data, int width, int bands)
1402     : VariableBandsIteratorBase<PIXELTYPE, ConstSelectBandIterator>(
1403         const_cast<PIXELTYPE *>(data), width, bands, 1)
1404     {}
1405 
ConstSelectBandIterator()1406     ConstSelectBandIterator()
1407     {}
1408 
operator +(Diff2D const & s)1409     ConstSelectBandIterator operator+(Diff2D const & s)
1410     {
1411         ConstSelectBandIterator res(*this);
1412         res += s;
1413         return res;
1414     }
1415 
operator -(Diff2D const & s)1416     ConstSelectBandIterator operator-(Diff2D const & s)
1417     {
1418         ConstSelectBandIterator res(*this);
1419         res -= s;
1420         return res;
1421     }
1422 
operator ->() const1423     pointer operator->() const
1424     {
1425         return get();
1426     }
1427 
operator *() const1428     reference operator*() const
1429     {
1430         return *get();
1431     }
1432 
operator [](Diff2D const & dist) const1433     index_reference operator[](Diff2D const & dist) const
1434     {
1435         return *get(dist.x, dist.y);
1436     }
1437 
operator [](int dy) const1438     row_iterator operator[](int dy) const
1439     {
1440         typedef typename row_iterator::BaseType BaseType;
1441         return row_iterator(BaseType(const_cast<pointer>(get(0, dy)), bands_));   //  braeuchte man hier nicht die Auswahl von bands?
1442     }
1443 
operator ()(int const & dx,int const & dy) const1444     index_reference operator()(int const & dx, int const & dy) const
1445     {
1446         return *get(dx, dy);
1447     }
1448 
rowIterator() const1449     row_iterator rowIterator() const
1450     {
1451         typedef typename row_iterator::BaseType BaseType;
1452         return row_iterator(BaseType(get(), bands_));
1453     }
1454 
columnIterator() const1455     column_iterator columnIterator() const
1456     {
1457         typedef typename column_iterator::BaseType BaseType;
1458         return column_iterator(BaseType(get(), width_*bands_));
1459     }
1460 };
1461 
1462 template <class PIXELTYPE>
1463 class SelectBandIterator
1464 : public VariableBandsIteratorBase<PIXELTYPE, SelectBandIterator<PIXELTYPE> >
1465 {
1466   public:
1467 
1468     typedef PIXELTYPE          value_type;
1469     typedef PIXELTYPE          PixelType;
1470     typedef PIXELTYPE &        reference;
1471     typedef PIXELTYPE &        index_reference;
1472     typedef PIXELTYPE *        pointer;
1473     typedef Diff2D             difference_type;
1474     typedef image_traverser_tag  iterator_category;
1475     typedef IteratorAdaptor<ContigousMemoryColumnIteratorPolicy<SelectBandIterator> >
1476         row_iterator;
1477     typedef IteratorAdaptor<ContigousMemoryColumnIteratorPolicy<SelectBandIterator> >
1478         column_iterator;
1479 
SelectBandIterator(PIXELTYPE * data,int width,int bands)1480     SelectBandIterator(PIXELTYPE * data, int width, int bands)
1481     : VariableBandsIteratorBase<PIXELTYPE, SelectBandIterator>(data, width, bands, 1)
1482     {}
1483 
SelectBandIterator()1484     SelectBandIterator()
1485     {}
1486 
operator +(Diff2D const & s)1487     SelectBandIterator operator+(Diff2D const & s)
1488     {
1489         SelectBandIterator res(*this);
1490         res += s;
1491         return res;
1492     }
1493 
operator -(Diff2D const & s)1494     SelectBandIterator operator-(Diff2D const & s)
1495     {
1496         SelectBandIterator res(*this);
1497         res -= s;
1498         return res;
1499     }
1500 
operator ->() const1501     pointer operator->() const
1502     {
1503         return const_cast<pointer>(get());
1504     }
1505 
operator *() const1506     reference operator*() const
1507     {
1508         return const_cast<reference>(*get());
1509     }
1510 
operator [](Diff2D const & dist) const1511     index_reference operator[](Diff2D const & dist) const
1512     {
1513         return const_cast<index_reference>(*get(dist.x, dist.y));
1514     }
1515 
operator [](int dy) const1516     row_iterator operator[](int dy) const
1517     {
1518         typedef typename row_iterator::BaseType BaseType;
1519         return row_iterator(BaseType(const_cast<pointer>(get(0, dy)), bands_));
1520     }
1521 
operator ()(int const & dx,int const & dy) const1522     index_reference operator()(int const & dx, int const & dy) const
1523     {
1524         return const_cast<index_reference>(*get(dx, dy));
1525     }
1526 
rowIterator() const1527     row_iterator rowIterator() const
1528     {
1529         typedef typename row_iterator::BaseType BaseType;
1530         return (row_iterator(BaseType(const_cast<pointer>(get()), bands_)));
1531     }
1532 
columnIterator() const1533     column_iterator columnIterator() const
1534     {
1535         typedef typename column_iterator::BaseType BaseType;
1536         return (column_iterator(BaseType(const_cast<pointer>(get()), width_*bands_)));
1537     }
1538 };
1539 
1540 class SingleBandImage
1541 : public VariableBandsImage
1542 {
1543   public:
1544 
1545     typedef GrayValue                                           value_type;         //entsricht float
1546     typedef value_type                                          PixelType;          // -||- float
1547     typedef value_type                                          ConstPixelType;     // -||- float
1548     typedef value_type &                                        reference;          // -||- float const &
1549     typedef value_type const &                                  const_reference;    // -||- float &
1550     typedef value_type *                                        pointer;            // -||- float *
1551     typedef value_type const *                                  const_pointer;      // -||- float const *
1552     typedef SelectBandIterator<PixelType>                       traverser;          //"normaler" 2D Iterator
1553     typedef SelectBandIterator<PixelType>                       Iterator;           //2D Iterator !!! Soll deprecated werden, wurde in traverser umbenannt
1554     typedef ConstSelectBandIterator<PixelType>                  const_traverser;    //"normaler" 2D ConstIterator
1555     typedef ConstSelectBandIterator<PixelType>                  ConstIterator;      //2D ConstIterator !!! Soll deprecated werden, wurde in const_traverser umbenannt
1556     typedef IteratorAdaptor<ScanOrderIteratorPolicy<Iterator> > ScanOrderIterator;  // entspricht dem iterator, also gewoehnlicher 1D Iterator
1557     typedef ScanOrderIterator                                   iterator;           //1D Iterator entspricht den ScanOrderIterator
1558     typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstIterator> > ConstScanOrderIterator;
1559     typedef ConstScanOrderIterator                              const_iterator;     //1D ConstIterator entspricht den ConstScanOrderIterator
1560     typedef Diff2D                                              difference_type;
1561     typedef Diff2D                                              size_type;
1562     typedef StandardAccessor<PixelType>                         Accessor;
1563     typedef StandardConstAccessor<ConstPixelType>               ConstAccessor;
1564 #ifndef NO_COVARIANT_RETURN_TYPES                                                                         ////////AEND_8///////
1565     typedef SingleBandImage CloneType;
1566 #endif                                                                                                  ////////AEND_8///////
~SingleBandImage()1567     virtual ~SingleBandImage()
1568         {}
1569 
1570     /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
1571     *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
1572     *   mit der Groesse und Pixelinitialisierung der ROI
1573     */
1574     virtual CloneType * clone() const = 0;                                          // dadurch wird gekennzeichent, dass die Funktion "virtual CloneType * clone() const" in der abgeleiteten Klasse implementiert werden soll, das gleiche wie eine abstrakte Funktion
1575 
1576     /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer
1577     *   auf das aufrufende Objekt zurueckgeliefert.
1578     *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
1579     *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
1580     *   dabei ist an der shallowCopy genau so die ROI gesetzt.
1581     */
1582     virtual SingleBandImage * shallowCopy() const = 0;                              // --//-- "virtual SingleBandImage * shallowCopy() const" --//--
1583 
operator [](Diff2D const & c)1584     PixelType & operator[](Diff2D const & c)
1585         { return *get(c.x, c.y); }
1586 
operator [](Diff2D const & c) const1587     PixelType const & operator[](Diff2D const & c) const
1588         { return *get(c.x, c.y); }
1589  ////////////////////////////////////////////////
1590 
1591 
operator [](int dy)1592     ScanOrderIterator operator[](int dy)
1593         { return begin()+dy*width(); }
1594 
operator [](int dy) const1595     ConstScanOrderIterator operator[](int dy) const
1596         { return begin()+dy*width(); }
1597 
1598 ////////////////////////////////////////////////
1599 
operator ()(int x,int y)1600     PixelType & operator()(int x, int y)
1601         { return *get(x, y); }
1602 
operator ()(int x,int y) const1603     PixelType const & operator()(int x, int y) const
1604         { return *get(x, y); }
1605 
upperLeft()1606     Iterator upperLeft()
1607         { return Iterator(get(0,0), actualWidth(), actualBands_); }
1608 
lowerRight()1609     Iterator lowerRight()
1610         { return upperLeft()+size(); }
1611 
upperLeft() const1612     ConstIterator upperLeft() const
1613         { return ConstIterator(get(0,0), actualWidth(), actualBands_); }
1614 
lowerRight() const1615     ConstIterator lowerRight() const
1616         { return upperLeft()+size(); }
1617 
begin()1618     iterator begin()
1619         { return ScanOrderIterator(ScanOrderIteratorPolicy<Iterator>::ROI(upperLeft(), lowerRight())); }
1620 
end()1621     iterator end()
1622         { return begin() + width()*height(); }
1623 
begin() const1624     const_iterator begin() const
1625         { return ConstScanOrderIterator(ScanOrderIteratorPolicy<ConstIterator>::ROI(upperLeft(), lowerRight())); }
1626 
end() const1627     const_iterator end() const
1628         { return begin() + width()*height(); }
1629 
accessor()1630     Accessor accessor()
1631         { return Accessor(); }
1632 
accessor() const1633     ConstAccessor accessor() const
1634         { return ConstAccessor(); }
1635 
1636   protected:
SingleBandImage()1637     SingleBandImage()
1638     {}
1639 
SingleBandImage(SingleBandImage const & s)1640     SingleBandImage(SingleBandImage const & s)
1641     : VariableBandsImage(s)
1642     {}
1643 
operator =(SingleBandImage const & s)1644     SingleBandImage & operator=(SingleBandImage const & s)
1645     {
1646         VariableBandsImage::operator=(s);
1647         return *this;
1648     }
1649 };// end of SingleBandsImage
1650 
1651 /** entspricht BasicImage<float> und stellt die gleiche Operationen zur Verfuegung wie BasicImage,
1652 * also ist ein EinbandImage, der in die Imagehierarchie eingebetet ist.
1653 */
1654 class GrayImage
1655 : public SingleBandImage
1656 {
1657   public:
1658 
1659     typedef BasicImage<GrayValue>                                      InnerImage;              // entspricht BasicImage<float>
1660     typedef InnerImage::value_type                                     value_type;              // -||- float
1661     typedef value_type                                                 PixelType;               // -||- float
1662     typedef value_type                                                 ConstPixelType;          // -||- float
1663     typedef value_type &                                               reference;               // -||- float &
1664     typedef value_type const &                                         const_reference;         // -||- float const &
1665     typedef value_type *                                               pointer;                 // -||- float *
1666     typedef value_type const *                                         const_pointer;           // -||- float const *
1667     typedef InnerImage::Iterator                                       traverser;               //"normaler"(gewoehnlicher) 2D-Iterator
1668     typedef InnerImage::Iterator                                       Iterator;                // soll deprecated werden !!! Entspricht dem traverser
1669     typedef InnerImage::ConstIterator                                  const_traverser;         //"normaler"(gewoehnlicher) 2D-ConstIterator
1670     typedef InnerImage::ConstIterator                                  ConstIterator;           // soll deprecated werden !!! Entspricht dem const_traverser
1671     typedef IteratorAdaptor<ScanOrderIteratorPolicy<Iterator> >        ScanOrderIterator;       // 1D Iterator ueber das Bild (bzw. ROI), entspricht dem iterator
1672     typedef ScanOrderIterator                                          iterator;                // "normaler" 1D Iterator ueber das Bild (bzw.ROI)
1673     typedef IteratorAdaptor<ScanOrderIteratorPolicy<ConstIterator> >   ConstScanOrderIterator;  // 1D ConstIterator ueber das Bild (bzw. ROI), entspricht dem const_iterator
1674     typedef ConstScanOrderIterator                                     const_iterator;          // "normaler" 1D ConstIterator ueber das Bild (bzw.ROI)
1675 
1676     typedef Diff2D                                                      difference_type;
1677     typedef Diff2D                                                      size_type;
1678     typedef InnerImage::Accessor                                        Accessor;               // Accessor aus dem BasicImage<float>
1679     typedef InnerImage::ConstAccessor                                   ConstAccessor;          // ConstAccessor aus dem BasicImage<float>
1680 #ifndef NO_COVARIANT_RETURN_TYPES                                                                   //////AEND_9////////
1681     typedef GrayImage CloneType;
1682 #endif                                                                                            //////AEND_9////////
1683 
GrayImage()1684     GrayImage()
1685     : image_(new InnerImage(0,0))
1686     {
1687         initAdministrationData(0, image_->size(), 1);
1688     }
1689 
GrayImage(int w,int h)1690     GrayImage(int w, int h)
1691     : image_(new InnerImage(w,h))
1692     {
1693         initAdministrationData((w*h == 0) ? 0 : getDataPtr(image_->begin()), image_->size(), 1);
1694     }
1695 
GrayImage(int w,int h,GrayValue gray_value)1696     GrayImage(int w, int h, GrayValue gray_value)
1697     : image_(new InnerImage(w,h, gray_value))
1698     {
1699         initAdministrationData((w*h == 0) ? 0 : getDataPtr(image_->begin()), image_->size(), 1);
1700     }
1701 
GrayImage(Diff2D const & s)1702     GrayImage(Diff2D const & s)
1703     : image_(new InnerImage(s))
1704     {
1705         initAdministrationData((s.x*s.y == 0) ? 0 : getDataPtr(image_->begin()), image_->size(), 1);
1706     }
1707 
GrayImage(GrayImage const & s)1708     GrayImage(GrayImage const & s)
1709     : SingleBandImage(s),
1710       image_(s.image_)
1711     {}
1712 
GrayImage(InnerImage * i)1713     GrayImage(InnerImage * i)
1714     : image_(i)
1715     {
1716         initAdministrationData((i->width()*i->height() == 0) ? 0 : getDataPtr(image_->begin()), image_->size(), BandsForPixelType<PixelType>::bands);
1717     }
1718 
operator =(GrayImage const & s)1719     GrayImage & operator=(GrayImage const & s)
1720     {
1721         if(this != &s)
1722         {
1723             image_ = s.image_;
1724             SingleBandImage::operator=(s);
1725         }
1726         return *this;
1727     }
1728 
init(PixelType const & pixel)1729     GrayImage & init(PixelType const & pixel)
1730     {
1731         initImage(upperLeft(), lowerRight(), accessor(), pixel);
1732         return *this;
1733     }
1734 
~GrayImage()1735     virtual ~GrayImage()
1736         {}
1737 
1738     /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
1739     *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
1740     *   mit der Groesse und Pixelinitialisierung der ROI
1741     */
clone() const1742     virtual CloneType * clone() const
1743     {
1744         InnerImage * newimg = new InnerImage(size());
1745         copyImage(srcIterRange(upperLeft(), lowerRight()), destImage(*newimg));   // copyImage  kommt ueber imagefunctions.hxx aus copyimage.hxx; srcIterRange kommt aus stdimage.hxx 762; destImage kommt aus stdimage.hxx 733
1746         return new GrayImage(newimg);
1747     }
1748 
1749     /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer
1750     *   auf das aufrufende Objekt zurueckgeliefert.
1751     *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
1752     *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
1753     *   dabei ist an der shallowCopy genau so die ROI gesetzt.
1754     */
shallowCopy() const1755     virtual GrayImage * shallowCopy() const
1756     {
1757         return new GrayImage(*this);
1758     }
1759 
operator [](Diff2D const & c)1760     PixelType & operator[](Diff2D const & c)
1761         { return image_->operator[](c+roiUL_); }
1762 
operator [](Diff2D const & c) const1763     PixelType const & operator[](Diff2D const & c) const
1764         { return image_->operator[](c+roiUL_); }
1765 
operator [](int c)1766     PixelType * operator[](int c)
1767         { return image_->operator[](c+roiUL_.y) + roiUL_.x; }
1768 
operator [](int c) const1769     PixelType  const * operator[](int c) const
1770         { return image_->operator[](c+roiUL_.y) + roiUL_.x; }
1771 
operator ()(int x,int y)1772     PixelType & operator()(int x, int y)
1773         { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
1774 
operator ()(int x,int y) const1775     PixelType const & operator()(int x, int y) const
1776         { return image_->operator()(x+roiUL_.x,y+roiUL_.y); }
1777 
upperLeft()1778     Iterator upperLeft()
1779         { return image_->upperLeft()+roiUL_;}
1780 
lowerRight()1781     Iterator lowerRight()
1782         { return upperLeft()+size(); }
1783 
upperLeft() const1784     ConstIterator upperLeft() const
1785         { return image_->upperLeft()+roiUL_; }
1786 
lowerRight() const1787     ConstIterator lowerRight() const
1788         { return upperLeft()+size(); }
1789 
begin()1790     iterator begin()
1791         { return ScanOrderIterator(ScanOrderIteratorPolicy<Iterator>::ROI(upperLeft(), lowerRight())); }
1792 
end()1793     iterator end()
1794         { return begin() + width()*height(); }
1795 
begin() const1796     const_iterator begin() const
1797         { return ConstScanOrderIterator(ScanOrderIteratorPolicy<ConstIterator>::ROI(upperLeft(), lowerRight())); }
1798 
end() const1799     const_iterator end() const
1800         { return begin() + width()*height(); }
1801 
accessor()1802     Accessor accessor()
1803         { return Accessor(); }
1804 
accessor() const1805     ConstAccessor accessor() const
1806         { return ConstAccessor(); }
1807 
1808   private:
1809     boost::shared_ptr<InnerImage> image_;
1810 };// end of GrayImage
1811 
1812 class SelectBandImage
1813 : public SingleBandImage
1814 {
1815     class ImageHandle
1816     {
1817       public:
~ImageHandle()1818         virtual ~ImageHandle() {}         /////////das verstehe ich nicht
1819     };
1820 
1821     template <class IMAGE>
1822     class ImageHandleImpl
1823     : public ImageHandle
1824     {
1825         boost::shared_ptr<IMAGE> ptr_;
1826 
1827         typedef typename IMAGE::PixelType PixelType;
1828 
1829       public:
ImageHandleImpl(boost::shared_ptr<IMAGE> const & p)1830         ImageHandleImpl(boost::shared_ptr<IMAGE> const & p)
1831         : ptr_(p)
1832         {}
1833     };
1834 
1835   public:
1836 #ifndef NO_COVARIANT_RETURN_TYPES                                           //////AEND_10//////
1837     typedef GrayImage CloneType;
1838     typedef SelectBandImage ShallowCopyType;
1839 #else                                                                       //////AEND_10//////
1840     typedef CloneType ShallowCopyType;
1841 #endif
1842 
1843     template <class IMAGE>
SelectBandImage(IMAGE const & s,int band)1844     SelectBandImage(IMAGE const & s, int band)
1845     : imageHandle_(new ImageHandleImpl<typename IMAGE::InnerImage>(s.image_)),
1846       band_(band)
1847     {
1848         vigra_precondition(band >= 0 && band < s.actualBands(),
1849             "SelectBandImage(): band out of range.");
1850         initAdministrationData(getDataPtr(s.image_->begin())+band, s.actualSize(), s.actualBands(), 1);
1851         if(s.width()*s.height() > 0)
1852             setROI(s.roiUpperLeft(), s.size());
1853     }
1854 
SelectBandImage(SelectBandImage const & s)1855     SelectBandImage(SelectBandImage const & s)
1856     : SingleBandImage(s),
1857       imageHandle_(s.imageHandle_),
1858       band_(s.band_)
1859     {}
1860 
operator =(SelectBandImage const & s)1861     SelectBandImage & operator=(SelectBandImage const & s)
1862     {
1863         if(this != &s)
1864         {
1865             imageHandle_ = s.imageHandle_;
1866             band_ = s.band_;
1867             SingleBandImage::operator=(s);
1868         }
1869         return *this;
1870     }
1871 
~SelectBandImage()1872     virtual ~SelectBandImage()
1873         {}
1874 
1875     /** Entspricht einer deepCopy(), d.h. es wird eine Kopie vom aufrufendem Objekt in Speicher abgelegt
1876     *   Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
1877     *   mit der Groesse und Pixelinitialisierung der ROI
1878     */
clone() const1879     virtual CloneType * clone() const
1880     {
1881         CloneType::InnerImage * newimg = new CloneType::InnerImage(size());
1882         copyImage(srcIterRange(upperLeft(), lowerRight(), accessor()), destImage(*newimg));
1883         return new CloneType(newimg);
1884     }
1885 
1886     /** Erzeugt eine flache Kopie vom aufrufendem Objekt, d.h. es wird pointer
1887     *   auf das aufrufende Objekt zurueckgeliefert.
1888     *   Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
1889     *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
1890     *   dabei ist an der shallowCopy genau so die ROI gesetzt.
1891     */
shallowCopy() const1892     virtual SelectBandImage * shallowCopy() const
1893     {
1894         return new SelectBandImage(*this);
1895     }
1896 
setROI(Diff2D const & ul,Diff2D const & new_size)1897     virtual void setROI(Diff2D const & ul, Diff2D const & new_size)
1898     {
1899         VariableBandsImage::setROI(ul, new_size);
1900     }
1901 
1902     /** die Methode "setROI(int band)" aendert den selektierten Band.
1903     * Parameter "band" ist der neue zu selektierender Band des Bildes
1904     */
setROI(int band)1905     virtual void setROI(int band)
1906     {
1907         vigra_precondition(band >= 0 && band < actualBands_,
1908             "SelectbandImage::setROI(): band out of range.");
1909         data_ = (data_ - band_ + band);
1910         band_ = band;
1911     }
1912 
1913     /** Liefert die "Nummer" des selektierten Bandes
1914     */
getSelectedBand()1915     int getSelectedBand()
1916     { return band_; }
1917 
1918  private:
1919     boost::shared_ptr<ImageHandle> imageHandle_;
1920     int band_;
1921 };
1922 
1923 /****************************************************************/
1924 
1925 #if 0 // this didn't work with MSVC
1926 
1927 #define defineArgumentFactories(Image) \
1928 template <class Accessor> \
1929 inline triple<Image::ConstIterator, Image::ConstIterator, Accessor> \
1930 srcImageRange(Image const & img, Accessor a) \
1931 { \
1932     return triple<Image::ConstIterator, Image::ConstIterator, Accessor>( \
1933             img.upperLeft(), img.lowerRight(), a); \
1934 } \
1935  \
1936 template <class Accessor> \
1937 inline pair<Image::ConstIterator, Accessor> \
1938 srcImage(Image const & img, Accessor a) \
1939 { \
1940     return pair<Image::ConstIterator, Accessor>( \
1941             img.upperLeft(), a); \
1942 } \
1943  \
1944 template <class Accessor> \
1945 inline triple<Image::Iterator, Image::Iterator, Accessor> \
1946 destImageRange(Image & img, Accessor a) \
1947 { \
1948     return triple<Image::Iterator, Image::Iterator, Accessor>( \
1949             img.upperLeft(), img.lowerRight(), a); \
1950 } \
1951  \
1952 template <class Accessor> \
1953 inline pair<Image::Iterator, Accessor> \
1954 destImage(Image & img, Accessor a) \
1955 { \
1956     return pair<Image::Iterator, Accessor>( \
1957             img.upperLeft(), a); \
1958 } \
1959  \
1960 template <class Accessor> \
1961 inline pair<Image::ConstIterator, Accessor> \
1962 maskImage(Image const & img, Accessor a) \
1963 { \
1964     return pair<Image::ConstIterator, Accessor>( \
1965             img.upperLeft(), a); \
1966 } \
1967  \
1968 inline triple<Image::ConstIterator, Image::ConstIterator, Image::ConstAccessor> \
1969 srcImageRange(Image const & img) \
1970 { \
1971     return triple<Image::ConstIterator, Image::ConstIterator, Image::ConstAccessor>( \
1972             img.upperLeft(), img.lowerRight(), img.accessor()); \
1973 } \
1974  \
1975 inline pair<Image::ConstIterator, Image::ConstAccessor> \
1976 srcImage(Image const & img) \
1977 { \
1978     return pair<Image::ConstIterator, Image::ConstAccessor>( \
1979             img.upperLeft(), img.accessor()); \
1980 } \
1981  \
1982 inline triple<Image::Iterator, Image::Iterator, Image::Accessor> \
1983 destImageRange(Image & img) \
1984 { \
1985     return triple<Image::Iterator, Image::Iterator, Image::Accessor>( \
1986             img.upperLeft(), img.lowerRight(), img.accessor()); \
1987 } \
1988  \
1989 inline pair<Image::Iterator, Image::Accessor> \
1990 destImage(Image & img) \
1991 { \
1992     return pair<Image::Iterator, Image::Accessor>( \
1993             img.upperLeft(), img.accessor()); \
1994 } \
1995  \
1996 inline pair<Image::ConstIterator, Image::ConstAccessor> \
1997 maskImage(Image const & img) \
1998 { \
1999     return pair<Image::ConstIterator, Image::ConstAccessor>( \
2000             img.upperLeft(), img.accessor()); \
2001 }
2002 
2003 defineArgumentFactories(VariableBandsImage)
2004 defineArgumentFactories(Vector2Image)
2005 defineArgumentFactories(Vector3Image)
2006 defineArgumentFactories(Vector4Image)
2007 defineArgumentFactories(GrayImage)
2008 defineArgumentFactories(RGBImage)
2009 defineArgumentFactories(SelectBandImage)
2010 defineArgumentFactories(SingleBandImage)
2011 
2012 #endif
2013 ////////////////////////////////////////ab hier bis Markierung soll eine Anpassung an den Kompiler sein
2014 #define defineArgumentFactories(Image) \
2015 template <class Accessor> \
2016 inline triple<Image::ConstIterator, Image::ConstIterator, Accessor> \
2017 srcImageRange(Image const & img, Accessor a) \
2018 { \
2019     return triple<Image::ConstIterator, Image::ConstIterator, Accessor>( \
2020             img.upperLeft(), img.lowerRight(), a); \
2021 } \
2022   \
2023 template <class Accessor> \
2024 inline pair<Image::ConstIterator, Accessor> \
2025 srcImage(Image const & img, Accessor a) \
2026 { \
2027     return pair<Image::ConstIterator, Accessor>( \
2028             img.upperLeft(), a); \
2029 } \
2030  \
2031 template <class Accessor> \
2032 inline triple<Image::Iterator, Image::Iterator, Accessor> \
2033 destImageRange(Image & img, Accessor a) \
2034 { \
2035     return triple<Image::Iterator, Image::Iterator, Accessor>( \
2036             img.upperLeft(), img.lowerRight(), a); \
2037 } \
2038  \
2039 template <class Accessor> \
2040 inline pair<Image::Iterator, Accessor> \
2041 destImage(Image & img, Accessor a) \
2042 { \
2043     return pair<Image::Iterator, Accessor>( \
2044             img.upperLeft(), a); \
2045 } \
2046  \
2047 template <class Accessor> \
2048 inline pair<Image::ConstIterator, Accessor> \
2049 maskImage(Image const & img, Accessor a) \
2050 { \
2051     return pair<Image::ConstIterator, Accessor>( \
2052             img.upperLeft(), a); \
2053 } \
2054  \
2055 inline triple<Image::ConstIterator, Image::ConstIterator, Image::ConstAccessor> \
2056 srcImageRange(Image const & img) \
2057 { \
2058     return triple<Image::ConstIterator, Image::ConstIterator, Image::ConstAccessor>( \
2059             img.upperLeft(), img.lowerRight(), img.accessor()); \
2060 } \
2061  \
2062 inline pair<Image::ConstIterator, Image::ConstAccessor> \
2063 srcImage(Image const & img) \
2064 { \
2065     return pair<Image::ConstIterator, Image::ConstAccessor>( \
2066             img.upperLeft(), img.accessor()); \
2067 } \
2068  \
2069 inline triple<Image::Iterator, Image::Iterator, Image::Accessor> \
2070 destImageRange(Image & img) \
2071 { \
2072     return triple<Image::Iterator, Image::Iterator, Image::Accessor>( \
2073             img.upperLeft(), img.lowerRight(), img.accessor()); \
2074 } \
2075  \
2076 inline pair<Image::Iterator, Image::Accessor> \
2077 destImage(Image & img) \
2078 { \
2079     return pair<Image::Iterator, Image::Accessor>( \
2080             img.upperLeft(), img.accessor()); \
2081 } \
2082  \
2083 inline pair<Image::ConstIterator, Image::ConstAccessor> \
2084 maskImage(Image const & img) \
2085 { \
2086     return pair<Image::ConstIterator, Image::ConstAccessor>( \
2087             img.upperLeft(), img.accessor()); \
2088 }
2089 
2090 #define defineArgumentFactories2(Image, BaseImage) \
2091 template <class Accessor> \
2092 inline triple<BaseImage::ConstIterator, BaseImage::ConstIterator, Accessor> \
2093 srcImageRange(Image const & img, Accessor a) \
2094 { \
2095     return triple<BaseImage::ConstIterator, BaseImage::ConstIterator, Accessor>( \
2096             img.upperLeft(), img.lowerRight(), a); \
2097 } \
2098   \
2099 template <class Accessor> \
2100 inline pair<BaseImage::ConstIterator, Accessor> \
2101 srcImage(Image const & img, Accessor a) \
2102 { \
2103     return pair<BaseImage::ConstIterator, Accessor>( \
2104             img.upperLeft(), a); \
2105 } \
2106  \
2107 template <class Accessor> \
2108 inline triple<BaseImage::Iterator, BaseImage::Iterator, Accessor> \
2109 destImageRange(Image & img, Accessor a) \
2110 { \
2111     return triple<BaseImage::Iterator, BaseImage::Iterator, Accessor>( \
2112             img.upperLeft(), img.lowerRight(), a); \
2113 } \
2114  \
2115 template <class Accessor> \
2116 inline pair<BaseImage::Iterator, Accessor> \
2117 destImage(Image & img, Accessor a) \
2118 { \
2119     return pair<BaseImage::Iterator, Accessor>( \
2120             img.upperLeft(), a); \
2121 } \
2122  \
2123 template <class Accessor> \
2124 inline pair<BaseImage::ConstIterator, Accessor> \
2125 maskImage(Image const & img, Accessor a) \
2126 { \
2127     return pair<BaseImage::ConstIterator, Accessor>( \
2128             img.upperLeft(), a); \
2129 } \
2130  \
2131 inline triple<BaseImage::ConstIterator, BaseImage::ConstIterator, Image::ConstAccessor> \
2132 srcImageRange(Image const & img) \
2133 { \
2134     return triple<BaseImage::ConstIterator, BaseImage::ConstIterator, Image::ConstAccessor>( \
2135             img.upperLeft(), img.lowerRight(), img.accessor()); \
2136 } \
2137  \
2138 inline pair<BaseImage::ConstIterator, Image::ConstAccessor> \
2139 srcImage(Image const & img) \
2140 { \
2141     return pair<BaseImage::ConstIterator, Image::ConstAccessor>( \
2142             img.upperLeft(), img.accessor()); \
2143 } \
2144  \
2145 inline triple<BaseImage::Iterator, BaseImage::Iterator, Image::Accessor> \
2146 destImageRange(Image & img) \
2147 { \
2148     return triple<BaseImage::Iterator, BaseImage::Iterator, Image::Accessor>( \
2149             img.upperLeft(), img.lowerRight(), img.accessor()); \
2150 } \
2151  \
2152 inline pair<BaseImage::Iterator, Image::Accessor> \
2153 destImage(Image & img) \
2154 { \
2155     return pair<BaseImage::Iterator, Image::Accessor>( \
2156             img.upperLeft(), img.accessor()); \
2157 } \
2158  \
2159 inline pair<BaseImage::ConstIterator, Image::ConstAccessor> \
2160 maskImage(Image const & img) \
2161 { \
2162     return pair<BaseImage::ConstIterator, Image::ConstAccessor>( \
2163             img.upperLeft(), img.accessor()); \
2164 }
2165 
2166 defineArgumentFactories(VariableBandsImage)
2167 defineArgumentFactories2(Vector2Image, FVector2Image)
2168 //defineArgumentFactories2(Vector3Image, FVector3Image)
2169 defineArgumentFactories2(Vector4Image, FVector4Image)
2170 defineArgumentFactories(GrayImage)
2171 defineArgumentFactories(RGBImage)
2172 defineArgumentFactories(SelectBandImage)
2173 defineArgumentFactories(SingleBandImage)
2174 ////////////////////////////////////////
2175 
2176 template<>
2177 struct IteratorTraits<VariableBandsIterator >
2178 {
2179     typedef StandardValueAccessor<VectorProxy> DefaultAccessor;
2180 };
2181 
2182 template<>
2183 struct IteratorTraits<ConstVariableBandsIterator >
2184 {
2185     typedef StandardConstValueAccessor<ConstVectorProxy> DefaultAccessor;
2186 };
2187 
2188 template<>
2189 struct IteratorTraits<SelectBandIterator<GrayValue> >
2190 {
2191     typedef StandardAccessor<GrayValue> DefaultAccessor;
2192 };
2193 
2194 template<>
2195 struct IteratorTraits<ConstSelectBandIterator<GrayValue> >
2196 {
2197     typedef StandardConstAccessor<GrayValue> DefaultAccessor;
2198 };
2199 
2200 
2201 } // namespace vigra
2202 
2203 #endif /* VIGRA_IMAGEHIERARCHY_HXX */
2204 
2205 
2206