const char * UsageLines [] = {
"Usage: p6orient (output width) (output height)",
" (pivot point #1) (pivot point #2)",
"Shifts, rotates, and resizes input image so that",
" the two input pivots are positioned as",
" specified on the output image.",
"Output is cropped or padded (with gray) as needed",
" to reach specified output dimensions.",
"Reads P6 PPM image from standard input,",
" writes PPM image to standard output.",
"Each pivot point is of the form:",
" (input across),(input down)=(output across),(output down)",
" where the leftmost pixels are (- width/2) across,",
" and the topmost pixels are (- height/2) down.",
"For example, 0,0=0,0 matches the center of the input image",
" with the center of the output image.",
"Pixels are moved, repeated, or skipped to produce output",
" image. No recalculating of pixel values is done.",
"With appropriate choice of pivot points, p6orient can be",
" used to pad, crop, or resize an image.",
"For example: 0,0=0,0 0,1=0,1",
" will keep the center as the center and not resize,",
" if the supplied output dimensions are smaller than the input",
" it will crop, and,",
" if the supplied output dimensions are larger than the input",
" it will pad.",
"November 24, 2011. Newest is at gopher -p users/julianbr sdf.org",
};
const int NumUsageLines = sizeof (UsageLines)/sizeof (UsageLines [0] );
void OrientImage (
char (* * InputPixels) [3],
int InputWidth, int InputHeight,
int OutputWidth, int OutputHeight,
int InputPoint1Across, int InputPoint1Down,
int OutputPoint1Across, int OutputPoint1Down,
int InputPoint2Across, int InputPoint2Down,
int OutputPoint2Across, int OutputPoint2Down)
{
char PaddingPixel [] = {200, 200, 200};
int InputAcross, InputDown, OutputAcross, OutputDown;
long int InputAcrossRemainder, InputDownRemainder;
long int OutputDotOutput, OutputDotInput, OutputCrossInput;
int main (int argc, char * argv [] )
{
char (* * InputPixels) [3];
int InputWidth, InputHeight, OutputWidth, OutputHeight;
int InputPoint1Across, InputPoint1Down;
int InputPoint2Across, InputPoint2Down;
int OutputPoint1Across, OutputPoint1Down;
int OutputPoint2Across, OutputPoint2Down;
int i, ok;
if (argc < 2) {
for (i = 0; i < NumUsageLines; i++)
printf ("%s\n", UsageLines [i] );
}
else if (argc == 5) {
ok = 1;
if (sscanf (argv [1], "%d", & OutputWidth) != 1
|| OutputWidth < 1) {
fprintf (stderr, "***p6orient: Expecting output");
fprintf (stderr, " width,");
fprintf (stderr, " found \"%s\".\n", argv [1] );
ok = 0;
}
if (sscanf (argv [2], "%d", & OutputHeight) != 1
|| OutputHeight < 1) {
fprintf (stderr, "***p6orient: Expecting output");
fprintf (stderr, " height,");
fprintf (stderr, " found \"%s\".\n", argv [2] );
}
if (!ReadPivotPoint (
argv [3],
& InputPoint1Across, & InputPoint1Down,
& OutputPoint1Across, & OutputPoint1Down) )
ok = 0;
if (!ReadPivotPoint (
argv [4],
& InputPoint2Across, & InputPoint2Down,
& OutputPoint2Across, & OutputPoint2Down) )
ok = 0;
if (ok) {
if (OutputPoint1Across == OutputPoint2Across
&& OutputPoint1Down == OutputPoint2Down) {
fprintf (stderr, "***p6orient: Both pivot");
fprintf (stderr, " points are at same");
fprintf (stderr, " output location:");
fprintf (stderr, " %d,", OutputPoint1Across);
fprintf (stderr, "%d\n", OutputPoint1Down);
ok = 0;
}
}
if (ok) {
if (ReadImage (
& InputPixels,
& InputWidth, & InputHeight) ) {
OrientImage (
InputPixels,
InputWidth, InputHeight,
OutputWidth, OutputHeight,
InputPoint1Across, InputPoint1Down,
OutputPoint1Across, OutputPoint1Down,
InputPoint2Across, InputPoint2Down,
OutputPoint2Across, OutputPoint2Down
);
ClosePixels (InputPixels, InputHeight);
}
else
ClosePixels (InputPixels, InputHeight);
}
}
else {
fprintf (stderr, "Usage: p6orient");
fprintf (stderr, " (output width)");
fprintf (stderr, " (output height)");
fprintf (stderr, " (pivot point #1)");
fprintf (stderr, " (pivot point #2)\n");
}
return 0;
}