1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#if !defined(_FX_JPEG_TURBO_)
2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/*
3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * jcdctmgr.c
4e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *
5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Copyright (C) 1994-1996, Thomas G. Lane.
6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This file is part of the Independent JPEG Group's software.
7e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * For conditions of distribution and use, see the accompanying README file.
8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *
9e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This file contains the forward-DCT management logic.
10e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This code selects a particular DCT implementation to be used,
11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * and it performs related housekeeping chores including coefficient
12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * quantization.
13e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define JPEG_INTERNALS
16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "jinclude.h"
17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "jpeglib.h"
18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "jdct.h"		/* Private declarations for DCT subsystem */
19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Private subobject for this module */
22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtypedef struct {
24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  struct jpeg_forward_dct pub;	/* public fields */
25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  /* Pointer to the DCT routine actually in use */
27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  forward_DCT_method_ptr do_dct;
28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
29e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  /* The actual post-DCT divisors --- not identical to the quant table
30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov   * entries, because of scaling (especially for an unnormalized DCT).
31e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov   * Each table is given in normal array order.
32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov   */
33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  DCTELEM * divisors[NUM_QUANT_TBLS];
34e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef DCT_FLOAT_SUPPORTED
36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  /* Same as above for the floating-point case. */
37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  float_DCT_method_ptr do_float_dct;
38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
40e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} my_fdct_controller;
41e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
42e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtypedef my_fdct_controller * my_fdct_ptr;
43e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
44e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/*
46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Initialize for a processing pass.
47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Verify that all referenced Q-tables are present, and set up
48e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * the divisor table for each one.
49e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * In the current implementation, DCT of all components is done during
50e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * the first pass, even if only some components will be output in the
51e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * first scan.  Hence all components should be examined here.
52e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
53e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
54e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovMETHODDEF(void)
55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstart_pass_fdctmgr (j_compress_ptr cinfo)
56e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
57e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
58e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  int ci, qtblno, i;
59e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  jpeg_component_info *compptr;
60e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  JQUANT_TBL * qtbl;
61e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  DCTELEM * dtbl;
62e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
63e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov       ci++, compptr++) {
65e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    qtblno = compptr->quant_tbl_no;
66e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    /* Make sure specified quantization table is present */
67e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
68e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	cinfo->quant_tbl_ptrs[qtblno] == NULL)
69e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
70e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    qtbl = cinfo->quant_tbl_ptrs[qtblno];
71e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    /* Compute divisors for this quant table */
72e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    /* We may do this more than once for same table, but it's not a big deal */
73e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    switch (cinfo->dct_method) {
74e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef DCT_ISLOW_SUPPORTED
75e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    case JDCT_ISLOW:
76e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      /* For LL&M IDCT method, divisors are equal to raw quantization
77e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov       * coefficients multiplied by 8 (to counteract scaling).
78e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov       */
79e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      if (fdct->divisors[qtblno] == NULL) {
80e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	fdct->divisors[qtblno] = (DCTELEM *)
81e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
82e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				      DCTSIZE2 * SIZEOF(DCTELEM));
83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      }
84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      dtbl = fdct->divisors[qtblno];
85e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      for (i = 0; i < DCTSIZE2; i++) {
86e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
87e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      }
88e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      break;
89e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
90e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef DCT_IFAST_SUPPORTED
91e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    case JDCT_IFAST:
92e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      {
93e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	/* For AA&N IDCT method, divisors are equal to quantization
94e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
95e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 *   scalefactor[0] = 1
96e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
97e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * We apply a further scale factor of 8.
98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 */
99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define CONST_BITS 14
100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	static const INT16 aanscales[DCTSIZE2] = {
101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  /* precomputed values scaled up by 14 bits */
102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
104e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
107e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
108e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
109e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
110e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	};
111e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	SHIFT_TEMPS
112e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
113e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (fdct->divisors[qtblno] == NULL) {
114e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  fdct->divisors[qtblno] = (DCTELEM *)
115e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
116e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					DCTSIZE2 * SIZEOF(DCTELEM));
117e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
118e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	dtbl = fdct->divisors[qtblno];
119e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	for (i = 0; i < DCTSIZE2; i++) {
120e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  dtbl[i] = (DCTELEM)
121e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
122e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				  (INT32) aanscales[i]),
123e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		    CONST_BITS-3);
124e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
125e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      }
126e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      break;
127e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
128e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef DCT_FLOAT_SUPPORTED
129e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    case JDCT_FLOAT:
130e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      {
131e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	/* For float AA&N IDCT method, divisors are equal to quantization
132e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * coefficients scaled by scalefactor[row]*scalefactor[col], where
133e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 *   scalefactor[0] = 1
134e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
135e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * We apply a further scale factor of 8.
136e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * What's actually stored is 1/divisor so that the inner loop can
137e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * use a multiplication rather than a division.
138e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 */
139e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	FAST_FLOAT * fdtbl;
140e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	int row, col;
141e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	static const double aanscalefactor[DCTSIZE] = {
142e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  1.0, 1.387039845, 1.306562965, 1.175875602,
143e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  1.0, 0.785694958, 0.541196100, 0.275899379
144e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	};
145e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
146e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (fdct->float_divisors[qtblno] == NULL) {
147e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  fdct->float_divisors[qtblno] = (FAST_FLOAT *)
148e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
149e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov					DCTSIZE2 * SIZEOF(FAST_FLOAT));
150e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
151e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	fdtbl = fdct->float_divisors[qtblno];
152e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	i = 0;
153e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	for (row = 0; row < DCTSIZE; row++) {
154e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  for (col = 0; col < DCTSIZE; col++) {
155e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	    fdtbl[i] = (FAST_FLOAT)
156e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	      (1.0 / (((double) qtbl->quantval[i] *
157e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		       aanscalefactor[row] * aanscalefactor[col] * 8.0)));
158e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	    i++;
159e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  }
160e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
161e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      }
162e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      break;
163e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
164e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    default:
165e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      ERREXIT(cinfo, JERR_NOT_COMPILED);
166e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      break;
167e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
168e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  }
169e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
170e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
171e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
172e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/*
173e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Perform forward DCT on one or more blocks of a component.
174e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *
175e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * The input samples are taken from the sample_data[] array starting at
176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * position start_row/start_col, and moving to the right for any additional
177e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * blocks. The quantized coefficients are returned in coef_blocks[].
178e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
179e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
180e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovMETHODDEF(void)
181e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovforward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
182e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	     JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
183e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	     JDIMENSION start_row, JDIMENSION start_col,
184e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	     JDIMENSION num_blocks)
185e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* This version is used for integer DCT implementations. */
186e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
187e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  /* This routine is heavily used, so it's worth coding it tightly. */
188e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
189e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  forward_DCT_method_ptr do_dct = fdct->do_dct;
190e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
191e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  DCTELEM workspace[DCTSIZE2];	/* work area for FDCT subroutine */
192e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  JDIMENSION bi;
193e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
194e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  sample_data += start_row;	/* fold in the vertical offset once */
195e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
196e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
197e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    /* Load data into workspace, applying unsigned->signed conversion */
198e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    { register DCTELEM *workspaceptr;
199e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      register JSAMPROW elemptr;
200e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      register int elemr;
201e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
202e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      workspaceptr = workspace;
203e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      for (elemr = 0; elemr < DCTSIZE; elemr++) {
204e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	elemptr = sample_data[elemr] + start_col;
205e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#if DCTSIZE == 8		/* unroll the inner loop */
206e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
207e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
208e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
209e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
210e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
211e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
212e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
213e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
214e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#else
215e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	{ register int elemc;
216e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
217e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
218e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  }
219e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
220e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
221e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      }
222e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
223e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
224e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    /* Perform the DCT */
225e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    (*do_dct) (workspace);
226e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
227e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    /* Quantize/descale the coefficients, and store into coef_blocks[] */
228e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    { register DCTELEM temp, qval;
229e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      register int i;
230e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      register JCOEFPTR output_ptr = coef_blocks[bi];
231e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
232e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      for (i = 0; i < DCTSIZE2; i++) {
233e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	qval = divisors[i];
234e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	temp = workspace[i];
235e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	/* Divide the coefficient value by qval, ensuring proper rounding.
236e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * Since C does not specify the direction of rounding for negative
237e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * quotients, we have to force the dividend positive for portability.
238e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 *
239e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * In most files, at least half of the output values will be zero
240e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * (at default quantization settings, more like three-quarters...)
241e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * so we should ensure that this case is fast.  On many machines,
242e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * a comparison is enough cheaper than a divide to make a special test
243e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * a win.  Since both inputs will be nonnegative, we need only test
244e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * for a < b to discover whether a/b is 0.
245e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * If your machine's division is fast enough, define FAST_DIVIDE.
246e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 */
247e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FAST_DIVIDE
248e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define DIVIDE_BY(a,b)	a /= b
249e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#else
250e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0
251e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
252e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (temp < 0) {
253e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  temp = -temp;
254e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  temp += qval>>1;	/* for rounding */
255e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  DIVIDE_BY(temp, qval);
256e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  temp = -temp;
257e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	} else {
258e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  temp += qval>>1;	/* for rounding */
259e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  DIVIDE_BY(temp, qval);
260e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
261e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	output_ptr[i] = (JCOEF) temp;
262e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      }
263e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
264e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  }
265e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
266e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
267e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
268e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef DCT_FLOAT_SUPPORTED
269e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
270e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovMETHODDEF(void)
271e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovforward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
272e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		   JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
273e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		   JDIMENSION start_row, JDIMENSION start_col,
274e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		   JDIMENSION num_blocks)
275e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* This version is used for floating-point DCT implementations. */
276e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
277e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  /* This routine is heavily used, so it's worth coding it tightly. */
278e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
279e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  float_DCT_method_ptr do_dct = fdct->do_float_dct;
280e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
281e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
282e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  JDIMENSION bi;
283e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
284e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  sample_data += start_row;	/* fold in the vertical offset once */
285e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
286e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
287e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    /* Load data into workspace, applying unsigned->signed conversion */
288e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    { register FAST_FLOAT *workspaceptr;
289e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      register JSAMPROW elemptr;
290e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      register int elemr;
291e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
292e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      workspaceptr = workspace;
293e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      for (elemr = 0; elemr < DCTSIZE; elemr++) {
294e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	elemptr = sample_data[elemr] + start_col;
295e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#if DCTSIZE == 8		/* unroll the inner loop */
296e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
297e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
298e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
299e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
300e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
301e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
302e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
303e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
304e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#else
305e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	{ register int elemc;
306e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
307e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	    *workspaceptr++ = (FAST_FLOAT)
308e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	      (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
309e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	  }
310e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
311e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
312e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      }
313e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
314e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
315e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    /* Perform the DCT */
316e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    (*do_dct) (workspace);
317e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
318e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    /* Quantize/descale the coefficients, and store into coef_blocks[] */
319e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    { register FAST_FLOAT temp;
320e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      register int i;
321e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      register JCOEFPTR output_ptr = coef_blocks[bi];
322e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
323e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      for (i = 0; i < DCTSIZE2; i++) {
324e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	/* Apply the quantization and scaling factor */
325e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	temp = workspace[i] * divisors[i];
326e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	/* Round to nearest integer.
327e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * Since C does not specify the direction of rounding for negative
328e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * quotients, we have to force the dividend positive for portability.
329e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * The maximum coefficient size is +-16K (for 12-bit data), so this
330e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 * code should work for either 16-bit or 32-bit ints.
331e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	 */
332e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
333e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      }
334e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
335e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  }
336e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
337e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
338e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif /* DCT_FLOAT_SUPPORTED */
339e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
340e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
341e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/*
342e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Initialize FDCT manager.
343e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
344e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
345e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovGLOBAL(void)
346e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovjinit_forward_dct (j_compress_ptr cinfo)
347e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
348e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  my_fdct_ptr fdct;
349e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  int i;
350e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
351e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  fdct = (my_fdct_ptr)
352e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
353e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				SIZEOF(my_fdct_controller));
354e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  cinfo->fdct = (struct jpeg_forward_dct *) fdct;
355e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  fdct->pub.start_pass = start_pass_fdctmgr;
356e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
357e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  switch (cinfo->dct_method) {
358e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef DCT_ISLOW_SUPPORTED
359e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  case JDCT_ISLOW:
360e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    fdct->pub.forward_DCT = forward_DCT;
361e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    fdct->do_dct = jpeg_fdct_islow;
362e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    break;
363e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
364e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef DCT_IFAST_SUPPORTED
365e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  case JDCT_IFAST:
366e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    fdct->pub.forward_DCT = forward_DCT;
367e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    fdct->do_dct = jpeg_fdct_ifast;
368e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    break;
369e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
370e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef DCT_FLOAT_SUPPORTED
371e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  case JDCT_FLOAT:
372e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    fdct->pub.forward_DCT = forward_DCT_float;
373e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    fdct->do_float_dct = jpeg_fdct_float;
374e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    break;
375e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
376e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  default:
377e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    ERREXIT(cinfo, JERR_NOT_COMPILED);
378e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    break;
379e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  }
380e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
381e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  /* Mark divisor tables unallocated */
382e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  for (i = 0; i < NUM_QUANT_TBLS; i++) {
383e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    fdct->divisors[i] = NULL;
384e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef DCT_FLOAT_SUPPORTED
385e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    fdct->float_divisors[i] = NULL;
386e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
387e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  }
388e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
389e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
390e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif //_FX_JPEG_TURBO_
391