33 #ifndef __INCLUDE_MIST_PNM__
34 #define __INCLUDE_MIST_PNM__
37 #ifndef __INCLUDE_MIST_H__
42 #ifndef __INCLUDE_MIST_COLOR_H__
43 #include "../config/color.h"
56 namespace __pnm_controller__
70 struct _gray_converter_
73 static T get_value(
const T &v ){
return( v ); }
77 struct _gray_converter_< true >
80 static typename T::value_type get_value(
const T &v ){
return( v.get_value( ) ); }
83 template <
class T,
class Allocator >
86 typedef typename array2< T, Allocator >::size_type size_type;
87 typedef _pixel_converter_< T > pixel_converter;
88 typedef _gray_converter_< is_color< T >::value > gray_converter;
89 typedef typename pixel_converter::color_type color_type;
90 typedef typename pixel_converter::value_type value_type;
92 static PNM_TYPE pnm_format(
const std::string &str )
98 else if( str ==
"P2" )
102 else if( str ==
"P3" )
106 else if( str ==
"P4" )
110 else if( str ==
"P5" )
114 else if( str ==
"P6" )
124 static const unsigned char *get_line(
const unsigned char *s,
const unsigned char *e, std::string &line )
131 if( s + 1 != e && s[ 1 ] ==
'\n' )
141 else if( s[ 0 ] ==
'\n' )
149 return( s > e ? e : s );
152 static const unsigned char *get_value(
const unsigned char *s,
const unsigned char *e, std::string &line,
bool &flag )
158 if( flag && s[ 0 ] ==
'#' )
165 if( s + 1 != e && s[ 1 ] ==
'\n' )
175 else if( s[ 0 ] ==
'\n' )
183 else if( s[ 0 ] ==
'\r' )
185 if( s + 1 != e && s[ 1 ] ==
'\n' )
195 else if( s[ 0 ] ==
'\n' )
200 else if( s[ 0 ] ==
' ' || s[ 0 ] ==
'\t' )
215 if( s + 1 != e && s[ 1 ] ==
'\n' )
226 else if( s[ 0 ] ==
'\n' )
232 else if( s[ 0 ] ==
' ' || s[ 0 ] ==
'\t' )
240 return( s > e ? e : s );
243 static size_type split_string(
const std::string &line,
const char ch, std::vector< std::string > &elements )
245 std::string str =
"";
248 while( i < line.size( ) )
250 for( ; i < line.size( ) && line[ i ] == ch ; i++ ){}
253 for( ; i < line.size( ) && line[ i ] != ch ; i++ )
260 elements.push_back( str );
263 return( elements.size( ) );
266 static bool is_number(
const std::string &line )
268 for(
size_t i = 0 ; i < line.size( ) ; i++ )
270 if( line[ i ] <
'0' ||
'9' < line[ i ] )
278 static bool convert_from_pnm_data( array2< T, Allocator > &image,
const unsigned char *buff, size_type len,
typename array2< T, Allocator >::size_type level )
281 const unsigned char *p = buff;
282 const unsigned char *e = buff + len;
283 std::string line =
"";
284 std::vector< std::string > elements;
287 p = get_value( p, e, line, flag );
288 PNM_TYPE pnm_type = pnm_format( line );
292 std::cerr <<
"This format is not supported currently!" << std::endl;
297 size_type w = 0, h = 0, gray_level = level;
298 p = get_value( p, e, line, flag );
299 if( is_number( line ) )
301 w = atoi( line.c_str( ) );
306 std::cerr <<
"Image size is unknown!" << std::endl;
309 p = get_value( p, e, line, flag );
310 if( is_number( line ) )
312 h = atoi( line.c_str( ) );
317 std::cerr <<
"Image size is unknown!" << std::endl;
320 image.resize( w, h );
329 p = get_value( p, e, line, flag );
330 if( !is_number( line ) )
333 std::cerr <<
"Image size is unknown!" << std::endl;
336 gray_level = atoi( line.c_str( ) );
345 double scale =
static_cast< double >( level ) / static_cast< double >( gray_level );
350 while( i < image.size( ) && p < e )
352 p = get_line( p, e, line );
353 split_string( line,
' ', elements );
354 for( size_type j = 0 ; i < image.size( ) && j < elements.size( ) ; j++ )
356 image[ i++ ] =
static_cast< value_type
>( atoi( elements[ j ].c_str( ) ) * scale );
362 while( i < image.size( ) && p < e )
364 p = get_line( p, e, line );
365 split_string( line,
' ', elements );
366 for( size_type j = 0 ; i < image.size( ) && j < elements.size( ) ; j += 3 )
368 value_type r =
static_cast< value_type
>( atoi( elements[ j + 0 ].c_str( ) ) * scale );
369 value_type g =
static_cast< value_type
>( atoi( elements[ j + 1 ].c_str( ) ) * scale );
370 value_type b =
static_cast< value_type
>( atoi( elements[ j + 2 ].c_str( ) ) * scale );
371 image[ i++ ] = pixel_converter::convert_to( r, g, b );
378 while( i < image.size( ) && p < e )
380 image[ i++ ] =
static_cast< value_type
>( *p++ * scale );
385 while( i < image.size( ) && p < e )
387 value_type r =
static_cast< value_type
>( p[ 0 ] * scale );
388 value_type g =
static_cast< value_type
>( p[ 1 ] * scale );
389 value_type b =
static_cast< value_type
>( p[ 2 ] * scale );
390 image[ i++ ] = pixel_converter::convert_to( r, g, b );
402 static bool read( array2< T, Allocator > &image,
const std::string &filename,
typename array2< T, Allocator >::size_type level )
404 typedef typename array2< T, Allocator >::size_type size_type;
408 if( ( fp = fopen( filename.c_str( ),
"rb" ) ) == NULL )
return(
false );
410 fseek( fp, 0, SEEK_END );
411 filesize = ftell( fp );
412 fseek( fp, 0, SEEK_SET );
414 unsigned char *buff =
new unsigned char[ filesize + 1 ];
415 unsigned char *pointer = buff;
416 size_type read_size = 0;
417 while( feof( fp ) == 0 )
419 read_size = fread( pointer,
sizeof(
unsigned char ), 1024, fp );
420 if( read_size < 1024 )
424 pointer += read_size;
428 bool ret = convert_from_pnm_data( image, buff, filesize, level );
433 static bool write(
const array2< T, Allocator > &image,
const std::string &filename, PNM_TYPE pnm_type,
typename array2< T, Allocator >::size_type level )
435 typedef typename array2< T, Allocator >::size_type size_type;
437 if( image.width( ) == 0 )
439 std::cerr <<
"Image width is zero!" << std::endl;
442 else if( image.height( ) == 0 )
444 std::cerr <<
"Image height is zero!" << std::endl;
449 std::cerr <<
"This format is not supported currently!" << std::endl;
454 if( ( fp = fopen( filename.c_str( ),
"wb" ) ) == NULL )
460 fprintf( fp,
"P%1d\n", pnm_type );
461 fprintf( fp,
"# Created by MIST\n" );
462 fprintf( fp,
"%d %d\n", static_cast< int >( image.width( ) ), static_cast< int >( image.height( ) ) );
473 typename array2< T, Allocator >::value_type max = image[ 0 ];
474 for( i = 1 ; i < image.size( ) ; i++ )
476 max = max > image[ i ] ? max : image[ i ];
478 int max_level =
static_cast< int >( gray_converter::get_value( max ) );
479 max_level = max_level >
static_cast< int >( level ) ? max_level : static_cast< int >( level );
480 fprintf( fp,
"%d\n", max_level );
494 for( j = 0 ; j < image.height( ) ; j++ )
496 for( i = 0 ; i < image.width( ) ; i++ )
498 fprintf( fp,
"%d ", static_cast< int >( gray_converter::get_value( image( i, j ) ) ) );
505 for( j = 0 ; j < image.height( ) ; j++ )
507 for( i = 0 ; i < image.width( ) ; i++ )
509 color_type c = pixel_converter::convert_from( image( i, j ) );
510 fprintf( fp,
"%d ", static_cast< int >( c.r ) );
511 fprintf( fp,
"%d ", static_cast< int >( c.g ) );
512 fprintf( fp,
"%d ", static_cast< int >( c.b ) );
520 for( j = 0 ; j < image.height( ) ; j++ )
522 for( i = 0 ; i < image.width( ) ; i++ )
524 fprintf( fp,
"%c", static_cast< unsigned char >( gray_converter::get_value( image( i, j ) ) ) );
530 for( j = 0 ; j < image.height( ) ; j++ )
532 for( i = 0 ; i < image.width( ) ; i++ )
534 color_type c = pixel_converter::convert_from( image( i, j ) );
535 fprintf( fp,
"%c", static_cast< unsigned char >( c.r ) );
536 fprintf( fp,
"%c", static_cast< unsigned char >( c.g ) );
537 fprintf( fp,
"%c", static_cast< unsigned char >( c.b ) );
583 template <
class T,
class Allocator >
586 return( __pnm_controller__::pnm_controller< T, Allocator >::read( image, filename, level ) );
601 template <
class T,
class Allocator >
629 template <
class T,
class Allocator >
634 std::cerr <<
"This format is not supported currently!" << std::endl;
637 return( __pnm_controller__::pnm_controller< T, Allocator >::write( image, filename, static_cast< __pnm_controller__::PNM_TYPE >( pnm_type ), level ) );
662 template <
class T,
class Allocator >
665 return(
write_pnm( image,
wstr2str( filename ), static_cast< __pnm_controller__::PNM_TYPE >( pnm_type ), level ) );
680 #endif // __INCLUDE_MIST_PNM__