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