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 namespace celeste
00032 {
00033 // read PGM image from file
00034 int PGMImage::Read( char* file )
00035 {
00036         int                     i,j;
00037         char            buf[256];
00038         std::ifstream   imgFile( file );
00039 
00040         if ( !imgFile ) // Invalid FileName
00041         {
00042                 std::cerr << "invalid filename: \"" << file << "\"" << std::endl;
00043                 exit(1);
00044                 return 0;
00045         }
00046         if ( mVerbosity ) std::cerr << "reading image from file \"" << file << "\"" << std::endl;
00047 
00048 // get file type
00049         imgFile.getline( mMagicNumber, 256 );
00050 
00051 // ignore comments
00052         imgFile.getline( buf, 256 );
00053         while ( buf[0] == '#' ) imgFile.getline( buf, 256 );
00054         
00055 // get dimensions of image
00056         mWidth = atoi( buf );
00057         mHeight = atoi( strpbrk( buf, " \t" ) );
00058         mNumPixels = mWidth * mHeight;
00059 
00060 // get color levels
00061         if ( mMagicNumber[1] == '1' || mMagicNumber[1] == '4' )
00062         {
00063                 mNumLevels = 1;
00064         }
00065         else
00066         {
00067                 imgFile.getline( buf, 256        );
00068                 mNumLevels = atoi( buf );
00069         }
00070 
00071 // determine number of bits given image level
00072         mNumBits = (int)( log( (float)( mNumLevels+2 ) )/log( 2.0 ) );
00073         if ( mVerbosity ) std::cerr << "[" << mNumBits << "-bit ";
00074 
00075 // read pixels
00076         if ( mMagicNumber[1] == '5' || mMagicNumber[1] == '2' )   // GrayScale
00077         {
00078         // allocate pixel storage
00079                 Allocate( kChars );
00080 
00081                 if ( mMagicNumber[1] == '5' )           // RAWBITs
00082                 {
00083                         if ( mVerbosity ) std::cerr << "GrayScale RAWBITs PGM format]";
00084                         for ( i = 0; i < mHeight; i++ )
00085                                 imgFile.read( (char *)mPixels[i], mWidth );
00086                 }
00087                 else                                                            // ASCII
00088                 {
00089                         if ( mVerbosity ) std::cerr << "GrayScale ASCII PGM format]";
00090                         for ( i = 0; i < mHeight; i++ )
00091                         {
00092                                 for ( j = 0; j < mWidth; j++ )
00093                                 {
00094                                         int pix;
00095                                         imgFile >> pix;
00096                                         mPixels[i][j] = (unsigned char)( pix / pow( 2, (double)(mNumBits-8) ) );
00097                                 }
00098                         }
00099                 }
00100         }
00101         else if ( mMagicNumber[1] == '6' || mMagicNumber[1] == '3' ) // RGB
00102         {
00103         // allocate rgb pixel storage
00104                 Allocate( kRGB );
00105                 
00106                 if ( mMagicNumber[1] == '6' )   // RAWBITs
00107                 {
00108                         if ( mVerbosity ) std::cerr << "RGB RAWBITs PPM format]";
00109                         for ( i = 0; i < mHeight; i++ )
00110                                 for ( j = 0; j < mWidth; j++ )
00111                                 {
00112                                         unsigned char rgb[3];
00113                                         imgFile.read( (char *)rgb,3 );
00114                                         mRGB[0][i][j] = (int)rgb[0];
00115                                         mRGB[1][i][j] = (int)rgb[1];
00116                                         mRGB[2][i][j] = (int)rgb[2];
00117                                 }
00118                 }
00119                 else                                                    // ASCII
00120                 {
00121                         if ( mVerbosity ) std::cerr << "RGB ASCII PPM format]";
00122                         for ( i = 0; i < mHeight; i++ )
00123                                 for ( j = 0; j < mWidth; j++ )
00124                                 {
00125                                         imgFile >> mRGB[0][i][j];
00126                                         imgFile >> mRGB[1][i][j];
00127                                         imgFile >> mRGB[2][i][j];
00128                                 }
00129                 }
00130         }
00131         else if ( mMagicNumber[1] == '4' || mMagicNumber[1] == '1' ) // Binary
00132         {
00133         // allocate pixel storage
00134                 Allocate( kChars );
00135 
00136                 if ( mMagicNumber[1] == '4' )           // RAWBITs
00137                 {
00138                         if ( mVerbosity ) std::cerr << "Binary RAWBITs PBM format]";
00139                         for ( i = 0; i < mHeight; i++ )
00140                                 for ( j = 0; j < mWidth; j += 8 )
00141                                 {
00142                                         char pix[1];
00143                                         imgFile.read( pix, 1 );
00144                                         unsigned int x = (unsigned int)pix[0];
00145                                         for ( int k = 0; k < 8; k++ )
00146                                         {
00147                                                 unsigned int y = x/( (unsigned int)pow( 2, (double)(7-k) ) );
00148                                                 if ( y )
00149                                                         mPixels[i][j+k] = 0;
00150                                                 else
00151                                                         mPixels[i][j+k] = 255;
00152                                                 x -= y*( (unsigned int)pow( 2, (double)(7-k) ) );
00153                                         }
00154                                 }
00155                 }
00156                 else
00157                 {
00158                         if ( mVerbosity ) std::cerr << "Binary ASCII PBM format]";
00159                         for ( i = 0; i < mHeight; i++ )
00160                                 for ( j = 0; j < mWidth; j++ )
00161                                 {
00162                                         int pix;
00163                                         imgFile >> pix;
00164                                         if ( pix == 0 )
00165                                                 mPixels[i][j] = 0;
00166                                         else
00167                                                 mPixels[i][j] = 255;
00168                                 }
00169                 }
00170         }
00171 
00172         imgFile.close();
00173 
00174         if ( mVerbosity )
00175         {
00176                 std::cerr << std::endl;
00177                 std::cerr << "\twidth = " << mWidth << std::endl;
00178                 std::cerr << "\theight = " << mHeight << std::endl;
00179                 std::cerr << "\t#pixels = " << mNumPixels << std::endl;
00180         }
00181         mNumLevels = 255;
00182         mNumBits = 8;
00183         mMagicNumber[1] = '5';
00184 
00185         return 1;       // No error encountered....successful completion
00186 }
00187 
00188 
00189 // write PGM image to file
00190 void PGMImage::Write( char* file )
00191 {
00192         std::ofstream outfile( file );
00193 
00194         if ( mVerbosity )
00195         {
00196                 //std::cerr << "writing " << mWidth << "x" << mHeight;
00197                 //std::cerr << " image to file1 \"" << file << "\"...";
00198         }
00199         outfile << mMagicNumber[0] << mMagicNumber[1] << std::endl;  // 8-bit grayscale
00200         outfile << "# grayscale image" << std::endl;
00201         outfile << mWidth << " " << mHeight << std::endl;
00202         outfile << mNumLevels << std::endl;
00203 
00204         for ( int i = 0; i < mHeight; i++ )
00205                 outfile.write( (char *)mPixels[i], mWidth );
00206 
00207         outfile.close();
00208 
00209         //if ( mVerbosity ) std::cerr << "done" << std::endl;
00210 }
00211 
00212 
00213 // Write a PGM image in a file from output as is
00214 void PGMImage::Write( char* filename, float** output, int height, int width )
00215 {
00216         int i, j;
00217 
00218         // clear old data first
00219         Deallocate();
00220         
00221         // set dimensions of pixelmap and allocate memory
00222     mWidth = width;
00223     mHeight = height;
00224     mMagicNumber[0] = 'P'; 
00225     mMagicNumber[1] = '5';
00226     mNumLevels = 255;
00227         Allocate( kChars );
00228 
00229         for( i = 0; i < mHeight; i++ )
00230                 for( j = 0; j < mWidth; j++ )
00231                         mPixels[i][j] = (unsigned char)output[i][j];
00232 
00233     Write( filename );
00234 }
00235 
00236 
00237 // Write a color PPM image in a file
00238 void PGMImage::Write( char* filename, float*** pixels, int height, int width )
00239 {
00240         std::ofstream outfile( filename );
00241         unsigned char   rgb[3];
00242         
00243         // set dimensions of pixelmap and allocate memory
00244         //if ( mVerbosity ) std::cerr << "writing " << width << "x" << height;
00245         //if ( mVerbosity ) std::cerr << " image to file2 \"" << filename << "\"...";
00246         outfile << "P6" << std::endl;  // 8-bit color
00247         outfile << "# color image" << std::endl;
00248         outfile << width << " " << height << std::endl;
00249         outfile << 255 << std::endl;
00250 
00251         for ( int i = 0; i < height; i++ )
00252                 for ( int j = 0; j < width; j++ )
00253                 {
00254                         rgb[0] = (unsigned char)(pixels[0][i][j]*255.0);
00255                         rgb[1] = (unsigned char)(pixels[1][i][j]*255.0);
00256                         rgb[2] = (unsigned char)(pixels[2][i][j]*255.0);
00257                         outfile.write( (char *)rgb, 3 );
00258                 }
00259 
00260         outfile.close();
00261 
00262         //if ( mVerbosity ) std::cerr << "done" << std::endl;
00263 }
00264 
00265 
00266 // Write a one-channel color PPM image in a file
00267 void PGMImage::Write( char* filename, float** pixels, int height, int width, int channel )
00268 {
00269         std::ofstream outfile( filename );
00270         unsigned char   rgb[3];
00271     float                       max, min, maxmin;
00272         int                             i, j;
00273         
00274         // set dimensions of pixelmap and allocate memory
00275         //if ( mVerbosity ) std::cerr << "writing " << width << "x" << height;
00276         //if ( mVerbosity ) std::cerr << " image to file3 \"" << filename << "\"...";
00277         outfile << "P6" << std::endl;  // 8-bit color
00278         outfile << "# color image" << std::endl;
00279         outfile << width << " " << height << std::endl;
00280         outfile << 255 << std::endl;
00281 
00282         // original float values scaled to [0,255]
00283         max = min = pixels[0][0];
00284         for( i = 0; i < height; i++ )
00285                 for( j = 0; j < width; j++ )
00286                 {
00287                         if( pixels[i][j] > max ) max = pixels[i][j];
00288                         if( pixels[i][j] < min ) min = pixels[i][j];
00289                 }
00290         maxmin = max - min;
00291 
00292         if ( channel == 0 )
00293                 for ( i = 0; i < height; i++ )
00294                 {
00295                         for ( j = 0; j < width; j++ )
00296                         {
00297                                 rgb[0] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
00298                                 //(unsigned char)(pixels[i][j]*255.0);
00299                                 rgb[1] = 0;
00300                                 rgb[2] = 0;
00301                                 outfile.write( (char *)rgb, 3 );
00302                         }
00303                 }
00304         else if ( channel == 1 )
00305                 for ( i = 0; i < height; i++ )
00306                 {
00307                         for ( j = 0; j < width; j++ )
00308                         {
00309                                 rgb[0] = 0;
00310                                 rgb[1] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
00311                                 rgb[2] = 0;
00312                                 outfile.write( (char *)rgb, 3 );
00313                         }
00314                 }
00315         else
00316                 for ( i = 0; i < height; i++ )
00317                 {
00318                         for ( j = 0; j < width; j++ )
00319                         {
00320                                 rgb[0] = 0;
00321                                 rgb[1] = 0;
00322                                 rgb[2] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
00323                                 outfile.write( (char *)rgb, 3 );
00324                         }
00325                 }       
00326 
00327         outfile.close();
00328 
00329         //if ( mVerbosity ) std::cerr << "done" << std::endl;
00330 }
00331 
00332 
00333 // Write a PGM image in a file with output values scaled
00334 void PGMImage::WriteScaled( char* filename, float** output, int height, int width )
00335 {
00336     float       max, min, maxmin;
00337         int             i, j;
00338 
00339 // clear old data first
00340         Deallocate();
00341         
00342 // set dimensions of pixelmap and allocate memory
00343     mWidth = width;
00344     mHeight = height;
00345     mMagicNumber[0] = 'P';
00346     mMagicNumber[1] = '5';
00347     mNumLevels = 255;
00348         Allocate( kChars );
00349 
00350 // original float values scaled to [0,255]
00351         max = min = output[0][0];
00352         for( i = 0; i < mHeight; i++ )
00353                 for( j = 0; j < mWidth; j++ )
00354                 {
00355                         if( output[i][j] > max ) max = output[i][j];
00356                         if( output[i][j] < min ) min = output[i][j];
00357                 }
00358 
00359         maxmin = max - min;
00360         for( i = 0; i < mHeight; i++ )
00361                 for( j = 0; j < mWidth; j++ )
00362                         mPixels[i][j] = (unsigned char)(255.0 * ( (output[i][j] - min ) / maxmin ));
00363 
00364     Write( filename );
00365 }
00366 
00367 }; // namespace

Generated on 8 Feb 2016 for Hugintrunk by  doxygen 1.4.7