/*
 * jrdrle.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 Utah RLE format.
 * The Utah Raster Toolkit library is required (version 3.0).
 *
 * 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 RLE format).
 *
 * These routines are invoked via the methods get_input_row
 * and input_init/term.
 *
 * Based on code contributed by Mike Lijewski.
 */

#include "jinclude.h"

#ifdef RLE_SUPPORTED

/* rle.h is provided by the Utah Raster Toolkit. */

#include <rle.h>


/*
 * load_image assumes that JSAMPLE has the same representation as rle_pixel,
 * to wit, "unsigned char".  Hence we can't cope with 12- or 16-bit samples.
 */

#ifndef EIGHT_BIT_SAMPLES
  Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
#endif


/*
 * We support the following types of RLE files:
 *   
 *   GRAYSCALE   - 8 bits, no colormap
 *   PSEUDOCOLOR - 8 bits, colormap
 *   TRUECOLOR   - 24 bits, colormap
 *   DIRECTCOLOR - 24 bits, no colormap
 *
 * For now, we ignore any alpha channel in the image.
 */

typedef enum { GRAYSCALE, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind;

static rle_kind visual;		/* actual type of input file */

/*
 * Since RLE stores scanlines bottom-to-top, we have to invert the image
 * to conform to JPEG's top-to-bottom order.  To do this, we read the
 * incoming image into a virtual array on the first get_input_row call,
 * then fetch the required row from the virtual array on subsequent calls.
 */

static big_sarray_ptr image;	/* single array for GRAYSCALE/PSEUDOCOLOR */
static big_sarray_ptr red_channel; /* three arrays for TRUECOLOR/DIRECTCOLOR */
static big_sarray_ptr green_channel;
static big_sarray_ptr blue_channel;
static long cur_row_number;	/* last row# read from virtual array */

static rle_hdr header;		/* Input file information */
static rle_map *colormap;	/* RLE colormap, if any */


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

METHODDEF void
input_init (compress_info_ptr cinfo)
{
  long width, height;

  /* Use RLE library routine to get the header info */
  header.rle_file = cinfo->input_file;
  switch (rle_get_setup(&header)) {
  case RLE_SUCCESS:
    /* A-OK */
    break;
  case RLE_NOT_RLE:
    ERREXIT(cinfo->emethods, "Not an RLE file");
    break;
  case RLE_NO_SPACE:
    ERREXIT(cinfo->emethods, "Insufficient memory for RLE header");
    break;
  case RLE_EMPTY:
    ERREXIT(cinfo->emethods, "Empty RLE file");
    break;
  case RLE_EOF:
    ERREXIT(cinfo->emethods, "Premature EOF in RLE header");
    break;
  default:
    ERREXIT(cinfo->emethods, "Bogus RLE error code");
    break;
  }

  /* Figure out what we have, set private vars and return values accordingly */
  
  width  = header.xmax - header.xmin + 1;
  height = header.ymax - header.ymin + 1;
  header.xmin = 0;		/* realign horizontally */
  header.xmax = width-1;

  cinfo->image_width      = width;
  cinfo->image_height     = height;
  cinfo->data_precision   = 8;  /* we can only handle 8 bit data */

  if (header.ncolors == 1 && header.ncmap == 0) {
    visual     = GRAYSCALE;
    TRACEMS(cinfo->emethods, 1, "Gray-scale RLE file");
  } else if (header.ncolors == 1 && header.ncmap == 3) {
    visual     = PSEUDOCOLOR;
    colormap   = header.cmap;
    TRACEMS1(cinfo->emethods, 1, "Colormapped RLE file with map of length %d",
	     1 << header.cmaplen);
  } else if (header.ncolors == 3 && header.ncmap == 3) {
    visual     = TRUECOLOR;
    colormap   = header.cmap;
    TRACEMS1(cinfo->emethods, 1, "Full-color RLE file with map of length %d",
	     1 << header.cmaplen);
  } else if (header.ncolors == 3 && header.ncmap == 0) {
    visual     = DIRECTCOLOR;
    TRACEMS(cinfo->emethods, 1, "Full-color RLE file");
  } else
    ERREXIT(cinfo->emethods, "Can't handle this RLE setup");
  
  switch (visual) {
  case GRAYSCALE:
    /* request one big array to hold the grayscale image */
    image = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
    cinfo->in_color_space   = CS_GRAYSCALE;
    cinfo->input_components = 1;
    break;
  case PSEUDOCOLOR:
    /* request one big array to hold the pseudocolor image */
    image = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
    cinfo->in_color_space   = CS_RGB;
    cinfo->input_components = 3;
    break;
  case TRUECOLOR:
  case DIRECTCOLOR:
    /* request three big arrays to hold the RGB channels */
    red_channel   = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
    green_channel = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
    blue_channel  = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
    cinfo->in_color_space   = CS_RGB;
    cinfo->input_components = 3;
    break;
  }
}


/*
 * Read one row of pixels.
 * These are called only after load_image has read the image into
 * the virtual array(s).
 */


METHODDEF void
get_grayscale_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This is used for GRAYSCALE images */
{
  JSAMPROW inputrows[1];	/* a pseudo JSAMPARRAY structure */

  cur_row_number--;		/* work down in array */
  
  inputrows[0] = *((*cinfo->emethods->access_big_sarray)
			(image, cur_row_number, FALSE));

  jcopy_sample_rows(inputrows, 0, pixel_row, 0, 1, cinfo->image_width);
}


METHODDEF void
get_pseudocolor_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This is used for PSEUDOCOLOR images */
{
  long col;
  JSAMPROW image_ptr, ptr0, ptr1, ptr2;
  int val;

  cur_row_number--;		/* work down in array */
  
  image_ptr = *((*cinfo->emethods->access_big_sarray)
		(image, cur_row_number, FALSE));

  ptr0 = pixel_row[0];
  ptr1 = pixel_row[1];
  ptr2 = pixel_row[2];
  
  for (col = cinfo->image_width; col > 0; col--) {
    val = GETJSAMPLE(*image_ptr++);
    *ptr0++ = colormap[val      ] >> 8;
    *ptr1++ = colormap[val + 256] >> 8;
    *ptr2++ = colormap[val + 512] >> 8;
  }
}


METHODDEF void
get_truecolor_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This is used for TRUECOLOR images */
/* The colormap consists of 3 independent lookup tables */
{
  long col;
  JSAMPROW red_ptr, green_ptr, blue_ptr, ptr0, ptr1, ptr2;
  
  cur_row_number--;		/* work down in array */
  
  red_ptr   = *((*cinfo->emethods->access_big_sarray)
		(red_channel, cur_row_number, FALSE));
  green_ptr = *((*cinfo->emethods->access_big_sarray)
		(green_channel, cur_row_number, FALSE));
  blue_ptr  = *((*cinfo->emethods->access_big_sarray)
		(blue_channel, cur_row_number, FALSE));
  
  ptr0 = pixel_row[0];
  ptr1 = pixel_row[1];
  ptr2 = pixel_row[2];
  
  for (col = cinfo->image_width; col > 0; col--) {
    *ptr0++ = colormap[GETJSAMPLE(*red_ptr++)        ] >> 8;
    *ptr1++ = colormap[GETJSAMPLE(*green_ptr++) + 256] >> 8;
    *ptr2++ = colormap[GETJSAMPLE(*blue_ptr++)  + 512] >> 8;
  }
}


METHODDEF void
get_directcolor_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This is used for DIRECTCOLOR images */
{
  JSAMPROW inputrows[3];	/* a pseudo JSAMPARRAY structure */

  cur_row_number--;		/* work down in array */
  
  inputrows[0] = *((*cinfo->emethods->access_big_sarray)
			(red_channel, cur_row_number, FALSE));
  inputrows[1] = *((*cinfo->emethods->access_big_sarray)
			(green_channel, cur_row_number, FALSE));
  inputrows[2] = *((*cinfo->emethods->access_big_sarray)
			(blue_channel, cur_row_number, FALSE));

  jcopy_sample_rows(inputrows, 0, pixel_row, 0, 3, cinfo->image_width);
}


/*
 * Load the color channels into separate arrays.  We have to do
 * this because RLE files start at the lower left while the JPEG standard
 * has them starting in the upper left.  This is called the first time
 * we want to get a row of input.  What we do is load the RLE data into
 * big arrays and then call the appropriate routine to read one row from
 * the big arrays.  We also change cinfo->methods->get_input_row so that
 * subsequent calls go straight to the row-reading routine.
 */

METHODDEF void
load_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
{
  long row;
  rle_pixel *rle_row[3];
  
  /* Read the RLE data into our virtual array(s).
   * We assume here that (a) rle_pixel is represented the same as JSAMPLE,
   * and (b) we are not on a machine where FAR pointers differ from regular.
   */
  RLE_CLR_BIT(header, RLE_ALPHA); /* don't read the alpha channel */

  switch (visual) {
  case GRAYSCALE:
  case PSEUDOCOLOR:
    for (row = 0; row < cinfo->image_height; row++) {
      /*
       * Read a row of the image directly into our big array.
       * Too bad this doesn't seem to return any indication of errors :-(.
       */
      rle_row[0] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
					(image, row, TRUE));
      rle_getrow(&header, rle_row);
    }
    break;
  case TRUECOLOR:
  case DIRECTCOLOR:
    for (row = 0; row < cinfo->image_height; row++) {
      /*
       * Read a row of the image directly into our big arrays.
       * Too bad this doesn't seem to return any indication of errors :-(.
       */
      rle_row[0] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
					(red_channel, row, TRUE));
      rle_row[1] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
					(green_channel, row, TRUE));
      rle_row[2] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
					(blue_channel, row, TRUE));
      rle_getrow(&header, rle_row);
    }
    break;
  }
  
  /* Set up to call proper row-extraction routine in future */
  switch (visual) {
  case GRAYSCALE:
    cinfo->methods->get_input_row = get_grayscale_row;
    break;
  case PSEUDOCOLOR:
    cinfo->methods->get_input_row = get_pseudocolor_row;
    break;
  case TRUECOLOR:
    cinfo->methods->get_input_row = get_truecolor_row;
    break;
  case DIRECTCOLOR:
    cinfo->methods->get_input_row = get_directcolor_row;
    break;
  }

  /* And fetch the topmost (bottommost) row */
  cur_row_number = cinfo->image_height;
  (*cinfo->methods->get_input_row) (cinfo, pixel_row);   
}


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

METHODDEF void
input_term (compress_info_ptr cinfo)
{
  switch (visual) {
  case GRAYSCALE:
  case PSEUDOCOLOR:
    (*cinfo->emethods->free_big_sarray) (image);
    break;
  case TRUECOLOR:
  case DIRECTCOLOR:
    (*cinfo->emethods->free_big_sarray) (red_channel);
    (*cinfo->emethods->free_big_sarray) (green_channel);
    (*cinfo->emethods->free_big_sarray) (blue_channel);
    break;
  }
}


/*
 * The method selection routine for RLE 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
jselrrle (compress_info_ptr cinfo)
{
  cinfo->methods->input_init    = input_init;
  cinfo->methods->get_input_row = load_image; /* until first call */
  cinfo->methods->input_term    = input_term;
}

#endif /* RLE_SUPPORTED */
