 /*
  * Khoros: $Id: tga.c,v 1.3 1991/12/18 09:50:22 dkhoros Exp $
  */

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

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


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name:  tga.c                                 <<<<
   >>>>                                                       <<<<
   >>>>   description:  utilities for tga2viff and viff2tga   <<<<
   >>>>                                                       <<<<
   >>>>      routines: write_rast() 			      <<<<
   >>>>                                                       <<<<
   >>>> modifications:					      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */

/*

/**************************************************************
*
* MODULE NAME:  write_tga
*
*     PURPOSE:  writes out a T.G.A image file format.
*
*       INPUT:  int file - file descriptor to an open file
*		struct tga *tga_image - pointer to Truevision image
*
*      OUTPUT:  
*
* ROUTINES CALLED: None
*
**************************************************************/
/*
 *  This code "write_tga" is commented out and must be rewritten.
 *  It can be used as a frame work only. This code was never 
 *  completed.
 *    Tom S. 11/14/91
 *

int write_tga(file, image)
tga *image;
int file;
{
char *program = "write_tga";
unsigned int size_iden, size_col_map, size_image;
short val;
unsigned char trash[128];
int ii, machine, machtype();


 machine = machtype(NULL);

 for (ii = 0; ii< 128; ii++) trash[ii] = 0; 
 if (write(file,trash,128) != 128) 
    { fprintf(stderr,
      "%s: Unable to write number of characters in quickdraw header\n",
      program);
      return(FALSE);
    }

 if (write(file,
           & (image -> tgaheader.num_char_iden),
           sizeof(tga_header)) != sizeof(unsigned char))
    { fprintf(stderr,
      "%s: Unable to write number of characters in TGA HEADER.\n",
      program);
      return(FALSE);
    }

 if (write(file,
           & (image->tgaheader.col_map_typ),
           sizeof(tga_header)) != sizeof(unsigned char))
    { fprintf(stderr,
      "%s: Unable to write color map type in TGA HEADER.\n",
      program);
      return(FALSE);
    }
 if (write(file,
           & (image->tgaheader.ima_typ_code),
           sizeof(tga_header)) != sizeof(unsigned char))
    { fprintf(stderr,
      "%s: Unable to write image type in TGA HEADER.\n",
      program);
      return(FALSE);
    }
 

 if (machine == VFF_DEP_IEEEORDER)
      ieeetonss(&image -> tgaheader.col_map_orig);
 if (write(file,
           &val ,
           sizeof(tga_header)) != sizeof(short))
    { fprintf(stderr,
      "%s: Unable to write color map origin in TGA HEADER.\n",
      program);
      return(FALSE);
    }

 if (machine == VFF_DEP_IEEEORDER)
      ieeetonss(&image -> tgaheader.col_map_len);
 if (write(file,
           &val,
           sizeof(tga_header)) != sizeof(short))
    { fprintf(stderr,
      "%s: Unable to write color map length in TGA HEADER.\n",
      program);
      return(FALSE);
    }


 if (write(file,
           & (image->tgaheader.col_map_entry_size),
           sizeof(tga_header)) != sizeof(unsigned char))
    { fprintf(stderr,
      "%s: Unable to write color map entry size  in TGA HEADER.\n",
      program);
      return(FALSE);
    }

 if (machine == VFF_DEP_IEEEORDER)
      ieeetonss(&image -> tgaheader.X);
 if (write(file,
           &val,
           sizeof(tga_header)) != sizeof(short))
    { fprintf(stderr,
      "%s: Unable to write image X-Origin in TGA HEADER.\n",
      program);
      return(FALSE);
    }

 if (machine == VFF_DEP_IEEEORDER)
      ieeetonss(&image -> tgaheader.Y);
 if (write(file,
           &val,
           sizeof(tga_header)) != sizeof(short))
    { fprintf(stderr,
      "%s: Unable to write image Y-Origin in TGA HEADER.\n",
      program);
      return(FALSE);
    }

 if (machine == VFF_DEP_IEEEORDER)
      ieeetonss(&image -> tgaheader.width);
 if (write(file,
           &val,
           sizeof(tga_header)) != sizeof(short))
    { fprintf(stderr,
      "%s: Unable to write image width in TGA HEADER.\n",
      program);
      return(FALSE);
    }

 if (machine == VFF_DEP_IEEEORDER)
      ieeetonss(&image -> tgaheader.height);
 if (write(file,
           &val,
           sizeof(tga_header)) != sizeof(short))
    { fprintf(stderr,
      "%s: Unable to write image height in TGA HEADER.\n",
      program);
      return(FALSE);
    }

 if (write(file,
           & (image->tgaheader.pix_size),
           sizeof(tga_header)) != sizeof(unsigned char))
    { fprintf(stderr,
      "%s: Unable to write pixel size in TGA HEADER.\n",
      program);
      return(FALSE);
    }
 if (write(file,
           & (image->tgaheader.ima_descript),
           sizeof(tga_header)) != sizeof(unsigned char))
    { fprintf(stderr,
      "%s: Unable to write image description in TGA HEADER.\n",
      program);
      return(FALSE);
    }


 size_iden = image -> tgaheader.num_char_iden;
 if (write(file,
            image -> imageidentifier,
            size_iden) != size_iden)
    { fprintf(stderr,
      "%s: Unable to write image identification field.\n",
      program);
      return(FALSE);
    }

 size_col_map = image -> tgaheader . col_map_len *
                image -> tgaheader . col_map_entry_size;
 if (write(file,
            image -> colormapdata,   
            size_col_map) != size_col_map) 
    { fprintf(stderr,
      "%s: Unable to write color map data.\n",
      program);
      return(FALSE);
    }

 size_image = image -> tgaheader . width *
              image -> tgaheader . height *
              (image -> tgaheader . pix_size / 8);
 if (write(file,
            image -> imagedata,
            size_image) != size_image)
    { fprintf(stderr,
      "%s: Unable to write image data.\n",
      program);
      return(FALSE);
    }


 return(TRUE);
}
*  end of "write_tga()" commented out code
*/

/**************************************************************
*
* MODULE NAME:  read_tga()
*
*     PURPOSE:  Reads a T. G. A.  image file.
*
*       INPUT:  file - fid of the input image file.
*		extraskip - number of bytes to skip at beginnning of the
*			    file;  ie, there may be an extra header at the
*			    top of the tga file.
*
*      OUTPUT:  struct tga *image - pointer to the raster image block_read
*
* ROUTINES CALLED: blockj_read()
*
**************************************************************/

tga *read_tga(file,extraskip)
int file,extraskip;
{
 unsigned char trash[512];
 unsigned int num_read; 
 unsigned int size_iden, size_col_map, size_image;

 char *malloc();
 char *program = "read_tga";
 unsigned long type;
 tga *image;
 int machine, machtype();

 machine = machtype(NULL);

 /* Allocate space for the image structure and read in the image */
 image = (tga *) malloc (sizeof(tga));
 if (image == NULL)
    { (void) fprintf(stderr,
      "%s: Not enough memory available to block_read in image.\n",program);
      return(NULL);
    }

 /* read trash from mac under quickdraw               */
 if (extraskip > 512) {
    (void) fprintf(stderr,
    "%s: The maximum number of skipped bytes should be 512\n",
    program);
    return(NULL);
    }

 (void) block_read(file, trash, extraskip);


 /* read     H E A D E R                              */
 num_read = block_read(file,
                       &(image -> tgaheader.num_char_iden),
                       sizeof(unsigned char));
 if (num_read != sizeof(unsigned char))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(unsigned char)); 
      free(image);
      return(NULL);
    }

 num_read = block_read(file,
                       &(image -> tgaheader.col_map_typ),
                       sizeof(unsigned char));
 if (num_read != sizeof(unsigned char))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(unsigned char));
      free(image);
      return(NULL);
    }

 num_read = block_read(file,
                       &(image -> tgaheader.ima_typ_code),
                       sizeof(unsigned char));
 if (num_read != sizeof(unsigned char))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(unsigned char));
      free(image);
      return(NULL);
    }

 num_read = block_read(file,
                       &(image -> tgaheader.col_map_orig),
                       sizeof(short));

 if (machine == VFF_DEP_IEEEORDER)
      nstoieees(&image -> tgaheader.col_map_orig);

 if (num_read != sizeof(short))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(short));
      free(image);
      return(NULL);
    }

 num_read = block_read(file,
                       &(image -> tgaheader.col_map_len),
                       sizeof(short));
 if (machine == VFF_DEP_IEEEORDER)
      nstoieees(&image -> tgaheader.col_map_len);
 if (num_read != sizeof(short))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(short));
      free(image);
      return(NULL);
    }
 
 num_read = block_read(file,
                       &(image -> tgaheader.col_map_entry_size),
                       sizeof(unsigned char));
 if (num_read != sizeof(unsigned char))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(unsigned char));
      free(image);
      return(NULL);
    }

 num_read = block_read(file,
                       &(image -> tgaheader.X),
                       sizeof(short));
 if (machine == VFF_DEP_IEEEORDER)
      nstoieees(&image -> tgaheader.X);
 if (num_read != sizeof(short))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(short));
      free(image);
      return(NULL);
    }

 num_read = block_read(file,
                       &(image -> tgaheader.Y),
                       sizeof(short));
 if (machine == VFF_DEP_IEEEORDER)
      nstoieees(&image -> tgaheader.Y);
 if (num_read != sizeof(short))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(short));
      free(image);
      return(NULL);
    }

 num_read = block_read(file,
                       &(image -> tgaheader.width),
                       sizeof(short));
 if (machine == VFF_DEP_IEEEORDER)
      nstoieees(&image -> tgaheader.width);
 if (num_read != sizeof(short))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(short));
      free(image);
      return(NULL);
    }

 num_read = block_read(file,
                       &(image -> tgaheader.height),
                       sizeof(short));
 if (machine == VFF_DEP_IEEEORDER)
      nstoieees(&image -> tgaheader.height);
 if (num_read != sizeof(short))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(short));
      free(image);
      return(NULL);
    }

 num_read = block_read(file,
                       &(image -> tgaheader.pix_size),
                       sizeof(unsigned char));
 if (num_read != sizeof(unsigned char))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(unsigned char));
      free(image);
      return(NULL);
    }

 num_read = block_read(file,
                       &(image -> tgaheader.ima_descript),
                       sizeof(unsigned char));
 if (num_read != sizeof(unsigned char))
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,sizeof(unsigned char));
      free(image);
      return(NULL);
    }



 /* read Image identification field ..................*/
 size_iden = (unsigned int)(image->tgaheader.num_char_iden);
 image -> imageidentifier =  malloc(size_iden);
 if (image -> imageidentifier == NULL)
    { (void)fprintf(stderr,
      "%s: Not enough memory available to read in image.\n"
      ,program);
      freeimage(image);
      return(NULL);
    }

 num_read = block_read(file,image -> imageidentifier,
                       size_iden);
 if (num_read != image -> tgaheader.num_char_iden)
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,(int)image -> tgaheader.num_char_iden);
      free(image);
      return(NULL);
    }


 /* read color map data ..............................*/
 size_col_map = (unsigned int) 
                (image -> tgaheader.col_map_len *
                 image -> tgaheader.col_map_entry_size/8);
                 /* Allocate space for color map data */
 image -> colormapdata = (unsigned char *)malloc(size_col_map);
 if (image -> colormapdata == NULL)
    { (void)fprintf(stderr,
      "%s: Not enough memory available to read in image.\n"
      ,program);
      freeimage(image);
      return(NULL);
    }
 num_read = block_read(file,image -> colormapdata,size_col_map);
 if (num_read != size_col_map)
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
             "found %d, bytes, should be %d bytes\n",
             num_read,size_col_map);
      free(image);
      return(NULL);
    }

 /* read Image data...................................*/
 size_image = image -> tgaheader . width *
              image -> tgaheader . height *
              (image -> tgaheader . pix_size / 8);
                     /* Allocate space for image data */
 image -> imagedata = (unsigned char *)malloc(size_image);
 if (image -> imagedata == NULL)
    { (void)fprintf(stderr,
      "%s: Not enough memory available to read in image.\n"
      ,program);
      freeimage(image);
      return(NULL);
    }
 num_read = block_read(file,image -> imagedata,(int)size_image);
 if (num_read != size_image) 
    { (void) fprintf(stderr,"%s: Incorrect header byte count: ",program);
      (void) fprintf(stderr,
           "found %d, bytes, should be %d bytes\n",
           num_read,size_image);
      free(image);
      return(NULL);
    }


  return(image);
}
