/*
 * jcpipe.c
 *
 * Copyright (C) 1991, 1992, 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 compression pipeline controllers.
 * These routines are invoked via the c_pipeline_controller method.
 *
 * There are four basic pipeline controllers, one for each combination of:
 *	single-scan JPEG file (single component or fully interleaved)
 *  vs. multiple-scan JPEG file (noninterleaved or partially interleaved).
 *
 *	optimization of entropy encoding parameters
 *  vs. usage of default encoding parameters.
 *
 * Note that these conditions determine the needs for "big" arrays:
 * multiple scans imply a big array for splitting the color components;
 * entropy encoding optimization needs a big array for the MCU data.
 *
 * All but the simplest controller (single-scan, no optimization) can be
 * compiled out through configuration options, if you need to make a minimal
 * implementation.
 */

#include "jinclude.h"


/*
 * About the data structures:
 *
 * The processing chunk size for subsampling is referred to in this file as
 * a "row group": a row group is defined as Vk (v_samp_factor) sample rows of
 * any component after subsampling, or Vmax (max_v_samp_factor) unsubsampled
 * rows.  In an interleaved scan each MCU row contains exactly DCTSIZE row
 * groups of each component in the scan.  In a noninterleaved scan an MCU row
 * is one row of blocks, which might not be an integral number of row groups;
 * for convenience we use a buffer of the same size as in interleaved scans,
 * and process Vk MCU rows in each burst of subsampling.
 * To provide context for the subsampling step, we have to retain the last
 * two row groups of the previous MCU row while reading in the next MCU row
 * (or set of Vk MCU rows).  To do this without copying data about, we create
 * a rather strange data structure.  Exactly DCTSIZE+2 row groups of samples
 * are allocated, but we create two different sets of pointers to this array.
 * The second set swaps the last two pairs of row groups.  By working
 * alternately with the two sets of pointers, we can access the data in the
 * desired order.
 */



/*
 * Utility routines: common code for pipeline controllers
 */

LOCAL void
interleaved_scan_setup (compress_info_ptr cinfo)
/* Compute all derived info for an interleaved (multi-component) scan */
/* On entry, cinfo->comps_in_scan and cinfo->cur_comp_info[] are set up */
{
  short ci, mcublks;
  jpeg_component_info *compptr;

  if (cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
    ERREXIT(cinfo->emethods, "Too many components for interleaved scan");

  cinfo->MCUs_per_row = (cinfo->image_width
			 + cinfo->max_h_samp_factor*DCTSIZE - 1)
			/ (cinfo->max_h_samp_factor*DCTSIZE);

  cinfo->MCU_rows_in_scan = (cinfo->image_height
			     + cinfo->max_v_samp_factor*DCTSIZE - 1)
			    / (cinfo->max_v_samp_factor*DCTSIZE);
  
  cinfo->blocks_in_MCU = 0;

  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    compptr = cinfo->cur_comp_info[ci];
    /* for interleaved scan, sampling factors give # of blocks per component */
    compptr->MCU_width = compptr->h_samp_factor;
    compptr->MCU_height = compptr->v_samp_factor;
    compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
    /* compute physical dimensions of component */
    compptr->subsampled_width = jround_up(compptr->true_comp_width,
					  (long) (compptr->MCU_width*DCTSIZE));
    compptr->subsampled_height = jround_up(compptr->true_comp_height,
					   (long) (compptr->MCU_height*DCTSIZE));
    /* Sanity check */
    if (compptr->subsampled_width !=
	(cinfo->MCUs_per_row * (compptr->MCU_width*DCTSIZE)))
      ERREXIT(cinfo->emethods, "I'm confused about the image width");
    /* Prepare array describing MCU composition */
    mcublks = compptr->MCU_blocks;
    if (cinfo->blocks_in_MCU + mcublks > MAX_BLOCKS_IN_MCU)
      ERREXIT(cinfo->emethods, "Sampling factors too large for interleaved scan");
    while (mcublks-- > 0) {
      cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
    }
  }

  (*cinfo->methods->c_per_scan_method_selection) (cinfo);
}


LOCAL void
noninterleaved_scan_setup (compress_info_ptr cinfo)
/* Compute all derived info for a noninterleaved (single-component) scan */
/* On entry, cinfo->comps_in_scan = 1 and cinfo->cur_comp_info[0] is set up */
{
  jpeg_component_info *compptr = cinfo->cur_comp_info[0];

  /* for noninterleaved scan, always one block per MCU */
  compptr->MCU_width = 1;
  compptr->MCU_height = 1;
  compptr->MCU_blocks = 1;
  /* compute physical dimensions of component */
  compptr->subsampled_width = jround_up(compptr->true_comp_width,
					(long) DCTSIZE);
  compptr->subsampled_height = jround_up(compptr->true_comp_height,
					 (long) DCTSIZE);

  cinfo->MCUs_per_row = compptr->subsampled_width / DCTSIZE;
  cinfo->MCU_rows_in_scan = compptr->subsampled_height / DCTSIZE;

  /* Prepare array describing MCU composition */
  cinfo->blocks_in_MCU = 1;
  cinfo->MCU_membership[0] = 0;

  (*cinfo->methods->c_per_scan_method_selection) (cinfo);
}



LOCAL void
alloc_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2],
		       long fullsize_width)
/* Create a pre-subsampling data buffer having the desired structure */
/* (see comments at head of file) */
{
  short ci, vs, i;

  vs = cinfo->max_v_samp_factor; /* row group height */

  /* Get top-level space for array pointers */
  fullsize_data[0] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
				(cinfo->num_components * SIZEOF(JSAMPARRAY));
  fullsize_data[1] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
				(cinfo->num_components * SIZEOF(JSAMPARRAY));

  for (ci = 0; ci < cinfo->num_components; ci++) {
    /* Allocate the real storage */
    fullsize_data[0][ci] = (*cinfo->emethods->alloc_small_sarray)
				(fullsize_width,
				(long) (vs * (DCTSIZE+2)));
    /* Create space for the scrambled-order pointers */
    fullsize_data[1][ci] = (JSAMPARRAY) (*cinfo->emethods->alloc_small)
				(vs * (DCTSIZE+2) * SIZEOF(JSAMPROW));
    /* Duplicate the first DCTSIZE-2 row groups */
    for (i = 0; i < vs * (DCTSIZE-2); i++) {
      fullsize_data[1][ci][i] = fullsize_data[0][ci][i];
    }
    /* Copy the last four row groups in swapped order */
    for (i = 0; i < vs * 2; i++) {
      fullsize_data[1][ci][vs*DCTSIZE + i] = fullsize_data[0][ci][vs*(DCTSIZE-2) + i];
      fullsize_data[1][ci][vs*(DCTSIZE-2) + i] = fullsize_data[0][ci][vs*DCTSIZE + i];
    }
  }
}


#if 0				/* this routine not currently needed */

LOCAL void
free_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2])
/* Release a sampling buffer created by alloc_sampling_buffer */
{
  short ci;

  for (ci = 0; ci < cinfo->num_components; ci++) {
    /* Free the real storage */
    (*cinfo->emethods->free_small_sarray) (fullsize_data[0][ci]);
    /* Free the scrambled-order pointers */
    (*cinfo->emethods->free_small) ((void *) fullsize_data[1][ci]);
  }

  /* Free the top-level space */
  (*cinfo->emethods->free_small) ((void *) fullsize_data[0]);
  (*cinfo->emethods->free_small) ((void *) fullsize_data[1]);
}

#endif


LOCAL void
subsample (compress_info_ptr cinfo,
	   JSAMPIMAGE fullsize_data, JSAMPIMAGE subsampled_data,
	   long fullsize_width,
	   short above, short current, short below, short out)
/* Do subsampling of a single row group (of each component). */
/* above, current, below are indexes of row groups in fullsize_data;      */
/* out is the index of the target row group in subsampled_data.           */
/* Special case: above, below can be -1 to indicate top, bottom of image. */
{
  jpeg_component_info *compptr;
  JSAMPARRAY above_ptr, below_ptr;
  JSAMPROW dummy[MAX_SAMP_FACTOR]; /* for subsample expansion at top/bottom */
  short ci, vs, i;

  vs = cinfo->max_v_samp_factor; /* row group height */

  for (ci = 0; ci < cinfo->num_components; ci++) {
    compptr = & cinfo->comp_info[ci];

    if (above >= 0)
      above_ptr = fullsize_data[ci] + above * vs;
    else {
      /* Top of image: make a dummy above-context with copies of 1st row */
      /* We assume current=0 in this case */
      for (i = 0; i < vs; i++)
	dummy[i] = fullsize_data[ci][0];
      above_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
    }

    if (below >= 0)
      below_ptr = fullsize_data[ci] + below * vs;
    else {
      /* Bot of image: make a dummy below-context with copies of last row */
      for (i = 0; i < vs; i++)
	dummy[i] = fullsize_data[ci][(current+1)*vs-1];
      below_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
    }

    (*cinfo->methods->subsample[ci])
		(cinfo, (int) ci,
		 fullsize_width, (int) vs,
		 compptr->subsampled_width, (int) compptr->v_samp_factor,
		 above_ptr,
		 fullsize_data[ci] + current * vs,
		 below_ptr,
		 subsampled_data[ci] + out * compptr->v_samp_factor);
  }
}


/* These vars are initialized by the pipeline controller for use by
 * MCU_output_catcher.
 * To avoid a lot of row-pointer overhead, we cram as many MCUs into each
 * row of whole_scan_MCUs as we can get without exceeding 64KB per row.
 */

#define MAX_WHOLE_ROW_BLOCKS	((int) (65500 / SIZEOF(JBLOCK))) /* max blocks/row */

static big_barray_ptr whole_scan_MCUs; /* Big array for saving the MCUs */
static int MCUs_in_big_row;	/* # of MCUs in each row of whole_scan_MCUs */
static long next_whole_row;	/* next row to access in whole_scan_MCUs */
static int next_MCU_index;	/* next MCU in current row */


METHODDEF void
MCU_output_catcher (compress_info_ptr cinfo, JBLOCK *MCU_data)
/* Output method for siphoning off extract_MCUs output into a big array */
{
  static JBLOCKARRAY rowptr;

  if (next_MCU_index >= MCUs_in_big_row) {
    rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
						    next_whole_row, TRUE);
    next_whole_row++;
    next_MCU_index = 0;
  }

  /*
   * note that on 80x86, the cast applied to MCU_data implies
   * near to far pointer conversion.
   */
  jcopy_block_row((JBLOCKROW) MCU_data,
		  rowptr[0] + next_MCU_index * cinfo->blocks_in_MCU,
		  (long) cinfo->blocks_in_MCU);
  next_MCU_index++;
}


METHODDEF void
dump_scan_MCUs (compress_info_ptr cinfo, MCU_output_method_ptr output_method)
/* Dump the MCUs saved in whole_scan_MCUs to the output method. */
/* The method may be either the entropy encoder or some routine supplied */
/* by the entropy optimizer. */
{
  /* On an 80x86 machine, the entropy encoder expects the passed data block
   * to be in NEAR memory (for performance reasons), so we have to copy it
   * back from the big array to a local array.  On less brain-damaged CPUs
   * we needn't do that.
   */
#ifdef NEED_FAR_POINTERS
  JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
#endif
  long mcurow, mcuindex, next_row;
  int next_index;
  JBLOCKARRAY rowptr = NULL;	/* init only to suppress compiler complaint */

  next_row = 0;
  next_index = MCUs_in_big_row;

  for (mcurow = 0; mcurow < cinfo->MCU_rows_in_scan; mcurow++) {
    (*cinfo->methods->progress_monitor) (cinfo, mcurow,
					 cinfo->MCU_rows_in_scan);
    for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
      if (next_index >= MCUs_in_big_row) {
	rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
							next_row, FALSE);
	next_row++;
	next_index = 0;
      }
#ifdef NEED_FAR_POINTERS
      jcopy_block_row(rowptr[0] + next_index * cinfo->blocks_in_MCU,
		      (JBLOCKROW) MCU_data, /* casts near to far pointer! */
		      (long) cinfo->blocks_in_MCU);
      (*output_method) (cinfo, MCU_data);
#else
      (*output_method) (cinfo, rowptr[0] + next_index * cinfo->blocks_in_MCU);
#endif
      next_index++;
    }
  }

  cinfo->completed_passes++;
}



/*
 * Compression pipeline controller used for single-scan files
 * with no optimization of entropy parameters.
 */

METHODDEF void
single_ccontroller (compress_info_ptr cinfo)
{
  int rows_in_mem;		/* # of sample rows in full-size buffers */
  long fullsize_width;		/* # of samples per row in full-size buffers */
  long cur_pixel_row;		/* counts # of pixel rows processed */
  long mcu_rows_output;		/* # of MCU rows actually emitted */
  int mcu_rows_per_loop;	/* # of MCU rows processed per outer loop */
  /* Work buffer for pre-subsampling data (see comments at head of file) */
  JSAMPIMAGE fullsize_data[2];
  /* Work buffer for subsampled data */
  JSAMPIMAGE subsampled_data;
  int rows_this_time;
  short ci, whichss, i;

  /* Prepare for single scan containing all components */
  if (cinfo->num_components > MAX_COMPS_IN_SCAN)
    ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
  cinfo->comps_in_scan = cinfo->num_components;
  for (ci = 0; ci < cinfo->num_components; ci++) {
    cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
  }
  if (cinfo->comps_in_scan == 1) {
    noninterleaved_scan_setup(cinfo);
    /* Vk block rows constitute the same number of MCU rows */
    mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
  } else {
    interleaved_scan_setup(cinfo);
    /* in an interleaved scan, one MCU row contains Vk block rows */
    mcu_rows_per_loop = 1;
  }
  cinfo->total_passes++;

  /* Compute dimensions of full-size pixel buffers */
  /* Note these are the same whether interleaved or not. */
  rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
  fullsize_width = jround_up(cinfo->image_width,
			     (long) (cinfo->max_h_samp_factor * DCTSIZE));

  /* Allocate working memory: */
  /* fullsize_data is sample data before subsampling */
  alloc_sampling_buffer(cinfo, fullsize_data, fullsize_width);
  /* subsampled_data is sample data after subsampling */
  subsampled_data = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
				(cinfo->num_components * SIZEOF(JSAMPARRAY));
  for (ci = 0; ci < cinfo->num_components; ci++) {
    subsampled_data[ci] = (*cinfo->emethods->alloc_small_sarray)
			(cinfo->comp_info[ci].subsampled_width,
			 (long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
  }

  /* Tell the memory manager to instantiate big arrays.
   * We don't need any big arrays in this controller,
   * but some other module (like the input file reader) may need one.
   */
  (*cinfo->emethods->alloc_big_arrays)
	((long) 0,				/* no more small sarrays */
	 (long) 0,				/* no more small barrays */
	 (long) 0);				/* no more "medium" objects */

  /* Initialize output file & do per-scan object init */

  (*cinfo->methods->write_scan_header) (cinfo);
  cinfo->methods->entropy_output = cinfo->methods->write_jpeg_data;
  (*cinfo->methods->entropy_encoder_init) (cinfo);
  (*cinfo->methods->subsample_init) (cinfo);
  (*cinfo->methods->extract_init) (cinfo);

  /* Loop over input image: rows_in_mem pixel rows are processed per loop */

  mcu_rows_output = 0;
  whichss = 1;			/* arrange to start with fullsize_data[0] */

  for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
       cur_pixel_row += rows_in_mem) {
    (*cinfo->methods->progress_monitor) (cinfo, cur_pixel_row,
					 cinfo->image_height);

    whichss ^= 1;		/* switch to other fullsize_data buffer */
    
    /* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
    /* Then we have exactly DCTSIZE row groups for subsampling. */   
    rows_this_time = (int) MIN((long) rows_in_mem,
			       cinfo->image_height - cur_pixel_row);
 
    (*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
					fullsize_data[whichss]);
    (*cinfo->methods->edge_expand) (cinfo,
				    cinfo->image_width, rows_this_time,
				    fullsize_width, rows_in_mem,
				    fullsize_data[whichss]);
    
    /* Subsample the data (all components) */
    /* First time through is a special case */
    
    if (cur_pixel_row) {
      /* Subsample last row group of previous set */
      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
		(short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
		(short) (DCTSIZE-1));
      /* and dump the previous set's subsampled data */
      (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data, 
				       mcu_rows_per_loop,
				       cinfo->methods->entropy_encode);
      mcu_rows_output += mcu_rows_per_loop;
      /* Subsample first row group of this set */
      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
		(short) (DCTSIZE+1), (short) 0, (short) 1,
		(short) 0);
    } else {
      /* Subsample first row group with dummy above-context */
      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
		(short) (-1), (short) 0, (short) 1,
		(short) 0);
    }
    /* Subsample second through next-to-last row groups of this set */
    for (i = 1; i <= DCTSIZE-2; i++) {
      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
		(short) (i-1), (short) i, (short) (i+1),
		(short) i);
    }
  } /* end of outer loop */
  
  /* Subsample the last row group with dummy below-context */
  /* Note whichss points to last buffer side used */
  subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
	    (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
	    (short) (DCTSIZE-1));
  /* Dump the remaining data (may be less than full height if uninterleaved) */
  (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data, 
		(int) (cinfo->MCU_rows_in_scan - mcu_rows_output),
		cinfo->methods->entropy_encode);

  /* Finish output file */
  (*cinfo->methods->extract_term) (cinfo);
  (*cinfo->methods->subsample_term) (cinfo);
  (*cinfo->methods->entropy_encoder_term) (cinfo);
  (*cinfo->methods->write_scan_trailer) (cinfo);
  cinfo->completed_passes++;

  /* Release working memory */
  /* (no work -- we let free_all release what's needful) */
}


/*
 * Compression pipeline controller used for single-scan files
 * with optimization of entropy parameters.
 */

#ifdef ENTROPY_OPT_SUPPORTED

METHODDEF void
single_eopt_ccontroller (compress_info_ptr cinfo)
{
  int rows_in_mem;		/* # of sample rows in full-size buffers */
  long fullsize_width;		/* # of samples per row in full-size buffers */
  long cur_pixel_row;		/* counts # of pixel rows processed */
  long mcu_rows_output;		/* # of MCU rows actually emitted */
  int mcu_rows_per_loop;	/* # of MCU rows processed per outer loop */
  /* Work buffer for pre-subsampling data (see comments at head of file) */
  JSAMPIMAGE fullsize_data[2];
  /* Work buffer for subsampled data */
  JSAMPIMAGE subsampled_data;
  int rows_this_time;
  int blocks_in_big_row;
  short ci, whichss, i;

  /* Prepare for single scan containing all components */
  if (cinfo->num_components > MAX_COMPS_IN_SCAN)
    ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
  cinfo->comps_in_scan = cinfo->num_components;
  for (ci = 0; ci < cinfo->num_components; ci++) {
    cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
  }
  if (cinfo->comps_in_scan == 1) {
    noninterleaved_scan_setup(cinfo);
    /* Vk block rows constitute the same number of MCU rows */
    mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
  } else {
    interleaved_scan_setup(cinfo);
    /* in an interleaved scan, one MCU row contains Vk block rows */
    mcu_rows_per_loop = 1;
  }
  cinfo->total_passes += 2;	/* entropy encoder must add # passes it uses */

  /* Compute dimensions of full-size pixel buffers */
  /* Note these are the same whether interleaved or not. */
  rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
  fullsize_width = jround_up(cinfo->image_width,
			     (long) (cinfo->max_h_samp_factor * DCTSIZE));

  /* Allocate working memory: */
  /* fullsize_data is sample data before subsampling */
  alloc_sampling_buffer(cinfo, fullsize_data, fullsize_width);
  /* subsampled_data is sample data after subsampling */
  subsampled_data = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
				(cinfo->num_components * SIZEOF(JSAMPARRAY));
  for (ci = 0; ci < cinfo->num_components; ci++) {
    subsampled_data[ci] = (*cinfo->emethods->alloc_small_sarray)
			(cinfo->comp_info[ci].subsampled_width,
			 (long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
  }

  /* Figure # of MCUs to be packed in a row of whole_scan_MCUs */
  MCUs_in_big_row = MAX_WHOLE_ROW_BLOCKS / cinfo->blocks_in_MCU;
  blocks_in_big_row = MCUs_in_big_row * cinfo->blocks_in_MCU;

  /* Request a big array: whole_scan_MCUs saves the MCU data for the scan */
  whole_scan_MCUs = (*cinfo->emethods->request_big_barray)
		((long) blocks_in_big_row,
		 (long) (cinfo->MCUs_per_row * cinfo->MCU_rows_in_scan
			 + MCUs_in_big_row-1) / MCUs_in_big_row,
		 1L);		/* unit height is 1 row */

  next_whole_row = 0;		/* init output ptr for MCU_output_catcher */
  next_MCU_index = MCUs_in_big_row; /* forces access on first call! */

  /* Tell the memory manager to instantiate big arrays */
  (*cinfo->emethods->alloc_big_arrays)
	((long) 0,				/* no more small sarrays */
	 (long) 0,				/* no more small barrays */
	 (long) 0);				/* no more "medium" objects */

  /* Do per-scan object init */

  (*cinfo->methods->subsample_init) (cinfo);
  (*cinfo->methods->extract_init) (cinfo);

  /* Loop over input image: rows_in_mem pixel rows are processed per loop */
  /* MCU data goes into whole_scan_MCUs, not to the entropy encoder */

  mcu_rows_output = 0;
  whichss = 1;			/* arrange to start with fullsize_data[0] */

  for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
       cur_pixel_row += rows_in_mem) {
    (*cinfo->methods->progress_monitor) (cinfo, cur_pixel_row,
					 cinfo->image_height);

    whichss ^= 1;		/* switch to other fullsize_data buffer */
    
    /* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
    /* Then we have exactly DCTSIZE row groups for subsampling. */   
    rows_this_time = (int) MIN((long) rows_in_mem,
			       cinfo->image_height - cur_pixel_row);
 
    (*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
					fullsize_data[whichss]);
    (*cinfo->methods->edge_expand) (cinfo,
				    cinfo->image_width, rows_this_time,
				    fullsize_width, rows_in_mem,
				    fullsize_data[whichss]);
    
    /* Subsample the data (all components) */
    /* First time through is a special case */
    
    if (cur_pixel_row) {
      /* Subsample last row group of previous set */
      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
		(short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
		(short) (DCTSIZE-1));
      /* and dump the previous set's subsampled data */
      (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data, 
				       mcu_rows_per_loop,
				       MCU_output_catcher);
      mcu_rows_output += mcu_rows_per_loop;
      /* Subsample first row group of this set */
      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
		(short) (DCTSIZE+1), (short) 0, (short) 1,
		(short) 0);
    } else {
      /* Subsample first row group with dummy above-context */
      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
		(short) (-1), (short) 0, (short) 1,
		(short) 0);
    }
    /* Subsample second through next-to-last row groups of this set */
    for (i = 1; i <= DCTSIZE-2; i++) {
      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
		(short) (i-1), (short) i, (short) (i+1),
		(short) i);
    }
  } /* end of outer loop */
  
  /* Subsample the last row group with dummy below-context */
  /* Note whichss points to last buffer side used */
  subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
	    (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
	    (short) (DCTSIZE-1));
  /* Dump the remaining data (may be less than full height if uninterleaved) */
  (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data, 
		(int) (cinfo->MCU_rows_in_scan - mcu_rows_output),
		MCU_output_catcher);

  /* Clean up after that stuff, then find the optimal entropy parameters */

  (*cinfo->methods->extract_term) (cinfo);
  (*cinfo->methods->subsample_term) (cinfo);

  cinfo->completed_passes++;

  (*cinfo->methods->entropy_optimize) (cinfo, dump_scan_MCUs);

  /* Emit scan to output file */
  /* Note: we can't do write_scan_header until entropy parameters are set! */

  (*cinfo->methods->write_scan_header) (cinfo);
  cinfo->methods->entropy_output = cinfo->methods->write_jpeg_data;
  (*cinfo->methods->entropy_encoder_init) (cinfo);
  dump_scan_MCUs(cinfo, cinfo->methods->entropy_encode);
  (*cinfo->methods->entropy_encoder_term) (cinfo);
  (*cinfo->methods->write_scan_trailer) (cinfo);

  /* Release working memory */
  /* (no work -- we let free_all release what's needful) */
}

#endif /* ENTROPY_OPT_SUPPORTED */


/*
 * Compression pipeline controller used for multiple-scan files
 * with no optimization of entropy parameters.
 */

#ifdef MULTISCAN_FILES_SUPPORTED

METHODDEF void
multi_ccontroller (compress_info_ptr cinfo)
{
  ERREXIT(cinfo->emethods, "Not implemented yet");
}

#endif /* MULTISCAN_FILES_SUPPORTED */


/*
 * Compression pipeline controller used for multiple-scan files
 * with optimization of entropy parameters.
 */

#ifdef MULTISCAN_FILES_SUPPORTED
#ifdef ENTROPY_OPT_SUPPORTED

METHODDEF void
multi_eopt_ccontroller (compress_info_ptr cinfo)
{
  ERREXIT(cinfo->emethods, "Not implemented yet");
}

#endif /* ENTROPY_OPT_SUPPORTED */
#endif /* MULTISCAN_FILES_SUPPORTED */


/*
 * The method selection routine for compression pipeline controllers.
 */

GLOBAL void
jselcpipeline (compress_info_ptr cinfo)
{
  if (cinfo->interleave || cinfo->num_components == 1) {
    /* single scan needed */
#ifdef ENTROPY_OPT_SUPPORTED
    if (cinfo->optimize_coding)
      cinfo->methods->c_pipeline_controller = single_eopt_ccontroller;
    else
#endif
      cinfo->methods->c_pipeline_controller = single_ccontroller;
  } else {
    /* multiple scans needed */
#ifdef MULTISCAN_FILES_SUPPORTED
#ifdef ENTROPY_OPT_SUPPORTED
    if (cinfo->optimize_coding)
      cinfo->methods->c_pipeline_controller = multi_eopt_ccontroller;
    else
#endif
      cinfo->methods->c_pipeline_controller = multi_ccontroller;
#else
    ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled");
#endif
  }
}
