The Independent JPEG Group's JPEG software v6
diff --git a/jddctmgr.c b/jddctmgr.c
index 0dd7716..71215f1 100644
--- a/jddctmgr.c
+++ b/jddctmgr.c
@@ -1,14 +1,14 @@
 /*
  * jddctmgr.c
  *
- * Copyright (C) 1994, Thomas G. Lane.
+ * Copyright (C) 1994-1995, 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 pass setup.
+ * is executed per IDCT step, only during output pass setup.
  *
  * Note that the IDCT routines are responsible for performing coefficient
  * dequantization as well as the IDCT proper.  This module sets up the
@@ -21,30 +21,50 @@
 #include "jdct.h"		/* Private declarations for DCT subsystem */
 
 
+/*
+ * The decompressor input side (jdinput.c) saves away the appropriate
+ * quantization table for each component at the start of the first scan
+ * involving that component.  (This is necessary in order to correctly
+ * decode files that reuse Q-table slots.)
+ * When we are ready to make an output pass, the saved Q-table is converted
+ * to a multiplier table that will actually be used by the IDCT routine.
+ * The multiplier table contents are IDCT-method-dependent.  To support
+ * application changes in IDCT method between scans, we can remake the
+ * multiplier tables if necessary.
+ * In buffered-image mode, the first output pass may occur before any data
+ * has been seen for some components, and thus before their Q-tables have
+ * been saved away.  To handle this case, multiplier tables are preset
+ * to zeroes; the result of the IDCT will be a neutral gray level.
+ */
+
+
 /* Private subobject for this module */
 
 typedef struct {
   struct jpeg_inverse_dct pub;	/* public fields */
 
-  /* Record the IDCT method type actually selected for each component */
-  J_DCT_METHOD real_method[MAX_COMPONENTS];
+  /* This array contains the IDCT method code that each multiplier table
+   * is currently set up for, or -1 if it's not yet set up.
+   * The actual multiplier tables are pointed to by dct_table in the
+   * per-component comp_info structures.
+   */
+  int cur_method[MAX_COMPONENTS];
 } my_idct_controller;
 
 typedef my_idct_controller * my_idct_ptr;
 
 
-/* ZIG[i] is the zigzag-order position of the i'th element of a DCT block */
-/* read in natural order (left to right, top to bottom). */
-static const int ZIG[DCTSIZE2] = {
-     0,  1,  5,  6, 14, 15, 27, 28,
-     2,  4,  7, 13, 16, 26, 29, 42,
-     3,  8, 12, 17, 25, 30, 41, 43,
-     9, 11, 18, 24, 31, 40, 44, 53,
-    10, 19, 23, 32, 39, 45, 52, 54,
-    20, 22, 33, 38, 46, 51, 55, 60,
-    21, 34, 37, 47, 50, 56, 59, 61,
-    35, 36, 48, 49, 57, 58, 62, 63
-};
+/* Allocated multiplier tables: big enough for any supported variant */
+
+typedef union {
+  ISLOW_MULT_TYPE islow_array[DCTSIZE2];
+#ifdef DCT_IFAST_SUPPORTED
+  IFAST_MULT_TYPE ifast_array[DCTSIZE2];
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+  FLOAT_MULT_TYPE float_array[DCTSIZE2];
+#endif
+} multiplier_table;
 
 
 /* The current scaled-IDCT routines require ISLOW-style multiplier tables,
@@ -60,51 +80,92 @@
 
 
 /*
- * Initialize for an input scan.
- *
- * Verify that all referenced Q-tables are present, and set up
- * the multiplier table for each one.
- * With a multiple-scan JPEG file, this is called during each input scan,
- * NOT during the final output pass where the IDCT is actually done.
- * The purpose is to save away the current Q-table contents just in case
- * the encoder changes tables between scans.  This decoder will dequantize
- * any component using the Q-table which was current at the start of the
- * first scan using that component.
+ * Prepare for an output pass.
+ * Here we select the proper IDCT routine for each component and build
+ * a matching multiplier table.
  */
 
 METHODDEF void
-start_input_pass (j_decompress_ptr cinfo)
+start_pass (j_decompress_ptr cinfo)
 {
   my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
-  int ci, qtblno, i;
+  int ci, i;
   jpeg_component_info *compptr;
+  int method = 0;
+  inverse_DCT_method_ptr method_ptr = NULL;
   JQUANT_TBL * qtbl;
 
-  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
-    compptr = cinfo->cur_comp_info[ci];
-    qtblno = compptr->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);
-    qtbl = cinfo->quant_tbl_ptrs[qtblno];
-    /* Create multiplier table from quant table, unless we already did so. */
-    if (compptr->dct_table != NULL)
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++) {
+    /* Select the proper IDCT routine for this component's scaling */
+    switch (compptr->DCT_scaled_size) {
+#ifdef IDCT_SCALING_SUPPORTED
+    case 1:
+      method_ptr = jpeg_idct_1x1;
+      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
+      break;
+    case 2:
+      method_ptr = jpeg_idct_2x2;
+      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
+      break;
+    case 4:
+      method_ptr = jpeg_idct_4x4;
+      method = JDCT_ISLOW;	/* jidctred uses islow-style table */
+      break;
+#endif
+    case DCTSIZE:
+      switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+      case JDCT_ISLOW:
+	method_ptr = jpeg_idct_islow;
+	method = JDCT_ISLOW;
+	break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+      case JDCT_IFAST:
+	method_ptr = jpeg_idct_ifast;
+	method = JDCT_IFAST;
+	break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+      case JDCT_FLOAT:
+	method_ptr = jpeg_idct_float;
+	method = JDCT_FLOAT;
+	break;
+#endif
+      default:
+	ERREXIT(cinfo, JERR_NOT_COMPILED);
+	break;
+      }
+      break;
+    default:
+      ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
+      break;
+    }
+    idct->pub.inverse_DCT[ci] = method_ptr;
+    /* Create multiplier table from quant table.
+     * However, we can skip this if the component is uninteresting
+     * or if we already built the table.  Also, if no quant table
+     * has yet been saved for the component, we leave the
+     * multiplier table all-zero; we'll be reading zeroes from the
+     * coefficient controller's buffer anyway.
+     */
+    if (! compptr->component_needed || idct->cur_method[ci] == method)
       continue;
-    switch (idct->real_method[compptr->component_index]) {
+    qtbl = compptr->quant_table;
+    if (qtbl == NULL)		/* happens if no data yet for component */
+      continue;
+    idct->cur_method[ci] = method;
+    switch (method) {
 #ifdef PROVIDE_ISLOW_TABLES
     case JDCT_ISLOW:
       {
 	/* For LL&M IDCT method, multipliers are equal to raw quantization
 	 * coefficients, but are stored in natural order as ints.
 	 */
-	ISLOW_MULT_TYPE * ismtbl;
-	compptr->dct_table =
-	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				      DCTSIZE2 * SIZEOF(ISLOW_MULT_TYPE));
-	ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
+	ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
 	for (i = 0; i < DCTSIZE2; i++) {
-	  ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[ZIG[i]];
+	  ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[jpeg_zigzag_order[i]];
 	}
       }
       break;
@@ -119,7 +180,7 @@
 	 * For integer operation, the multiplier table is to be scaled by
 	 * IFAST_SCALE_BITS.  The multipliers are stored in natural order.
 	 */
-	IFAST_MULT_TYPE * ifmtbl;
+	IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
 #define CONST_BITS 14
 	static const INT16 aanscales[DCTSIZE2] = {
 	  /* precomputed values scaled up by 14 bits */
@@ -134,13 +195,9 @@
 	};
 	SHIFT_TEMPS
 
-	compptr->dct_table =
-	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				      DCTSIZE2 * SIZEOF(IFAST_MULT_TYPE));
-	ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
 	for (i = 0; i < DCTSIZE2; i++) {
 	  ifmtbl[i] = (IFAST_MULT_TYPE)
-	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[ZIG[i]],
+	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]],
 				  (INT32) aanscales[i]),
 		    CONST_BITS-IFAST_SCALE_BITS);
 	}
@@ -156,22 +213,18 @@
 	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
 	 * The multipliers are stored in natural order.
 	 */
-	FLOAT_MULT_TYPE * fmtbl;
+	FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
 	int row, col;
 	static const double aanscalefactor[DCTSIZE] = {
 	  1.0, 1.387039845, 1.306562965, 1.175875602,
 	  1.0, 0.785694958, 0.541196100, 0.275899379
 	};
 
-	compptr->dct_table =
-	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				      DCTSIZE2 * SIZEOF(FLOAT_MULT_TYPE));
-	fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
 	i = 0;
 	for (row = 0; row < DCTSIZE; row++) {
 	  for (col = 0; col < DCTSIZE; col++) {
 	    fmtbl[i] = (FLOAT_MULT_TYPE)
-	      ((double) qtbl->quantval[ZIG[i]] *
+	      ((double) qtbl->quantval[jpeg_zigzag_order[i]] *
 	       aanscalefactor[row] * aanscalefactor[col]);
 	    i++;
 	  }
@@ -188,32 +241,6 @@
 
 
 /*
- * Prepare for an output pass that will actually perform IDCTs.
- *
- * start_input_pass should already have been done for all components
- * of interest; we need only verify that this is true.
- * Note that uninteresting components are not required to have loaded tables.
- * This allows the master controller to stop before reading the whole file
- * if it has obtained the data for the interesting component(s).
- */
-
-METHODDEF void
-start_output_pass (j_decompress_ptr cinfo)
-{
-  jpeg_component_info *compptr;
-  int ci;
-
-  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
-       ci++, compptr++) {
-    if (! compptr->component_needed)
-      continue;
-    if (compptr->dct_table == NULL)
-      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, compptr->quant_tbl_no);
-  }
-}
-
-
-/*
  * Initialize IDCT manager.
  */
 
@@ -228,55 +255,16 @@
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
 				SIZEOF(my_idct_controller));
   cinfo->idct = (struct jpeg_inverse_dct *) idct;
-  idct->pub.start_input_pass = start_input_pass;
-  idct->pub.start_output_pass = start_output_pass;
+  idct->pub.start_pass = start_pass;
 
   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
        ci++, compptr++) {
-    compptr->dct_table = NULL;	/* initialize tables to "not prepared" */
-    switch (compptr->DCT_scaled_size) {
-#ifdef IDCT_SCALING_SUPPORTED
-    case 1:
-      idct->pub.inverse_DCT[ci] = jpeg_idct_1x1;
-      idct->real_method[ci] = JDCT_ISLOW; /* jidctred uses islow-style table */
-      break;
-    case 2:
-      idct->pub.inverse_DCT[ci] = jpeg_idct_2x2;
-      idct->real_method[ci] = JDCT_ISLOW; /* jidctred uses islow-style table */
-      break;
-    case 4:
-      idct->pub.inverse_DCT[ci] = jpeg_idct_4x4;
-      idct->real_method[ci] = JDCT_ISLOW; /* jidctred uses islow-style table */
-      break;
-#endif
-    case DCTSIZE:
-      switch (cinfo->dct_method) {
-#ifdef DCT_ISLOW_SUPPORTED
-      case JDCT_ISLOW:
-	idct->pub.inverse_DCT[ci] = jpeg_idct_islow;
-	idct->real_method[ci] = JDCT_ISLOW;
-	break;
-#endif
-#ifdef DCT_IFAST_SUPPORTED
-      case JDCT_IFAST:
-	idct->pub.inverse_DCT[ci] = jpeg_idct_ifast;
-	idct->real_method[ci] = JDCT_IFAST;
-	break;
-#endif
-#ifdef DCT_FLOAT_SUPPORTED
-      case JDCT_FLOAT:
-	idct->pub.inverse_DCT[ci] = jpeg_idct_float;
-	idct->real_method[ci] = JDCT_FLOAT;
-	break;
-#endif
-      default:
-	ERREXIT(cinfo, JERR_NOT_COMPILED);
-	break;
-      }
-      break;
-    default:
-      ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
-      break;
-    }
+    /* Allocate and pre-zero a multiplier table for each component */
+    compptr->dct_table =
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				  SIZEOF(multiplier_table));
+    MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
+    /* Mark multiplier table not yet set up for any method */
+    idct->cur_method[ci] = -1;
   }
 }