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