#include <stdlib.h> #include <stdio.h> int main ( int argc, char* argv[] ) { FILE *file; char buffer[1024]; int nrows, ncols, ngray ; int ch, count ; int moreComments=1; if ( argc != 2 ) { printf("imageInfo filename\n"); exit( EXIT_FAILURE ); } /* open the image file for reading binary */ if ( (file = fopen( argv[1], "rb") ) == NULL ) { printf("image file %s could not be opened\n", argv[1] ); exit( EXIT_FAILURE ); } /* read signature on first line -- read in nonwhitespace characters */ if ( fscanf( file, "%s", buffer ) != 1 ) { printf("error in image header: no signature\n" ); exit( EXIT_FAILURE ); } if ( strncmp( buffer, "P5", 2 ) == 0 ) printf("type: PGM\n" ); else if ( strncmp( buffer, "P6", 2 ) == 0 ) printf("type: PPM\n" ); else { printf("type: %s\n", buffer ); exit( EXIT_FAILURE ); } /* echo comment lines */ /* comment lines start with # and end with a linefeed */ while ( moreComments ) { /* advance to first nonwhitespace characgter */ while ( (ch=fgetc(file)) && isspace(ch) ); /* if there is a comment */ if ( ch=='#' ) { fgets( buffer, 1024, file ); /* read up to the required linefeed */ printf("#%s", buffer ); } /* this is not the start of a comment */ else { moreComments = 0; ungetc( ch, file ); } } /* Read in nrows, ncols, ngray. */ /* The three values are in ascii, separated by white space */ /* which might include a line terminator. */ count = fscanf( file, " %d %d %d", &ncols, &nrows, &ngray ); if ( count != 3 ) { printf("error in image header\n" ); exit( EXIT_FAILURE ); } /* echo ncols, nrows, ngray */ printf("ncols: %d\n", ncols ); printf("nrows: %d\n", nrows ); printf("ngray: %d\n", ngray ); }
Comments: The section that echos comment lines is slightly
tricky. There might not be any comment lines, and the only way to know is to
check if the whitespace that follows P5 or P6 is followed by a #.
If
it is, all characters up to the next linefeed character are a comment.
fgets()
reads up to the newline character that is required at
the end of a comment.
If the next nonwhitespace character is not a #
the next character
is part of the number of columns. The call to ungetc(ch,file)
"puts
back" the character just read in. The character must be scanned by the fscanf()
in the next section of code.