/* >c.fileio */
/****************************************************************/
/*                                                              */
/*                   FILE : FILEIO.C                            */
/*                                                              */
/*             Last Updated : 10 - 12 - 87                      */
/*                       By : R. de Vries                       */
/*                                                              */
/*      CONTENTS :                                              */
/*      set_impar(), getFile(), putFile(), fromdisc(),          */
/*      todisc()                                                */
/*                                                              */
/****************************************************************/

/*       Original filename : TRANSFILE.C
*
*        DESCRIPTION
*        Contains functions to store and recall data in/from file.
*
*        HISTORY
*        25-sep-85  Frank van Breukelen (breuk) at TPD Delft created
*            according to calls to the functions getFile and putFile
*            in TRANSFER.C
*
*/

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "window.h"
#include "errors.h"
#include "stdlib.h"
#include "arthur.h"
/* #include "io.h" */
/* #include "standard.h" */
#include "filetype.h"

#define max(a,b) ((a) > (b) ? (a) : (b))
#define O_RDONLY        0
#define O_RAW           0
#define O_WRONLY        1
#define O_CREAT         0
#define O_TRUNC         0
#define Arc_Word        32
#define Arc_Byte        8



os_error er;
extern int disp_on;
extern VENSTER *vp[MAXSIG];
extern int Realloc_Venster(VENSTER *vp, unsigned int alloc_size);
extern int SAMPLE_RATE;

extern void fatal_err(char *);

/* Dpg
static osfile_block osfileblok[1];
*/

os_error *SetFileType(char *filename,int filetype)
{
   os_error *err;
   wimpt_complain(os_swi3(OS_File,0x12,(int)filename,filetype));
   return(err);
}

void GetFileType(char *name, int *type)
{
 os_regset r;
os_error *e;
r.r[0]=17;
r.r[1]=(int)name;
e = os_swix(8,&r);
*type=(r.r[2]&0x000fff00)>>8;
}




/**************************************************************************
 * getFile: Leest een array van char uit een file.                        *
 * Input  : filename.                                                     *
 *        : buffer: hierin komt de gelezen array te staan.                *
 *        : nbytes: aantal te lezen chars.                                *
 *        : offset: Eerst offset chars overslaan.                         *
 * Returns: Aantal gelezen chars.                                         *
 *        : -1 als file niet bestaat.                                     *
 **************************************************************************/

int getFile (char *filename, char *buffer, int nbytes, int offset)

{
 int n;          /* number of bytes actual read */
 FILE *fp;       /* filedescriptor              */
 
 
                 /* Open the file               */

 if((fp=fopen(filename,"rb"))==NULL)
   { 
   fclose(fp);
   strcpy(er.errmess,"File not found\n --");
   strcat(er.errmess,filename);
   er.errnum=3;
   wimpt_complain(&er);
   return(-1);
   }

 if (offset > 0) fseek(fp,offset,SEEK_CUR);
 n=fread(buffer,sizeof(char),(int)nbytes,fp);
 fclose(fp);

 return (n);
}


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

int putFile (char *filename, char *buffer, int nbytes, int verbose, BOOL data)

{
 
 FILE *fp;
 char txtbuf[256];
 

/* Set protection mode, create and open the file,
*  reset the protection mode
*/


if (!data)
   {
   fp=fopen(filename,"wb");
   
   /* Write the buffer and check                                        */
   if (fwrite(buffer,sizeof(char),nbytes, fp) < (int)nbytes)
      {
      sprintf(txtbuf,"Error writing in file %s\n", filename);
      if (verbose) printw("%s",txtbuf);
      fclose(fp);
      return (ERR_WRITEFILE);
      } 
   
 /*  Close the file and return  */
   if (fclose(fp))
      {
      sprintf(txtbuf,"Error closing %s\n", filename);
      if (verbose) printw("%s",txtbuf);
      return (ERR_CLOSEFILE);
      }
   return (NO_ERROR);
   }


/* Schrijf de data weg */

if (data)
   {
   fp=fopen(filename,"ab");
   if (fp==NULL)
      { 
      strcpy(er.errmess,"File not found\n --");
      strcat(er.errmess,filename);
      er.errnum=3;
      wimpt_complain(&er);
      fclose(fp);
      return(ERR_OPENFILE);
      } 

 /* Write the buffer and check */
   if (fwrite(buffer,sizeof(char),nbytes, fp) < (int)nbytes)
      {
      sprintf(txtbuf,"Error writing in file %s\n", filename);
      if (verbose) printw("%s",txtbuf);
      fclose(fp);
      return (ERR_WRITEFILE);
      }

/* Close the file and return */
   if (fclose(fp))
      {
      sprintf(txtbuf,"Error closing %s\n", filename);
      if (verbose) printw("%s",txtbuf);
      return (ERR_CLOSEFILE);
      }
      return (NO_ERROR);
   }
   return (NO_ERROR);
}



/************************************************************************/
/*
*  fromdisc reads an image from floppy disc
*  wp    : image structure to be written to disc
*  filename : name of file to be read from disc
*/

int fromdisc(VENSTER *vp, int file_type)
{
  
   asm_header *hp;
   char *filename;
   char *real_data_char;
   char *imag_data_char;
   short *real_data_short;
   short *imag_data_short;
   int *real_data_int;
   int *imag_data_int;
   float *real_data_float;
   float *imag_data_float;
   double *real_data_double;
   double *imag_data_double;
   SAMPLE *real_data;
   SAMPLE *imag_data;
   unsigned int elements,alloc_size;
   int    nbytes;
   int    teller,offset;
   int    dtype;

   
   real_data = DataReal(vp); /* Bewaar de pointers */
   imag_data = DataImag(vp);

   filename = Window_File(vp);
   hp = &vp -> header;
   if (getFile(filename, (char *)hp, (int)sizeof(asm_header),0) == -1)
   return ERR_OPENFILE;     

   DataReal(vp) = real_data;  /* Zet pointers terug */
   DataImag(vp) = imag_data;
  


  if (file_type == TCL )
    {
      wprintf("Inputfile is a TCL-file.\n");
      DataDomain(vp) = TIME;
      DataType(vp) = REAL;
      DataRecords(vp)= 1;
      DataSampleRate(vp) = SAMPLE_RATE;
    }
   
   elements =DataChannels(vp)*DataRecords(vp)*DataLength(vp);
   alloc_size = elements;

   Realloc_Venster(vp,alloc_size);

   real_data = DataReal(vp);
   imag_data = DataImag(vp);


      


   dtype = DataType(vp);

   switch (DataBits_p_s(vp))
   {
   case 8:                        /* Binnenhalen 8 bits data. (char) */   
              nbytes=elements;
              if ((dtype == 0) || (dtype == 2))   /* Reele deel */
              {
                if ((real_data_char = (char *) heap_alloc((unsigned int)elements*sizeof(char))) == NULL)
                      werr (1,"Error in fromdisc: heap_alloc failed\r");
              
                if (getFile(filename,(char *)real_data_char,(int)nbytes,(int)sizeof(asm_header)) == -1)
                {
                 heap_free(real_data_char);
                 return ERR_OPENFILE; 
                }
              
                for (teller=0;teller < elements;teller++)
                {
                  real_data[teller]=(SAMPLE)real_data_char[teller];
                  if (dtype == 0) imag_data[teller]=(SAMPLE)0;
                }
                heap_free(real_data_char);
              }
             if ((dtype == 1) || (dtype == 2))   /* Imaginaire deel */
              { 
                if (dtype == 1) offset=(int)(sizeof(asm_header));
                if (dtype == 2) offset=(int)(sizeof(asm_header)+nbytes);
                if ((imag_data_char = (char *) heap_alloc((unsigned int)elements*sizeof(char))) == NULL)
                      werr (1,"Error in fromdisc: heap_alloc failed\r");
              
                if (getFile(filename,(char *)imag_data_char,(int)nbytes,offset) == -1)
                {
                 heap_free(imag_data_char);
                 return ERR_OPENFILE; 
                } 
              
                for (teller=0;teller < elements;teller++)
                {
                  if (dtype == 1) real_data[teller]=(SAMPLE)0;
                  imag_data[teller]=(SAMPLE)imag_data_char[teller]; 
                }
                heap_free(imag_data_char);
              }     
              break;
              

   case 16:                /* Binnenhalen 16 bits data (short) */
              nbytes=elements*2;
              if ((dtype == 0) || (dtype == 2))   /* Reele deel */
              {
                if ((real_data_short = (short *) heap_alloc((unsigned int)elements*sizeof(short))) == NULL)
                      werr (1,"Error in fromdisc: heap_alloc failed\r");
              
                if(getFile(filename,(char *)real_data_short,(int)nbytes,(int)sizeof(asm_header))==-1)
                 {
                 heap_free(real_data_short);
                 return ERR_OPENFILE; 
                 } 
              
                for (teller=0;teller < elements;teller++)
                {
                   real_data[teller]=(SAMPLE)real_data_short[teller]; 
                   if (dtype == 0) imag_data[teller]=(SAMPLE)0;
                }
               heap_free(real_data_short);
              
              }
              if ((dtype == 1) || (dtype == 2))  /* imaginaire deel */
              {
                if (dtype == 1) offset=(int)(sizeof(asm_header));
                if (dtype == 2) offset=(int)(sizeof(asm_header)+nbytes);
                if ((imag_data_short = (short *) heap_alloc((unsigned int)elements*sizeof(short))) == NULL)
                      werr (1,"Error in fromdisc: heap_alloc failed\r");
              
                if(getFile(filename,(char *)imag_data_short,(int)nbytes,offset)==-1)
                {
                 heap_free(imag_data_short);
                 return ERR_OPENFILE; 
                } 
              
                for (teller=0;teller < elements;teller++)
                {
                  if (dtype == 1) real_data[teller]=(SAMPLE)0;
                  imag_data[teller]=(SAMPLE)imag_data_short[teller]; 
                }
                heap_free(imag_data_short);
              }   
              break;
             

  case 32:             /* Binnenhalen 32 bits data (int) */
              nbytes=elements*4;
              if ((dtype == 0) || (dtype == 2))   /* Reele deel */
              {
                if ((real_data_int = (int *) heap_alloc((unsigned int)elements*sizeof(int))) == NULL)
                      werr (1,"Error in fromdisc: heap_alloc failed\r");
              
                if (getFile(filename,(char *)real_data_int,(int)nbytes,(int)sizeof(asm_header))==-1)
                 {
                 heap_free(real_data_int);
                 return ERR_OPENFILE; 
                 }; 
              
                for (teller=0;teller < elements;teller++)
                {
                    real_data[teller]=(SAMPLE)real_data_int[teller]; 
                   if (dtype == 0) imag_data[teller]=(SAMPLE)0;
                }
                heap_free(real_data_int);
              }

              if ((dtype == 1) || (dtype == 2))   /* Imaginaire deel */
              {
                if (dtype == 1) offset=(int)(sizeof(asm_header));
                if (dtype == 2) offset=(int)(sizeof(asm_header)+nbytes);
                if ((imag_data_int = (int *) heap_alloc((unsigned int)elements*sizeof(int))) == NULL)
                      werr (1,"Error in fromdisc: heap_alloc failed\r");
              
                if(getFile(filename,(char *)imag_data_int,(int)nbytes,offset)==-1)
                 {
                  heap_free(imag_data_int);
                  return ERR_OPENFILE; 
                 }; 
              
                for (teller=0;teller < elements;teller++)
                {                                             
                  if (dtype == 1) real_data[teller]=(SAMPLE)0;
                  imag_data[teller]=(SAMPLE)imag_data_int[teller]; 
                }
                heap_free(imag_data_int);
              }     
     
              break;
              

  case 3232:           /* 32 bits float */
              nbytes=elements*4;
              if ((dtype == 0) || (dtype == 2))   /* Reele deel */
              {
                if ((real_data_float = (float *) heap_alloc((unsigned int)elements*sizeof(float))) == NULL)
                      werr (1,"Error in fromdisc: heap_alloc failed\r");
              
                if(getFile(filename,(char *)real_data_float,(int)nbytes,(int)sizeof(asm_header))==-1)
                 {
                  heap_free(real_data_float);
                  return ERR_OPENFILE; 
                 } 
              
                for (teller=0;teller < elements;teller++)
                {
                     real_data[teller]=(SAMPLE)real_data_float[teller]; 
                     if (dtype == 0) imag_data[teller]=(SAMPLE)0;
                }
                heap_free(real_data_float);
              } 
              if ((dtype == 1) || (dtype == 2))   /* Imaginaire deel */
              {
                if (dtype == 1) offset=(int)(sizeof(asm_header));
                if (dtype == 2) offset=(int)(sizeof(asm_header)+nbytes);
                if ((imag_data_float = (float *) heap_alloc((unsigned int)elements*sizeof(float))) == NULL)
                      werr (1,"Error in fromdisc: heap_alloc failed\r");
              
                if(getFile(filename,(char *)imag_data_float,(int)nbytes,offset)==-1)
                 {
                   heap_free(imag_data_float);
                   return ERR_OPENFILE; 
                 }; 
              
                for (teller=0;teller < elements;teller++)
                {                                             
                  if (dtype == 1) real_data[teller]=(SAMPLE)0;
                  imag_data[teller]=(SAMPLE)imag_data_float[teller]; 
                }
                heap_free(imag_data_float);
              }     
  
              break;
              

  case 6464:           /* 64 bits double */
              nbytes=elements*8;
              if ((dtype == 0) || (dtype == 2))   /* Reele deel */
              {
                if ((real_data_double = (double *) heap_alloc((unsigned int)elements*sizeof(double))) == NULL)
                      werr (1,"Error in fromdisc: heap_alloc failed\r");
              
                if(getFile(filename,(char *)real_data_double,(int)nbytes,(int)sizeof(asm_header))==-1)
                 {
                  heap_free(real_data_double);
                  return ERR_OPENFILE; 
                 }; 
              
                for (teller=0;teller < elements;teller++)
                { 
                    real_data[teller]=(SAMPLE)real_data_double[teller]; 
                    if (dtype == 0) imag_data[teller]=(SAMPLE)0;
                }
                heap_free(real_data_double);
              }

              if ((dtype == 1) || (dtype == 2))   /* Imaginaire deel */
              {
                if (dtype == 1) offset=(int)(sizeof(asm_header));
                if (dtype == 2) offset=(int)(sizeof(asm_header)+nbytes);
                if ((imag_data_double = (double *) heap_alloc((unsigned int)elements*sizeof(double))) == NULL)
                      werr (1,"Error in fromdisc: heap_alloc failed\r");
              
                 if (getFile(filename,(char *)imag_data_double,(int)nbytes,offset)==-1)
                 {
                  heap_free(imag_data_double);
                  return ERR_OPENFILE; 
                 } 
              
                for (teller=0;teller < elements;teller++)
                {                                             
                  if (dtype == 1) real_data[teller]=(SAMPLE)0;
                  imag_data[teller]=(SAMPLE)imag_data_double[teller]; 
                }
                heap_free(imag_data_double);
              }     
  

              break;
              

 default:     break;
 }

/*   switch (type)
   {
 
 
      default:      printw("Trying to read image from non-ASM file.\n");
                    type = GREY;
                    break;
   }

  */


   return (NO_ERROR);
}


/***************************************************************************************/
/*
*  todisc writes an image to disc
*
*  wp       : image structure to be written
*
*  filename : name of file
*
*  returns  TRUE if succesfull
*  returns  FALSE if an error in opening or closing occurred
*  returns  the number of bytes written in this does not equal
*  the image size
*
*********************************************************************************/



int  todisc(VENSTER *vp, int file_type, short bps)
{  
   char *filename;
   char *real_data_char;
   char *imag_data_char;
   short *real_data_short;
   short *imag_data_short;
   int *real_data_int;
   int *imag_data_int;   
   unsigned int elements;
   float *real_data_float;
   float *imag_data_float;
   double *real_data_double;
   double *imag_data_double;
   SAMPLE *real_data;
   SAMPLE *imag_data;
   

   asm_header *hp;
   int    outfile;
   int    nbytes;
   int    teller;
   int    dtype;

   filename = Window_File(vp);
   real_data=DataReal(vp);
   imag_data=DataImag(vp);
   
   dtype = DataType(vp);
   
   if ((hp = (asm_header *) malloc(sizeof(asm_header))) == NULL) return (ERR_ALLOC);

   *hp = (*vp).header;

   hp->bits_p_samp=bps;
   
/*  Wegschrijven van de header  */ 
   
   outfile = putFile(filename,(char *) hp, (int)sizeof(asm_header),TRUE,FALSE);

   free((char *)hp);

 /* Totaal aantal elementen */
   elements = DataChannels(vp)*DataRecords(vp)*DataLength(vp);  

/* Wegschrijven van de data (todisc)   */

   switch (bps)
   {
     case 8:          /* Data saven als chars (8 bit)    */
                 
                 nbytes = elements;
                 if ((dtype == 0) || (dtype == 2))   /* Reele deel */
                  {
                    if ((real_data_char = (char *) heap_alloc((unsigned int)elements*sizeof(char))) == NULL)
                        werr (1,"Error in todisc: heap_alloc failed\r");
                    for (teller=0;teller < elements;teller++)
                        real_data_char[teller]=(char)real_data[teller];
                    outfile = putFile(filename,(char *) real_data_char ,nbytes ,TRUE ,TRUE ); 
                    heap_free(real_data_char);
                  }
                 if ((dtype == 1) || (dtype == 2))   /* Imaginaire deel */
                  {
                    if ((imag_data_char = (char *) heap_alloc((unsigned int)elements*sizeof(char))) == NULL)
                       werr (1,"Error in todisc: heap_alloc failed\r");
                    for (teller=0;teller < elements;teller++)
                       imag_data_char[teller]=(char)imag_data[teller];
                    outfile = putFile(filename,(char *) imag_data_char ,nbytes ,TRUE ,TRUE ); 
                    heap_free(imag_data_char);
                  }
                 break;
               
     case 16:                        /* Data saven als shorts (16 bit) */
                 nbytes = elements*2;

                 if ((dtype == 0) || (dtype == 2))   /* Reele deel */
                  {
                    if ((real_data_short = (short *) heap_alloc((unsigned int)elements*sizeof(short))) == NULL)
                       werr (1,"Error in todisc: heap_alloc failed\r");
                    for (teller=0;teller < elements;teller++)
                       real_data_short[teller]=(short)real_data[teller];
                    outfile = putFile(filename,(char *) real_data_short ,nbytes ,TRUE ,TRUE ); 
                    heap_free(real_data_short);
                  }
                 if ((dtype == 1) || (dtype == 2))   /* Imaginaire deel */
                  {
                    if ((imag_data_short = (short *) heap_alloc((unsigned int)elements*sizeof(short))) == NULL)
                      werr (1,"Error in todisc: heap_alloc failed\r");
                    for (teller=0;teller < elements;teller++)
                     imag_data_short[teller]=(short)imag_data[teller];
                    outfile = putFile(filename,(char *) imag_data_short ,nbytes ,TRUE ,TRUE ); 
                    heap_free(imag_data_short);
                  }
                
                 break;
               
     case 32:    nbytes = elements*4;       /* Data saven als integers (32 bit) */

   
                 if ((dtype == 0) || (dtype == 2))   /* Reele deel */
                  {
                    if ((real_data_int = (int *) heap_alloc((unsigned int)elements*sizeof(int))) == NULL)
                      werr (1,"Error in todisc: heap_alloc failed\r");
                   for (teller=0;teller < elements;teller++)
                      real_data_int[teller]=(int)real_data[teller];
                   outfile = putFile(filename,(char *) real_data_int ,nbytes ,TRUE ,TRUE ); 
                     heap_free(real_data_int);
                  }
                 if ((dtype == 1) || (dtype == 2))   /* Imaginaire deel */
                  {
                    if ((imag_data_int = (int *) heap_alloc((unsigned int)elements*sizeof(int))) == NULL)
                      werr (1,"Error in todisc: heap_alloc failed\r");
                    for (teller=0;teller < elements;teller++)
                     imag_data_int[teller]=(int)imag_data[teller];
                    outfile = putFile(filename,(char *) imag_data_int ,nbytes ,TRUE ,TRUE ); 
                    heap_free(imag_data_int);
                  }
                
                 break;
               


     case 3232:     /* Data saven als float (32 bit) */
                 nbytes = elements*4;
                 if ((dtype == 0) || (dtype == 2))   /* Reele deel */
                  {
                    if ((real_data_float = (float *) heap_alloc((unsigned int)elements*sizeof(float))) == NULL)
                      werr (1,"Error in todisc: heap_alloc failed\r");
                   for (teller=0;teller < elements;teller++)
                      real_data_float[teller]=(float)real_data[teller];
                    outfile = putFile(filename,(char *) real_data_float ,nbytes ,TRUE ,TRUE ); 
                    heap_free(real_data_float);
                  }
                 if ((dtype == 1) || (dtype == 2))   /* Imaginaire deel */
                  {
                    if ((imag_data_float = (float *) heap_alloc((unsigned int)elements*sizeof(float))) == NULL)
                      werr (1,"Error in todisc: heap_alloc failed\r");
                    for (teller=0;teller < elements;teller++)
                         imag_data_float[teller]=(float)imag_data[teller];
                    outfile = putFile(filename,(char *) imag_data_float ,nbytes ,TRUE ,TRUE ); 
                    heap_free(imag_data_float);
                  }
                
                 break;
               
     case 6464: 
                 nbytes = elements*8; 
                 if ((dtype == 0) || (dtype == 2))   /* Reele deel */
                  {
                    if ((real_data_double = (double *) heap_alloc((unsigned int)elements*sizeof(double))) == NULL)
                      werr (1,"Error in todisc: heap_alloc failed\r");
                    for (teller=0;teller < elements;teller++)
                      real_data_double[teller]=(double)real_data[teller];
                    outfile = putFile(filename,(char *) real_data_double ,nbytes ,TRUE ,TRUE ); 
                    heap_free(real_data_double);
                  }
                 if ((dtype == 1) || (dtype == 2))   /* Imaginaire deel */
                  {
                    if ((imag_data_double = (double *)heap_alloc((unsigned int)elements*sizeof(double))) == NULL)
                      werr (1,"Error in todisc: heap_alloc failed\r");
                    for (teller=0;teller < elements;teller++)
                     imag_data_double[teller]=(double)imag_data[teller];
                    outfile = putFile(filename,(char *) imag_data_double ,nbytes ,TRUE ,TRUE ); 
                    heap_free(imag_data_double);
                  }
                
                 break;
     default:    break;
   }

if (outfile !=NO_ERROR) return(ERR_WRITEFILE); 

/* set filetype of just written file */
  SetFileType(filename,ASMF);       

   return(NO_ERROR);
}
