irplib_filter.c

00001 /* $Id: irplib_filter.c,v 1.21 2008/01/31 15:25:26 llundin Exp $
00002  *
00003  * This file is part of the irplib package 
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2008/01/31 15:25:26 $
00024  * $Revision: 1.21 $
00025  * $Name: uves-4_2_2 $
00026  */
00027 
00028 
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032 
00033 
00034 /*-----------------------------------------------------------------------------
00035                                  Includes
00036  -----------------------------------------------------------------------------*/
00037 
00038 #include "irplib_filter.h"
00039 
00040 #include <assert.h>
00041 
00042 /*----------------------------------------------------------------------------*/
00058 /*----------------------------------------------------------------------------*/
00059 
00060 /*-----------------------------------------------------------------------------
00061                             Private Function prototypes
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                             Function definitions
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     /* FIXME: Insufficient check, need to check for partial overlap */
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             /* It is an error in CPL to reach this point */
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                 /* It is an error in CPL to reach this point */
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                 /* It is an error in CPL to reach this point */
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                 /* It is an error in CPL to reach this point */
00333                 assert( 0 );
00334             }
00335             break;
00336         }
00337 
00338         default:
00339             /* It is an error in CPL to reach this point */
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 /* These macros are needed for support of the different pixel types */
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"

Generated on Mon Apr 21 10:56:54 2008 for UVES Pipeline Reference Manual by  doxygen 1.5.1