/* $Id: cpl_image_basic-test.c,v 1.64 2008/02/07 16:35:02 llundin Exp $ * * This file is part of the ESO Common Pipeline Library * Copyright (C) 2001-2004 European Southern Observatory * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * $Author: llundin $ * $Date: 2008/02/07 16:35:02 $ * $Revision: 1.64 $ * $Name: $ */ /*----------------------------------------------------------------------------- Includes -----------------------------------------------------------------------------*/ #include #include #include #include #include #include "cpl_image_basic.h" #include "cpl_image_stats.h" #include "cpl_image_gen.h" #include "cpl_image_bpm.h" #include "cpl_image_io.h" #include "cpl_stats.h" #include "cpl_vector.h" #include "cpl_memory.h" #include "cpl_tools.h" #include "cpl_math_const.h" /*----------------------------------------------------------------------------- Defines -----------------------------------------------------------------------------*/ #define IMAGESZ 512 #define MAGIC_PIXEL 42 #define POLY_SIZE 24 /*----------------------------------------------------------------------------- Private function prototypes -----------------------------------------------------------------------------*/ static double cpl_image_get_diff(const cpl_image *, const cpl_image *); static void cpl_image_turn_test(void); /*----------------------------------------------------------------------------- Main -----------------------------------------------------------------------------*/ int main(void) { cpl_image * imf1 ; cpl_image * imf2 ; cpl_image * imd1 ; cpl_image * imd2 ; cpl_image * imi1 ; cpl_image * imi2 ; cpl_image * imf ; cpl_image * imd ; cpl_image * imi ; cpl_image * imtmp ; cpl_vector * taylor ; double * ddata; int nb_cut ; int * new_pos ; double ampl, xcen, ycen, sig_x, sig_y ; double err; double value; int is_rejected; cpl_mask * mask ; int is_bad; int i, j, k; cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING); /* Insert tests below */ cpl_image_turn_test(); /* Tests of cpl_image_collapse_window_create() */ /* Tests of cpl_image_collapse_create() */ imtmp = cpl_image_collapse_create(NULL, 1); cpl_test_error( CPL_ERROR_NULL_INPUT ); cpl_test_null( imtmp ); imtmp = cpl_image_collapse_window_create(NULL, 1, 1, 1, 1, 1); cpl_test_error( CPL_ERROR_NULL_INPUT ); cpl_test_null( imtmp ); imd = cpl_image_new(IMAGESZ, IMAGESZ, CPL_TYPE_DOUBLE); imtmp = cpl_image_collapse_create(imd, -1); cpl_test_error( CPL_ERROR_ILLEGAL_INPUT ); cpl_test_null( imtmp ); /* Set two pixels in the last columns to 1 */ cpl_test_zero(cpl_image_set(imd, IMAGESZ-1, IMAGESZ, 1.0)); cpl_test_zero(cpl_image_set(imd, IMAGESZ, IMAGESZ, 1.0)); /* No BPM */ /* Collapse the x-direction to an image with 1 row */ imtmp = cpl_image_collapse_create(imd, 1); cpl_test( cpl_image_get_type(imtmp) == cpl_image_get_type(imd)); cpl_test( cpl_image_get_size_x(imtmp) == 1); cpl_test( cpl_image_get_size_y(imtmp) == IMAGESZ); cpl_test( cpl_image_get(imtmp, 1, IMAGESZ-1, &is_bad) == 0); cpl_test_zero( is_bad ); cpl_test( cpl_image_get(imtmp, 1, IMAGESZ, &is_bad) == 2); cpl_test_zero( is_bad ); cpl_image_delete(imtmp); imtmp = cpl_image_collapse_window_create(imd, IMAGESZ-1, IMAGESZ-1, IMAGESZ, IMAGESZ, 1); cpl_test( cpl_image_get_type(imtmp) == cpl_image_get_type(imd)); cpl_test( cpl_image_get_size_x(imtmp) == 1); cpl_test( cpl_image_get_size_y(imtmp) == 2); cpl_test( cpl_image_get(imtmp, 1, 1, &is_bad) == 0); cpl_test_zero( is_bad ); cpl_test( cpl_image_get(imtmp, 1, 2, &is_bad) == 2); cpl_test_zero( is_bad ); cpl_image_delete(imtmp); /* Collapse the y-direction to an image with 1 column */ imtmp = cpl_image_collapse_create(imd, 0); cpl_test( cpl_image_get_type(imtmp) == cpl_image_get_type(imd)); cpl_test( cpl_image_get_size_x(imtmp) == IMAGESZ); cpl_test( cpl_image_get_size_y(imtmp) == 1); cpl_test( cpl_image_get(imtmp, IMAGESZ - 1, 1, &is_bad) == 1); cpl_test_zero( is_bad ); cpl_test( cpl_image_get(imtmp, IMAGESZ, 1, &is_bad) == 1); cpl_test_zero( is_bad ); cpl_image_delete(imtmp); imtmp = cpl_image_collapse_window_create(imd, IMAGESZ-1, IMAGESZ-1, IMAGESZ, IMAGESZ, 0); cpl_test( cpl_image_get_type(imtmp) == cpl_image_get_type(imd)); cpl_test( cpl_image_get_size_x(imtmp) == 2); cpl_test( cpl_image_get_size_y(imtmp) == 1); cpl_test( cpl_image_get(imtmp, 1, 1, &is_bad) == 1); cpl_test_zero( is_bad ); cpl_test( cpl_image_get(imtmp, 2, 1, &is_bad) == 1); cpl_test_zero( is_bad ); cpl_image_delete(imtmp); /* Force creation of BPM */ mask = cpl_image_get_bpm(imd); /* Collapse the x-direction to an image with 1 row */ imtmp = cpl_image_collapse_window_create(imd, IMAGESZ-1, IMAGESZ-1, IMAGESZ, IMAGESZ, 1); cpl_test( cpl_image_get_type(imtmp) == cpl_image_get_type(imd)); cpl_test( cpl_image_get_size_x(imtmp) == 1); cpl_test( cpl_image_get_size_y(imtmp) == 2); cpl_test( cpl_image_get(imtmp, 1, 1, &is_bad) == 0); cpl_test_zero( is_bad ); cpl_test( cpl_image_get(imtmp, 1, 2, &is_bad) == 2); cpl_test_zero( is_bad ); cpl_image_delete(imtmp); /* Collapse the y-direction to an image with 1 column */ imtmp = cpl_image_collapse_window_create(imd, IMAGESZ-1, IMAGESZ-1, IMAGESZ, IMAGESZ, 0); cpl_test( cpl_image_get_type(imtmp) == cpl_image_get_type(imd)); cpl_test( cpl_image_get_size_x(imtmp) == 2); cpl_test( cpl_image_get_size_y(imtmp) == 1); cpl_test( cpl_image_get(imtmp, 1, 1, &is_bad) == 1); cpl_test_zero( is_bad ); cpl_test( cpl_image_get(imtmp, 2, 1, &is_bad) == 1); cpl_test_zero( is_bad ); cpl_image_delete(imtmp); /* Flag the two zero pixels in the last row as bad */ cpl_test_zero( cpl_mask_set(mask, IMAGESZ-1, IMAGESZ-1, CPL_BINARY_1)); cpl_test_zero( cpl_mask_set(mask, IMAGESZ, IMAGESZ-1, CPL_BINARY_1)); /* Collapse the x-direction to an image with 1 row */ imtmp = cpl_image_collapse_window_create(imd, IMAGESZ-1, IMAGESZ-1, IMAGESZ, IMAGESZ, 1); cpl_test( cpl_image_get_type(imtmp) == cpl_image_get_type(imd)); cpl_test( cpl_image_get_size_x(imtmp) == 1); cpl_test( cpl_image_get_size_y(imtmp) == 2); value = cpl_image_get(imtmp, 1, 1, &is_bad); cpl_test( is_bad ); cpl_test( cpl_image_get(imtmp, 1, 2, &is_bad) == 2); cpl_test_zero( is_bad ); cpl_image_delete(imtmp); /* Collapse the y-direction to an image with 1 column */ imtmp = cpl_image_collapse_window_create(imd, IMAGESZ-1, IMAGESZ-1, IMAGESZ, IMAGESZ, 0); cpl_test( cpl_image_get_type(imtmp) == cpl_image_get_type(imd)); cpl_test( cpl_image_get_size_x(imtmp) == 2); cpl_test( cpl_image_get_size_y(imtmp) == 1); cpl_test( cpl_image_get(imtmp, 1, 1, &is_bad) == 2); cpl_test_zero( is_bad ); cpl_test( cpl_image_get(imtmp, 2, 1, &is_bad) == 2); cpl_test_zero( is_bad ); cpl_image_delete(imtmp); /* Finished testing cpl_image_collapse_window_create() */ /* Finished testing cpl_image_collapse_create() */ cpl_image_delete(imd); /* Test for DFS 1724 */ imd1 = cpl_image_new(2, 2, CPL_TYPE_DOUBLE); imd2 = cpl_image_new(2, 2, CPL_TYPE_DOUBLE); imi1 = cpl_image_new(2, 2, CPL_TYPE_INT); imi2 = cpl_image_new(2, 2, CPL_TYPE_INT); /* Fill images with values 0, 1, 2, 3 */ value = 0.0; for (i=1; i <= 2; i++) { for (j=1; j <= 2; j++) { cpl_test_zero( cpl_image_set(imd1, i, j, value)); cpl_test_zero( cpl_image_set(imd2, i, j, value)); cpl_test_zero( cpl_image_set(imi1, i, j, value)); cpl_test_zero( cpl_image_set(imi2, i, j, value)); value++; } } /* Test cpl_image_divide_create() on integer and double */ imd = cpl_image_divide_create(imd1, imd2); cpl_test_nonnull( imd); imi = cpl_image_divide_create(imi1, imi2); cpl_test_nonnull( imi); value = 0.0; for (i=1; i <= 2; i++) { for (j=1; j <= 2; j++, value++) { const double vald = cpl_image_get(imd, i, j, &is_bad); const double vali = cpl_image_get(imi, i, j, &is_bad); if (value != 0.0) cpl_test_abs(vald, 1.0, 0.0); if (value != 0.0) cpl_test_abs(vali, 1.0, 0.0); } } /* Test with lo_cut equal to hi_cut */ cpl_test(cpl_image_threshold(imd1, (double)MAGIC_PIXEL, (double)MAGIC_PIXEL, (double)MAGIC_PIXEL, (double)MAGIC_PIXEL) == CPL_ERROR_NONE); cpl_test_leq( cpl_image_get_max(imd1), (double)MAGIC_PIXEL); cpl_test_leq( (double)MAGIC_PIXEL, cpl_image_get_min(imd1)); cpl_image_delete(imd1); cpl_image_delete(imd2); cpl_image_delete(imd); cpl_image_delete(imi1); cpl_image_delete(imi2); cpl_image_delete(imi); /* Test for DFS02782 */ imi = cpl_image_new(1, 1, CPL_TYPE_INT); imd = cpl_image_new(1, 1, CPL_TYPE_DOUBLE); cpl_image_set(imi, 1, 1, 10) ; cpl_image_set(imd, 1, 1, 0.5) ; imi1 = cpl_image_divide_create(imi, imd); cpl_image_delete(imi) ; cpl_image_delete(imd) ; value = (double)cpl_image_get(imi1, 1, 1, &is_bad) ; cpl_test_leq(fabs(value - 20.0), 0.0); cpl_image_delete(imi1) ; imd = cpl_image_new(IMAGESZ, IMAGESZ, CPL_TYPE_DOUBLE) ; /* Fill the image with a sinus */ ddata = cpl_image_get_data(imd) ; cpl_test_nonnull( ddata ); for (i=0 ; i < IMAGESZ ; i++) { for (j=0 ; j < IMAGESZ ; j++) { value = sin(i*CPL_MATH_2PI/IMAGESZ) * sin(j*CPL_MATH_2PI/IMAGESZ); if (cpl_image_set(imd, i+1, j+1, value)) break; if ( ddata[i + j * IMAGESZ] != value ) break; if (cpl_image_get(imd, i+1, j+1, &is_rejected) != value) break; if (is_rejected) break; /* Not really useful */ } cpl_test( j == IMAGESZ); } cpl_test( imd1 = cpl_image_duplicate(imd) ); cpl_test_zero( cpl_image_fft(imd1, NULL, CPL_FFT_DEFAULT) ); cpl_test_zero( cpl_image_abs(imd1) ); /* 4 FFT-components are non-zero */ value = IMAGESZ*IMAGESZ/4; err = fabs(cpl_image_get(imd1, 2, 2, &is_rejected) - value); cpl_test_zero( cpl_image_set(imd1, 2, 2, err) ); err = fabs(cpl_image_get(imd1, 2, IMAGESZ, &is_rejected) - value); cpl_test_zero( cpl_image_set(imd1, 2, IMAGESZ, err) ); err = fabs(cpl_image_get(imd1, IMAGESZ, 2, &is_rejected) - value); cpl_test_zero( cpl_image_set(imd1, IMAGESZ, 2, err) ); err = fabs(cpl_image_get(imd1, IMAGESZ, IMAGESZ, &is_rejected) - value); cpl_test_zero( cpl_image_set(imd1, IMAGESZ, IMAGESZ, err) ); err = cpl_image_get_max(imd1); cpl_msg_info("", "FFT(%g) round-off [DBL_EPSILON]: %g < %d", value, err/DBL_EPSILON, IMAGESZ*IMAGESZ); cpl_test_leq( fabs(err), IMAGESZ*IMAGESZ * DBL_EPSILON/2.44863); cpl_image_delete(imd1) ; /* Create a Taylor-expansion of exp() */ cpl_test_nonnull( taylor = cpl_vector_new(POLY_SIZE) ); i = 0; cpl_vector_set(taylor, i, 1); for (i=1 ; i 0 ; k--) { cpl_test_zero( cpl_image_multiply(imd2, imd) ); if (k&1) { cpl_test_zero( cpl_image_add_scalar(imd2, cpl_vector_get(taylor, k-1)) ); } else { cpl_test_zero( cpl_image_subtract_scalar(imd2, -cpl_vector_get(taylor, k-1)) ); } } /* Verify the result (against cpl_image_exponential() ) */ cpl_test( imd1 = cpl_image_duplicate(imd) ); cpl_test_zero( cpl_image_exponential(imd1, CPL_MATH_E) ); cpl_test_zero( cpl_image_subtract(imd2, imd1) ); cpl_test_zero( cpl_image_divide(imd2, imd1) ); cpl_test_zero( cpl_image_divide_scalar(imd2, DBL_EPSILON) ); cpl_test_leq( fabs(cpl_image_get_max(imd2)), 2.64494 ); cpl_test_leq( fabs(cpl_image_get_min(imd2)), 2.03626 ); cpl_image_delete(imd2) ; /* Evaluate exp() using cpl_image_pow() on the Taylor expansion */ cpl_test( imd2 = cpl_image_new(IMAGESZ, IMAGESZ, CPL_TYPE_DOUBLE) ); cpl_test_zero( cpl_image_add_scalar(imd2, cpl_vector_get(taylor, 0)) ); /* POLY_SIZE > 10 on alphaev56: Program received signal SIGFPE, Arithmetic exception. 0x200000a3ff0 in cpl_vector_multiply_scalar () */ for (k=1; k < POLY_SIZE ; k++) { imtmp = cpl_image_duplicate(imd); cpl_test_zero( cpl_image_power(imtmp, k) ); cpl_test_zero( cpl_image_multiply_scalar(imtmp, cpl_vector_get(taylor, k)) ); cpl_test_zero( cpl_image_add(imd2, imtmp) ); cpl_image_delete(imtmp); } cpl_vector_delete(taylor); /* Much less precise than Horner ... */ cpl_test_leq(cpl_image_get_diff(imd2, imd1), 16 * DBL_EPSILON); /* Verify cpl_image_logarithm() ) */ cpl_test_zero( cpl_image_logarithm(imd1, 10) ); cpl_test_zero( cpl_image_multiply_scalar(imd1, CPL_MATH_LN10) ); cpl_test_abs(cpl_image_get_diff(imd, imd1), 0.0, 3 * DBL_EPSILON); cpl_test_zero( cpl_image_exponential(imd, CPL_MATH_E) ); cpl_test_zero( cpl_image_copy(imd1, imd,1,1) ); cpl_test_zero( cpl_image_fft(imd1, NULL, CPL_FFT_DEFAULT) ); cpl_image_delete(imd2); cpl_test( imd2 = cpl_image_duplicate(imd1) ); cpl_test( imtmp = cpl_image_duplicate(imd1) ); cpl_test_zero( cpl_image_copy(imd1, imd2, 1, 1) ); cpl_test_zero( cpl_image_add(imd1, imd2) ); cpl_test_zero( cpl_image_add(imd1, imd2) ); cpl_test_zero( cpl_image_add(imd1, imd2) ); cpl_test_zero( cpl_image_subtract(imd1, imd2) ); cpl_test_zero( cpl_image_multiply_scalar(imtmp, 3) ); cpl_test_eq(cpl_image_count_rejected(imtmp), 0); cpl_test_zero( cpl_image_divide(imtmp, imd1) ); cpl_test_zero( cpl_image_abs(imtmp) ); cpl_test_abs( modf(IMAGESZ*IMAGESZ - cpl_image_get_flux(imtmp), &err), 0.0, DBL_EPSILON); cpl_test_eq(cpl_image_count_rejected(imtmp), err); cpl_test_zero( cpl_image_fft(imd1, NULL, CPL_FFT_INVERSE) ); cpl_test_zero( cpl_image_divide_scalar(imd1, 3) ); cpl_test_abs(cpl_image_get_diff(imd, imd1), 0.0, 32 * DBL_EPSILON); cpl_test_zero( cpl_image_copy(imd1, imd, 1, 1) ); cpl_test_zero( cpl_image_fft(imd1, NULL, CPL_FFT_INVERSE) ); cpl_test_zero( cpl_image_fft(imd1, NULL, CPL_FFT_DEFAULT) ); cpl_test_abs(cpl_image_get_diff(imd, imd1), 0.0, 32 * DBL_EPSILON); cpl_image_delete(imd) ; cpl_image_delete(imd1) ; cpl_image_delete(imd2) ; cpl_image_delete(imtmp) ; /* Create test images */ imd1 = cpl_image_new(IMAGESZ, IMAGESZ, CPL_TYPE_DOUBLE) ; cpl_image_fill_noise_uniform(imd1, 1, 100) ; imf1 = cpl_image_cast(imd1, CPL_TYPE_FLOAT) ; imi1 = cpl_image_cast(imd1, CPL_TYPE_INT) ; imd2 = cpl_image_fill_test_create(IMAGESZ, IMAGESZ) ; cpl_image_save(imd2, "test.fits", CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_DEFAULT) ; remove("test.fits"); imf2 = cpl_image_cast(imd2, CPL_TYPE_FLOAT) ; imi2 = cpl_image_cast(imd2, CPL_TYPE_INT) ; cpl_test( imd1 != NULL && imf1 != NULL && imi1 != NULL); cpl_test( imd2 != NULL && imf2 != NULL && imi2 != NULL); /* Test cpl_image_fit_gaussian */ cpl_msg_info("","Apply a gaussian fit on imi, imf, imd") ; cpl_test_eq(cpl_image_fit_gaussian(NULL, 205, 205, 50, &l, &xcen, &ycen, &sig_x, &sig_y, NULL, NULL), CPL_ERROR_NULL_INPUT); cpl_test_error(CPL_ERROR_NULL_INPUT); cpl_test_eq(cpl_image_fit_gaussian(imd2, 205, 205, 3, &l, &xcen, &ycen, &sig_x, &sig_y, NULL, NULL), CPL_ERROR_ILLEGAL_INPUT); cpl_test_error(CPL_ERROR_ILLEGAL_INPUT); cpl_test_zero(cpl_image_fit_gaussian(imd2, 205, 205, 50, &l, &xcen, &ycen, &sig_x, &sig_y, NULL, NULL)); cpl_test_error(CPL_ERROR_NONE); cpl_test_zero(cpl_image_fit_gaussian(imf2, 205, 205, 50, &l, &xcen, &ycen, &sig_x, &sig_y, NULL, NULL)); cpl_test_error(CPL_ERROR_NONE); cpl_test_zero(cpl_image_fit_gaussian(imi2, 205, 205, 50, &l, &xcen, &ycen, &sig_x, &sig_y, NULL, NULL)); cpl_test_error(CPL_ERROR_NONE); /* COMPUTE imi =(imi1-imi2)*imi1/(imi1+imi2) with local functions */ cpl_msg_info("","Compute imi = (imi1-imi2)*imi1/(imi1+imi2) in INTEGER") ; imi = cpl_image_duplicate(imi1) ; cpl_test_zero( cpl_image_subtract(imi, imi2) ); cpl_test_zero( cpl_image_multiply(imi, imi1) ); imtmp = cpl_image_duplicate(imi1) ; cpl_test_zero( cpl_image_add(imtmp, imi2) ); cpl_test_zero( cpl_image_divide(imi, imtmp) ); cpl_image_delete(imtmp) ; /* Delete imi1 and imi2 */ cpl_image_delete(imi1) ; cpl_image_delete(imi2) ; /* COMPUTE imf =(imf1-imf2)*imf1/(imf1+imf2) with local functions */ cpl_msg_info("","Compute imf = (imf1-imf2)*imf1/(imf1+imf2) in FLOAT") ; imf = cpl_image_duplicate(imf1) ; cpl_test_zero( cpl_image_subtract(imf, imf2) ); cpl_test_zero( cpl_image_multiply(imf, imf1) ); imtmp = cpl_image_duplicate(imf1) ; cpl_test_zero( cpl_image_add(imtmp, imf2) ); cpl_test_zero( cpl_image_divide(imf, imtmp) ); cpl_image_delete(imtmp) ; /* Delete imf1 and imf2 */ cpl_image_delete(imf1) ; cpl_image_delete(imf2) ; /* COMPUTE imd =(imd1-imd2)*imd1/(imd1+imd2) with local functions */ cpl_msg_info("","Compute imd = (imd1-imd2)*imd1/(imd1+imd2) in DOUBLE") ; imd = cpl_image_duplicate(imd1) ; cpl_test_zero( cpl_image_subtract(imd, imd2) ); cpl_test_zero( cpl_image_multiply(imd, imd1) ); imtmp = cpl_image_duplicate(imd1) ; cpl_test_zero( cpl_image_add(imtmp, imd2) ); cpl_test_zero( cpl_image_divide(imd, imtmp) ); cpl_image_delete(imtmp) ; /* Delete imd1 and imd2 */ cpl_image_delete(imd1) ; cpl_image_delete(imd2) ; /* At this point imi, imf and imd are int, resp float and double type */ /* images with the same values - apart from differences in rounding. */ /* Test cpl_image_average_create() */ cpl_image_delete( cpl_image_average_create(imf, imd) ); /* Test collapse functions */ /* Set all pixels as bad */ mask = cpl_mask_new(IMAGESZ, IMAGESZ) ; cpl_mask_not(mask) ; cpl_image_reject_from_mask(imd, mask) ; cpl_mask_delete(mask) ; /* Collapse with bad pixels */ imtmp = cpl_image_collapse_create(imd, 0) ; cpl_test( cpl_mask_count(cpl_image_get_bpm(imtmp)) == IMAGESZ); cpl_image_delete(imtmp); /* Reset the bad pixlels in imd */ cpl_image_accept_all(imd) ; /* Collapse */ imtmp = cpl_image_collapse_create(imd, 0) ; cpl_test( cpl_mask_count(cpl_image_get_bpm(imtmp)) == 0); cpl_image_delete(imtmp); /* Median collapse */ imtmp = cpl_image_collapse_median_create(imf, 0, 10, 10) ; cpl_image_delete(imtmp); /* imf=((((imf+MAGIC_PIXEL)*MAGIC_PIXEL)-MAGIC_PIXEL)/-MAGIC_PIXEL)*/ /* with non local functions */ cpl_msg_info("","Compute imf = ((((imf+42)*42)-42)/-42)") ; cpl_test_zero( cpl_image_add_scalar(imf, (double)MAGIC_PIXEL) ); cpl_test_zero( cpl_image_multiply_scalar(imf, (double)MAGIC_PIXEL) ); cpl_test_zero( cpl_image_subtract_scalar(imf, (double)MAGIC_PIXEL) ); cpl_test_zero( cpl_image_divide_scalar(imf, -(double)MAGIC_PIXEL) ); /* imd=((((imd+MAGIC_PIXEL)*MAGIC_PIXEL)-MAGIC_PIXEL)/-MAGIC_PIXEL)*/ /* with local functions */ cpl_msg_info("","Compute imd = ((((imd+42)*42)-42)/-42)") ; cpl_test_zero( cpl_image_add_scalar(imd, (double)MAGIC_PIXEL) ); cpl_test_zero( cpl_image_multiply_scalar(imd, (double)MAGIC_PIXEL) ); cpl_test_zero( cpl_image_subtract_scalar(imd, (double)MAGIC_PIXEL) ); cpl_test_zero( cpl_image_divide_scalar(imd, -(double)MAGIC_PIXEL) ); /* imi=((((imi+MAGIC_PIXEL)*MAGIC_PIXEL)-MAGIC_PIXEL)/-MAGIC_PIXEL)*/ /* with local functions */ cpl_msg_info("","Compute imi = ((((imi+42)*42)-42)/-42)") ; cpl_test_zero( cpl_image_add_scalar(imi, (double)MAGIC_PIXEL) ); cpl_test_zero( cpl_image_multiply_scalar(imi, (double)MAGIC_PIXEL) ); cpl_test_zero( cpl_image_subtract_scalar(imi, (double)MAGIC_PIXEL) ); cpl_test_zero( cpl_image_divide_scalar(imi, -(double)MAGIC_PIXEL) ); /* Compute imi = |imi|, imf = |imf| and imd = |imd| */ cpl_msg_info("","Take the absolute value of imi, imf and imd") ; imtmp = cpl_image_abs_create(imi) ; cpl_image_delete(imi) ; imi = imtmp ; imtmp = NULL ; imtmp = cpl_image_abs_create(imf) ; cpl_image_delete(imf) ; imf = imtmp ; imtmp = NULL ; imtmp = cpl_image_abs_create(imd) ; cpl_image_delete(imd) ; imd = imtmp ; imtmp = NULL ; /* Test cpl_image_move() */ cpl_msg_info("","Test the pixels moving function on imd") ; imd1 = cpl_image_extract(imd, 11, 11, 13, 16) ; nb_cut = 3 ; new_pos = cpl_malloc(nb_cut*nb_cut*sizeof(int)) ; new_pos[0] = 9 ; new_pos[1] = 8 ; new_pos[2] = 7 ; new_pos[3] = 6 ; new_pos[4] = 5 ; new_pos[5] = 4 ; new_pos[6] = 3 ; new_pos[7] = 2 ; new_pos[8] = 1 ; if (cpl_image_move(imd1, nb_cut, new_pos) != CPL_ERROR_NONE) { cpl_free(new_pos) ; cpl_image_delete(imd1) ; return cpl_test_end(1); } cpl_free(new_pos) ; cpl_image_delete(imd1) ; /* Threshold imi, imf and imd */ cpl_msg_info("","Threshold imi, imf and imd") ; cpl_image_threshold(imi, -DBL_MAX, (double)MAGIC_PIXEL, 0.0, (double)MAGIC_PIXEL) ; cpl_image_threshold(imf, -DBL_MAX, (double)MAGIC_PIXEL, 0.0, (double)MAGIC_PIXEL) ; cpl_image_threshold(imd, -DBL_MAX, (double)MAGIC_PIXEL, 0.0, (double)MAGIC_PIXEL) ; /* Subtract the min of the image from the image -> imi, imf and imd */ cpl_msg_info("","Subtract the minimum for imi, imf and imd") ; cpl_test_zero( cpl_image_subtract_scalar(imi, cpl_image_get_min(imi)) ); cpl_test_zero( cpl_image_subtract_scalar(imf, cpl_image_get_min(imf)) ); cpl_test_zero( cpl_image_subtract_scalar(imd, cpl_image_get_min(imd)) ); /* Extract sub windows from imf and imd */ cpl_msg_info("","Extract the central part of imi, imf and imd") ; imtmp = cpl_image_extract(imi, IMAGESZ/4, IMAGESZ/4, IMAGESZ/2, IMAGESZ/2); cpl_image_delete(imi) ; cpl_test( imi = imtmp ); imtmp = NULL ; imtmp = cpl_image_extract(imf, IMAGESZ/4, IMAGESZ/4, IMAGESZ/2, IMAGESZ/2); cpl_image_delete(imf) ; cpl_test( imf = imtmp ); imtmp = NULL ; imtmp = cpl_image_extract(imd, IMAGESZ/4, IMAGESZ/4, IMAGESZ/2, IMAGESZ/2); cpl_image_delete(imd) ; cpl_test( imd = imtmp ); imtmp = NULL ; /* Test flip function */ cpl_msg_info("","Compute various flipping on imi, imf and imd") ; cpl_test_zero( cpl_image_flip(imd, 0) ); cpl_test_zero( cpl_image_flip(imd, 1) ); cpl_test_zero( cpl_image_flip(imd, 2) ); cpl_test_zero( cpl_image_flip(imd, 3) ); cpl_test_zero( cpl_image_flip(imf, 0) ); cpl_test_zero( cpl_image_flip(imf, 1) ); cpl_test_zero( cpl_image_flip(imf, 2) ); cpl_test_zero( cpl_image_flip(imf, 3) ); cpl_test_zero( cpl_image_flip(imi, 0) ); cpl_test_zero( cpl_image_flip(imi, 1) ); cpl_test_zero( cpl_image_flip(imi, 2) ); cpl_test_zero( cpl_image_flip(imi, 3) ); /* Test exp operation */ cpl_msg_info("","Compute exp(imi), exp(imf) and exp(imd)") ; cpl_test_zero( cpl_image_exponential(imi, CPL_MATH_E) ); cpl_test_zero( cpl_image_exponential(imf, CPL_MATH_E) ); cpl_test_zero( cpl_image_exponential(imd, CPL_MATH_E) ); /* Test log operation */ cpl_msg_info("","Compute log(imi), log(imf) and log(imd)") ; cpl_test_zero( cpl_image_logarithm(imi, CPL_MATH_E) ); cpl_test_zero( cpl_image_logarithm(imf, CPL_MATH_E) ); cpl_test_zero( cpl_image_logarithm(imd, CPL_MATH_E) ); /* Test ^ operation */ cpl_msg_info("","Compute imi^2, imf^2 and imd^2") ; cpl_test_zero( cpl_image_power(imi, 2.0) ); cpl_test_zero( cpl_image_power(imf, 2.0) ); cpl_test_zero( cpl_image_power(imd, 2.0) ); /* Test sqrt operation */ cpl_msg_info("","Compute imf^0.5 and imd^0.5") ; cpl_test_zero( cpl_image_power(imf, 0.5) ); cpl_test_zero( cpl_image_power(imd, 0.5) ); /* TEST CROSS-TYPES OPERATIONS */ cpl_msg_info("","Test cross types operations") ; imtmp = cpl_image_add_create(imf, imd) ; cpl_msg_info("","Get mean of imf + imd : %g", cpl_image_get_mean(imtmp)) ; cpl_image_delete(imtmp) ; imtmp = cpl_image_add_create(imd, imf) ; cpl_msg_info("","Get mean of imd + imf : %g", cpl_image_get_mean(imtmp)) ; cpl_image_delete(imtmp) ; imtmp = cpl_image_subtract_create(imf, imd) ; cpl_msg_info("","Get mean of imf - imd : %g", cpl_image_get_mean(imtmp)) ; cpl_image_delete(imtmp) ; imtmp = cpl_image_subtract_create(imd, imf) ; cpl_msg_info("","Get mean of imd - imf : %g", cpl_image_get_mean(imtmp)) ; cpl_image_delete(imtmp) ; imtmp = cpl_image_multiply_create(imf, imd) ; cpl_msg_info("","Get mean of imf * imd : %g", cpl_image_get_mean(imtmp)) ; cpl_image_delete(imtmp) ; imtmp = cpl_image_multiply_create(imd, imf) ; cpl_msg_info("","Get mean of imd * imf : %g", cpl_image_get_mean(imtmp)) ; cpl_image_delete(imtmp) ; imtmp = cpl_image_divide_create(imf, imd) ; cpl_msg_info("","Get mean of imf / imd : %g", cpl_image_get_mean(imtmp)) ; cpl_image_delete(imtmp) ; imtmp = cpl_image_divide_create(imd, imf) ; cpl_msg_info("","Get mean of imd / imf : %g", cpl_image_get_mean(imtmp)) ; cpl_image_delete(imtmp) ; /* Normalize imf and imd */ cpl_msg_info("","Normalize imf and imd") ; imtmp = cpl_image_normalise_create(imf, CPL_NORM_MEAN) ; cpl_image_delete(imf) ; cpl_test( imf = imtmp ); imtmp = NULL ; imtmp = cpl_image_normalise_create(imd, CPL_NORM_MEAN) ; cpl_image_delete(imd) ; cpl_test( imd = imtmp ); imtmp = NULL ; /* Test the insertion function */ cpl_msg_info("","Insert an image in an other one") ; imtmp = cpl_image_duplicate(imd) ; cpl_image_reject(imtmp, 1, 1) ; cpl_test_zero( cpl_image_copy(imd, imtmp, 100, 100) ); cpl_image_delete(imtmp) ; /* Test the shift function */ cpl_msg_info("","Compute various shifts on imi, imf and imda") ; cpl_test_zero( cpl_image_shift(imd, 1, 1) ); cpl_test_zero( cpl_image_shift(imf, 1, 1) ); cpl_test_zero( cpl_image_shift(imi, 1, 1) ); cpl_image_delete(imi) ; cpl_image_delete(imf) ; cpl_image_delete(imd) ; /* Test for DFS02049 : Handle the division by ZERO */ /* Divide 3 | 4 by 2 | 0 --> 1.5 | X */ /* - - - - - - */ /* 2 | 3 2 | 0 1 | X */ imtmp = cpl_image_new(2, 2, CPL_TYPE_DOUBLE) ; imd = cpl_image_new(2, 2, CPL_TYPE_DOUBLE) ; imf = cpl_image_new(2, 2, CPL_TYPE_FLOAT) ; imi = cpl_image_new(2, 2, CPL_TYPE_INT) ; for (i=0 ; i<2 ; i++) { for (j=0 ; j<2 ; j++) { if (i==0) cpl_image_set(imtmp, i+1, j+1, 2.0) ; cpl_image_set(imi, i+1, j+1, (double)(i+j+2)) ; cpl_image_set(imf, i+1, j+1, (double)(i+j+2)) ; cpl_image_set(imd, i+1, j+1, (double)(i+j+2)) ; } } imd1 = cpl_image_divide_create(imd, imtmp) ; imf1 = cpl_image_divide_create(imf, imtmp) ; imi1 = cpl_image_divide_create(imi, imtmp) ; cpl_test_nonnull( imd1 ); cpl_test_nonnull( imf1 ); cpl_test_nonnull( imi1 ); cpl_test( cpl_image_get_flux(imd1) == 2.5 ) ; cpl_test( cpl_image_get_flux(imf1) == 2.5 ) ; cpl_test( cpl_image_get_flux(imi1) == 2 ) ; cpl_image_delete(imd1) ; cpl_image_delete(imf1) ; cpl_image_delete(imi1) ; cpl_test_zero( cpl_image_divide(imd, imtmp) ); cpl_test_zero( cpl_image_divide(imf, imtmp) ); cpl_test_zero( cpl_image_divide(imi, imtmp) ); cpl_test( cpl_image_get_flux(imd) == 2.5 ) ; cpl_test( cpl_image_get_flux(imf) == 2.5 ) ; cpl_test( cpl_image_get_flux(imi) == 2 ) ; cpl_image_delete(imtmp) ; cpl_image_delete(imd) ; cpl_image_delete(imf) ; cpl_image_delete(imi) ; /* End of tests */ return cpl_test_end(0); } /**@}*/ /*----------------------------------------------------------------------------*/ /** @brief Compute the inf-norm of an image difference @param im1 First cpl_image @param im2 Second cpl_image of the same size as im1 @return The (non-negative) inf-norm of the image difference The inf-norm of a image is the absolute value of the maximum element-wise difference. */ /*----------------------------------------------------------------------------*/ static double cpl_image_get_diff( const cpl_image * im1, const cpl_image * im2) { cpl_image * diff; double norm; int n, m; /* Test inputs */ cpl_test_nonnull(im1); cpl_test_nonnull(im2); n = cpl_image_get_size_x(im1); m = cpl_image_get_size_y(im1); cpl_test(cpl_image_get_size_x(im2) == n); cpl_test(cpl_image_get_size_y(im2) == m); diff = cpl_image_subtract_create(im1, im2); cpl_image_abs(diff); norm = cpl_image_get_max(diff); cpl_image_delete(diff); return norm; } /*----------------------------------------------------------------------------*/ /** @brief Test cpl_image_turn @return void */ /*----------------------------------------------------------------------------*/ static void cpl_image_turn_test(void) { const cpl_type ttype[] = {CPL_TYPE_INT, CPL_TYPE_FLOAT, CPL_TYPE_DOUBLE}; size_t itype; const int npix[] = {1, 2, 3, 5, 10, 11}; const int buf9[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; /* Rotation 90 degrees counterclockwise */ const int rot9[] = {3, 6, 9, 2, 5, 8, 1, 4, 7}; /* This image is not modified while wrapping around this buffer */ cpl_image * ref = cpl_image_wrap_int(3, 3, (int*)rot9); cpl_image * raw = cpl_image_new(3, 3, CPL_TYPE_INT); /* Test 1: Verify direction of 90 degree rotation */ memcpy(cpl_image_get_data_int(raw), buf9, 9*sizeof(int)); cpl_test(cpl_image_turn(raw, 1) == CPL_ERROR_NONE); cpl_test_abs(cpl_image_get_diff(raw, ref), 0.0, 0.0); cpl_image_delete(raw); (void)cpl_image_unwrap(ref); /* Test 2: Check error handling */ cpl_test(cpl_image_turn(NULL, 1) == CPL_ERROR_NULL_INPUT); cpl_error_reset(); /* Test 3: Verify consistency of rotations across types */ for (itype = 0; itype < sizeof(ttype)/sizeof(ttype[0]); itype++) { const cpl_type imtype = ttype[itype]; size_t ipix; for (ipix = 0; ipix < sizeof(npix)/sizeof(npix[0]); ipix++) { const int nx = npix[ipix]; size_t jpix; for (jpix = 0; jpix < sizeof(npix)/sizeof(npix[0]); jpix++) { const int ny = npix[jpix]; raw = cpl_image_new(nx, ny, imtype); cpl_test(cpl_image_fill_noise_uniform(raw, (double)-ny, (double)nx) == CPL_ERROR_NONE); ref = cpl_image_duplicate(raw); /* Turn the image all the way around */ cpl_test(cpl_image_turn(raw, 0) == CPL_ERROR_NONE); cpl_test(cpl_image_turn(raw, 1) == CPL_ERROR_NONE); cpl_test(cpl_image_turn(raw, 2) == CPL_ERROR_NONE); cpl_test(cpl_image_turn(raw, 3) == CPL_ERROR_NONE); cpl_test(cpl_image_turn(raw, 4) == CPL_ERROR_NONE); cpl_test(cpl_image_turn(raw,-1) == CPL_ERROR_NONE); cpl_test(cpl_image_turn(raw,-2) == CPL_ERROR_NONE); cpl_test(cpl_image_turn(raw,-3) == CPL_ERROR_NONE); cpl_test(cpl_image_turn(raw, 0) == CPL_ERROR_NONE); cpl_test_abs(cpl_image_get_diff(raw, ref), 0.0, 0.0); cpl_image_delete(ref); cpl_image_delete(raw); } } } }