home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 309.lha / PBM_PLUS / ppm / ppmshear.c < prev    next >
C/C++ Source or Header  |  1980-12-04  |  3KB  |  112 lines

  1. /* ppmshear.c - read a portable pixmap and shear it by some angle
  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 <stdio.h>
  14. #include <math.h>
  15. #define M_PI    3.14159265358979323846
  16. #include "ppm.h"
  17.  
  18. #define SCALE 4096
  19. #define HALFSCALE 2048
  20.  
  21. main( argc, argv )
  22. int argc;
  23. char *argv[];
  24.     {
  25.     FILE *ifd;
  26.     pixel **pixels;
  27.     register pixel *newpixelrow, *pP, *npP;
  28.     pixel bgpixel, prevpixel;
  29.     int argn, rows, cols, newcols, row, col;
  30.     pixval maxval;
  31.     float fangle, shearfac, new0;
  32.     int intnew0;
  33.     register long fracnew0, omfracnew0;
  34.     char *usage = "<angle> [ppmfile]";
  35.  
  36.     pm_progname = argv[0];
  37.  
  38.     argn = 1;
  39.  
  40.     if ( argn == argc )
  41.     pm_usage( usage );
  42.     if ( sscanf( argv[argn], "%g", &fangle ) != 1 )
  43.     pm_usage( usage );
  44.     argn++;
  45.     if ( fangle <= -90.0 || fangle >= 90.0 )
  46.     pm_error( "angle must be between -90 and 90", 0,0,0,0,0 );
  47.     fangle = fangle * M_PI / 180.0;    /* convert to radians */
  48.     shearfac = tan( fangle );
  49.     if ( shearfac < 0.0 )
  50.     shearfac = -shearfac;
  51.  
  52.     if ( argn != argc )
  53.     {
  54.     ifd = pm_openr( argv[argn] );
  55.     argn++;
  56.     }
  57.     else
  58.     ifd = stdin;
  59.  
  60.     if ( argn != argc )
  61.     pm_usage( usage );
  62.  
  63.     ppm_pbmmaxval = 255;    /* use larger value for better results */
  64.     pixels = ppm_readppm( ifd, &cols, &rows, &maxval );
  65.  
  66.     pm_close( ifd );
  67.  
  68.     newcols = rows * shearfac + cols + 0.999999;
  69.  
  70.     ppm_writeppminit( stdout, newcols, rows, maxval );
  71.     newpixelrow = ppm_allocrow( newcols );
  72.  
  73.     bgpixel = ppm_backgroundpixel( pixels, cols, rows );
  74.  
  75.     for ( row = 0; row < rows; row++ )
  76.     {
  77.     if ( fangle > 0.0 )
  78.         new0 = row * shearfac;
  79.     else
  80.         new0 = ( rows - row ) * shearfac;
  81.     intnew0 = (int) new0;
  82.     fracnew0 = ( new0 - intnew0 ) * SCALE;
  83.     omfracnew0 = SCALE - fracnew0;
  84.  
  85.     for ( col = 0, npP = newpixelrow; col < newcols; col++, npP++ )
  86.         *npP = bgpixel;
  87.  
  88.     prevpixel = bgpixel;
  89.  
  90.     for ( col = 0, npP = &(newpixelrow[intnew0]), pP = pixels[row]; col < cols; col++, npP++, pP++ )
  91.         {
  92.         PPM_ASSIGN( *npP,
  93.         ( fracnew0 * PPM_GETR(prevpixel) + omfracnew0 * PPM_GETR(*pP) + HALFSCALE ) / SCALE,
  94.         ( fracnew0 * PPM_GETG(prevpixel) + omfracnew0 * PPM_GETG(*pP) + HALFSCALE ) / SCALE,
  95.         ( fracnew0 * PPM_GETB(prevpixel) + omfracnew0 * PPM_GETB(*pP) + HALFSCALE ) / SCALE );
  96.         prevpixel = *pP;
  97.         }
  98.     if ( fracnew0 > 0 )
  99.         {
  100.         npP = &(newpixelrow[intnew0 + cols]);
  101.         PPM_ASSIGN( *npP,
  102.         ( fracnew0 * PPM_GETR(prevpixel) + omfracnew0 * PPM_GETR(bgpixel) + HALFSCALE ) / SCALE,
  103.         ( fracnew0 * PPM_GETG(prevpixel) + omfracnew0 * PPM_GETG(bgpixel) + HALFSCALE ) / SCALE,
  104.         ( fracnew0 * PPM_GETB(prevpixel) + omfracnew0 * PPM_GETB(bgpixel) + HALFSCALE ) / SCALE );
  105.         }
  106.  
  107.     ppm_writeppmrow( stdout, newpixelrow, newcols, maxval );
  108.     }
  109.  
  110.     exit( 0 );
  111.     }
  112.