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

Generated on Thu Nov 15 14:32:26 2007 for UVES Pipeline Reference Manual by  doxygen 1.5.1