/*===========================================================================
  Copyright (C) 1993-2009 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
===========================================================================*/

/******************************************************************************
**
**    UNIT
**
**    Version: 19.1
**
**    Author: Jean-Luc Starck
**
**    Date:  03/02/25
**    
**    File:  entr_plan.c
**
.VERSION
 090804		last modif
*******************************************************************************
**
**    DESCRIPTION  replace a plane of a wavelet transform by an image
**    -----------  
**  
******************************************************************************
**
** wavelet_enter_plan_file (File_Name_Imag, File_Name_Transform, 
**                          Num_Plan, File_Name_Out)
** char *File_Name_Imag, *File_Name_Transform, *File_Name_Out;
** int Num_Plan;
** 
** Remplace un plan de la transformee en ondelette contenue dans le fichier
** File_Name_Transform  par une image de nom File_Name_Imag. 
** Num_Plan = numero du plan a remplacer (Num_Plan = 1 .. Nbr_Plan)
** La transformee resultante est ecrit dans un fichier de nom File_Name_Out
** Replaces a plane from a wavelet transform which is in the file of name
** File_Name_Transform by an image. The new wavelet transform is saved
** in a file of name File_Name_Out
** 
** File_Name_Imag = input file name of the image
** File_Name_Transform = input file name of the wavelet transform
** Num_Plan = plane number to extract (Num_Plan = 1 .. Number_of_Planes)
** File_Name_Out = output file name of the wavelet transform
**
******************************************************************************
**
** wavelet_enter_plan (Wavelet, Imag, Nl, Nc, Num_Plan)
** float *Imag;
** wave_transf_des *Wavelet;
** int *Nl, *Nc, Num_Plan;
** 
** Replaces a plane of a wavelet transform by an image
** 
** Wavelet = INPUT:OUTPUT: wavelet transform
** Imag = INPUT: image
** Nl = OUTPUT: ptr to the number of lines
** Nc = OUTPUT: ptr to the number of columns
** Num_Plan = plane number to replace (Num_Plan = 1 .. Number_of_Planes)
**  
******************************************************************************/


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

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

extern void wave_io_read(), wave_io_free(), wave_io_write();
extern void io_read_file_to_pict_f(), io_err_message_exit();
extern void mallat_2d_enter_plan();

void wavelet_enter_plan(), wavelet_enter_plan_mallat();

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

void wavelet_enter_plan_file (File_Name_Imag, File_Name_Transform, Num_Plan, File_Name_Out)
char *File_Name_Imag, *File_Name_Transform, *File_Name_Out;
int Num_Plan;
{
    float *Imag;
    wave_transf_des Wavelet;
    int Nl, Nc;

    /* read the wavelet file */
    wave_io_read (File_Name_Transform, &Wavelet);

    /* read the image */
    io_read_file_to_pict_f (File_Name_Imag, &Imag, &Nl, &Nc);

    /* replace the plane */
    wavelet_enter_plan (&Wavelet, Imag, Nl, Nc, Num_Plan);

    /* write the result */
    wave_io_write (File_Name_Out, &Wavelet);

    wave_io_free (&Wavelet);
    free ((void *) Imag);
}

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

void wavelet_enter_plan (Wavelet, Imag, Nl, Nc, Num_Plan)
float *Imag;
wave_transf_des *Wavelet;
int Nl, Nc, Num_Plan;
{
    float *Ptr;
    int i, Nl1, Nc1, Nbr_Plan;
    string Mes_Memory;

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

    /* Test the plane number Num_Plan */
    if ((Num_Plan <= 0) || (Num_Plan > Nbr_Plan))
    {
        /* The plane number Num_Plan is false */
        sprintf (Mes_Memory," : Number of planes = %d\n", Nbr_Plan);
        io_err_message_exit (ERR_PLANE_NUMBER, Mes_Memory);
    }

    switch (Wavelet->Type_Wave_Transform)
    {
        case TO_PAVE_LINEAR:
        case TO_PAVE_BSPLINE:
        case TO_PAVE_BSPLINE_FFT:
                   if ((Nl != Wavelet->Nbr_Ligne) || (Nc != Wavelet->Nbr_Col))
                   {
                       sprintf (Mes_Memory, 
                           ", plane and image must have the same size");
                       io_err_message_exit (ERR_IMAGE_SIZE, Mes_Memory);
                   }
                   Ptr = Wavelet->Pave.Data + (Num_Plan - 1) * Nl * Nc;
                   for (i = 0; i < Nl * Nc; i++) Ptr[i] = Imag[i];
                   break;
        case TO_PYR_LINEAR:
        case TO_PYR_BSPLINE:
        case TO_PYR_FFT_DIFF_RESOL:
        case TO_PYR_FFT_DIFF_SQUARE_RESOL:
                   Nl1 = (Wavelet->Pyramid.Tab_Nl) [Num_Plan - 1];
                   Nc1 = (Wavelet->Pyramid.Tab_Col)[Num_Plan - 1];
                   if ((Nl != Nl1) || (Nc != Nc1))
                   {
                       sprintf (Mes_Memory, 
                           ", plane and image must have the same size");
                       io_err_message_exit (ERR_IMAGE_SIZE, Mes_Memory);
                   }
                   Ptr = Wavelet->Pyramid.Data +
                                    (Wavelet->Pyramid.Tab_Pos)[Num_Plan - 1];
                   for (i = 0; i < Nl * Nc; i++) Ptr[i] = Imag[i];
                   break;
        case TO_MALLAT_BARLAUD:
                  wavelet_enter_plan_mallat (Wavelet,Imag,Nl,Nc,Num_Plan);
                   break;
        default:
                   io_err_message_exit (ERR_TRANSF, " ");
                   break;
    }   
}

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

void wavelet_enter_plan_mallat (Wavelet, Imag,  Nl, Nc, Num_Plan)
float *Imag;
wave_transf_des *Wavelet;
int Nl, Nc, Num_Plan;
{
    struct mallat_plan_des *Ptr_Mallat;
    int Num_Etap, i, Nbr_Plan;
    string Mes_Memory;

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

    /* Test the plane number Num_Plan */
    if ((Num_Plan <= 0) || (Num_Plan > Nbr_Plan))
    {
        /* The plane number Num_Plan is false */
        sprintf (Mes_Memory,", Number of scales = %d\n", Nbr_Plan);
        io_err_message_exit (ERR_PLANE_NUMBER, Mes_Memory);
    }

    Ptr_Mallat = &(Wavelet -> Mallat);

    if (Num_Plan == Nbr_Plan)
    {
        /* we go to the last plane */
        for (Num_Etap = 1; Num_Etap < Nbr_Plan - 1; Num_Etap++)
        {
            Ptr_Mallat = Ptr_Mallat -> Smooth_Imag;
        }
        if ((Ptr_Mallat -> Nl != Nl) || (Ptr_Mallat -> Nc != Nc))
	{
           /* The image size is bad */
           sprintf (Mes_Memory, ", plane and image must have the same size");
           io_err_message_exit (ERR_IMAGE_SIZE, Mes_Memory);
        }
        /* copy the imag to the last resolution plane */
        for (i = 0; i < Nl*Nc; i++)
                  (Ptr_Mallat -> Low_Resol) [i] = Imag[i];
    }
    else
    {
        /* we go the plane to extract */
        for (Num_Etap = 1; Num_Etap < Num_Plan; Num_Etap++)
        {
            Ptr_Mallat = Ptr_Mallat -> Smooth_Imag;
        }

        if ((2*Ptr_Mallat -> Nl != Nl) || (2*Ptr_Mallat -> Nc != Nc))
	{
           /* The image size is bad */
           sprintf (Mes_Memory, ", plane and image must have the same size");
           io_err_message_exit (ERR_IMAGE_SIZE, Mes_Memory);
        }

        /* enter the image */
        mallat_2d_enter_plan(Imag,Nl,Nc, Ptr_Mallat, Nbr_Plan-Num_Plan+1);
    }
}




