00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef IRPLIB_FILTER_NO_RECIPROCAL
00029 #ifndef ACCU_TYPE_IS_INT
00030 #define ALLOW_RECIPROCAL
00031 #endif
00032 #endif
00033
00034 #ifdef ALLOW_RECIPROCAL
00035
00036
00037 #define RUNSUM_MEAN (runsum * rnpix)
00038 #else
00039 #define RUNSUM_MEAN (runsum / npix)
00040 #endif
00041
00042 #define TYPE_ADD(a) CONCAT2X(a, CONCAT2X(OUT_TYPE, IN_TYPE))
00043
00044 static void
00045 TYPE_ADD(irplib_image_filter)(OUT_TYPE * out, const IN_TYPE * in,
00046 int Nx, int Ny, int hsizex, int hsizey,
00047 unsigned border_mode)
00048 {
00049
00050 ACCU_TYPE * colsum;
00051 ACCU_TYPE npix, npixy;
00052 int x, y, i;
00053
00054 assert(out != NULL);
00055 assert(in != NULL);
00056
00057 assert( hsizex >= 0 );
00058 assert( hsizey >= 0 );
00059 assert( 2*hsizex + 1 <= Nx );
00060 assert( 2*hsizey + 1 <= Ny );
00061
00062 border_mode &= IRPLIB_FILTER_BORDER_MODE;
00063
00064
00065 assert( border_mode == IRPLIB_FILTER_BORDER_FILTER );
00066
00067
00068 npixy = (ACCU_TYPE)hsizey;
00069 npix = (ACCU_TYPE)(1+hsizex) * npixy;
00070
00071
00072 colsum = cpl_calloc(Nx, sizeof(*colsum));
00073 for (y=0; y < hsizey; y++) {
00074 for (i=0; i < Nx; i++) {
00075 colsum[i] += in[i + y * Nx];
00076 }
00077 }
00078
00079 for (y = 0; y <= hsizey; y++) {
00080
00081 ACCU_TYPE runsum = (ACCU_TYPE)0;
00082
00083 #ifdef ALLOW_RECIPROCAL
00084 ACCU_TYPE rnpix;
00085 #endif
00086
00087 npixy += (ACCU_TYPE)1;
00088 npix = (ACCU_TYPE)(hsizex)*npixy;
00089
00090 for (x = 0; x < 1; x ++) {
00091
00092
00093 for (i = 0; i <= hsizex; i ++) {
00094 colsum[i] += in[i + (y + hsizey) * Nx];
00095 runsum += colsum[i];
00096 }
00097
00098 npix += npixy;
00099
00100 out[x + y * Nx] = (OUT_TYPE)(runsum/npix);
00101 }
00102
00103 for (; x <= hsizex; x ++) {
00104
00105
00106 colsum[x + hsizex] += in[x + hsizex + (y + hsizey) * Nx];
00107
00108
00109 runsum += colsum[x + hsizex];
00110
00111 npix += npixy;
00112
00113 out[x + y * Nx] = (OUT_TYPE)(runsum/npix);
00114 }
00115
00116 #ifdef ALLOW_RECIPROCAL
00117 rnpix = (ACCU_TYPE)1.0/npix;
00118 #endif
00119
00120 for (; x < Nx-hsizex; x ++) {
00121
00122
00123 colsum[x + hsizex] += in[x + hsizex + (y + hsizey) * Nx];
00124
00125
00126
00127 runsum -= colsum[x - hsizex - 1];
00128 runsum += colsum[x + hsizex];
00129
00130 out[x + y * Nx] = (OUT_TYPE)(RUNSUM_MEAN);
00131 }
00132
00133 for (; x < Nx; x++) {
00134
00135
00136 runsum -= colsum[x - hsizex - 1];
00137
00138 npix -= npixy;
00139
00140 out[x + y * Nx] = (OUT_TYPE)(runsum/npix);
00141 }
00142 }
00143
00144 for (;y < Ny-hsizey; y++) {
00145
00146 ACCU_TYPE runsum = (ACCU_TYPE)0;
00147
00148 #ifdef ALLOW_RECIPROCAL
00149 ACCU_TYPE rnpix;
00150 #endif
00151 npix = (ACCU_TYPE)(hsizex)*npixy;
00152
00153 for (x = 0; x < 1; x++) {
00154
00155
00156 for (i = 0; i <= hsizex; i ++) {
00157 colsum[i] -= in[i + (y - hsizey - 1) * Nx];
00158 colsum[i] += in[i + (y + hsizey) * Nx];
00159 runsum += colsum[i];
00160 }
00161
00162 npix += npixy;
00163
00164 out[x + y * Nx] = (OUT_TYPE)(runsum/npix);
00165 }
00166
00167 for (; x <= hsizex; x++) {
00168
00169
00170 colsum[x + hsizex] -= in[x + hsizex + (y - hsizey - 1) * Nx];
00171 colsum[x + hsizex] += in[x + hsizex + (y + hsizey) * Nx];
00172
00173
00174 runsum += colsum[x + hsizex];
00175
00176 npix += npixy;
00177
00178 out[x + y * Nx] = (OUT_TYPE)(runsum/npix);
00179 }
00180
00181 #ifdef ALLOW_RECIPROCAL
00182 rnpix = (ACCU_TYPE)1.0/npix;
00183 #endif
00184
00185 for (; x < Nx-hsizex; x++) {
00186
00187
00188 colsum[x + hsizex] -= in[x + hsizex + (y - hsizey - 1) * Nx];
00189 colsum[x + hsizex] += in[x + hsizex + (y + hsizey) * Nx];
00190
00191
00192
00193 runsum -= colsum[x - hsizex - 1];
00194 runsum += colsum[x + hsizex];
00195
00196 out[x + y * Nx] = (OUT_TYPE)(RUNSUM_MEAN);
00197 }
00198
00199 for (; x < Nx; x++) {
00200
00201
00202 runsum -= colsum[x - hsizex - 1];
00203
00204 npix -= npixy;
00205
00206 out[x + y * Nx] = (OUT_TYPE)(runsum/npix);
00207 }
00208 }
00209
00210 for (;y < Ny; y++) {
00211
00212 ACCU_TYPE runsum = (ACCU_TYPE)0;
00213
00214 #ifdef ALLOW_RECIPROCAL
00215 ACCU_TYPE rnpix;
00216 #endif
00217
00218 npixy -= (ACCU_TYPE)1;
00219 npix = (ACCU_TYPE)(hsizex)*npixy;
00220
00221 for (x = 0; x < 1; x++) {
00222
00223
00224 for (i = 0; i <= hsizex; i ++) {
00225 colsum[i] -= in[i + (y - hsizey - 1) * Nx];
00226 runsum += colsum[i];
00227 }
00228
00229 npix += npixy;
00230
00231 out[x + y * Nx] = (OUT_TYPE)(runsum/npix);
00232 }
00233
00234 for (; x <= hsizex; x++) {
00235
00236
00237 colsum[x + hsizex] -= in[x + hsizex + (y - hsizey - 1) * Nx];
00238
00239
00240 runsum += colsum[x + hsizex];
00241
00242 npix += npixy;
00243
00244 out[x + y * Nx] = (OUT_TYPE)(runsum/npix);
00245 }
00246
00247 #ifdef ALLOW_RECIPROCAL
00248 rnpix = (ACCU_TYPE)1.0/npix;
00249 #endif
00250
00251 for (; x < Nx-hsizex; x++) {
00252
00253
00254 colsum[x + hsizex] -= in[x + hsizex + (y - hsizey - 1) * Nx];
00255
00256
00257
00258 runsum -= colsum[x - hsizex - 1];
00259 runsum += colsum[x + hsizex];
00260
00261 out[x + y * Nx] = (OUT_TYPE)(RUNSUM_MEAN);
00262 }
00263
00264 for (; x < Nx; x++) {
00265
00266
00267 runsum -= colsum[x - hsizex - 1];
00268
00269 npix -= npixy;
00270
00271 out[x + y * Nx] = (OUT_TYPE)(runsum/npix);
00272 }
00273 }
00274
00275 cpl_free(colsum);
00276
00277 return;
00278
00279 }
00280
00281 #undef ACCU_TYPE
00282 #undef IN_TYPE
00283 #undef OUT_TYPE
00284 #undef ACCU_TYPE_IS_INT
00285 #undef ALLOW_RECIPROCAL
00286 #undef RUNSUM_MEAN