00001 #include "sadie.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 void
00013 ROTATE (IMAGE * in,
00014 double angle,
00015
00016 PIXEL glev,
00017 double option,
00018
00019
00020
00021 IMAGE ** out
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
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
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
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 }