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