image_ref.h

Go to the documentation of this file.
00001 #ifndef IMAGE_REF_H
00002 #define IMAGE_REF_H
00003 
00004 #include <cassert>
00005 #include "object.h"
00006 #include "primitives.h"
00007 
00008 namespace mimas {
00009 
00012 struct dist2D{
00013   dist2D(int x = 0, int y = 0):
00014     width(x), height(y){}
00015   
00016   int width;
00017   int height;
00018 };
00019 
00023 template<
00024   typename T,
00025   typename TPtr = const T* >
00026 class const_image_ref: public object
00027 {
00028 public:
00031   const_image_ref(void): data(NULL), width(0), height(0) { dummy = T(); }
00033   const_image_ref( TPtr _data, int _width, int _height ):
00034     data(_data), width(_width), height(_height) { dummy = T(); }
00036   template< typename OPtr >
00037   const_image_ref( const const_image_ref< T, OPtr > &_imgref ):
00038     data( _imgref.rawData() ),
00039     width( _imgref.getWidth() ), height( _imgref.getHeight() )
00040     { dummy = T(); }
00042   class const_iterator{
00043   public:
00044     typedef T value_type;
00045     typedef const value_type * MoveX;
00046         
00047     struct MoveY{   
00048       MoveY(unsigned int width = 0):
00049         width(width),offset(0){
00050       }
00051       
00052       void operator++(void){
00053         offset += width;
00054       }
00055 
00056       //postfix operator. There is no difference as we don't return any value
00057       //but avoid any warning message
00058       void operator++(int){
00059         offset += width;
00060       }
00061       
00062       void operator--(void){
00063         offset -= width;
00064       }
00065 
00066       //postfix operator. There is no difference as we don't return any value
00067       //but avoid any warning message
00068       void operator--(int){
00069         offset -= width;
00070       }
00071     
00072       MoveY & operator+=(int n)
00073       {
00074         offset += width * n;
00075         return *this;
00076       }
00077 
00078       MoveY & operator-=(int n)
00079       {
00080         offset -= width * n;
00081         return *this;
00082       }
00083       
00084       int operator-(const MoveY &y2) const
00085       {
00086         return (offset - y2.offset)/width;
00087       }
00088 
00089       MoveY & operator=(const MoveY &y2) 
00090       {
00091         offset = y2.offset;
00092         width = y2.width;
00093         return *this;
00094       }
00095       
00096       bool operator==(const MoveY &y2) const
00097       {
00098         return (offset == y2.offset) && (width == y2.width);
00099       }
00100 
00101       bool operator<(const MoveY &y2) const
00102       {
00103         return offset < y2.offset;
00104       }
00105 
00106       unsigned int width;
00107       unsigned int offset;
00108     };
00109     
00110     MoveX x;
00111     MoveY y;
00112     
00113     const_iterator(const value_type *data = NULL, unsigned int width = 0):
00114       x(data), y(width) {}
00115         
00116     const_iterator(const const_iterator & rhs)
00117     {
00118       x = rhs.x;
00119       y = MoveY(rhs.y.width);  
00120       y.offset = rhs.y.offset;
00121     }
00122     
00123     const_iterator & operator=(const const_iterator & rhs)
00124     {
00125       x = rhs.x;
00126       y = rhs.y;
00127       return *this;
00128     }
00129 
00130     const_iterator & operator+=(const dist2D & dist)
00131     {
00132       x += dist.width;
00133       y += dist.height;
00134       return *this;
00135     }
00136     
00137     const_iterator & operator-=(const dist2D & dist)
00138     {
00139       x -= dist.width;
00140       y -= dist.height;
00141       return *this;
00142     }
00143     
00144     const_iterator operator+(const dist2D & dist) const 
00145     {
00146       const_iterator k(*this);
00147       k += dist;
00148       return k;
00149     }
00150     
00151     const_iterator operator-(const dist2D & dist) const
00152     {
00153       const_iterator k(*this);
00154       k -= dist;
00155       return k;
00156     }
00157     
00158     //mechanism to check the iterator of both images are of same width.
00159     dist2D operator-(const const_iterator & rhs) const
00160     {
00161 #ifndef NDEBUG
00162       if(y.width != rhs.y.width){
00163         std::cerr<<"const_iterator (in image.h): you cannot compare"
00164           "2 iterators if both images don't have the same width" <<std::endl;
00165       }
00166 #endif
00167       return dist2D(x - rhs.x, (y.offset - rhs.y.offset)/ rhs.y.width);
00168     }
00169     
00170     bool operator==(const const_iterator & imIt) const
00171     {
00172       return (x == imIt.x) && (y == imIt);
00173     }
00174     
00175     const value_type & operator*()
00176     {
00177       return *(x + y.offset);
00178     }
00179     
00180     const value_type operator*() const 
00181     {
00182       return *(x + y.offset);
00183     }
00184     
00185     const value_type &operator[](const dist2D dist) 
00186     {
00187       return *(x + y.offset + dist.width + dist.height * y.width);
00188     }
00189     
00190     const value_type operator[](const dist2D dist) const
00191     {
00192       return *(x + y.offset + dist.width + dist.height * y.width);
00193     }
00194     
00195   };
00196 
00198   int getWidth(void) const { return width; }
00200   int getHeight(void) const { return height; }
00201 
00203   int getSize(void) const { return width * height; }
00204 
00213   const T &getPixel( int x, int y ) const {
00214     if ( x>=0 && y>=0 && x<getWidth() && y<getHeight() )
00215       return data[ y * getWidth() + x ];
00216     else
00217     {
00218 #ifndef NDEBUG
00219   std::cerr << "The usage of the dummy variable is deprecated."<<std::endl 
00220       << "Instead use the pixel() function or the getPixel() function in conjunction with the in() function."
00221       << std::endl << "If you do not have this message you are succesfully not using the dummy variable." 
00222       << std::endl<< std::endl; 
00223 #endif
00224       return dummy;
00225     }
00226   }
00227 
00233   const T& pixel(  int x, int y ) const {
00234     assert( x>=0 && y>=0 && x<getWidth() && y<getHeight() );
00235     return data[ y * getWidth() + x ];
00236   }
00237 
00239   const T *rawData( void ) const {
00240     return data;
00241   }
00242 
00244   bool initialised( void ) const {
00245     assert( ( data != NULL ) == ( width > 0 && height > 0 ) );
00246     return data != NULL;
00247   }
00248 
00249   //To be able to instantiate the point when calling the function
00250   //we must not have a reference as parameter.
00251   //Does this lead to performance issues? Since we are likely to call this function often.
00252   bool in(const mimas::point p) const {
00253     if ( p.x < 0 || p.y < 0 ||
00254          p.x >= getWidth() || p.y >= getHeight() ) {
00255      return false;
00256    }
00257     return true;
00258   }
00259 
00260   bool in(const mimas::pixel p) const{
00261     if (p.x < 0 || p.y < 0 ||
00262         p.x >= getWidth() || p.y >= getHeight()) {
00263     return false;
00264     }
00265     return true;
00266   }
00267 
00268   bool in(int x, int y) const{
00269     if (x < 0 || y < 0 ||
00270         x >= getWidth() || y >= getHeight()) {
00271     return false;
00272     }
00273     return true;
00274   }
00275 
00276   //to return const values
00277   inline const_iterator upperLeft(void) const
00278   {
00279     return const_iterator(data,getWidth());
00280   }
00281   
00282   inline const_iterator lowerRight(void) const
00283   {
00284     const_iterator t(data,getWidth());
00285     t.x += getWidth();
00286     t.y += getHeight();
00287     return t;
00288   }
00289 
00290   inline const_iterator ul(void) const
00291   {
00292     return const_iterator(data,getWidth());
00293   }
00294       
00295   inline const_iterator lr(void) const
00296   {
00297     const_iterator t(data,getWidth());
00298     t.x += getWidth();
00299     t.y += getHeight();
00300     return t;
00301   }
00302 protected:
00305   TPtr data;
00306   int width;
00307   int height;
00308   T dummy;
00309 };
00310 
00314 template< typename T >
00315 class image_ref: public const_image_ref< T, T* >
00316 {
00317 public:
00325   class iterator {
00326   public:
00327     typedef T value_type;
00328     typedef value_type * MoveX;
00329     
00330     struct MoveY{   
00331       MoveY(unsigned int width = 0):
00332         width(width),offset(0) {
00333         //      std::cerr<< "constructor MoveY"<<std::endl;
00334       }
00335 
00336       void operator++(void){
00337         offset += width;
00338       }
00339       
00340       //postfix operator. There is no difference as we don't return any value
00341       //but avoid any warning message
00342       void operator++(int) {
00343         offset += width;
00344       }
00345       
00346       void operator--(void) {
00347         offset -= width;
00348       }
00349 
00350       //postfix operator. There is no difference as we don't return any value
00351       //but avoid any warning message
00352       void operator--(int) {
00353         offset -= width;
00354       }
00355     
00356       MoveY & operator+=(int n)
00357       {
00358         offset += width * n;
00359         return *this;
00360       }
00361 
00362       MoveY & operator-=(int n)
00363       {
00364         offset -= width * n;
00365         return *this;
00366       }
00367       
00368       int operator-(const MoveY &y2) const
00369       {
00370         return (offset - y2.offset)/width;
00371       }
00372       
00373       MoveY & operator=(const MoveY &y2) 
00374       {
00375         offset = y2.offset;
00376         width = y2.width;
00377         return *this;
00378       }
00379   
00380       bool operator==(const MoveY &y2) const
00381       {
00382         return (offset == y2.offset) && (width == y2.width);
00383       }
00384 
00385       bool operator<(const MoveY &y2) const
00386       {
00387         return offset < y2.offset;
00388       }
00389       
00390       unsigned int width;
00391       unsigned int offset;
00392     };
00393     
00394     MoveX x;
00395     MoveY y;
00396         
00397     iterator(value_type *data = NULL, unsigned int width = 0):
00398       x(data), y(width) {}
00399       
00400     iterator(const iterator & rhs)
00401     {
00402       x = rhs.x;
00403       y = MoveY(rhs.y.width);  
00404       y.offset = rhs.y.offset;
00405     }
00406     
00407     iterator & operator=(const iterator & rhs)
00408     {
00409       //std::cerr<< "operator= iterator"<<std::endl;
00410       x = rhs.x;
00411       y = rhs.y;
00412       return *this;
00413     }
00414 
00415     iterator & operator+=(const dist2D & dist)
00416     {
00417       x += dist.width;
00418       y += dist.height;
00419       return *this;
00420     }
00421   
00422     iterator & operator-=(const dist2D & dist)
00423     {
00424       x -= dist.width;
00425       y -= dist.height;
00426       return *this;
00427     }
00428     
00429     iterator operator+(const dist2D & dist) const 
00430     {
00431       iterator k(*this);
00432       k += dist;
00433       return k;
00434     }
00435     
00436     iterator operator-(const dist2D & dist) const
00437     {
00438       iterator k(*this);
00439       k -= dist;
00440       return k;
00441     }
00442 
00443     //mechanism to check the iterator of both images are of same width.
00444     dist2D operator-(const iterator & rhs) const
00445     {
00446 #ifndef NDEBUG
00447       if(y.width != rhs.y.width){
00448         std::cerr<<"Image iterator (in image.h): you cannot compare"
00449           "2 iterators if both images don't have the same width" <<std::endl;
00450       }
00451 #endif
00452       return dist2D(x - rhs.x, (y.offset - rhs.y.offset)/ rhs.y.width);
00453     }
00454     
00455     bool operator==(const iterator & imIt) const
00456     {
00457       return (x == imIt.x) && (y == imIt);
00458     }
00459     
00460     value_type & operator*()
00461     {
00462       return *(x + y.offset);
00463     }
00464     
00465     value_type operator*() const 
00466     {
00467       return *(x + y.offset);
00468     }
00469 
00470     value_type &operator[](const dist2D dist)
00471     {
00472       return *(x + y.offset + dist.width + (signed)( dist.height * y.width ) );
00473     }
00474 
00475     value_type operator[](const dist2D dist) const
00476     {
00477       return *(x + y.offset + dist.width + (signed)( dist.height * y.width ) );
00478     }
00479     
00480   };
00481 
00484   image_ref(void) {}
00488   explicit image_ref( const image_ref< T > &_imgref ):
00489     const_image_ref< T, T* >( _imgref ) {}
00490 
00492   image_ref( T *_data, int _width, int _height ):
00493     const_image_ref< T, T* >( _data, _width, _height ) {}
00494 
00496   virtual void fill( const T &initVal ) {
00497     int size = image_ref< T >::getSize();
00498     std::fill( image_ref< T >::data,
00499                image_ref< T >::data + size, initVal );
00500   };
00501 
00509   T &getPixel( int x, int y ) {
00510     if ( x>=0 && y>=0 &&
00511          x<image_ref< T >::getWidth() &&
00512          y<image_ref< T >::getHeight() )
00513       return image_ref< T >::data
00514         [ y * image_ref< T >::getWidth() + x ];
00515     else
00516       {
00517 #ifndef NDEBUG
00518   std::cerr << "The usage of the dummy variable is deprecated."<<std::endl 
00519       << "Instead use the pixel() function or the getPixel() function in conjunction with the in() function."
00520       << std::endl << "If you do not have this message you are succesfully not using the dummy variable." 
00521       << std::endl<< std::endl; 
00522 #endif
00523   return image_ref< T >::dummy;
00524       }  
00525 }
00526 
00535   const T &getPixel( int x, int y ) const {
00536     if ( x>=0 && y>=0 &&
00537          x<image_ref< T >::getWidth() &&
00538          y<image_ref< T >::getHeight() )
00539       return image_ref< T >::data
00540         [ y * image_ref< T >::getWidth() + x ];
00541     else
00542       {
00543 #ifndef NDEBUG
00544   std::cerr << "The usage of the dummy variable is deprecated."<<std::endl 
00545       << "Instead use the pixel() function or the getPixel() function in conjunction with the in() function."
00546       << std::endl << "If you do not have this message you are succesfully not using the dummy variable." 
00547       << std::endl<< std::endl; 
00548 #endif
00549   return image_ref< T >::dummy;
00550       }  
00551 }
00552 
00559   virtual void setPixel( int x, int y, T val ) {
00560     if ( x>=0 &&
00561          y>=0 &&
00562          x<image_ref< T >::getWidth() &&
00563          y<image_ref< T >::getHeight() )
00564       image_ref< T >::data
00565         [ y * image_ref< T >::getWidth() + x ]  =  val;
00566   }
00567 
00573   T& pixel(  int x, int y ) {
00574     assert( x>=0 && y>=0 && x<image_ref< T >::getWidth()&& y<image_ref< T >::getHeight() );
00575     return image_ref< T >::data
00576       [ y * image_ref< T >::getWidth() + x ];
00577   }
00578 
00584   const T& pixel(  int x, int y ) const {
00585     assert( x>=0 && y>=0 &&
00586             x<image_ref< T >::getWidth() &&
00587             y<image_ref< T >::getHeight() );
00588     return image_ref< T >::data
00589       [ y * image_ref< T >::getWidth() + x ];
00590   }
00591 
00593   const T *rawData( void ) const {
00594     return image_ref< T >::data;
00595   }
00596 
00598   T *rawData(void) {
00599     return image_ref< T >::data;
00600   }
00601 
00602   inline iterator upperLeft(void)
00603   {
00604     return iterator(image_ref< T >::data,
00605                     image_ref< T >::getWidth());
00606   }
00607   
00608   inline iterator lowerRight(void)
00609   {
00610     iterator t(image_ref< T >::data,
00611                image_ref< T >::getWidth());
00612     t.x += image_ref< T >::getWidth();
00613     t.y += image_ref< T >::getHeight();
00614     return t;
00615   }
00616   
00617   //For lazy guys/pals/mates/fellows only!!!
00618   //the same as uperLeft
00619   inline iterator ul(void)
00620   {
00621     return iterator(image_ref< T >::data,
00622                     image_ref< T >::getWidth());
00623   }
00624   
00625   //the same as lowerRight
00626   inline iterator lr(void)
00627   {
00628     iterator t(image_ref< T >::data,
00629                image_ref< T >::getWidth());
00630     t.x += image_ref< T >::getWidth();
00631     t.y += image_ref< T >::getHeight();
00632     return t;
00633   }
00634   
00635 };
00636 
00637 }
00638 
00639 #endif

[GNU/Linux] [Qt] [Mesa] [STL] [Lapack] [Boost] [Magick++] [Xalan-C and Xerces-C] [doxygen] [graphviz] [FFTW] [popt] [xine] [Gnuplot] [gnu-arch] [gcc] [gstreamer] [autoconf/automake/make] [freshmeat.net] [opensource.org] [sourceforge.net] [MMVL]
mimas 2.1 - Copyright Mon Oct 30 11:31:17 2006, Bala Amavasai, Stuart Meikle, Arul Selvan, Fabio Caparrelli, Jan Wedekind, Manuel Boissenin, ...