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