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
00013 ROTATE (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   )
00024 {
00025   register short i;
00026   char msg[SLEN];
00027   double s, w, xmin, xmax, ymin, ymax, x[4], y[4], xp[4], yp[4], xc[3], yc[3];
00028 
00029   if (TIMES)
00030     TIMING (T_ROTATE);
00031   if (NAMES)
00032     {
00033       MESSAGE ('I', "");
00034       MESSAGE ('I', "ROTATE");
00035       MESSAGE ('I', "");
00036       sprintf (msg, " Input image:   %s", in->text);
00037       MESSAGE ('I', msg);
00038       sprintf (msg, " Rotation:    %12.4e", angle);
00039       MESSAGE ('I', msg);
00040       sprintf (msg, " Fill graylevel:             %12.4e", glev);
00041       MESSAGE ('I', msg);
00042       if (option < 0.0)
00043         {
00044           sprintf (msg, " Parametric cubic interpolation, alpha = %5.2f",
00045                    option);
00046           MESSAGE ('I', msg);
00047         }
00048       else if (option == 0.0)
00049         {
00050           MESSAGE ('I', " Bilinear interpolation");
00051         }
00052       else if (option > 0.0)
00053         {
00054           MESSAGE ('I', " Nearest-neighbor interpolation");
00055         }
00056       MESSAGE ('I', " ...............");
00057     }
00058 
00059   /* check input */
00060   if (!CHECKIMG (in))
00061     {
00062       MESSAGE ('E', " Can't identify image.");
00063       goto the_end;
00064     }
00065   else if (angle < -360.0 || 360.0 < angle)
00066     {
00067       MESSAGE ('E', " Rotation angle must be between -360 and +360 degrees.");
00068       goto the_end;
00069     }
00070 
00071   if (angle == (double) ((short) angle) && ((short) angle) % 90 == 0
00072       && option > 0.0)
00073     {
00074       /* perform transformation directly */
00075       if ((short) angle == -360 || (short) angle == 0 || (short) angle == 360)
00076         {
00077           TRNSFORM (in, ROTPM0, out);
00078         }
00079       else if ((short) angle == -270 || (short) angle == 90)
00080         {
00081           TRNSFORM (in, ROTP90, out);
00082         }
00083       else if ((short) angle == -180 || (short) angle == 180)
00084         {
00085           TRNSFORM (in, ROT180, out);
00086         }
00087       else if ((short) angle == -90 || (short) angle == 270)
00088         {
00089           TRNSFORM (in, ROTM90, out);
00090         }
00091     }
00092   else
00093     {
00094       /* compute transformation coefficients and perform transformation */
00095       s =
00096         sqrt ((double) in->npix * (double) in->npix +
00097               (double) in->nlin * (double) in->nlin) / 2.0;
00098       for (i = 0; i < 4; i++)
00099         {
00100           w =
00101             i * PI / 2.0 +
00102             atan (i % 2 ? (double) in->npix /
00103                   (double) in->nlin : (double) in->nlin / (double) in->npix);
00104           x[i] = (double) in->npix / 2.0 + s * cos (w);
00105           y[i] = (double) in->nlin / 2.0 + s * sin (w);
00106           xp[i] = (double) in->npix / 2.0 + s * cos (w + PI * angle / 180.0);
00107           yp[i] = (double) in->nlin / 2.0 + s * sin (w + PI * angle / 180.0);
00108           if (i == 0)
00109             {
00110               xmin = xp[i];
00111               xmax = xp[i];
00112               ymin = yp[i];
00113               ymax = yp[i];
00114             }
00115           else
00116             {
00117               xmin = min (xmin, xp[i]);
00118               xmax = max (xmax, xp[i]);
00119               ymin = min (ymin, yp[i]);
00120               ymax = max (ymax, yp[i]);
00121             }
00122         }
00123       for (i = 0; i < 4; i++)
00124         {
00125           xp[i] -= xmin;
00126           yp[i] -= ymin;
00127         }
00128       GEOMCOEF (x, y, xp, yp, 4, 3, xc, yc);
00129       GEOMWARP (in, in->nbnd,
00130                 (short) (ymax - ymin) + ((ymax - ymin) >
00131                                          (double) (short) (ymax - ymin)),
00132                 (short) (xmax - xmin) + ((xmax - xmin) >
00133                                          (double) (short) (xmax - xmin)), xc,
00134                 yc, 3, option, glev, out);
00135     }
00136 
00137 the_end:
00138   if (TIMES)
00139     TIMING (T_EXIT);
00140 }

Generated on Sun May 18 15:36:13 2003 for tclSadie by doxygen1.3