Bug Summary

File:root/firefox-clang/media/libjpeg/src/wrapper/../jcdctmgr.c
Warning:line 109, column 5
Value stored to 'val' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name jcdctmgr-8.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libjpeg/src/wrapper -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libjpeg/src/wrapper -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_WITH_SIMD=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/media/libjpeg/src/wrapper -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libjpeg/src/wrapper -I /root/firefox-clang/media/libjpeg -I /root/firefox-clang/media/libjpeg/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c /root/firefox-clang/media/libjpeg/src/wrapper/jcdctmgr-8.c
1/*
2 * jcdctmgr.c
3 *
4 * This file was part of the Independent JPEG Group's software:
5 * Copyright (C) 1994-1996, Thomas G. Lane.
6 * libjpeg-turbo Modifications:
7 * Copyright (C) 1999-2006, MIYASAKA Masaru.
8 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
9 * Copyright (C) 2011, 2014-2015, 2022, 2024, 2026, D. R. Commander.
10 * For conditions of distribution and use, see the accompanying README.ijg
11 * file.
12 *
13 * This file contains the forward-DCT management logic.
14 * This code selects a particular DCT implementation to be used,
15 * and it performs related housekeeping chores including coefficient
16 * quantization.
17 */
18
19#define JPEG_INTERNALS
20#include "jinclude.h"
21#include "jpeglib.h"
22#include "jdct.h" /* Private declarations for DCT subsystem */
23#include "jsimddct.h"
24
25
26#if defined(DCT_ISLOW_SUPPORTED) || defined(DCT_IFAST_SUPPORTED) || \
27 defined(DCT_FLOAT_SUPPORTED)
28
29/* Private subobject for this module */
30
31typedef void (*forward_DCT_method_ptr) (DCTELEM *data);
32typedef void (*float_DCT_method_ptr) (FAST_FLOATfloat *data);
33
34typedef void (*convsamp_method_ptr) (_JSAMPARRAYJSAMPARRAY sample_data,
35 JDIMENSION start_col,
36 DCTELEM *workspace);
37typedef void (*float_convsamp_method_ptr) (_JSAMPARRAYJSAMPARRAY sample_data,
38 JDIMENSION start_col,
39 FAST_FLOATfloat *workspace);
40
41typedef void (*quantize_method_ptr) (JCOEFPTR coef_block, DCTELEM *divisors,
42 DCTELEM *workspace);
43typedef void (*float_quantize_method_ptr) (JCOEFPTR coef_block,
44 FAST_FLOATfloat *divisors,
45 FAST_FLOATfloat *workspace);
46
47METHODDEF(void)static void quantize(JCOEFPTR, DCTELEM *, DCTELEM *);
48
49typedef struct {
50 struct jpeg_forward_dct pub; /* public fields */
51
52 /* Pointer to the DCT routine actually in use */
53 forward_DCT_method_ptr dct;
54 convsamp_method_ptr convsamp;
55 quantize_method_ptr quantize;
56
57 /* The actual post-DCT divisors --- not identical to the quant table
58 * entries, because of scaling (especially for an unnormalized DCT).
59 * Each table is given in normal array order.
60 */
61 DCTELEM *divisors[NUM_QUANT_TBLS4];
62
63 /* work area for FDCT subroutine */
64 DCTELEM *workspace;
65
66#ifdef DCT_FLOAT_SUPPORTED
67 /* Same as above for the floating-point case. */
68 float_DCT_method_ptr float_dct;
69 float_convsamp_method_ptr float_convsamp;
70 float_quantize_method_ptr float_quantize;
71 FAST_FLOATfloat *float_divisors[NUM_QUANT_TBLS4];
72 FAST_FLOATfloat *float_workspace;
73#endif
74} my_fdct_controller;
75
76typedef my_fdct_controller *my_fdct_ptr;
77
78
79#if BITS_IN_JSAMPLE8 == 8
80
81/*
82 * Find the highest bit in an integer through binary search.
83 */
84
85LOCAL(int)static int
86flss(UINT16 val)
87{
88 int bit;
89
90 bit = 16;
91
92 if (!val)
93 return 0;
94
95 if (!(val & 0xff00)) {
96 bit -= 8;
97 val <<= 8;
98 }
99 if (!(val & 0xf000)) {
100 bit -= 4;
101 val <<= 4;
102 }
103 if (!(val & 0xc000)) {
104 bit -= 2;
105 val <<= 2;
106 }
107 if (!(val & 0x8000)) {
108 bit -= 1;
109 val <<= 1;
Value stored to 'val' is never read
110 }
111
112 return bit;
113}
114
115
116/*
117 * Compute values to do a division using reciprocal.
118 *
119 * This implementation is based on an algorithm described in
120 * "Optimizing subroutines in assembly language:
121 * An optimization guide for x86 platforms" (https://agner.org/optimize).
122 * More information about the basic algorithm can be found in
123 * the paper "Integer Division Using Reciprocals" by Robert Alverson.
124 *
125 * The basic idea is to replace x/d by x * d^-1. In order to store
126 * d^-1 with enough precision we shift it left a few places. It turns
127 * out that this algoright gives just enough precision, and also fits
128 * into DCTELEM:
129 *
130 * b = (the number of significant bits in divisor) - 1
131 * r = (word size) + b
132 * f = 2^r / divisor
133 *
134 * f will not be an integer for most cases, so we need to compensate
135 * for the rounding error introduced:
136 *
137 * no fractional part:
138 *
139 * result = input >> r
140 *
141 * fractional part of f < 0.5:
142 *
143 * round f down to nearest integer
144 * result = ((input + 1) * f) >> r
145 *
146 * fractional part of f > 0.5:
147 *
148 * round f up to nearest integer
149 * result = (input * f) >> r
150 *
151 * This is the original algorithm that gives truncated results. But we
152 * want properly rounded results, so we replace "input" with
153 * "input + divisor/2".
154 *
155 * In order to allow SIMD implementations we also tweak the values to
156 * allow the same calculation to be made at all times:
157 *
158 * dctbl[0] = f rounded to nearest integer
159 * dctbl[1] = divisor / 2 (+ 1 if fractional part of f < 0.5)
160 * dctbl[2] = 1 << ((word size) * 2 - r)
161 * dctbl[3] = r - (word size)
162 *
163 * dctbl[2] is for stupid instruction sets where the shift operation
164 * isn't member wise (e.g. MMX).
165 *
166 * The reason dctbl[2] and dctbl[3] reduce the shift with (word size)
167 * is that most SIMD implementations have a "multiply and store top
168 * half" operation.
169 *
170 * Lastly, we store each of the values in their own table instead
171 * of in a consecutive manner, yet again in order to allow SIMD
172 * routines.
173 */
174
175LOCAL(int)static int
176compute_reciprocal(UINT16 divisor, DCTELEM *dtbl)
177{
178 UDCTELEM2 fq, fr;
179 UDCTELEM c;
180 int b, r;
181
182 if (divisor <= 1) {
183 /* divisor == 1 means unquantized, so these reciprocal/correction/shift
184 * values will cause the C quantization algorithm to act like the
185 * identity function. Since only the C quantization algorithm is used in
186 * these cases, the scale value is irrelevant.
187 *
188 * divisor == 0 can never happen in a normal program, because
189 * jpeg_add_quant_table() clamps values < 1. However, a program could
190 * abuse the API by manually modifying the exposed quantization table just
191 * before calling jpeg_start_compress(). Thus, we effectively clamp
192 * values < 1 here as well, to avoid dividing by 0.
193 */
194 dtbl[DCTSIZE264 * 0] = (DCTELEM)1; /* reciprocal */
195 dtbl[DCTSIZE264 * 1] = (DCTELEM)0; /* correction */
196 dtbl[DCTSIZE264 * 2] = (DCTELEM)1; /* scale */
197 dtbl[DCTSIZE264 * 3] = -(DCTELEM)(sizeof(DCTELEM) * 8); /* shift */
198 return 0;
199 }
200
201 b = flss(divisor) - 1;
202 r = sizeof(DCTELEM) * 8 + b;
203
204 fq = ((UDCTELEM2)1 << r) / divisor;
205 fr = ((UDCTELEM2)1 << r) % divisor;
206
207 c = divisor / 2; /* for rounding */
208
209 if (fr == 0) { /* divisor is power of two */
210 /* fq will be one bit too large to fit in DCTELEM, so adjust */
211 fq >>= 1;
212 r--;
213 } else if (fr <= (divisor / 2U)) { /* fractional part is < 0.5 */
214 c++;
215 } else { /* fractional part is > 0.5 */
216 fq++;
217 }
218
219 dtbl[DCTSIZE264 * 0] = (DCTELEM)fq; /* reciprocal */
220 dtbl[DCTSIZE264 * 1] = (DCTELEM)c; /* correction + roundfactor */
221#ifdef WITH_SIMD1
222 dtbl[DCTSIZE264 * 2] = (DCTELEM)(1 << (sizeof(DCTELEM) * 8 * 2 - r)); /* scale */
223#else
224 dtbl[DCTSIZE264 * 2] = 1;
225#endif
226 dtbl[DCTSIZE264 * 3] = (DCTELEM)r - sizeof(DCTELEM) * 8; /* shift */
227
228 if (r <= 16) return 0;
229 else return 1;
230}
231
232#endif
233
234
235/*
236 * Initialize for a processing pass.
237 * Verify that all referenced Q-tables are present, and set up
238 * the divisor table for each one.
239 * In the current implementation, DCT of all components is done during
240 * the first pass, even if only some components will be output in the
241 * first scan. Hence all components should be examined here.
242 */
243
244METHODDEF(void)static void
245start_pass_fdctmgr(j_compress_ptr cinfo)
246{
247 my_fdct_ptr fdct = (my_fdct_ptr)cinfo->fdct;
248 int ci, qtblno, i;
249 jpeg_component_info *compptr;
250 JQUANT_TBL *qtbl;
251 DCTELEM *dtbl;
252
253 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
254 ci++, compptr++) {
255 qtblno = compptr->quant_tbl_no;
256 /* Make sure specified quantization table is present */
257 if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS4 ||
258 cinfo->quant_tbl_ptrs[qtblno] == NULL((void*)0))
259 ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno)((cinfo)->err->msg_code = (JERR_NO_QUANT_TABLE), (cinfo
)->err->msg_parm.i[0] = (qtblno), (*(cinfo)->err->
error_exit) ((j_common_ptr)(cinfo)))
;
260 qtbl = cinfo->quant_tbl_ptrs[qtblno];
261 /* Compute divisors for this quant table */
262 /* We may do this more than once for same table, but it's not a big deal */
263 switch (cinfo->dct_method) {
264#ifdef DCT_ISLOW_SUPPORTED
265 case JDCT_ISLOW:
266 /* For LL&M IDCT method, divisors are equal to raw quantization
267 * coefficients multiplied by 8 (to counteract scaling).
268 */
269 if (fdct->divisors[qtblno] == NULL((void*)0)) {
270 fdct->divisors[qtblno] = (DCTELEM *)
271 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE1,
272 (DCTSIZE264 * 4) * sizeof(DCTELEM));
273 }
274 dtbl = fdct->divisors[qtblno];
275 for (i = 0; i < DCTSIZE264; i++) {
276#if BITS_IN_JSAMPLE8 == 8
277#ifdef WITH_SIMD1
278 if (!compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]) &&
279 fdct->quantize == jsimd_quantize)
280 fdct->quantize = quantize;
281#else
282 compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]);
283#endif
284#else
285 dtbl[i] = ((DCTELEM)qtbl->quantval[i]) << 3;
286#endif
287 }
288 break;
289#endif
290#ifdef DCT_IFAST_SUPPORTED
291 case JDCT_IFAST:
292 {
293 /* For AA&N IDCT method, divisors are equal to quantization
294 * coefficients scaled by scalefactor[row]*scalefactor[col], where
295 * scalefactor[0] = 1
296 * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
297 * We apply a further scale factor of 8.
298 */
299#define CONST_BITS14 14
300 static const INT16 aanscales[DCTSIZE264] = {
301 /* precomputed values scaled up by 14 bits */
302 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
303 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
304 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
305 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
306 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
307 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
308 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
309 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
310 };
311 SHIFT_TEMPS
312
313 if (fdct->divisors[qtblno] == NULL((void*)0)) {
314 fdct->divisors[qtblno] = (DCTELEM *)
315 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE1,
316 (DCTSIZE264 * 4) * sizeof(DCTELEM));
317 }
318 dtbl = fdct->divisors[qtblno];
319 for (i = 0; i < DCTSIZE264; i++) {
320#if BITS_IN_JSAMPLE8 == 8
321#ifdef WITH_SIMD1
322 if (!compute_reciprocal(
323 DESCALE(MULTIPLY16V16((JLONG)qtbl->quantval[i],((((((JLONG)qtbl->quantval[i]) * ((JLONG)aanscales[i]))) +
(((JLONG)1) << ((14 - 3) - 1))) >> (14 - 3))
324 (JLONG)aanscales[i]),((((((JLONG)qtbl->quantval[i]) * ((JLONG)aanscales[i]))) +
(((JLONG)1) << ((14 - 3) - 1))) >> (14 - 3))
325 CONST_BITS - 3)((((((JLONG)qtbl->quantval[i]) * ((JLONG)aanscales[i]))) +
(((JLONG)1) << ((14 - 3) - 1))) >> (14 - 3))
, &dtbl[i]) &&
326 fdct->quantize == jsimd_quantize)
327 fdct->quantize = quantize;
328#else
329 compute_reciprocal(
330 DESCALE(MULTIPLY16V16((JLONG)qtbl->quantval[i],((((((JLONG)qtbl->quantval[i]) * ((JLONG)aanscales[i]))) +
(((JLONG)1) << ((14 -3) - 1))) >> (14 -3))
331 (JLONG)aanscales[i]),((((((JLONG)qtbl->quantval[i]) * ((JLONG)aanscales[i]))) +
(((JLONG)1) << ((14 -3) - 1))) >> (14 -3))
332 CONST_BITS-3)((((((JLONG)qtbl->quantval[i]) * ((JLONG)aanscales[i]))) +
(((JLONG)1) << ((14 -3) - 1))) >> (14 -3))
, &dtbl[i]);
333#endif
334#else
335 dtbl[i] = (DCTELEM)
336 DESCALE(MULTIPLY16V16((JLONG)qtbl->quantval[i],((((((JLONG)qtbl->quantval[i]) * ((JLONG)aanscales[i]))) +
(((JLONG)1) << ((14 - 3) - 1))) >> (14 - 3))
337 (JLONG)aanscales[i]),((((((JLONG)qtbl->quantval[i]) * ((JLONG)aanscales[i]))) +
(((JLONG)1) << ((14 - 3) - 1))) >> (14 - 3))
338 CONST_BITS - 3)((((((JLONG)qtbl->quantval[i]) * ((JLONG)aanscales[i]))) +
(((JLONG)1) << ((14 - 3) - 1))) >> (14 - 3))
;
339#endif
340 }
341 }
342 break;
343#endif
344#ifdef DCT_FLOAT_SUPPORTED
345 case JDCT_FLOAT:
346 {
347 /* For float AA&N IDCT method, divisors are equal to quantization
348 * coefficients scaled by scalefactor[row]*scalefactor[col], where
349 * scalefactor[0] = 1
350 * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
351 * We apply a further scale factor of 8.
352 * What's actually stored is 1/divisor so that the inner loop can
353 * use a multiplication rather than a division.
354 */
355 FAST_FLOATfloat *fdtbl;
356 int row, col;
357 static const double aanscalefactor[DCTSIZE8] = {
358 1.0, 1.387039845, 1.306562965, 1.175875602,
359 1.0, 0.785694958, 0.541196100, 0.275899379
360 };
361
362 if (fdct->float_divisors[qtblno] == NULL((void*)0)) {
363 fdct->float_divisors[qtblno] = (FAST_FLOATfloat *)
364 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE1,
365 DCTSIZE264 * sizeof(FAST_FLOATfloat));
366 }
367 fdtbl = fdct->float_divisors[qtblno];
368 i = 0;
369 for (row = 0; row < DCTSIZE8; row++) {
370 for (col = 0; col < DCTSIZE8; col++) {
371 fdtbl[i] = (FAST_FLOATfloat)
372 (1.0 / (((double)qtbl->quantval[i] *
373 aanscalefactor[row] * aanscalefactor[col] * 8.0)));
374 i++;
375 }
376 }
377 }
378 break;
379#endif
380 default:
381 ERREXIT(cinfo, JERR_NOT_COMPILED)((cinfo)->err->msg_code = (JERR_NOT_COMPILED), (*(cinfo
)->err->error_exit) ((j_common_ptr)(cinfo)))
;
382 break;
383 }
384 }
385}
386
387
388/*
389 * Load data into workspace, applying unsigned->signed conversion.
390 */
391
392METHODDEF(void)static void
393convsamp(_JSAMPARRAYJSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM *workspace)
394{
395 register DCTELEM *workspaceptr;
396 register _JSAMPROWJSAMPROW elemptr;
397 register int elemr;
398
399 workspaceptr = workspace;
400 for (elemr = 0; elemr < DCTSIZE8; elemr++) {
401 elemptr = sample_data[elemr] + start_col;
402
403#if DCTSIZE8 == 8 /* unroll the inner loop */
404 *workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE128;
405 *workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE128;
406 *workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE128;
407 *workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE128;
408 *workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE128;
409 *workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE128;
410 *workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE128;
411 *workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE128;
412#else
413 {
414 register int elemc;
415 for (elemc = DCTSIZE8; elemc > 0; elemc--)
416 *workspaceptr++ = (*elemptr++) - _CENTERJSAMPLE128;
417 }
418#endif
419 }
420}
421
422
423/*
424 * Quantize/descale the coefficients, and store into coef_blocks[].
425 */
426
427METHODDEF(void)static void
428quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
429{
430 int i;
431 DCTELEM temp;
432 JCOEFPTR output_ptr = coef_block;
433
434#if BITS_IN_JSAMPLE8 == 8
435
436 UDCTELEM recip, corr;
437 int shift;
438 UDCTELEM2 product;
439
440 for (i = 0; i < DCTSIZE264; i++) {
441 temp = workspace[i];
442 recip = divisors[i + DCTSIZE264 * 0];
443 corr = divisors[i + DCTSIZE264 * 1];
444 shift = divisors[i + DCTSIZE264 * 3];
445
446 if (temp < 0) {
447 temp = -temp;
448 product = (UDCTELEM2)(temp + corr) * recip;
449 product >>= shift + sizeof(DCTELEM) * 8;
450 temp = (DCTELEM)product;
451 temp = -temp;
452 } else {
453 product = (UDCTELEM2)(temp + corr) * recip;
454 product >>= shift + sizeof(DCTELEM) * 8;
455 temp = (DCTELEM)product;
456 }
457 output_ptr[i] = (JCOEF)temp;
458 }
459
460#else
461
462 register DCTELEM qval;
463
464 for (i = 0; i < DCTSIZE264; i++) {
465 qval = divisors[i];
466 temp = workspace[i];
467 /* Divide the coefficient value by qval, ensuring proper rounding.
468 * Since C does not specify the direction of rounding for negative
469 * quotients, we have to force the dividend positive for portability.
470 *
471 * In most files, at least half of the output values will be zero
472 * (at default quantization settings, more like three-quarters...)
473 * so we should ensure that this case is fast. On many machines,
474 * a comparison is enough cheaper than a divide to make a special test
475 * a win. Since both inputs will be nonnegative, we need only test
476 * for a < b to discover whether a/b is 0.
477 * If your machine's division is fast enough, define FAST_DIVIDE.
478 */
479#ifdef FAST_DIVIDE
480#define DIVIDE_BY(a, b) a /= b
481#else
482#define DIVIDE_BY(a, b) if (a >= b) a /= b; else a = 0
483#endif
484 if (temp < 0) {
485 temp = -temp;
486 temp += qval >> 1; /* for rounding */
487 DIVIDE_BY(temp, qval);
488 temp = -temp;
489 } else {
490 temp += qval >> 1; /* for rounding */
491 DIVIDE_BY(temp, qval);
492 }
493 output_ptr[i] = (JCOEF)temp;
494 }
495
496#endif
497
498}
499
500
501/*
502 * Perform forward DCT on one or more blocks of a component.
503 *
504 * The input samples are taken from the sample_data[] array starting at
505 * position start_row/start_col, and moving to the right for any additional
506 * blocks. The quantized coefficients are returned in coef_blocks[].
507 */
508
509METHODDEF(void)static void
510forward_DCT(j_compress_ptr cinfo, jpeg_component_info *compptr,
511 _JSAMPARRAYJSAMPARRAY sample_data, JBLOCKROW coef_blocks,
512 JDIMENSION start_row, JDIMENSION start_col, JDIMENSION num_blocks)
513/* This version is used for integer DCT implementations. */
514{
515 /* This routine is heavily used, so it's worth coding it tightly. */
516 my_fdct_ptr fdct = (my_fdct_ptr)cinfo->fdct;
517 DCTELEM *divisors = fdct->divisors[compptr->quant_tbl_no];
518 DCTELEM *workspace;
519 JDIMENSION bi;
520
521 /* Make sure the compiler doesn't look up these every pass */
522 forward_DCT_method_ptr do_dct = fdct->dct;
523 convsamp_method_ptr do_convsamp = fdct->convsamp;
524 quantize_method_ptr do_quantize = fdct->quantize;
525 workspace = fdct->workspace;
526
527 sample_data += start_row; /* fold in the vertical offset once */
528
529 for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE8) {
530 /* Load data into workspace, applying unsigned->signed conversion */
531 (*do_convsamp) (sample_data, start_col, workspace);
532
533 /* Perform the DCT */
534 (*do_dct) (workspace);
535
536 /* Quantize/descale the coefficients, and store into coef_blocks[] */
537 (*do_quantize) (coef_blocks[bi], divisors, workspace);
538 }
539}
540
541
542#ifdef DCT_FLOAT_SUPPORTED
543
544METHODDEF(void)static void
545convsamp_float(_JSAMPARRAYJSAMPARRAY sample_data, JDIMENSION start_col,
546 FAST_FLOATfloat *workspace)
547{
548 register FAST_FLOATfloat *workspaceptr;
549 register _JSAMPROWJSAMPROW elemptr;
550 register int elemr;
551
552 workspaceptr = workspace;
553 for (elemr = 0; elemr < DCTSIZE8; elemr++) {
554 elemptr = sample_data[elemr] + start_col;
555#if DCTSIZE8 == 8 /* unroll the inner loop */
556 *workspaceptr++ = (FAST_FLOATfloat)((*elemptr++) - _CENTERJSAMPLE128);
557 *workspaceptr++ = (FAST_FLOATfloat)((*elemptr++) - _CENTERJSAMPLE128);
558 *workspaceptr++ = (FAST_FLOATfloat)((*elemptr++) - _CENTERJSAMPLE128);
559 *workspaceptr++ = (FAST_FLOATfloat)((*elemptr++) - _CENTERJSAMPLE128);
560 *workspaceptr++ = (FAST_FLOATfloat)((*elemptr++) - _CENTERJSAMPLE128);
561 *workspaceptr++ = (FAST_FLOATfloat)((*elemptr++) - _CENTERJSAMPLE128);
562 *workspaceptr++ = (FAST_FLOATfloat)((*elemptr++) - _CENTERJSAMPLE128);
563 *workspaceptr++ = (FAST_FLOATfloat)((*elemptr++) - _CENTERJSAMPLE128);
564#else
565 {
566 register int elemc;
567 for (elemc = DCTSIZE8; elemc > 0; elemc--)
568 *workspaceptr++ = (FAST_FLOATfloat)((*elemptr++) - _CENTERJSAMPLE128);
569 }
570#endif
571 }
572}
573
574
575METHODDEF(void)static void
576quantize_float(JCOEFPTR coef_block, FAST_FLOATfloat *divisors,
577 FAST_FLOATfloat *workspace)
578{
579 register FAST_FLOATfloat temp;
580 register int i;
581 register JCOEFPTR output_ptr = coef_block;
582
583 for (i = 0; i < DCTSIZE264; i++) {
584 /* Apply the quantization and scaling factor */
585 temp = workspace[i] * divisors[i];
586
587 /* Round to nearest integer.
588 * Since C does not specify the direction of rounding for negative
589 * quotients, we have to force the dividend positive for portability.
590 * The maximum coefficient size is +-16K (for 12-bit data), so this
591 * code should work for either 16-bit or 32-bit ints.
592 */
593 output_ptr[i] = (JCOEF)((int)(temp + (FAST_FLOATfloat)16384.5) - 16384);
594 }
595}
596
597
598METHODDEF(void)static void
599forward_DCT_float(j_compress_ptr cinfo, jpeg_component_info *compptr,
600 _JSAMPARRAYJSAMPARRAY sample_data, JBLOCKROW coef_blocks,
601 JDIMENSION start_row, JDIMENSION start_col,
602 JDIMENSION num_blocks)
603/* This version is used for floating-point DCT implementations. */
604{
605 /* This routine is heavily used, so it's worth coding it tightly. */
606 my_fdct_ptr fdct = (my_fdct_ptr)cinfo->fdct;
607 FAST_FLOATfloat *divisors = fdct->float_divisors[compptr->quant_tbl_no];
608 FAST_FLOATfloat *workspace;
609 JDIMENSION bi;
610
611
612 /* Make sure the compiler doesn't look up these every pass */
613 float_DCT_method_ptr do_dct = fdct->float_dct;
614 float_convsamp_method_ptr do_convsamp = fdct->float_convsamp;
615 float_quantize_method_ptr do_quantize = fdct->float_quantize;
616 workspace = fdct->float_workspace;
617
618 sample_data += start_row; /* fold in the vertical offset once */
619
620 for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE8) {
621 /* Load data into workspace, applying unsigned->signed conversion */
622 (*do_convsamp) (sample_data, start_col, workspace);
623
624 /* Perform the DCT */
625 (*do_dct) (workspace);
626
627 /* Quantize/descale the coefficients, and store into coef_blocks[] */
628 (*do_quantize) (coef_blocks[bi], divisors, workspace);
629 }
630}
631
632#endif /* DCT_FLOAT_SUPPORTED */
633
634
635/*
636 * Initialize FDCT manager.
637 */
638
639GLOBAL(void)void
640_jinit_forward_dctjinit_forward_dct(j_compress_ptr cinfo)
641{
642 my_fdct_ptr fdct;
643 int i;
644
645 if (cinfo->data_precision != BITS_IN_JSAMPLE8)
646 ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision)((cinfo)->err->msg_code = (JERR_BAD_PRECISION), (cinfo)
->err->msg_parm.i[0] = (cinfo->data_precision), (*(cinfo
)->err->error_exit) ((j_common_ptr)(cinfo)))
;
647
648 fdct = (my_fdct_ptr)
649 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE1,
650 sizeof(my_fdct_controller));
651 cinfo->fdct = (struct jpeg_forward_dct *)fdct;
652 fdct->pub.start_pass = start_pass_fdctmgr;
653
654 /* First determine the DCT... */
655 switch (cinfo->dct_method) {
656#ifdef DCT_ISLOW_SUPPORTED
657 case JDCT_ISLOW:
658 fdct->pub._forward_DCTforward_DCT = forward_DCT;
659#ifdef WITH_SIMD1
660 if (jsimd_can_fdct_islow())
661 fdct->dct = jsimd_fdct_islow;
662 else
663#endif
664 fdct->dct = _jpeg_fdct_islowjpeg_fdct_islow;
665 break;
666#endif
667#ifdef DCT_IFAST_SUPPORTED
668 case JDCT_IFAST:
669 fdct->pub._forward_DCTforward_DCT = forward_DCT;
670#ifdef WITH_SIMD1
671 if (jsimd_can_fdct_ifast())
672 fdct->dct = jsimd_fdct_ifast;
673 else
674#endif
675 fdct->dct = _jpeg_fdct_ifastjpeg_fdct_ifast;
676 break;
677#endif
678#ifdef DCT_FLOAT_SUPPORTED
679 case JDCT_FLOAT:
680 fdct->pub._forward_DCTforward_DCT = forward_DCT_float;
681#ifdef WITH_SIMD1
682 if (jsimd_can_fdct_float())
683 fdct->float_dct = jsimd_fdct_float;
684 else
685#endif
686 fdct->float_dct = jpeg_fdct_float;
687 break;
688#endif
689 default:
690 ERREXIT(cinfo, JERR_NOT_COMPILED)((cinfo)->err->msg_code = (JERR_NOT_COMPILED), (*(cinfo
)->err->error_exit) ((j_common_ptr)(cinfo)))
;
691 break;
692 }
693
694 /* ...then the supporting stages. */
695 switch (cinfo->dct_method) {
696#ifdef DCT_ISLOW_SUPPORTED
697 case JDCT_ISLOW:
698#endif
699#ifdef DCT_IFAST_SUPPORTED
700 case JDCT_IFAST:
701#endif
702#if defined(DCT_ISLOW_SUPPORTED) || defined(DCT_IFAST_SUPPORTED)
703#ifdef WITH_SIMD1
704 if (jsimd_can_convsamp())
705 fdct->convsamp = jsimd_convsamp;
706 else
707#endif
708 fdct->convsamp = convsamp;
709#ifdef WITH_SIMD1
710 if (jsimd_can_quantize())
711 fdct->quantize = jsimd_quantize;
712 else
713#endif
714 fdct->quantize = quantize;
715 break;
716#endif
717#ifdef DCT_FLOAT_SUPPORTED
718 case JDCT_FLOAT:
719#ifdef WITH_SIMD1
720 if (jsimd_can_convsamp_float())
721 fdct->float_convsamp = jsimd_convsamp_float;
722 else
723#endif
724 fdct->float_convsamp = convsamp_float;
725#ifdef WITH_SIMD1
726 if (jsimd_can_quantize_float())
727 fdct->float_quantize = jsimd_quantize_float;
728 else
729#endif
730 fdct->float_quantize = quantize_float;
731 break;
732#endif
733 default:
734 ERREXIT(cinfo, JERR_NOT_COMPILED)((cinfo)->err->msg_code = (JERR_NOT_COMPILED), (*(cinfo
)->err->error_exit) ((j_common_ptr)(cinfo)))
;
735 break;
736 }
737
738 /* Allocate workspace memory */
739#ifdef DCT_FLOAT_SUPPORTED
740 if (cinfo->dct_method == JDCT_FLOAT)
741 fdct->float_workspace = (FAST_FLOATfloat *)
742 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE1,
743 sizeof(FAST_FLOATfloat) * DCTSIZE264);
744 else
745#endif
746 fdct->workspace = (DCTELEM *)
747 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE1,
748 sizeof(DCTELEM) * DCTSIZE264);
749
750 /* Mark divisor tables unallocated */
751 for (i = 0; i < NUM_QUANT_TBLS4; i++) {
752 fdct->divisors[i] = NULL((void*)0);
753#ifdef DCT_FLOAT_SUPPORTED
754 fdct->float_divisors[i] = NULL((void*)0);
755#endif
756 }
757}
758
759#endif /* defined(DCT_ISLOW_SUPPORTED) || defined(DCT_IFAST_SUPPORTED) ||
760 defined(DCT_FLOAT_SUPPORTED) */