/*
 * jrdtarga.c
 *
 * Copyright (C) 1991, Thomas G. Lane.
 * This file is part of the Independent JPEG Group's software.
 * For conditions of distribution and use, see the accompanying README file.
 *
 * This file contains routines to read input images in Targa format.
 *
 * These routines may need modification for non-Unix environments or
 * specialized applications.  As they stand, they assume input from
 * an ordinary stdio stream.  They further assume that reading begins
 * at the start of the file; input_init may need work if the
 * user interface has already read some data (e.g., to determine that
 * the file is indeed Targa format).
 *
 * These routines are invoked via the methods get_input_row
 * and input_init/term.
 *
 * Based on code contributed by Lee Daniel Crocker.
 */

#include "jinclude.h"

#ifdef TARGA_SUPPORTED


/* Macros to deal with unsigned chars as efficiently as compiler allows */

#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char U_CHAR;
#define UCH(x)	((int) (x))
#else /* !HAVE_UNSIGNED_CHAR */
#ifdef CHAR_IS_UNSIGNED
typedef char U_CHAR;
#define UCH(x)	((int) (x))
#else
typedef char U_CHAR;
#define UCH(x)	((int) (x) & 0xFF)
#endif
#endif /* HAVE_UNSIGNED_CHAR */


#define	ReadOK(file,buffer,len)	(FREAD(file,buffer,len) == ((size_t) (len)))


static JSAMPARRAY colormap;	/* Targa colormap (converted to my format) */

static big_sarray_ptr whole_image; /* Needed if funny input row order */
static long current_row;	/* Current logical row number to read */

/* Pointer to routine to extract next Targa pixel from input file */
static void (*read_pixel) PP((compress_info_ptr cinfo));

/* Result of read_pixel is delivered here: */
static U_CHAR tga_pixel[4];

static int pixel_size;		/* Bytes per Targa pixel (1 to 4) */

/* State info for reading RLE-coded pixels; both counts must be init to 0 */
static int block_count;		/* # of pixels remaining in RLE block */
static int dup_pixel_count;	/* # of times to duplicate previous pixel */

/* This saves the correct pixel-row-expansion method for preload_image */
static void (*get_pixel_row) PP((compress_info_ptr cinfo,
				 JSAMPARRAY pixel_row));


/* For expanding 5-bit pixel values to 8-bit with best rounding */

static const UINT8 c5to8bits[32] = {
    0,   8,  16,  24,  32,  41,  49,  57,
   65,  74,  82,  90,  98, 106, 115, 123,
  131, 139, 148, 156, 164, 172, 180, 189,
  197, 205, 213, 222, 230, 238, 246, 255
};



LOCAL int
read_byte (compress_info_ptr cinfo)
/* Read next byte from Targa file */
{
  register FILE *infile = cinfo->input_file;
  register int c;

  if ((c = getc(infile)) == EOF)
    ERREXIT(cinfo->emethods, "Premature EOF in Targa file");
  return c;
}


LOCAL void
read_colormap (compress_info_ptr cinfo, int cmaplen, int mapentrysize)
/* Read the colormap from a Targa file */
{
  int i;

  /* Presently only handles 24-bit BGR format */
  if (mapentrysize != 24)
    ERREXIT(cinfo->emethods, "Unsupported Targa colormap format");

  for (i = 0; i < cmaplen; i++) {
    colormap[2][i] = (JSAMPLE) read_byte(cinfo);
    colormap[1][i] = (JSAMPLE) read_byte(cinfo);
    colormap[0][i] = (JSAMPLE) read_byte(cinfo);
  }
}


/*
 * read_pixel methods: get a single pixel from Targa file into tga_pixel[]
 */

LOCAL void
read_non_rle_pixel (compress_info_ptr cinfo)
/* Read one Targa pixel from the input file; no RLE expansion */
{
  register FILE * infile = cinfo->input_file;
  register int i;

  for (i = 0; i < pixel_size; i++) {
    tga_pixel[i] = (U_CHAR) getc(infile);
  }
}


LOCAL void
read_rle_pixel (compress_info_ptr cinfo)
/* Read one Targa pixel from the input file, expanding RLE data as needed */
{
  register FILE * infile = cinfo->input_file;
  register int i;

  /* Duplicate previously read pixel? */
  if (dup_pixel_count > 0) {
    dup_pixel_count--;
    return;
  }

  /* Time to read RLE block header? */
  if (--block_count < 0) {	/* decrement pixels remaining in block */
    i = read_byte(cinfo);
    if (i & 0x80) {		/* Start of duplicate-pixel block? */
      dup_pixel_count = i & 0x7F; /* number of duplications after this one */
      block_count = 0;		/* then read new block header */
    } else {
      block_count = i & 0x7F;	/* number of pixels after this one */
    }
  }

  /* Read next pixel */
  for (i = 0; i < pixel_size; i++) {
    tga_pixel[i] = (U_CHAR) getc(infile);
  }
}


/*
 * Read one row of pixels.
 *
 * We provide several different versions depending on input file format.
 */


METHODDEF void
get_8bit_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading 8-bit grayscale pixels */
{
  register JSAMPROW ptr0;
  register long col;
  
  ptr0 = pixel_row[0];
  for (col = cinfo->image_width; col > 0; col--) {
    (*read_pixel) (cinfo);	/* Load next pixel into tga_pixel */
    *ptr0++ = (JSAMPLE) UCH(tga_pixel[0]);
  }
}

METHODDEF void
get_8bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading 8-bit colormap indexes */
{
  register int t;
  register JSAMPROW ptr0, ptr1, ptr2;
  register long col;
  
  ptr0 = pixel_row[0];
  ptr1 = pixel_row[1];
  ptr2 = pixel_row[2];
  for (col = cinfo->image_width; col > 0; col--) {
    (*read_pixel) (cinfo);	/* Load next pixel into tga_pixel */
    t = UCH(tga_pixel[0]);
    *ptr0++ = colormap[0][t];
    *ptr1++ = colormap[1][t];
    *ptr2++ = colormap[2][t];
  }
}

METHODDEF void
get_16bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading 16-bit pixels */
{
  register int t;
  register JSAMPROW ptr0, ptr1, ptr2;
  register long col;
  
  ptr0 = pixel_row[0];
  ptr1 = pixel_row[1];
  ptr2 = pixel_row[2];
  for (col = cinfo->image_width; col > 0; col--) {
    (*read_pixel) (cinfo);	/* Load next pixel into tga_pixel */
    t = UCH(tga_pixel[0]);
    t += UCH(tga_pixel[1]) << 8;
    /* We expand 5 bit data to 8 bit sample width.
     * The format of the 16-bit (LSB first) input word is
     *     xRRRRRGGGGGBBBBB
     */
    *ptr2++ = (JSAMPLE) c5to8bits[t & 0x1F];
    t >>= 5;
    *ptr1++ = (JSAMPLE) c5to8bits[t & 0x1F];
    t >>= 5;
    *ptr0++ = (JSAMPLE) c5to8bits[t & 0x1F];
  }
}

METHODDEF void
get_24bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading 24-bit pixels */
{
  register JSAMPROW ptr0, ptr1, ptr2;
  register long col;
  
  ptr0 = pixel_row[0];
  ptr1 = pixel_row[1];
  ptr2 = pixel_row[2];
  for (col = cinfo->image_width; col > 0; col--) {
    (*read_pixel) (cinfo);	/* Load next pixel into tga_pixel */
    *ptr0++ = (JSAMPLE) UCH(tga_pixel[2]); /* convert BGR to RGB order */
    *ptr1++ = (JSAMPLE) UCH(tga_pixel[1]);
    *ptr2++ = (JSAMPLE) UCH(tga_pixel[0]);
  }
}

METHODDEF void
get_32bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading 32-bit pixels */
/* Attribute bits are ignored for now */
{
  register JSAMPROW ptr0, ptr1, ptr2;
  register long col;

/* NOTE: there seems to be considerable confusion over whether the order
 * of the bytes in a 32-bit Targa file is A,B,G,R or B,G,R,A.
 * On Lee Crocker's authority, we think the attribute byte comes first.
 * Make ATTR_BYTE_FIRST be 0 if you have files in which it comes last.
 */
#ifndef ATTR_BYTE_FIRST    /* so you can say -DATTR_BYTE_FIRST=0 in Makefile */
#define ATTR_BYTE_FIRST  1	/* must be 0 or 1 */
#endif
  
  ptr0 = pixel_row[0];
  ptr1 = pixel_row[1];
  ptr2 = pixel_row[2];
  for (col = cinfo->image_width; col > 0; col--) {
    (*read_pixel) (cinfo);	/* Load next pixel into tga_pixel */
    /* convert ABGR (or BGRA) to RGB order */
    *ptr0++ = (JSAMPLE) UCH(tga_pixel[2+ATTR_BYTE_FIRST]);
    *ptr1++ = (JSAMPLE) UCH(tga_pixel[1+ATTR_BYTE_FIRST]);
    *ptr2++ = (JSAMPLE) UCH(tga_pixel[0+ATTR_BYTE_FIRST]);
  }
}


/*
 * This method is for re-reading the input data in standard top-down
 * row order.  The entire image has already been read into whole_image
 * with proper conversion of pixel format, but it's in a funny row order.
 */

METHODDEF void
get_memory_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
{
  JSAMPARRAY image_ptr;
  long source_row;

  /* Compute row of source that maps to current_row of normal order */
  /* For now, assume image is bottom-up and not interlaced. */
  /* NEEDS WORK to support interlaced images! */
  source_row = cinfo->image_height - current_row - 1;

  /* Fetch that row from virtual array */
  image_ptr = (*cinfo->emethods->access_big_sarray)
		(whole_image, source_row * cinfo->input_components, FALSE);

  jcopy_sample_rows(image_ptr, 0, pixel_row, 0,
		    cinfo->input_components, cinfo->image_width);

  current_row++;
}


/*
 * This method loads the image into whole_image during the first call on
 * get_input_row.  The get_input_row pointer is then adjusted to call
 * get_memory_row on subsequent calls.
 */

METHODDEF void
preload_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
{
  JSAMPARRAY image_ptr;
  long row;

  /* Read the data into a virtual array in input-file row order */
  for (row = 0; row < cinfo->image_height; row++) {
    image_ptr = (*cinfo->emethods->access_big_sarray)
			(whole_image, row * cinfo->input_components, TRUE);
    (*get_pixel_row) (cinfo, image_ptr);
  }
  /* Set up to read from the virtual array in unscrambled order */
  cinfo->methods->get_input_row = get_memory_row;
  current_row = 0;
  /* And read the first row */
  get_memory_row(cinfo, pixel_row);
}


/*
 * Read the file header; return image size and component count.
 */

METHODDEF void
input_init (compress_info_ptr cinfo)
{
  U_CHAR targaheader[18];
  int idlen, cmaptype, subtype, flags, interlace_type, components;
  UINT16 width, height, maplen;
  boolean is_bottom_up;

#define GET_2B(offset)	((unsigned int) UCH(targaheader[offset]) + \
			 (((unsigned int) UCH(targaheader[offset+1])) << 8))
  
  if (! ReadOK(cinfo->input_file, targaheader, 18))
    ERREXIT(cinfo->emethods, "Unexpected end of file");

  /* Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway */
  if (targaheader[16] == 15)
    targaheader[16] = 16;

  idlen = UCH(targaheader[0]);
  cmaptype = UCH(targaheader[1]);
  subtype = UCH(targaheader[2]);
  maplen = GET_2B(5);
  width = GET_2B(12);
  height = GET_2B(14);
  pixel_size = UCH(targaheader[16]) >> 3;
  flags = UCH(targaheader[17]);	/* Image Descriptor byte */

  is_bottom_up = ((flags & 0x20) == 0);	/* bit 5 set => top-down */
  interlace_type = flags >> 6;	/* bits 6/7 are interlace code */

  if (cmaptype > 1 ||		/* cmaptype must be 0 or 1 */
      pixel_size < 1 || pixel_size > 4 ||
      (UCH(targaheader[16]) & 7) != 0 || /* bits/pixel must be multiple of 8 */
      interlace_type != 0)	/* currently don't allow interlaced image */
    ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
  
  if (subtype > 8) {
    /* It's an RLE-coded file */
    read_pixel = read_rle_pixel;
    block_count = dup_pixel_count = 0;
    subtype -= 8;
  } else {
    /* Non-RLE file */
    read_pixel = read_non_rle_pixel;
  }

  /* Now should have subtype 1, 2, or 3 */
  components = 3;		/* until proven different */
  cinfo->in_color_space = CS_RGB;

  switch (subtype) {
  case 1:			/* colormapped image */
    if (pixel_size == 1 && cmaptype == 1)
      get_pixel_row = get_8bit_row;
    else
      ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
    break;
  case 2:			/* RGB image */
    switch (pixel_size) {
    case 2:
      get_pixel_row = get_16bit_row;
      break;
    case 3:
      get_pixel_row = get_24bit_row;
      break;
    case 4:
      get_pixel_row = get_32bit_row;
      break;
    default:
      ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
      break;
    }
    break;
  case 3:			/* Grayscale image */
    components = 1;
    cinfo->in_color_space = CS_GRAYSCALE;
    if (pixel_size == 1)
      get_pixel_row = get_8bit_gray_row;
    else
      ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
    break;
  default:
    ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
    break;
  }

  if (is_bottom_up) {
    whole_image = (*cinfo->emethods->request_big_sarray)
			((long) width, (long) height * components,
			 (long) components);
    cinfo->methods->get_input_row = preload_image;
  } else {
    whole_image = NULL;
    cinfo->methods->get_input_row = get_pixel_row;
  }
  
  while (idlen--)		/* Throw away ID field */
    (void) read_byte(cinfo);

  if (maplen > 0) {
    if (maplen > 256 || GET_2B(3) != 0)
      ERREXIT(cinfo->emethods, "Colormap too large");
    /* Allocate space to store the colormap */
    colormap = (*cinfo->emethods->alloc_small_sarray)
			((long) maplen, 3L);
    /* and read it from the file */
    read_colormap(cinfo, (int) maplen, UCH(targaheader[7]));
  } else {
    if (cmaptype)		/* but you promised a cmap! */
      ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
    colormap = NULL;
  }

  cinfo->input_components = components;
  cinfo->image_width = width;
  cinfo->image_height = height;
  cinfo->data_precision = 8;	/* always, even if 12-bit JSAMPLEs */
}


/*
 * Finish up at the end of the file.
 */

METHODDEF void
input_term (compress_info_ptr cinfo)
{
  if (whole_image != NULL)
    (*cinfo->emethods->free_big_sarray) (whole_image);
  if (colormap != NULL)
    (*cinfo->emethods->free_small_sarray) (colormap, 3L);
}


/*
 * The method selection routine for Targa format input.
 * Note that this must be called by the user interface before calling
 * jpeg_compress.  If multiple input formats are supported, the
 * user interface is responsible for discovering the file format and
 * calling the appropriate method selection routine.
 */

GLOBAL void
jselrtarga (compress_info_ptr cinfo)
{
  cinfo->methods->input_init = input_init;
  /* cinfo->methods->get_input_row is set by input_init */
  cinfo->methods->input_term = input_term;
}

#endif /* TARGA_SUPPORTED */
