PGMImage.cpp

Go to the documentation of this file.
00001 /* Import from Gabor API
00002 
00003 Copyright (c) 2002-3 Adriaan Tijsseling
00004 
00005 
00006                              All Rights Reserved
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program. If not, see <http://www.gnu.org/licenses/>.
00020 */
00021 
00022 /*
00023         Description:            class for reading and storing pgm images
00024         Author:                         Adriaan Tijsseling ( AGT )
00025         Copyright:                      ( c ) Copyright 2002-3 Adriaan Tijsseling. All rights reserved.
00026 */
00027 
00028 #include <cstring>
00029 #include "PGMImage.h"
00030 
00031 using namespace std; 
00032 
00033 namespace celeste
00034 {
00035 // read PGM image from file
00036 int PGMImage::Read( char* file )
00037 {
00038         int                     i,j;
00039         char            buf[256];
00040         ifstream        imgFile( file );
00041 
00042         if ( !imgFile ) // Invalid FileName
00043         {
00044                 cerr << "invalid filename: \"" << file << "\"" << endl;
00045                 exit(1);
00046                 return 0;
00047         }
00048         if ( mVerbosity ) cerr << "reading image from file \"" << file << "\"" << endl;
00049 
00050 // get file type
00051         imgFile.getline( mMagicNumber, 256 );
00052 
00053 // ignore comments
00054         imgFile.getline( buf, 256 );
00055         while ( buf[0] == '#' ) imgFile.getline( buf, 256 );
00056         
00057 // get dimensions of image
00058         mWidth = atoi( buf );
00059         mHeight = atoi( strpbrk( buf, " \t" ) );
00060         mNumPixels = mWidth * mHeight;
00061 
00062 // get color levels
00063         if ( mMagicNumber[1] == '1' || mMagicNumber[1] == '4' )
00064         {
00065                 mNumLevels = 1;
00066         }
00067         else
00068         {
00069                 imgFile.getline( buf, 256        );
00070                 mNumLevels = atoi( buf );
00071         }
00072 
00073 // determine number of bits given image level
00074         mNumBits = (int)( log( (float)( mNumLevels+2 ) )/log( 2.0 ) );
00075         if ( mVerbosity ) cerr << "[" << mNumBits << "-bit ";
00076 
00077 // read pixels
00078         if ( mMagicNumber[1] == '5' || mMagicNumber[1] == '2' )   // GrayScale
00079         {
00080         // allocate pixel storage
00081                 Allocate( kChars );
00082 
00083                 if ( mMagicNumber[1] == '5' )           // RAWBITs
00084                 {
00085                         if ( mVerbosity ) cerr << "GrayScale RAWBITs PGM format]";
00086                         for ( i = 0; i < mHeight; i++ )
00087                                 imgFile.read( (char *)mPixels[i], mWidth );
00088                 }
00089                 else                                                            // ASCII
00090                 {
00091                         if ( mVerbosity ) cerr << "GrayScale ASCII PGM format]";
00092                         for ( i = 0; i < mHeight; i++ )
00093                         {
00094                                 for ( j = 0; j < mWidth; j++ )
00095                                 {
00096                                         int pix;
00097                                         imgFile >> pix;
00098                                         mPixels[i][j] = (unsigned char)( pix / pow( 2, (double)(mNumBits-8) ) );
00099                                 }
00100                         }
00101                 }
00102         }
00103         else if ( mMagicNumber[1] == '6' || mMagicNumber[1] == '3' ) // RGB
00104         {
00105                 unsigned char rgb[3];
00106         // allocate rgb pixel storage
00107                 Allocate( kRGB );
00108                 
00109                 if ( mMagicNumber[1] == '6' )   // RAWBITs
00110                 {
00111                         if ( mVerbosity ) cerr << "RGB RAWBITs PPM format]";
00112                         for ( i = 0; i < mHeight; i++ )
00113                                 for ( j = 0; j < mWidth; j++ )
00114                                 {
00115                                         imgFile.read( (char *)rgb,3 );
00116                                         mRGB[0][i][j] = (int)rgb[0];
00117                                         mRGB[1][i][j] = (int)rgb[1];
00118                                         mRGB[2][i][j] = (int)rgb[2];
00119                                 }
00120                 }
00121                 else                                                    // ASCII
00122                 {
00123                         if ( mVerbosity ) cerr << "RGB ASCII PPM format]";
00124                         for ( i = 0; i < mHeight; i++ )
00125                                 for ( j = 0; j < mWidth; j++ )
00126                                 {
00127                                         imgFile >> mRGB[0][i][j];
00128                                         imgFile >> mRGB[1][i][j];
00129                                         imgFile >> mRGB[2][i][j];
00130                                 }
00131                 }
00132         }
00133         else if ( mMagicNumber[1] == '4' || mMagicNumber[1] == '1' ) // Binary
00134         {
00135         // allocate pixel storage
00136                 Allocate( kChars );
00137 
00138                 if ( mMagicNumber[1] == '4' )           // RAWBITs
00139                 {
00140                         if ( mVerbosity ) cerr << "Binary RAWBITs PBM format]";
00141                         for ( i = 0; i < mHeight; i++ )
00142                                 for ( j = 0; j < mWidth; j += 8 )
00143                                 {
00144                                         char pix[1];
00145                                         imgFile.read( pix, 1 );
00146                                         unsigned int x = (unsigned int)pix[0];
00147                                         for ( int k = 0; k < 8; k++ )
00148                                         {
00149                                                 unsigned int y = x/( (unsigned int)pow( 2, (double)(7-k) ) );
00150                                                 if ( y )
00151                                                         mPixels[i][j+k] = 0;
00152                                                 else
00153                                                         mPixels[i][j+k] = 255;
00154                                                 x -= y*( (unsigned int)pow( 2, (double)(7-k) ) );
00155                                         }
00156                                 }
00157                 }
00158                 else
00159                 {
00160                         if ( mVerbosity ) cerr << "Binary ASCII PBM format]";
00161                         for ( i = 0; i < mHeight; i++ )
00162                                 for ( j = 0; j < mWidth; j++ )
00163                                 {
00164                                         int pix;
00165                                         imgFile >> pix;
00166                                         if ( pix == 0 )
00167                                                 mPixels[i][j] = 0;
00168                                         else
00169                                                 mPixels[i][j] = 255;
00170                                 }
00171                 }
00172         }
00173 
00174         imgFile.close();
00175 
00176         if ( mVerbosity )
00177         {
00178                 cerr << endl;
00179                 cerr << "\twidth = " << mWidth << endl;
00180                 cerr << "\theight = " << mHeight << endl;
00181                 cerr << "\t#pixels = " << mNumPixels << endl;
00182         }
00183         mNumLevels = 255;
00184         mNumBits = 8;
00185         mMagicNumber[1] = '5';
00186 
00187         return 1;       // No error encountered....successful completion
00188 }
00189 
00190 
00191 // write PGM image to file
00192 void PGMImage::Write( char* file )
00193 {
00194         ofstream outfile( file );
00195 
00196         if ( mVerbosity )
00197         {
00198                 //cerr << "writing " << mWidth << "x" << mHeight;
00199                 //cerr << " image to file1 \"" << file << "\"...";
00200         }
00201         outfile << mMagicNumber[0] << mMagicNumber[1] << endl;  // 8-bit grayscale
00202         outfile << "# grayscale image" << endl;
00203         outfile << mWidth << " " << mHeight << endl;
00204         outfile << mNumLevels << endl;
00205 
00206         for ( int i = 0; i < mHeight; i++ )
00207                 outfile.write( (char *)mPixels[i], mWidth );
00208 
00209         outfile.close();
00210 
00211         //if ( mVerbosity ) cerr << "done" << endl;
00212 }
00213 
00214 
00215 // Write a PGM image in a file from output as is
00216 void PGMImage::Write( char* filename, float** output, int height, int width )
00217 {
00218         int i, j;
00219 
00220         // clear old data first
00221         Deallocate();
00222         
00223         // set dimensions of pixelmap and allocate memory
00224     mWidth = width;
00225     mHeight = height;
00226     mMagicNumber[0] = 'P'; 
00227     mMagicNumber[1] = '5';
00228     mNumLevels = 255;
00229         Allocate( kChars );
00230 
00231         for( i = 0; i < mHeight; i++ )
00232                 for( j = 0; j < mWidth; j++ )
00233                         mPixels[i][j] = (unsigned char)output[i][j];
00234 
00235     Write( filename );
00236 }
00237 
00238 
00239 // Write a color PPM image in a file
00240 void PGMImage::Write( char* filename, float*** pixels, int height, int width )
00241 {
00242         ofstream                outfile( filename );
00243         unsigned char   rgb[3];
00244         
00245         // set dimensions of pixelmap and allocate memory
00246         //if ( mVerbosity ) cerr << "writing " << width << "x" << height;
00247         //if ( mVerbosity ) cerr << " image to file2 \"" << filename << "\"...";
00248         outfile << "P6" << endl;  // 8-bit color
00249         outfile << "# color image" << endl;
00250         outfile << width << " " << height << endl;
00251         outfile << 255 << endl;
00252 
00253         for ( int i = 0; i < height; i++ )
00254                 for ( int j = 0; j < width; j++ )
00255                 {
00256                         rgb[0] = (unsigned char)(pixels[0][i][j]*255.0);
00257                         rgb[1] = (unsigned char)(pixels[1][i][j]*255.0);
00258                         rgb[2] = (unsigned char)(pixels[2][i][j]*255.0);
00259                         outfile.write( (char *)rgb, 3 );
00260                 }
00261 
00262         outfile.close();
00263 
00264         //if ( mVerbosity ) cerr << "done" << endl;
00265 }
00266 
00267 
00268 // Write a one-channel color PPM image in a file
00269 void PGMImage::Write( char* filename, float** pixels, int height, int width, int channel )
00270 {
00271         ofstream                outfile( filename );
00272         unsigned char   rgb[3];
00273     float                       max, min, maxmin;
00274         int                             i, j;
00275         
00276         // set dimensions of pixelmap and allocate memory
00277         //if ( mVerbosity ) cerr << "writing " << width << "x" << height;
00278         //if ( mVerbosity ) cerr << " image to file3 \"" << filename << "\"...";
00279         outfile << "P6" << endl;  // 8-bit color
00280         outfile << "# color image" << endl;
00281         outfile << width << " " << height << endl;
00282         outfile << 255 << endl;
00283 
00284         // original float values scaled to [0,255]
00285         max = min = pixels[0][0];
00286         for( i = 0; i < height; i++ )
00287                 for( j = 0; j < width; j++ )
00288                 {
00289                         if( pixels[i][j] > max ) max = pixels[i][j];
00290                         if( pixels[i][j] < min ) min = pixels[i][j];
00291                 }
00292         maxmin = max - min;
00293 
00294         if ( channel == 0 )
00295                 for ( i = 0; i < height; i++ )
00296                 {
00297                         for ( j = 0; j < width; j++ )
00298                         {
00299                                 rgb[0] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
00300                                 //(unsigned char)(pixels[i][j]*255.0);
00301                                 rgb[1] = 0;
00302                                 rgb[2] = 0;
00303                                 outfile.write( (char *)rgb, 3 );
00304                         }
00305                 }
00306         else if ( channel == 1 )
00307                 for ( i = 0; i < height; i++ )
00308                 {
00309                         for ( j = 0; j < width; j++ )
00310                         {
00311                                 rgb[0] = 0;
00312                                 rgb[1] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
00313                                 rgb[2] = 0;
00314                                 outfile.write( (char *)rgb, 3 );
00315                         }
00316                 }
00317         else
00318                 for ( i = 0; i < height; i++ )
00319                 {
00320                         for ( j = 0; j < width; j++ )
00321                         {
00322                                 rgb[0] = 0;
00323                                 rgb[1] = 0;
00324                                 rgb[2] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
00325                                 outfile.write( (char *)rgb, 3 );
00326                         }
00327                 }       
00328 
00329         outfile.close();
00330 
00331         //if ( mVerbosity ) cerr << "done" << endl;
00332 }
00333 
00334 
00335 // Write a PGM image in a file with output values scaled
00336 void PGMImage::WriteScaled( char* filename, float** output, int height, int width )
00337 {
00338     float       max, min, maxmin;
00339         int             i, j;
00340 
00341 // clear old data first
00342         Deallocate();
00343         
00344 // set dimensions of pixelmap and allocate memory
00345     mWidth = width;
00346     mHeight = height;
00347     mMagicNumber[0] = 'P';
00348     mMagicNumber[1] = '5';
00349     mNumLevels = 255;
00350         Allocate( kChars );
00351 
00352 // original float values scaled to [0,255]
00353         max = min = output[0][0];
00354         for( i = 0; i < mHeight; i++ )
00355                 for( j = 0; j < mWidth; j++ )
00356                 {
00357                         if( output[i][j] > max ) max = output[i][j];
00358                         if( output[i][j] < min ) min = output[i][j];
00359                 }
00360 
00361         maxmin = max - min;
00362         for( i = 0; i < mHeight; i++ )
00363                 for( j = 0; j < mWidth; j++ )
00364                         mPixels[i][j] = (unsigned char)(255.0 * ( (output[i][j] - min ) / maxmin ));
00365 
00366     Write( filename );
00367 }
00368 
00369 }; // namespace

Generated on 20 Oct 2014 for Hugintrunk by  doxygen 1.4.7