00001 #include "sadie.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 static void FHT1D (
00015 short option,
00016
00017
00018 short size,
00019 short p,
00020 short *a,
00021 short *pwr,
00022 double *sine,
00023 double *tang,
00024 double *array
00025
00026 ) { register short o, n, m, l, k, j, i;
00027 register double t, u, v, w, x, y;
00028
00029 if (TIMES) TIMING (T_FHT1D);
00030
00031 a[0] = 0;
00032 a[1] = 1;
00033 for (i=2; i<=p/2+p%2; i++) {
00034 for (j=0; j<pwr[i-1]; j++) {
00035 a[j+pwr[i-1]] = (a[j] *= 2) + 1;
00036 }
00037 }
00038 for (i=1; i<pwr[p/2]; i++) {
00039 k = i;
00040 l = m = pwr[p/2]*a[i];
00041 t = array[k];
00042 array[k] = array[m];
00043 array[m] = t;
00044 for (j=1; j<=a[i]-1; j++) {
00045 k += pwr[p/2];
00046 m = l + a[j];
00047 t = array[k];
00048 array[k] = array[m];
00049 array[m] = t;
00050 }
00051 }
00052 for (i=0; i<size-1; i+=2) {
00053 t = array[i] + array[i+1];
00054 u = array[i] - array[i+1];
00055 array[i ] = t;
00056 array[i+1] = u;
00057 }
00058 for (i=0; i<size-3; i+=4) {
00059 t = array[i ] + array[i+2];
00060 u = array[i+1] + array[i+3];
00061 v = array[i ] - array[i+2];
00062 w = array[i+1] - array[i+3];
00063 array[i ] = t;
00064 array[i+1] = u;
00065 array[i+2] = v;
00066 array[i+3] = w;
00067 }
00068 for (i=2; i<p; i++) {
00069 for (j=0; j<size; j+=pwr[i+1]) {
00070 t = array[j] + array[j+pwr[i]];
00071 u = array[j] - array[j+pwr[i]];
00072 array[j ] = t;
00073 array[j+pwr[i]] = u;
00074 l = j + 1;
00075 m = j + pwr[i] - 1;
00076 n = l + pwr[i];
00077 o = m + pwr[i];
00078 for (k=pwr[p-i-1]; k<=size/4; k+=pwr[p-i-1]) {
00079 t = array[n] + tang[k]*array[o];
00080 x = array[o] - sine[k]*t;
00081 y = t + tang[k]*x;
00082 t = array[l] + y;
00083 u = array[m] - x;
00084 v = array[l] - y;
00085 w = array[m] + x;
00086 array[l++] = t;
00087 array[m--] = u;
00088 array[n++] = v;
00089 array[o--] = w;
00090 }
00091 }
00092 }
00093
00094 if (option == FORWARD) for (i=0; i<size; array[i++]/=(double)size);
00095
00096 the_end:
00097 if (TIMES) TIMING(T_EXIT);
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 void FHT2D (
00117 IMAGE *in,
00118 short option,
00119
00120
00121 IMAGE **out
00122
00123 ) { register short i, j, k, p, *a=0, *pwr=0;
00124 char msg[SLEN];
00125 double *sine=0, *tang=0, *array=0, pinc, psum;
00126 PIXEL t, u, v, w;
00127 IMAGE *img;
00128
00129 if (TIMES) TIMING(T_FHT2D);
00130 if (NAMES) {
00131 MESSAGE('I',"");
00132 MESSAGE('I',"FHT2D");
00133 MESSAGE('I',"");
00134 sprintf(msg," Input image: %s",in->text);
00135 MESSAGE('I',msg);
00136 if (option == FORWARD) {
00137 MESSAGE('I'," Forward FHT");
00138 } else if (option == INVERSE) {
00139 MESSAGE('I'," Inverse FHT");
00140 }
00141 MESSAGE('I'," ...............");
00142 }
00143
00144
00145 if (!CHECKIMG(in)) {
00146 MESSAGE('E'," Can't identify image.");
00147 goto the_end;
00148 } else if (in->nlin != 1L<<rnd(log10((double)in->nlin)/log10(2.0))) {
00149 MESSAGE('E'," Number of lines must be a power of two.");
00150 goto the_end;
00151 } else if (in->npix != 1L<<rnd(log10((double)in->npix)/log10(2.0))) {
00152 MESSAGE('E'," Number of pixels/line must be a power of two.");
00153 goto the_end;
00154 } else if (option != FORWARD && option != INVERSE) {
00155 MESSAGE('E'," Transformation option must be either FORWARD or INVERSE.");
00156 goto the_end;
00157 } else if (option == FORWARD && in->nlin != in->npix || option == INVERSE && in->nlin != in->npix/2) {
00158 MESSAGE('E'," Number of lines must be equal to number of pixels/line.");
00159 goto the_end;
00160 }
00161
00162
00163 if (!CHECKIMG(*out)) GETMEM(in->nbnd,in->nlin,(short)((option == FORWARD ? 2.0 : 0.5)*in->npix),out);
00164 if (!*out) goto the_end;
00165 img = option == FORWARD ? in : *out;
00166
00167
00168 if (img->nlin == 1) {
00169 (*out)->data[0][0][0] = in->data[0][0][0];
00170 if (option == FORWARD) {
00171 (*out)->data[0][0][1] = 0.0;
00172 }
00173 goto the_end;
00174 }
00175
00176
00177 i = max(img->nlin,img->npix);
00178 p = rnd(log10((double)i)/log10(2.0));
00179 if (!(a=(short *)malloc((1<<p/2+p%2)*sizeof(short)))) {
00180 MESSAGE('E'," Memory request failed.");
00181 goto the_end;
00182 }
00183
00184
00185 if (!(pwr=(short *)malloc((p+1)*sizeof(short)))) {
00186 MESSAGE('E'," Memory request failed.");
00187 goto the_end;
00188 }
00189 for (j=0; j<=p; pwr[j]=1<<j,j++);
00190
00191
00192 if (!(sine=(double *)malloc((i/4+1)*sizeof(double)))) {
00193 MESSAGE('E'," Memory request failed.");
00194 goto the_end;
00195 }
00196 if (!(tang=(double *)malloc((i/4+1)*sizeof(double)))) {
00197 MESSAGE('E'," Memory request failed.");
00198 goto the_end;
00199 }
00200 for (j=0; j<=i/4; j++) {
00201 sine[j] = sin((2.0*PI*(double)j)/(double)i);
00202 tang[j] = tan(( PI*(double)j)/(double)i);
00203 }
00204
00205
00206 if (!(array=(double *)malloc(i*sizeof(double)))) {
00207 MESSAGE('E'," Memory request failed.");
00208 goto the_end;
00209 }
00210
00211
00212 if (LINES && !PROGRESS(psum=0.0)) goto the_end;
00213 pinc = 1.0/(double)img->nbnd/(double)(img->nlin+img->npix);
00214
00215
00216 for (i=0; i<(*out)->nbnd; i++) {
00217
00218 if (option == FORWARD) {
00219
00220 for (j=0; j<(*out)->nlin/2; j++) {
00221 for (k=0; k<(*out)->npix/4; k++) {
00222 (*out)->data[i][j][k] = in->data[i][in->nlin/2+j][in->npix/2+k];
00223 (*out)->data[i][(*out)->nlin/2+j][k] = in->data[i][j][in->npix/2+k];
00224 (*out)->data[i][j][(*out)->npix/4+k] = in->data[i][in->nlin/2+j][k];
00225 (*out)->data[i][(*out)->nlin/2+j][(*out)->npix/4+k] = in->data[i][j][k];
00226 }
00227 }
00228 } else {
00229
00230 for (j=0; j<(*out)->nlin/2; j++) {
00231 for (k=0; k<(*out)->npix/2; k++) {
00232 (*out)->data[i][j][k] = in->data[i][in->nlin/2+j][in->npix/2+2*k] - in->data[i][in->nlin/2+j][in->npix/2+2*k+1];
00233 (*out)->data[i][(*out)->nlin/2+j][k] = in->data[i][j][in->npix/2+2*k] - in->data[i][j][in->npix/2+2*k+1];
00234 (*out)->data[i][j][(*out)->npix/2+k] = in->data[i][in->nlin/2+j][2*k] - in->data[i][in->nlin/2+j][2*k+1];
00235 (*out)->data[i][(*out)->nlin/2+j][(*out)->npix/2+k] = in->data[i][j][2*k] - in->data[i][j][2*k+1];
00236 }
00237 }
00238 }
00239
00240
00241 for (j=0; j<img->nlin; j++) {
00242 for (k=0; k<img->npix; k++) {
00243 array[k] = (double)(*out)->data[i][j][k];
00244 }
00245 FHT1D(option,img->npix,p,a,pwr,sine,tang,array);
00246 for (k=0; k<img->npix; k++) {
00247 (*out)->data[i][j][k] = (PIXEL)array[k];
00248 }
00249 if (LINES && !PROGRESS(psum+=pinc)) goto the_end;
00250 }
00251
00252
00253 for (k=img->npix-1; k>=0; k--) {
00254 for (j=0; j<img->nlin; j++) {
00255 array[j] = (double)(*out)->data[i][j][k];
00256 }
00257 FHT1D(option,img->nlin,p,a,pwr,sine,tang,array);
00258 if (option == FORWARD) {
00259 for (j=0; j<img->nlin; j++) {
00260 (*out)->data[i][j][2*k] = (PIXEL)array[j];
00261 }
00262 } else {
00263 for (j=0; j<img->nlin; j++) {
00264 (*out)->data[i][j][k] = (PIXEL)array[j];
00265 }
00266 }
00267 if (LINES && !PROGRESS(psum+=pinc)) goto the_end;
00268 }
00269
00270 if (option == FORWARD) {
00271
00272 (*out)->data[i][0][1] = (*out)->data[i][(*out)->nlin/2][1] = (*out)->data[i][0][(*out)->npix/2+1] = (*out)->data[i][(*out)->nlin/2][(*out)->npix/2+1] = 0.0;
00273 for (k=2; k<(*out)->npix/2; k+=2) {
00274 (*out)->data[i][0][(*out)->npix-k+1] = -((*out)->data[i][0][k+1] = ((*out)->data[i][0][(*out)->npix-k]-(*out)->data[i][0][k]) / 2.0);
00275 (*out)->data[i][0][(*out)->npix-k ] = ((*out)->data[i][0][k ] = ((*out)->data[i][0][(*out)->npix-k]+(*out)->data[i][0][k]) / 2.0);
00276 (*out)->data[i][(*out)->nlin/2][(*out)->npix-k+1] = -((*out)->data[i][(*out)->nlin/2][k+1] = ((*out)->data[i][(*out)->nlin/2][(*out)->npix-k]-(*out)->data[i][(*out)->nlin/2][k]) / 2.0);
00277 (*out)->data[i][(*out)->nlin/2][(*out)->npix-k ] = ((*out)->data[i][(*out)->nlin/2][k ] = ((*out)->data[i][(*out)->nlin/2][(*out)->npix-k]+(*out)->data[i][(*out)->nlin/2][k]) / 2.0);
00278 }
00279 for (j=1; j<(*out)->nlin/2; j++) {
00280 (*out)->data[i][(*out)->nlin-j][1] = -((*out)->data[i][j][1] = ((*out)->data[i][(*out)->nlin-j][0]-(*out)->data[i][j][0]) / 2.0);
00281 (*out)->data[i][(*out)->nlin-j][0] = ((*out)->data[i][j][0] = ((*out)->data[i][(*out)->nlin-j][0]+(*out)->data[i][j][0]) / 2.0);
00282 (*out)->data[i][(*out)->nlin-j][(*out)->npix/2+1] = -((*out)->data[i][j][(*out)->npix/2+1] = ((*out)->data[i][(*out)->nlin-j][(*out)->npix/2]-(*out)->data[i][j][(*out)->npix/2]) / 2.0);
00283 (*out)->data[i][(*out)->nlin-j][(*out)->npix/2 ] = ((*out)->data[i][j][(*out)->npix/2 ] = ((*out)->data[i][(*out)->nlin-j][(*out)->npix/2]+(*out)->data[i][j][(*out)->npix/2]) / 2.0);
00284 for (k=2; k<(*out)->npix/2; k+=2) {
00285 t = (*out)->data[i][(*out)->nlin-j][(*out)->npix-k];
00286 u = (*out)->data[i][j][k];
00287 v = (*out)->data[i][j][(*out)->npix-k];
00288 w = (*out)->data[i][(*out)->nlin-j][k];
00289 (*out)->data[i][(*out)->nlin-j][(*out)->npix-k+1] = -((*out)->data[i][j][k+1] = (t-u) / 2.0);
00290 (*out)->data[i][j][(*out)->npix-k ] = ((*out)->data[i][(*out)->nlin-j][k ] = (t+u) / 2.0);
00291 (*out)->data[i][j][(*out)->npix-k+1] = -((*out)->data[i][(*out)->nlin-j][k+1] = (v-w) / 2.0);
00292 (*out)->data[i][(*out)->nlin-j][(*out)->npix-k ] = ((*out)->data[i][j][k ] = (v+w) / 2.0);
00293 }
00294 }
00295 } else {
00296
00297 for (j=1; j<(*out)->nlin/2; j++) {
00298 for (k=1; k<(*out)->npix/2; k++) {
00299 t = ((*out)->data[i][j][k] - (*out)->data[i][(*out)->nlin-j][k] - (*out)->data[i][j][(*out)->npix-k] + (*out)->data[i][(*out)->nlin-j][(*out)->npix-k]) / 2.0;
00300 (*out)->data[i][j][k] -= t;
00301 (*out)->data[i][(*out)->nlin-j][k] += t;
00302 (*out)->data[i][j][(*out)->npix-k] += t;
00303 (*out)->data[i][(*out)->nlin-j][(*out)->npix-k] -= t;
00304 }
00305 }
00306 }
00307
00308
00309 for (j=0; j<(*out)->nlin/2; j++) {
00310 for (k=0; k<(*out)->npix/2; k++) {
00311 t = (*out)->data[i][j][k];
00312 (*out)->data[i][j][k] = (*out)->data[i][(*out)->nlin/2+j][(*out)->npix/2+k];
00313 (*out)->data[i][(*out)->nlin/2+j][(*out)->npix/2+k] = t;
00314 t = (*out)->data[i][(*out)->nlin/2+j][k];
00315 (*out)->data[i][(*out)->nlin/2+j][k] = (*out)->data[i][j][(*out)->npix/2+k];
00316 (*out)->data[i][j][(*out)->npix/2+k] = t;
00317 }
00318 }
00319 }
00320
00321 the_end:
00322 if (a) free(a);
00323 if (pwr) free(pwr);
00324 if (sine) free(sine);
00325 if (tang) free(tang);
00326 if (array) free(array);
00327 if (TIMES) TIMING(T_EXIT);
00328 }