/*
 * jdpred.c
 *
 * This file was part of the Independent JPEG Group's software:
 * Copyright (C) 1998, Thomas G. Lane.
 * Lossless JPEG Modifications:
 * Copyright (C) 1999, Ken Murchison.
 * For conditions of distribution and use, see the accompanying README file.
 *
 * This file contains sample undifferencing (reconstruction) for lossless JPEG.
 *
 * In order to avoid paying the performance penalty of having to check the
 * predictor being used and the row being processed for each call of the
 * undifferencer, and to promote optimization, we have separate undifferencing
 * functions for each case.
 *
 * We are able to avoid duplicating source code by implementing the predictors
 * and undifferencers as macros.  Each of the undifferencing functions are
 * simply wrappers around an UNDIFFERENCE macro with the appropriate PREDICTOR
 * macro passed as an argument.
 */

#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jlossls.h"		/* Private declarations for lossless codec */


#ifdef D_LOSSLESS_SUPPORTED

/* Predictor for the first column of the first row: 2^(P-Pt-1) */
#define INITIAL_PREDICTORx	(1 << (cinfo->data_precision - cinfo->Al - 1))

/* Predictor for the first column of the remaining rows: Rb */
#define INITIAL_PREDICTOR2	GETJSAMPLE(prev_row[0])


/*
 * 1-Dimensional undifferencer routine.
 *
 * This macro implements the 1-D horizontal predictor (1).  INITIAL_PREDICTOR
 * is used as the special case predictor for the first column, which must be
 * either INITIAL_PREDICTOR2 or INITIAL_PREDICTORx.  The remaining samples
 * use PREDICTOR1.
 *
 * The reconstructed sample is supposed to be calculated modulo 2^16, so we
 * logically AND the result with 0xFFFF.
*/

#define UNDIFFERENCE_1D(INITIAL_PREDICTOR) \
	int xindex; \
	int Ra; \
 \
	Ra = (diff_buf[0] + INITIAL_PREDICTOR) & 0xFFFF; \
	undiff_buf[0] = Ra; \
 \
	for (xindex = 1; xindex < width; xindex++) { \
	  Ra = (diff_buf[xindex] + PREDICTOR1) & 0xFFFF; \
	  undiff_buf[xindex] = Ra; \
	}

/*
 * 2-Dimensional undifferencer routine.
 *
 * This macro implements the 2-D horizontal predictors (#2-7).  PREDICTOR2 is
 * used as the special case predictor for the first column.  The remaining
 * samples use PREDICTOR, which is a function of Ra, Rb, Rc.
 *
 * Because prev_row and output_buf may point to the same storage area (in an
 * interleaved image with Vi=1, for example), we must take care to buffer Rb/Rc
 * before writing the current reconstructed sample value into output_buf.
 *
 * The reconstructed sample is supposed to be calculated modulo 2^16, so we
 * logically AND the result with 0xFFFF.
 */

#define UNDIFFERENCE_2D(PREDICTOR) \
	int xindex; \
	int Ra, Rb, Rc; \
 \
	Rb = GETJSAMPLE(prev_row[0]); \
	Ra = (diff_buf[0] + PREDICTOR2) & 0xFFFF; \
	undiff_buf[0] = Ra; \
 \
	for (xindex = 1; xindex < width; xindex++) { \
	  Rc = Rb; \
	  Rb = GETJSAMPLE(prev_row[xindex]); \
	  Ra = (diff_buf[xindex] + PREDICTOR) & 0xFFFF; \
	  undiff_buf[xindex] = Ra; \
	}


/*
 * Undifferencers for the all rows but the first in a scan or restart interval.
 * The first sample in the row is undifferenced using the vertical
 * predictor (2).  The rest of the samples are undifferenced using the
 * predictor specified in the scan header.
 */

METHODDEF(void)
jpeg_undifference1(j_decompress_ptr cinfo, int comp_index,
		   JDIFFROW diff_buf, JDIFFROW prev_row,
		   JDIFFROW undiff_buf, JDIMENSION width)
{
  UNDIFFERENCE_1D(INITIAL_PREDICTOR2);
}

METHODDEF(void)
jpeg_undifference2(j_decompress_ptr cinfo, int comp_index,
		   JDIFFROW diff_buf, JDIFFROW prev_row,
		   JDIFFROW undiff_buf, JDIMENSION width)
{
  UNDIFFERENCE_2D(PREDICTOR2);
}

METHODDEF(void)
jpeg_undifference3(j_decompress_ptr cinfo, int comp_index,
		   JDIFFROW diff_buf, JDIFFROW prev_row,
		   JDIFFROW undiff_buf, JDIMENSION width)
{
  UNDIFFERENCE_2D(PREDICTOR3);
}

METHODDEF(void)
jpeg_undifference4(j_decompress_ptr cinfo, int comp_index,
		   JDIFFROW diff_buf, JDIFFROW prev_row,
		   JDIFFROW undiff_buf, JDIMENSION width)
{
  UNDIFFERENCE_2D(PREDICTOR4);
}

METHODDEF(void)
jpeg_undifference5(j_decompress_ptr cinfo, int comp_index,
		   JDIFFROW diff_buf, JDIFFROW prev_row,
		   JDIFFROW undiff_buf, JDIMENSION width)
{
  UNDIFFERENCE_2D(PREDICTOR5);
}

METHODDEF(void)
jpeg_undifference6(j_decompress_ptr cinfo, int comp_index,
		   JDIFFROW diff_buf, JDIFFROW prev_row,
		   JDIFFROW undiff_buf, JDIMENSION width)
{
  UNDIFFERENCE_2D(PREDICTOR6);
}

METHODDEF(void)
jpeg_undifference7(j_decompress_ptr cinfo, int comp_index,
		   JDIFFROW diff_buf, JDIFFROW prev_row,
		   JDIFFROW undiff_buf, JDIMENSION width)
{
  UNDIFFERENCE_2D(PREDICTOR7);
}


/*
 * Undifferencer for the first row in a scan or restart interval.  The first
 * sample in the row is undifferenced using the special predictor constant
 * x=2^(P-Pt-1).  The rest of the samples are undifferenced using the
 * 1-D horizontal predictor (1).
 */

METHODDEF(void)
jpeg_undifference_first_row(j_decompress_ptr cinfo, int comp_index,
			    JDIFFROW diff_buf, JDIFFROW prev_row,
			    JDIFFROW undiff_buf, JDIMENSION width)
{
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;

  UNDIFFERENCE_1D(INITIAL_PREDICTORx);

  /*
   * Now that we have undifferenced the first row, we want to use the
   * undifferencer which corresponds to the predictor specified in the
   * scan header.
   */
  switch (cinfo->Ss) {
  case 1:
    losslsd->predict_undifference[comp_index] = jpeg_undifference1;
    break;
  case 2:
    losslsd->predict_undifference[comp_index] = jpeg_undifference2;
    break;
  case 3:
    losslsd->predict_undifference[comp_index] = jpeg_undifference3;
    break;
  case 4:
    losslsd->predict_undifference[comp_index] = jpeg_undifference4;
    break;
  case 5:
    losslsd->predict_undifference[comp_index] = jpeg_undifference5;
    break;
  case 6:
    losslsd->predict_undifference[comp_index] = jpeg_undifference6;
    break;
  case 7:
    losslsd->predict_undifference[comp_index] = jpeg_undifference7;
    break;
  }
}


/*
 * Initialize for an input processing pass.
 */

METHODDEF(void)
predict_start_pass (j_decompress_ptr cinfo)
{
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
  int ci;

  /* Check that the scan parameters Ss, Se, Ah, Al are OK for lossless JPEG.
   *
   * Ss is the predictor selection value (psv).  Legal values for sequential
   * lossless JPEG are: 1 <= psv <= 7.
   *
   * Se and Ah are not used and should be zero.
   *
   * Al specifies the point transform (Pt).  Legal values are: 0 <= Pt <= 15.
   */
  if (cinfo->Ss < 1 || cinfo->Ss > 7 ||
      cinfo->Se != 0 || cinfo->Ah != 0 ||
      cinfo->Al > 15)				/* need not check for < 0 */
    ERREXIT4(cinfo, JERR_BAD_LOSSLESS,
	     cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);

  /* Set undifference functions to first row function */
  for (ci = 0; ci < cinfo->num_components; ci++)
    losslsd->predict_undifference[ci] = jpeg_undifference_first_row;
}


/*
 * Module initialization routine for the undifferencer.
 */

GLOBAL(void)
jinit_undifferencer (j_decompress_ptr cinfo)
{
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;

  losslsd->predict_start_pass = predict_start_pass;
  losslsd->predict_process_restart = predict_start_pass;
}

#endif /* D_LOSSLESS_SUPPORTED */

