
What's new in CPL 5.2
============================================

 - New functions in CPL 5.2:
   cpl_array_cast()
   cpl_mask_filter()
   cpl_plot_mask()
   cpl_image_unset_bpm()

 - New functionality:
   cpl_table_cast_column() allows casting from array columns of depth one
      to plain columns, and viceversa.

 - Bug fixes:
   Casting table columns of type array to columns of type array.
   cpl_table_save() returns in case of ILLEGAL_OUTPUT caused by 
      zero depth integer array columns; allocate empty integer 
      arrays in case they must be written to file.
   cpl_image_new_from_accepted(): Older versions would force the
      creation of an empty bad pixel map in any image in the input
      image list, that did not already have one.
   cpl_detector_interpolate_rejected(): Older versions would use wrong
     interpolation values at the image border.
   cpl_wcs_platesol(): All previous versions computes a wrong solution.
   cpl_bivector_interpolate_linear(): Versions from 4.2.0 interpolates
     the first value wrongly.
   cpl_stats_dump(): Older versions do not dump median deviation
   cpl_geom_img_offset_combine(): Older versions would use the error code
     CPL_ERROR_ILLEGAL_OUTPUT instead of CPL_ERROR_DATA_NOT_FOUND.
   cpl_dfs_update_product_header(): Older versions would not work if the
     system macro L2_CACHE_BYTES was defined to 0.
   cpl_end(): Free any memory allocated internally by FFTW.

 - Deprecated functions
   cpl_mask_closing(): Use cpl_mask_filter() instead
   cpl_mask_opening(): Use cpl_mask_filter() instead
   cpl_mask_erosion(): Use cpl_mask_filter() instead
   cpl_mask_dilation(): Use cpl_mask_filter() instead

 - Doc fixes:
   Specify that all arrays in a column must have same length
   Complete doc of cpl_table_set_array()
   Fix wrong LaTex code in cpl_fit_image_gaussian() doc.
   Document that cpl_geom_img_offset_saa() handles bad pixels.
   The pixel indexing convention ((1,1) for lower left) is documented.
   The deprecated CPL functions are clearly documented as such.

What's new in CPL 5.1
============================================

 - New functions in CPL 5.1
   cpl_array_is_valid
   cpl_array_dump_structure
   cpl_array_dump
   cpl_fit_image_gaussian
   cpl_flux_get_bias_window
   cpl_mask_dump_window
   cpl_propertylist_append_property
   cpl_propertylist_prepend_property
   cpl_propertylist_insert_property
   cpl_propertylist_insert_after_property
   cpl_test_array_abs
   cpl_test_eq_error
   cpl_test_eq_ptr
   cpl_test_get_cputime
   cpl_test_get_walltime
   cpl_test_imagelist_abs
   cpl_test_noneq_ptr
   cpl_test_vector_abs

 - New function modes in CPL 5.1.
   CPL_IO_APPEND

 - Deprecated functions
      cpl_image_fit_gaussian: Use cpl_fit_image_gaussian instead.

 - Other Changes
   CPL functions with complex types in their API are only available
   (declared) when the CPL-based application #include's <complex.h>.
   The functions effected by this are:
      cpl_image_wrap_double_complex
      cpl_image_wrap_float_complex
      cpl_image_get_complex
      cpl_image_set_complex
      cpl_image_get_data_double_complex
      cpl_image_get_data_double_complex_const
      cpl_image_get_data_float_complex
      cpl_image_get_data_float_complex_const

 - Bug fixes
   The filtering mode CPL_FILTER_STDEV had a bug which could cause wrong
   outputs. This has been fixed.
 
 - Known Problems
   CPL release 5.1 (and all releases back to and including 4.1) has
   a documentation bug in both cpl_image_turn() and cpl_mask_turn().
   The orientation of the rotation is opposite of what is stated in
   the documentation.
   Given a rotation of 1, the function will rotate by
   90 degrees clockwise and given a rotation of -1 the function
   will rotate by 90 degrees counterclockwise. The documentation of
   rotation by any odd number is similarly wrong. The documentation of
   rotation by any even number is unaffected by the error.

What's new in CPL 5.0
============================================

 - Deprecated functions.
   A number of functions are now deprecated. The deprecated functions
   will remain in CPL 5.X. The deprecated functions are:
   cpl_fits_get_nb_extensions
   cpl_fits_get_extension_nb
   cpl_image_filter_median
   cpl_image_filter_linear
   cpl_image_filter_stdev
   cpl_image_filter_morpho
   cpl_msg_progress
   cpl_polynomial_fit_1d_create
   cpl_polynomial_fit_2d_create
   cpl_vector_new_lss_kernel
   cpl_vector_convolve_symmetric

 - Warnings of use of deprecated functions.
   Using gcc to compile code using the above mentioned functions will
   lead to compiler warnings. These warnings can be suppressed with
   -Wno-deprecated-declarations. This gcc option can be applied with
   ./configure CFLAGS=-Wno-deprecated-declarations .

 - Functions with changed API
   cpl_dfs_save_image
   cpl_dfs_save_table
   cpl_dfs_save_propertylist
   cpl_dfs_save_imagelist
   cpl_dfs_setup_product_header
   cpl_geom_img_offset_saa
   cpl_propertylist_erase_regexp
   cpl_image_get_bpm_const
   cpl_polynomial_shift_1d
   cpl_imagelist_collapse_sigclip_create


 - How to replace deprecated functions
   cpl_fits_get_nb_extensions: Replace with cpl_fits_count_extensions
   cpl_fits_get_extension_nb:  Replace with cpl_fits_find_extension
   cpl_image_filter_median: cpl_image * a = cpl_image_filter_median(b, k)
       can be replaced by
     int nx   = cpl_image_get_size_x(b);
     int ny   = cpl_image_get_size_y(b);
     int type = cpl_image_type(b);
     cpl_image * a = cpl_image_new(nx, ny, type);
     cpl_image_filter_mask(a, b, m, CPL_FILTER_MEDIAN, CPL_BORDER_FILTER);
       - where m is a cpl_mask with a CPL_BINARY_1 whereever k has a 1.0.
   cpl_image_filter_stdev: Same as for cpl_image_filter_median, but with
     CPL_FILTER_STDEV
   cpl_image_filter_linear: cpl_image * a = cpl_image_filter_linear(b, k)
       can be replaced by
     int nx   = cpl_image_get_size_x(b);
     int ny   = cpl_image_get_size_y(b);
     int type = cpl_image_type(b);
     cpl_image * a = cpl_image_new(nx, ny, type);
     cpl_image_filter(a, b, k, CPL_FILTER_LINEAR, CPL_BORDER_FILTER);
       - where m is the cpl_matrix with the weights.
   cpl_image_filter_morpho: Same as for cpl_image_filter_linear, but with
     CPL_FILTER_MORPHO
   cpl_polynomial_fit_1d_create:
     cpl_polynomial * fit1d = cpl_polynomial_fit_1d_create(x_pos,
                                                          values,
                                                          degree,
                                                          mse);
       can be replaced by
     cpl_polynomial * fit1d = cpl_polynomial_new(1);
     cpl_matrix     * samppos = cpl_matrix_wrap(1, cpl_vector_get_size(x_pos),
                                                cpl_vector_get_data(x_pos));
     cpl_vector     * fitresidual = cpl_vector_new(cpl_vector_get_size(x_pos));
     cpl_polynomial_fit(fit1d, samppos, NULL, values, NULL,
                        CPL_FALSE, NULL, &degree);

     cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL, fit1d,
                                             samppos, NULL);
     cpl_matrix_unwrap(samppos);
     mse = cpl_vector_product(fitresidual, fitresidual)
         / cpl_vector_get_size(fitresidual);
     cpl_vector_delete(fitresidual);

   cpl_polynomial_fit_2d_create: Similar to 1D, and the samppos matrix must
     have two rows with copies of the two vectors in the x_pos bivector.
   cpl_msg_progress: This function has no CPL 5.X equivalent
   cpl_vector_new_lss_kernel: This function has no CPL 5.X equivalent
   cpl_vector_convolve_symmetric: This function has no CPL 5.X equivalent
 
 - How to change the calls to functions with new prototypes
   cpl_dfs_save_image(allframes, parlist, usedframes, image, bpp, recipe,
                      procat, applist, remregexp, pipe_id, filename);
    can be replaced with:
      cpl_propertylist * prolist  = applist
                                  ? cpl_propertylist_duplicate(applist)
                                  : cpl_propertylist_new();
      cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procat);

      cpl_dfs_save_image(allframes, NULL, parlist, usedframes, NULL, image, bpp,
                         recipe, prolist, remregexp, pipe_id, filename);
      cpl_propertylist_delete(prolist);

   cpl_dfs_save_table: See cpl_dfs_save_image
   cpl_dfs_save_propertylist: See cpl_dfs_save_image
   cpl_dfs_save_imagelist: See cpl_dfs_save_image
   cpl_dfs_setup_product_header: Append a NULL pointer to the argument list,
   cpl_geom_img_offset_saa: : Append two NULL pointers to the argument list,
   cpl_propertylist_erase_regexp: In case of error, the return value is now
     -1 instead of 0.
   cpl_image_get_bpm_const: The function will now return NULL if the image
     does not have a bad pixel map, meaning no pixels are bad. If the input
     image is guaranteed to have a bad pixel map, then no change is needed.
     Otherwise, if the bad pixel map must be modified the call should be
     replaced with cpl_image_get_bpm().  If the bad pixel map will not be
     modified i.e. only read, then a NULL value indicates that no pixels
     are bad. This can be used both to determine if a pixel map exists for
     the image, and to choose faster methods when no pixels are bad.
   cpl_polynomial_shift_1d: Insert a 0 between the current two parameters.
   cpl_imagelist_collapse_sigclip_create: Extend the argument list with
     0.0, 1.0, 1, NULL.

 - New functions in CPL
     cpl_image_filter_xyz
     cpl_fits_count_extensions
     cpl_fits_find_extension
     cpl_array_get_max
     cpl_array_get_min
     cpl_array_get_maxpos
     cpl_array_get_minpos
     cpl_array_get_mean
     cpl_array_get_median
     cpl_array_get_stdev
     cpl_array_extract
     cpl_array_insert_window
     cpl_array_erase_window
     cpl_array_insert
     cpl_array_add
     cpl_array_subtract
     cpl_array_multiply
     cpl_array_divide
     cpl_array_add_scalar
     cpl_array_subtract_scalar
     cpl_array_multiply_scalar
     cpl_array_divide_scalar
     cpl_array_set_size
     cpl_image_rebin
     cpl_image_fill_jacobian
     cpl_image_fill_jacobian_polynomial
     cpl_array_power
     cpl_array_abs
     cpl_array_logarithm
     cpl_array_exponential
     cpl_table_where_selected
     cpl_table_set_column_savetype
     cpl_image_wrap_double_complex
     cpl_image_wrap_float_complex
     cpl_image_get_data_double_complex
     cpl_image_get_data_double_complex_const
     cpl_image_get_data_float_complex
     cpl_image_get_data_float_complex_const
     cpl_image_get_complex
     cpl_image_set_complex

 - New types CPL_TYPE_DOUBLE_COMPLEX and CPL_TYPE_FLOAT_COMPLEX
   These 2 types are now supported for a limited set of image functions:
     cpl_image_new
     cpl_image_add
     cpl_image_subtract
     cpl_image_multiply
     cpl_image_divide
     cpl_image_add_create
     cpl_image_subtract_create
     cpl_image_multiply_create
     cpl_image_divide_create
     cpl_image_cast
     cpl_image_fill_rejected
     cpl_image_dump_window
     cpl_image_extract

   The purpose of the inclusion of these new types is to ease operations with
   the FFTW library on CPL images. With these new types, there is no need to
   remap the input pixel buffer before calling FFTW.

   Example (with FFTW 2.1.5):

     cpl_image     * in    = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
     cpl_image     * out   = cpl_image_new(nx, ny, CPL_TYPE_FLOAT_COMPLEX);

     float         * in_b  = cpl_image_get_data_float(in);
     float complex * out_b = cpl_image_get_data_float_complex(out);

     fftwnd_plan rp = rfftw2d_create_plan(nx, ny, FFTW_FORWARD, FFTW_ESTIMATE);

     cpl_image_fill_noise_uniform(in, 0.0, 10.0);

     rfftwnd_real_to_complex(rp, 1, 
	               	     (fftw_real *)in_b,     1, nx * ny,
                 	     (fftw_complex *)out_b, 1, nx * ny);

     my_frequency_processing(out);
