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;
       }