SigPack - the C++ signal processing library
 
Loading...
Searching...
No Matches
image.h
Go to the documentation of this file.
1#ifndef IMAGE_H_INCLUDED
2#define IMAGE_H_INCLUDED
3
4#include <string>
5#include <fstream>
6#include <bitset>
7
8namespace sp
9{
14
21
22class PNM
23{
24 private:
25 std::ifstream ifs;
26 std::ofstream ofs;
27 arma::uword cols;
28 arma::uword rows;
29 int maxval;
30 public:
41
46 {
47 type = NOTUSED;
48 cols = 0;
49 rows = 0;
50 maxval = 0;
51 }
52
57 {
58 }
59
63 void clear( void )
64 {
65 type = NOTUSED;
66 cols = 0;
67 rows = 0;
68 maxval = 0;
69 }
70
76 {
77 std::string str;
78 while( ifs >> str ) // Read until we have maxval
79 {
80 // Remove comments
81 size_t mark = str.find_first_of( "#" );
82 if( mark != std::string::npos )
83 {
84 ifs.ignore( 256, '\n' );
85 str.erase( mark, 1 );
86
87 if( str.empty() )
88 continue;
89 }
90
91 if( type == NOTUSED )
92 {
93 type = static_cast<imtype>( str.at( 1 ) - 48 ); // Conv char to int
94 if( str.at( 0 ) != 'P' || type > PPM_B )
95 err_handler( "Wrong type!" );
96 }
97 else if( cols == 0 )
98 {
99 cols = atoi( str.c_str() );
100 }
101 else if( rows == 0 )
102 {
103 rows = atoi( str.c_str() );
104 if( type == PBM_A || type == PBM_B )
105 {
106 maxval = 1; // Set maxval=1 for .PBM types
107 break;
108 }
109 }
110 else if( maxval == 0 )
111 {
112 maxval = atoi( str.c_str() );
113 break;
114 }
115 }
116 ifs.ignore( 1 ); // Skip one char before data
117 }
118
128 void write_header( const imtype _type, const arma::uword _rows, const arma::uword _cols, const int _maxval, const std::string comments )
129 {
130 type = _type;
131 rows = _rows;
132 cols = _cols;
133 maxval = _maxval;
134 ofs << "P" << type << std::endl;
135 ofs << "# " << comments << std::endl;
136 ofs << cols << " " << rows << std::endl;
137 if( !( ( type == PBM_A ) || ( type == PBM_B ) ) )
138 ofs << maxval << std::endl;
139 }
140
150 bool write( std::string fname, const imtype _type, const arma::cube& img, const std::string info = "" )
151 {
152 // Open file
153 ofs.open( fname.c_str(), std::ofstream::binary );
154 if( !ofs.good() )
155 {
156 std::cout << "Could not open " << fname << std::endl;
157 return false;
158 }
159 else
160 {
161 write_header( _type, img.n_rows, img.n_cols, (int)img.max(), info );
162 // get_info();
163
164 // Write data
165 if( type == PPM_A ) // Plain (ASCII )type
166 {
167 for( arma::uword r = 0; r < rows; r++ )
168 {
169 arma::uword i = 0;
170 for( arma::uword c = 0; c < cols; c++ )
171 {
172 ofs << img( r, c, 0 ) << " " << img( r, c, 1 ) << " " << img( r, c, 2 ) << " "; // R G B
173 if( ++i % 5 == 0 )
174 ofs << std::endl; // Max len is 70 chars/line
175 }
176 }
177 }
178 else if( type == PPM_B )
179 {
180 for( arma::uword r = 0; r < rows; r++ )
181 for( arma::uword c = 0; c < cols; c++ )
182 {
183 unsigned char bb;
184 bb = static_cast<unsigned char>( img( r, c, 0 ) ); // R
185 ofs.write( reinterpret_cast<char*>( &bb ), 1 );
186 bb = static_cast<unsigned char>( img( r, c, 1 ) ); // G
187 ofs.write( reinterpret_cast<char*>( &bb ), 1 );
188 bb = static_cast<unsigned char>( img( r, c, 2 ) ); // B
189 ofs.write( reinterpret_cast<char*>( &bb ), 1 );
190 }
191 }
192 }
193 ofs.close();
194 return true;
195 }
196
206 bool write( std::string fname, const imtype _type, arma::mat& img, const std::string info = "" )
207 {
208 // Open file
209 ofs.open( fname.c_str(), std::ofstream::binary );
210 if( !ofs.good() )
211 {
212 std::cout << "Could not open " << fname << std::endl;
213 return false;
214 }
215 else
216 {
217 write_header( _type, img.n_rows, img.n_cols, (int)img.max(), info );
218 // get_info();
219
220 // Write data
221 if( type == PBM_A || type == PGM_A ) // Plain (ASCII )type
222 {
223 arma::uword i = 0;
224 for( arma::mat::iterator ii = img.begin(); ii != img.end(); ++ii )
225 {
226 ofs << *ii << " ";
227 if( ++i % 11 == 0 )
228 ofs << std::endl; // Max len is 70 chars/line
229 }
230 }
231 else if( type == PBM_B ) // Raw .pbm
232 {
233 std::bitset<8> b;
234 for( arma::uword r = 0; r < rows; r++ )
235 for( arma::uword c = 0; c < cols; c++ )
236 {
237 arma::uword ix = 7 - ( c % 8 );
238 b[ix] = ( img( r, c ) > 0 );
239 if( ix == 0 || c == cols - 1 )
240 {
241 ofs.write( reinterpret_cast<char*>( &b ), 1 );
242 b.reset();
243 }
244 }
245 }
246 else if( type == PGM_B ) // Raw .pgm
247 {
248 if( maxval <= 255 )
249 {
250 for( arma::uword r = 0; r < rows; r++ )
251 for( arma::uword c = 0; c < cols; c++ )
252 {
253 unsigned char bb = static_cast<unsigned char>( img( r, c ) );
254 ofs.write( reinterpret_cast<char*>( &bb ), 1 );
255 }
256 }
257 else
258 {
259 for( arma::uword r = 0; r < rows; r++ )
260 for( arma::uword c = 0; c < cols; c++ )
261 {
262 unsigned int bb;
263 bb = ( ( static_cast<unsigned int>( img( r, c ) ) ) >> 8 ) & 0x00ff; // Write MSB first
264 ofs.write( reinterpret_cast<char*>( &bb ), 1 );
265 bb = static_cast<unsigned int>( img( r, c ) ) & 0x00ff;
266 ofs.write( reinterpret_cast<char*>( &bb ), 1 );
267 }
268 }
269 }
270 }
271
272 ofs.close();
273 return true;
274 }
275
280 void get_info()
281 {
282 std::cout << "Type: P" << type << std::endl;
283 std::cout << "cols: " << cols << std::endl;
284 std::cout << "rows: " << rows << std::endl;
285 if( type == PGM_A || type == PGM_B )
286 std::cout << "Maxval: " << maxval << std::endl;
287 }
288
294 arma::uword get_rows()
295 {
296 return rows;
297 }
298
304 arma::uword get_cols()
305 {
306 return cols;
307 }
308
315 {
316 return maxval;
317 }
318
326 bool read( std::string fname, arma::cube& img )
327 {
328 // Open file
329 ifs.open( fname.c_str(), std::ifstream::binary );
330 if( !ifs.good() )
331 {
332 std::cout << "Could not open " << fname << std::endl;
333 return false;
334 }
335 else
336 {
337 read_header();
338 // get_info();
339
340 img.set_size( rows, cols, 3 );
341 arma::uword r = 0, c = 0;
342 // Get the data
343 if( type == PPM_A ) // Plain .PPM
344 {
345 std::string str;
346 arma::uword i = 0;
347 while( ifs >> str && r < rows ) // Read until eof
348 {
349 // Remove comments
350 size_t mark = str.find_first_of( "#" );
351 if( mark != std::string::npos )
352 {
353 ifs.ignore( 256, '\n' );
354 str.erase( mark, 1 );
355
356 if( str.empty() )
357 continue;
358 }
359 int pix = atoi( str.c_str() ); // Convert to int
360
361 img( r, c, i % 3 ) = pix;
362 i++;
363 if( i % 3 == 0 )
364 if( ++c == cols )
365 {
366 c = 0;
367 r++;
368 }
369 }
370 }
371 else if( type == PPM_B ) // Raw .PPM
372 {
373 for( arma::uword r = 0; r < rows; r++ )
374 for( arma::uword c = 0; c < cols; c++ )
375 {
376 unsigned char bb;
377 ifs.read( reinterpret_cast<char*>( &bb ), 1 ); // R
378 img( r, c, 0 ) = bb;
379 ifs.read( reinterpret_cast<char*>( &bb ), 1 ); // G
380 img( r, c, 1 ) = bb;
381 ifs.read( reinterpret_cast<char*>( &bb ), 1 ); // B
382 img( r, c, 2 ) = bb;
383 }
384 }
385 }
386 ifs.close();
387 return true;
388 }
389
397 bool read( std::string fname, arma::mat& img )
398 {
399 // Open file
400 ifs.open( fname.c_str(), std::ifstream::binary );
401 if( !ifs.good() )
402 {
403 std::cout << "Could not open " << fname << std::endl;
404 return false;
405 }
406 else
407 {
408 read_header();
409 get_info();
410
411 img.set_size( rows, cols );
412 arma::uword r = 0, c = 0;
413 // Get the data
414 if( type == PBM_A || type == PGM_A ) // Plain .PGM or .PBM
415 {
416 std::string str;
417 while( ifs >> str && r < rows ) // Read until eof
418 {
419 // Remove comments
420 size_t mark = str.find_first_of( "#" );
421 if( mark != std::string::npos )
422 {
423 ifs.ignore( 256, '\n' );
424 str.erase( mark, 1 );
425
426 if( str.empty() )
427 continue;
428 }
429 int pix = atoi( str.c_str() ); // Convert to int
430 img( r, c ) = pix;
431
432 if( ++c == cols )
433 {
434 c = 0;
435 r++;
436 }
437 }
438 }
439 else if( type == PBM_B ) // Raw PBM
440 {
441 unsigned char ch;
442 while( ifs.read( reinterpret_cast<char*>( &ch ), 1 ) && r < rows ) // Read until eof
443 {
444 std::bitset<8> pix( ch );
445 for( int b = 7; b >= 0; b-- )
446 {
447 img( r, c ) = pix[b];
448 if( ++c >= cols )
449 {
450 c = 0;
451 r++;
452 break;
453 }
454 }
455 }
456 }
457 else if( type == PGM_B ) // Raw PGM
458 {
459 if( maxval <= 255 )
460 {
461 for( arma::uword r = 0; r < rows; r++ )
462 for( arma::uword c = 0; c < cols; c++ )
463 {
464 unsigned char bb;
465 ifs.read( reinterpret_cast<char*>( &bb ), 1 );
466 img( r, c ) = bb;
467 }
468 }
469 else
470 {
471 for( arma::uword r = 0; r < rows; r++ )
472 for( arma::uword c = 0; c < cols; c++ )
473 {
474 unsigned char bb[2];
475 ifs.read( reinterpret_cast<char*>( bb ), 2 );
476 img( r, c ) = ( bb[0] << 8 ) + bb[1];
477 }
478 }
479 }
480 }
481 ifs.close();
482 return true;
483 }
484};
485
487} // namespace sp
488#endif
Portable anymap format class.
Definition image.h:23
bool write(std::string fname, const imtype _type, arma::mat &img, const std::string info="")
Write the .pnm file.
Definition image.h:206
~PNM()
Destructor.
Definition image.h:56
PNM()
Constructor.
Definition image.h:45
std::ofstream ofs
Output stream handle.
Definition image.h:26
void write_header(const imtype _type, const arma::uword _rows, const arma::uword _cols, const int _maxval, const std::string comments)
Write the .pnm header.
Definition image.h:128
imtype
Definition image.h:32
@ PBM_B
Definition image.h:37
@ PPM_B
Definition image.h:39
@ PGM_A
Definition image.h:35
@ NOTUSED
Definition image.h:33
@ PGM_B
Definition image.h:38
@ PPM_A
Definition image.h:36
@ PBM_A
Definition image.h:34
bool read(std::string fname, arma::mat &img)
Read image.
Definition image.h:397
arma::uword get_rows()
Get nr of rows.
Definition image.h:294
arma::uword cols
Nr of columns in image.
Definition image.h:27
arma::uword get_cols()
Get nr of cols.
Definition image.h:304
std::ifstream ifs
Input stream handle.
Definition image.h:25
void clear(void)
Clears the internal variables.
Definition image.h:63
int get_maxval()
Get maxval.
Definition image.h:314
enum sp::PNM::imtype type
Image format.
int maxval
Maximum pixel value in image.
Definition image.h:29
arma::uword rows
Nr of rows in image.
Definition image.h:28
bool write(std::string fname, const imtype _type, const arma::cube &img, const std::string info="")
Write the .pnm file.
Definition image.h:150
void get_info()
Prints header info.
Definition image.h:280
bool read(std::string fname, arma::cube &img)
Read image.
Definition image.h:326
void read_header()
Reads the .pnm header.
Definition image.h:75
#define err_handler(msg)
Definition base.h:212
Definition base.h:8