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