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