00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <cstring>
00029 #include "PGMImage.h"
00030
00031 using namespace std;
00032
00033 namespace celeste
00034 {
00035
00036 int PGMImage::Read( char* file )
00037 {
00038 int i,j;
00039 char buf[256];
00040 ifstream imgFile( file );
00041
00042 if ( !imgFile )
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
00051 imgFile.getline( mMagicNumber, 256 );
00052
00053
00054 imgFile.getline( buf, 256 );
00055 while ( buf[0] == '#' ) imgFile.getline( buf, 256 );
00056
00057
00058 mWidth = atoi( buf );
00059 mHeight = atoi( strpbrk( buf, " \t" ) );
00060 mNumPixels = mWidth * mHeight;
00061
00062
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
00074 mNumBits = (int)( log( (float)( mNumLevels+2 ) )/log( 2.0 ) );
00075 if ( mVerbosity ) cerr << "[" << mNumBits << "-bit ";
00076
00077
00078 if ( mMagicNumber[1] == '5' || mMagicNumber[1] == '2' )
00079 {
00080
00081 Allocate( kChars );
00082
00083 if ( mMagicNumber[1] == '5' )
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
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' )
00104 {
00105 unsigned char rgb[3];
00106
00107 Allocate( kRGB );
00108
00109 if ( mMagicNumber[1] == '6' )
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
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' )
00134 {
00135
00136 Allocate( kChars );
00137
00138 if ( mMagicNumber[1] == '4' )
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;
00188 }
00189
00190
00191
00192 void PGMImage::Write( char* file )
00193 {
00194 ofstream outfile( file );
00195
00196 if ( mVerbosity )
00197 {
00198
00199
00200 }
00201 outfile << mMagicNumber[0] << mMagicNumber[1] << endl;
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
00212 }
00213
00214
00215
00216 void PGMImage::Write( char* filename, float** output, int height, int width )
00217 {
00218 int i, j;
00219
00220
00221 Deallocate();
00222
00223
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
00240 void PGMImage::Write( char* filename, float*** pixels, int height, int width )
00241 {
00242 ofstream outfile( filename );
00243 unsigned char rgb[3];
00244
00245
00246
00247
00248 outfile << "P6" << endl;
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
00265 }
00266
00267
00268
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
00277
00278
00279 outfile << "P6" << endl;
00280 outfile << "# color image" << endl;
00281 outfile << width << " " << height << endl;
00282 outfile << 255 << endl;
00283
00284
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
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
00332 }
00333
00334
00335
00336 void PGMImage::WriteScaled( char* filename, float** output, int height, int width )
00337 {
00338 float max, min, maxmin;
00339 int i, j;
00340
00341
00342 Deallocate();
00343
00344
00345 mWidth = width;
00346 mHeight = height;
00347 mMagicNumber[0] = 'P';
00348 mMagicNumber[1] = '5';
00349 mNumLevels = 255;
00350 Allocate( kChars );
00351
00352
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 };