/*
 * jddctmgr.c
 *
 * Copyright (C) 1994, 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 the inverse-DCT management logic.
 * This code selects a particular IDCT implementation to be used,
 * and it performs related housekeeping chores.  No code in this file
 * is executed per IDCT step, only during setup.
 */

#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jdct.h"		/* Private declarations for DCT subsystem */


/* Private subobject for this module */

typedef struct {
  struct jpeg_inverse_dct pub;	/* public fields */
  /* no private fields for now */
} my_idct_controller;

typedef my_idct_controller * my_idct_ptr;


/*
 * Initialize for a processing pass.
 * Verify that all referenced Q-tables are present, and set up
 * the multiplier tables for each one.
 */

METHODDEF void
start_pass (j_decompress_ptr cinfo)
{
  int ci, qtblno, i;
  JDQUANT_TBL * qtbl;

  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    qtblno = cinfo->cur_comp_info[ci]->quant_tbl_no;
    /* Make sure specified quantization table is present */
    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
	cinfo->quant_tbl_ptrs[qtblno] == NULL)
      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
    /* Compute multipliers for this quant table */
    /* We may do this more than once for same table, but it's not a big deal */
    qtbl = (JDQUANT_TBL *) cinfo->quant_tbl_ptrs[qtblno];
    for (i = 0; i < DCTSIZE2; i++) {
      /* For now, multipliers are same as raw quantization coefficients */
      qtbl->multipliers[i] = (MULTIPLIER) qtbl->pub.quantval[i];
    }
  }
}


/*
 * Initialize IDCT manager.
 */

GLOBAL void
jinit_inverse_dct (j_decompress_ptr cinfo)
{
  my_idct_ptr idct;
  int ci;
  jpeg_component_info * compptr;

  idct = (my_idct_ptr)
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				SIZEOF(my_idct_controller));
  cinfo->idct = (struct jpeg_inverse_dct *) idct;

  idct->pub.start_pass = start_pass;
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
       ci++, compptr++) {
    switch (compptr->DCT_scaled_size) {
#ifdef IDCT_SCALING_SUPPORTED
    case 1:
      idct->pub.inverse_DCT[ci] = jpeg_idct_1x1;
      break;
    case 2:
      idct->pub.inverse_DCT[ci] = jpeg_idct_2x2;
      break;
    case 4:
      idct->pub.inverse_DCT[ci] = jpeg_idct_4x4;
      break;
#endif
    case DCTSIZE:
      idct->pub.inverse_DCT[ci] = jpeg_idct_llm;
      break;
    default:
      ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
      break;
    }
  }
}
