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 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
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
00057
00058
00059 #ifndef inline
00060 #define 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
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
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;
00195 cpl_bivector * offscopy = (cpl_bivector *)offs;
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
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
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
00236
00237
00238
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
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
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
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
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
00295
00296 copy = hawki_imagelist_wrap_all_but_first(copy);
00297 offscopy = hawki_bivector_wrap_all_but_first(offscopy);
00298
00299
00300 }
00301
00302 } else {
00303
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
00319 final = cpl_image_new(nx, ny, type);
00320
00321
00322 contrib = cpl_image_new(nx, ny, CPL_TYPE_INT);
00323 } else {
00324 cpl_mask * mask1;
00325
00326
00327 final = cpl_image_duplicate(img1);
00328 cpl_image_fill_rejected(final, 0.0);
00329
00330
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
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
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
00431 for (j = 0; j < jeq; j++) {
00432
00433 for (i = n-j-1; i > j; i--) {
00434 CPL_SORT(a, i, i-1, tmp);
00435 }
00436
00437 for (i += 2; i < n - j; i++) {
00438 CPL_SORT(a, i, i-1, tmp);
00439 }
00440 }
00441
00442
00443
00444
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
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
00557
00558
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