/* ppm.c */ /* This is a general parser for reading ppm files. */ #include #include #include #include #include int main() { char id[3] = {0, 0, 0}; int vals[6]; int count = 0; char *buf = malloc(256); int rc; unsigned char *base; unsigned char *im1; unsigned char *im2; int size; int i; /* Acquire first line of text */ fgets(buf, 256, stdin); /* Extract the P5 or P6 tag */ memcpy(id, buf, 2); /* Try to get any numeric values that follow the tag */ rc = sscanf(buf + 2, "%d %d %d", vals, vals + 1, vals + 2); /* Update count if any were obtained */ if (rc > 0) count = rc; /* Loop until we have 3 values or run out of data */ while (count < 3) { /* Break out of loop on end of file */ if (fgets(buf, 256, stdin) <= 0) break; /* Try again to get three values */ /* Its important to read them into the array starting */ /* at the proper offset which is the value of count. */ rc = sscanf(buf, "%d %d %d", &vals[count], &vals[count + 1], &vals[count + 2]); /* If values were obtained update count */ if (rc > 0) count += rc; } /* With any luck we have now processed a complete header */ /* vals[0] has number of image columns, vals[1] the number */ /* of rows. Save total number of pixels in "size" */ size = vals[0] * vals[1]; /* Allocate input and output pixel arrays .. need 3 bytes */ /* per pixel in the input image.. only 1 byte per pix in */ /* the output. */ im1 = (unsigned char *)malloc(3 * size); im2 = (unsigned char *)malloc( size); /* Need to remember the start address of the output array */ /* so we can write it out after we fill it in. */ base = im2; count = fread(im1, 3, size, stdin); /* If it didn't work warn the customer */ if (count != size) { fprintf(stderr, "Tried to read %d but read %d \n", size, count); perror("Error was"); exit(1); } for (i = 0; i < size; i++) { float sum = 0.0; /* Build output value */ sum += 0.30 * *im1; sum += 0.59 * *(im1 + 1); sum += 0.11 * *(im1 + 2); /* Store it in the output pixel array */ *im2 = sum + 0.5; /* Advance both ptrs to next pixel */ im2 += 1; im1 += 3; } /* Write the P5 header... Don't want extra spaces after 3rd value */ /* MUST have \n after last value */ fprintf(stdout, "P5 %d %d %d\n", vals[0], vals[1], vals[2]); /* Write output image */ count = fwrite(base, 1, size, stdout); /* If it didn't work warn the customer */ if (count != size) { fprintf(stderr, "Tried to write %d but wrote %d \n", size, count); perror("Error was"); } fclose(stdout); return(0); }