irplib_filter-test.c

00001 /*                                                                              *
00002  *   This file is part of the ESO IRPLIB package                                *
00003  *   Copyright (C) 2004,2005 European Southern Observatory                      *
00004  *                                                                              *
00005  *   This library is free software; you can redistribute it and/or modify       *
00006  *   it under the terms of the GNU General Public License as published by       *
00007  *   the Free Software Foundation; either version 2 of the License, or          *
00008  *   (at your option) any later version.                                        *
00009  *                                                                              *
00010  *   This program is distributed in the hope that it will be useful,            *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
00013  *   GNU General Public License for more details.                               *
00014  *                                                                              *
00015  *   You should have received a copy of the GNU General Public License          *
00016  *   along with this program; if not, write to the Free Software                *
00017  *   Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA       *
00018  *                                                                              */
00019  
00020 #ifdef HAVE_CONFIG_H
00021 #  include <config.h>
00022 #endif
00023 
00024 /*-----------------------------------------------------------------------------
00025                                 Includes
00026  -----------------------------------------------------------------------------*/
00027 
00028 #include <irplib_filter.h>
00029 
00030 /* sqrt() */
00031 #include <math.h>
00032 #include <assert.h>
00033 
00034 /* clock() */
00035 #include <time.h>
00036 
00037 /* memcpy() */
00038 #include <string.h>
00039 
00040 /*-----------------------------------------------------------------------------
00041                                 Defines
00042  -----------------------------------------------------------------------------*/
00043 
00044 #ifndef BENCHSIZE
00045 #define BENCHSIZE 5
00046 #endif
00047 
00048 #define assure(x) assert(x)
00049 
00050 #ifdef bool
00051 #define mybool bool
00052 #else
00053 #define mybool unsigned char
00054 #endif
00055 
00056 #ifdef true
00057 #define mytrue true
00058 #else
00059 #define mytrue 1
00060 #endif
00061 
00062 #ifdef false
00063 #define myfalse false
00064 #else
00065 #define myfalse 0
00066 #endif
00067 
00068 /*-----------------------------------------------------------------------------
00069                                 Private function prototypes
00070  -----------------------------------------------------------------------------*/
00071 
00072 static void test_filter(void);
00073 
00074 static void benchmark(irplib_filter_mode filter,
00075                       irplib_filter_mode border_mode);
00076 
00077 static double rand_gauss(void);
00078 static int test_irplib_image_filter_double(unsigned, unsigned, unsigned,
00079                                            unsigned, unsigned, unsigned,
00080                                            unsigned);
00081 static int test_irplib_image_filter_float(unsigned, unsigned, unsigned,
00082                                           unsigned, unsigned, unsigned,
00083                                           unsigned);
00084 static int test_irplib_image_filter_int(unsigned, unsigned, unsigned,
00085                                         unsigned, unsigned, unsigned,
00086                                         unsigned);
00087 
00088 static void test_irplib_image_filter(int, int,
00089                                      int, int, 
00090                                      irplib_filter_mode,
00091                                      irplib_filter_mode);
00092 
00093 #ifdef IRPLIB_FILTER_TEST_AVERAGE_FAST
00094 
00095 static void
00096 image_filter_average_ref_double(double *, const double *,
00097                                 int, int, int,
00098                                 int, unsigned);
00099 
00100 
00101 static void
00102 image_filter_average_ref_float(float *, const float *,
00103                                int, int, int,
00104                                int, unsigned);
00105 
00106 static void
00107 image_filter_average_ref_int(int *, const int *,
00108                              int, int, int,
00109                              int, unsigned);
00110 
00111 #elif 1
00112 
00113 static void
00114 image_filter_average_bf_double(double *, const double *,
00115                                   int, int, int,
00116                                   int, unsigned);
00117 
00118 static void
00119 image_filter_average_bf_float(float *, const float *,
00120                                   int, int, int,
00121                                   int, unsigned);
00122 
00123 static void
00124 image_filter_average_bf_int(int *, const int *,
00125                                   int, int, int,
00126                                   int, unsigned);
00127 
00128 #else
00129 static cpl_error_code filter_average_bf(cpl_image *, const cpl_image *,
00130                                         unsigned, unsigned, unsigned);
00131 
00132 #endif
00133 
00134 /*----------------------------------------------------------------------------*/
00138 /*----------------------------------------------------------------------------*/
00139 
00140 /*----------------------------------------------------------------------------*/
00144 /*----------------------------------------------------------------------------*/
00145 
00146 /*----------------------------------------------------------------------------*/
00150 /*----------------------------------------------------------------------------*/
00151 int main(void)
00152 {
00153     /* Initialize CPL + IRPLIB */
00154     cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
00155 
00156     test_filter();
00157 
00158     return cpl_test_end(0);
00159 }
00160 
00161 
00162 /*----------------------------------------------------------------------------*/
00166 /*----------------------------------------------------------------------------*/
00167 static void test_filter(void)
00168 {
00169     const irplib_filter_mode filter_mode[] = {IRPLIB_FILTER_AVERAGE, 
00170                                               IRPLIB_FILTER_MEDIAN};
00171 
00172     const irplib_filter_mode border_mode[] = {IRPLIB_FILTER_BORDER_NOP,
00173                                               IRPLIB_FILTER_BORDER_FILTER,
00174                                               IRPLIB_FILTER_BORDER_EXTRAPOL_OUT,
00175                                               IRPLIB_FILTER_BORDER_CROP,
00176                                               IRPLIB_FILTER_BORDER_COPY};
00177     const int dopix[] = {1, 2, 3, 4, 7, 8};
00178     const int dor[] = {0, 1, 2, 3, 7};
00179 
00180     unsigned ifilt;
00181     
00182     for (ifilt = 0; 
00183          ifilt < sizeof(filter_mode)/sizeof(filter_mode[0]); 
00184          ifilt++) {
00185 
00186         unsigned ibord;
00187         
00188         for (ibord = 0 ; 
00189              ibord < sizeof(border_mode)/sizeof(border_mode[0]); 
00190              ibord++) {
00191 
00192             unsigned ix;
00193 
00194             if (filter_mode[ifilt] == IRPLIB_FILTER_AVERAGE &&
00195                 border_mode[ibord] != IRPLIB_FILTER_BORDER_FILTER) continue;
00196                         
00197             for (ix = 0; ix < sizeof(dopix)/sizeof(dopix[0]); ix++) {
00198                 const int nx = dopix[ix];
00199                 unsigned iy;            
00200                 
00201                 for (iy = 0; iy < sizeof(dopix)/sizeof(dopix[0]); iy++) {
00202                     const int ny = dopix[iy];
00203                     unsigned irx;
00204 
00205                     for (irx = 0; irx < sizeof(dor)/sizeof(dor[0]); irx++) {
00206                         const int rx = 
00207                             2*dor[irx] + 1 >= nx ? (nx-1)/2 : dor[irx];
00208                         unsigned iry;
00209                         
00210                         for (iry = 0; iry < sizeof(dor)/sizeof(dor[0]); iry++) {
00211                             const int ry =
00212                                 2*dor[iry] + 1 >= ny ? (ny-1)/2 : dor[iry];
00213                             
00214                             if (2*rx + 1 <= nx &&
00215                                 2*ry + 1 <= ny) {
00216                                 test_irplib_image_filter(nx, ny, rx, ry,
00217                                                          filter_mode[ifilt],
00218                                                          border_mode[ibord]);
00219                             }
00220                         }
00221                     }
00222                 }
00223             }
00224             
00225             benchmark(filter_mode[ifilt], border_mode[ibord]);
00226         }
00227     }
00228 }
00229 
00230 static void test_irplib_image_filter(int nx, int ny,
00231                                      int rx, int ry, 
00232                                      irplib_filter_mode filter,
00233                                      irplib_filter_mode border_mode)
00234 {
00235     cpl_msg_debug(cpl_func,
00236                   "Testing %dx%d image, "
00237                   "%dx%d kernel, filter = %d, border = %d",
00238                   nx, ny, rx, ry, 
00239                   filter, border_mode);
00240     
00241     /* Failure runs */
00242     {
00243         cpl_image * in  = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00244         cpl_image * out = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00245         
00246         assert( in  != NULL);
00247         assert( out != NULL);
00248         
00249         cpl_test_eq(irplib_image_filter(NULL, in, rx, ry,
00250                                            filter | border_mode),
00251                        CPL_ERROR_NULL_INPUT);
00252         
00253         cpl_error_reset();
00254         
00255         cpl_test_eq(irplib_image_filter(out, NULL, rx, ry,
00256                                            filter | border_mode),
00257                        CPL_ERROR_NULL_INPUT);
00258         
00259         cpl_error_reset();
00260         
00261         cpl_image_delete(in);
00262         cpl_image_delete(out);
00263     }
00264     
00265     /* Successful runs */
00266     cpl_test_zero(test_irplib_image_filter_double(nx, ny,
00267                                                   rx, ry,
00268                                                   filter | border_mode, 1, 1));
00269     cpl_test_zero(test_irplib_image_filter_float(nx, ny,
00270                                                  rx, ry,
00271                                                  filter | border_mode, 1, 1));
00272     cpl_test_zero(test_irplib_image_filter_int(nx, ny,
00273                                                rx, ry,
00274                                                filter | border_mode, 1, 1));
00275     return;
00276 }
00277 
00278 static
00279 void benchmark(irplib_filter_mode filter,
00280                irplib_filter_mode border_mode)
00281 {
00282     irplib_filter_mode mode = filter | border_mode;
00283 
00284     cpl_test_zero(test_irplib_image_filter_float(BENCHSIZE, BENCHSIZE, 1, 1,
00285                                                  mode, 100, 3));
00286     cpl_test_zero(test_irplib_image_filter_double(BENCHSIZE, BENCHSIZE, 1, 1,
00287                                                   mode, 100, 3));
00288     cpl_test_zero(test_irplib_image_filter_int(BENCHSIZE, BENCHSIZE, 1, 1,
00289                                                mode, 100, 3));
00290     
00291     if (border_mode == IRPLIB_FILTER_BORDER_NOP) {
00292         
00293         cpl_test_zero(test_irplib_image_filter_float(BENCHSIZE, BENCHSIZE, 2, 2,
00294                                                      mode, 20, 3));
00295         cpl_test_zero(test_irplib_image_filter_double(BENCHSIZE, BENCHSIZE, 2, 2,
00296                                                       mode, 20, 3));
00297         cpl_test_zero(test_irplib_image_filter_int(BENCHSIZE, BENCHSIZE, 2, 2,
00298                                                    mode, 20, 3));
00299         
00300         if (filter == IRPLIB_FILTER_AVERAGE) {
00301             
00302             cpl_test_zero(test_irplib_image_filter_float(BENCHSIZE, BENCHSIZE, 14, 14,
00303                                                          mode, 20, 3));
00304             cpl_test_zero(test_irplib_image_filter_double(BENCHSIZE, BENCHSIZE, 14, 14,
00305                                                           mode, 20, 3));
00306             cpl_test_zero(test_irplib_image_filter_int(BENCHSIZE, BENCHSIZE, 14, 14,
00307                                                        mode, 20, 3));
00308         }
00309     }
00310 
00311     return;
00312 }            
00313 
00314 
00315 static
00316 double rand_gauss(void)
00317 {
00318     static double V1, V2, S;
00319     static int phase = 0;
00320     double X;
00321     
00322     if(phase == 0) {
00323     do {
00324         double U1 = (double)rand() / RAND_MAX;
00325         double U2 = (double)rand() / RAND_MAX;
00326         
00327         V1 = 2 * U1 - 1;
00328         V2 = 2 * U2 - 1;
00329         S = V1 * V1 + V2 * V2;
00330     } while(S >= 1 || S == 0);
00331     
00332     X = V1 * sqrt(-2 * log(S) / S);
00333     } else
00334     X = V2 * sqrt(-2 * log(S) / S);
00335     
00336     phase = 1 - phase;
00337     
00338     return X;
00339 }
00340 
00341 #if 0
00342 static cpl_error_code filter_average_bf(cpl_image * self,
00343                                         const cpl_image * other,
00344                                         unsigned hsizex, unsigned hsizey,
00345                                         unsigned mode)
00346 {
00347 
00348     const int nx = cpl_image_get_size_x(self);
00349     const int ny = cpl_image_get_size_y(self);
00350     cpl_matrix * kernel = cpl_matrix_new(1+2*hsizex, 1+2*hsizey);
00351     cpl_image * copy;
00352     cpl_errorstate prevstate = cpl_errorstate_get();
00353 
00354     cpl_matrix_fill(kernel, 1.0);
00355 
00356     copy = cpl_image_filter_linear(other, kernel);
00357 
00358     if (cpl_error_get_code()) {
00359         cpl_errorstate_dump(prevstate, CPL_FALSE, NULL);
00360     }
00361 
00362     assert(copy != NULL);
00363 
00364     assert(cpl_image_get_type(copy) == cpl_image_get_type(self));
00365     assert(cpl_image_get_size_x(copy) == nx);
00366     assert(cpl_image_get_size_y(copy) == ny);
00367 
00368     assert((mode & ~IRPLIB_FILTER_BORDER_MODE) == IRPLIB_FILTER_AVERAGE);
00369 
00370     switch (cpl_image_get_type(self)) {
00371         case CPL_TYPE_DOUBLE: {
00372             const double * sour = cpl_image_get_data_double_const(copy);
00373             double * dest = cpl_image_get_data_double(self);
00374 
00375             (void)memcpy(dest, sour, nx*ny*sizeof(double));
00376 
00377             break;
00378         }
00379 
00380         case CPL_TYPE_FLOAT: {
00381             const float * sour = cpl_image_get_data_float_const(copy);
00382             float * dest = cpl_image_get_data_float(self);
00383 
00384             (void)memcpy(dest, sour, nx*ny*sizeof(float));
00385 
00386             break;
00387         }
00388         case CPL_TYPE_INT: {
00389             const int * sour = cpl_image_get_data_int_const(copy);
00390             int * dest = cpl_image_get_data_int(self);
00391 
00392             (void)memcpy(dest, sour, nx*ny*sizeof(int));
00393 
00394             break;
00395         }
00396         default:
00397             /* It is an error in CPL to reach this point */
00398             assert( 0 );
00399     }
00400 
00401     cpl_image_delete(copy);
00402 
00403     return cpl_error_get_code();
00404 
00405 }
00406 
00407 #endif
00408 
00409 /* These macros are needed for support of the different pixel types */
00410 
00411 #define CONCAT(a,b) a ## _ ## b
00412 #define CONCAT2X(a,b) CONCAT(a,b)
00413 
00414 #define PIXEL_TYPE double
00415 #include "filter_median_type.c"
00416 #undef PIXEL_TYPE
00417 
00418 #define PIXEL_TYPE float
00419 #include "filter_median_type.c"
00420 #undef PIXEL_TYPE
00421 
00422 #define PIXEL_TYPE_IS_INT 1
00423 #define PIXEL_TYPE int
00424 #include "filter_median_type.c"
00425 #undef PIXEL_TYPE
00426 #undef PIXEL_TYPE_IS_INT

Generated on Fri Jul 3 11:15:22 2009 for VISIR Pipeline Reference Manual by  doxygen 1.5.8