readppm-headers.c

This program is the end result of the "ppm-headers" lab. It reads the ASCII headers from a .ppm graphic file.

/* read-ppm-headers.c
 * Read a PPM/PGM/PBM image file into a struct.
 * Used by negate-pnm, laplacians-pgm, zero-crossings-pgm, etc.
 * 2020-08-16
 */
#include<stdio.h>
#include<stdlib.h>  // malloc(), abs(), exit()
#include<string.h>  // strlen()
#include<ctype.h>   // isspace()
#include<errno.h>


void retrieve_comment(char *comment_buffer, int cblength, FILE *src)
{
    char c;
    comment_buffer[0] = '\0';   // assume no-comment

    while ( isspace( c = getc(src) ) ) {   // read & discard each whitespace
        ;   // null statement
    }
    // found a non-whitespace:
    ungetc(c, src); // put it back into the stream, to be processed

    if ('#' == c)   // found a comment!
        fgets(comment_buffer, cblength, src);   // including the "#"
    // else it's a non-comment, presumably the start of a token...

    return;
}


int main(int argc, char **argv)
{
    if (argc != 3) {
        fprintf(stderr, "usage: %s infile outfile\n", argv[0]);
        return 1;
    }

    // Open, read/process, and close image file; open, write, and close output file.

    FILE *infile = fopen(argv[1], "r");
    if (infile == NULL) {
        fprintf(stderr, "Can't open file %s for reading!\n", argv[1]);
        return 2;
    }
    FILE *outfile = fopen(argv[2], "w");
    if (outfile == NULL) {
        fprintf(stderr, "Can't open file %s for writing!\n", argv[2]);
        return 2;
    }

    char magicnum[3];
    unsigned width, height, maxval = 0;
    char comment[4096];     // not needed at first...

    fscanf(infile, " %2s", magicnum);
    fprintf(outfile, "%2s\n", magicnum);
    // Grab as many comments as there may be:
    do {
        retrieve_comment(comment, 4096, infile);
        if (comment[0] == '#') {
            fprintf(outfile, "%s", comment);
            printf("comment: %s\n", comment);
        }
    } while (comment[0] != '\0');

    fscanf(infile, " %u", &width);
    fprintf(outfile, "%u\n", width);
    do {
        retrieve_comment(comment, 4096, infile);
        if (comment[0] == '#') {
            fprintf(outfile, "%s", comment);
            printf("comment: %s\n", comment);
        }
    } while (comment[0] != '\0');

    fscanf(infile, " %u", &height);
    fprintf(outfile, "%u\n", height);
    do {
        retrieve_comment(comment, 4096, infile);
        if (comment[0] == '#') {
            fprintf(outfile, "%s", comment);
            printf("comment: %s\n", comment);
        }
    } while (comment[0] != '\0');

    fscanf(infile, " %u", &maxval);
    fprintf(outfile, "%u\n", maxval);
    do {
        retrieve_comment(comment, 4096, infile);
        if (comment[0] == '#') {
            fprintf(outfile, "%s", comment);
            printf("comment: %s\n", comment);
        }
    } while (comment[0] != '\0');

    // Copy headers to output file.  Also report values to the console:
    printf("magic number: %2s\nwidth x height: %u x %u\nmaximum: %u\n",
        magicnum, width, height, maxval);

    fclose(infile);
    fclose(outfile);

    return 0;
}