const char * UsageLines [] = {
       "NOTICE: p6addpolygon is deprecated.",
       "use p4polygons and pnmcomp instead.",
       "Usage: p6addpolygon (r) (g) (b)",
       "\t[(polygon corner across) (polygon corner down) ]+",
       "Reads P6 PPM image from standard input and writes to",
       "standard output same size but with specified polygon.",
       "Each corner on the polygon is specified by an across",
       "and down (left and top edges are zero).  The polygon",
       "is filled (using nonzero method) with the specified",
       "color.",
       "August 22, 2021.  Newest is at gopher -p users/julianbr sdf.org",
       };
const int NumUsageLines = sizeof (UsageLines)/sizeof (UsageLines [0] );


#include <stdio.h>


void AddPolygon (
               int width, int height,
               int fillr, int fillg, int fillb,
               int (* Corners) [2], int NumCorners)
       {
       int across1, down1, across2, down2, across, down;
       int r, g, b, i, NumCrossings;

       printf ("P6\n");
       printf ("%d %d\n", width, height);
       printf ("255\n");
       r = getchar ();
       for (down = 0; down < height; down++) {
               for (across = 0; across < width; across++) {
                       NumCrossings = 0;
                       for (i = 0; i < NumCorners; i++) {
                               across1 = Corners [i] [0];
                               down1 = Corners [i] [1];
                               if (i + 1 < NumCorners) {
                                       across2 = Corners [i + 1] [0];
                                       down2 = Corners [i + 1] [1];
                                       }
                               else {
                                       across2 = Corners [0] [0];
                                       down2 = Corners [0] [1];
                                       }
                               if (down1 <= down && down < down2) {
                                       if (
                                               (across - across1)*(down2 - down1)
                                               >=
                                               (across2 - across1)*(down - down1)
                                               )
                                               NumCrossings--;
                                       }
                               else if (down1 > down && down >= down2) {
                                       if (
                                               (across - across2)*(down1 - down2)
                                               >=
                                               (across1 - across2)*(down - down2)
                                               )
                                               NumCrossings++;
                                       }
                               }
                       if (r != EOF)
                               g = getchar ();
                       if (g != EOF)
                               b = getchar ();
                       if (NumCrossings == 0) {
                               putchar (r);
                               putchar (g);
                               putchar (b);
                               }
                       else {
                               putchar (fillr);
                               putchar (fillg);
                               putchar (fillb);
                               }
                       if (b != EOF)
                               r = getchar ();
                       }
               }
       if (b == EOF)
               fprintf (stderr, "***p6addpolygon: Not enough image data.\n");
       if (r != EOF)
               fprintf (stderr, "***p6addpolygon: Too much image data.\n");
       }


#include <stdlib.h>


int main (int argc, char * argv [] )
       {
       int (* Corners) [2];
       int i, width, height, fillr, fillg, fillb, NumCorners, ok, depth;
       char c;

       Corners = NULL;
       if (argc < 2) {
               for (i = 0; i < NumUsageLines; i++)
                       printf ("%s\n", UsageLines [i] );
               }
       else if (argc < 6 || (argc - 4) % 2 > 0) {
               fprintf (stderr, "***Usage: %s", argv [0] );
               fprintf (stderr, " (r) (g) (b)");
               fprintf (stderr, " (across down for each corner)\n");
               }
       else {
               ok = 1;
               if (sscanf (argv [1], "%d%c", & fillr, & c) != 1) {
                       fprintf (stderr, "***p6addpolygon: Expecting number");
                       fprintf (stderr, " for fill r, found");
                       fprintf (stderr, " \"%s\".\n", argv [1] );
                       ok = 0;
                       }
               if (sscanf (argv [2], "%d%c", & fillg, & c) != 1) {
                       fprintf (stderr, "***p6addpolygon: Expecting number");
                       fprintf (stderr, " for fill g, found");
                       fprintf (stderr, " \"%s\".\n", argv [2] );
                       ok = 0;
                       }
               if (sscanf (argv [3], "%d%c", & fillb, & c) != 1) {
                       fprintf (stderr, "***p6addpolygon: Expecting number");
                       fprintf (stderr, " for fill b, found");
                       fprintf (stderr, " \"%s\".\n", argv [3] );
                       ok = 0;
                       }
               if (ok) {
                       NumCorners = (argc - 4)/2;
                       Corners = NULL;
                       if (NumCorners > 0) {
                               Corners = malloc (NumCorners*sizeof (Corners [0] ) );
                               if (Corners == NULL) {
                                       fprintf (stderr, "***p6addpolygon: Not");
                                       fprintf (stderr, " enough memory.\n");
                                       ok = 0;
                                       }
                               }
                       }
               if (ok) {
                       for (i = 0; i < NumCorners; i++) {
                               if (sscanf (argv [i + i + 4], "%d%c",
                                               Corners [i] + 0, & c) != 1) {
                                       fprintf (stderr, "***p6addpolygon: Expecting");
                                       fprintf (stderr, " number for across,");
                                       fprintf (stderr, " found \"");
                                       fprintf (stderr, "%s", argv [i + 4] );
                                       fprintf (stderr, "\".\n");
                                       ok = 0;
                                       }
                               if (sscanf (argv [i + i + 5], "%d%c",
                                               Corners [i] + 1, & c) != 1) {
                                       fprintf (stderr, "***p6addpolygon: Expecting");
                                       fprintf (stderr, " number for down,");
                                       fprintf (stderr, " found \"");
                                       fprintf (stderr, "%s", argv [i + 5] );
                                       fprintf (stderr, "\".\n");
                                       ok = 0;
                                       }
                               }
                       }
               if (ok) {
                       if (getchar () != 'P'
                                       || getchar () != '6'
                                       || scanf ("%d", & width) != 1
                                       || scanf ("%d", & height) != 1
                                       || scanf ("%d", & depth) != 1
                                       || getchar () != '\n') {
                               fprintf (stderr, "***p6addpolygon: Improper input,");
                               fprintf (stderr, " must be P6 PPM.\n");
                               ok = 0;
                               }
                       }
               if (ok) {
                       AddPolygon (width, height, fillr, fillg, fillb,
                                       Corners, NumCorners);
                       }
               }
       if (Corners != NULL)
               free (Corners);
       return 0;
       }