Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

ppm_image.cpp

00001 //FILE:         ppm_image.cpp
00002 //AUTHOR:       Nathan Cournia <nathan@cournia.com>
00003 
00004 #include <fstream>
00005 #include "ppm_image.h"
00006 
00008 image::image_t*
00009 image::ppm::load( const std::string& filename )
00010 {
00011         //open file
00012         std::ifstream stream( filename.c_str( ) );
00013         if( !stream ) {
00014                 //could not open file
00015                 return NULL;
00016         }
00017 
00018         //load the file
00019         image_t* img = load( stream );
00020 
00021         //close the file
00022         stream.close( );
00023 
00024         //return the image
00025         return img;
00026 }
00027 
00029 image::image_t*
00030 image::ppm::load( std::istream& stream )
00031 {
00032         //local vars
00033         char c;
00034 
00035         //first byte must be a 'P'
00036         stream.read( &c, 1 );
00037         if( c != 'P' ) return NULL;
00038 
00039         //next byte is a number
00040         stream.read( &c, 1 );
00041         if( c == '2' ) {
00042                 return load_ascii_pgm( stream );
00043         } else if( c == '3' ) {
00044                 return load_ascii_ppm( stream );
00045         } else if( c == '5' ) {
00046                 return load_binary_pgm( stream );
00047         } else if( c == '6' ) {
00048                 return load_binary_ppm( stream );
00049         } else {
00050                 return NULL;
00051         }
00052 }
00053 
00055 bool
00056 image::ppm::can_load( const std::string& filename )
00057 {
00058         //open file
00059         std::ifstream stream( filename.c_str( ) );
00060         if( !stream ) {
00061                 //could not open file
00062                 return false;
00063         }
00064 
00065         //load the file
00066         bool loadable = can_load( stream );
00067 
00068         //close the file
00069         stream.close( );
00070 
00071         //return status
00072         return loadable;
00073 }
00074 
00076 bool
00077 image::ppm::can_load( std::istream& stream )
00078 {
00079         //local vars
00080         char c;
00081 
00082         //save current position in stream
00083         std::streampos save = stream.tellg( );
00084 
00085         //first byte must be a 'P'
00086         stream.read( &c, 1 );
00087         if( c != 'P' ) return false;
00088 
00089         //next byte is a number
00090         stream.read( &c, 1 );
00091 
00092         //return current position to saved value
00093         stream.seekg( save );
00094         
00095         if( (c == '2') || (c == '3') || (c == '5') || (c == '6') ) {
00096                 return true;
00097         }
00098 
00099         //format unknown
00100         return false;
00101 }
00102 
00104 image::image_t*
00105 image::ppm::load_ascii_pgm( std::istream& stream )
00106 {
00107         //local vars
00108         std::string line;
00109         unsigned int rows, cols, pixels;
00110         float max, g;
00111         unsigned int gn;
00112         
00113         //get rest of the magic number line
00114         getline( stream, line );
00115 
00116         //next line can be a comment
00117         while( stream.peek( ) == '#' ) {
00118                 //this line is a comment
00119                 getline( stream, line );
00120         }
00121         
00122         //read in width
00123         if( !(stream >> cols) ) return NULL;
00124 
00125         //read in height
00126         if( !(stream >> rows) ) return NULL;
00127 
00128         //read in max value
00129         if( !(stream >> max) ) return NULL;
00130         if( max == 0.0 ) return NULL;
00131 
00132         //create the image
00133         image_t *img = new image_t( cols, rows, image_t::GREYSCALE, image_t::BYTE );
00134         img->seek( 0, 0 );
00135 
00136         //read in each pixel
00137         pixels = rows * cols;
00138         for( unsigned int i = 0; i < pixels; ++i ) {
00139                 if( !(stream >> g) ) {
00140                         //either not enough data, or corrupt data
00141                         delete img;
00142                         return NULL;
00143                 }
00144 
00145                 //normalize and scale colors;
00146                 gn = static_cast<unsigned int>(g / max * 255.0);
00147 
00148                 //set pixel
00149                 img->write( gn );
00150         }
00151 
00152         //all done
00153         return img;
00154 }
00155 
00157 image::image_t*
00158 image::ppm::load_ascii_ppm( std::istream& stream )
00159 {
00160         //local vars
00161         std::string line;
00162         unsigned int rows, cols, pixels;
00163         float max, r, g, b;
00164         unsigned int rn, gn, bn;
00165         
00166         //get rest of the magic number line
00167         getline( stream, line );
00168 
00169         //next line can be a comment
00170         while( stream.peek( ) == '#' ) {
00171                 //this line is a comment
00172                 getline( stream, line );
00173         }
00174         
00175         //read in width
00176         if( !(stream >> cols) ) return NULL;
00177 
00178         //read in height
00179         if( !(stream >> rows) ) return NULL;
00180 
00181         //read in max value
00182         if( !(stream >> max) ) return NULL;
00183         if( max == 0.0 ) return NULL;
00184 
00185         //create the image
00186         image_t *img = new image_t( cols, rows, image_t::RGB, image_t::BYTE );
00187         img->seek( 0, 0 );
00188 
00189         //read in each pixel
00190         pixels = rows * cols;
00191         for( unsigned int i = 0; i < pixels; ++i ) {
00192                 if( !(stream >> r >> g >> b) ) {
00193                         //either not enough data, or corrupt data
00194                         delete img;
00195                         return NULL;
00196                 }
00197 
00198                 //normalize and scale colors;
00199                 rn = static_cast<unsigned int>(r / max * 255.0);
00200                 gn = static_cast<unsigned int>(g / max * 255.0);
00201                 bn = static_cast<unsigned int>(b / max * 255.0);
00202 
00203                 //set pixel
00204                 img->write( rn, gn, bn );
00205         }
00206 
00207         //all done
00208         return img;
00209 }
00210 
00212 image::image_t*
00213 image::ppm::load_binary_pgm( std::istream& stream )
00214 {
00215         //local vars
00216         std::string line;
00217         unsigned int rows, cols, pixels;
00218         float max; 
00219         char g;
00220         unsigned int gn;
00221         
00222         //get rest of the magic number line
00223         getline( stream, line );
00224 
00225         //next line can be a comment
00226         while( stream.peek( ) == '#' ) {
00227                 //this line is a comment
00228                 getline( stream, line );
00229         }
00230         
00231         //read in width
00232         if( !(stream >> cols) ) return NULL;
00233 
00234         //read in height
00235         if( !(stream >> rows) ) return NULL;
00236 
00237         //read in max value
00238         if( !(stream >> max) ) return NULL;
00239         if( max == 0.0 ) return NULL;
00240 
00241         //read in rest of max value line
00242         getline( stream, line );
00243 
00244         //create the image
00245         image_t *img = new image_t( cols, rows, image_t::GREYSCALE, image_t::BYTE );
00246         img->seek( 0, 0 );
00247 
00248         //read in each pixel
00249         pixels = rows * cols;
00250         for( unsigned int i = 0; i < pixels; ++i ) {
00251                 if( !stream.read( &g, 1 ) ) {
00252                         //either not enough data, or corrupt data
00253                         delete img;
00254                         return NULL;
00255                 }
00256 
00257                 //normalize and scale colors;
00258                 gn = static_cast<unsigned int>(static_cast<unsigned char>( g ) / max * 255.0);
00259 
00260                 //set pixel
00261                 img->write( gn );
00262         }
00263 
00264         //all done
00265         return img;
00266 }
00267 
00269 image::image_t*
00270 image::ppm::load_binary_ppm( std::istream& stream )
00271 {
00272         //local vars
00273         std::string line;
00274         unsigned int rows, cols, pixels;
00275         float max; 
00276         char r, g, b;
00277         unsigned int rn, gn, bn;
00278         
00279         //get rest of the magic number line
00280         getline( stream, line );
00281 
00282         //next line can be a comment
00283         while( stream.peek( ) == '#' ) {
00284                 //this line is a comment
00285                 getline( stream, line );
00286         }
00287         
00288         //read in width
00289         if( !(stream >> cols) ) return NULL;
00290 
00291         //read in height
00292         if( !(stream >> rows) ) return NULL;
00293 
00294         //read in max value
00295         if( !(stream >> max) ) return NULL;
00296         if( max == 0.0 ) return NULL;
00297 
00298         //read in rest of max value line
00299         getline( stream, line );
00300 
00301         //create the image
00302         image_t *img = new image_t( cols, rows, image_t::RGB, image_t::BYTE );
00303         img->seek( 0, 0 );
00304 
00305         //read in each pixel
00306         pixels = rows * cols;
00307         for( unsigned int i = 0; i < pixels; ++i ) {
00308                 if( !(stream.read( &r, 1 ) &&
00309                         stream.read( &g, 1 ) &&
00310                         stream.read( &b, 1 )) ) {
00311                         //either not enough data, or corrupt data
00312                         delete img;
00313                         return NULL;
00314                 }
00315 
00316                 //normalize and scale colors;
00317                 rn = static_cast<unsigned int>(static_cast<unsigned char>( r ) / max * 255.0);
00318                 gn = static_cast<unsigned int>(static_cast<unsigned char>( g ) / max * 255.0);
00319                 bn = static_cast<unsigned int>(static_cast<unsigned char>( b ) / max * 255.0);
00320 
00321                 //set pixel
00322                 img->write( rn, gn, bn );
00323         }
00324 
00325         //all done
00326         return img;
00327 }

Generated on Tue Feb 11 18:49:41 2003 for uber by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002