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
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032
00033
00034
00035
00036
00037
00038 #include "irplib_filter.h"
00039
00040 #include <assert.h>
00041
00042
00058
00059
00060
00061
00062
00063
00064 static void
00065 irplib_image_filter_double_double(double *, const double *,
00066 int, int, int,
00067 int, unsigned);
00068
00069 static void
00070 irplib_image_filter_double_float(double *, const float *,
00071 int, int, int,
00072 int, unsigned);
00073 static void
00074 irplib_image_filter_double_int(double *, const int *,
00075 int, int, int,
00076 int, unsigned);
00077
00078 static void
00079 irplib_image_filter_float_double(float *, const double *,
00080 int, int, int,
00081 int, unsigned);
00082
00083 static void
00084 irplib_image_filter_float_float(float *, const float *,
00085 int, int, int,
00086 int, unsigned);
00087 static void
00088 irplib_image_filter_float_int(float *, const int *,
00089 int, int, int,
00090 int, unsigned);
00091
00092 static void
00093 irplib_image_filter_int_double(int *, const double *,
00094 int, int, int,
00095 int, unsigned);
00096
00097 static void
00098 irplib_image_filter_int_float(int *, const float *,
00099 int, int, int,
00100 int, unsigned);
00101 static void
00102 irplib_image_filter_int_int(int *, const int *,
00103 int, int, int,
00104 int, unsigned);
00105
00106
00107
00108
00109
00112
00163
00164
00165 cpl_error_code irplib_image_filter(cpl_image * self, const cpl_image * other,
00166 int hsizex, int hsizey,
00167 irplib_filter_mode mode)
00168 {
00169
00170 int nx, ny;
00171 const irplib_filter_mode filter_mode = mode & ~IRPLIB_FILTER_BORDER_MODE;
00172 const irplib_filter_mode border_mode = mode & IRPLIB_FILTER_BORDER_MODE;
00173
00174 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00175 cpl_ensure_code(other != NULL, CPL_ERROR_NULL_INPUT);
00176
00177 cpl_ensure_code(self != other, CPL_ERROR_UNSUPPORTED_MODE);
00178
00179 cpl_ensure_code(cpl_image_get_data(self) != cpl_image_get_data_const(other),
00180 CPL_ERROR_UNSUPPORTED_MODE);
00181
00182 cpl_ensure_code(hsizex >= 0, CPL_ERROR_ILLEGAL_INPUT);
00183 cpl_ensure_code(hsizey >= 0, CPL_ERROR_ILLEGAL_INPUT);
00184 cpl_ensure_code(hsizex >= 0 || hsizey >= 0, CPL_ERROR_ILLEGAL_INPUT);
00185
00186 nx = cpl_image_get_size_x(other);
00187 ny = cpl_image_get_size_y(other);
00188
00189 cpl_ensure_code(2 * hsizex + 1 <= nx, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00190 cpl_ensure_code(2 * hsizey + 1 <= ny, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00191
00192 if (border_mode == IRPLIB_FILTER_BORDER_CROP) {
00193 cpl_ensure_code(cpl_image_get_size_x(self) == nx - 2 * hsizex,
00194 CPL_ERROR_INCOMPATIBLE_INPUT);
00195
00196 cpl_ensure_code(cpl_image_get_size_y(self) == ny - 2 * hsizey,
00197 CPL_ERROR_INCOMPATIBLE_INPUT);
00198
00199 } else {
00200 cpl_ensure_code(cpl_image_get_size_x(self) == nx,
00201 CPL_ERROR_INCOMPATIBLE_INPUT);
00202
00203 cpl_ensure_code(cpl_image_get_size_y(self) == ny,
00204 CPL_ERROR_INCOMPATIBLE_INPUT);
00205
00206 }
00207
00208 if (filter_mode == IRPLIB_FILTER_MEDIAN) {
00209
00210 cpl_ensure_code(cpl_image_get_type(self) == cpl_image_get_type(other),
00211 CPL_ERROR_TYPE_MISMATCH);
00212
00213 switch (cpl_image_get_type(other)) {
00214 case CPL_TYPE_DOUBLE:
00215 irplib_image_filter_double(cpl_image_get_data_double(self),
00216 cpl_image_get_data_double_const(other),
00217 (unsigned)nx, (unsigned)ny,
00218 (unsigned)hsizex, (unsigned)hsizey,
00219 (unsigned)mode);
00220 break;
00221 case CPL_TYPE_FLOAT:
00222 irplib_image_filter_float(cpl_image_get_data_float(self),
00223 cpl_image_get_data_float_const(other),
00224 (unsigned)nx, (unsigned)ny,
00225 (unsigned)hsizex, (unsigned)hsizey,
00226 (unsigned)mode);
00227 break;
00228 case CPL_TYPE_INT:
00229 irplib_image_filter_int(cpl_image_get_data_int(self),
00230 cpl_image_get_data_int_const(other),
00231 (unsigned)nx, (unsigned)ny,
00232 (unsigned)hsizex, (unsigned)hsizey,
00233 (unsigned)mode);
00234 break;
00235 default:
00236
00237 assert( 0 );
00238 }
00239
00240 } else if (filter_mode == IRPLIB_FILTER_AVERAGE) {
00241
00242 cpl_ensure_code(border_mode == IRPLIB_FILTER_BORDER_FILTER,
00243 CPL_ERROR_UNSUPPORTED_MODE);
00244
00245 switch (cpl_image_get_type(self)) {
00246 case CPL_TYPE_DOUBLE: {
00247 switch (cpl_image_get_type(other)) {
00248 case CPL_TYPE_DOUBLE:
00249 irplib_image_filter_double_double(cpl_image_get_data_double(self),
00250 cpl_image_get_data_double_const(other),
00251 nx, ny,
00252 hsizex, hsizey,
00253 (unsigned)mode);
00254 break;
00255 case CPL_TYPE_FLOAT:
00256 irplib_image_filter_double_float(cpl_image_get_data_double(self),
00257 cpl_image_get_data_float_const(other),
00258 nx, ny,
00259 hsizex, hsizey,
00260 (unsigned)mode);
00261 break;
00262 case CPL_TYPE_INT:
00263 irplib_image_filter_double_int(cpl_image_get_data_double(self),
00264 cpl_image_get_data_int_const(other),
00265 nx, ny,
00266 hsizex, hsizey,
00267 (unsigned)mode);
00268 break;
00269 default:
00270
00271 assert( 0 );
00272 }
00273
00274 break;
00275 }
00276
00277 case CPL_TYPE_FLOAT: {
00278 switch (cpl_image_get_type(other)) {
00279 case CPL_TYPE_DOUBLE:
00280 irplib_image_filter_float_double(cpl_image_get_data_float(self),
00281 cpl_image_get_data_double_const(other),
00282 nx, ny,
00283 hsizex, hsizey,
00284 (unsigned)mode);
00285 break;
00286 case CPL_TYPE_FLOAT:
00287 irplib_image_filter_float_float(cpl_image_get_data_float(self),
00288 cpl_image_get_data_float_const(other),
00289 nx, ny,
00290 hsizex, hsizey,
00291 (unsigned)mode);
00292 break;
00293 case CPL_TYPE_INT:
00294 irplib_image_filter_float_int(cpl_image_get_data_float(self),
00295 cpl_image_get_data_int_const(other),
00296 nx, ny,
00297 hsizex, hsizey,
00298 (unsigned)mode);
00299 break;
00300 default:
00301
00302 assert( 0 );
00303 }
00304 break;
00305 }
00306
00307
00308 case CPL_TYPE_INT: {
00309 switch (cpl_image_get_type(other)) {
00310 case CPL_TYPE_DOUBLE:
00311 irplib_image_filter_int_double(cpl_image_get_data_int(self),
00312 cpl_image_get_data_double_const(other),
00313 nx, ny,
00314 hsizex, hsizey,
00315 (unsigned)mode);
00316 break;
00317 case CPL_TYPE_FLOAT:
00318 irplib_image_filter_int_float(cpl_image_get_data_int(self),
00319 cpl_image_get_data_float_const(other),
00320 nx, ny,
00321 hsizex, hsizey,
00322 (unsigned)mode);
00323 break;
00324 case CPL_TYPE_INT:
00325 irplib_image_filter_int_int(cpl_image_get_data_int(self),
00326 cpl_image_get_data_int_const(other),
00327 nx, ny,
00328 hsizex, hsizey,
00329 (unsigned)mode);
00330 break;
00331 default:
00332
00333 assert( 0 );
00334 }
00335 break;
00336 }
00337
00338 default:
00339
00340 assert( 0 );
00341 }
00342 } else {
00343 cpl_ensure_code(0, CPL_ERROR_UNSUPPORTED_MODE);
00344 }
00345
00346
00347 return CPL_ERROR_NONE;
00348
00349 }
00350
00353
00354
00355 #define CONCAT(a,b) a ## _ ## b
00356 #define CONCAT2X(a,b) CONCAT(a,b)
00357
00358 #define IN_TYPE double
00359 #define OUT_TYPE double
00360 #define ACCU_TYPE double
00361 #include "irplib_filter_body.c"
00362
00363 #define IN_TYPE float
00364 #define OUT_TYPE float
00365 #define ACCU_TYPE float
00366 #include "irplib_filter_body.c"
00367
00368 #define IN_TYPE int
00369 #define OUT_TYPE int
00370 #define ACCU_TYPE int
00371 #define ACCU_TYPE_IS_INT
00372 #include "irplib_filter_body.c"
00373
00374
00375 #define IN_TYPE double
00376 #define OUT_TYPE float
00377 #define ACCU_TYPE double
00378 #include "irplib_filter_body.c"
00379
00380 #define IN_TYPE double
00381 #define OUT_TYPE int
00382 #define ACCU_TYPE double
00383 #include "irplib_filter_body.c"
00384
00385 #define IN_TYPE float
00386 #define OUT_TYPE double
00387 #define ACCU_TYPE double
00388 #include "irplib_filter_body.c"
00389
00390 #define IN_TYPE float
00391 #define OUT_TYPE int
00392 #define ACCU_TYPE float
00393 #include "irplib_filter_body.c"
00394
00395
00396 #define IN_TYPE int
00397 #define OUT_TYPE double
00398 #define ACCU_TYPE double
00399 #include "irplib_filter_body.c"
00400
00401 #define IN_TYPE int
00402 #define OUT_TYPE float
00403 #define ACCU_TYPE float
00404 #include "irplib_filter_body.c"