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