/*
 * jdscale.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 scaling for lossless JPEG.  This is a
 * combination of upscaling the undifferenced sample by 2^Pt and downscaling
 * the sample to fit into JSAMPLE.
 */

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


#ifdef D_LOSSLESS_SUPPORTED

/*
 * Private scaler object for lossless decoding.
 */

typedef struct {
  int scale_factor;
} scaler;

typedef scaler * scaler_ptr;


/*
 * Scalers for packing sample differences into JSAMPLEs.
 */

METHODDEF(void)
simple_upscale(j_decompress_ptr cinfo,
	       JDIFFROW diff_buf, JSAMPROW output_buf,
	       JDIMENSION width)
{
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
  scaler_ptr scaler = (scaler_ptr) losslsd->scaler_private;
  int scale_factor = scaler->scale_factor;
  int xindex;

  for (xindex = 0; xindex < width; xindex++)
    output_buf[xindex] = (JSAMPLE) (diff_buf[xindex] << scale_factor);
}

METHODDEF(void)
simple_downscale(j_decompress_ptr cinfo,
		 JDIFFROW diff_buf, JSAMPROW output_buf,
		 JDIMENSION width)
{
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
  scaler_ptr scaler = (scaler_ptr) losslsd->scaler_private;
  int scale_factor = scaler->scale_factor;
  int xindex;

  for (xindex = 0; xindex < width; xindex++)
    output_buf[xindex] = (JSAMPLE) RIGHT_SHIFT(diff_buf[xindex], scale_factor);
}

METHODDEF(void)
noscale(j_decompress_ptr cinfo,
	JDIFFROW diff_buf, JSAMPROW output_buf,
	JDIMENSION width)
{
  int xindex;

  for (xindex = 0; xindex < width; xindex++)
    output_buf[xindex] = (JSAMPLE) diff_buf[xindex];
}


METHODDEF(void)
scaler_start_pass (j_decompress_ptr cinfo)
{
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
  scaler_ptr scaler = (scaler_ptr) losslsd->scaler_private;
  int downscale;

  /*
   * Downscale by the difference in the input vs. output precision.  If the
   * output precision >= input precision, then do not downscale.
   */
  downscale = BITS_IN_JSAMPLE < cinfo->data_precision ?
    cinfo->data_precision - BITS_IN_JSAMPLE : 0;

  scaler->scale_factor = cinfo->Al - downscale;

  /* Set scaler functions based on scale_factor (positive = left shift) */
  if (scaler->scale_factor > 0)
    losslsd->scaler_scale = simple_upscale;
  else if (scaler->scale_factor < 0) {
    scaler->scale_factor = -scaler->scale_factor;
    losslsd->scaler_scale = simple_downscale;
  }
  else
    losslsd->scaler_scale = noscale;
}


GLOBAL(void)
jinit_d_scaler (j_decompress_ptr cinfo)
{
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
  scaler_ptr scaler;

  scaler = (scaler_ptr)
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				SIZEOF(scaler));
  losslsd->scaler_private = (void *) scaler;
  losslsd->scaler_start_pass = scaler_start_pass;
}

#endif /* D_LOSSLESS_SUPPORTED */

