Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PGMImage.cpp
Go to the documentation of this file.
1 /* Import from Gabor API
2 
3 Copyright (c) 2002-3 Adriaan Tijsseling
4 
5 
6  All Rights Reserved
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 /*
23  Description: class for reading and storing pgm images
24  Author: Adriaan Tijsseling ( AGT )
25  Copyright: ( c ) Copyright 2002-3 Adriaan Tijsseling. All rights reserved.
26 */
27 
28 #include <cstring>
29 #include "PGMImage.h"
30 
31 namespace celeste
32 {
33 // read PGM image from file
34 int PGMImage::Read( char* file )
35 {
36  int i,j;
37  char buf[256];
38  std::ifstream imgFile( file );
39 
40  if ( !imgFile ) // Invalid FileName
41  {
42  std::cerr << "invalid filename: \"" << file << "\"" << std::endl;
43  exit(1);
44  return 0;
45  }
46  if ( mVerbosity ) std::cerr << "reading image from file \"" << file << "\"" << std::endl;
47 
48 // get file type
49  imgFile.getline( mMagicNumber, 256 );
50 
51 // ignore comments
52  imgFile.getline( buf, 256 );
53  while ( buf[0] == '#' ) imgFile.getline( buf, 256 );
54 
55 // get dimensions of image
56  mWidth = atoi( buf );
57  mHeight = atoi( strpbrk( buf, " \t" ) );
59 
60 // get color levels
61  if ( mMagicNumber[1] == '1' || mMagicNumber[1] == '4' )
62  {
63  mNumLevels = 1;
64  }
65  else
66  {
67  imgFile.getline( buf, 256 );
68  mNumLevels = atoi( buf );
69  }
70 
71 // determine number of bits given image level
72  mNumBits = (int)( log( (float)( mNumLevels+2 ) )/log( 2.0 ) );
73  if ( mVerbosity ) std::cerr << "[" << mNumBits << "-bit ";
74 
75 // read pixels
76  if ( mMagicNumber[1] == '5' || mMagicNumber[1] == '2' ) // GrayScale
77  {
78  // allocate pixel storage
79  Allocate( kChars );
80 
81  if ( mMagicNumber[1] == '5' ) // RAWBITs
82  {
83  if ( mVerbosity ) std::cerr << "GrayScale RAWBITs PGM format]";
84  for ( i = 0; i < mHeight; i++ )
85  imgFile.read( (char *)mPixels[i], mWidth );
86  }
87  else // ASCII
88  {
89  if ( mVerbosity ) std::cerr << "GrayScale ASCII PGM format]";
90  for ( i = 0; i < mHeight; i++ )
91  {
92  for ( j = 0; j < mWidth; j++ )
93  {
94  int pix;
95  imgFile >> pix;
96  mPixels[i][j] = (unsigned char)( pix / pow( 2, (double)(mNumBits-8) ) );
97  }
98  }
99  }
100  }
101  else if ( mMagicNumber[1] == '6' || mMagicNumber[1] == '3' ) // RGB
102  {
103  // allocate rgb pixel storage
104  Allocate( kRGB );
105 
106  if ( mMagicNumber[1] == '6' ) // RAWBITs
107  {
108  if ( mVerbosity ) std::cerr << "RGB RAWBITs PPM format]";
109  for ( i = 0; i < mHeight; i++ )
110  for ( j = 0; j < mWidth; j++ )
111  {
112  unsigned char rgb[3];
113  imgFile.read( (char *)rgb,3 );
114  mRGB[0][i][j] = (int)rgb[0];
115  mRGB[1][i][j] = (int)rgb[1];
116  mRGB[2][i][j] = (int)rgb[2];
117  }
118  }
119  else // ASCII
120  {
121  if ( mVerbosity ) std::cerr << "RGB ASCII PPM format]";
122  for ( i = 0; i < mHeight; i++ )
123  for ( j = 0; j < mWidth; j++ )
124  {
125  imgFile >> mRGB[0][i][j];
126  imgFile >> mRGB[1][i][j];
127  imgFile >> mRGB[2][i][j];
128  }
129  }
130  }
131  else if ( mMagicNumber[1] == '4' || mMagicNumber[1] == '1' ) // Binary
132  {
133  // allocate pixel storage
134  Allocate( kChars );
135 
136  if ( mMagicNumber[1] == '4' ) // RAWBITs
137  {
138  if ( mVerbosity ) std::cerr << "Binary RAWBITs PBM format]";
139  for ( i = 0; i < mHeight; i++ )
140  for ( j = 0; j < mWidth; j += 8 )
141  {
142  char pix[1];
143  imgFile.read( pix, 1 );
144  unsigned int x = (unsigned int)pix[0];
145  for ( int k = 0; k < 8; k++ )
146  {
147  unsigned int y = x/( (unsigned int)pow( 2, (double)(7-k) ) );
148  if ( y )
149  mPixels[i][j+k] = 0;
150  else
151  mPixels[i][j+k] = 255;
152  x -= y*( (unsigned int)pow( 2, (double)(7-k) ) );
153  }
154  }
155  }
156  else
157  {
158  if ( mVerbosity ) std::cerr << "Binary ASCII PBM format]";
159  for ( i = 0; i < mHeight; i++ )
160  for ( j = 0; j < mWidth; j++ )
161  {
162  int pix;
163  imgFile >> pix;
164  if ( pix == 0 )
165  mPixels[i][j] = 0;
166  else
167  mPixels[i][j] = 255;
168  }
169  }
170  }
171 
172  imgFile.close();
173 
174  if ( mVerbosity )
175  {
176  std::cerr << std::endl;
177  std::cerr << "\twidth = " << mWidth << std::endl;
178  std::cerr << "\theight = " << mHeight << std::endl;
179  std::cerr << "\t#pixels = " << mNumPixels << std::endl;
180  }
181  mNumLevels = 255;
182  mNumBits = 8;
183  mMagicNumber[1] = '5';
184 
185  return 1; // No error encountered....successful completion
186 }
187 
188 
189 // write PGM image to file
190 void PGMImage::Write( char* file )
191 {
192  std::ofstream outfile( file );
193 
194  if ( mVerbosity )
195  {
196  //std::cerr << "writing " << mWidth << "x" << mHeight;
197  //std::cerr << " image to file1 \"" << file << "\"...";
198  }
199  outfile << mMagicNumber[0] << mMagicNumber[1] << std::endl; // 8-bit grayscale
200  outfile << "# grayscale image" << std::endl;
201  outfile << mWidth << " " << mHeight << std::endl;
202  outfile << mNumLevels << std::endl;
203 
204  for ( int i = 0; i < mHeight; i++ )
205  outfile.write( (char *)mPixels[i], mWidth );
206 
207  outfile.close();
208 
209  //if ( mVerbosity ) std::cerr << "done" << std::endl;
210 }
211 
212 
213 // Write a PGM image in a file from output as is
214 void PGMImage::Write( char* filename, float** output, int height, int width )
215 {
216  int i, j;
217 
218  // clear old data first
219  Deallocate();
220 
221  // set dimensions of pixelmap and allocate memory
222  mWidth = width;
223  mHeight = height;
224  mMagicNumber[0] = 'P';
225  mMagicNumber[1] = '5';
226  mNumLevels = 255;
227  Allocate( kChars );
228 
229  for( i = 0; i < mHeight; i++ )
230  for( j = 0; j < mWidth; j++ )
231  mPixels[i][j] = (unsigned char)output[i][j];
232 
233  Write( filename );
234 }
235 
236 
237 // Write a color PPM image in a file
238 void PGMImage::Write( char* filename, float*** pixels, int height, int width )
239 {
240  std::ofstream outfile( filename );
241  unsigned char rgb[3];
242 
243  // set dimensions of pixelmap and allocate memory
244  //if ( mVerbosity ) std::cerr << "writing " << width << "x" << height;
245  //if ( mVerbosity ) std::cerr << " image to file2 \"" << filename << "\"...";
246  outfile << "P6" << std::endl; // 8-bit color
247  outfile << "# color image" << std::endl;
248  outfile << width << " " << height << std::endl;
249  outfile << 255 << std::endl;
250 
251  for ( int i = 0; i < height; i++ )
252  for ( int j = 0; j < width; j++ )
253  {
254  rgb[0] = (unsigned char)(pixels[0][i][j]*255.0);
255  rgb[1] = (unsigned char)(pixels[1][i][j]*255.0);
256  rgb[2] = (unsigned char)(pixels[2][i][j]*255.0);
257  outfile.write( (char *)rgb, 3 );
258  }
259 
260  outfile.close();
261 
262  //if ( mVerbosity ) std::cerr << "done" << std::endl;
263 }
264 
265 
266 // Write a one-channel color PPM image in a file
267 void PGMImage::Write( char* filename, float** pixels, int height, int width, int channel )
268 {
269  std::ofstream outfile( filename );
270  unsigned char rgb[3];
271  float max, min, maxmin;
272  int i, j;
273 
274  // set dimensions of pixelmap and allocate memory
275  //if ( mVerbosity ) std::cerr << "writing " << width << "x" << height;
276  //if ( mVerbosity ) std::cerr << " image to file3 \"" << filename << "\"...";
277  outfile << "P6" << std::endl; // 8-bit color
278  outfile << "# color image" << std::endl;
279  outfile << width << " " << height << std::endl;
280  outfile << 255 << std::endl;
281 
282  // original float values scaled to [0,255]
283  max = min = pixels[0][0];
284  for( i = 0; i < height; i++ )
285  for( j = 0; j < width; j++ )
286  {
287  if( pixels[i][j] > max ) max = pixels[i][j];
288  if( pixels[i][j] < min ) min = pixels[i][j];
289  }
290  maxmin = max - min;
291 
292  if ( channel == 0 )
293  for ( i = 0; i < height; i++ )
294  {
295  for ( j = 0; j < width; j++ )
296  {
297  rgb[0] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
298  //(unsigned char)(pixels[i][j]*255.0);
299  rgb[1] = 0;
300  rgb[2] = 0;
301  outfile.write( (char *)rgb, 3 );
302  }
303  }
304  else if ( channel == 1 )
305  for ( i = 0; i < height; i++ )
306  {
307  for ( j = 0; j < width; j++ )
308  {
309  rgb[0] = 0;
310  rgb[1] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
311  rgb[2] = 0;
312  outfile.write( (char *)rgb, 3 );
313  }
314  }
315  else
316  for ( i = 0; i < height; i++ )
317  {
318  for ( j = 0; j < width; j++ )
319  {
320  rgb[0] = 0;
321  rgb[1] = 0;
322  rgb[2] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
323  outfile.write( (char *)rgb, 3 );
324  }
325  }
326 
327  outfile.close();
328 
329  //if ( mVerbosity ) std::cerr << "done" << std::endl;
330 }
331 
332 
333 // Write a PGM image in a file with output values scaled
334 void PGMImage::WriteScaled( char* filename, float** output, int height, int width )
335 {
336  float max, min, maxmin;
337  int i, j;
338 
339 // clear old data first
340  Deallocate();
341 
342 // set dimensions of pixelmap and allocate memory
343  mWidth = width;
344  mHeight = height;
345  mMagicNumber[0] = 'P';
346  mMagicNumber[1] = '5';
347  mNumLevels = 255;
348  Allocate( kChars );
349 
350 // original float values scaled to [0,255]
351  max = min = output[0][0];
352  for( i = 0; i < mHeight; i++ )
353  for( j = 0; j < mWidth; j++ )
354  {
355  if( output[i][j] > max ) max = output[i][j];
356  if( output[i][j] < min ) min = output[i][j];
357  }
358 
359  maxmin = max - min;
360  for( i = 0; i < mHeight; i++ )
361  for( j = 0; j < mWidth; j++ )
362  mPixels[i][j] = (unsigned char)(255.0 * ( (output[i][j] - min ) / maxmin ));
363 
364  Write( filename );
365 }
366 
367 }; // namespace
unsigned char ** mPixels
Definition: ImageFile.h:82
char mMagicNumber[2]
Definition: PGMImage.h:55
int Read(char *)
Definition: PGMImage.cpp:34
void Write(char *)
Definition: PGMImage.cpp:190
float pow(float a, double b)
Definition: utils.h:181
void Allocate(int dataset)
Definition: ImageFile.cpp:50
vigra::RGBValue< T, RIDX, GIDX, BIDX > log(vigra::RGBValue< T, RIDX, GIDX, BIDX > const &v)
component-wise logarithm
Definition: utils.h:209
static T max(T x, T y)
Definition: svm.cpp:65
void WriteScaled(char *filename, float **output, int height, int width)
Definition: PGMImage.cpp:334
static T min(T x, T y)
Definition: svm.cpp:62