Main Page   Data Structures   File List   Data Fields   Globals  

rotate.c

Go to the documentation of this file.
00001 #include        "sadie.h"
00002 
00003 /*-Copyright Information------------------------------------------------------*/
00004 /* Copyright (c) 1993 by the University of Arizona Digital Image Analysis Lab */
00005 /*----------------------------------------------------------------------------*/
00006 /*-General Information--------------------------------------------------------*/
00007 /*                                                                            */
00008 /*   This function rotates an image.                                          */
00009 /*                                                                            */
00010 /*----------------------------------------------------------------------------*/
00011 /*-Interface Information------------------------------------------------------*/
00012 void ROTATE (
00013 IMAGE  *in,     /*  I   Pointer to the input image.                           */
00014 double angle,   /*  I   Rotation angle,                                       */
00015                 /*      measured in degrees clockwise from the horizon.       */
00016 PIXEL  glev,    /*  I   Graylevel to fill otherwise empty pixels.             */
00017 double option,  /*  I   Switch, determines interpolation method:              */
00018                 /*      < 0.0   -   Cubic interpolation (alpha = option).     */
00019                 /*      = 0.0   -   Bilinear interpolation.                   */
00020                 /*      > 0.0   -   Nearest neighbor interpolation.           */
00021 IMAGE  **out    /*  O   Address of a pointer to the output image.             */
00022 /*----------------------------------------------------------------------------*/
00023 ) { register short i;
00024     char   msg[SLEN];
00025     double s, w, xmin, xmax, ymin, ymax, x[4], y[4], xp[4], yp[4], xc[3], yc[3];
00026 
00027     if (TIMES) TIMING(T_ROTATE);
00028     if (NAMES) {
00029         MESSAGE('I',"");
00030         MESSAGE('I',"ROTATE");
00031         MESSAGE('I',"");
00032         sprintf(msg," Input image:   %s",in->text);
00033         MESSAGE('I',msg);
00034         sprintf(msg," Rotation:    %12.4e",angle);
00035         MESSAGE('I',msg);
00036         sprintf(msg," Fill graylevel:             %12.4e",glev);
00037         MESSAGE('I',msg);
00038         if (option < 0.0) {
00039             sprintf(msg," Parametric cubic interpolation, alpha = %5.2f",option);
00040             MESSAGE('I',msg);
00041         } else if (option == 0.0) {
00042             MESSAGE('I'," Bilinear interpolation");
00043         } else if (option > 0.0) {
00044             MESSAGE('I'," Nearest-neighbor interpolation");
00045         }
00046         MESSAGE('I'," ...............");
00047     }
00048 
00049     /* check input */
00050     if (!CHECKIMG(in)) {
00051         MESSAGE('E'," Can't identify image.");
00052         goto the_end;
00053     } else if (angle < -360.0  ||  360.0 < angle) {
00054         MESSAGE('E'," Rotation angle must be between -360 and +360 degrees.");
00055         goto the_end;
00056     }
00057 
00058     if (angle == (double)((short)angle)  &&  ((short)angle)%90 == 0  &&  option > 0.0) {
00059         /* perform transformation directly */
00060         if ((short)angle == -360  ||  (short)angle == 0  ||  (short)angle == 360) {
00061             TRNSFORM(in,ROTPM0,out);
00062         } else if ((short)angle == -270  ||  (short)angle == 90) {
00063             TRNSFORM(in,ROTP90,out);
00064         } else if ((short)angle == -180  ||  (short)angle == 180) {
00065             TRNSFORM(in,ROT180,out);
00066         } else if ((short)angle == -90  ||  (short)angle == 270) {
00067             TRNSFORM(in,ROTM90,out);
00068         }
00069     } else {
00070         /* compute transformation coefficients and perform transformation */
00071         s = sqrt((double)in->npix*(double)in->npix + (double)in->nlin*(double)in->nlin) / 2.0;
00072         for (i=0; i<4; i++) {
00073             w = i*PI/2.0 + atan(i%2 ? (double)in->npix/(double)in->nlin : (double)in->nlin/(double)in->npix);
00074             x[i]  = (double)in->npix/2.0 + s*cos(w);
00075             y[i]  = (double)in->nlin/2.0 + s*sin(w);
00076             xp[i] = (double)in->npix/2.0 + s*cos(w+PI*angle/180.0);
00077             yp[i] = (double)in->nlin/2.0 + s*sin(w+PI*angle/180.0);
00078             if (i == 0) {
00079                 xmin = xp[i];
00080                 xmax = xp[i];
00081                 ymin = yp[i];
00082                 ymax = yp[i];
00083             } else {
00084                 xmin = min(xmin,xp[i]);
00085                 xmax = max(xmax,xp[i]);
00086                 ymin = min(ymin,yp[i]);
00087                 ymax = max(ymax,yp[i]);
00088             }
00089         }
00090         for (i=0; i<4; i++) {
00091             xp[i] -= xmin;
00092             yp[i] -= ymin;
00093         }
00094         GEOMCOEF(x,y,xp,yp,4,3,xc,yc);
00095         GEOMWARP(in,in->nbnd,(short)(ymax-ymin)+((ymax-ymin) > (double)(short)(ymax-ymin)),(short)(xmax-xmin)+((xmax-xmin) > (double)(short)(xmax-xmin)),xc,yc,3,option,glev,out);
00096     }
00097 
00098     the_end:
00099     if (TIMES) TIMING(T_EXIT);
00100 }

Generated on Wed Apr 9 08:56:11 2003 for TREES by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002