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