00001
00002
00003 #include "Image.h"
00004 #include "Error.h"
00005 #include "Property.h"
00006
00007 #include <errno.h>
00008 #include <iostream>
00009
00010 using namespace std;
00011
00012 namespace RenderTools {
00013
00014
00015 #ifdef RT_DEVIL
00016 bool Image::s_init = false;
00017 #endif
00018
00019 Image::Image( void ):
00020 AbstractPropertyContainer(),
00021 m_w( 0 ),
00022 m_h( 0 ),
00023 m_filename( "" ),
00024 m_fileNotFound( false ),
00025 m_channels( 4 ),
00026 m_bytespp( 4 ),
00027 m_format( IL_RGBA ),
00028 m_type( IL_UNSIGNED_BYTE ),
00029 m_data( 0 ){
00030
00031 #ifdef RT_DEVIL
00032
00033 initIL();
00034 #endif
00035
00036 }
00037
00038 PropertyPtr Image::create( const XMLNodePtr & xml ){
00039 ImagePtr p( new Image() );
00040 p->setName( xml );
00041 p->createProperties();
00042 p->setProperties( xml, false );
00043 return( dynamic_pointer_cast< AbstractProperty, Image >( p ) );
00044 }
00045
00046 void Image::createProperties( void ){
00047 AbstractPropertyContainer::createProperties();
00048 createProperty( this, "filename", & m_filename, AbstractProperty::FILENAME );
00049 createProperty( this, "width", & m_w );
00050 createProperty( this, "height", & m_h );
00051
00052 EnumList formats;
00053 #ifdef GL_ALPHA
00054 formats << GL_ALPHA;
00055 #endif
00056 #ifdef GL_RGB
00057 formats << GL_RGB;
00058 #endif
00059 #ifdef GL_RGBA
00060 formats << GL_RGBA;
00061 #endif
00062 #ifdef GL_LUMINANCE
00063 formats << GL_LUMINANCE;
00064 #endif
00065 #ifdef GL_LUMINANCE_ALPHA
00066 formats << GL_LUMINANCE_ALPHA;
00067 #endif
00068 createProperty( this, "format", GLenumStruct( & m_format ), formats );
00069
00070 EnumList types;
00071 #ifdef GL_UNSIGNED_BYTE
00072 types << GL_UNSIGNED_BYTE;
00073 #endif
00074 #ifdef GL_BYTE
00075 types << GL_BYTE;
00076 #endif
00077 #ifdef GL_UNSIGNED_SHORT
00078 types << GL_UNSIGNED_SHORT;
00079 #endif
00080 #ifdef GL_SHORT
00081 types << GL_SHORT;
00082 #endif
00083 #ifdef GL_UNSIGNED_INT
00084 types << GL_UNSIGNED_INT;
00085 #endif
00086 #ifdef GL_INT
00087 types << GL_INT;
00088 #endif
00089 #ifdef GL_HALF
00090 types << GL_HALF;
00091 #endif
00092 #ifdef GL_FLOAT
00093 types << GL_FLOAT;
00094 #endif
00095 #ifdef GL_DOUBLE
00096 types << GL_DOUBLE;
00097 #endif
00098 createProperty( this, "type", GLenumStruct( & m_type ), types );
00099 }
00100
00101 const string Image::getTypeName( bool ofComponent ) const {
00102 return( "Image" );
00103 }
00104
00105 Image::~Image( void ){
00106 #ifdef RT_DEVIL
00107 if( m_idIL ){
00108 ilDeleteImages( 1, & m_idIL );
00109 }
00110 #endif
00111
00112 }
00113
00114 void Image::onInitialize( void ){
00115 #ifdef RT_DEVIL
00116 ilInit();
00117 makeAndBindILName();
00118 if( m_filename != "" ){
00119 m_filename = findFile( m_filename ).c_str();
00120 if( ! ilLoadImage( m_filename.c_str() ) ){
00121 Error::warning( Error::IMAGE_NOT_LOADED, __FILE__, __LINE__, getError() + " loading " + string( basename( ( char * )m_filename.c_str() ) ) );
00123 m_channels = getChannels( m_format );
00125 m_bytespp = getBytesPerPixel( m_type, m_format );
00127 ilTexImage( m_w, m_h, 1, m_channels, m_format, m_type, m_data );
00129 m_data = (void *)ilGetData();
00131 m_fileNotFound = true;
00132 }
00133 else{
00134
00135 m_w = ilGetInteger( IL_IMAGE_WIDTH );
00136 m_h = ilGetInteger( IL_IMAGE_HEIGHT );
00137 m_channels = ilGetInteger( IL_IMAGE_CHANNELS );
00138 m_bytespp = ilGetInteger( IL_IMAGE_BYTES_PER_PIXEL );
00139 m_format = ilGetInteger( IL_IMAGE_FORMAT );
00140 m_type = ilGetInteger( IL_IMAGE_TYPE );
00141 m_data = (void *)ilGetData();
00142 }
00143 }
00144 else{
00145
00146 m_channels = getChannels( m_format );
00147
00148 m_bytespp = getBytesPerPixel( m_type, m_format );
00149
00150 ilTexImage( m_w, m_h, 1, m_channels, m_format, m_type, m_data );
00151
00152 m_data = (void *)ilGetData();
00153 }
00154 #endif
00155 }
00156
00157 void Image::onPropertyEvent( const PropertyEvent & e ){
00158
00159 }
00160
00161 const string & Image::getFilename( void ) const {
00162 return( m_filename );
00163 }
00164
00165 GLuint Image::getWidth( void ) const {
00166 return( m_w );
00167 }
00168
00169 GLuint Image::getHeight( void ) const {
00170 return( m_h );
00171 }
00172
00173 GLuint Image::getChannels( void ) const {
00174 return( m_channels );
00175 }
00176
00177 GLuint Image::getBytesPerPixel( void ) const {
00178 return( m_bytespp );
00179 }
00180
00181 GLenum Image::getFormat( void ) const {
00182 return( m_format );
00183 }
00184
00185 GLenum Image::getType( void ) const {
00186 return( m_type );
00187 }
00188
00189 const void * Image::getData( void ) const {
00190 return( m_data );
00191 }
00192
00193 void Image::screenDump( int w, int h, string filename ){
00194
00195 #ifdef RT_DEVIL
00196
00197 GLuint id;
00198
00199
00200 ilGenImages( 1, & id );
00201
00202
00203 ilBindImage( id );
00204
00205
00206 ilActiveImage( id );
00207
00208 GLubyte * pixels = new GLubyte [ w * h * 4 ];
00209
00210 #if glReadBuffer
00211 glReadBuffer( GL_BACK );
00212 #endif
00213 glReadPixels( 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
00214
00215 ilTexImage( w, h, 1, 4, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
00216
00217 ilSaveImage( filename.c_str() );
00218
00219 ilDeleteImages( 1, & id );
00220
00221 delete [] pixels;
00222 #endif
00223 }
00224
00225 void Image::deleteImage( bool send ){
00226 #ifdef RT_DEVIL
00227 ilDeleteImages( 1, &m_idIL );
00228 m_idIL = 0;
00229 #endif
00230 if( send ){
00232 }
00233 }
00234
00235 void Image::setData( const void *data, bool send ){
00236 #ifdef RT_DEVIL
00237 ilActiveImage( 0 );
00238 ilBindImage( m_idIL );
00239 ilTexImage( m_w, m_h, 1, m_channels, m_format, m_type, const_cast< void * >( data ) );
00240 m_data = ilGetData();
00241 #endif
00242 if( send ){
00244 }
00245 }
00246
00247 void Image::save( string filename ){
00248 #ifdef RT_DEVIL
00249 ilActiveImage( m_idIL );
00250 ilBindImage( m_idIL );
00251 ilEnable( IL_FILE_OVERWRITE );
00252 string str = filename.c_str();
00253 if( str == "" ){
00254 str = m_filename;
00255 }
00256 ilSaveImage( str.c_str() );
00257 #endif
00258 }
00259
00260 #ifdef RT_DEVIL
00261
00265 void Image::makeAndBindILName(){
00266
00267 ilGenImages( 1, &m_idIL );
00268
00269
00270 ilActiveImage( 0 );
00271
00272
00273 ilBindImage( m_idIL );
00274 }
00275
00279 void Image::initIL(){
00280 if( ! s_init ){
00281
00282 ilInit();
00283
00284
00285 ilEnable( IL_ORIGIN_SET );
00286 ilSetInteger( IL_ORIGIN_MODE, IL_ORIGIN_LOWER_LEFT );
00287
00288 s_init = true;
00289 }
00290 }
00291
00296 GLuint Image::getChannels( ILenum format ){
00297
00298 ILuint channels = 1;
00299
00300 switch( format ){
00301 case IL_COLOR_INDEX: channels = 1; break;
00302 case IL_ALPHA: channels = 1; break;
00303 case IL_RGB: channels = 3; break;
00304 case IL_RGBA: channels = 4; break;
00305 case IL_BGR: channels = 3; break;
00306 case IL_BGRA: channels = 4; break;
00307 case IL_LUMINANCE: channels = 1; break;
00308 case IL_LUMINANCE_ALPHA: channels = 2; break;
00309 }
00310 return( channels );
00311 }
00312
00318 GLuint Image::getBytesPerPixel( ILenum type, ILenum format ){
00319
00320 ILuint size = 1;
00321
00322 switch( type ){
00323 case IL_BYTE: size = sizeof( ILbyte ); break;
00324 case IL_UNSIGNED_BYTE: size = sizeof( ILubyte ); break;
00325 case IL_SHORT: size = sizeof( ILshort ); break;
00326 case IL_UNSIGNED_SHORT: size = sizeof( ILushort ); break;
00327 case IL_INT: size = sizeof( ILint ); break;
00328 case IL_UNSIGNED_INT: size = sizeof( ILuint ); break;
00329 case IL_HALF: size = sizeof( ILfloat ) / 2; break;
00330 case IL_FLOAT: size = sizeof( ILfloat ); break;
00331 case IL_DOUBLE: size = sizeof( ILdouble ); break;
00332 }
00333
00334 GLuint channels = getChannels( format );
00335 return( size * channels );
00336 }
00337
00338 string Image::getError(){
00339 GLenum error = ilGetError();
00340 switch( error ){
00341 case IL_NO_ERROR: return( string( "IL_NO_ERROR" ) );
00342 case IL_INVALID_ENUM: return( string( "IL_INVALID_ENUM" ) );
00343 case IL_OUT_OF_MEMORY: return( string( "IL_OUT_OF_MEMORY" ) );
00344 case IL_FORMAT_NOT_SUPPORTED: return( string( "IL_FORMAT_NOT_SUPPORTED" ) );
00345 case IL_INTERNAL_ERROR: return( string( "IL_INTERNAL_ERROR" ) );
00346 case IL_INVALID_VALUE: return( string( "IL_INVALID_VALUE" ) );
00347 case IL_ILLEGAL_OPERATION: return( string( "IL_ILLEGAL_OPERATION" ) );
00348 case IL_ILLEGAL_FILE_VALUE: return( string( "IL_ILLEGAL_FILE_VALUE" ) );
00349 case IL_INVALID_FILE_HEADER: return( string( "IL_INVALID_FILE_HEADER" ) );
00350 case IL_INVALID_PARAM: return( string( "IL_INVALID_PARAM" ) );
00351 case IL_COULD_NOT_OPEN_FILE: return( string( "IL_COULD_NOT_OPEN_FILE" ) );
00352 case IL_INVALID_EXTENSION: return( string( "IL_INVALID_EXTENSION" ) );
00353 case IL_FILE_ALREADY_EXISTS: return( string( "IL_FILE_ALREADY_EXISTS" ) );
00354 case IL_OUT_FORMAT_SAME: return( string( "IL_OUT_FORMAT_SAME" ) );
00355 case IL_STACK_OVERFLOW: return( string( "IL_STACK_OVERFLOW" ) );
00356 case IL_STACK_UNDERFLOW: return( string( "IL_STACK_UNDERFLOW" ) );
00357 case IL_INVALID_CONVERSION: return( string( "IL_INVALID_CONVERSION" ) );
00358 case IL_BAD_DIMENSIONS: return( string( "IL_BAD_DIMENSIONS" ) );
00359 case IL_FILE_READ_ERROR: return( string( "IL_FILE_READ_ERROR" ) );
00360 case IL_LIB_GIF_ERROR: return( string( "IL_LIB_GIF_ERROR" ) );
00361 case IL_LIB_JPEG_ERROR: return( string( "IL_LIB_JPEG_ERROR" ) );
00362 case IL_LIB_PNG_ERROR: return( string( "IL_LIB_PNG_ERROR" ) );
00363 case IL_LIB_TIFF_ERROR: return( string( "IL_LIB_TIFF_ERROR" ) );
00364 case IL_LIB_MNG_ERROR: return( string( "IL_LIB_MNG_ERROR" ) );
00365 case IL_LIB_JP2_ERROR: return( string( "IL_LIB_JP2_ERROR" ) );
00366 case IL_LIB_EXR_ERROR: return( string( "IL_LIB_EXR_ERROR" ) );
00367 case IL_UNKNOWN_ERROR: return( string( "IL_UNKNOWN_ERROR" ) );
00368 default: return( string( "NO_ERROR" ) );
00369 }
00370 }
00371
00372 #endif
00373
00374 };
00375