char * (UsageLines [] ) = { "p4grow: Reads P4 PBM image from standard input,", "writes P4 PBM image to standard output.", "Output will be same dimensions as input.", "Output pixel will be '1' if input pixel is '1',", "or if any adjacent input pixel (including", "diagonal) is '1'.", "", "March 4, 2023: Latest at gopher -p users/julianbr sdf.org", }; int NumUsageLines = sizeof (UsageLines) / sizeof (UsageLines [0] ); #include <stdio.h> void GrowImage (int width, int height, unsigned char * Previous, unsigned char * Current, unsigned char * Next) { unsigned int cout; int i, j, k, cin, linewidth; printf ("P4\n%d %d\n", width, height); linewidth = (width + 7)/8; cin = 0; for (k = 0; k < linewidth; k++) { if (cin != EOF) cin = getchar (); Next [k] = cin; } for (i = 0; i < height; i++) { for (k = 0; k < linewidth; k++) { if (i > 0) Previous [k] = Current [k]; Current [k] = Next [k]; if (i + 1 < height) { if (cin != EOF) cin = getchar (); Next [k] = cin; } } for (j = 0; j < width; j++) { if (j%8 == 0) cout = 0; if ( (i > 0 && j > 0 && Previous [(j - 1)/8] & (1 << (7 - (j - 1)%8) ) ) || (i > 0 && Previous [j/8] & (1 << (7 - j%8) ) ) || (i > 0 && j + 1 < width && Previous [(j + 1)/8] & (1 << (7 - (j + 1)%8) ) ) || (j > 0 && Current [(j - 1)/8] & (1 << (7 - (j - 1)%8) ) ) || Current [j/8] & (1 << (7 - j%8) ) || (j + 1 < width && Current [(j + 1)/8] & (1 << (7 - (j + 1)%8) ) ) || (i + 1 < height && j > 0 && Next [(j - 1)/8] & (1 << (7 - (j - 1)%8) ) ) || (i + 1 < height && Next [j/8] & (1 << (7 - j%8) ) ) || (i + 1 < height && j + 1 < width && Next [(j + 1)/8] & (1 << (7 - (j + 1)%8) ) ) ) cout += 1 << (7 - j%8); if (j%8 == 7 || j + 1 == width) putchar (cout); } } if (cin == EOF) fprintf (stderr, "***p4grow: Not enough input image data.\n"); else if (getchar () != EOF) fprintf (stderr, "***p4grow: Too much input image data.\n"); j = 0; cout = 0; } #include <stdlib.h> void Grow (void) { unsigned char * Previous, * Current, * Next; int width, height, linewidth; if (scanf ("P4\n%d %d\n", & width, & height) != 2) { fprintf (stderr, "***p4grow: Input must be P4 type.\n"); } else { linewidth = (width + 7)/8; Previous = NULL; Current = NULL; Next = NULL; Previous = malloc (linewidth); if (Previous != NULL) Current = malloc (linewidth); if (Current != NULL) Next = malloc (linewidth); GrowImage (width, height, Previous, Current, Next); Next = NULL; if (Previous != NULL) free (Previous); if (Current != NULL) free (Current); if (Next != NULL) free (Next); } } int main (int argc, char * * argv) { int i; if (argc > 1) { fprintf (stderr, "Usage: %s\n", argv [0] ); for (i = 0; i < NumUsageLines; i++) printf ("%s\n", UsageLines [i] ); } else Grow (); return 0; }