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