home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / pnm / pnmflip.c < prev    next >
C/C++ Source or Header  |  1993-10-04  |  6KB  |  246 lines

  1. /* pnmflip.c - perform one or more flip operations on a portable anymap
  2. **
  3. ** Copyright (C) 1989 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "pnm.h"
  14.  
  15. static void leftright ARGS(( int* aP, int* bP, int* cP, int* dP, int* eP, int* fP ));
  16. static void topbottom ARGS(( int* aP, int* bP, int* cP, int* dP, int* eP, int* fP ));
  17. static void transpose ARGS(( int* aP, int* bP, int* cP, int* dP, int* eP, int* fP ));
  18.  
  19. int
  20. main( argc, argv )
  21.     int argc;
  22.     char* argv[];
  23.     {
  24.     FILE* ifp;
  25.     int argn, cols, rows, format, newrows, newcols;
  26.     int a, b, c, d, e, f;
  27.     register int row, col, newrow, newcol;
  28.     xelval maxval;
  29.     char* usage = "[-leftright|-lr] [-topbottom|-tb] [-transpose|-xy]\n            [-rotate90|-r90|-ccw] [-rotate270|r270|-cw]\n            [-rotate180|-r180] [pnmfile]";
  30.  
  31.     pnm_init( &argc, argv );
  32.  
  33.     argn = 1;
  34.  
  35.     /* Just check the validity of arguments here. */
  36.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  37.     {
  38.     if ( pm_keymatch( argv[argn], "-lr", 2 ) ||
  39.          pm_keymatch( argv[argn], "-leftright", 2 ) )
  40.         { }
  41.     else if ( pm_keymatch( argv[argn], "-tb", 3 ) ||
  42.          pm_keymatch( argv[argn], "-topbottom", 3 ) )
  43.         { }
  44.     else if ( pm_keymatch( argv[argn], "-xy", 2 ) ||
  45.          pm_keymatch( argv[argn], "-transpose", 3 ) )
  46.         { }
  47.     else if ( pm_keymatch( argv[argn], "-r90", 3 ) ||
  48.          pm_keymatch( argv[argn], "-rotate90", 8 ) ||
  49.          pm_keymatch( argv[argn], "-ccw", 3 ) )
  50.         { }
  51.     else if ( pm_keymatch( argv[argn], "-r270", 3 ) ||
  52.          pm_keymatch( argv[argn], "-rotate270", 8 ) ||
  53.          pm_keymatch( argv[argn], "-cw", 3 ) )
  54.         { }
  55.     else if ( pm_keymatch( argv[argn], "-r180", 3 ) ||
  56.          pm_keymatch( argv[argn], "-rotate180", 8 ) )
  57.         { }
  58.     else
  59.         pm_usage( usage );
  60.     ++argn;
  61.     }
  62.  
  63.     if ( argn != argc )
  64.     {
  65.     ifp = pm_openr( argv[argn] );
  66.     ++argn;
  67.     }
  68.     else
  69.     ifp = stdin;
  70.  
  71.     if ( argn != argc )
  72.     pm_usage( usage );
  73.  
  74.     pnm_readpnminit( ifp, &cols, &rows, &maxval, &format );
  75.  
  76.     /* Now go through the flags again, this time accumulating transforms. */
  77.     a = 1; b = 0;
  78.     c = 0; d = 1;
  79.     e = 0; f = 0;
  80.     argn = 1;
  81.     while ( argn < argc && argv[argn][0] == '-' )
  82.     {
  83.     if ( pm_keymatch( argv[argn], "-lr", 2 ) ||
  84.          pm_keymatch( argv[argn], "-leftright", 2 ) )
  85.         leftright( &a, &b, &c, &d, &e, &f );
  86.     else if ( pm_keymatch( argv[argn], "-tb", 3 ) ||
  87.          pm_keymatch( argv[argn], "-topbottom", 3 ) )
  88.         topbottom( &a, &b, &c, &d, &e, &f );
  89.     else if ( pm_keymatch( argv[argn], "-xy", 2 ) ||
  90.          pm_keymatch( argv[argn], "-transpose", 3 ) )
  91.         transpose( &a, &b, &c, &d, &e, &f );
  92.     else if ( pm_keymatch( argv[argn], "-r90", 3 ) ||
  93.          pm_keymatch( argv[argn], "-rotate90", 8 ) ||
  94.          pm_keymatch( argv[argn], "-ccw", 3 ) )
  95.         {
  96.         transpose( &a, &b, &c, &d, &e, &f );
  97.         topbottom( &a, &b, &c, &d, &e, &f );
  98.         }
  99.     else if ( pm_keymatch( argv[argn], "-r270", 3 ) ||
  100.          pm_keymatch( argv[argn], "-rotate270", 8 ) ||
  101.          pm_keymatch( argv[argn], "-cw", 3 ) )
  102.         {
  103.         transpose( &a, &b, &c, &d, &e, &f );
  104.         leftright( &a, &b, &c, &d, &e, &f );
  105.         }
  106.     else if ( pm_keymatch( argv[argn], "-r180", 3 ) ||
  107.          pm_keymatch( argv[argn], "-rotate180", 8 ) )
  108.         {
  109.         leftright( &a, &b, &c, &d, &e, &f );
  110.         topbottom( &a, &b, &c, &d, &e, &f );
  111.         }
  112.     else
  113.         pm_error( "shouldn't happen!" );
  114.     ++argn;
  115.     }
  116.  
  117.     /* Okay, we've got a matrix. */
  118.     newcols = abs( a ) * cols + abs( c ) * rows;
  119.     newrows = abs( b ) * cols + abs( d ) * rows;
  120.  
  121.     if ( b == 0 && d == 1 && f == 0 )
  122.     {
  123.     /* In this case newrow is always equal to row, so we can do the
  124.     ** transform line by line and avoid in-memory buffering altogether.
  125.     */
  126.     register xel* xelrow;
  127.     register xel* newxelrow;
  128.     register xel* xP;
  129.  
  130.     xelrow = pnm_allocrow( cols );
  131.     newxelrow = pnm_allocrow( newcols );
  132.     pnm_writepnminit( stdout, newcols, newrows, maxval, format, 0 );
  133.  
  134.     for ( row = 0; row < rows; ++row )
  135.         {
  136.         pnm_readpnmrow( ifp, xelrow, cols, maxval, format );
  137.         for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
  138.         {
  139.         /* Transform a point:
  140.         **
  141.         **            [ a b 0 ]
  142.         **  [ x y 1 ] [ c d 0 ] = [ x2 y2 1 ]
  143.         **            [ e f 1 ]
  144.         */
  145.         newcol = a * col + c * row + e * ( newcols - 1 );
  146.         newxelrow[newcol] = *xP;
  147.         }
  148.         pnm_writepnmrow( stdout, newxelrow, newcols, maxval, format, 0 );
  149.         }
  150.     }
  151. #ifdef notdef
  152.     else if ( a == 0 && b != 0 && c != 0 && d == 0 )
  153.     {
  154.     /* This case is likely to thrash.  Can't think of any fix at the
  155.     ** moment, though.
  156.     */
  157.     }
  158. #endif /* notdef */
  159.     else
  160.     {
  161.     /* Generic case.  Read in the anymap a line at a time and transform
  162.     ** it into an in-memory array.
  163.     */
  164.     register xel* xelrow;
  165.     register xel** newxels;
  166.     register xel* xP;
  167.  
  168.     xelrow = pnm_allocrow( cols );
  169.     newxels = pnm_allocarray( newcols, newrows );
  170.  
  171.     for ( row = 0; row < rows; ++row )
  172.         {
  173.         pnm_readpnmrow( ifp, xelrow, cols, maxval, format );
  174.         for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
  175.         {
  176.         /* Transform a point:
  177.         **
  178.         **            [ a b 0 ]
  179.         **  [ x y 1 ] [ c d 0 ] = [ x2 y2 1 ]
  180.         **            [ e f 1 ]
  181.         */
  182.         newcol = a * col + c * row + e * ( newcols - 1 );
  183.         newrow = b * col + d * row + f * ( newrows - 1 );
  184.         newxels[newrow][newcol] = *xP;
  185.         }
  186.         }
  187.  
  188.     pnm_writepnm( stdout, newxels, newcols, newrows, maxval, format, 0 );
  189.     }
  190.  
  191.     pm_close( ifp );
  192.     pm_close( stdout );
  193.  
  194.     exit( 0 );
  195.     }
  196.  
  197. static void
  198. leftright( aP, bP, cP, dP, eP, fP )
  199.     int* aP;
  200.     int* bP;
  201.     int* cP;
  202.     int* dP;
  203.     int* eP;
  204.     int* fP;
  205.     {
  206.     *aP = - *aP;
  207.     *cP = - *cP;
  208.     *eP = - *eP + 1;
  209.     }
  210.  
  211. static void
  212. topbottom( aP, bP, cP, dP, eP, fP )
  213.     int* aP;
  214.     int* bP;
  215.     int* cP;
  216.     int* dP;
  217.     int* eP;
  218.     int* fP;
  219.     {
  220.     *bP = - *bP;
  221.     *dP = - *dP;
  222.     *fP = - *fP + 1;
  223.     }
  224.  
  225. static void
  226. transpose( aP, bP, cP, dP, eP, fP )
  227.     int* aP;
  228.     int* bP;
  229.     int* cP;
  230.     int* dP;
  231.     int* eP;
  232.     int* fP;
  233.     {
  234.     register int t;
  235.  
  236.     t = *aP;
  237.     *aP = *bP;
  238.     *bP = t;
  239.     t = *cP;
  240.     *cP = *dP;
  241.     *dP = t;
  242.     t = *eP;
  243.     *eP = *fP;
  244.     *fP = t;
  245.     }
  246.