/* * usage: autocolor * * inputfile is "-" to read from stdin. result (a PPM) is produced on stdout. * maps input gray levels to arbitrary unique colors. leaves black pixels * unchanged. */ #include #include #include #include #include #include #include using namespace std; void hsv_to_rgb( double h, double s, double v, unsigned char* r, unsigned char* g, unsigned char* b ); unsigned char* read_pgm( char* filename, int* width, int* height ); void write_ppm( FILE* f, int width, int height, unsigned char* data ); main( int argc, char **argv ) { unsigned char* image; unsigned char* colimage; int width, height; int i; int max; unsigned char map[256][3]; if ( argc != 2 ) { fprintf( stderr, "usage: %s inputfile\n", argv[0] ); exit( 1 ); } image = read_pgm( argv[1], &width, &height ); colimage = (unsigned char*)malloc( width * height * 3 ); max = 0; for ( i = 0; i < width*height; ++i ) if ( image[i] > max ) max = image[i]; for ( i = 1; i <= max; ++i ) hsv_to_rgb( (i-1) * M_PI * 2 / max, 1.0, 1.0, map[i]+0, map[i]+1, map[i]+2 ); for ( i = 0; i < width*height; ++i ) { colimage[i*3+0] = map[image[i]][0]; colimage[i*3+1] = map[image[i]][1]; colimage[i*3+2] = map[image[i]][2]; } write_ppm( stdout, width, height, colimage ); } void hsv_to_rgb( double h, double s, double v, unsigned char* r, unsigned char* g, unsigned char* b ) { int i; double f; unsigned char p, q, t, z; if ( s == 0 ) { *r = *g = *b = v*255; return; } h /= (M_PI/3); i = h; f = h - i; p = 255 * v * (1-s); q = 255 * v * (1-s*f); t = 255 * v * (1-(s*(1-f))); z = 255 * v; *r = (i==0||i==5) ? z : ( (i==2||i==3) ? p : ( i==1 ? q : t ) ); *g = (i==1||i==2) ? z : ( (i==4||i==5) ? p : ( i==3 ? q : t ) ); *b = (i==3||i==4) ? z : ( (i==0||i==1) ? p : ( i==5 ? q : t ) ); } unsigned char* read_pgm( char* filename, int* width, int* height ) { char buffer[80]; int phase = 0; int type, maxval; int j; unsigned char* data; FILE* f; if ( strcmp( filename, "-" ) == 0 ) { f = stdin; } else { f = fopen( filename, "rb" ); if ( f == NULL ) return NULL; } while ( phase < 4 ) { fgets( buffer, 80, f ); if ( buffer[0] == '#' ) continue; switch( phase ) { case 0: j = sscanf( buffer, "P%d %d %d %d\n", &type, width, height, &maxval ); break; case 1: j = sscanf( buffer, "%d %d %d\n", width, height, &maxval ); break; case 2: j = sscanf( buffer, "%d %d\n", height, &maxval ); break; case 3: j = sscanf( buffer, "%d\n", &maxval ); break; case 4: j = 0; break; } phase += j; } if ( type != 5 ) { fprintf( stderr, "bad input image format.\n" ); return NULL; } data = (unsigned char*)malloc ( *width * *height ); fread( data, *width * *height, 1, f ); fclose( f ); return data; } void write_ppm( FILE* f, int width, int height, unsigned char* data ) { fprintf( f, "P6\n%d %d\n%d\n", width, height, 255 ); fwrite( data, width*height*3, 1, f ); fclose( f ); }