 /*
  * Khoros: $Id: big.c,v 1.2 1991/12/18 09:49:17 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: big.c,v 1.2 1991/12/18 09:49:17 dkhoros Exp $";
#endif

 /*
  * $Log: big.c,v $
 * Revision 1.2  1991/12/18  09:49:17  dkhoros
 * HellPatch3
 *
  */ 


/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.

 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *---------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "vinclude.h"	
#include "file_formats/big.h"	


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: big.c                                  <<<<
   >>>>                                                       <<<<
   >>>>   description: utilities to read and write big images  <<<<
   >>>>                                                       <<<<
   >>>>      routines: write_big()			      <<<<
   >>>>			read_big()
   >>>>                                                       <<<<
   >>>> modifications:					      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
/*
#
# SPEICAL NOTE:
#
#	IMPORTANT----------
#	The utilities used to read and write the BIG image file are machine 
#	dependent. WE ASSUME THAT THE BIG IMAGE WILL ALWAYS BE 
#	IN LITENDIAN BYTE FORMAT, since the Terra-Mar Image 
#	processing system runs under DOS on a PC. This means
#	that a machine that uses bigendian byt order (i.e. sun, sony, etc) must
#	byte swap some fields in the image header. So, a #if has been placed
#	in the code to allow conversion between litendian byte order and
#	bigendian byte order. 
#	
*/

/**************************************************************
*
* MODULE NAME:  write_big
*
*     PURPOSE:  writes out a big image file format.
*
*       INPUT:  char *filename - file name
*		struct big *big_image - pointer to big image
*
*      OUTPUT:  
*
* ROUTINES CALLED: None
*
**************************************************************/

write_big(filename, imageptr)
struct big *imageptr;
char *filename;
{
    int imgsize, header_size,file;
    unsigned long type;

    /* Open the output file */
    if ( (file = kopen(filename, O_WRONLY|O_CREAT|O_TRUNC, 644)) < 0)
      {
        fprintf(stderr,"write_big: unable to access output file\n");
        return(0);
      }

       /* calculate the image data size before possibly
        * swapping bytes
       */

    imgsize = imageptr->num_channels * imageptr->num_lines 
              * imageptr->records_line * 512;


	/* if in big endian then swap bytes */

    type = machtype(NULL);
    if (type != VFF_DEP_NSORDER)
    {
       ieeetodecs(&imageptr->num_channels);
       ieeetodecs(&imageptr->start_line_num);
       ieeetodecs(&imageptr->start_pixel_num);
       ieeetodecs(&imageptr->num_lines);
       ieeetodecs(&imageptr->num_pixels_line);
       ieeetodecs(&imageptr->records_line);
    }

    /* Write the image header.
     * Note that the pointer fields in the header must be written out
     * as NULLs in order that an image file on the disk can be
     * compared using diff or cmp! 
     */

    header_size = sizeof(struct big) - sizeof(char *);
    if ((kwrite(file,imageptr,header_size)) != header_size)
    {
      fprintf(stderr,"write_big: Unable to write image header\n");
      kclose(file);
      return(0);
    }


         /* write image data */
    if (kwrite(file,imageptr->imagedata,imgsize) != imgsize)
    {
        fprintf(stderr,"write_big: Unable to write image data\n");
        kclose(file);
        return(0);
    }
    kclose(file);
    return(1);
}


/**************************************************************
*
* MODULE NAME:  read_big()
*
*     PURPOSE:  Reads a big image file format.
*
*       INPUT:  filename - filename of the input image file.
*
*      OUTPUT:  struct big *imageptr - pointer to big image read
*
* ROUTINES CALLED: block_read()
*
**************************************************************/

struct big
*read_big(filename)
char *filename;

{

    char *malloc();
    struct big *imageptr;
    int numread,headersize, imgsize,file; 
    unsigned long type;

    /* Open the output file */
    if ( (file = kopen(filename, O_RDONLY)) < 0)
      {
        fprintf(stderr,"read_big: unable to access output file\n");
        return(0);
      }

/* Grab space for the image structure and read it */

    imageptr = (struct big *)malloc(sizeof(struct big));
    if (imageptr == NULL)
    {
        (void) fprintf(stderr,"\nread_big: Not enough memory ");
        (void) fprintf(stderr,"for image header\n");
        kclose(file);
        return(NULL);
    }

     /* we need the byte order to be litendian since Terra-Mar
      * runs on a dos machine. 
      */

    type = machtype(NULL);
    if (type != VFF_DEP_NSORDER)
    {
       dectoieees(&imageptr->num_channels);
       dectoieees(&imageptr->start_line_num);
       dectoieees(&imageptr->start_pixel_num);
       dectoieees(&imageptr->num_lines);
       dectoieees(&imageptr->num_pixels_line);
       dectoieees(&imageptr->records_line);
    }

     /* only want to read in the first 512 bytes of the header */

    headersize = sizeof(struct big) - sizeof(char *);

    numread = block_read(file, imageptr, headersize);
    if (numread != headersize)
    {
        (void) fprintf(stderr,"\nread_big: Incorrect header byte count: ");
        (void) fprintf(stderr,"found %d, should be %d\n",numread,headersize);
        free(imageptr);
        kclose(file);
        return(NULL);
    }

       /* calculate the iamge size from the header information 
	* All lines are padded to a multiple of 512 bytes 
        */

    imgsize = imageptr->num_channels * imageptr->num_lines 
              * imageptr->records_line * 512;

       /* Get space for image data */

    imageptr->imagedata = (char *)malloc(imgsize);
    if (imageptr->imagedata == NULL)
    {
        (void)fprintf(stderr,"\nread_big: Not enough memory for image data.\n")
;
        freeimage(imageptr);
        kclose(file);
        return(NULL);
    }

         /* read the image */

    if (block_read(file,imageptr->imagedata, imgsize) != imgsize)
    {
       (void) fprintf(stderr,"\nread_big: ");
       (void) fprintf(stderr,"Incorrect byte count reading image data!\n");
       freeimage(imageptr);
       kclose(file);
       return(NULL);
    }

    kclose(file);
    return(imageptr);
}
