char * UsageLines [] = { "Usage p4width (width)", "Resizes width of P4 PBM image on standard input, writes", "to specified width at standard output. Height remains", "the same. Pixels are repeated or skipped to fit.", }; int NumUsageLines = sizeof (UsageLines) / sizeof (UsageLines [0] ); #include <stdio.h> void ResizeWidth (int InputWidth, int OutputWidth, int Height) { int InputValue; unsigned char InputWeight, OutputWeight, OutputValue; int EndOfInput, Remainder, InputPosition, LineNum; printf ("P4\n%d %d\n", OutputWidth, Height); EndOfInput = 0; for (LineNum = 0; LineNum < Height; LineNum++) { InputWeight = 1; OutputValue = 0; OutputWeight = 128; Remainder = InputWidth/2; for (InputPosition = 0; InputPosition < InputWidth; InputPosition++) { InputWeight /= 2; if (InputWeight == 0) { if (!EndOfInput) { InputValue = getchar (); if (InputValue == EOF) EndOfInput = 1; } InputWeight = 128; } Remainder += OutputWidth; while (Remainder >= InputWidth) { if (InputValue & InputWeight) OutputValue += OutputWeight; OutputWeight /= 2; if (OutputWeight == 0) { putchar (OutputValue); OutputValue = 0; OutputWeight = 128; } Remainder -= InputWidth; } } if (OutputWeight < 128) putchar (OutputValue); } if (EndOfInput) fprintf (stderr, "***p4width: Not enough input image data.\n"); else if (getchar () != EOF) fprintf (stderr, "***p4width: Too much input image data.\n"); } int main (int argc, char * * argv) { int InputWidth, OutputWidth, Height, i, ok; char c; if (argc == 2) { ok = 1; if (scanf ("P4\n%d %d\n", & InputWidth, & Height) != 2) { fprintf (stderr, "***p4width: Improper input, must"); fprintf (stderr, " be P4 PBM image.\n"); ok = 0; } if (sscanf (argv [1], "%d%c", & OutputWidth, & c) != 1 || OutputWidth < 1) { fprintf (stderr, "***p4width: Expecting number > 0 for"); fprintf (stderr, " width, found \"%s\".\n", argv [1] ); ok = 0; } if (ok) ResizeWidth (InputWidth, OutputWidth, Height); } else { for (i = 0; i < NumUsageLines; i++) printf ("%s\n", UsageLines [i] ); } return 0; }