/*===========================================================================
  Copyright (C) 1993-2009-2005 European Southern Observatory (ESO)
 
  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., 675 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*****************************************************************************
**              Copyright (C) 1993 by European Southern Observatory
*******************************************************************************
**
**    UNIT
**
**    Version: 19.1
**
**    Author: Jean-Luc Starck
**
**    Date:  03/02/25
**    
**    File:  filtering.c
**
.VERSION
 090804		last modif

*******************************************************************************
**
**    DESCRIPTION  routines for the filtering in the wavelet space
**    -----------  of an image
**
*******************************************************************************
**
** wave_filter_threshold (Plan, Nl, Nc, Noise)
** float *Plan;
** int Nl, Nc;
** float Noise;
**
** Thresholding the plane
** Plan = IN:OUT wavelet plane
** Nl, Nc = IN: dimension of Plan
** Noise = IN: significant level = k*standard deviation of the noise
**
** Operation:
** For all i, if | Plan[i] | < Noise then Plan[i] = 0
**
*******************************************************************************
**
** wave_filter_hierarchical_thresh(Plan, Nl, Nc, Plan_Next, Noise)
** float *Plan, *Plan_Next;
** int Nl,Nc;
** float Noise;
**
** Hierarchical adaptative thresholding:
** Thresholding the plane
** The level of the threshold is estimated from the next plane
**
** Plan = IN:OUT wavelet plane
** Nl, Nc = IN: dimension of Plan
** Noise = IN: significant level = k*standard deviation of the noise
** Plan_Next =  next plane of the wavelet transform
**               Plan and Plan_Next must have the same size
**
** Operation
**      . A = | Plan [i] | / Noise
**      . If A > 1 then Seuil = 0
**      . Else 
**      .      B = | Plan_Next[i] | / Sigma_Next 
**      .      If B > 1 Then Coef_B = 0     ** linear
**      .      Else B = 1. - 1. / N_Sigma * B     ** interpolation
**      .      Seuil = Noise * B 
**
** Notes:
**     When the wavelet coefficient is superior to the noise 
**   then we don't threshold (Seuil = 0).
**   In the contrary, we look the next plane and we compute
**     B = | Plan_Next[i] | / Sigma_Next. t
**   If B is significant (B > 1), then we don't threshold  (Seuil = 0).
**   If B is under the statistical significant level 
**   then we wheigh the thresholding level by the distance of B
**   from the significant level
**  
*******************************************************************************
**
** wave_filter_hierarchical_wiener (Plan, Nl, Nc, Plan_Next, Sigma_Noise)
** float *Plan, *Plan_Next;
** int Nl,Nc;
** float Sigma_Noise;
**
** Plan = IN:OUT wavelet plane
** Nl, Nc = IN: dimension of Plan
** Sigma_Noise = IN: standart deviation of the noise
** Plan_Next =  next plane of the wavelet transform
**               Plan and Plan_Next must have the same size
** 
**
** Hierarchical Wiener Filtering:
**   Plan[i] = x1 * Plan[i] + x2 * Plan_Next[i]
**   with
**      x1 = T^2 / (B^2 + T^2 + Q^2)
**      x2 = B^2 / (B^2 + T^2 + Q^2)
**      Q^2 = T^2 * B^2 / S^2
**    and
**      B^2 = noise variance = Sigma_Noise * Sigma_Noise
**      S^2 = signal variance = Standart_Deviation(Plan)^2 - B^2
**      T^2 = inter-scale dependance variance
**          = Standart_Deviation(Plan - Plan_Next)^2
**
**  These parameters are computed from the hypothesis that
**  signal and noise are gaussian.
** 
*******************************************************************************
**
** wave_filter_multi_wiener (Plan, Nl, Nc, Sigma_Noise)
** float *Plan;
** int Nl,Nc;
** float Sigma_Noise;
**
** Multiresolution Wiener Filtering
** Plan = IN:OUT wavelet plane
** Nl, Nc = IN: dimension of Plan
** Sigma_Noise = IN: standart deviation of the noise
**
** Plan[i] = x1 * Plan[i]
** with:
**      x1 = S^2 / (B^2 + S^2)
** and
**      B^2 = noise variance= Sigma_Noise * Sigma_Noise
**      S^2 = signal variance = Standart_Deviation(Plan)^2 - B^2
**
*******************************************************************************
**
** wavelet_filtering (Wavelet, N_Sigma, Type_Filter, Noise_Ima)
** wave_transf_des *Wavelet;
** float N_Sigma;
** int Type_Filter;
** float Noise_Ima;
**
** Wavelet = Wavelet transform
** N_Sigma: If we threshold, the level is estimated by:
**          Level = N_Sigma * Noise_Standart_Deviation
**          N_Sigma = 3 is a standart value
** Type_Filter: defines the choosen filtering
**    FILTER_TRESHOLD              1 ==> Thresholding
**    FILTER_HIERARCHICAL_TRESHOLD 2 ==> Hierarchical Thresholding
**    FILTER_HIERARCHICAL          3 ==> Hierarchical Wiener Filtering
**    FILTER_MULTI_RES_WIENER      4  ==> Multiresolution Wiener Filtering
**
** Noise_Ima: Standard deviation of the noise.
**
*******************************************************************************
**
** wave_filter_imag (Imag, Nl, Nc, Result, N_Sigma, Type_Filter, 
**                   Nbr_Iter, Type_Transform, Nbr_Plan, Fc, Sigma_Noise)
** float *Imag, *Result;
** int Type_Transform, Nbr_Plan;
** int Nl, Nc, Type_Filter, Nbr_Iter;
** float Fc, N_Sigma, Sigma_Noise;
**
** filering af an image in the wavelet space
**
** Imag = IN: image
**
** Nl, Nc = IN: dimension of Plan
**
** N_Sigma: If we threshold, the level is estimated by:
**          Level = N_Sigma * Noise_Standart_Deviation
**          N_Sigma = 3 is a standart value
**
** Result = OUT: image filtered
**
** Type_Filter: defines the choosen filtering
**    FILTER_TRESHOLD              1 ==> Thresholding
**    FILTER_HIERARCHICAL_TRESHOLD 2 ==> Hierarchical Thresholding
**    FILTER_HIERARCHICAL          3 ==> Hierarchical Wiener Filtering
**    FILTER_MULTI_RES_WIENER      4  ==> Multiresolution Wiener Filtering
**
**  The best results are obtained with the Hierarchical Wiener Filtering
**
**
** Nbr_Iter: if we threshold, the reconstruction is iterative
** Nbr_Iter between 6 and 10 is generally good
**           Nbr_Iter = 1 ==> no iterative reconstruction
** Type_Transform: wavelet transform algorithm choosen
**       TO_PAVE_LINEAR   1
**       TO_PAVE_BSPLINE  2
**       TO_PAVE_BSPLINE_FFT 3
**       TO_PYR_LINEAR 4
**       TO_PYR_BSPLINE 5
**       TO_PYR_FFT_DIFF_RESOL 6
**       TO_PYR_FFT_DIFF_SQUARE_RESOL 7
**       TO_MALLAT_BARLAUD 8
**           if Type_Transform = TO_MALLAT_BARLAUD, a thresholdind is 
**           performed and Type_Filter has no effect.
**  
** Nbr_Plan: number of scales 
**           it is not necessary to take values for Nbr_Plan superior to 5
** Fc: if Type_Transform = TO_PAVE_BSPLINE_FFT
**                     or  TO_PYR_FFT_DIFF_RESOL
**                     or  TO_PYR_FFT_DIFF_SQUARE_RESOL
**     then we need to know the cut-off frequency of the scaling function
**           generally we take Fc = 0.5
**
** Sigma_Noise: Standard deviation of the noise.
**              if Sigma_Noise = 0, the standart deviation of the noise
**              is estimated in this routine from an automatically way
**
*******************************************************************************
**
** wave_filter_wiener_hier_imag (Imag, Nl, Nc, Result, Nbr_Plan)
** float *Imag, *Result;
** int Nl, Nc, Nbr_Plan;
**
** image filtering by the Hierarchical wiener filtering with the
** a-trou algorithm.
**
** Imag = IN: image
** Nl, Nc = dimension of Plan
** Result = OUT: filtered image
** Nbr_Plan = number of scales
**             (Nbr_Plan = 5 gives good results)
** 
*******************************************************************************
**
** wave_filter_mallat_threshold (Wavelet, Noise_Ima)
** wave_transf_des *Wavelet;
** float Noise_Ima;
**
** Threshold an the wavelet transform of an image which has 
** a noise of standart deviation Noise_Ima
**
******************************************************************************/ 



#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "Def_Math.h"
#include "Def_Mem.h"
#include "Def_Wavelet.h"

#define PRINT_DATA FALSE

/****************************************************************************/

extern void wavelet_pointer_plan(), wavelet_extract_plan();
extern void wavelet_interpol_plan(), wavelet_reconstruct_data();
extern void wavelet_enter_plan(), wavelet_transform_data();
extern void wave_io_alloc(), wave_io_free();
extern void lib_mat_detect_snr();

float lib_mat_ecart_type ();
float lib_mat_correl();

/***************************************************************************/

void wave_filter_mallat_threshold (Wavelet, Noise_Ima)
wave_transf_des *Wavelet;
float Noise_Ima;
{
    struct mallat_plan_des *Ptr_Mallat;
    int Num_Etap, i, Nbr_Plan, Nl, Nc;
    float *Imag_H, *Imag_V, *Imag_D, Noise;
    int Cpt = 0;

    /* number of planes */
    Nbr_Plan = Wavelet -> Nbr_Plan;

    Ptr_Mallat = &(Wavelet -> Mallat);

    for (Num_Etap = 1; Num_Etap < Nbr_Plan; Num_Etap++)
    {
        Noise = Noise_Ima / pow (2., (float) Num_Etap);
        Nl = Ptr_Mallat -> Nl;
        Nc = Ptr_Mallat -> Nc;

        Imag_H = Ptr_Mallat -> Coef_Horiz;
        Imag_V = Ptr_Mallat -> Coef_Vert;
        Imag_D = Ptr_Mallat -> Coef_Diag;
        Cpt = 0;
        for (i = 0; i < Nl*Nc; i++)
        {
           if (fabs(Imag_H[i]) < Noise) 
           {
               Imag_H[i] = 0.;
               Cpt ++;
	   }
           if (fabs(Imag_V[i]) < Noise) 
           {
               Imag_H[i] = 0.;
               Cpt ++;
	   }
           if (fabs(Imag_D[i]) < Noise) 
           {
               Imag_H[i] = 0.;
               Cpt ++;
	   }
        }
#if PRINT_DATA
    Val = (float) Cpt / (float) (3*Nl*Nc) * 100.;
    printf ("Seuil = %f : Pourcentage de Pixels seuilles = %2f \n", Noise, Val);
#endif
        Ptr_Mallat = Ptr_Mallat -> Smooth_Imag;
    }
}

/************************************************************************/

void wave_filter_threshold (Plan, Nl, Nc, Noise)
float *Plan;
int Nl, Nc;
float Noise;
{
    int i;
    int Cpt = 0;
    float Seuil;
    
    Seuil = Noise;
    for (i = 0; i < Nl*Nc; i ++)
    {
        if (fabs(Plan[i]) < Seuil)
        {
            Plan[i] = 0.;
            Cpt ++;
        }
    }
#if PRINT_DATA
    Val = (float) Cpt / (float) (Nl*Nc) * 100.;
    printf ("Seuil = %f : Pourcentage de Pixels seuilles = %2f \n", Seuil, Val);
#endif
}

/***************************************************************************/

void wave_filter_hierarchical_thresh (Plan, Nl, Nc, Plan_Next, Noise)
float *Plan, *Plan_Next;
int Nl,Nc;
float Noise;
{
    int i;
    float Sigma_Next;
    float Coef_Alpha,Coef_Beta,Seuil;
    int Cpt = 0;

    if (Noise > FLOAT_EPSILON)
    {
        /* standart deviation of the next plane */
        Sigma_Next = lib_mat_ecart_type (Plan_Next, Nl, Nc);

        for (i = 0; i < Nl*Nc; i ++)
        {
            /* Threshold calcul */
            Coef_Alpha = fabs(Plan [i]) / Noise;
            if (Coef_Alpha > 1) Seuil = 0.;
            else
            {
                Coef_Beta = fabs(Plan_Next [i]) / Sigma_Next;
                if (Coef_Beta > 1) Coef_Beta = 0.;
                else Coef_Beta = 1. - Coef_Beta;
                Seuil = Noise * Coef_Beta;
            }

            /* Thresholding*/
            if (fabs(Plan [i]) < Seuil) 
            {
                Plan [i] = 0;
                Cpt ++;

            }
        }
    }
#if PRINT_DATA
    Val = (float) Cpt / (float) (Nl*Nc) * 100.;
    printf ("Pourcentage de Pixels seuilles = %2f \n",Val);
#endif
}

/***************************************************************************/

void wave_filter_hierarchical_wiener (Plan, Nl, Nc, Plan_Next, Sigma_Noise)
float *Plan, *Plan_Next;
int Nl,Nc;
float Sigma_Noise;
{
    int i;
    float Sigma_Signal;
    float Sigma_Diff;
    float Coef_T2,Coef_B2,Coef_S2,Coef_Q2,Coef_x1,Coef_x1_Bis;

    Sigma_Signal = lib_mat_ecart_type (Plan, Nl, Nc);

    /* standart deviation of the difference between the two images */
    Sigma_Diff = 0.; 
    for (i = 0; i < Nl*Nc; i++) Sigma_Diff += pow ((Plan [i]-Plan_Next [i]),2.);
    Sigma_Diff = sqrt(Sigma_Diff/(float) (Nl * Nc));

#if PRINT_DATA
    printf ("Sigma_Diff  = %f\n", Sigma_Diff);
    printf ("Sigma_Signal = %f\n", Sigma_Signal);
    printf ("Sigma_Bruit = %f\n", Sigma_Noise);
#endif

    /* Computes the filtering coefficients */
    Coef_T2 = pow ((double)(Sigma_Diff),2.);
    Coef_B2 = pow ((double)(Sigma_Noise),2.);
    Coef_S2 = pow ((double)(Sigma_Signal),2.) - Coef_B2; 
    if (Coef_S2 < 0) Coef_S2 = 0.; 

    Coef_Q2 = Coef_T2 * Coef_B2 / Coef_S2;
    Coef_x1 = Coef_T2 / (Coef_B2 + Coef_T2 + Coef_Q2);
    Coef_x1_Bis = Coef_B2 / (Coef_B2 + Coef_T2 + Coef_Q2);

#if PRINT_DATA    
    printf ("C_T2 = %f, C_B2 = %f\nC_S2 = %f, C_Q2 = %f\n", 
             Coef_T2, Coef_B2, Coef_S2, Coef_Q2);
    printf ("Coef_x1 = %f, Coef_x1_Bis = %f\n", Coef_x1, Coef_x1_Bis);
#endif

    /* Filtering */
    for (i = 0; i < Nl * Nc; i++)
        Plan[i] = Coef_x1 * Plan[i] + Coef_x1_Bis * Plan_Next[i];
}

/***************************************************************************/

void wave_filter_multi_wiener (Plan, Nl, Nc, Sigma_Noise)
float *Plan;
int Nl,Nc;
float Sigma_Noise;
{
    int i;
    float Sigma_Signal, Coef_B2, Coef_S2;
    float Coef_Alpha;

    Sigma_Signal = lib_mat_ecart_type (Plan, Nl, Nc);    

    Coef_B2 = pow ((double)(Sigma_Noise),2.);
    Coef_S2 = pow ((double)(Sigma_Signal),2.) - Coef_B2;
    if (Coef_S2 < 0) Coef_S2 = 0.; 
    Coef_Alpha = Coef_S2 / (Coef_B2 + Coef_S2);

#if PRINT_DATA
   printf ("Coef_Alpha = %f\n", Coef_Alpha);
#endif

    for (i = 0; i < Nl * Nc; i++) Plan[i] *= Coef_Alpha;
}


/***************************************************************************/

void wavelet_filtering (Wavelet, N_Sigma, Type_Filter, Noise_Ima)
wave_transf_des *Wavelet;
float N_Sigma;
int Type_Filter;
float Noise_Ima;
{
    int i, Nl, Nc, Nbr_Etap;
    float *Plan;
    float *Plan_Next;
    float Noise;

    Nbr_Etap = Wavelet->Nbr_Plan - 1;

    /* Filtering scale by scale */
    for (i = Nbr_Etap-2; i >= 0; i--)
    {
        /* estimation of the noise at the scale i */
          /*Noise = N_Sigma *  Noise_Ima / pow (4., (float) i);*/
	  switch(i)
	  {
	  case 0: Noise = 0.89*Noise_Ima;break;
	  case 1: Noise = 0.2*Noise_Ima;break;
	  case 2: Noise = 0.086*Noise_Ima;break;
	  case 3: Noise = 0.04*Noise_Ima;break;
          default: Noise = 0.;break;
	  }
          wavelet_pointer_plan (Wavelet, &Plan, &Nl, &Nc, i+1, 0);
#if PRINT_DATA
        printf ("\nPlan %d (%d,%d) : Seuil = %f\n", i+1, Nl, Nc, Noise);
#endif

        switch (Type_Filter)
        {
            case FILTER_TRESHOLD:
                  wave_filter_threshold (Plan, Nl, Nc, Noise*N_Sigma);
                  break;
            case FILTER_HIERARCHICAL_TRESHOLD:
                 wavelet_interpol_plan(Wavelet,&Plan_Next, &Nl, &Nc, i+2, i+1);
                 wave_filter_hierarchical_thresh (Plan, Nl, Nc, Plan_Next,
                                                      Noise*N_Sigma);
                 free ((void *) Plan_Next);
                 break;
            case FILTER_HIERARCHICAL:
                 wavelet_interpol_plan(Wavelet,&Plan_Next, &Nl, &Nc, i+2, i+1);
                 wave_filter_hierarchical_wiener (Plan, Nl, Nc, 
                                                   Plan_Next, Noise);
                 free ((void *) Plan_Next);
                 break;
            case FILTER_MULTI_RES_WIENER:
                  wave_filter_multi_wiener (Plan, Nl, Nc, Noise);
                  break;
            default:
                  printf ("Bad Type Filtering\n");
                  exit (-1);
        }

    }
}

/***************************************************************************/

static void copy_wave (W1, W2)
wave_transf_des *W1, *W2;
{
    int i, Nl, Nc, Nbr_Plan;
    float *P1;

    Nbr_Plan = W1->Nbr_Plan;

    for (i = 0; i < Nbr_Plan; i++)
    { 
        wavelet_extract_plan (W1, &P1, &Nl, &Nc, i+1);

        wavelet_enter_plan (W2, P1, Nl, Nc, i+1);
        free ((void *) P1);
     }
}

/***************************************************************************/

void wave_filter_rec_iter_citter (Wavelet, Imag, Nbr_Iter)
wave_transf_des *Wavelet;
float *Imag;
int Nbr_Iter;
{
    int i, j, Iter, Nbr_Plan, Nl0, Nc0, Nl,Nc;
    float *Oper,*Sol,*List_Dirac, *Old_Oper;
    float Distance;
 

    wave_transf_des Wavelet_Oper, Wavelet_Sol, W_Old_Oper;

    Nbr_Plan = Wavelet->Nbr_Plan;
    Nl0 = Wavelet->Nbr_Ligne;
    Nc0 = Wavelet->Nbr_Col;
    wave_io_alloc (&Wavelet_Sol, Wavelet->Type_Wave_Transform, 
                   Nbr_Plan, Nl0, Nc0, Wavelet->Pyramid.Freq_Coup);
    wave_io_alloc (&W_Old_Oper, Wavelet->Type_Wave_Transform, 
                   Nbr_Plan, Nl0, Nc0, Wavelet->Pyramid.Freq_Coup);
    copy_wave (Wavelet, &Wavelet_Sol);

    for (Iter = 0; Iter < Nbr_Iter; Iter++)
    {
        wavelet_reconstruct_data (&Wavelet_Sol, Imag, 0);
        
        for (j = 0; j < Nl0*Nc0; j++) if (Imag[j] < 0.) Imag[j] = 0.;

        wavelet_transform_data (Imag, Wavelet->Nbr_Ligne,
                                Wavelet->Nbr_Col,
                                &Wavelet_Oper,
                                Wavelet->Type_Wave_Transform,
                                Wavelet->Pyramid.Freq_Coup, 
                                Wavelet->Nbr_Plan);
        Distance = 0.;
        for (i = Nbr_Plan - 1; i >= 0; i--)
        { 
            float Val;
            int Cpt = 0;

            wavelet_pointer_plan (Wavelet, &List_Dirac, &Nl, &Nc, i+1, 0);
            wavelet_pointer_plan (&Wavelet_Oper, &Oper, &Nl, &Nc, i+1, 0);
            wavelet_pointer_plan (&Wavelet_Sol, &Sol, &Nl, &Nc, i+1, 0);
            wavelet_pointer_plan (&W_Old_Oper, &Old_Oper, &Nl, &Nc, i+1, 0);
            for (j = 0; j < Nl*Nc; j++)
            {
                if (fabs(List_Dirac[j]) > FLOAT_EPSILON)
                {
                    Val = Sol[j] + List_Dirac[j] - Oper[j];
                    Distance += fabs(List_Dirac[j] - Oper[j]);
                    Sol[j] = Val;
                    Cpt ++;
                }
                else
                { 
                    if (Iter == 0) Sol[j] = Oper[j];
                    else Sol[j] += Old_Oper[j] - Oper[j];
		}
            }
#if PRINT_DATA
    Val = (float) Cpt / (float) (Nl*Nc) * 100.;
    printf ("Pourcentage de Pixels seuilles = %2f \n", Val);
#endif
        }

#if PRINT_DATA
        printf ("%d : Distance = %f\n", Iter, Distance);
#endif
        copy_wave (&Wavelet_Oper, &W_Old_Oper);
    }

    wave_io_free (&Wavelet_Sol);
    wave_io_free (&Wavelet_Oper);
    wave_io_free (&W_Old_Oper);
}

/****************************************************************************/

void wave_filter_imag (Imag, Nl, Nc, Result, N_Sigma, Type_Filter,
                  Nbr_Iter, Type_Transform, Nbr_Plan, Fc, Sigma_Noise)
float *Imag, *Result;
int Type_Transform, Nbr_Plan;
int Nl, Nc, Type_Filter, Nbr_Iter;
float Fc, N_Sigma, Sigma_Noise;
{
    wave_transf_des Wavelet;
    float Moyenne, Noise_Ima;

    if (Sigma_Noise < FLOAT_EPSILON)
            lib_mat_detect_snr (Nc,Nl,Imag,1,3,&Moyenne,&Noise_Ima);
    else Noise_Ima = Sigma_Noise;

    if (Type_Transform == TO_MALLAT_BARLAUD)
    {
        wavelet_transform_data (Imag, Nl, Nc, &Wavelet, 
                            Type_Transform, Fc, Nbr_Plan);
        wave_filter_mallat_threshold (&Wavelet, Noise_Ima*N_Sigma);
        wavelet_reconstruct_data (&Wavelet, Result, 0);
    }
    else
    {
        wavelet_transform_data (Imag, Nl, Nc, &Wavelet, 
                            Type_Transform, Fc, Nbr_Plan+1);
        wavelet_filtering (&Wavelet, N_Sigma, Type_Filter, Noise_Ima);

        if (((Type_Filter > 2) && (Type_Filter < 6))  || (Nbr_Iter == 1))
                  wavelet_reconstruct_data (&Wavelet, Result, 0);
        else  wave_filter_rec_iter_citter (&Wavelet, Result, Nbr_Iter);
    }
    wave_io_free (&Wavelet);
}

/****************************************************************************/

void wave_filter_wiener_hier_imag (Imag, Nl, Nc, Result, Nbr_Plan)
float *Imag, *Result;
int Nl, Nc, Nbr_Plan;
{
    int Type_Transform = TO_PAVE_BSPLINE;
    float Fc = 0.5, N_Sigma = 3.;
    int Nbr_Iter = 1, Type_Filter = FILTER_HIERARCHICAL;

    wave_filter_imag (Imag, Nl, Nc, Result, N_Sigma, Type_Filter,
                  Nbr_Iter, Type_Transform, Nbr_Plan, Fc, 0.);
}



