media/libjpeg/jcdctmgr.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * jcdctmgr.c
michael@0 3 *
michael@0 4 * This file was part of the Independent JPEG Group's software:
michael@0 5 * Copyright (C) 1994-1996, Thomas G. Lane.
michael@0 6 * libjpeg-turbo Modifications:
michael@0 7 * Copyright (C) 1999-2006, MIYASAKA Masaru.
michael@0 8 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
michael@0 9 * Copyright (C) 2011 D. R. Commander
michael@0 10 * For conditions of distribution and use, see the accompanying README file.
michael@0 11 *
michael@0 12 * This file contains the forward-DCT management logic.
michael@0 13 * This code selects a particular DCT implementation to be used,
michael@0 14 * and it performs related housekeeping chores including coefficient
michael@0 15 * quantization.
michael@0 16 */
michael@0 17
michael@0 18 #define JPEG_INTERNALS
michael@0 19 #include "jinclude.h"
michael@0 20 #include "jpeglib.h"
michael@0 21 #include "jdct.h" /* Private declarations for DCT subsystem */
michael@0 22 #include "jsimddct.h"
michael@0 23
michael@0 24
michael@0 25 /* Private subobject for this module */
michael@0 26
michael@0 27 typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
michael@0 28 typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
michael@0 29
michael@0 30 typedef JMETHOD(void, convsamp_method_ptr,
michael@0 31 (JSAMPARRAY sample_data, JDIMENSION start_col,
michael@0 32 DCTELEM * workspace));
michael@0 33 typedef JMETHOD(void, float_convsamp_method_ptr,
michael@0 34 (JSAMPARRAY sample_data, JDIMENSION start_col,
michael@0 35 FAST_FLOAT *workspace));
michael@0 36
michael@0 37 typedef JMETHOD(void, quantize_method_ptr,
michael@0 38 (JCOEFPTR coef_block, DCTELEM * divisors,
michael@0 39 DCTELEM * workspace));
michael@0 40 typedef JMETHOD(void, float_quantize_method_ptr,
michael@0 41 (JCOEFPTR coef_block, FAST_FLOAT * divisors,
michael@0 42 FAST_FLOAT * workspace));
michael@0 43
michael@0 44 METHODDEF(void) quantize (JCOEFPTR, DCTELEM *, DCTELEM *);
michael@0 45
michael@0 46 typedef struct {
michael@0 47 struct jpeg_forward_dct pub; /* public fields */
michael@0 48
michael@0 49 /* Pointer to the DCT routine actually in use */
michael@0 50 forward_DCT_method_ptr dct;
michael@0 51 convsamp_method_ptr convsamp;
michael@0 52 quantize_method_ptr quantize;
michael@0 53
michael@0 54 /* The actual post-DCT divisors --- not identical to the quant table
michael@0 55 * entries, because of scaling (especially for an unnormalized DCT).
michael@0 56 * Each table is given in normal array order.
michael@0 57 */
michael@0 58 DCTELEM * divisors[NUM_QUANT_TBLS];
michael@0 59
michael@0 60 /* work area for FDCT subroutine */
michael@0 61 DCTELEM * workspace;
michael@0 62
michael@0 63 #ifdef DCT_FLOAT_SUPPORTED
michael@0 64 /* Same as above for the floating-point case. */
michael@0 65 float_DCT_method_ptr float_dct;
michael@0 66 float_convsamp_method_ptr float_convsamp;
michael@0 67 float_quantize_method_ptr float_quantize;
michael@0 68 FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
michael@0 69 FAST_FLOAT * float_workspace;
michael@0 70 #endif
michael@0 71 } my_fdct_controller;
michael@0 72
michael@0 73 typedef my_fdct_controller * my_fdct_ptr;
michael@0 74
michael@0 75
michael@0 76 /*
michael@0 77 * Find the highest bit in an integer through binary search.
michael@0 78 */
michael@0 79 LOCAL(int)
michael@0 80 flss (UINT16 val)
michael@0 81 {
michael@0 82 int bit;
michael@0 83
michael@0 84 bit = 16;
michael@0 85
michael@0 86 if (!val)
michael@0 87 return 0;
michael@0 88
michael@0 89 if (!(val & 0xff00)) {
michael@0 90 bit -= 8;
michael@0 91 val <<= 8;
michael@0 92 }
michael@0 93 if (!(val & 0xf000)) {
michael@0 94 bit -= 4;
michael@0 95 val <<= 4;
michael@0 96 }
michael@0 97 if (!(val & 0xc000)) {
michael@0 98 bit -= 2;
michael@0 99 val <<= 2;
michael@0 100 }
michael@0 101 if (!(val & 0x8000)) {
michael@0 102 bit -= 1;
michael@0 103 val <<= 1;
michael@0 104 }
michael@0 105
michael@0 106 return bit;
michael@0 107 }
michael@0 108
michael@0 109 /*
michael@0 110 * Compute values to do a division using reciprocal.
michael@0 111 *
michael@0 112 * This implementation is based on an algorithm described in
michael@0 113 * "How to optimize for the Pentium family of microprocessors"
michael@0 114 * (http://www.agner.org/assem/).
michael@0 115 * More information about the basic algorithm can be found in
michael@0 116 * the paper "Integer Division Using Reciprocals" by Robert Alverson.
michael@0 117 *
michael@0 118 * The basic idea is to replace x/d by x * d^-1. In order to store
michael@0 119 * d^-1 with enough precision we shift it left a few places. It turns
michael@0 120 * out that this algoright gives just enough precision, and also fits
michael@0 121 * into DCTELEM:
michael@0 122 *
michael@0 123 * b = (the number of significant bits in divisor) - 1
michael@0 124 * r = (word size) + b
michael@0 125 * f = 2^r / divisor
michael@0 126 *
michael@0 127 * f will not be an integer for most cases, so we need to compensate
michael@0 128 * for the rounding error introduced:
michael@0 129 *
michael@0 130 * no fractional part:
michael@0 131 *
michael@0 132 * result = input >> r
michael@0 133 *
michael@0 134 * fractional part of f < 0.5:
michael@0 135 *
michael@0 136 * round f down to nearest integer
michael@0 137 * result = ((input + 1) * f) >> r
michael@0 138 *
michael@0 139 * fractional part of f > 0.5:
michael@0 140 *
michael@0 141 * round f up to nearest integer
michael@0 142 * result = (input * f) >> r
michael@0 143 *
michael@0 144 * This is the original algorithm that gives truncated results. But we
michael@0 145 * want properly rounded results, so we replace "input" with
michael@0 146 * "input + divisor/2".
michael@0 147 *
michael@0 148 * In order to allow SIMD implementations we also tweak the values to
michael@0 149 * allow the same calculation to be made at all times:
michael@0 150 *
michael@0 151 * dctbl[0] = f rounded to nearest integer
michael@0 152 * dctbl[1] = divisor / 2 (+ 1 if fractional part of f < 0.5)
michael@0 153 * dctbl[2] = 1 << ((word size) * 2 - r)
michael@0 154 * dctbl[3] = r - (word size)
michael@0 155 *
michael@0 156 * dctbl[2] is for stupid instruction sets where the shift operation
michael@0 157 * isn't member wise (e.g. MMX).
michael@0 158 *
michael@0 159 * The reason dctbl[2] and dctbl[3] reduce the shift with (word size)
michael@0 160 * is that most SIMD implementations have a "multiply and store top
michael@0 161 * half" operation.
michael@0 162 *
michael@0 163 * Lastly, we store each of the values in their own table instead
michael@0 164 * of in a consecutive manner, yet again in order to allow SIMD
michael@0 165 * routines.
michael@0 166 */
michael@0 167 LOCAL(int)
michael@0 168 compute_reciprocal (UINT16 divisor, DCTELEM * dtbl)
michael@0 169 {
michael@0 170 UDCTELEM2 fq, fr;
michael@0 171 UDCTELEM c;
michael@0 172 int b, r;
michael@0 173
michael@0 174 b = flss(divisor) - 1;
michael@0 175 r = sizeof(DCTELEM) * 8 + b;
michael@0 176
michael@0 177 fq = ((UDCTELEM2)1 << r) / divisor;
michael@0 178 fr = ((UDCTELEM2)1 << r) % divisor;
michael@0 179
michael@0 180 c = divisor / 2; /* for rounding */
michael@0 181
michael@0 182 if (fr == 0) { /* divisor is power of two */
michael@0 183 /* fq will be one bit too large to fit in DCTELEM, so adjust */
michael@0 184 fq >>= 1;
michael@0 185 r--;
michael@0 186 } else if (fr <= (divisor / 2U)) { /* fractional part is < 0.5 */
michael@0 187 c++;
michael@0 188 } else { /* fractional part is > 0.5 */
michael@0 189 fq++;
michael@0 190 }
michael@0 191
michael@0 192 dtbl[DCTSIZE2 * 0] = (DCTELEM) fq; /* reciprocal */
michael@0 193 dtbl[DCTSIZE2 * 1] = (DCTELEM) c; /* correction + roundfactor */
michael@0 194 dtbl[DCTSIZE2 * 2] = (DCTELEM) (1 << (sizeof(DCTELEM)*8*2 - r)); /* scale */
michael@0 195 dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */
michael@0 196
michael@0 197 if(r <= 16) return 0;
michael@0 198 else return 1;
michael@0 199 }
michael@0 200
michael@0 201 /*
michael@0 202 * Initialize for a processing pass.
michael@0 203 * Verify that all referenced Q-tables are present, and set up
michael@0 204 * the divisor table for each one.
michael@0 205 * In the current implementation, DCT of all components is done during
michael@0 206 * the first pass, even if only some components will be output in the
michael@0 207 * first scan. Hence all components should be examined here.
michael@0 208 */
michael@0 209
michael@0 210 METHODDEF(void)
michael@0 211 start_pass_fdctmgr (j_compress_ptr cinfo)
michael@0 212 {
michael@0 213 my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
michael@0 214 int ci, qtblno, i;
michael@0 215 jpeg_component_info *compptr;
michael@0 216 JQUANT_TBL * qtbl;
michael@0 217 DCTELEM * dtbl;
michael@0 218
michael@0 219 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
michael@0 220 ci++, compptr++) {
michael@0 221 qtblno = compptr->quant_tbl_no;
michael@0 222 /* Make sure specified quantization table is present */
michael@0 223 if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
michael@0 224 cinfo->quant_tbl_ptrs[qtblno] == NULL)
michael@0 225 ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
michael@0 226 qtbl = cinfo->quant_tbl_ptrs[qtblno];
michael@0 227 /* Compute divisors for this quant table */
michael@0 228 /* We may do this more than once for same table, but it's not a big deal */
michael@0 229 switch (cinfo->dct_method) {
michael@0 230 #ifdef DCT_ISLOW_SUPPORTED
michael@0 231 case JDCT_ISLOW:
michael@0 232 /* For LL&M IDCT method, divisors are equal to raw quantization
michael@0 233 * coefficients multiplied by 8 (to counteract scaling).
michael@0 234 */
michael@0 235 if (fdct->divisors[qtblno] == NULL) {
michael@0 236 fdct->divisors[qtblno] = (DCTELEM *)
michael@0 237 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
michael@0 238 (DCTSIZE2 * 4) * SIZEOF(DCTELEM));
michael@0 239 }
michael@0 240 dtbl = fdct->divisors[qtblno];
michael@0 241 for (i = 0; i < DCTSIZE2; i++) {
michael@0 242 if(!compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i])
michael@0 243 && fdct->quantize == jsimd_quantize)
michael@0 244 fdct->quantize = quantize;
michael@0 245 }
michael@0 246 break;
michael@0 247 #endif
michael@0 248 #ifdef DCT_IFAST_SUPPORTED
michael@0 249 case JDCT_IFAST:
michael@0 250 {
michael@0 251 /* For AA&N IDCT method, divisors are equal to quantization
michael@0 252 * coefficients scaled by scalefactor[row]*scalefactor[col], where
michael@0 253 * scalefactor[0] = 1
michael@0 254 * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
michael@0 255 * We apply a further scale factor of 8.
michael@0 256 */
michael@0 257 #define CONST_BITS 14
michael@0 258 static const INT16 aanscales[DCTSIZE2] = {
michael@0 259 /* precomputed values scaled up by 14 bits */
michael@0 260 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
michael@0 261 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
michael@0 262 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
michael@0 263 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
michael@0 264 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
michael@0 265 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
michael@0 266 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
michael@0 267 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
michael@0 268 };
michael@0 269 SHIFT_TEMPS
michael@0 270
michael@0 271 if (fdct->divisors[qtblno] == NULL) {
michael@0 272 fdct->divisors[qtblno] = (DCTELEM *)
michael@0 273 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
michael@0 274 (DCTSIZE2 * 4) * SIZEOF(DCTELEM));
michael@0 275 }
michael@0 276 dtbl = fdct->divisors[qtblno];
michael@0 277 for (i = 0; i < DCTSIZE2; i++) {
michael@0 278 if(!compute_reciprocal(
michael@0 279 DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
michael@0 280 (INT32) aanscales[i]),
michael@0 281 CONST_BITS-3), &dtbl[i])
michael@0 282 && fdct->quantize == jsimd_quantize)
michael@0 283 fdct->quantize = quantize;
michael@0 284 }
michael@0 285 }
michael@0 286 break;
michael@0 287 #endif
michael@0 288 #ifdef DCT_FLOAT_SUPPORTED
michael@0 289 case JDCT_FLOAT:
michael@0 290 {
michael@0 291 /* For float AA&N IDCT method, divisors are equal to quantization
michael@0 292 * coefficients scaled by scalefactor[row]*scalefactor[col], where
michael@0 293 * scalefactor[0] = 1
michael@0 294 * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
michael@0 295 * We apply a further scale factor of 8.
michael@0 296 * What's actually stored is 1/divisor so that the inner loop can
michael@0 297 * use a multiplication rather than a division.
michael@0 298 */
michael@0 299 FAST_FLOAT * fdtbl;
michael@0 300 int row, col;
michael@0 301 static const double aanscalefactor[DCTSIZE] = {
michael@0 302 1.0, 1.387039845, 1.306562965, 1.175875602,
michael@0 303 1.0, 0.785694958, 0.541196100, 0.275899379
michael@0 304 };
michael@0 305
michael@0 306 if (fdct->float_divisors[qtblno] == NULL) {
michael@0 307 fdct->float_divisors[qtblno] = (FAST_FLOAT *)
michael@0 308 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
michael@0 309 DCTSIZE2 * SIZEOF(FAST_FLOAT));
michael@0 310 }
michael@0 311 fdtbl = fdct->float_divisors[qtblno];
michael@0 312 i = 0;
michael@0 313 for (row = 0; row < DCTSIZE; row++) {
michael@0 314 for (col = 0; col < DCTSIZE; col++) {
michael@0 315 fdtbl[i] = (FAST_FLOAT)
michael@0 316 (1.0 / (((double) qtbl->quantval[i] *
michael@0 317 aanscalefactor[row] * aanscalefactor[col] * 8.0)));
michael@0 318 i++;
michael@0 319 }
michael@0 320 }
michael@0 321 }
michael@0 322 break;
michael@0 323 #endif
michael@0 324 default:
michael@0 325 ERREXIT(cinfo, JERR_NOT_COMPILED);
michael@0 326 break;
michael@0 327 }
michael@0 328 }
michael@0 329 }
michael@0 330
michael@0 331
michael@0 332 /*
michael@0 333 * Load data into workspace, applying unsigned->signed conversion.
michael@0 334 */
michael@0 335
michael@0 336 METHODDEF(void)
michael@0 337 convsamp (JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM * workspace)
michael@0 338 {
michael@0 339 register DCTELEM *workspaceptr;
michael@0 340 register JSAMPROW elemptr;
michael@0 341 register int elemr;
michael@0 342
michael@0 343 workspaceptr = workspace;
michael@0 344 for (elemr = 0; elemr < DCTSIZE; elemr++) {
michael@0 345 elemptr = sample_data[elemr] + start_col;
michael@0 346
michael@0 347 #if DCTSIZE == 8 /* unroll the inner loop */
michael@0 348 *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
michael@0 349 *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
michael@0 350 *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
michael@0 351 *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
michael@0 352 *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
michael@0 353 *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
michael@0 354 *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
michael@0 355 *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
michael@0 356 #else
michael@0 357 {
michael@0 358 register int elemc;
michael@0 359 for (elemc = DCTSIZE; elemc > 0; elemc--)
michael@0 360 *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
michael@0 361 }
michael@0 362 #endif
michael@0 363 }
michael@0 364 }
michael@0 365
michael@0 366
michael@0 367 /*
michael@0 368 * Quantize/descale the coefficients, and store into coef_blocks[].
michael@0 369 */
michael@0 370
michael@0 371 METHODDEF(void)
michael@0 372 quantize (JCOEFPTR coef_block, DCTELEM * divisors, DCTELEM * workspace)
michael@0 373 {
michael@0 374 int i;
michael@0 375 DCTELEM temp;
michael@0 376 UDCTELEM recip, corr, shift;
michael@0 377 UDCTELEM2 product;
michael@0 378 JCOEFPTR output_ptr = coef_block;
michael@0 379
michael@0 380 for (i = 0; i < DCTSIZE2; i++) {
michael@0 381 temp = workspace[i];
michael@0 382 recip = divisors[i + DCTSIZE2 * 0];
michael@0 383 corr = divisors[i + DCTSIZE2 * 1];
michael@0 384 shift = divisors[i + DCTSIZE2 * 3];
michael@0 385
michael@0 386 if (temp < 0) {
michael@0 387 temp = -temp;
michael@0 388 product = (UDCTELEM2)(temp + corr) * recip;
michael@0 389 product >>= shift + sizeof(DCTELEM)*8;
michael@0 390 temp = product;
michael@0 391 temp = -temp;
michael@0 392 } else {
michael@0 393 product = (UDCTELEM2)(temp + corr) * recip;
michael@0 394 product >>= shift + sizeof(DCTELEM)*8;
michael@0 395 temp = product;
michael@0 396 }
michael@0 397
michael@0 398 output_ptr[i] = (JCOEF) temp;
michael@0 399 }
michael@0 400 }
michael@0 401
michael@0 402
michael@0 403 /*
michael@0 404 * Perform forward DCT on one or more blocks of a component.
michael@0 405 *
michael@0 406 * The input samples are taken from the sample_data[] array starting at
michael@0 407 * position start_row/start_col, and moving to the right for any additional
michael@0 408 * blocks. The quantized coefficients are returned in coef_blocks[].
michael@0 409 */
michael@0 410
michael@0 411 METHODDEF(void)
michael@0 412 forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
michael@0 413 JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
michael@0 414 JDIMENSION start_row, JDIMENSION start_col,
michael@0 415 JDIMENSION num_blocks)
michael@0 416 /* This version is used for integer DCT implementations. */
michael@0 417 {
michael@0 418 /* This routine is heavily used, so it's worth coding it tightly. */
michael@0 419 my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
michael@0 420 DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
michael@0 421 DCTELEM * workspace;
michael@0 422 JDIMENSION bi;
michael@0 423
michael@0 424 /* Make sure the compiler doesn't look up these every pass */
michael@0 425 forward_DCT_method_ptr do_dct = fdct->dct;
michael@0 426 convsamp_method_ptr do_convsamp = fdct->convsamp;
michael@0 427 quantize_method_ptr do_quantize = fdct->quantize;
michael@0 428 workspace = fdct->workspace;
michael@0 429
michael@0 430 sample_data += start_row; /* fold in the vertical offset once */
michael@0 431
michael@0 432 for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
michael@0 433 /* Load data into workspace, applying unsigned->signed conversion */
michael@0 434 (*do_convsamp) (sample_data, start_col, workspace);
michael@0 435
michael@0 436 /* Perform the DCT */
michael@0 437 (*do_dct) (workspace);
michael@0 438
michael@0 439 /* Quantize/descale the coefficients, and store into coef_blocks[] */
michael@0 440 (*do_quantize) (coef_blocks[bi], divisors, workspace);
michael@0 441 }
michael@0 442 }
michael@0 443
michael@0 444
michael@0 445 #ifdef DCT_FLOAT_SUPPORTED
michael@0 446
michael@0 447
michael@0 448 METHODDEF(void)
michael@0 449 convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col, FAST_FLOAT * workspace)
michael@0 450 {
michael@0 451 register FAST_FLOAT *workspaceptr;
michael@0 452 register JSAMPROW elemptr;
michael@0 453 register int elemr;
michael@0 454
michael@0 455 workspaceptr = workspace;
michael@0 456 for (elemr = 0; elemr < DCTSIZE; elemr++) {
michael@0 457 elemptr = sample_data[elemr] + start_col;
michael@0 458 #if DCTSIZE == 8 /* unroll the inner loop */
michael@0 459 *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
michael@0 460 *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
michael@0 461 *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
michael@0 462 *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
michael@0 463 *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
michael@0 464 *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
michael@0 465 *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
michael@0 466 *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
michael@0 467 #else
michael@0 468 {
michael@0 469 register int elemc;
michael@0 470 for (elemc = DCTSIZE; elemc > 0; elemc--)
michael@0 471 *workspaceptr++ = (FAST_FLOAT)
michael@0 472 (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
michael@0 473 }
michael@0 474 #endif
michael@0 475 }
michael@0 476 }
michael@0 477
michael@0 478
michael@0 479 METHODDEF(void)
michael@0 480 quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors, FAST_FLOAT * workspace)
michael@0 481 {
michael@0 482 register FAST_FLOAT temp;
michael@0 483 register int i;
michael@0 484 register JCOEFPTR output_ptr = coef_block;
michael@0 485
michael@0 486 for (i = 0; i < DCTSIZE2; i++) {
michael@0 487 /* Apply the quantization and scaling factor */
michael@0 488 temp = workspace[i] * divisors[i];
michael@0 489
michael@0 490 /* Round to nearest integer.
michael@0 491 * Since C does not specify the direction of rounding for negative
michael@0 492 * quotients, we have to force the dividend positive for portability.
michael@0 493 * The maximum coefficient size is +-16K (for 12-bit data), so this
michael@0 494 * code should work for either 16-bit or 32-bit ints.
michael@0 495 */
michael@0 496 output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
michael@0 497 }
michael@0 498 }
michael@0 499
michael@0 500
michael@0 501 METHODDEF(void)
michael@0 502 forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
michael@0 503 JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
michael@0 504 JDIMENSION start_row, JDIMENSION start_col,
michael@0 505 JDIMENSION num_blocks)
michael@0 506 /* This version is used for floating-point DCT implementations. */
michael@0 507 {
michael@0 508 /* This routine is heavily used, so it's worth coding it tightly. */
michael@0 509 my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
michael@0 510 FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
michael@0 511 FAST_FLOAT * workspace;
michael@0 512 JDIMENSION bi;
michael@0 513
michael@0 514
michael@0 515 /* Make sure the compiler doesn't look up these every pass */
michael@0 516 float_DCT_method_ptr do_dct = fdct->float_dct;
michael@0 517 float_convsamp_method_ptr do_convsamp = fdct->float_convsamp;
michael@0 518 float_quantize_method_ptr do_quantize = fdct->float_quantize;
michael@0 519 workspace = fdct->float_workspace;
michael@0 520
michael@0 521 sample_data += start_row; /* fold in the vertical offset once */
michael@0 522
michael@0 523 for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
michael@0 524 /* Load data into workspace, applying unsigned->signed conversion */
michael@0 525 (*do_convsamp) (sample_data, start_col, workspace);
michael@0 526
michael@0 527 /* Perform the DCT */
michael@0 528 (*do_dct) (workspace);
michael@0 529
michael@0 530 /* Quantize/descale the coefficients, and store into coef_blocks[] */
michael@0 531 (*do_quantize) (coef_blocks[bi], divisors, workspace);
michael@0 532 }
michael@0 533 }
michael@0 534
michael@0 535 #endif /* DCT_FLOAT_SUPPORTED */
michael@0 536
michael@0 537
michael@0 538 /*
michael@0 539 * Initialize FDCT manager.
michael@0 540 */
michael@0 541
michael@0 542 GLOBAL(void)
michael@0 543 jinit_forward_dct (j_compress_ptr cinfo)
michael@0 544 {
michael@0 545 my_fdct_ptr fdct;
michael@0 546 int i;
michael@0 547
michael@0 548 fdct = (my_fdct_ptr)
michael@0 549 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
michael@0 550 SIZEOF(my_fdct_controller));
michael@0 551 cinfo->fdct = (struct jpeg_forward_dct *) fdct;
michael@0 552 fdct->pub.start_pass = start_pass_fdctmgr;
michael@0 553
michael@0 554 /* First determine the DCT... */
michael@0 555 switch (cinfo->dct_method) {
michael@0 556 #ifdef DCT_ISLOW_SUPPORTED
michael@0 557 case JDCT_ISLOW:
michael@0 558 fdct->pub.forward_DCT = forward_DCT;
michael@0 559 if (jsimd_can_fdct_islow())
michael@0 560 fdct->dct = jsimd_fdct_islow;
michael@0 561 else
michael@0 562 fdct->dct = jpeg_fdct_islow;
michael@0 563 break;
michael@0 564 #endif
michael@0 565 #ifdef DCT_IFAST_SUPPORTED
michael@0 566 case JDCT_IFAST:
michael@0 567 fdct->pub.forward_DCT = forward_DCT;
michael@0 568 if (jsimd_can_fdct_ifast())
michael@0 569 fdct->dct = jsimd_fdct_ifast;
michael@0 570 else
michael@0 571 fdct->dct = jpeg_fdct_ifast;
michael@0 572 break;
michael@0 573 #endif
michael@0 574 #ifdef DCT_FLOAT_SUPPORTED
michael@0 575 case JDCT_FLOAT:
michael@0 576 fdct->pub.forward_DCT = forward_DCT_float;
michael@0 577 if (jsimd_can_fdct_float())
michael@0 578 fdct->float_dct = jsimd_fdct_float;
michael@0 579 else
michael@0 580 fdct->float_dct = jpeg_fdct_float;
michael@0 581 break;
michael@0 582 #endif
michael@0 583 default:
michael@0 584 ERREXIT(cinfo, JERR_NOT_COMPILED);
michael@0 585 break;
michael@0 586 }
michael@0 587
michael@0 588 /* ...then the supporting stages. */
michael@0 589 switch (cinfo->dct_method) {
michael@0 590 #ifdef DCT_ISLOW_SUPPORTED
michael@0 591 case JDCT_ISLOW:
michael@0 592 #endif
michael@0 593 #ifdef DCT_IFAST_SUPPORTED
michael@0 594 case JDCT_IFAST:
michael@0 595 #endif
michael@0 596 #if defined(DCT_ISLOW_SUPPORTED) || defined(DCT_IFAST_SUPPORTED)
michael@0 597 if (jsimd_can_convsamp())
michael@0 598 fdct->convsamp = jsimd_convsamp;
michael@0 599 else
michael@0 600 fdct->convsamp = convsamp;
michael@0 601 if (jsimd_can_quantize())
michael@0 602 fdct->quantize = jsimd_quantize;
michael@0 603 else
michael@0 604 fdct->quantize = quantize;
michael@0 605 break;
michael@0 606 #endif
michael@0 607 #ifdef DCT_FLOAT_SUPPORTED
michael@0 608 case JDCT_FLOAT:
michael@0 609 if (jsimd_can_convsamp_float())
michael@0 610 fdct->float_convsamp = jsimd_convsamp_float;
michael@0 611 else
michael@0 612 fdct->float_convsamp = convsamp_float;
michael@0 613 if (jsimd_can_quantize_float())
michael@0 614 fdct->float_quantize = jsimd_quantize_float;
michael@0 615 else
michael@0 616 fdct->float_quantize = quantize_float;
michael@0 617 break;
michael@0 618 #endif
michael@0 619 default:
michael@0 620 ERREXIT(cinfo, JERR_NOT_COMPILED);
michael@0 621 break;
michael@0 622 }
michael@0 623
michael@0 624 /* Allocate workspace memory */
michael@0 625 #ifdef DCT_FLOAT_SUPPORTED
michael@0 626 if (cinfo->dct_method == JDCT_FLOAT)
michael@0 627 fdct->float_workspace = (FAST_FLOAT *)
michael@0 628 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
michael@0 629 SIZEOF(FAST_FLOAT) * DCTSIZE2);
michael@0 630 else
michael@0 631 #endif
michael@0 632 fdct->workspace = (DCTELEM *)
michael@0 633 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
michael@0 634 SIZEOF(DCTELEM) * DCTSIZE2);
michael@0 635
michael@0 636 /* Mark divisor tables unallocated */
michael@0 637 for (i = 0; i < NUM_QUANT_TBLS; i++) {
michael@0 638 fdct->divisors[i] = NULL;
michael@0 639 #ifdef DCT_FLOAT_SUPPORTED
michael@0 640 fdct->float_divisors[i] = NULL;
michael@0 641 #endif
michael@0 642 }
michael@0 643 }

mercurial