hawki_geom_img.c

00001 /* $Id: hawki_geom_img.c,v 1.1 2009/06/28 18:46:41 cgarcia Exp $
00002  *
00003  * This file is part of the ESO Common Pipeline Library
00004  * Copyright (C) 2001-2008 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: cgarcia $
00023  * $Date: 2009/06/28 18:46:41 $
00024  * $Revision: 1.1 $
00025  * $Name: hawki-1_7_2 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <unistd.h>
00040 #include <math.h>
00041 #include <assert.h>
00042 
00043 #include <cpl_memory.h>
00044 #include <cpl_image.h>
00045 #include <cpl_imagelist.h>
00046 #include <cpl_stats.h>
00047 
00048 #include <cpl_vector.h>
00049 #include <cpl_error.h>
00050 #include <cpl_errorstate.h>
00051 
00052 #include "cpl_apertures.h"
00053 #include "hawki_geom_img.h"
00054 
00055 /*-----------------------------------------------------------------------------
00056                             Defines
00057  -----------------------------------------------------------------------------*/
00058 
00059 #ifndef inline
00060 #define inline /* inline */
00061 #endif
00062 
00063 #define CPL_SORT(a, i, j, tmp) do { \
00064         if (a[i] < a[j]) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; }} while (0)
00065 
00066 /*-----------------------------------------------------------------------------
00067                             Static Function Prototypes
00068  -----------------------------------------------------------------------------*/
00069 
00070 static cpl_imagelist * hawki_imagelist_wrap_all_but_first(cpl_imagelist *);
00071 static void hawki_imagelist_unwrap(cpl_imagelist *);
00072 
00073 static cpl_bivector * hawki_bivector_wrap_all_but_first(cpl_bivector *);
00074 static void hawki_bivector_unwrap(cpl_bivector *);
00075 
00076 static void hawki_geom_img_get_min_max_double(double *, int, int, int);
00077 
00078 static cpl_error_code hawki_geom_img_offset_saa_double(cpl_image *, cpl_image *,
00079                                                      int, int, double, double,
00080                                                      const cpl_imagelist *,
00081                                                      const cpl_bivector *,
00082                                                      const cpl_vector *,
00083                                                      int);
00084 
00085 static cpl_error_code hawki_geom_img_offset_saa_float(cpl_image *, cpl_image *,
00086                                                     int, int, double, double,
00087                                                     const cpl_imagelist *,
00088                                                     const cpl_bivector *,
00089                                                     const cpl_vector *,
00090                                                     int);
00091 static cpl_error_code hawki_geom_img_offset_saa_all_double(cpl_image *,
00092                                                          cpl_image *,
00093                                                          double, double,
00094                                                          const cpl_imagelist *,
00095                                                          const cpl_bivector *,
00096                                                          const cpl_vector *,
00097                                                          int);
00098 
00099 static cpl_error_code hawki_geom_img_offset_saa_all_float(cpl_image *,
00100                                                          cpl_image *,
00101                                                          double, double,
00102                                                          const cpl_imagelist *,
00103                                                          const cpl_bivector *,
00104                                                          const cpl_vector *,
00105                                                          int);
00106 
00107 
00108 /*----------------------------------------------------------------------------*/
00120 /*----------------------------------------------------------------------------*/
00123 /*-----------------------------------------------------------------------------
00124                             Function codes
00125  -----------------------------------------------------------------------------*/
00126 
00127 
00128 /*----------------------------------------------------------------------------*/
00184 /*----------------------------------------------------------------------------*/
00185 cpl_image ** hawki_geom_img_offset_saa(const cpl_imagelist * ilist,
00186                                      const cpl_bivector  * offs,
00187                                      cpl_kernel            kernel,
00188                                      int                   rejmin,
00189                                      int                   rejmax,
00190                                      cpl_geom_combine      union_flag,
00191                                      double              * ppos_x,
00192                                      double              * ppos_y)
00193 {
00194     cpl_imagelist    * copy = (cpl_imagelist *)ilist; /* Not modified */
00195     cpl_bivector     * offscopy = (cpl_bivector *)offs; /* Not modified */
00196     const int          nima  = cpl_imagelist_get_size(ilist);
00197     const cpl_image  * img1  = cpl_imagelist_get_const(ilist, 0);
00198     const int          sizex = cpl_image_get_size_x(img1);
00199     const int          sizey = cpl_image_get_size_y(img1);
00200     const cpl_type     type  = cpl_image_get_type(img1);
00201     const cpl_vector * voffsx;
00202     const cpl_vector * voffsy;
00203     /* Test rejection parameters */
00204     const cpl_boolean  do_rej = nima > 3 && nima > 2*(rejmin+rejmax)
00205         ? CPL_TRUE : CPL_FALSE;
00206     const int          rmin = do_rej ? rejmin : 0;
00207     const int          rmax = do_rej ? rejmax : 0;
00208     const int          rtot = rmin + rmax;
00209     const int          tabsperpix = CPL_KERNEL_TABSPERPIX;
00210     cpl_vector       * xyprofile;
00211     int                nx, ny;
00212     double             start_x, start_y;
00213     cpl_image        * final;
00214     cpl_image        * contrib;
00215     cpl_image       ** out_arr;
00216     int                iimage;
00217     int                bpmflag;
00218 
00219 
00220     cpl_ensure(ilist != NULL, CPL_ERROR_NULL_INPUT, NULL);
00221     cpl_ensure(offs  != NULL, CPL_ERROR_NULL_INPUT, NULL);
00222     cpl_ensure(cpl_imagelist_is_uniform(ilist) == 0, CPL_ERROR_ILLEGAL_INPUT,
00223                NULL);
00224     cpl_ensure(cpl_bivector_get_size(offs) == nima, CPL_ERROR_INCOMPATIBLE_INPUT,
00225                NULL);
00226     cpl_ensure(rejmin>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00227     cpl_ensure(rejmax>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
00228     
00229    
00230     /* Compute output image size for union/intersection */
00231     voffsx = cpl_bivector_get_x_const(offs);
00232     voffsy = cpl_bivector_get_y_const(offs);
00233 
00234     if (union_flag == CPL_GEOM_UNION) {
00235         /* Union image */
00236 
00237         /* For this mode, the rejection arguments are also used
00238            to reduce the size of the resulting image */
00239 
00240         cpl_vector   * ox_tmp  = cpl_vector_duplicate(voffsx);
00241         cpl_vector   * oy_tmp  = cpl_vector_duplicate(voffsy);
00242         const double * ox_data = cpl_vector_get_data_const(ox_tmp);
00243         const double * oy_data = cpl_vector_get_data_const(oy_tmp);
00244         double         ox_max, oy_max;
00245 
00246 
00247         cpl_vector_sort(ox_tmp, 1);
00248         cpl_vector_sort(oy_tmp, 1);
00249 
00250         start_x = ox_data[rtot];
00251         start_y = oy_data[rtot];
00252 
00253         if (ppos_x != NULL) *ppos_x = 1.0 - start_x;
00254         if (ppos_y != NULL) *ppos_y = 1.0 - start_y;
00255 
00256         ox_max = ox_data[nima - rtot - 1];
00257         oy_max = oy_data[nima - rtot - 1];
00258 
00259         /* Round down */
00260         nx = (int)(sizex + ox_max - start_x);
00261         ny = (int)(sizey + oy_max - start_y);
00262 
00263         cpl_vector_delete(ox_tmp);
00264         cpl_vector_delete(oy_tmp);
00265     } else if (union_flag == CPL_GEOM_INTERSECT) {
00266         /* Intersection image */
00267         const double ox_min = cpl_vector_get_min(voffsx);
00268         const double oy_min = cpl_vector_get_min(voffsy);
00269 
00270         start_x = cpl_vector_get_max(voffsx);
00271         start_y = cpl_vector_get_max(voffsy);
00272 
00273         if (ppos_x != NULL) *ppos_x = start_x;
00274         if (ppos_y != NULL) *ppos_y = start_y;
00275 
00276         /* Round down */
00277         nx = (int)(sizex - start_x + ox_min);
00278         ny = (int)(sizey - start_y + oy_min);
00279 
00280         cpl_ensure(nx > 0, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
00281         cpl_ensure(ny > 0, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
00282 
00283     } else if (union_flag == CPL_GEOM_FIRST) {
00284         /* First image as reference */
00285         nx = sizex;
00286         ny = sizey;
00287         start_x = 0.0;
00288         start_y = 0.0;
00289 
00290         if (ppos_x != NULL) *ppos_x = 1.0;
00291         if (ppos_y != NULL) *ppos_y = 1.0;
00292 
00293         if (rtot == 0) {
00294             /* Create shallow copies, without the 1st element */
00295 
00296             copy = hawki_imagelist_wrap_all_but_first(copy);
00297             offscopy = hawki_bivector_wrap_all_but_first(offscopy);
00298 
00299             /* copy and offscopy are NOT modified below */
00300         }
00301 
00302     } else {
00303         /* union_flag is not one of the three supported modes */
00304         cpl_ensure(0, CPL_ERROR_UNSUPPORTED_MODE, NULL);
00305     }
00306 
00307     xyprofile = cpl_vector_new(CPL_KERNEL_DEF_SAMPLES);
00308 
00309     if (cpl_vector_fill_kernel_profile(xyprofile, kernel,
00310                                        CPL_KERNEL_DEF_WIDTH)) {
00311         cpl_vector_delete(xyprofile);
00312         if (copy != ilist) hawki_imagelist_unwrap(copy);
00313         if (offscopy != offs) hawki_bivector_unwrap(offscopy);
00314         cpl_ensure(0, cpl_error_get_code(), NULL);
00315     }
00316 
00317     if (copy == ilist) {
00318         /* Create output image, initialized to zero */
00319         final = cpl_image_new(nx, ny, type);
00320 
00321         /* Create output contribution image, initialized to zero */
00322         contrib = cpl_image_new(nx, ny, CPL_TYPE_INT);
00323     } else {
00324         cpl_mask * mask1;
00325 
00326         /* Create output image, duplicated from 1st image */
00327         final = cpl_image_duplicate(img1);
00328         cpl_image_fill_rejected(final, 0.0);
00329 
00330         /* FIXME: This may force the creation of an empty mask :-(((( */
00331         mask1 = cpl_image_get_bpm(final);
00332         cpl_mask_not(mask1);
00333         contrib = cpl_image_new_from_mask(mask1);
00334         cpl_image_accept_all(final);
00335 
00336     }
00337 
00338     /* Test if bad pixel masks are provided */
00339     bpmflag = 0;
00340     for(iimage=0; iimage < cpl_imagelist_get_size(ilist); iimage++)
00341     {
00342         if(cpl_image_count_rejected(cpl_imagelist_get_const(ilist, iimage)) > 0)
00343             bpmflag = 1;
00344     }
00345 
00346     /* Switch on the data type */
00347     if (type == CPL_TYPE_DOUBLE) {
00348         if (rtot > 0 || bpmflag) {
00349             (void)hawki_geom_img_offset_saa_double(final, contrib, rmin, rmax,
00350                                                  start_x, start_y,
00351                                                  ilist, offs,
00352                                                  xyprofile, tabsperpix);
00353         } else {
00354             (void)hawki_geom_img_offset_saa_all_double(final, contrib,
00355                                                      start_x, start_y,
00356                                                      copy, offscopy,
00357                                                      xyprofile, tabsperpix);
00358         }
00359     } else if (type == CPL_TYPE_FLOAT) {
00360         if (rtot > 0 || bpmflag) {
00361             (void)hawki_geom_img_offset_saa_float(final, contrib, rmin, rmax,
00362                                                  start_x, start_y,
00363                                                  ilist, offs,
00364                                                  xyprofile, tabsperpix);
00365         } else {
00366             (void)hawki_geom_img_offset_saa_all_float(final, contrib,
00367                                                      start_x, start_y,
00368                                                      copy, offscopy,
00369                                                      xyprofile, tabsperpix);
00370         }
00371     } else {
00372             cpl_vector_delete(xyprofile);
00373             cpl_image_delete(final);
00374             cpl_image_delete(contrib);
00375             if (copy != ilist) hawki_imagelist_unwrap(copy);
00376             if (offscopy != offs) hawki_bivector_unwrap(offscopy);
00377             cpl_ensure(0, CPL_ERROR_INVALID_TYPE, NULL);
00378     }
00379 
00380     cpl_vector_delete(xyprofile);
00381 
00382     out_arr = cpl_malloc(2*sizeof(cpl_image *));
00383     out_arr[0] = final;
00384     out_arr[1] = contrib;
00385     if (copy != ilist) hawki_imagelist_unwrap(copy);
00386     if (offscopy != offs) hawki_bivector_unwrap(offscopy);
00387 
00388     return out_arr;
00389 }
00390   
00394 /*----------------------------------------------------------------------------*/
00410 /*----------------------------------------------------------------------------*/
00411 inline static void hawki_geom_img_get_min_max_double(double * a,
00412                                                    int      n,
00413                                                    int      rmin,
00414                                                    int      rmax)
00415 {
00416 
00417     double tmp;
00418     const int jeq = CX_MIN(rmin, rmax);
00419     int i, j;
00420 
00421 #if 0
00422     cpl_ensure_code(a != NULL,  CPL_ERROR_NULL_INPUT);
00423     cpl_ensure_code(n > 0,      CPL_ERROR_NULL_INPUT);
00424     cpl_ensure_code(rmin >= 0,  CPL_ERROR_ILLEGAL_INPUT);
00425     cpl_ensure_code(rmax >= 0,  CPL_ERROR_ILLEGAL_INPUT);
00426     cpl_ensure_code(rmin + rmax < n, CPL_ERROR_ILLEGAL_INPUT);
00427 #endif
00428 
00429 
00430     /* Gain some locality */
00431     for (j = 0; j < jeq; j++) {
00432         /* Bubble one minimum value into place */
00433         for (i = n-j-1; i > j; i--) {
00434             CPL_SORT(a, i, i-1, tmp);
00435         }
00436         /* Bubble one maximum value into place */
00437         for (i += 2; i < n - j; i++) {
00438             CPL_SORT(a, i, i-1, tmp);
00439         }
00440     }
00441 
00442     /* Will enter at most one of the below two loops */
00443 
00444     /* Bubble one minimum value into place */
00445     for (; j < rmin; j++) {
00446         for (i = n-rmax-1; i > j; i--) {
00447             CPL_SORT(a, i, i-1, tmp);
00448         }
00449     }
00450 
00451     /* Bubble one maximum value into place */
00452     for (; j < rmax; j++) {
00453         for (i = rmin+1; i < n - j; i++) {
00454             CPL_SORT(a, i, i-1, tmp);
00455         }
00456     }
00457 
00458 }
00459 
00460 
00461 /*----------------------------------------------------------------------------*/
00469 /*----------------------------------------------------------------------------*/
00470 static cpl_imagelist * hawki_imagelist_wrap_all_but_first(cpl_imagelist * other)
00471 {
00472 
00473     cpl_imagelist * self;
00474     const int n = cpl_imagelist_get_size(other);
00475     int i;
00476 
00477 
00478     cpl_ensure(other != NULL, CPL_ERROR_NULL_INPUT, NULL);
00479 
00480     self = cpl_imagelist_new();
00481 
00482     for (i=1; i < n; i++) {
00483         const cpl_image * copy = cpl_imagelist_get_const(other, i);
00484         (void)cpl_imagelist_set(self, (cpl_image*)copy, i-1);
00485     }
00486 
00487     return self;
00488 }
00489 
00490 /*----------------------------------------------------------------------------*/
00498 /*----------------------------------------------------------------------------*/
00499 static void hawki_imagelist_unwrap(cpl_imagelist * self)
00500 {
00501     if (self != NULL) {
00502         int n = cpl_imagelist_get_size(self);
00503 
00504         for (; n > 0; n--) {
00505             (void)cpl_imagelist_unset(self, n-1);
00506         }
00507         cpl_imagelist_delete(self);
00508     }
00509 }
00510 
00511 
00512 /*----------------------------------------------------------------------------*/
00520 /*----------------------------------------------------------------------------*/
00521 static cpl_bivector * hawki_bivector_wrap_all_but_first(cpl_bivector * self)
00522 {
00523 
00524     const int      n = cpl_bivector_get_size(self);
00525     cpl_vector   * xvec;
00526     cpl_vector   * yvec;
00527 
00528 
00529     cpl_ensure(self  != NULL, CPL_ERROR_NULL_INPUT, NULL);
00530     cpl_ensure(n > 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
00531 
00532     xvec = cpl_vector_wrap(n-1, 1+cpl_bivector_get_x_data(self));
00533     yvec = cpl_vector_wrap(n-1, 1+cpl_bivector_get_y_data(self));
00534 
00535     return cpl_bivector_wrap_vectors(xvec, yvec);
00536 }
00537 
00538 /*----------------------------------------------------------------------------*/
00546 /*----------------------------------------------------------------------------*/
00547 static void hawki_bivector_unwrap(cpl_bivector * self)
00548 {
00549     if (self != NULL) {
00550         (void)cpl_vector_unwrap(cpl_bivector_get_x(self));
00551         (void)cpl_vector_unwrap(cpl_bivector_get_y(self));
00552         cpl_bivector_unwrap_vectors(self);
00553     }
00554 }
00555 
00556 /* Define the C-type dependent functions */
00557 
00558 /* These three macros are needed for support of the different pixel types */
00559 
00560 #define CONCAT(a,b) a ## _ ## b
00561 #define CONCAT2X(a,b) CONCAT(a,b)
00562 #define CONCAT3X(a,b,c) CONCAT2X(CONCAT2X(a,b),c)
00563 
00564 #define CPL_TYPE double
00565 #include "hawki_geom_img_body.h"
00566 #undef CPL_TYPE
00567 
00568 #define CPL_TYPE float
00569 #include "hawki_geom_img_body.h"
00570 #undef CPL_TYPE

Generated on 10 Jun 2010 for HAWKI Pipeline Reference Manual by  doxygen 1.6.1