/*
 * 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 += GETJSAMPLE(*inptr++);
	}
      }
      *outptr++ = (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;
}
