/* inout.c -- routines for disk and screen i/o      */

#include "erlib.h"
#include "inout.h"

/* ------------------------------------------------------------ */
int hf_write(char *fname)                /* print out hf array to file */
{
  int ix,iy;
  FILE *fpout;
  int rval;
  float maxheight = 65535;        /* maximum value of array */
						/* open input file */
  if ((fpout = fopen(fname,"w")) == NULL)
   { perror("Could not open output file ");
     exit(1);
   }

  printf("Writing %s",fname);
  printf(" (%dx%d)",xsize,ysize);
  fflush(stdout);
  fprintf(fpout,"P2\n");
  fprintf(fpout,"%d %d\n",xsize,ysize);
  fprintf(fpout,"%5.3f\n",maxheight);

   for (iy = 1; iy<(ysize+1); iy++) {
    for (ix = 1; ix<(xsize+1); ix++) {
	fprintf(fpout,"%1.5e ",Eh(hf,ix,iy));
    }
     fprintf(fpout,"\n");
   }
   fclose(fpout);
   printf(".\n");
   rval = 0;
   return(rval);
}

/* ------------------------------------------------------------ */
int pgm_write(char *fname, float *array)   /* write out an array to file */
{
  int ix,iy;
  FILE *fpout;
  int rval;
  float uval, umax, umin, scale;
  float tval;
  float maxheight = 255;        /* maximum value of array */
					/* open input file */
  if ((fpout = fopen(fname,"w")) == NULL)
   { perror("Could not open output file ");
     exit(1);
   }

   umax = (float) sqrt( (double) El(array,0,0) );
   umin = umax;
					/* change scale, take sqrt() */
   for (iy = 0; iy<ysize; iy++) {
    for (ix = 0; ix<xsize; ix++) {
	uval = El(array,ix,iy);
	if (uval < 0.0) uval = 0.0;
	/* printf("%1.1f ",tval); */
	/* uval = (float) sqrt((double)tval); */
	/* El(array,ix,iy) = uval; */
	if (uval > umax) umax = uval;
	if (uval < umin) umin = uval;
    }
    /* printf("\n"); */
   }
  if ((umax-umin) != 0)
    scale = 255.0 / (umax-umin);
  else scale = 0;

  printf("Writing %s ",fname);
  printf("(%dx%d)",xsize,ysize);
  fflush(stdout);
  fprintf(fpout,"P2\n");
  fprintf(fpout,"# %s saved from erode.c\n",fname);
  fprintf(fpout,"# umax= %lf, umin= %lf, scale= %lf\n",umax,umin,scale);
  fprintf(fpout,"%d %d\n",xsize,ysize);
  fprintf(fpout,"%d\n",(int)maxheight);

   for (iy = 0; iy<ysize; iy++) {
    for (ix = 0; ix<xsize; ix++) {
	fprintf(fpout,"%d\n",(int) ((El(array,ix,iy)-umin)*scale) );
    }
     /* fprintf(fpout,"\n"); */
   }
   fclose(fpout);
   printf(".\n");
   rval = 0;
   return(rval);
}

/* ------------------------------------------------------------ */
int pgm_write_hf(char *fname, float *array)   /* write out an array to file */
{
  int ix,iy;
  FILE *fpout;
  int rval;
  float uval, umax, umin, scale;
  float tval;
  float maxheight = 255;        /* maximum value of array */
					/* open input file */
  if ((fpout = fopen(fname,"w")) == NULL)
   { perror("Could not open output file ");
     exit(1);
   }

   umax = (float) sqrt( (double) Eh(array,0,0) );
   umin = umax;
					/* change scale, take sqrt() */
   for (iy = 0; iy<ysize; iy++) {
    for (ix = 0; ix<xsize; ix++) {
	uval = Eh(array,ix,iy);
	if (uval < 0.0) uval = 0.0;
	/* printf("%1.1f ",tval); */
	/* uval = (float) sqrt((double)tval); */
	/* El(array,ix,iy) = uval; */
	if (uval > umax) umax = uval;
	if (uval < umin) umin = uval;
    }
    /* printf("\n"); */
   }
  if ((umax-umin) != 0)
    scale = 255.0 / (umax-umin);
  else scale = 0;

  printf("Writing %s ",fname);
  printf("(%dx%d)",xsize,ysize);
  fflush(stdout);
  fprintf(fpout,"P2\n");
  fprintf(fpout,"# %s saved from erode.c\n",fname);
  fprintf(fpout,"# umax= %lf, umin= %lf, scale= %lf\n",umax,umin,scale);
  fprintf(fpout,"%d %d\n",xsize,ysize);
  fprintf(fpout,"%d\n",(int)maxheight);

   for (iy = 0; iy<ysize; iy++) {
    for (ix = 0; ix<xsize; ix++) {
	fprintf(fpout,"%d\n",(int) ((Eh(array,ix,iy)-umin)*scale) );
    }
     /* fprintf(fpout,"\n"); */
   }
   fclose(fpout);
   printf(".\n");
   rval = 0;
   return(rval);
}

/* ------------------------------------------------------------ */
int gif_write(char *fname, float *array)   /* write out an array to gif file */
{
  int ix,iy;
  int rval;
  float uval, umax, umin,scale;
  float *tt;            /* temporary array */

 /* allocate temporary storage array */
 tt = (PTYPE *) malloc((size_t)sizeof(PTYPE)*(xsize)*(ysize));
   if (tt == NULL) {
     fprintf(stderr,"Could not allocate hf buffer memory.\n");
     exit(1);
   }

   umax = El(array,0,0);
   umin = umax;
					/* find max, min */
   for (iy = 0; iy<ysize; iy++) {
    for (ix = 0; ix<xsize; ix++) {
	uval = El(array,ix,iy);
	if (uval > umax) umax = uval;
	if (uval < umin) umin = uval;
    }
    /* printf("\n"); */
   }
  if ((umax-umin) != 0)
    scale = 255.0 / (umax-umin);
  else scale = 0;

  printf("Writing %s ",fname);
  printf("(%dx%d)",xsize,ysize);
  fflush(stdout);

   for (iy = 0; iy<ysize; iy++) {   /* rescale array to 0..255 */
    for (ix = 0; ix<xsize; ix++) {
	El(tt,ix,iy)= (El(array,ix,iy)-umin)*scale;
    }
   }
   gwrite(fname,tt); /* write the .gif file */
   printf(".\n");
   rval = 0;
   free(tt);
   return(rval);
} /* end gifwrite() */


/* ------------------------------------------------------------ */
/* gif_vwrite()  --  write array of vectors to a gif file       */
/*                   use a white->blue colormap for rivers      */
/* ------------------------------------------------------------ */

int gif_vwrite(char *fname, float *array)   /* write array to gif vectors */
{
  int ix,iy;
  int rval;
  float uval, umax, umin,scale;
  float tval;

   umax = (float) sqrt( (double) El(array,0,0) );
   umin = umax;
					/* change scale, take sqrt() */
   for (iy = 0; iy<ysize; iy++) {
    for (ix = 0; ix<xsize; ix++) {
	tval = El(array,ix,iy);
	if (tval < 0.0) tval = 0.0;
	/* printf("%1.1f ",tval); */
	uval = (float) pow((double)tval,0.35);
	El(array,ix,iy) = uval;
	if (uval > umax) umax = uval;
	if (uval < umin) umin = uval;
    }
    /* printf("\n"); */
   }
  if ((umax-umin) != 0)
    scale = 255.0 / (umax-umin);
  else scale = 0;

/*  printf("Writing vector to %s ",fname);
  printf("(%dx%d)",xsize,ysize); 
  fflush(stdout); */

   for (iy = 0; iy<ysize; iy++) {   /* rescale array to 0..255 */
    for (ix = 0; ix<xsize; ix++) {
	El(array,ix,iy)= (El(array,ix,iy)-umin)*scale;
    }
   }
   gvec_write(fname,array); /* write the .gif file */
   printf(".\n");
   rval = 0;
   return(rval);
}



/* ------------------------------------------------------------ */
void hf_print()                /* print out hf array on stdout */
{
  int ix,iy;

   printf("J-printout array: %dx%d\n",xsize,ysize);
   for (iy = 0; iy<(ysize+2); iy++) {
    printf("%d:",iy);
    for (ix = 0; ix<(xsize+2); ix++) {
	printf("%1.1f ",Eh(hf,ix,iy));
    }
     printf("\n");
   }
}

/* ------------------------------------------------------------ */
void fl_print()                /* print out fl array (down) on stdout */
{
  int ix,iy;

   printf("flow array: %dx%d\n",xsize,ysize);
   for (iy = 0; iy<ysize; iy++) {
    printf("%d: ",iy);
    for (ix = 0; ix<xsize; ix++) {
	printf(" %u",El(fl,ix,iy));
    }
     printf("\n");
   }
}

/* ------------------------------------------------------------ */
void flag_print()                /* print out fl array on stdout */
{
  int ix,iy;

   printf("flag array: %dx%d\n",xsize,ysize);
   for (iy = 0; iy<ysize; iy++) {
    printf("%d: ",iy);
    for (ix = 0; ix<xsize; ix++) {
	printf(" %u",El(flag,ix,iy));
    }
     printf("\n");
   }
}

/* ------------------------------------------------------------ */
void ar_print(float*ar)                /* print out fl array on stdout */
{
  int ix,iy;

   printf("array: %dx%d\n",xsize,ysize);
   for (iy = 0; iy<ysize; iy++) {
    printf("%d: ",iy);
    for (ix = 0; ix<xsize; ix++) {
	printf("%0.1f ",El(ar,ix,iy));
    }
     printf("\n");
   }
}


/* ------------------------------------------------------------ */
void fl_p2()                /* print out fl array on stdout */
{
  int ix,iy,lines=0;
  int d;

   printf("flow array: %dx%d\n",xsize,ysize);
   for (iy = 0; iy<ysize; iy++) {
    printf("%d: ",iy);
    for (ix = 0; ix<xsize; ix++) {
      d = El(fl,ix,iy);
      if (d==0) printf("*");
      if ((d==1) || (d==5)) printf("\\");
      if ((d==3) || (d==7)) printf("/");
      if ((d==2) || (d==6)) printf("|");
      if ((d==4) || (d==8)) printf("-");
    }
     printf("\n");
     if (++lines > 20) {  /* no off-screen scrolling pls. */
       lines = 0;
     }
   }
}

/* ------------------------------------------------------------ */
void fl_p3()                /* print out flag array on stdout */
{
  int ix,iy,lines=0;
  int d;

   printf("uphill neighbor array: %dx%d\n",xsize,ysize);
   for (iy = 0; iy<ysize; iy++) {
    printf("%d: ",iy);
    for (ix = 0; ix<xsize; ix++) {
      d = (El(flag,ix,iy) & 0x0f);
      if ((El(flag,ix,iy) & 0x10) == 0x10) printf(".");
      else {
	if (d==0) printf("@");
	if ((d==1) || (d==5)) printf("\\");
	if ((d==3) || (d==7)) printf("/");
	if ((d==2) || (d==6)) printf("|");
	if ((d==4) || (d==8)) printf("-");
      }
    }
     printf("\n");
     if (++lines > 20) {  /* no off-screen scrolling pls. */
       lines = 0;
     }
   }
}


/* -----------------------------------------------------------*/
/* hf_read2 -- read in heightfield data from file <fname> into hf array,  */
/* allocating memory to fit a (xsize+2) x (ysize+2) array. */
/* -----------------------------------------------------------*/

int hf_read2(char *fname)
{
  unsigned int ix, iy;                  /* indexes to hf array */
  size_t hsize;                         /* # bytes memory needed */

  unsigned long npoints;                /* # points that should be in file */
  unsigned long points_read;            /* # points read from hf datafile */
  char sbuf[512],                       /* buffer for file input */
	dummy[2];                       /* used for \n and \0   */
  char *junk;                           /* unconverted part of a number */
  double a, maxval;
  FILE *fpin;                           /* input file pointer */
  int rval;
						/* open input file */
  if ((fpin = fopen(fname,"r")) == NULL)
   { perror("Could not open input file ");
     exit(1);
   }

  printf("Opening files %s\n",fname);

  if (fscanf(fpin,"%s",sbuf) == EOF)
    {   perror("Could not read file"); exit(1); }
  else {
	printf("Initial file string: %s\n",sbuf);   /* better be P2 */
  }

  while ((fscanf(fpin,"%s",sbuf) != EOF) && sbuf[0] == '#') {
	printf("comment:");
	fscanf(fpin,"%[^\n]",sbuf);  /* read comment beyond '#' */
	fscanf(fpin,"%[\n]",dummy);  /* read newline */
	printf("%s\n",sbuf);            /* display comment */
	}

  xsize = (int) strtoul(sbuf, &junk, 10);
  fscanf(fpin,"%s",sbuf);               /* read ysize of array */
  ysize = (int) strtoul(sbuf, &junk, 10);
  fscanf(fpin,"%s",sbuf);               /* read maxval of array */
  maxval = strtod(sbuf, &junk);

  printf("xsize %d  ysize %d  maxval %5.3f\n",xsize,ysize,maxval);
  hsize = (size_t) ( (xsize+2) * (ysize+2) * sizeof(float));
  sprintf(sbuf,"Could not allocate memory for heightfield (%lu bytes)",
	   (long)hsize);
  if ((hf = (float *) malloc( hsize ) ) == NULL)   {
   fprintf(stderr,"%s\n",sbuf);
   exit(1);
  }
  memset(hf,(char) 0, hsize);

  points_read = 0;              /* haven't read any data points yet */
  npoints = (unsigned long int) (xsize * ysize);
  ix = 1;
  iy = 1;                       /* fill array 1..xsize, 1..size */

  while ((fscanf(fpin,"%s",sbuf) != EOF) && (points_read < npoints) ) {
	a = strtod( sbuf, &junk);
	Eh(hf,ix,iy) = (float) a/maxval;       /* store as 0..1 */
	/* printf("%dx%d:%1.2f ",ix,iy,Eh(hf,ix,iy)); */
	if (++ix > xsize) {
	  ix = 1;
	  iy++;
	  /* printf("\n"); */
	}
	++points_read;
  }
  printf("%lu elements read.\n",points_read);
  if (points_read != npoints) {
	printf("Warning: %lu points missing.\n",npoints-points_read);
  }
  rval = fclose( fpin );


  return(rval);
} /* end hf_read2 */

void edge_fill()        /* fill in edges of hf array by duplication */
{
int ix, iy;

  for (ix=1;ix<=xsize;ix++) {
	Eh(hf,ix,0) = Eh(hf,ix,1);              /* fill top edge */
	Eh(hf,ix,ysize+1) = Eh(hf,ix,ysize);    /* bottom edge */
  }

  for (iy = 0;iy<=ysize+1;iy++) {               /* fill in corners too */
	Eh(hf,0,iy) = Eh(hf,1,iy);              /* left edge */
	Eh(hf,xsize+1,iy) = Eh(hf,xsize,iy);    /* right edge */
  }

}


/* -----------------------------------------------------------   */
/* hf_read -- read in pgm data from file <fname> into hf array,  */
/* allocating memory to fit a (xsize+2 x ysize+2) array.         */
/* readin PGM binary or ascii, or if neither, call read_mfile()  */
/* PGM ascii may contain floating-point values, somewhat uncommon */
/* -----------------------------------------------------------   */

int hf_read(char *fname)
{
  unsigned long ix, iy;                  /* indexes to hf array */
  size_t hsize;                         /* # bytes memory needed */
  unsigned long npoints;            /* # points that should be in file */
  unsigned long points_read;        /* # points read from hf datafile */
  char sbuf[512],                       /* buffer for file input */
	dummy[2];                       /* used for \n and \0   */
  char *junk;                           /* unconverted part of a number */
  double a, maxval;
  FILE *fpin;                           /* input file pointer */
  BYTE fbin;                            /* PGM binary format flag */
  BYTE oneb;                            /* one byte from file */
  int rval;
						/* open input file */
  if ((fpin = fopen(fname,"rb")) == NULL)
   { perror("Could not open input file ");
     exit(1);
   }

  printf("Opening files %s\n",fname);

  if (fread(&sbuf,sizeof(char),2,fpin) != 2)
    {   perror("Could not read file"); exit(1); }
  else {
	sbuf[2] = 0x00;
	printf("Initial file string: %s\n",sbuf);   /* better be P2 */
  }
  fbin = 0;                             /* assume PGM ascii */
  if (strcmp(sbuf,"P5") == 0) fbin = 1; /* PGM binary format */
  if ((strcmp(sbuf,"P5") != 0) && (strcmp(sbuf,"P2") != 0)) {
					      /* not PGM Ascii */
	  fclose(fpin);   /* close file to reopen as binary */
	  rval = read_mfile(fname);
  } else {  /* file is PGM, either P5 (binary) or P2 (ascii) */

  while ((fscanf(fpin,"%s",sbuf) != EOF) && sbuf[0] == '#') {
	printf("comment:");
	fscanf(fpin,"%[^\n]",sbuf);  /* read comment beyond '#' */
	fscanf(fpin,"%[\n]",dummy);  /* read newline */
	printf("%s\n",sbuf);            /* display comment */
	}

  xsize = (int) strtoul(sbuf, &junk, 10); /* cvt. xsize of array */
  fscanf(fpin,"%s",sbuf);                 /* read ysize of array */
  ysize = (int) strtoul(sbuf, &junk, 10); /* cvt. ysize */
  fscanf(fpin,"%s",sbuf);               /* read maxval of array */
  maxval = strtod(sbuf, &junk);

  printf("xsize %d  ysize %d  maxval %5.3f\n",xsize,ysize,maxval);
  hsize = (size_t) ( (xsize+2) * (ysize+2) * sizeof(PTYPE));
  if ((hf = (PTYPE *) malloc( hsize ) ) == NULL)   {
   fprintf(stderr,"Could not allocate %lu bytes for heightfield.\n",
		   (long)hsize);
   exit(1);
  }
  memset(hf,(BYTE) 0, hsize);

  points_read = 0;              /* haven't read any data points yet */
  npoints = (unsigned long int) (xsize * ysize);
  ix = 1;
  iy = 1;                       /* fill array 1..xsize, 1..size */

  printf("reading in...\n");
  if (fbin) {
     while ((fread(&oneb,sizeof(BYTE),1,fpin) == 1) && (points_read < npoints) ) {
	Eh(hf,ix,iy) = (PTYPE) oneb;
	if (++ix > xsize) {
	  ix = 1;
	  iy++;
	}
	++points_read;
     } /* end while not end-of-file */
  } /* end if fbin */
  else {
      while ((fscanf(fpin,"%s",sbuf) != EOF) && (points_read < npoints) ) {
	a = strtod( sbuf, &junk);
	Eh(hf,ix,iy) = (float) a/maxval;
	if (++ix > xsize) {
	  ix = 1;
	  ++iy;
	}
	++points_read;
      }
  } /* end else */

  printf("\n");
  printf("%lu elements read.\n",points_read);
  if (points_read != npoints) {
	printf("Warning: %lu points missing.\n",npoints-points_read);
  }
  rval = fclose( fpin );

  printf("Files closed.\n");
  } /* end else */

  edge_fill();          /* fill in edges of hf array */
  return(rval);
} /* end hf_read */


/* -------------------------------------------------------------- */
/* read_mfile --  read in data matrix in Matlab Level 1.0 format  */
/*               and put data in header "x" and data array "hf"   */
/*               which has one empty row along each edge.         */
/* -------------------------------------------------------------- */

int read_mfile(char *fname)
{
  char pname[80]="dat1\x00";           /* data matrix name, null-terminated*/
  int mn;
  Fmatrix hd;                           /* header */

  int a,b,c,i,j;
  int etype;
  int mtype,prec,rem,numtype;
  double tdbl;
  float tflt;
  FILE *fpin;

   /* --------- read in Matlab-format (Level 1.0) file ------- */

   etype = (NUM_FMT*1000) + (PREC*10);    /* expected data type flag */

   if ((fpin = fopen(fname,"rb")) == NULL) {
    perror("could not open file.\n");
    exit(1);
   }

   printf("Opening matlab file %s...\n",fname);

   a = fread(&hd, sizeof(Fmatrix),(size_t)1, fpin);          /* read header */
    if (a != 1) {
      perror("Problem reading matlab file header.\n");
      exit(1);
    }
   numtype = (hd.type % 10000)/1000;
   prec = (hd.type % 100)/10;
   mtype = (hd.type % 10);
   rem = (hd.type - (1000*numtype + 10*prec + mtype));
   printf("Data type flag: M%d P%d T%d R%d\n",
       numtype,prec,mtype,rem);
   if ( (numtype!=NUM_FMT) || ((prec!=0)&&(prec!=1)) || (mtype!=0) )  {
     perror("Unsupported file format type\n");
     exit(1);
   }
   b = fread(pname, sizeof(char), (size_t)hd.namelen, fpin); /* read mx name */
   xsize = hd.ncols;
   ysize = hd.mrows;
   printf("Array name: %s [%dx%d]\n",pname,xsize,ysize);
   mn = (hd.mrows + 2) * (hd.ncols + 2); /* size of expanded array */
   if ((hf = (PTYPE *) malloc(mn*sizeof(PTYPE)) ) == NULL) {
     perror("Could not allocate memory for input array.\n");
     exit(1);
   }
   if (prec==1) {               /* read in floats 1 by 1 */
     for (i=0;i<xsize;i++) {
      for (j=0;j<ysize;j++) {   /* format is columns saved first */
       c = fread(&tflt, sizeof(float), 1, fpin);
       if (c != 1) {
	 perror("Trouble reading data from file.\n");
	 exit(1);
       }
       Ehn(hf,i,j) = (PTYPE) tflt;
      } /* end for j */
     } /* end for i */
   } else if (prec==0) {                     /* read doubles 1 by 1 and convert */

     for (i=0;i<xsize;i++) {
      for (j=0;j<ysize;j++) {   /* format is columns saved first */
       c = fread(&tdbl, sizeof(double), 1, fpin);
       if (c != 1) {
	 perror("Trouble reading data from file.\n");
	 exit(1);
       }
       Ehn(hf,i,j) = (PTYPE) tdbl;
      } /* end for j */
     } /* end for i */

   } else {
	perror("Unsupported floating-point type\n");
	exit(1);
   } /* end else */

   fclose( fpin );

  return(0);

} /* end read_mfile */


/* --------------------------------------------------------------  */
/* write_mfile -- write out data matrix in Matlab Level 1.0 format */
/*               creates data header fhdr from xsize, ysize and    */
/*               writes data array 'hh' of dimension xsize x ysize */
/* --------------------------------------------------------------  */

int write_mfile(char *fname, char *pname, PTYPE *hh, 
   unsigned int xsize, unsigned int ysize)
{
FILE *fpout;
Fmatrix fhdr;
int rv,mn,i,j,c;

   fpout = fopen(fname,"wb");
   if (fpout == NULL)
    { perror("Error opening file.\n");
      exit(1);
    }
   fhdr.type = NUM_FMT*1000 + PREC*10;
   fhdr.ncols = xsize;
   fhdr.mrows = ysize;
   fhdr.imagf = 0;
   fhdr.namelen = strlen(pname) + 1;

   rv = fwrite(&fhdr, sizeof(Fmatrix),(size_t)1, fpout);          /* write header */
   if (rv != 1) {
     perror("Error writing file.\n");
     exit(1);
   }
   rv = fwrite(pname, sizeof(char), (size_t)fhdr.namelen, fpout);   /* write mx name */
   if (rv != fhdr.namelen) {
     perror("Error writing file.\n");
     exit(1);
   }
   mn = fhdr.mrows * fhdr.ncols;

   for (i=0;i<xsize;i++) {
      for (j=0;j<ysize;j++) {   /* format is columns saved first */

       c = fwrite(&El(hh,i,j), sizeof(PTYPE), 1, fpout);
       if (c != 1) {
	 perror("Trouble writing data to file.\n");
	 exit(1);
       }
      } /* end for j */
   } /* end for i */

  if (fclose( fpout ) == EOF) {
	perror("Error closing file.\n");
	exit(1);
  }

  printf("%s written.\n",fname);
  return(0);
} /* end write_mfile */

/* like write_mfile() but writes an array that is 1 larger each way 
   using Ehn() instead of El() */

int write_mfile1(char *fname, char *pname, PTYPE *hh, 
   unsigned int xsize, unsigned int ysize)
{
FILE *fpout;
Fmatrix fhdr;
int rv,mn,i,j,c;

   fpout = fopen(fname,"wb");
   if (fpout == NULL)
    { perror("Error opening file.\n");
      exit(1);
    }
   fhdr.type = NUM_FMT*1000 + PREC*10;
   fhdr.ncols = xsize;
   fhdr.mrows = ysize;
   fhdr.imagf = 0;
   fhdr.namelen = strlen(pname) + 1;

   rv = fwrite(&fhdr, sizeof(Fmatrix),(size_t)1, fpout);          /* write header */
   if (rv != 1) {
     perror("Error writing file.\n");
     exit(1);
   }
   rv = fwrite(pname, sizeof(char), (size_t)fhdr.namelen, fpout);   /* write mx name */
   if (rv != fhdr.namelen) {
     perror("Error writing file.\n");
     exit(1);
   }
   mn = fhdr.mrows * fhdr.ncols;

   for (i=0;i<xsize;i++) {
      for (j=0;j<ysize;j++) {   /* format is columns saved first */

       c = fwrite(&Ehn(hh,i,j), sizeof(PTYPE), 1, fpout);
       if (c != 1) {
	 perror("Trouble writing data to file.\n");
	 exit(1);
       }
      } /* end for j */
   } /* end for i */

  if (fclose( fpout ) == EOF) {
	perror("Error closing file.\n");
	exit(1);
  }

  printf("%s written.\n",fname);
  return(0);
} /* end write_mfile1 */

