home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / imgtrans.c < prev    next >
C/C++ Source or Header  |  1990-04-20  |  4KB  |  159 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    imgtrans.c (Image Transformation)
  6.  * Purpose:    Routines to orthogonally translate buffers.
  7.  * Subroutine:    rotate_buf()            returns: void
  8.  * Copyright:    1988 Smithsonian Astrophysical Observatory
  9.  *        You may do anything you like with this file except remove
  10.  *        this copyright.  The Smithsonian Astrophysical Observatory
  11.  *        makes no representations about the suitability of this
  12.  *        software for any purpose.  It is provided "as is" without
  13.  *        express or implied warranty.
  14.  * Modified:    {0} Michael VanHilst    initial version          8 December 1988
  15.  *        {n} <who> -- <does what> -- <when>
  16.  */
  17.  
  18. #include <stdio.h>        /* define stderr */
  19. #include "hfiles/define.h"    /* define MIN, MAX, etc. */
  20.  
  21. /*
  22.  * Subroutine:    rotate_buf
  23.  * Purpose:    Rotate a buffer as indicated by the code
  24.  * Parameter:    rotcode
  25.  *     0-3 = rotate clockwise by code * 90 degrees
  26.  *     4-7 = flip y axis then rotate clockwise by (code - 4) * 90 degrees
  27.  * Called by:    load_image() in ImageRead.c
  28.  */
  29. void rotate_buf ( buf, flip, rotcode, width, height, buf_squared, buf_doubled )
  30.      short *buf;
  31.      int flip;
  32.      int rotcode;
  33.      int width, height;
  34.      int buf_squared, buf_doubled;
  35. {
  36.   int maxdim;
  37.   void xflip_buf(), yflip_buf(), zflip_buf(), cwturn_buf(), ccwturn_buf();
  38.   void transfer_buf();
  39.   static void square_buf(), unsquare_buf();
  40.  
  41.   if( flip )
  42.     rotcode += 4;
  43.   if( rotcode & 1 ) {
  44.     if( buf_doubled ) {
  45.       short *dst;
  46.       dst = buf + (width * height);
  47.       transfer_buf(buf, dst, width, height, rotcode);
  48.       transfer_buf(dst, buf, width, height, 0);
  49.       return;
  50.     } else if( buf_squared || (width == height) ) {
  51.       maxdim = MAX(width, height);
  52.     } else {
  53.       (void)fprintf(stderr, "ERROR: no buffer to rotate image\n");
  54.       return;
  55.     }
  56.   }
  57.   /* if not a square or like a square with filler on bottom */
  58.   switch( rotcode ) {
  59.   case 0:
  60.     return;
  61.   case 2:
  62.     /* 180 degree rotation */
  63.     zflip_buf(buf, width, height);
  64.     break;
  65.   case 4:
  66.     /* flip along y axis */
  67.     xflip_buf(buf, width, height);
  68.     break;
  69.   case 6:
  70.     /* flip then rotate 180 degrees clockwise */
  71.     yflip_buf(buf, width, height);
  72.     break;
  73.   case 5:
  74.     /* flip along y axis, then rotate */
  75.     xflip_buf(buf, width, height);
  76.   case 1:
  77.     /* 90 degree clockwise rotation */
  78.     if( width < height )
  79.       square_buf(buf, width, height, 1);
  80.     cwturn_buf(buf, maxdim);
  81.     if( height < width )
  82.       unsquare_buf(buf, width, height, 0);
  83.     break;
  84.   case 7:
  85.     /* flip along y axis, then rotate */
  86.     xflip_buf(buf, width, height);
  87.   case 3:
  88.     /* 270 degree clockwise rotation */
  89.     if( width < height )
  90.       square_buf(buf, width, height, 0);
  91.     ccwturn_buf(buf, maxdim);
  92.     if( height < width )
  93.       unsquare_buf(buf, width, height, 1);
  94.     break;
  95.   }
  96. }
  97.  
  98. /*
  99.  * Subroutine:    square_buf
  100.  * Purpose:    Rearrange lines in a buffer for square symmetry
  101.  * Exception:    Assumes that height of rectangle is greater than width
  102.  * Parameter:    left
  103.  *    left = 1 will put reactangle on left with lines padded out
  104.  *    left = 0 will put rectangle on right with padded in front of lines
  105.  */
  106. static void square_buf ( buf, width, height, left )
  107.      short *buf;
  108.      int width, height;
  109.      int left;
  110. {
  111.   short *rectline, *sqline;
  112.   int bytes;
  113.  
  114.   /* make buf square with lines filled to end */
  115.   rectline = buf + ((height - 1) * width);
  116.   if( left == 0 )
  117.     sqline = buf + (height * height) - width;
  118.   else
  119.     sqline = buf + (height * height) - height;
  120.   bytes = width * sizeof(short);
  121.   while( sqline > rectline ) {
  122.     bcopy((char *)rectline, (char *)sqline, bytes);
  123.     rectline -= width;
  124.     sqline -= height;
  125.   }
  126. }
  127.  
  128. /*
  129.  * Subroutine:    unsquare_buf
  130.  * Purpose:    Make rectangular data in square buffer occupy rectangle at top
  131.  * Exception:    Assumes output height is greater than width
  132.  *    left = 1 moves data which is on left side of square
  133.  *    left = 0 moves data which is on right side of square
  134.  */
  135. static void unsquare_buf ( buf, width, height, left )
  136.      short *buf;
  137.      int width, height;
  138.      int left;
  139. {
  140.   short *rectline, *sqline;
  141.   int bytes;
  142.   int i;
  143.  
  144.   /* make buf square with lines filled to end */
  145.   if( left == 0 ) {
  146.     rectline = buf;
  147.     sqline = buf + (height - width);
  148.   } else {
  149.     rectline = buf + width;
  150.     sqline = buf + height;
  151.   }
  152.   bytes = width * sizeof(short);
  153.   for( i=0; i<height; i++ ) {
  154.     bcopy((char *)sqline, (char *)rectline, bytes);
  155.     rectline += width;
  156.     sqline += height;
  157.   }
  158. }
  159.