 /*
  * Khoros: $Id: rast.c,v 1.2 1991/12/18 09:50:02 dkhoros Exp $
  */

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

 /*
  * $Log: rast.c,v $
 * Revision 1.2  1991/12/18  09:50:02  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/rast.h"


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: rast.c  
   >>>>                
   >>>>   description: Sun raster image utilities
   >>>>              
   >>>>      routines: read_rast()
   >>>>			write_rast()
   >>>>              
   >>>> modifications: Modified to use filenames instead of 
   >>>> 		file descriptors Scott Wilson
   >>>>							      <<<<
   >>>>		       write_rast not writing out all map and <<<<
   >>>>		        image data. - Mark Young	      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


/**************************************************************
*
* MODULE NAME:  write_rast
*
*     PURPOSE:  writes out a Sun Raster image file format.
*
*       INPUT:  char *filename - filename of file to be read 
*		struct rast *rast_image - pointer to Raster image
*
*      OUTPUT: 
*
* ROUTINES CALLED: None
*
**************************************************************/

write_rast(filename, imageptr)
struct rast *imageptr;
char *filename;
{
 int imgsize, header_size;
 char *program = "write_rast";
 unsigned long type;
 int file;

 /* 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 rast) - sizeof(char *);
 imgsize = imageptr->ras_length + imageptr->ras_maplength;

 type = machtype(NULL);
 if (type != VFF_DEP_IEEEORDER)
    { dectoieeel(&imageptr->ras_magic);
      dectoieeel(&imageptr->ras_width);
      dectoieeel(&imageptr->ras_height);
      dectoieeel(&imageptr->ras_depth);
      dectoieeel(&imageptr->ras_length);
      dectoieeel(&imageptr->ras_type);
      dectoieeel(&imageptr->ras_maptype);
      dectoieeel(&imageptr->ras_maplength);
    }

 /* Open the output file */
 if ( (file = kopen(filename, O_WRONLY|O_TRUNC|O_CREAT,0664)) < 0)
     {
       fprintf(stderr,
               "write_rast: Unable to access output image %s\n",filename);
       return(NULL);
     }

 if ((kwrite(file,imageptr,header_size)) != header_size)
    { fprintf(stderr,"%s: Unable to write image header.\n",program);
      kclose(file);
      return(0);
    }

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


/**************************************************************
*
* MODULE NAME:  read_rast()
*
*     PURPOSE:  Reads a Sun Raster image file.
*
*       INPUT:  char *filename - name of file to be read
*
*      OUTPUT:  struct rast *imageptr - pointer to the raster image read
*
* ROUTINES CALLED: block_read()
*
**************************************************************/

struct rast *read_rast(filename)
char *filename;
{
 int numread, headersize, imgsize; 
 char *malloc();
 char *program = "read_rast";
 unsigned long type;
 struct rast *imageptr;
 int file, width, height, num_bytes;

    /* Allocate space for the image structure and read in the image */

    imageptr = (struct rast *)malloc(sizeof(struct rast));
    if (imageptr == NULL)
    { 
       (void) fprintf(stderr,
              "%s: Not enough memory available to read in image.\n",program);
      return(NULL);
    }

    /* Open the input file */
    if ( (file = kopen(filename, O_RDONLY)) < 0)
      {
        fprintf(stderr,
                "read_rast: Unable to access input image %s\n",filename);
        return(NULL);
      }

    headersize = sizeof(struct rast)-sizeof(char *);
    numread = block_read(file,imageptr,headersize);
    if (numread != headersize)
    { 
       (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
       (void) fprintf(stderr,
               "found %d, bytes, should be %d bytes\n",numread,headersize); 
       free(imageptr);
       kclose(file);
       return(NULL);
    }

    type = machtype(NULL);
    if (type != VFF_DEP_IEEEORDER)
    { 
      ieeetodecl(&imageptr->ras_magic);
      ieeetodecl(&imageptr->ras_width);
      ieeetodecl(&imageptr->ras_height);
      ieeetodecl(&imageptr->ras_depth);
      ieeetodecl(&imageptr->ras_length);
      ieeetodecl(&imageptr->ras_type);
      ieeetodecl(&imageptr->ras_maptype);
      ieeetodecl(&imageptr->ras_maplength);
    }
 

    if (imageptr->ras_length == 0 && imageptr->ras_type == RT_OLD)
    {
       width  = imageptr->ras_width;
       height = imageptr->ras_height;
       if (imageptr->ras_depth == 1)
       {
	  num_bytes = (width + 7)/8;
	  imageptr->ras_length = (num_bytes + num_bytes % 2) * height;
       }
       else if (imageptr->ras_depth == 8)
	  imageptr->ras_length = (width + width % 2) * height;
       else
	  imageptr->ras_length = (width * 3 + (width*3) % 2) * height;
    }

      /* get the image size from the header information */
    imgsize = imageptr->ras_length + imageptr->ras_maplength;

       /* Allocate space for image data */
    imageptr->data = (char *)malloc(imgsize);
    if (imageptr->data == NULL)
    { 
       (void)fprintf(stderr,
               "%s: Not enough memory available to read in image.\n",program);
       freeimage(imageptr);
       kclose(file);
       return(NULL);
    }

           /* read the image */
  if (block_read(file,imageptr->data, imgsize) != imgsize)
    { 
      (void) fprintf(stderr,
               "%s: Incorrect byte count reading image data.\n",program);
      freeimage(imageptr);
      kclose(file);
      return(NULL);
    }
  kclose(file);
  return(imageptr);
}
