Bug Summary

File:root/firefox-clang/media/libjpeg/src/jclhuff.c
Warning:line 366, column 11
Value stored to 'temp2' 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 jclhuff.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 -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libjpeg -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 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libjpeg -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/jclhuff.c
1/*
2 * jclhuff.c
3 *
4 * This file was part of the Independent JPEG Group's software:
5 * Copyright (C) 1991-1997, Thomas G. Lane.
6 * Lossless JPEG Modifications:
7 * Copyright (C) 1999, Ken Murchison.
8 * libjpeg-turbo Modifications:
9 * Copyright (C) 2022, 2026, D. R. Commander.
10 * For conditions of distribution and use, see the accompanying README.ijg
11 * file.
12 *
13 * This file contains Huffman entropy encoding routines for lossless JPEG.
14 *
15 * Much of the complexity here has to do with supporting output suspension.
16 * If the data destination module demands suspension, we want to be able to
17 * back up to the start of the current MCU. To do this, we copy state
18 * variables into local working storage, and update them back to the
19 * permanent JPEG objects only upon successful completion of an MCU.
20 */
21
22#define JPEG_INTERNALS
23#include "jinclude.h"
24#include "jpeglib.h"
25#include "jlossls.h" /* Private declarations for lossless codec */
26#include "jchuff.h" /* Declarations shared with jc*huff.c */
27
28
29#ifdef C_LOSSLESS_SUPPORTED
30
31/* The legal range of a spatial difference is
32 * -32767 .. +32768.
33 * Hence the magnitude should always fit in 16 bits.
34 */
35
36#define MAX_DIFF_BITS16 16
37
38
39/* Expanded entropy encoder object for Huffman encoding in lossless mode.
40 *
41 * The savable_state subrecord contains fields that change within an MCU,
42 * but must not be updated permanently until we complete the MCU.
43 */
44
45typedef struct {
46 size_t put_buffer; /* current bit-accumulation buffer */
47 int put_bits; /* # of bits now in it */
48} savable_state;
49
50
51typedef struct {
52 int ci, yoffset, MCU_width;
53} lhe_input_ptr_info;
54
55
56typedef struct {
57 struct jpeg_entropy_encoder pub; /* public fields */
58
59 savable_state saved; /* Bit buffer at start of MCU */
60
61 /* These fields are NOT loaded into local working state. */
62 unsigned int restarts_to_go; /* MCUs left in this restart interval */
63 int next_restart_num; /* next restart number to write (0-7) */
64
65 /* Pointers to derived tables (these workspaces have image lifespan) */
66 c_derived_tbl *derived_tbls[NUM_HUFF_TBLS4];
67
68 /* Pointers to derived tables to be used for each data unit within an MCU */
69 c_derived_tbl *cur_tbls[C_MAX_BLOCKS_IN_MCU10];
70
71#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */
72 long *count_ptrs[NUM_HUFF_TBLS4];
73
74 /* Pointers to stats tables to be used for each data unit within an MCU */
75 long *cur_counts[C_MAX_BLOCKS_IN_MCU10];
76#endif
77
78 /* Pointers to the proper input difference row for each group of data units
79 * within an MCU. For each component, there are Vi groups of Hi data units.
80 */
81 JDIFFROW input_ptr[C_MAX_BLOCKS_IN_MCU10];
82
83 /* Number of input pointers in use for the current MCU. This is the sum
84 * of all Vi in the MCU.
85 */
86 int num_input_ptrs;
87
88 /* Information used for positioning the input pointers within the input
89 * difference rows.
90 */
91 lhe_input_ptr_info input_ptr_info[C_MAX_BLOCKS_IN_MCU10];
92
93 /* Index of the proper input pointer for each data unit within an MCU */
94 int input_ptr_index[C_MAX_BLOCKS_IN_MCU10];
95
96} lhuff_entropy_encoder;
97
98typedef lhuff_entropy_encoder *lhuff_entropy_ptr;
99
100/* Working state while writing an MCU.
101 * This struct contains all the fields that are needed by subroutines.
102 */
103
104typedef struct {
105 JOCTET *next_output_byte; /* => next byte to write in buffer */
106 size_t free_in_buffer; /* # of byte spaces remaining in buffer */
107 savable_state cur; /* Current bit buffer & DC state */
108 j_compress_ptr cinfo; /* dump_buffer needs access to this */
109} working_state;
110
111
112/* Forward declarations */
113METHODDEF(JDIMENSION)static JDIMENSION encode_mcus_huff(j_compress_ptr cinfo,
114 JDIFFIMAGE diff_buf,
115 JDIMENSION MCU_row_num,
116 JDIMENSION MCU_col_num,
117 JDIMENSION nMCU);
118METHODDEF(void)static void finish_pass_huff(j_compress_ptr cinfo);
119#ifdef ENTROPY_OPT_SUPPORTED
120METHODDEF(JDIMENSION)static JDIMENSION encode_mcus_gather(j_compress_ptr cinfo,
121 JDIFFIMAGE diff_buf,
122 JDIMENSION MCU_row_num,
123 JDIMENSION MCU_col_num,
124 JDIMENSION nMCU);
125METHODDEF(void)static void finish_pass_gather(j_compress_ptr cinfo);
126#endif
127
128
129/*
130 * Initialize for a Huffman-compressed scan.
131 * If gather_statistics is TRUE, we do not output anything during the scan,
132 * just count the Huffman symbols used and generate Huffman code tables.
133 */
134
135METHODDEF(void)static void
136start_pass_lhuff(j_compress_ptr cinfo, boolean gather_statistics)
137{
138 lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
139 int ci, dctbl, sampn, ptrn, yoffset, xoffset;
140 jpeg_component_info *compptr;
141
142 if (gather_statistics) {
143#ifdef ENTROPY_OPT_SUPPORTED
144 entropy->pub.encode_mcus = encode_mcus_gather;
145 entropy->pub.finish_pass = finish_pass_gather;
146#else
147 ERREXIT(cinfo, JERR_NOT_COMPILED)((cinfo)->err->msg_code = (JERR_NOT_COMPILED), (*(cinfo
)->err->error_exit) ((j_common_ptr)(cinfo)))
;
148#endif
149 } else {
150 entropy->pub.encode_mcus = encode_mcus_huff;
151 entropy->pub.finish_pass = finish_pass_huff;
152 }
153
154 for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
155 compptr = cinfo->cur_comp_info[ci];
156 dctbl = compptr->dc_tbl_no;
157 if (gather_statistics) {
158#ifdef ENTROPY_OPT_SUPPORTED
159 /* Check for invalid table indexes */
160 /* (make_c_derived_tbl does this in the other path) */
161 if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS4)
162 ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl)((cinfo)->err->msg_code = (JERR_NO_HUFF_TABLE), (cinfo)
->err->msg_parm.i[0] = (dctbl), (*(cinfo)->err->error_exit
) ((j_common_ptr)(cinfo)))
;
163 /* Allocate and zero the statistics tables */
164 /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
165 if (entropy->count_ptrs[dctbl] == NULL((void*)0))
166 entropy->count_ptrs[dctbl] = (long *)
167 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE1,
168 257 * sizeof(long));
169 memset(entropy->count_ptrs[dctbl], 0, 257 * sizeof(long));
170#endif
171 } else {
172 /* Compute derived values for Huffman tables */
173 /* We may do this more than once for a table, but it's not expensive */
174 jpeg_make_c_derived_tbl(cinfo, TRUE1, dctbl,
175 &entropy->derived_tbls[dctbl]);
176 }
177 }
178
179 /* Precalculate encoding info for each sample in an MCU of this scan */
180 for (sampn = 0, ptrn = 0; sampn < cinfo->blocks_in_MCU;) {
181 compptr = cinfo->cur_comp_info[cinfo->MCU_membership[sampn]];
182 ci = compptr->component_index;
183 for (yoffset = 0; yoffset < compptr->MCU_height; yoffset++, ptrn++) {
184 /* Precalculate the setup info for each input pointer */
185 entropy->input_ptr_info[ptrn].ci = ci;
186 entropy->input_ptr_info[ptrn].yoffset = yoffset;
187 entropy->input_ptr_info[ptrn].MCU_width = compptr->MCU_width;
188 for (xoffset = 0; xoffset < compptr->MCU_width; xoffset++, sampn++) {
189 /* Precalculate the input pointer index for each sample */
190 entropy->input_ptr_index[sampn] = ptrn;
191 /* Precalculate which tables to use for each sample */
192 entropy->cur_tbls[sampn] = entropy->derived_tbls[compptr->dc_tbl_no];
193#ifdef ENTROPY_OPT_SUPPORTED
194 entropy->cur_counts[sampn] = entropy->count_ptrs[compptr->dc_tbl_no];
195#endif
196 }
197 }
198 }
199 entropy->num_input_ptrs = ptrn;
200
201 /* Initialize bit buffer to empty */
202 entropy->saved.put_buffer = 0;
203 entropy->saved.put_bits = 0;
204
205 /* Initialize restart stuff */
206 entropy->restarts_to_go = cinfo->restart_interval;
207 entropy->next_restart_num = 0;
208}
209
210
211/* Outputting bytes to the file */
212
213/* Emit a byte, taking 'action' if must suspend. */
214#define emit_byte(state, val, action){ *(state)->next_output_byte++ = (JOCTET)(val); if (--(state
)->free_in_buffer == 0) if (!dump_buffer(state)) { action;
} }
{ \
215 *(state)->next_output_byte++ = (JOCTET)(val); \
216 if (--(state)->free_in_buffer == 0) \
217 if (!dump_buffer(state)) \
218 { action; } \
219}
220
221
222LOCAL(boolean)static boolean
223dump_buffer(working_state *state)
224/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
225{
226 struct jpeg_destination_mgr *dest = state->cinfo->dest;
227
228 if (!(*dest->empty_output_buffer) (state->cinfo))
229 return FALSE0;
230 /* After a successful buffer dump, must reset buffer pointers */
231 state->next_output_byte = dest->next_output_byte;
232 state->free_in_buffer = dest->free_in_buffer;
233 return TRUE1;
234}
235
236
237/* Outputting bits to the file */
238
239/* Only the right 24 bits of put_buffer are used; the valid bits are
240 * left-justified in this part. At most 16 bits can be passed to emit_bits
241 * in one call, and we never retain more than 7 bits in put_buffer
242 * between calls, so 24 bits are sufficient.
243 */
244
245INLINEinline
246LOCAL(boolean)static boolean
247emit_bits(working_state *state, unsigned int code, int size)
248/* Emit some bits; return TRUE if successful, FALSE if must suspend */
249{
250 /* This routine is heavily used, so it's worth coding tightly. */
251 register size_t put_buffer = (size_t)code;
252 register int put_bits = state->cur.put_bits;
253
254 /* if size is 0, caller used an invalid Huffman table entry */
255 if (size == 0)
256 ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE)((state->cinfo)->err->msg_code = (JERR_HUFF_MISSING_CODE
), (*(state->cinfo)->err->error_exit) ((j_common_ptr
)(state->cinfo)))
;
257
258 put_buffer &= (((size_t)1) << size) - 1; /* mask off any extra bits in code */
259
260 put_bits += size; /* new number of bits in buffer */
261
262 put_buffer <<= 24 - put_bits; /* align incoming bits */
263
264 put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
265
266 while (put_bits >= 8) {
267 int c = (int)((put_buffer >> 16) & 0xFF);
268
269 emit_byte(state, c, return FALSE){ *(state)->next_output_byte++ = (JOCTET)(c); if (--(state
)->free_in_buffer == 0) if (!dump_buffer(state)) { return 0
; } }
;
270 if (c == 0xFF) { /* need to stuff a zero byte? */
271 emit_byte(state, 0, return FALSE){ *(state)->next_output_byte++ = (JOCTET)(0); if (--(state
)->free_in_buffer == 0) if (!dump_buffer(state)) { return 0
; } }
;
272 }
273 put_buffer <<= 8;
274 put_bits -= 8;
275 }
276
277 state->cur.put_buffer = put_buffer; /* update state variables */
278 state->cur.put_bits = put_bits;
279
280 return TRUE1;
281}
282
283
284LOCAL(boolean)static boolean
285flush_bits(working_state *state)
286{
287 if (!emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
288 return FALSE0;
289 state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
290 state->cur.put_bits = 0;
291 return TRUE1;
292}
293
294
295/*
296 * Emit a restart marker & resynchronize predictions.
297 */
298
299LOCAL(boolean)static boolean
300emit_restart(working_state *state, int restart_num)
301{
302 if (!flush_bits(state))
303 return FALSE0;
304
305 emit_byte(state, 0xFF, return FALSE){ *(state)->next_output_byte++ = (JOCTET)(0xFF); if (--(state
)->free_in_buffer == 0) if (!dump_buffer(state)) { return 0
; } }
;
306 emit_byte(state, JPEG_RST0 + restart_num, return FALSE){ *(state)->next_output_byte++ = (JOCTET)(0xD0 + restart_num
); if (--(state)->free_in_buffer == 0) if (!dump_buffer(state
)) { return 0; } }
;
307
308 /* The restart counter is not updated until we successfully write the MCU. */
309
310 return TRUE1;
311}
312
313
314/*
315 * Encode and output nMCU MCUs' worth of Huffman-compressed differences.
316 */
317
318METHODDEF(JDIMENSION)static JDIMENSION
319encode_mcus_huff(j_compress_ptr cinfo, JDIFFIMAGE diff_buf,
320 JDIMENSION MCU_row_num, JDIMENSION MCU_col_num,
321 JDIMENSION nMCU)
322{
323 lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
324 working_state state;
325 int sampn, ci, yoffset, MCU_width, ptrn;
326 JDIMENSION mcu_num;
327
328 /* Load up working state */
329 state.next_output_byte = cinfo->dest->next_output_byte;
330 state.free_in_buffer = cinfo->dest->free_in_buffer;
331 state.cur = entropy->saved;
332 state.cinfo = cinfo;
333
334 /* Emit restart marker if needed */
335 if (cinfo->restart_interval) {
336 if (entropy->restarts_to_go == 0)
337 if (!emit_restart(&state, entropy->next_restart_num))
338 return 0;
339 }
340
341 /* Set input pointer locations based on MCU_col_num */
342 for (ptrn = 0; ptrn < entropy->num_input_ptrs; ptrn++) {
343 ci = entropy->input_ptr_info[ptrn].ci;
344 yoffset = entropy->input_ptr_info[ptrn].yoffset;
345 MCU_width = entropy->input_ptr_info[ptrn].MCU_width;
346 entropy->input_ptr[ptrn] =
347 diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width);
348 }
349
350 for (mcu_num = 0; mcu_num < nMCU; mcu_num++) {
351
352 /* Inner loop handles the samples in the MCU */
353 for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) {
354 register int temp, temp2;
355 register int nbits;
356 c_derived_tbl *dctbl = entropy->cur_tbls[sampn];
357
358 /* Encode the difference per section H.1.2.2 */
359
360 /* Input the sample difference */
361 temp = *entropy->input_ptr[entropy->input_ptr_index[sampn]]++;
362
363 if (temp & 0x8000) { /* instead of temp < 0 */
364 temp = (-temp) & 0x7FFF; /* absolute value, mod 2^16 */
365 if (temp == 0) /* special case: magnitude = 32768 */
366 temp2 = temp = 0x8000;
Value stored to 'temp2' is never read
367 temp2 = ~temp; /* one's complement of magnitude */
368 } else {
369 temp &= 0x7FFF; /* abs value mod 2^16 */
370 temp2 = temp; /* magnitude */
371 }
372
373 /* Find the number of bits needed for the magnitude of the difference */
374 nbits = 0;
375 while (temp) {
376 nbits++;
377 temp >>= 1;
378 }
379 /* Check for out-of-range difference values.
380 */
381 if (nbits > MAX_DIFF_BITS16)
382 ERREXIT(cinfo, JERR_BAD_DCT_COEF)((cinfo)->err->msg_code = (JERR_BAD_DCT_COEF), (*(cinfo
)->err->error_exit) ((j_common_ptr)(cinfo)))
;
383
384 /* Emit the Huffman-coded symbol for the number of bits */
385 if (!emit_bits(&state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
386 return mcu_num;
387
388 /* Emit that number of bits of the value, if positive, */
389 /* or the complement of its magnitude, if negative. */
390 if (nbits && /* emit_bits rejects calls with size 0 */
391 nbits != 16) /* special case: no bits should be emitted */
392 if (!emit_bits(&state, (unsigned int)temp2, nbits))
393 return mcu_num;
394 }
395
396 /* Completed MCU, so update state */
397 cinfo->dest->next_output_byte = state.next_output_byte;
398 cinfo->dest->free_in_buffer = state.free_in_buffer;
399 entropy->saved = state.cur;
400
401 /* Update restart-interval state too */
402 if (cinfo->restart_interval) {
403 if (entropy->restarts_to_go == 0) {
404 entropy->restarts_to_go = cinfo->restart_interval;
405 entropy->next_restart_num++;
406 entropy->next_restart_num &= 7;
407 }
408 entropy->restarts_to_go--;
409 }
410
411 }
412
413 return nMCU;
414}
415
416
417/*
418 * Finish up at the end of a Huffman-compressed scan.
419 */
420
421METHODDEF(void)static void
422finish_pass_huff(j_compress_ptr cinfo)
423{
424 lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
425 working_state state;
426
427 /* Load up working state ... flush_bits needs it */
428 state.next_output_byte = cinfo->dest->next_output_byte;
429 state.free_in_buffer = cinfo->dest->free_in_buffer;
430 state.cur = entropy->saved;
431 state.cinfo = cinfo;
432
433 /* Flush out the last data */
434 if (!flush_bits(&state))
435 ERREXIT(cinfo, JERR_CANT_SUSPEND)((cinfo)->err->msg_code = (JERR_CANT_SUSPEND), (*(cinfo
)->err->error_exit) ((j_common_ptr)(cinfo)))
;
436
437 /* Update state */
438 cinfo->dest->next_output_byte = state.next_output_byte;
439 cinfo->dest->free_in_buffer = state.free_in_buffer;
440 entropy->saved = state.cur;
441}
442
443
444/*
445 * Huffman coding optimization.
446 *
447 * We first scan the supplied data and count the number of uses of each symbol
448 * that is to be Huffman-coded. (This process MUST agree with the code above.)
449 * Then we build a Huffman coding tree for the observed counts.
450 * Symbols which are not needed at all for the particular image are not
451 * assigned any code, which saves space in the DHT marker as well as in
452 * the compressed data.
453 */
454
455#ifdef ENTROPY_OPT_SUPPORTED
456
457/*
458 * Trial-encode nMCU MCUs' worth of Huffman-compressed differences.
459 * No data is actually output, so no suspension return is possible.
460 */
461
462METHODDEF(JDIMENSION)static JDIMENSION
463encode_mcus_gather(j_compress_ptr cinfo, JDIFFIMAGE diff_buf,
464 JDIMENSION MCU_row_num, JDIMENSION MCU_col_num,
465 JDIMENSION nMCU)
466{
467 lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
468 int sampn, ci, yoffset, MCU_width, ptrn;
469 JDIMENSION mcu_num;
470
471 /* Take care of restart intervals if needed */
472 if (cinfo->restart_interval) {
473 if (entropy->restarts_to_go == 0) {
474 /* Update restart state */
475 entropy->restarts_to_go = cinfo->restart_interval;
476 }
477 entropy->restarts_to_go--;
478 }
479
480 /* Set input pointer locations based on MCU_col_num */
481 for (ptrn = 0; ptrn < entropy->num_input_ptrs; ptrn++) {
482 ci = entropy->input_ptr_info[ptrn].ci;
483 yoffset = entropy->input_ptr_info[ptrn].yoffset;
484 MCU_width = entropy->input_ptr_info[ptrn].MCU_width;
485 entropy->input_ptr[ptrn] =
486 diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width);
487 }
488
489 for (mcu_num = 0; mcu_num < nMCU; mcu_num++) {
490
491 /* Inner loop handles the samples in the MCU */
492 for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) {
493 register int temp;
494 register int nbits;
495 long *counts = entropy->cur_counts[sampn];
496
497 /* Encode the difference per section H.1.2.2 */
498
499 /* Input the sample difference */
500 temp = *entropy->input_ptr[entropy->input_ptr_index[sampn]]++;
501
502 if (temp & 0x8000) { /* instead of temp < 0 */
503 temp = (-temp) & 0x7FFF; /* absolute value, mod 2^16 */
504 if (temp == 0) /* special case: magnitude = 32768 */
505 temp = 0x8000;
506 } else
507 temp &= 0x7FFF; /* abs value mod 2^16 */
508
509 /* Find the number of bits needed for the magnitude of the difference */
510 nbits = 0;
511 while (temp) {
512 nbits++;
513 temp >>= 1;
514 }
515 /* Check for out-of-range difference values.
516 */
517 if (nbits > MAX_DIFF_BITS16)
518 ERREXIT(cinfo, JERR_BAD_DCT_COEF)((cinfo)->err->msg_code = (JERR_BAD_DCT_COEF), (*(cinfo
)->err->error_exit) ((j_common_ptr)(cinfo)))
;
519
520 /* Count the Huffman symbol for the number of bits */
521 counts[nbits]++;
522 }
523 }
524
525 return nMCU;
526}
527
528
529/*
530 * Finish up a statistics-gathering pass and create the new Huffman tables.
531 */
532
533METHODDEF(void)static void
534finish_pass_gather(j_compress_ptr cinfo)
535{
536 lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
537 int ci, dctbl;
538 jpeg_component_info *compptr;
539 JHUFF_TBL **htblptr;
540 boolean did_dc[NUM_HUFF_TBLS4];
541
542 /* It's important not to apply jpeg_gen_optimal_table more than once
543 * per table, because it clobbers the input frequency counts!
544 */
545 memset(did_dc, 0, sizeof(did_dc));
546
547 for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
548 compptr = cinfo->cur_comp_info[ci];
549 dctbl = compptr->dc_tbl_no;
550 if (!did_dc[dctbl]) {
551 htblptr = &cinfo->dc_huff_tbl_ptrs[dctbl];
552 if (*htblptr == NULL((void*)0))
553 *htblptr = jpeg_alloc_huff_table((j_common_ptr)cinfo);
554 jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[dctbl]);
555 did_dc[dctbl] = TRUE1;
556 }
557 }
558}
559
560
561#endif /* ENTROPY_OPT_SUPPORTED */
562
563
564/*
565 * Module initialization routine for Huffman entropy encoding.
566 */
567
568GLOBAL(void)void
569jinit_lhuff_encoder(j_compress_ptr cinfo)
570{
571 lhuff_entropy_ptr entropy;
572 int i;
573
574 entropy = (lhuff_entropy_ptr)
575 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE1,
576 sizeof(lhuff_entropy_encoder));
577 cinfo->entropy = (struct jpeg_entropy_encoder *)entropy;
578 entropy->pub.start_pass = start_pass_lhuff;
579
580 /* Mark tables unallocated */
581 for (i = 0; i < NUM_HUFF_TBLS4; i++) {
582 entropy->derived_tbls[i] = NULL((void*)0);
583#ifdef ENTROPY_OPT_SUPPORTED
584 entropy->count_ptrs[i] = NULL((void*)0);
585#endif
586 }
587}
588
589#endif /* C_LOSSLESS_SUPPORTED */