/*
 * jcsample.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 subsampling routines.
 * These routines are invoked via the subsample and
 * subsample_init/term methods.
 */

#include "jinclude.h"


/*
 * Initialize for subsampling a scan.
 */

METHODDEF void
subsample_init (compress_info_ptr cinfo)
{
  /* no work for now */
}


/*
 * Subsample pixel values of a single component.
 * This version only handles integral sampling ratios.
 */

METHODDEF void
subsample (compress_info_ptr cinfo, int which_component,
	   long input_cols, int input_rows,
	   long output_cols, int output_rows,
	   JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
	   JSAMPARRAY output_data)
{
  jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
  int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
  long outcol;
  JSAMPROW inptr, outptr;
  INT32 outvalue;

  /* TEMP FOR DEBUGGING PIPELINE CONTROLLER */
  if (output_rows != compptr->v_samp_factor ||
      input_rows != cinfo->max_v_samp_factor ||
      (output_cols % compptr->h_samp_factor) != 0 ||
      (input_cols % cinfo->max_h_samp_factor) != 0 ||
      input_cols*compptr->h_samp_factor != output_cols*cinfo->max_h_samp_factor)
    ERREXIT(cinfo->emethods, "Bogus subsample parameters");

  h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
  v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
  numpix = h_expand * v_expand;
  numpix2 = numpix/2;

  inrow = 0;
  for (outrow = 0; outrow < output_rows; outrow++) {
    outptr = output_data[outrow];
    for (outcol = 0; outcol < output_cols; outcol++) {
      outvalue = 0;
      for (v = 0; v < v_expand; v++) {
	inptr = input_data[inrow+v] + (outcol*h_expand);
	for (h = 0; h < h_expand; h++) {
	  outvalue += (INT32) GETJSAMPLE(*inptr++);
	}
      }
      *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
    }
    inrow += v_expand;
  }
}


/*
 * Subsample pixel values of a single component.
 * This version handles the special case of a full-size component.
 */

METHODDEF void
fullsize_subsample (compress_info_ptr cinfo, int which_component,
		    long input_cols, int input_rows,
		    long output_cols, int output_rows,
		    JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
		    JSAMPARRAY output_data)
{
  if (input_cols != output_cols || input_rows != output_rows) /* DEBUG */
    ERREXIT(cinfo->emethods, "Pipeline controller messed up");

  jcopy_sample_rows(input_data, 0, output_data, 0, output_rows, output_cols);
}


/*
 * Clean up after a scan.
 */

METHODDEF void
subsample_term (compress_info_ptr cinfo)
{
  /* no work for now */
}



/*
 * The method selection routine for subsampling.
 * Note that we must select a routine for each component.
 */

GLOBAL void
jselsubsample (compress_info_ptr cinfo)
{
  short ci;
  jpeg_component_info * compptr;

  if (cinfo->CCIR601_sampling)
    ERREXIT(cinfo->emethods, "CCIR601 subsampling not implemented yet");

  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    compptr = cinfo->cur_comp_info[ci];
    if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
	compptr->v_samp_factor == cinfo->max_v_samp_factor)
      cinfo->methods->subsample[ci] = fullsize_subsample;
    else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
	     (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
      cinfo->methods->subsample[ci] = subsample;
    else
      ERREXIT(cinfo->emethods, "Fractional subsampling not implemented yet");
  }

  cinfo->methods->subsample_init = subsample_init;
  cinfo->methods->subsample_term = subsample_term;
}
