/*********************************************************************/ /* pnmshift - shift lines of a picture left or right by x xels */ /* Frank Neumann, October 1993 */ /* V1.2 27.11.1999 */ /* */ /* version history: */ /* V1.0 11.10.1993 first version */ /* V1.1 16.11.1993 Rewritten to be NetPBM.programming conforming */ /* V1.2 27.11.1999 Promoted from ppmshift to pnmshift. */ /*********************************************************************/ #include #include "pnm.h" /* global variables */ #ifdef AMIGA static char *version = "$VER: pnmshift 1.2 (27.11.99)"; /* Amiga version identification */ #endif /**************************/ /* start of main function */ /**************************/ int main( int argc, char* argv[] ) { FILE* ifp; int argn, rows, cols, format, i = 0, j = 0; xel *srcrow, *destrow; xel *xP = NULL, *xP2 = NULL; xelval maxval; int shift, nowshift; char *usage = "shift [pnmfile]\n shift: maximum number of xels to shift a line by\n"; /* parse in 'default' parameters */ pnm_init(&argc, argv); argn = 1; /* parse in shift number */ if (argn == argc) pm_usage(usage); if (sscanf(argv[argn], "%d", &shift) != 1) pm_usage(usage); if (shift < 0) pm_error("shift factor must be 0 or more"); ++argn; /* parse in filename (if present, stdin otherwise) */ if (argn != argc) { ifp = pm_openr(argv[argn]); ++argn; } else ifp = stdin; if (argn != argc) pm_usage(usage); /* read first data from file */ pnm_readpnminit(ifp, &cols, &rows, &maxval, &format); if (shift > cols) { shift = cols; pm_message("shift amount is larger than picture width - reset to %d", shift); } /* no error checking required here, pnmlib does it all for us */ srcrow = pnm_allocrow(cols); /* allocate a row of xel data for the new xels */ destrow = pnm_allocrow(cols); pnm_writepnminit(stdout, cols, rows, maxval, format, 0); /* get time of day to feed the random number generator */ srandom( time( (time_t*) 0 ) ); /** now do the shifting **/ /* the range by which a line is shifted lays in the range from */ /* -shift/2 .. +shift/2 xels; however, within this range it is */ /* randomly chosen */ for (i = 0; i < rows; i++) { if (shift != 0) nowshift = (random() % (shift+1)) - ((shift+1) / 2); else nowshift = 0; pnm_readpnmrow(ifp, srcrow, cols, maxval, format); xP = srcrow; xP2 = destrow; /* if the shift value is less than zero, we take the original xel line and */ /* copy it into the destination line translated to the left by x xels. The */ /* empty xels on the right end of the destination line are filled up with */ /* the xel that is the right-most in the original xel line. */ if (nowshift < 0) { xP+= abs(nowshift); for (j = 0; j < cols; j++) { *xP2 = *xP; xP2++; if (j < (cols+nowshift)-1) xP++; } } /* if the shift value is 0 or positive, the first xels of the */ /* destination line are filled with the first xel from the source line, */ /* and the rest of the source line is copied to the dest line */ else { for (j = 0; j < cols; j++) { *xP2 = *xP; xP2++; if (j >= nowshift) xP++; } } /* write out one line of graphic data */ pnm_writepnmrow(stdout, destrow, cols, maxval, format, 0); } pm_closer(ifp); pm_closew(stdout); pnm_freerow(srcrow); pnm_freerow(destrow); exit(0); }