00001 #include "sadie.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 void FCONVL (
00014 IMAGE *in,
00015 IMAGE *filter,
00016 short option,
00017
00018
00019 IMAGE **out
00020
00021 ) { register short i, j, k;
00022 char msg[SLEN];
00023 short jbgn, kbgn;
00024 double pinc, psum;
00025 IMAGE *scratch1=0, *scratch2=0, *scratch3=0, *scratch4=0, *flt;
00026
00027 if (TIMES) TIMING(T_FCONVL);
00028 if (NAMES) {
00029 MESSAGE('I',"");
00030 MESSAGE('I',"FCONVL");
00031 MESSAGE('I',"");
00032 sprintf(msg," Input image: %s",in->text);
00033 MESSAGE('I',msg);
00034 sprintf(msg," Filter image: %s",filter->text);
00035 MESSAGE('I',msg);
00036 if (option == PSF) {
00037 MESSAGE('I'," Filter image is spatial kernel");
00038 } else if (option == OTF) {
00039 MESSAGE('I'," Filter image is frequency transfer function");
00040 }
00041 MESSAGE('I'," ...............");
00042 }
00043
00044
00045 if (!CHECKIMG(in)) {
00046 MESSAGE('E'," Can't identify image.");
00047 goto the_end;
00048 } else if (in->nlin != 1L<<rnd(log10((double)in->nlin)/log10(2.0))) {
00049 MESSAGE('E'," Number of lines must be a power of two.");
00050 goto the_end;
00051 } else if (in->npix != 1L<<rnd(log10((double)in->npix)/log10(2.0))) {
00052 MESSAGE('E'," Number of pixels/line must be a power of two.");
00053 goto the_end;
00054 } else if (!CHECKIMG(filter)) {
00055 MESSAGE('E'," Can't identify filter image.");
00056 goto the_end;
00057 } else if (in->nbnd != filter->nbnd) {
00058 MESSAGE('E'," Number of bands must be identical in both images.");
00059 goto the_end;
00060 }
00061 if (option == PSF) {
00062 if (in->nlin < filter->nlin) {
00063 MESSAGE('E'," Image size in lines must be equal to or greater than that of filter image.");
00064 goto the_end;
00065 } else if (in->npix < filter->npix) {
00066 MESSAGE('E'," Image size in pixels/line must be equal to or greater than that of filter image.");
00067 goto the_end;
00068 }
00069 } else {
00070 if (in->nlin != filter->nlin) {
00071 MESSAGE('E'," Image size in lines in the frequency domain must be equal to that of filter image.");
00072 goto the_end;
00073 } else if (in->npix != filter->npix/2) {
00074 MESSAGE('E'," Image size in pixels/line in the frequency domain must be equal to that of filter image.");
00075 goto the_end;
00076 }
00077 }
00078
00079
00080 FFT2D(in,FORWARD,&scratch1);
00081 if (ABORT || !scratch1) goto the_end;
00082 sprintf(scratch1->text,"Scratch");
00083
00084 if (option == PSF) {
00085
00086 if (in->nlin > filter->nlin || in->npix > filter->npix) {
00087 jbgn = (in->nlin-filter->nlin)/2;
00088 kbgn = (in->npix-filter->npix)/2;
00089 MOSAIC(&filter,1,in->nlin,in->npix,&jbgn,&kbgn,(PIXEL)0,&scratch2);
00090 if (ABORT || !scratch2) goto the_end;
00091 sprintf(scratch2->text,"Scratch");
00092 FFT2D(scratch2,FORWARD,&scratch3);
00093 if (ABORT || !scratch3) goto the_end;
00094 sprintf(scratch3->text,"Scratch");
00095 flt = scratch3;
00096 } else {
00097 FFT2D(filter,FORWARD,&scratch2);
00098 if (ABORT || !scratch2) goto the_end;
00099 sprintf(scratch2->text,"Scratch");
00100 flt = scratch2;
00101 }
00102 } else {
00103 flt = filter;
00104 }
00105
00106
00107 GETMEM(scratch1->nbnd,scratch1->nlin,scratch1->npix,&scratch4);
00108 if (!scratch4) goto the_end;
00109 sprintf(scratch4->text,"Scratch");
00110
00111
00112 if (LINES && !PROGRESS(psum=0.0)) goto the_end;
00113 pinc = 1.0/(double)scratch1->nbnd/(double)scratch1->nlin;
00114
00115
00116 for (i=0; i<scratch1->nbnd; i+=1) {
00117 for (j=0; j<scratch1->nlin; j+=1) {
00118 for (k=0; k<scratch1->npix; k+=2) {
00119 scratch4->data[i][j][k ] = (PIXEL)((double)scratch1->data[i][j][k]*(double)flt->data[i][j][k] - (double)scratch1->data[i][j][k+1]*(double)flt->data[i][j][k+1]);
00120 scratch4->data[i][j][k+1] = (PIXEL)((double)scratch1->data[i][j][k+1]*(double)flt->data[i][j][k] + (double)scratch1->data[i][j][k]*(double)flt->data[i][j][k+1]);
00121 }
00122 if (LINES && !PROGRESS(psum+=pinc)) goto the_end;
00123 }
00124 }
00125
00126
00127 FFT2D(scratch4,INVERSE,out);
00128
00129 the_end:
00130 if (scratch1) RELMEM(scratch1);
00131 if (scratch2) RELMEM(scratch2);
00132 if (scratch3) RELMEM(scratch3);
00133 if (scratch4) RELMEM(scratch4);
00134 if (TIMES) TIMING(T_EXIT);
00135 }