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