// read/write PPM (Portable Pixel Map) files // // assumes 8-bit data with max 255 // #include #include #include "ppm.h" // print error message and exit // static void error( const char *msg) { fprintf( stderr, "ppm: %s\n", msg); exit(1); } // create a 2D array of unsigned char // static unsigned char **amalloc( int rows, int cols) { unsigned char **a; if( (a = malloc( rows*sizeof(char*))) == NULL || (a[0] = malloc( rows*cols)) == NULL) error( "malloc failed."); for( int i = 1; i < rows; ++i) // set the row pointers a[i] = a[i-1] + cols; return a; } // create a new ppm structure // // initializes the ppm rows and cols fields, // allocates but does not initialize the RGB data fields // ppm ppm_new( int rows, int cols) { ppm p; p.rows = rows; p.cols = cols; p.r = amalloc( rows, cols); p.g = amalloc( rows, cols); p.b = amalloc( rows, cols); return p; } // read PPM data from stdin // ppm ppm_read( void) { ppm p; int rows, cols, max, r,g,b; if( getchar() != 'P' || getchar() != '6') error( "input is not P6 PPM format"); if( scanf( "%i%i%i", &cols, &rows, &max) != 3) error( "scanf() failed."); getchar(); // skip newline p = ppm_new( rows, cols); for( int i = 0; i < p.rows; ++i) for( int j = 0; j < p.cols; ++j) { r = getchar(); g = getchar(); b = getchar(); if( b < 0) error( "getchar() failed."); p.r[i][j] = r; p.g[i][j] = g; p.b[i][j] = b; } return p; } // write PPM data to stdout // void ppm_write( ppm p) { printf( "P6 %i %i 255\n", p.cols, p.rows); for( int i = 0; i < p.rows; ++i) for( int j = 0; j < p.cols; ++j) { putchar( p.r[i][j]); putchar( p.g[i][j]); putchar( p.b[i][j]); } }