Blame gtkmm-osx/jpeg-6b/jcdctmgr.c

darco 56a656
/*
darco 56a656
 * jcdctmgr.c
darco 56a656
 *
darco 56a656
 * Copyright (C) 1994-1996, Thomas G. Lane.
darco 56a656
 * This file is part of the Independent JPEG Group's software.
darco 56a656
 * For conditions of distribution and use, see the accompanying README file.
darco 56a656
 *
darco 56a656
 * This file contains the forward-DCT management logic.
darco 56a656
 * This code selects a particular DCT implementation to be used,
darco 56a656
 * and it performs related housekeeping chores including coefficient
darco 56a656
 * quantization.
darco 56a656
 */
darco 56a656
darco 56a656
#define JPEG_INTERNALS
darco 56a656
#include "jinclude.h"
darco 56a656
#include "jpeglib.h"
darco 56a656
#include "jdct.h"		/* Private declarations for DCT subsystem */
darco 56a656
darco 56a656
darco 56a656
/* Private subobject for this module */
darco 56a656
darco 56a656
typedef struct {
darco 56a656
  struct jpeg_forward_dct pub;	/* public fields */
darco 56a656
darco 56a656
  /* Pointer to the DCT routine actually in use */
darco 56a656
  forward_DCT_method_ptr do_dct;
darco 56a656
darco 56a656
  /* The actual post-DCT divisors --- not identical to the quant table
darco 56a656
   * entries, because of scaling (especially for an unnormalized DCT).
darco 56a656
   * Each table is given in normal array order.
darco 56a656
   */
darco 56a656
  DCTELEM * divisors[NUM_QUANT_TBLS];
darco 56a656
darco 56a656
#ifdef DCT_FLOAT_SUPPORTED
darco 56a656
  /* Same as above for the floating-point case. */
darco 56a656
  float_DCT_method_ptr do_float_dct;
darco 56a656
  FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
darco 56a656
#endif
darco 56a656
} my_fdct_controller;
darco 56a656
darco 56a656
typedef my_fdct_controller * my_fdct_ptr;
darco 56a656
darco 56a656
darco 56a656
/*
darco 56a656
 * Initialize for a processing pass.
darco 56a656
 * Verify that all referenced Q-tables are present, and set up
darco 56a656
 * the divisor table for each one.
darco 56a656
 * In the current implementation, DCT of all components is done during
darco 56a656
 * the first pass, even if only some components will be output in the
darco 56a656
 * first scan.  Hence all components should be examined here.
darco 56a656
 */
darco 56a656
darco 56a656
METHODDEF(void)
darco 56a656
start_pass_fdctmgr (j_compress_ptr cinfo)
darco 56a656
{
darco 56a656
  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
darco 56a656
  int ci, qtblno, i;
darco 56a656
  jpeg_component_info *compptr;
darco 56a656
  JQUANT_TBL * qtbl;
darco 56a656
  DCTELEM * dtbl;
darco 56a656
darco 56a656
  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
darco 56a656
       ci++, compptr++) {
darco 56a656
    qtblno = compptr->quant_tbl_no;
darco 56a656
    /* Make sure specified quantization table is present */
darco 56a656
    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
darco 56a656
	cinfo->quant_tbl_ptrs[qtblno] == NULL)
darco 56a656
      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
darco 56a656
    qtbl = cinfo->quant_tbl_ptrs[qtblno];
darco 56a656
    /* Compute divisors for this quant table */
darco 56a656
    /* We may do this more than once for same table, but it's not a big deal */
darco 56a656
    switch (cinfo->dct_method) {
darco 56a656
#ifdef DCT_ISLOW_SUPPORTED
darco 56a656
    case JDCT_ISLOW:
darco 56a656
      /* For LL&M IDCT method, divisors are equal to raw quantization
darco 56a656
       * coefficients multiplied by 8 (to counteract scaling).
darco 56a656
       */
darco 56a656
      if (fdct->divisors[qtblno] == NULL) {
darco 56a656
	fdct->divisors[qtblno] = (DCTELEM *)
darco 56a656
	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
darco 56a656
				      DCTSIZE2 * SIZEOF(DCTELEM));
darco 56a656
      }
darco 56a656
      dtbl = fdct->divisors[qtblno];
darco 56a656
      for (i = 0; i < DCTSIZE2; i++) {
darco 56a656
	dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
darco 56a656
      }
darco 56a656
      break;
darco 56a656
#endif
darco 56a656
#ifdef DCT_IFAST_SUPPORTED
darco 56a656
    case JDCT_IFAST:
darco 56a656
      {
darco 56a656
	/* For AA&N IDCT method, divisors are equal to quantization
darco 56a656
	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
darco 56a656
	 *   scalefactor[0] = 1
darco 56a656
	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
darco 56a656
	 * We apply a further scale factor of 8.
darco 56a656
	 */
darco 56a656
#define CONST_BITS 14
darco 56a656
	static const INT16 aanscales[DCTSIZE2] = {
darco 56a656
	  /* precomputed values scaled up by 14 bits */
darco 56a656
	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
darco 56a656
	  22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
darco 56a656
	  21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
darco 56a656
	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
darco 56a656
	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
darco 56a656
	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
darco 56a656
	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
darco 56a656
	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
darco 56a656
	};
darco 56a656
	SHIFT_TEMPS
darco 56a656
darco 56a656
	if (fdct->divisors[qtblno] == NULL) {
darco 56a656
	  fdct->divisors[qtblno] = (DCTELEM *)
darco 56a656
	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
darco 56a656
					DCTSIZE2 * SIZEOF(DCTELEM));
darco 56a656
	}
darco 56a656
	dtbl = fdct->divisors[qtblno];
darco 56a656
	for (i = 0; i < DCTSIZE2; i++) {
darco 56a656
	  dtbl[i] = (DCTELEM)
darco 56a656
	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
darco 56a656
				  (INT32) aanscales[i]),
darco 56a656
		    CONST_BITS-3);
darco 56a656
	}
darco 56a656
      }
darco 56a656
      break;
darco 56a656
#endif
darco 56a656
#ifdef DCT_FLOAT_SUPPORTED
darco 56a656
    case JDCT_FLOAT:
darco 56a656
      {
darco 56a656
	/* For float AA&N IDCT method, divisors are equal to quantization
darco 56a656
	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
darco 56a656
	 *   scalefactor[0] = 1
darco 56a656
	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
darco 56a656
	 * We apply a further scale factor of 8.
darco 56a656
	 * What's actually stored is 1/divisor so that the inner loop can
darco 56a656
	 * use a multiplication rather than a division.
darco 56a656
	 */
darco 56a656
	FAST_FLOAT * fdtbl;
darco 56a656
	int row, col;
darco 56a656
	static const double aanscalefactor[DCTSIZE] = {
darco 56a656
	  1.0, 1.387039845, 1.306562965, 1.175875602,
darco 56a656
	  1.0, 0.785694958, 0.541196100, 0.275899379
darco 56a656
	};
darco 56a656
darco 56a656
	if (fdct->float_divisors[qtblno] == NULL) {
darco 56a656
	  fdct->float_divisors[qtblno] = (FAST_FLOAT *)
darco 56a656
	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
darco 56a656
					DCTSIZE2 * SIZEOF(FAST_FLOAT));
darco 56a656
	}
darco 56a656
	fdtbl = fdct->float_divisors[qtblno];
darco 56a656
	i = 0;
darco 56a656
	for (row = 0; row < DCTSIZE; row++) {
darco 56a656
	  for (col = 0; col < DCTSIZE; col++) {
darco 56a656
	    fdtbl[i] = (FAST_FLOAT)
darco 56a656
	      (1.0 / (((double) qtbl->quantval[i] *
darco 56a656
		       aanscalefactor[row] * aanscalefactor[col] * 8.0)));
darco 56a656
	    i++;
darco 56a656
	  }
darco 56a656
	}
darco 56a656
      }
darco 56a656
      break;
darco 56a656
#endif
darco 56a656
    default:
darco 56a656
      ERREXIT(cinfo, JERR_NOT_COMPILED);
darco 56a656
      break;
darco 56a656
    }
darco 56a656
  }
darco 56a656
}
darco 56a656
darco 56a656
darco 56a656
/*
darco 56a656
 * Perform forward DCT on one or more blocks of a component.
darco 56a656
 *
darco 56a656
 * The input samples are taken from the sample_data[] array starting at
darco 56a656
 * position start_row/start_col, and moving to the right for any additional
darco 56a656
 * blocks. The quantized coefficients are returned in coef_blocks[].
darco 56a656
 */
darco 56a656
darco 56a656
METHODDEF(void)
darco 56a656
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
darco 56a656
	     JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
darco 56a656
	     JDIMENSION start_row, JDIMENSION start_col,
darco 56a656
	     JDIMENSION num_blocks)
darco 56a656
/* This version is used for integer DCT implementations. */
darco 56a656
{
darco 56a656
  /* This routine is heavily used, so it's worth coding it tightly. */
darco 56a656
  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
darco 56a656
  forward_DCT_method_ptr do_dct = fdct->do_dct;
darco 56a656
  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
darco 56a656
  DCTELEM workspace[DCTSIZE2];	/* work area for FDCT subroutine */
darco 56a656
  JDIMENSION bi;
darco 56a656
darco 56a656
  sample_data += start_row;	/* fold in the vertical offset once */
darco 56a656
darco 56a656
  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
darco 56a656
    /* Load data into workspace, applying unsigned->signed conversion */
darco 56a656
    { register DCTELEM *workspaceptr;
darco 56a656
      register JSAMPROW elemptr;
darco 56a656
      register int elemr;
darco 56a656
darco 56a656
      workspaceptr = workspace;
darco 56a656
      for (elemr = 0; elemr < DCTSIZE; elemr++) {
darco 56a656
	elemptr = sample_data[elemr] + start_col;
darco 56a656
#if DCTSIZE == 8		/* unroll the inner loop */
darco 56a656
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
darco 56a656
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
darco 56a656
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
darco 56a656
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
darco 56a656
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
darco 56a656
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
darco 56a656
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
darco 56a656
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
darco 56a656
#else
darco 56a656
	{ register int elemc;
darco 56a656
	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
darco 56a656
	    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
darco 56a656
	  }
darco 56a656
	}
darco 56a656
#endif
darco 56a656
      }
darco 56a656
    }
darco 56a656
darco 56a656
    /* Perform the DCT */
darco 56a656
    (*do_dct) (workspace);
darco 56a656
darco 56a656
    /* Quantize/descale the coefficients, and store into coef_blocks[] */
darco 56a656
    { register DCTELEM temp, qval;
darco 56a656
      register int i;
darco 56a656
      register JCOEFPTR output_ptr = coef_blocks[bi];
darco 56a656
darco 56a656
      for (i = 0; i < DCTSIZE2; i++) {
darco 56a656
	qval = divisors[i];
darco 56a656
	temp = workspace[i];
darco 56a656
	/* Divide the coefficient value by qval, ensuring proper rounding.
darco 56a656
	 * Since C does not specify the direction of rounding for negative
darco 56a656
	 * quotients, we have to force the dividend positive for portability.
darco 56a656
	 *
darco 56a656
	 * In most files, at least half of the output values will be zero
darco 56a656
	 * (at default quantization settings, more like three-quarters...)
darco 56a656
	 * so we should ensure that this case is fast.  On many machines,
darco 56a656
	 * a comparison is enough cheaper than a divide to make a special test
darco 56a656
	 * a win.  Since both inputs will be nonnegative, we need only test
darco 56a656
	 * for a < b to discover whether a/b is 0.
darco 56a656
	 * If your machine's division is fast enough, define FAST_DIVIDE.
darco 56a656
	 */
darco 56a656
#ifdef FAST_DIVIDE
darco 56a656
#define DIVIDE_BY(a,b)	a /= b
darco 56a656
#else
darco 56a656
#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0
darco 56a656
#endif
darco 56a656
	if (temp < 0) {
darco 56a656
	  temp = -temp;
darco 56a656
	  temp += qval>>1;	/* for rounding */
darco 56a656
	  DIVIDE_BY(temp, qval);
darco 56a656
	  temp = -temp;
darco 56a656
	} else {
darco 56a656
	  temp += qval>>1;	/* for rounding */
darco 56a656
	  DIVIDE_BY(temp, qval);
darco 56a656
	}
darco 56a656
	output_ptr[i] = (JCOEF) temp;
darco 56a656
      }
darco 56a656
    }
darco 56a656
  }
darco 56a656
}
darco 56a656
darco 56a656
darco 56a656
#ifdef DCT_FLOAT_SUPPORTED
darco 56a656
darco 56a656
METHODDEF(void)
darco 56a656
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
darco 56a656
		   JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
darco 56a656
		   JDIMENSION start_row, JDIMENSION start_col,
darco 56a656
		   JDIMENSION num_blocks)
darco 56a656
/* This version is used for floating-point DCT implementations. */
darco 56a656
{
darco 56a656
  /* This routine is heavily used, so it's worth coding it tightly. */
darco 56a656
  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
darco 56a656
  float_DCT_method_ptr do_dct = fdct->do_float_dct;
darco 56a656
  FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
darco 56a656
  FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
darco 56a656
  JDIMENSION bi;
darco 56a656
darco 56a656
  sample_data += start_row;	/* fold in the vertical offset once */
darco 56a656
darco 56a656
  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
darco 56a656
    /* Load data into workspace, applying unsigned->signed conversion */
darco 56a656
    { register FAST_FLOAT *workspaceptr;
darco 56a656
      register JSAMPROW elemptr;
darco 56a656
      register int elemr;
darco 56a656
darco 56a656
      workspaceptr = workspace;
darco 56a656
      for (elemr = 0; elemr < DCTSIZE; elemr++) {
darco 56a656
	elemptr = sample_data[elemr] + start_col;
darco 56a656
#if DCTSIZE == 8		/* unroll the inner loop */
darco 56a656
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
darco 56a656
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
darco 56a656
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
darco 56a656
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
darco 56a656
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
darco 56a656
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
darco 56a656
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
darco 56a656
	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
darco 56a656
#else
darco 56a656
	{ register int elemc;
darco 56a656
	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
darco 56a656
	    *workspaceptr++ = (FAST_FLOAT)
darco 56a656
	      (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
darco 56a656
	  }
darco 56a656
	}
darco 56a656
#endif
darco 56a656
      }
darco 56a656
    }
darco 56a656
darco 56a656
    /* Perform the DCT */
darco 56a656
    (*do_dct) (workspace);
darco 56a656
darco 56a656
    /* Quantize/descale the coefficients, and store into coef_blocks[] */
darco 56a656
    { register FAST_FLOAT temp;
darco 56a656
      register int i;
darco 56a656
      register JCOEFPTR output_ptr = coef_blocks[bi];
darco 56a656
darco 56a656
      for (i = 0; i < DCTSIZE2; i++) {
darco 56a656
	/* Apply the quantization and scaling factor */
darco 56a656
	temp = workspace[i] * divisors[i];
darco 56a656
	/* Round to nearest integer.
darco 56a656
	 * Since C does not specify the direction of rounding for negative
darco 56a656
	 * quotients, we have to force the dividend positive for portability.
darco 56a656
	 * The maximum coefficient size is +-16K (for 12-bit data), so this
darco 56a656
	 * code should work for either 16-bit or 32-bit ints.
darco 56a656
	 */
darco 56a656
	output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
darco 56a656
      }
darco 56a656
    }
darco 56a656
  }
darco 56a656
}
darco 56a656
darco 56a656
#endif /* DCT_FLOAT_SUPPORTED */
darco 56a656
darco 56a656
darco 56a656
/*
darco 56a656
 * Initialize FDCT manager.
darco 56a656
 */
darco 56a656
darco 56a656
GLOBAL(void)
darco 56a656
jinit_forward_dct (j_compress_ptr cinfo)
darco 56a656
{
darco 56a656
  my_fdct_ptr fdct;
darco 56a656
  int i;
darco 56a656
darco 56a656
  fdct = (my_fdct_ptr)
darco 56a656
    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
darco 56a656
				SIZEOF(my_fdct_controller));
darco 56a656
  cinfo->fdct = (struct jpeg_forward_dct *) fdct;
darco 56a656
  fdct->pub.start_pass = start_pass_fdctmgr;
darco 56a656
darco 56a656
  switch (cinfo->dct_method) {
darco 56a656
#ifdef DCT_ISLOW_SUPPORTED
darco 56a656
  case JDCT_ISLOW:
darco 56a656
    fdct->pub.forward_DCT = forward_DCT;
darco 56a656
    fdct->do_dct = jpeg_fdct_islow;
darco 56a656
    break;
darco 56a656
#endif
darco 56a656
#ifdef DCT_IFAST_SUPPORTED
darco 56a656
  case JDCT_IFAST:
darco 56a656
    fdct->pub.forward_DCT = forward_DCT;
darco 56a656
    fdct->do_dct = jpeg_fdct_ifast;
darco 56a656
    break;
darco 56a656
#endif
darco 56a656
#ifdef DCT_FLOAT_SUPPORTED
darco 56a656
  case JDCT_FLOAT:
darco 56a656
    fdct->pub.forward_DCT = forward_DCT_float;
darco 56a656
    fdct->do_float_dct = jpeg_fdct_float;
darco 56a656
    break;
darco 56a656
#endif
darco 56a656
  default:
darco 56a656
    ERREXIT(cinfo, JERR_NOT_COMPILED);
darco 56a656
    break;
darco 56a656
  }
darco 56a656
darco 56a656
  /* Mark divisor tables unallocated */
darco 56a656
  for (i = 0; i < NUM_QUANT_TBLS; i++) {
darco 56a656
    fdct->divisors[i] = NULL;
darco 56a656
#ifdef DCT_FLOAT_SUPPORTED
darco 56a656
    fdct->float_divisors[i] = NULL;
darco 56a656
#endif
darco 56a656
  }
darco 56a656
}