00001 #include "sadie.h"
00002 #include "math.h"
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 void
00015 SCONVL (IMAGE * in,
00016 PIXEL * psf,
00017 short jsize,
00018 short ksize,
00019 IMAGE ** out
00020
00021 )
00022 {
00023 register short j, k, l, m, n, jmarg = jsize / 2, kmarg = ksize / 2, box;
00024 char msg[SLEN];
00025 double sum, c1, cn, pinc, psum;
00026
00027 int progmeter;
00028 double progress;
00029 int progcount, progtotal, progincr;
00030 int cancel = 0;
00031
00032 progmeter = ProgMeter_Create ("Convolution");
00033 progress = 0.0;
00034
00035 if (TIMES)
00036 TIMING (T_SCONVL);
00037 if (NAMES)
00038 {
00039 MESSAGE ('I', "");
00040 MESSAGE ('I', "SCONVL");
00041 MESSAGE ('I', "");
00042 sprintf (msg, " Input image: %s", in->text);
00043 MESSAGE ('I', msg);
00044 sprintf (msg, " Kernel size: lines: %d", jsize);
00045 MESSAGE ('I', msg);
00046 sprintf (msg, " pixels: %d", ksize);
00047 MESSAGE ('I', msg);
00048 if (jsize <= SLEN / 16 && ksize <= SLEN / 16)
00049 {
00050 MESSAGE ('I', " Spatial kernel:");
00051 for (n = j = 0; j < jsize; j++)
00052 {
00053 for (m = k = 0, msg[m++] = ' '; k < ksize;
00054 k++, m = strlen (msg))
00055 {
00056 sprintf (msg + m, "%12.4e", (double) psf[n++]);
00057 }
00058 MESSAGE ('I', msg);
00059 }
00060 }
00061 else
00062 {
00063 MESSAGE ('I', " Kernel too large to list.");
00064 }
00065 MESSAGE ('I', " ...............");
00066 }
00067
00068
00069 if (!CHECKIMG (in))
00070 {
00071 MESSAGE ('E', " Can't identify image.");
00072 goto the_end;
00073 }
00074 else if (in->nbnd > 1)
00075 {
00076 MESSAGE ('E', " Image must be single-band.");
00077 goto the_end;
00078 }
00079 else if (jsize < 0 || jsize % 2 == 0)
00080 {
00081 MESSAGE ('E',
00082 " Number of lines in the convolution mask must be an odd number greater than zero.");
00083 goto the_end;
00084 }
00085 else if (jsize > in->nlin)
00086 {
00087 MESSAGE ('E',
00088 " Image size must be equal to or greater than convolution mask size in the line dimension.");
00089 goto the_end;
00090 }
00091 else if (ksize < 0 || ksize % 2 == 0)
00092 {
00093 MESSAGE ('E',
00094 " Number of pixels/line in the convolution mask must be an odd number greater than zero.");
00095 goto the_end;
00096 }
00097 else if (ksize > in->npix)
00098 {
00099 MESSAGE ('E',
00100 " Image size must be equal to or greater than convolution mask size in the pixel dimension.");
00101 goto the_end;
00102 }
00103
00104
00105 if (!CHECKIMG (*out))
00106 GETMEM (1, in->nlin, in->npix, out);
00107 if (!*out)
00108 goto the_end;
00109
00110
00111 if (LINES && !PROGRESS (psum = 0.0))
00112 goto the_end;
00113 pinc = 1.0 / (double) (in->nlin - 2 * jmarg);
00114 progtotal = in->nlin - 2 * jmarg;
00115 progcount = 0;
00116 progincr = rint ((double) progtotal / 20.0);
00117
00118
00119 for (box = TRUE, k = 1; box && k < jsize * ksize; k++)
00120 {
00121 box = psf[k] == psf[0];
00122 }
00123
00124 if (box)
00125 {
00126 for (j = jmarg; j < in->nlin - jmarg; j++)
00127 {
00128
00129
00130 for (c1 = sum = 0.0, l = j - jmarg; l <= j + jmarg; l++)
00131 {
00132 c1 += (double) in->data[0][l][0];
00133 for (k = 1; k < ksize; k++)
00134 {
00135 sum += (double) in->data[0][l][k];
00136 }
00137 }
00138 (*out)->data[0][j][kmarg] = (PIXEL) ((sum += c1) * (double) psf[0]);
00139
00140
00141 for (k = kmarg + 1; k < in->npix - kmarg; k++)
00142 {
00143 for (sum -= c1, c1 = cn = 0.0, l = j - jmarg; l <= j + jmarg;
00144 l++)
00145 {
00146 c1 += (double) in->data[0][l][k - kmarg];
00147 cn += (double) in->data[0][l][k + kmarg];
00148 }
00149 (*out)->data[0][j][k] = (PIXEL) ((sum += cn) * (double) psf[0]);
00150 }
00151 if (LINES && !PROGRESS (psum += pinc))
00152 goto the_end;
00153 if (progmeter)
00154 {
00155 progcount++;
00156 if ((progcount % progincr) == 0)
00157 {
00158 progress =
00159 ((double) progcount / (double) progtotal) * 100.0;
00160 cancel = ProgMeter_Update (progmeter, progress);
00161 if (cancel != 0)
00162 goto the_end;
00163 }
00164 }
00165 }
00166
00167 }
00168 else
00169 {
00170 for (j = jmarg; j < in->nlin - jmarg; j++)
00171 {
00172 for (k = kmarg; k < in->npix - kmarg; k++)
00173 {
00174 for (sum = 0.0, n = jsize * ksize, l = 0; l < jsize; l++)
00175 {
00176 for (m = 0; m < ksize; m++)
00177 {
00178 sum +=
00179 (double) in->data[0][j - jmarg + l][k - kmarg +
00180 m] *
00181 (double) psf[--n];
00182 }
00183 }
00184 (*out)->data[0][j][k] = (PIXEL) sum;
00185 }
00186 if (LINES && !PROGRESS (psum += pinc))
00187 goto the_end;
00188 if (progmeter)
00189 {
00190 progcount++;
00191 if ((progcount % progincr) == 0)
00192 {
00193 progress =
00194 ((double) progcount / (double) progtotal) * 100.0;
00195 cancel = ProgMeter_Update (progmeter, progress);
00196 if (cancel != 0)
00197 goto the_end;
00198 }
00199 }
00200 }
00201 }
00202
00203
00204 for (j = 0; j < jmarg; j++)
00205 {
00206 for (k = 0; k < in->npix - kmarg; k++)
00207 {
00208 (*out)->data[0][j][k] = (*out)->data[0][jmarg][k];
00209 (*out)->data[0][in->nlin - j - 1][k] =
00210 (*out)->data[0][in->nlin - jmarg - 1][k];
00211 }
00212 }
00213
00214
00215 for (j = 0; j < in->nlin; j++)
00216 {
00217 for (k = 0; k < kmarg; k++)
00218 {
00219 (*out)->data[0][j][k] = (*out)->data[0][j][kmarg];
00220 (*out)->data[0][j][in->npix - k - 1] =
00221 (*out)->data[0][j][in->npix - kmarg - 1];
00222 }
00223 }
00224
00225 the_end:
00226 if (TIMES)
00227 TIMING (T_EXIT);
00228
00229 if (progmeter)
00230 {
00231 ProgMeter_Destroy (progmeter);
00232 }
00233
00234 if (cancel != 0)
00235 {
00236 if (*out)
00237 RELMEM (*out);
00238 *out = NULL;
00239 }
00240 }