const char * UsageLines [] = { "Usage: p6colormatch (r) (g) (b) (radius)", "Reads P6 PPM image from standard input.", "Outputs bicolor PBM image to standard output.", "All input pixels with color components ri gi bi will", "produce a '1' output pixel if", "(ri - r)**2 + (gi - g)**2 + (bi - b)**2 <= radius**2", "and a '0' output pixel otherwise.", "Specifying a radius of 0 means only an exact r g b match", "produces a '1' output.", "May 16, 2011. Newest is at gopher -p users/julianbr sdf.org", }; const int NumUsageLines = sizeof (UsageLines)/sizeof (UsageLines [0] ); #include <stdio.h> void ColorMatchData ( int width, int height, int MatchingR, int MatchingG, int MatchingB, int MatchingRadius) { unsigned long int MatchingRadius2; int InputR, InputG, InputB, OutputWeight, OutputValue; int across, down; MatchingRadius2 = MatchingRadius*MatchingRadius; InputR = getchar (); for (down = 0; down < height; down++) { OutputWeight = 128; OutputValue = 0; for (across = 0; across < width; across++) { if (InputR == EOF) InputG = EOF; else InputG = getchar (); if (InputG == EOF) InputB = EOF; else InputB = getchar (); if ((InputR - MatchingR)*(InputR - MatchingR) + (InputG - MatchingG)*(InputG - MatchingG) + (InputB - MatchingB)*(InputB - MatchingB) <= MatchingRadius2) OutputValue += OutputWeight; if (InputB == EOF) InputR = EOF; else InputR = getchar (); OutputWeight /= 2; if (OutputWeight == 0) { putchar (OutputValue); OutputWeight = 128; OutputValue = 0; } } if (OutputWeight < 128) putchar (OutputValue); } if (InputB == EOF) { fprintf (stderr, "***p6colormatch: Premature end"); fprintf (stderr, " of input image data.\n"); } if (InputR != EOF) { fprintf (stderr, "***p6colormatch: Extra input"); fprintf (stderr, " image data.\n"); } } void ColorMatchFile ( int MatchingR, int MatchingG, int MatchingB, int MatchingRadius) { int InputWidth, InputHeight, InputDepth; if (getchar () != 'P' || getchar () != '6' || scanf ("%d", & InputWidth) != 1 || scanf ("%d", & InputHeight) != 1 || scanf ("%d", & InputDepth) != 1 || getchar () != '\n') { fprintf (stderr, "***p6colormatch: Improper input,"); fprintf (stderr, " must be P6 PPM.\n"); } else { printf ("P4\n"); printf ("%d %d\n", InputWidth, InputHeight); ColorMatchData ( InputWidth, InputHeight, MatchingR, MatchingG, MatchingB, MatchingRadius); } } int main (int argc, char * argv [] ) { int i, MatchingR, MatchingG, MatchingB, MatchingRadius, ok; char c; if (argc < 2) { for (i = 0; i < NumUsageLines; i++) printf ("%s\n", UsageLines [i] ); } else if (argc == 5) { ok = 1; if (sscanf (argv [1], "%d%c", & MatchingR, & c) != 1) { fprintf (stderr, "***p6colormatch: Expecting"); fprintf (stderr, " r value, found"); fprintf (stderr, " \"%s\".\n", argv [1] ); ok = 0; } if (sscanf (argv [2], "%d%c", & MatchingG, & c) != 1) { fprintf (stderr, "***p6colormatch: Expecting"); fprintf (stderr, " g value, found"); fprintf (stderr, " \"%s\".\n", argv [2] ); ok = 0; } if (sscanf (argv [3], "%d%c", & MatchingB, & c) != 1) { fprintf (stderr, "***p6colormatch: Expecting"); fprintf (stderr, " b value, found"); fprintf (stderr, " \"%s\".\n", argv [3] ); ok = 0; } if (sscanf (argv [4], "%d%c", & MatchingRadius, & c) != 1) { fprintf (stderr, "***p6colormatch: Expecting"); fprintf (stderr, " radius value, found"); fprintf (stderr, " \"%s\".\n", argv [4] ); ok = 0; } if (ok) ColorMatchFile ( MatchingR, MatchingG, MatchingB, MatchingRadius); } else { fprintf (stderr, "Usage: p6colormatch"); fprintf (stderr, " (r) (g) (b) (radius)\n"); } return 0; }