const char * UsageLines [] = { "Usage: p6fade (background r) (background g) (background b)", "\t(fade factor between -10 and 10)", "\t[(vertical edge across) (horizontal edge down) ]+", "Reads P6 PPM image from standard input and writes to", "standard output same size.", "", "Boundaries alternate", "between vertical edges specified by across (left edge = 0)", "and horizontal edges specified by down (top edge = 0).", "The edge path is always closed. p6fade will use the", "first across again if needed to close path.", "If no path is apecified, will operate on whole image.", "Need a minimum of 4 numbers for any effect (4 will be a rectangle).", "", "Fade factor of 0 will cause input image to pass to output unchanged.", "Fade factor of 10 will replace everything outside boundary", "with specified background color. Fade factor between 1 and 9", "will fade area outside boundary proportionally.", "Fade factor of -10 will replace everything inside boundary", "with specified background color. Fade factor between -1 and -9", "will fade area inside boundary proportionally.", "", "If no boundary is specified, p6fade will operate on whole", "image if fade factor is between 1 and 10.", "", "April 21, 2021. Newest is at gopher -p users/julianbr sdf.org", }; const int NumUsageLines = sizeof (UsageLines)/sizeof (UsageLines [0] ); #include <stdio.h> void Fade ( int width, int height, int backgroundr, int backgroundg, int backgroundb, int fade, int * Edges, int NumEdges) { int across1, down1, across2, across, down; int r, g, b, i, j, k; int 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; i = 0; j = 1; k = 2; while (j < NumEdges) { across1 = Edges [i]; down1 = Edges [j]; if (k < NumEdges) across2 = Edges [k]; else across2 = Edges [0]; if (down >= down1) { if (across2 > across && across >= across1) NumCrossings++; else if (across1 > across && across >= across2) NumCrossings--; } i += 2; j += 2; k += 2; } if (r != EOF) g = getchar (); if (g != EOF) b = getchar (); if (NumCrossings == 0) { if (fade > 0) { putchar ((fade*backgroundr + (10 - fade)*r + 5)/10); putchar ((fade*backgroundg + (10 - fade)*g + 5)/10); putchar ((fade*backgroundb + (10 - fade)*b + 5)/10); } else { putchar (r); putchar (g); putchar (b); } } else { if (fade < 0) { putchar ((- fade*backgroundr + (10 + fade)*r + 5)/10); putchar ((- fade*backgroundg + (10 + fade)*g + 5)/10); putchar ((- fade*backgroundb + (10 + fade)*b + 5)/10); } else { putchar (r); putchar (g); putchar (b); } } if (b != EOF) r = getchar (); } } if (b == EOF) fprintf (stderr, "***p6fade: Not enough image data.\n"); if (r != EOF) fprintf (stderr, "***p6fade: Too much image data.\n"); } #include <stdlib.h> int main (int argc, char * argv [] ) { int * Edges; int i, width, height, r, g, b, NumEdges, ok, depth, fade; char c; Edges = NULL; if (argc < 2) { for (i = 0; i < NumUsageLines; i++) printf ("%s\n", UsageLines [i] ); } else if (argc < 5) { fprintf (stderr, "***Usage: %s", argv [0] ); fprintf (stderr, " (r) (g) (b)"); fprintf (stderr, " (fade) (edges)\n"); } else { ok = 1; if (sscanf (argv [1], "%d%c", & r, & c) != 1) { fprintf (stderr, "***p6fade: Expecting number"); fprintf (stderr, " for background r, found"); fprintf (stderr, " \"%s\".\n", argv [1] ); ok = 0; } if (sscanf (argv [2], "%d%c", & g, & c) != 1) { fprintf (stderr, "***p6fade: Expecting number"); fprintf (stderr, " for background g, found"); fprintf (stderr, " \"%s\".\n", argv [2] ); ok = 0; } if (sscanf (argv [3], "%d%c", & b, & c) != 1) { fprintf (stderr, "***p6fade: Expecting number"); fprintf (stderr, " for background b, found"); fprintf (stderr, " \"%s\".\n", argv [3] ); ok = 0; } if (sscanf (argv [4], "%d%c", & fade, & c) != 1 || fade < -10 || fade > 10) { fprintf (stderr, "***p6fade: Expecting number"); fprintf (stderr, " between -10 and 10 for"); fprintf (stderr, " fade, found"); fprintf (stderr, " \"%s\".\n", argv [4] ); ok = 0; } if (ok) { NumEdges = argc - 5; Edges = NULL; if (NumEdges > 0) { Edges = malloc (NumEdges*sizeof (Edges [0] ) ); if (Edges == NULL) { fprintf (stderr, "***p6fade: Not"); fprintf (stderr, " enough memory.\n"); ok = 0; } } } if (ok) { for (i = 0; i < NumEdges; i++) { if (sscanf (argv [i + 5], "%d%c", Edges + i, & c) != 1) { fprintf (stderr, "***p6fade:"); fprintf (stderr, " Expecting"); fprintf (stderr, " number for edge,"); fprintf (stderr, " found \""); fprintf (stderr, "%s", argv [i + 4] ); fprintf (stderr, "\".\n"); ok = 0; } } } if (ok) { if (NumEdges > 2 && NumEdges%2 == 1 && Edges [0] != Edges [NumEdges - 1] ) { fprintf (stderr, "***p6fade:"); fprintf (stderr, " First across must be same"); fprintf (stderr, " as last across but found"); fprintf (stderr, " %d and", Edges [0] ); fprintf (stderr, " %d", Edges [NumEdges - 1] ); fprintf (stderr, ".\nCan omit last across.\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, "***p6fade: Improper"); fprintf (stderr, " input,"); fprintf (stderr, " must be P6 PPM.\n"); ok = 0; } } if (ok) Fade (width, height, r, g, b, fade, Edges, NumEdges); } if (Edges != NULL) free (Edges); return 0; }