00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef IMAGE_H_DEFINED
00040 #define IMAGE_H_DEFINED
00041
00042
00043
00044
00045 #include "Util/Assert.H"
00046 #include "Util/Promotions.H"
00047 #include "Image/ArrayData.H"
00048 #include "Image/Point2D.H"
00049 #include "Image/Rectangle.H"
00050
00051 #ifdef INVT_MEM_DEBUG
00052 #include "Image/CheckedIterator.H"
00053 #endif
00054
00055 #include <algorithm>
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 template <class T>
00073 class Image
00074 {
00075 public:
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 inline Image(const T* inarray, int width, int height);
00086
00087
00088
00089
00090
00091 inline Image(const T* inarray, const Dims& dims);
00092
00093
00094 inline Image(int width, int height, InitPolicy init);
00095
00096
00097 inline explicit Image(const Dims& dims, InitPolicy init);
00098
00099
00100 inline Image();
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 inline Image(const Image<T>& A);
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 template <class T2> inline Image(const Image<T2>& A);
00121
00122
00123
00124
00125
00126
00127
00128 inline Image<T>& operator=(const Image<T>& A);
00129
00130
00131
00132
00133
00134
00135
00136
00137 template <class T2> inline Image<T>& operator=(const Image<T2>& A);
00138
00139
00140 inline ~Image();
00141
00142
00143
00144
00145
00146
00147
00148 inline void freeMem();
00149
00150
00151
00152
00153
00154
00155
00156
00157 inline void swap(Image<T>& other);
00158
00159
00160
00161
00162
00163
00164 inline void attach(T* array, const int width, const int height);
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 inline void detach();
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 inline Image<T> deepcopy() const;
00223
00224
00225
00226 inline void resize(const Dims& dims, const bool clear = false);
00227
00228
00229
00230 inline void resize(const int width, const int height,
00231 const bool clear = false);
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 #ifndef INVT_MEM_DEBUG
00263
00264
00265 typedef T* iterator;
00266
00267 typedef const T* const_iterator;
00268 #else
00269
00270
00271 typedef CheckedIterator<T> iterator;
00272
00273 typedef CheckedIterator<const T> const_iterator;
00274 #endif
00275
00276
00277 inline const_iterator begin() const;
00278
00279
00280 inline const_iterator end() const;
00281
00282
00283 inline iterator beginw();
00284
00285
00286 inline iterator endw();
00287
00288
00289
00290
00291
00292
00293
00294
00295 inline bool initialized() const;
00296
00297
00298 inline int getSize() const;
00299
00300
00301 inline uint size() const;
00302
00303
00304 inline int getWidth() const;
00305
00306
00307 inline int getHeight() const;
00308
00309
00310 inline const Dims& getDims() const;
00311
00312
00313 inline Rectangle getBounds() const;
00314
00315
00316
00317
00318 template <class C>
00319 inline bool isSameSize(const C& other) const;
00320
00321
00322 inline bool is1D() const;
00323
00324
00325 inline bool isVector() const;
00326
00327
00328 inline bool isTransposedVector() const;
00329
00330
00331 inline bool isSquare() const;
00332
00333
00334 inline T& operator[](const int index);
00335
00336
00337 inline const T& operator[](const int index) const;
00338
00339
00340 inline T& operator[](const Point2D<int>& p);
00341
00342
00343 inline const T& operator[](const Point2D<int>& p) const;
00344
00345
00346 inline const T& getVal(const int index) const;
00347
00348
00349 inline const T& getVal(const int x, const int y) const;
00350
00351
00352 inline const T& getVal(const Point2D<int>& p) const;
00353
00354
00355 template <class T2> inline void getVal(const int x, const int y,
00356 T2& val) const;
00357
00358
00359 inline T getValInterp(const float x, const float y) const;
00360
00361
00362 inline T getValInterp(const Point2D<float>& p) const;
00363
00364
00365
00366
00367 inline T getValInterpScaled(const Point2D<int>& p, const Dims& pdims) const;
00368
00369
00370 template <class T2> inline void setVal(const int index, const T2& value);
00371
00372
00373 template <class T2> inline void setVal(const int x, const int y,
00374 const T2& value);
00375
00376
00377 template <class T2> inline void setVal(const Point2D<int>& p, const T2& value);
00378
00379
00380 inline const T* getArrayPtr() const;
00381
00382
00383 inline T* getArrayPtr();
00384
00385
00386 inline bool coordsOk(const Point2D<int>& P) const;
00387
00388
00389 inline bool coordsOk(const int i, const int j) const;
00390
00391
00392
00393 inline bool coordsOk(const Point2D<float>& p) const;
00394
00395
00396
00397 inline bool coordsOk(const float i, const float j) const;
00398
00399
00400 inline bool rectangleOk(const Rectangle& rect) const;
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 bool operator==(const Image<T>& that) const;
00416
00417
00418 Image<T>& operator+=(const T& val);
00419
00420
00421 Image<T>& operator-=(const T& val);
00422
00423
00424 Image<T>& operator*=(const T& val);
00425
00426
00427 Image<T>& operator/=(const T& val);
00428
00429
00430 Image<T>& operator<<=(const unsigned int nbits);
00431
00432
00433 Image<T>& operator>>=(const unsigned int nbits);
00434
00435
00436
00437 template <class T2> inline
00438 Image<T>& operator+=(const Image<T2>& A);
00439
00440
00441 template <class T2> inline
00442 Image<T>& operator-=(const Image<T2>& A);
00443
00444
00445 template <class T2> inline
00446 Image<T>& operator*=(const Image<T2>& A);
00447
00448
00449 template <class T2> inline
00450 Image<T>& operator/=(const Image<T2>& A);
00451
00452
00453 template <class T2> inline
00454 Image<T>& operator|=(const Image<T2>& A);
00455
00456
00457
00458 template <class T2> inline
00459 Image<typename promote_trait<T,T2>::TP> operator+(const T2& val) const;
00460
00461
00462 template <class T2> inline
00463 Image<typename promote_trait<T,T2>::TP> operator-(const T2& val) const;
00464
00465
00466 template <class T2> inline
00467 Image<typename promote_trait<T,T2>::TP> operator*(const T2& val) const;
00468
00469
00470 template <class T2> inline
00471 Image<typename promote_trait<T,T2>::TP> operator/(const T2& val) const;
00472
00473
00474 Image<T> operator<<(const unsigned int nbits) const;
00475
00476
00477 Image<T> operator>>(const unsigned int nbits) const;
00478
00479
00480
00481 template <class T2> inline
00482 Image<typename promote_trait<T,T2>::TP> operator+(const
00483 Image<T2>& img) const;
00484
00485
00486 template <class T2> inline
00487 Image<typename promote_trait<T,T2>::TP> operator-(const
00488 Image<T2>& img) const;
00489
00490
00491 template <class T2> inline
00492 Image<typename promote_trait<T,T2>::TP> operator*(const
00493 Image<T2>& img) const;
00494
00495
00496 template <class T2> inline
00497 Image<typename promote_trait<T,T2>::TP> operator/(const
00498 Image<T2>& img) const;
00499
00500
00501
00502 inline void clear(const T& val = T());
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 bool hasSameData(const Image<T>& b) const;
00514
00515
00516
00517 long refCount() const throw();
00518
00519
00520
00521 bool isShared() const throw();
00522
00523
00524
00525 private:
00526
00527
00528
00529 ArrayHandle<T> itsHdl;
00530 inline const ArrayData<T>& impl() const;
00531 inline ArrayData<T>& uniq();
00532 };
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 template <class T>
00565 inline Image<T> reshape(const Image<T>& orig, const Dims& newdims)
00566 {
00567 ASSERT(orig.getDims().sz() == newdims.sz());
00568 return Image<T>(orig.getArrayPtr(), newdims);
00569 }
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 template <class T> inline
00585 Image<T>::Image(const T* inarray, int width, int height) :
00586 itsHdl(new ArrayData<T>(Dims(width, height), inarray))
00587 {}
00588
00589
00590 template <class T> inline
00591 Image<T>::Image(const T* inarray, const Dims& dims) :
00592 itsHdl(new ArrayData<T>(dims, inarray))
00593 {}
00594
00595
00596 template <class T> inline
00597 Image<T>::Image(int width, int height, InitPolicy init) :
00598 itsHdl(new ArrayData<T>(Dims(width, height), init))
00599 {}
00600
00601
00602 template <class T> inline
00603 Image<T>::Image(const Dims& dims, InitPolicy init) :
00604 itsHdl(new ArrayData<T>(dims, init))
00605 {}
00606
00607
00608 template <class T> inline
00609 Image<T>::Image() :
00610 itsHdl(new ArrayData<T>())
00611 {}
00612
00613
00614 template <class T> inline
00615 Image<T>::Image(const Image<T>& A) :
00616 itsHdl(A.itsHdl)
00617 {}
00618
00619
00620 template <class T> template <class T2> inline
00621 Image<T>::Image(const Image<T2>& A) :
00622 itsHdl(new ArrayData<T>(A.getDims(), NO_INIT))
00623 {
00624 typename Image<T2>::const_iterator sptr = A.begin();
00625 typename Image<T>::iterator aptr = beginw();
00626 typename Image<T>::iterator stop = endw();
00627 while (aptr != stop)
00628 {
00629 *aptr++ = clamped_convert<T>(*sptr++);
00630 }
00631 }
00632
00633
00634 template <class T> inline
00635 Image<T>& Image<T>::operator=(const Image<T>& A)
00636 {
00637 Image<T> A_copy( A );
00638 this->swap(A_copy);
00639 return *this;
00640 }
00641
00642
00643 template <class T> template <class T2> inline
00644 Image<T>& Image<T>::operator=(const Image<T2>& A)
00645 {
00646
00647 if (this->getDims() != A.getDims() || itsHdl.isShared())
00648 *this = Image<T>(A.getDims(), NO_INIT);
00649
00650 typename Image<T2>::const_iterator sptr = A.begin();
00651 typename Image<T>::iterator aptr = this->beginw();
00652 typename Image<T>::iterator stop = this->endw();
00653 while (aptr != stop) *aptr++ = clamped_convert<T>(*sptr++);
00654 return *this;
00655 }
00656
00657
00658 template <class T> inline
00659 Image<T>::~Image()
00660 { }
00661
00662
00663 template <class T> inline
00664 void Image<T>::freeMem()
00665 {
00666 Image<T> empty;
00667 this->swap(empty);
00668 }
00669
00670
00671
00672
00673
00674
00675 template <class T> inline
00676 void Image<T>::swap(Image<T>& other)
00677 {
00678 itsHdl.swap(other.itsHdl);
00679 }
00680
00681
00682 template <class T> inline
00683 void Image<T>::attach(T* array, const int w, const int h)
00684 {
00685 ArrayHandle<T> attached(new ArrayData<T>(Dims(w, h), array, WRITE_THRU));
00686 itsHdl.swap(attached);
00687 }
00688
00689
00690 template <class T> inline
00691 void Image<T>::detach()
00692 {
00693 ArrayHandle<T> emptyHdl;
00694 itsHdl.swap(emptyHdl);
00695 }
00696
00697
00698 template <class T> inline
00699 Image<T> Image<T>::deepcopy() const
00700 {
00701
00702
00703 return Image<T>(this->getArrayPtr(), this->getDims());
00704 }
00705
00706
00707 template <class T> inline
00708 void Image<T>::resize(const Dims& dims, const bool do_clear)
00709 {
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719 if (dims != getDims())
00720 {
00721 ArrayHandle<T> resized(new ArrayData<T>(dims, do_clear ? ZEROS:NO_INIT));
00722 itsHdl.swap(resized);
00723 }
00724 else
00725 {
00726 if (do_clear) clear( T() );
00727 }
00728 }
00729
00730
00731 template <class T> inline
00732 void Image<T>::resize(const int width, const int height, const bool do_clear)
00733 {
00734 resize(Dims(width, height), do_clear);
00735 }
00736
00737
00738
00739
00740
00741 #ifndef INVT_MEM_DEBUG
00742
00743 template<class T> inline
00744 typename Image<T>::const_iterator Image<T>::begin() const
00745 { return impl().data(); }
00746
00747 template<class T> inline
00748 typename Image<T>::const_iterator Image<T>::end() const
00749 { return impl().end(); }
00750
00751 template<class T> inline
00752 typename Image<T>::iterator Image<T>::beginw()
00753 { return uniq().dataw(); }
00754
00755 template<class T> inline
00756 typename Image<T>::iterator Image<T>::endw()
00757 { return uniq().endw(); }
00758
00759 #else
00760
00761 template <class T> inline
00762 typename Image<T>::const_iterator Image<T>::begin() const
00763 { return const_iterator(impl().data(), impl().data(), impl().end()); }
00764
00765 template <class T> inline
00766 typename Image<T>::const_iterator Image<T>::end() const
00767 { return const_iterator(impl().end(), impl().data(), impl().end()); }
00768
00769 template <class T> inline
00770 typename Image<T>::iterator Image<T>::beginw()
00771 { return iterator(uniq().dataw(), uniq().dataw(), uniq().endw()); }
00772
00773 template <class T> inline
00774 typename Image<T>::iterator Image<T>::endw()
00775 { return iterator(uniq().endw(), uniq().dataw(), uniq().endw()); }
00776
00777 #endif
00778
00779
00780
00781
00782
00783
00784 template <class T> inline
00785 bool Image<T>::initialized() const
00786 { return getWidth() > 0 && getHeight() > 0; }
00787
00788
00789 template <class T> inline
00790 int Image<T>::getSize() const
00791 { return getDims().sz(); }
00792
00793
00794 template <class T> inline
00795 uint Image<T>::size() const
00796 { return getDims().sz(); }
00797
00798
00799 template <class T> inline
00800 int Image<T>::getWidth() const
00801 { return itsHdl.get().w(); }
00802
00803
00804 template <class T> inline
00805 int Image<T>::getHeight() const
00806 { return itsHdl.get().h(); }
00807
00808
00809 template <class T> inline
00810 const Dims& Image<T>::getDims() const
00811 { return itsHdl.get().dims(); }
00812
00813
00814 template <class T> inline
00815 Rectangle Image<T>::getBounds() const
00816 { return Rectangle(Point2D<int>(0,0), itsHdl.get().dims()); }
00817
00818
00819 template <class T> template <class C> inline
00820 bool Image<T>::isSameSize(const C& other) const
00821 { return getWidth() == other.getWidth() && getHeight() == other.getHeight(); }
00822
00823
00824 template <class T> inline
00825 bool Image<T>::is1D() const
00826 { return (getWidth() == 1) || (getHeight() == 1); }
00827
00828
00829 template <class T> inline
00830 bool Image<T>::isVector() const
00831 { return (getWidth() == 1); }
00832
00833
00834 template <class T> inline
00835 bool Image<T>::isTransposedVector() const
00836 { return (getHeight() == 1); }
00837
00838
00839 template <class T> inline
00840 bool Image<T>::isSquare() const
00841 { return (getWidth() == getHeight()); }
00842
00843
00844 template <class T> inline
00845 T& Image<T>::operator[](int index)
00846 {
00847 ASSERT(index >= 0 && index < this->getSize());
00848 return beginw()[index];
00849 }
00850
00851
00852 template <class T> inline
00853 const T& Image<T>::operator[](int index) const
00854 {
00855 ASSERT(index >= 0 && index < this->getSize());
00856 return begin()[index];
00857 }
00858
00859
00860 template <class T> inline
00861 T& Image<T>::operator[](const Point2D<int>& p)
00862 {
00863 ASSERT(this->coordsOk(p));
00864 return this->beginw()[p.i + p.j * this->getWidth()];
00865 }
00866
00867
00868 template <class T> inline
00869 const T& Image<T>::operator[](const Point2D<int>& p) const
00870 {
00871 ASSERT(this->coordsOk(p));
00872 return this->begin()[p.i + p.j * this->getWidth()];
00873 }
00874
00875
00876 template <class T> inline
00877 const T& Image<T>::getVal(const int index) const
00878 {
00879 ASSERT(index >= 0 && index < this->getSize());
00880 return begin()[index];
00881 }
00882
00883
00884 template <class T> inline
00885 const T& Image<T>::getVal(const int x, const int y) const
00886 {
00887 ASSERT(coordsOk(x, y));
00888 return(begin()[x + y * getWidth()]);
00889 }
00890
00891
00892 template <class T> inline
00893 const T& Image<T>::getVal(const Point2D<int>& p) const
00894 {
00895 ASSERT(coordsOk(p));
00896 return(begin()[p.i + p.j * getWidth()]);
00897 }
00898
00899
00900 template <class T> template <class T2> inline
00901 void Image<T>::getVal(const int x, const int y, T2& val) const
00902 {
00903 ASSERT(coordsOk(x, y));
00904 val = begin()[x + y * getWidth()];
00905 }
00906
00907
00908 template <class T> inline
00909 T Image<T>::getValInterp(const float x, const float y) const
00910 {
00911 typename Image<T>::const_iterator const sptr = begin();
00912 const int wid = getWidth(), hei = getHeight();
00913
00914 const int y0 = int(y);
00915 const int y1 = std::min(y0 + 1, hei - 1);
00916 const float fy = y - float(y0);
00917
00918 const int wy0 = wid * y0;
00919 const int wy1 = wid * y1;
00920
00921 const int x0 = int(x);
00922 const int x1 = std::min(x0 + 1, wid - 1);
00923 const float fx = x - float(x0);
00924
00925 ASSERT(coordsOk(x0, y0));
00926 typename promote_trait<T, float>::TP const
00927 d00( sptr[x0 + wy0] ), d10( sptr[x1 + wy0] ),
00928 d01( sptr[x0 + wy1] ), d11( sptr[x1 + wy1] ),
00929 dx0( d00 + (d10 - d00) * fx ),
00930 dx1( d01 + (d11 - d01) * fx );
00931
00932 return T( dx0 + (dx1 - dx0) * fy );
00933 }
00934
00935
00936 template <class T> inline
00937 T Image<T>::getValInterp(const Point2D<float>& p) const
00938 {
00939 return this->getValInterp(p.i, p.j);
00940 }
00941
00942
00943 template <class T> inline
00944 T Image<T>::getValInterpScaled(const Point2D<int>& p,
00945 const Dims& pdims) const
00946 {
00947 const float x =
00948 std::max(0.0f, (float(p.i)+0.5f) * float(this->getWidth())/pdims.w() - 0.5f);
00949 const float y =
00950 std::max(0.0f, (float(p.j)+0.5f) * float(this->getHeight())/pdims.h() - 0.5f);
00951
00952 return this->getValInterp(x, y);
00953 }
00954
00955
00956 template <class T> template <class T2> inline
00957 void Image<T>::setVal(const int index, const T2& value)
00958 {
00959 ASSERT(index >= 0 && index < this->getSize());
00960 beginw()[index] = clamped_convert<T>(value);
00961 }
00962
00963
00964 template <class T> template <class T2> inline
00965 void Image<T>::setVal(const int x, const int y, const T2& value)
00966 {
00967 ASSERT(coordsOk(x, y));
00968 beginw()[x + y * getWidth()] = clamped_convert<T>(value);
00969 }
00970
00971
00972 template <class T> template <class T2> inline
00973 void Image<T>::setVal(const Point2D<int>& p, const T2& value)
00974 {
00975 ASSERT(coordsOk(p));
00976 beginw()[p.i + p.j * getWidth()] = clamped_convert<T>(value);
00977 }
00978
00979
00980 template <class T> inline
00981 const T* Image<T>::getArrayPtr() const
00982 {
00983 return impl().data();
00984 }
00985
00986
00987 template <class T> inline
00988 T* Image<T>::getArrayPtr()
00989 {
00990 return uniq().dataw();
00991 }
00992
00993
00994 template <class T> inline
00995 bool Image<T>::coordsOk(const Point2D<int>& P) const
00996 {
00997 return (P.i >= 0 && P.j >= 0 && P.i < getWidth() && P.j < getHeight());
00998 }
00999
01000
01001 template <class T> inline
01002 bool Image<T>::coordsOk(const int i, const int j) const
01003 {
01004 return (i >= 0 && j >= 0 && i < getWidth() && j < getHeight());
01005 }
01006
01007
01008 template <class T> inline
01009 bool Image<T>::coordsOk(const Point2D<float>& p) const
01010 {
01011 return this->coordsOk(p.i, p.j);
01012 }
01013
01014
01015 template <class T> inline
01016 bool Image<T>::coordsOk(const float i, const float j) const
01017 {
01018 return (i >= 0.0F && j >= 0.0F &&
01019 i < float(getWidth() - 1) && j < float(getHeight() - 1));
01020 }
01021
01022
01023 template <class T> inline
01024 bool Image<T>::rectangleOk(const Rectangle& rect) const
01025 {
01026 return (rect.left() < getWidth() && rect.rightI() < getWidth() &&
01027 rect.top() < getHeight() && rect.bottomI() < getHeight() &&
01028 rect.left() >= 0 && rect.rightI() >= 0 &&
01029 rect.top() >= 0 && rect.bottomI() >= 0);
01030 }
01031
01032
01033 template <class T>
01034 bool Image<T>::operator==(const Image<T>& that) const
01035 {
01036 if (!this->isSameSize(that)) return false;
01037
01038 return std::equal(this->begin(), this->end(), that.begin());
01039 }
01040
01041
01042 template <class T> inline
01043 Image<T>& Image<T>::operator+=(const T& val)
01044 {
01045 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01046 itr != stop; ++itr)
01047 *itr = clamped_convert<T>( (*itr) + val );
01048 return *this;
01049 }
01050
01051
01052 template <class T> inline
01053 Image<T>& Image<T>::operator-=(const T& val)
01054 {
01055 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01056 itr != stop; ++itr)
01057 *itr = clamped_convert<T>( (*itr) - val );
01058 return *this;
01059 }
01060
01061
01062 template <class T> inline
01063 Image<T>& Image<T>::operator*=(const T& val)
01064 {
01065 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01066 itr != stop; ++itr)
01067 *itr = clamped_convert<T>( (*itr) * val );
01068 return *this;
01069 }
01070
01071
01072 template <class T> inline
01073 Image<T>& Image<T>::operator/=(const T& val)
01074 {
01075 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01076 itr != stop; ++itr)
01077 *itr = clamped_convert<T>( (*itr) / val );
01078 return *this;
01079 }
01080
01081
01082 template <class T> inline
01083 Image<T>& Image<T>::operator<<=(const unsigned int nbits)
01084 {
01085 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01086 itr != stop; ++itr)
01087 *itr <<= nbits;
01088 return *this;
01089 }
01090
01091
01092 template <class T> inline
01093 Image<T>& Image<T>::operator>>=(const unsigned int nbits)
01094 {
01095 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01096 itr != stop; ++itr)
01097 *itr >>= nbits;
01098 return *this;
01099 }
01100
01101
01102 template <class T> template <class T2> inline
01103 Image<T>& Image<T>::operator+=(const Image<T2>& A)
01104 {
01105 ASSERT(isSameSize(A));
01106 typename Image<T2>::const_iterator itr2 = A.begin();
01107 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01108 itr != stop; ++itr, ++itr2)
01109 *itr = clamped_convert<T>( (*itr) + (*itr2) );
01110 return *this;
01111 }
01112
01113
01114 template <class T> template <class T2> inline
01115 Image<T>& Image<T>::operator-=(const Image<T2>& A)
01116 {
01117 ASSERT(isSameSize(A));
01118 typename Image<T2>::const_iterator itr2 = A.begin();
01119 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01120 itr != stop; ++itr, ++itr2)
01121 *itr = clamped_convert<T>( (*itr) - (*itr2) );
01122 return *this;
01123 }
01124
01125
01126 template <class T> template <class T2> inline
01127 Image<T>& Image<T>::operator*=(const Image<T2>& A)
01128 {
01129 ASSERT(isSameSize(A));
01130 typename Image<T2>::const_iterator itr2 = A.begin();
01131 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01132 itr != stop; ++itr, ++itr2)
01133 *itr = clamped_convert<T>( (*itr) * (*itr2) );
01134 return *this;
01135 }
01136
01137
01138 template <class T> template <class T2> inline
01139 Image<T>& Image<T>::operator/=(const Image<T2>& A)
01140 {
01141 ASSERT(isSameSize(A));
01142 typename Image<T2>::const_iterator itr2 = A.begin();
01143 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01144 itr != stop; ++itr, ++itr2)
01145 *itr = clamped_convert<T>( (*itr) / (*itr2) );
01146 return *this;
01147 }
01148
01149
01150 template <class T> template <class T2> inline
01151 Image<T>& Image<T>::operator|=(const Image<T2>& A)
01152 {
01153 ASSERT(isSameSize(A));
01154 typename Image<T2>::const_iterator itr2 = A.begin();
01155 for (typename Image<T>::iterator itr = beginw(), stop = endw();
01156 itr != stop; ++itr, ++itr2)
01157 *itr = clamped_convert<T>( (*itr) | (*itr2) );
01158 return *this;
01159 }
01160
01161 template <class T> template <class T2> inline
01162 Image<typename promote_trait<T,T2>::TP> Image<T>::operator+(const T2& val) const
01163 {
01164 typedef typename promote_trait<T,T2>::TP TPRO;
01165 Image<TPRO> result(getWidth(), getHeight(), NO_INIT);
01166 typename Image<TPRO>::iterator ritr = result.beginw();
01167 for (typename Image<T>::const_iterator itr = begin(), stop = end();
01168 itr != stop; ++itr, ++ritr)
01169 *ritr = (*itr) + val;
01170 return result;
01171 }
01172
01173
01174 template <class T> template <class T2> inline
01175 Image<typename promote_trait<T,T2>::TP> Image<T>::operator-(const T2& val) const
01176 {
01177 typedef typename promote_trait<T,T2>::TP TPRO;
01178 Image<TPRO> result(getWidth(), getHeight(), NO_INIT);
01179 typename Image<TPRO>::iterator ritr = result.beginw();
01180 for (typename Image<T>::const_iterator itr = begin(), stop = end();
01181 itr != stop; ++itr, ++ritr)
01182 *ritr = (*itr) - val;
01183 return result;
01184 }
01185
01186
01187 template <class T> template <class T2> inline
01188 Image<typename promote_trait<T,T2>::TP> Image<T>::operator*(const T2& val) const
01189 {
01190 typedef typename promote_trait<T,T2>::TP TPRO;
01191 Image<TPRO> result(getWidth(), getHeight(), NO_INIT);
01192 typename Image<TPRO>::iterator ritr = result.beginw();
01193 for (typename Image<T>::const_iterator itr = begin(), stop = end();
01194 itr != stop; ++itr, ++ritr)
01195 *ritr = (*itr) * val;
01196 return result;
01197 }
01198
01199
01200 template <class T> template <class T2> inline
01201 Image<typename promote_trait<T,T2>::TP> Image<T>::operator/(const T2& val) const
01202 {
01203 typedef typename promote_trait<T,T2>::TP TPRO;
01204 Image<TPRO> result(getWidth(), getHeight(), NO_INIT);
01205 typename Image<TPRO>::iterator ritr = result.beginw();
01206 for (typename Image<T>::const_iterator itr = begin(), stop = end();
01207 itr != stop; ++itr, ++ritr)
01208 *ritr = (*itr) / val;
01209 return result;
01210 }
01211
01212
01213 template <class T> inline
01214 Image<T> Image<T>::operator<<(const unsigned int nbits) const
01215 {
01216 Image<T> result(getWidth(), getHeight(), NO_INIT);
01217 typename Image<T>::iterator ritr = result.beginw();
01218 for (typename Image<T>::const_iterator itr = this->begin(), stop = this->end();
01219 itr != stop; ++itr, ++ritr)
01220 *ritr = ((*itr) << nbits);
01221 return result;
01222 }
01223
01224
01225 template <class T> inline
01226 Image<T> Image<T>::operator>>(const unsigned int nbits) const
01227 {
01228 Image<T> result(getWidth(), getHeight(), NO_INIT);
01229 typename Image<T>::iterator ritr = result.beginw();
01230 for (typename Image<T>::const_iterator itr = this->begin(), stop = this->end();
01231 itr != stop; ++itr, ++ritr)
01232 *ritr = ((*itr) >> nbits);
01233 return result;
01234 }
01235
01236
01237 template <class T> template <class T2> inline
01238 Image<typename promote_trait<T,T2>::TP> Image<T>::operator+(const Image<T2>& img) const
01239 {
01240 ASSERT(isSameSize(img));
01241 typedef typename promote_trait<T,T2>::TP TPRO;
01242 Image<TPRO> result(getWidth(), getHeight(), NO_INIT);
01243 typename Image<TPRO>::iterator ritr = result.beginw();
01244 typename Image<T2>::const_iterator itr2 = img.begin();
01245 for (typename Image<T>::const_iterator itr = begin(), stop = end();
01246 itr != stop; ++itr, ++itr2, ++ritr)
01247 *ritr = (*itr) + (*itr2);
01248 return result;
01249 }
01250
01251
01252 template <class T> template <class T2> inline
01253 Image<typename promote_trait<T,T2>::TP> Image<T>::operator-(const Image<T2>& img) const
01254 {
01255 ASSERT(isSameSize(img));
01256 typedef typename promote_trait<T,T2>::TP TPRO;
01257 Image<TPRO> result(getWidth(), getHeight(), NO_INIT);
01258 typename Image<TPRO>::iterator ritr = result.beginw();
01259 typename Image<T2>::const_iterator itr2 = img.begin();
01260 for (typename Image<T>::const_iterator itr = begin(), stop = end();
01261 itr != stop; ++itr, ++itr2, ++ritr)
01262 *ritr = (*itr) - (*itr2);
01263 return result;
01264 }
01265
01266
01267 template <class T> template <class T2> inline
01268 Image<typename promote_trait<T,T2>::TP> Image<T>::operator*(const Image<T2>& img) const
01269 {
01270 ASSERT(isSameSize(img));
01271 typedef typename promote_trait<T,T2>::TP TPRO;
01272 Image<TPRO> result(getWidth(), getHeight(), NO_INIT);
01273 typename Image<TPRO>::iterator ritr = result.beginw();
01274 typename Image<T2>::const_iterator itr2 = img.begin();
01275 for (typename Image<T>::const_iterator itr = begin(), stop = end();
01276 itr != stop; ++itr, ++itr2, ++ritr)
01277 *ritr = (*itr) * (*itr2);
01278 return result;
01279 }
01280
01281
01282 template <class T> template <class T2> inline
01283 Image<typename promote_trait<T,T2>::TP> Image<T>::operator/(const Image<T2>& img) const
01284 {
01285 ASSERT(isSameSize(img));
01286 typedef typename promote_trait<T,T2>::TP TPRO;
01287 Image<TPRO> result(getWidth(), getHeight(), NO_INIT);
01288 typename Image<TPRO>::iterator ritr = result.beginw();
01289 typename Image<T2>::const_iterator itr2 = img.begin();
01290 for (typename Image<T>::const_iterator itr = begin(), stop = end();
01291 itr != stop; ++itr, ++itr2, ++ritr)
01292 *ritr = (*itr) / (*itr2);
01293 return result;
01294 }
01295
01296
01297 template <class T> inline
01298 void Image<T>::clear(const T& val)
01299 {
01300
01301
01302
01303
01304
01305 if (itsHdl.isShared())
01306 *this = Image<T>(getDims(), NO_INIT);
01307
01308 for (iterator itr = beginw(), stop = endw(); itr != stop; ++itr)
01309 *itr = val;
01310 }
01311
01312
01313
01314
01315
01316 template <class T> inline
01317 bool Image<T>::hasSameData(const Image<T>& b) const
01318 { return itsHdl.hasSameData(b.itsHdl); }
01319
01320
01321 template <class T> inline
01322 long Image<T>::refCount() const throw() { return itsHdl.refCount(); }
01323
01324
01325 template <class T> inline
01326 bool Image<T>::isShared() const throw() { return itsHdl.isShared(); }
01327
01328
01329
01330
01331
01332 template <class T> inline
01333 const ArrayData<T>& Image<T>::impl() const
01334 { return itsHdl.get(); }
01335
01336
01337 template <class T> inline
01338 ArrayData<T>& Image<T>::uniq()
01339 { return itsHdl.uniq(); }
01340
01341
01342
01343
01344
01345
01346
01347 #endif