home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_2.4 / imgrotate / imrotate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  4.3 KB  |  142 lines

  1. /* 
  2.  * imrotate.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* IMROTATE:    funtion rotates image by given angle using
  10.  *            bilinear interpolation (slower method) or nearest pixel
  11.  *              (quicker method)
  12.  *                  usage: imrotate(imgIn, imgOut, angle, x0, y0, quickFlag)
  13.  *
  14.  */
  15.  
  16. #include <math.h>
  17. #include <tiffimage.h>          /* tiff info on images */
  18. #include <images.h>             /* for sun images */
  19.  
  20. #ifndef M_PI
  21. #define M_PI 3.141592654
  22. #endif
  23.  
  24. int
  25. imrotate (imgI, imgO, angle, x0, y0, quickFlag)
  26.      Image *imgI, *imgO;        /* I/O image structures */
  27.      double angle;              /* angle to be rotated */
  28.      long x0, y0;               /* top left of output img in input img */
  29.      short quickFlag;           /* bilinear interp if 0; nearest pix if 1 */
  30. {
  31.   unsigned char **imgIn,        /* image array */
  32.   **imgOut;                     /* output image */
  33.   long widthI, heightI;         /* input image size */
  34.   int gray;                     /* flag = 1 if image is gray; 0 otherwise */
  35.   double cosA, sinA;            /* cos and sin of rotation angle */
  36.   long widthIM1, heightIM1;     /* width, height minus 1 */
  37.   double startX, startY;        /* start of rows/columns in rot. img. */
  38.   double x, y;
  39.   register long intX, intY;     /* integer truncation of x,y */
  40.   unsigned char *pImg, *pImgP1; /* pointers to image locations */
  41.   unsigned char *pImgOut;       /* pointer to output image */
  42.   register double fractX, fractY;  /* roundoff minus truncation of x,y */
  43.   register double fXfY;         /* fractX times fractY */
  44.   long temp;
  45.   long iX, iY;
  46.  
  47. /* input and output images */
  48.   imgIn = imgI->img;
  49.   heightI = ImageGetHeight (imgI);
  50.   widthI = ImageGetWidth (imgI);
  51.   gray = (ImageIsGray (imgI)) ? 1 : 0;
  52.   imgOut = imgO->img;           /* ImageGetPtr (imgO); */
  53.  
  54. /* rotate image */
  55.   angle = angle * M_PI / 180.0;
  56.   cosA = cos (angle);
  57.   sinA = sin (angle);
  58.   startX = -(double) x0 *cosA + (double) y0 *sinA + (double) x0;
  59.   startY = -(double) x0 *sinA - (double) y0 *cosA + (double) y0;
  60.  
  61.  
  62.   widthIM1 = widthI - 1;
  63.   heightIM1 = heightI - 1;
  64.  
  65. /* rotate image by bilinear interpolation (slower method) */
  66.   if (quickFlag == 0) {
  67.     for (iY = 0, y = startY; iY < heightI; iY++) {
  68.       pImgOut = imgOut[iY];
  69.       for (iX = 0, x = startX; iX < widthI; iX++) {
  70.         intX = (long) x;
  71.         intY = (long) y;
  72.         if ((intX >= 1 && intX < widthIM1)
  73.             && (intY >= 1 && intY < heightIM1)) {
  74.           fractX = x - (double) intX;
  75.           fractY = y - (double) intY;
  76.           pImg = &(imgIn[intY][intX]);
  77.           pImgP1 = &(imgIn[intY + 1][intX]);
  78.           fXfY = fractX * fractY;
  79.           temp = (long) ((1.0 - fractX - fractY + fXfY) * *pImg
  80.                          + (fractX - fXfY) * *(pImg + 1)
  81.                          + (fractY - fXfY) * *pImgP1
  82.                          + fXfY * *(pImgP1 + 1) + 0.5);
  83.           if (!gray) {
  84.             if (temp >= 128)
  85.               temp = 255;
  86.             else
  87.               temp = 0;
  88.           }
  89.           else {
  90.             if (temp > 255)
  91.               temp = 255;
  92.             else if (temp < 0)
  93.               temp = 0;
  94.           }
  95.         }
  96.         else
  97.           temp = 0;
  98.         *pImgOut = (unsigned char) temp;
  99.         pImgOut++;
  100.         x += cosA;
  101.         y += sinA;
  102.       }
  103.       startY += cosA;
  104.       y = startY;
  105.       startX -= sinA;
  106.     }
  107.   }
  108. /* rotate image by nearest pixel (quicker method) */
  109.   else {
  110.     for (iY = 0, y = startY; iY < heightI; iY++) {
  111.       pImgOut = imgOut[iY];
  112.       for (iX = 0, x = startX; iX < widthI; iX++) {
  113.         intX = (long) x;
  114.         intY = (long) y;
  115.         if ((intX >= 1 && intX < widthIM1)
  116.             && (intY >= 1 && intY < heightIM1)) {
  117.           fractX = x - (double) intX;
  118.           fractY = y - (double) intY;
  119.           pImg = &(imgIn[intY][intX]);
  120.           pImgP1 = &(imgIn[intY + 1][intX]);
  121.           if (fractX < 0.5)
  122.             *pImgOut = (fractY < 0.5) ?
  123.               imgIn[intY][intX] : imgIn[intY + 1][intX];
  124.           else
  125.             *pImgOut = (fractY < 0.5) ?
  126.               imgIn[intY][intX + 1] : imgIn[intY + 1][intX + 1];
  127.         }
  128.         else
  129.           *pImgOut = 0;
  130.         pImgOut++;
  131.         x += cosA;
  132.         y += sinA;
  133.       }
  134.       startY += cosA;
  135.       y = startY;
  136.       startX -= sinA;
  137.     }
  138.   }
  139.  
  140.   return (1);
  141. }
  142.