img_image.h
Go to the documentation of this file.
00001 #ifndef IMG_IMAGE_H_
00002 #define IMG_IMAGE_H_
00003 
00009 #include "img/img_base.h"
00010 #include "img/img_attributes.h"
00011 
00012 namespace img {
00013 
00025 template<int Channels=3, typename ScalarType=double, bool Safe=true> 
00026 class Image //TODO: Safe=false prima di mettere in vcg
00027 {
00028 private:
00029   // Data is private but controlled data wiews are
00030   // accessible from accessors
00031 
00033   int _width; 
00035   int _height; 
00037   ScalarType *_data; 
00038 
00039 // constructors
00040 public:
00042   ImgAttributes<ScalarType> attributes;
00043 
00044 
00049   Image() // creates a 0 x 0 image
00050   :_width(0),_height(0),_data(NULL),attributes()
00051   {
00052     STATIC_ASSERT( Channels>0 );
00053     STATIC_FLOAT_OR_DOUBLE_TYPECHECK( ScalarType );
00054   }
00055 
00062   Image(const Image<Channels,ScalarType,Safe> &image) // copy constructor (deep copy)
00063   {
00064     STATIC_ASSERT( Channels>0 );
00065     STATIC_FLOAT_OR_DOUBLE_TYPECHECK( ScalarType );
00066 
00067     assert(image._width > 0);
00068     assert(image._height > 0);
00069     assert(image._data != NULL);
00070     if(Safe) {
00071       if(image._width <= 0) throw ImageException("Image(Image): Nonpositive width");
00072       if(image._height <= 0) throw ImageException("Image(Image): Nonpositive height");
00073       if(image._data == NULL) throw ImageException("Image(Image): NULL data");     
00074     }    
00075     _width = image._width;
00076     _height = image._height;
00077     _data = new ScalarType[Channels * _width * _height];
00078     attributes=image.attributes;
00079 
00080     memcpy(_data, image._data, sizeof(ScalarType) * Channels * _width * _height);
00081   }
00082 
00087   template<typename OtherScalarType, bool OtherSafe> 
00088   Image(const Image<Channels,OtherScalarType,OtherSafe> &image) // templated copy constructor (deep copy)
00089   :_width(0),_height(0),_data(NULL)
00090   {
00091     STATIC_ASSERT( Channels>0 );
00092     STATIC_FLOAT_OR_DOUBLE_TYPECHECK( ScalarType );
00093 
00094     assert(image._width > 0);
00095     assert(image._height > 0);
00096     assert(image._data != NULL);
00097     if(Safe || OtherSafe) {
00098       if(image._width <= 0) throw ImageException("Image(Image): Nonpositive width");
00099       if(image._height <= 0) throw ImageException("Image(Image): Nonpositive height");
00100       if(image._data == NULL) throw ImageException("Image(Image): NULL data");     
00101     }    
00102     _width = image._width;
00103     _height = image._height;
00104     _data = new ScalarType[Channels * _width * _height];
00105     attributes=image.attributes;
00106 
00107     if(typeid( ScalarType ) == typeid( OtherScalarType ))
00108       memcpy(_data, image._data, sizeof(ScalarType) * Channels * _width * _height);
00109     else
00110       for(int offset=0;offset< Channels * _width * _height; ++offset)
00111         _data[offset] = static_cast<ScalarType>(image._data[offset]);
00112   }
00113 
00120   Image(int arg_width,int arg_height)
00121   :_width(arg_width),_height(arg_height),_data(NULL),attributes()
00122   {
00123     STATIC_ASSERT( Channels>0 );
00124     STATIC_FLOAT_OR_DOUBLE_TYPECHECK( ScalarType );
00125 
00126     assert(arg_width>0);
00127     assert(arg_height>0);
00128     if(Safe) {
00129       if(arg_width <= 0) throw ImageException("Image(int,int): Nonpositive width");
00130       if(arg_height <= 0) throw ImageException("Image(int,int): Nonpositive height");
00131     }
00132     _data = new ScalarType[Channels * _width * _height];
00133     for(int offset=0;offset< Channels * _width * _height; ++offset)
00134       _data[offset] = 0.0f;
00135   }  
00136 
00138   ~Image()
00139   {
00140     attributes.reset();
00141     if(_data!=NULL){
00142       delete [] _data;
00143       _data=NULL;
00144     }
00145   }
00146 
00147 // public functions
00148 public:
00154   template<typename OtherScalarType, bool OtherSafe> 
00155   inline Image< Channels,ScalarType,Safe> & operator =(const Image<Channels,OtherScalarType,OtherSafe> &image)
00156   {
00157     assert(image._width > 0);
00158     assert(image._height > 0);
00159     assert(image._data != NULL);
00160     if(Safe || OtherSafe) {
00161       if(image._width <= 0) throw ImageException("operator =: Nonpositive width");
00162       if(image._height <= 0) throw ImageException("operator =: Nonpositive height");
00163       if(image._data == NULL) throw ImageException("operator =: NULL data");     
00164     }    
00165     _width = image._width;
00166     _height = image._height;
00167     _data = new ScalarType[Channels * _width * _height];
00168     attributes=image.attributes;
00169 
00170     if(typeid( ScalarType ) == typeid( OtherSafe ))
00171       memcpy(_data, image._data, sizeof(ScalarType) * Channels * _width * _height);
00172     else
00173       for(int offset=0;offset < Channels * _width * _height; ++offset)
00174         _data[offset] = static_cast<ScalarType>(image._data[offset]);
00175     return *this;
00176   }
00177 
00184   inline void setZero(int arg_width, int arg_height)
00185   {
00186     assert(arg_width>0);
00187     assert(arg_height>0);
00188     if(Safe) {
00189       if(arg_width <= 0) throw ImageException("setZero: Nonpositive width");
00190       if(arg_height <= 0) throw ImageException("setZero: Nonpositive height");
00191     }
00192     if(_data!=NULL){
00193       delete [] _data;
00194       _data=NULL;
00195     }    
00196     _width = arg_width;
00197     _height = arg_height;
00198     _data = new ScalarType[Channels * _width * _height];
00199     attributes.reset();
00200     
00201     for(int offset=0;offset< Channels * _width * _height; ++offset)
00202       _data[offset] = 0.0f;
00203   }
00204 
00209   inline void deleteData()
00210   {
00211     if(_data!=NULL){
00212       delete [] _data;
00213       _data=NULL;
00214     }
00215     _width = 0;
00216     _height = 0;    
00217   } 
00218 
00219 
00226   inline void getPixel(int x, int y, ScalarType (& ret_pixel)[Channels]) const
00227   {
00228     assert( _data != NULL );
00229     assert( x >= 0 && x < _width );
00230     assert( y >= 0 && y < _height );
00231     if( Safe ){
00232       if ( _data == NULL ) throw ImageException("getPixel: NULL data");
00233       if ( !( x >= 0 && x < _width ) ) throw ImageException("getPixel: x out of bounds");
00234       if ( !( y >= 0 && y < _height ) ) throw ImageException("getPixel: y out of bounds");      
00235     }
00236     for (int channel=0;channel<Channels;++channel)
00237       ret_pixel[channel] = _data[ (x + y * _width) * Channels + channel ];
00238   }
00239 
00246   inline void setPixel(int x, int y, const ScalarType (& pixel)[Channels])
00247   {
00248     assert( _data != NULL );
00249     assert( x >= 0 && x < _width );
00250     assert( y >= 0 && y < _height );
00251     if( Safe ){
00252       if ( _data == NULL ) throw ImageException("setPixel: NULL data");
00253       if ( !( x >= 0 && x < _width ) ) throw ImageException("setPixel: x out of bounds");
00254       if ( !( y >= 0 && y < _height ) ) throw ImageException("setPixel: y out of bounds");      
00255     }
00256     for (int channel=0;channel<Channels;++channel)
00257       _data[ (x + y * _width) * Channels + channel ] = pixel[channel];
00258   }
00259 
00267   inline ScalarType getValue(int x, int y, int channel) const
00268   {
00269     assert( _data != NULL );
00270     assert( x >= 0 && x < _width );
00271     assert( y >= 0 && y < _height );
00272     assert( channel >=0 && channel < Channels );
00273     if( Safe ){
00274       if ( _data == NULL ) throw ImageException("getFloat: NULL data");
00275       if ( !( x >= 0 && x < _width ) ) throw ImageException("getFloat: x out of bounds");
00276       if ( !( y >= 0 && y < _height ) ) throw ImageException("getFloat: y out of bounds");
00277       if ( !( channel >=0 && channel < Channels ) ) throw ImageException("channel out of bounds");
00278     }
00279     return _data[ (x + y * _width) * Channels + channel ];
00280   }
00281 
00289   inline void setValue(int x, int y, int channel, ScalarType value)
00290   {
00291     assert( _data != NULL );
00292     assert( x >= 0 && x < _width );
00293     assert( y >= 0 && y < _height );
00294     assert( channel >=0 && channel < Channels );
00295     if( Safe ){
00296       if ( _data == NULL ) throw ImageException("setFloat: NULL data");
00297       if ( !( x >= 0 && x < _width ) ) throw ImageException("setFloat: x out of bounds");
00298       if ( !( y >= 0 && y < _height ) ) throw ImageException("setFloat: y out of bounds");      
00299       if ( !( channel >=0 && channel < Channels ) ) throw ImageException("channel out of bounds");
00300     }
00301     _data[(x + y * _width) * Channels + channel] = value;
00302   }
00303 
00310   inline void getPixelAsClamped(int x, int y, ScalarType (& ret_pixel)[Channels]) const
00311   {
00312     getPixel(x<0?0:(x<_width?x:_width-1), y<0?0:(y<_height?y:_height-1), ret_pixel);
00313   }
00314 
00322   inline float getValueAsClamped(int x, int y, int channel) const
00323   {
00324     return getValue(x<0?0:(x<_width?x:_width-1), y<0?0:(y<_height?y:_height-1),channel);
00325   }
00326 
00333   inline void nearestPixel(float x, float y, ScalarType (& ret_pixel)[Channels]) const
00334   {
00335   getPixel(static_cast<int>(floor(x+0.5f)),static_cast<int>(floor(y+0.5f)), ret_pixel);
00336   }
00337 
00339 //  inline void bilinearPixel(float x, float y, const ScalarType[] &pixel) const
00340 //  {
00341 //    assert( _data != NULL );
00342 //    assert( x >= 0.0f && x <= _width-1.0f );
00343 //    assert( y >= 0.0f && y <= _height-1.0f );
00344 //    if( SAFE ){
00345 //      if ( _data == NULL ) throw ImageException("bilinearPixel: NULL data");
00346 //      if ( !( x >= 0.0f && x <= _width-1.0f ) ) throw ImageException("bilinearPixel: x out of bounds");
00347 //      if ( !( y >= 0.0f && y <= _height-1.0f ) ) throw ImageException("bilinearPixel: y out of bounds");      
00348 //    }    
00349 //    
00350 //  int x1 = static_cast<int>(floor(x));
00351 //    int y1 = static_cast<int>(floor(y));
00352 //  float a = 1.0f;
00353 //  float b = 1.0f;
00354 //  
00355 //  if( x1 == _width )
00356 //      x1--;
00357 //  else
00358 //      a = x - x1;
00359 //  if( y1 == _height )
00360 //      y1--;
00361 //  else
00362 //      b = y - y1;
00363 //    
00364 //  float a1 = (1.0f - a);
00365 //    float b1 = (1.0f - b);
00366 //    
00367 //  int i = x1 + y1 * _width;
00368 //
00369 //  return _data[i] * a1 * b1
00370 //         + _data[i + 1] * a * b1 
00371 //         + _data[i + _width] * a1 * b + 
00372 //         _data[i + _width + 1] * a * b;  
00373 //  }
00374 
00375 // accessors
00376 public:
00381   inline int width() const
00382   {
00383     return _width;
00384   }
00385 
00390   inline int height() const
00391   {
00392     return _height;
00393   }
00394 
00400   inline void setWidth(int width)
00401   {
00402      assert(width > 0);
00403      if(Safe){
00404        if(width <= 0) throw ImageException("setWidth: Nonpositive width");
00405     }
00406     _width=width;
00407   }
00408 
00414    inline void setHeight(int height)
00415   {
00416     assert(height > 0);
00417     if(Safe){
00418        if(height <= 0) throw ImageException("setHeight: Nonpositive height");
00419     }
00420     _height=height;
00421   }
00422 
00428   inline ScalarType* dataValues() const
00429   {
00430     return _data;
00431   }
00432 
00437   inline int dataValuesSize() const
00438   {
00439     return _width * _height * Channels;
00440   }
00441 
00442 
00448   inline void setValues(ScalarType* data)
00449   {
00450     assert(data!=NULL);
00451     if(Safe){
00452       if(data == NULL) throw ImageException("setValues: NULL data");
00453     }
00454     _data = data;
00455   }
00456 
00463   inline bool isInside(int x, int y) const
00464   {
00465     return x >= 0 && x < _width && y >= 0 && y < _height;
00466   }
00467 
00474   inline bool isInside(float x, float y) const
00475   {
00476     return x >= 0.0f && x <= _width-1.0f && y >= 0.0f && y <= _height-1.0f;
00477   }
00478 
00483   inline bool isValid() const
00484   {
00485     return _data != NULL && _width > 0 && _height > 0;
00486   }
00487 
00492   inline int channels() const
00493   {
00494     return Channels;
00495   }
00496 
00503   inline void setRawValue(int i, ScalarType value)
00504   {
00505      _data[i] = value;
00506   }
00507   
00508 };
00509 
00510 } //end namespace img
00511 
00512 #endif /*IMG_IMAGE_H_*/


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:31:54