/src/libjpeg-turbo.main/jdlhuff.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * jdlhuff.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, D. R. Commander. |
10 | | * For conditions of distribution and use, see the accompanying README.ijg |
11 | | * file. |
12 | | * |
13 | | * This file contains Huffman entropy decoding routines for lossless JPEG. |
14 | | * |
15 | | * Much of the complexity here has to do with supporting input suspension. |
16 | | * If the data source module demands suspension, we want to be able to back |
17 | | * up to the start of the current MCU. To do this, we copy state variables |
18 | | * into local working storage, and update them back to the permanent |
19 | | * storage 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 "jdhuff.h" /* Declarations shared with jd*huff.c */ |
27 | | |
28 | | |
29 | | #ifdef D_LOSSLESS_SUPPORTED |
30 | | |
31 | | typedef struct { |
32 | | int ci, yoffset, MCU_width; |
33 | | } lhd_output_ptr_info; |
34 | | |
35 | | /* |
36 | | * Expanded entropy decoder object for Huffman decoding in lossless mode. |
37 | | */ |
38 | | |
39 | | typedef struct { |
40 | | struct jpeg_entropy_decoder pub; /* public fields */ |
41 | | |
42 | | /* These fields are loaded into local variables at start of each MCU. |
43 | | * In case of suspension, we exit WITHOUT updating them. |
44 | | */ |
45 | | bitread_perm_state bitstate; /* Bit buffer at start of MCU */ |
46 | | |
47 | | /* Pointers to derived tables (these workspaces have image lifespan) */ |
48 | | d_derived_tbl *derived_tbls[NUM_HUFF_TBLS]; |
49 | | |
50 | | /* Precalculated info set up by start_pass for use in decode_mcus: */ |
51 | | |
52 | | /* Pointers to derived tables to be used for each data unit within an MCU */ |
53 | | d_derived_tbl *cur_tbls[D_MAX_BLOCKS_IN_MCU]; |
54 | | |
55 | | /* Pointers to the proper output difference row for each group of data units |
56 | | * within an MCU. For each component, there are Vi groups of Hi data units. |
57 | | */ |
58 | | JDIFFROW output_ptr[D_MAX_BLOCKS_IN_MCU]; |
59 | | |
60 | | /* Number of output pointers in use for the current MCU. This is the sum |
61 | | * of all Vi in the MCU. |
62 | | */ |
63 | | int num_output_ptrs; |
64 | | |
65 | | /* Information used for positioning the output pointers within the output |
66 | | * difference rows. |
67 | | */ |
68 | | lhd_output_ptr_info output_ptr_info[D_MAX_BLOCKS_IN_MCU]; |
69 | | |
70 | | /* Index of the proper output pointer for each data unit within an MCU */ |
71 | | int output_ptr_index[D_MAX_BLOCKS_IN_MCU]; |
72 | | |
73 | | } lhuff_entropy_decoder; |
74 | | |
75 | | typedef lhuff_entropy_decoder *lhuff_entropy_ptr; |
76 | | |
77 | | |
78 | | /* |
79 | | * Initialize for a Huffman-compressed scan. |
80 | | */ |
81 | | |
82 | | METHODDEF(void) |
83 | | start_pass_lhuff_decoder(j_decompress_ptr cinfo) |
84 | 72.1k | { |
85 | 72.1k | lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy; |
86 | 72.1k | int ci, dctbl, sampn, ptrn, yoffset, xoffset; |
87 | 72.1k | jpeg_component_info *compptr; |
88 | | |
89 | 230k | for (ci = 0; ci < cinfo->comps_in_scan; ci++) { |
90 | 158k | compptr = cinfo->cur_comp_info[ci]; |
91 | 158k | dctbl = compptr->dc_tbl_no; |
92 | | /* Make sure requested tables are present */ |
93 | 158k | if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS || |
94 | 158k | cinfo->dc_huff_tbl_ptrs[dctbl] == NULL) |
95 | 247 | ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); |
96 | | /* Compute derived values for Huffman tables */ |
97 | | /* We may do this more than once for a table, but it's not expensive */ |
98 | 158k | jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, |
99 | 158k | &entropy->derived_tbls[dctbl]); |
100 | 158k | } |
101 | | |
102 | | /* Precalculate decoding info for each sample in an MCU of this scan */ |
103 | 230k | for (sampn = 0, ptrn = 0; sampn < cinfo->blocks_in_MCU;) { |
104 | 158k | compptr = cinfo->cur_comp_info[cinfo->MCU_membership[sampn]]; |
105 | 158k | ci = compptr->component_index; |
106 | 354k | for (yoffset = 0; yoffset < compptr->MCU_height; yoffset++, ptrn++) { |
107 | | /* Precalculate the setup info for each output pointer */ |
108 | 196k | entropy->output_ptr_info[ptrn].ci = ci; |
109 | 196k | entropy->output_ptr_info[ptrn].yoffset = yoffset; |
110 | 196k | entropy->output_ptr_info[ptrn].MCU_width = compptr->MCU_width; |
111 | 449k | for (xoffset = 0; xoffset < compptr->MCU_width; xoffset++, sampn++) { |
112 | | /* Precalculate the output pointer index for each sample */ |
113 | 253k | entropy->output_ptr_index[sampn] = ptrn; |
114 | | /* Precalculate which table to use for each sample */ |
115 | 253k | entropy->cur_tbls[sampn] = entropy->derived_tbls[compptr->dc_tbl_no]; |
116 | 253k | } |
117 | 196k | } |
118 | 158k | } |
119 | 72.1k | entropy->num_output_ptrs = ptrn; |
120 | | |
121 | | /* Initialize bitread state variables */ |
122 | 72.1k | entropy->bitstate.bits_left = 0; |
123 | 72.1k | entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ |
124 | 72.1k | entropy->pub.insufficient_data = FALSE; |
125 | 72.1k | } |
126 | | |
127 | | |
128 | | /* |
129 | | * Figure F.12: extend sign bit. |
130 | | * On some machines, a shift and add will be faster than a table lookup. |
131 | | */ |
132 | | |
133 | | #define AVOID_TABLES |
134 | | #ifdef AVOID_TABLES |
135 | | |
136 | 325M | #define NEG_1 ((unsigned int)-1) |
137 | | #define HUFF_EXTEND(x, s) \ |
138 | 325M | ((x) + ((((x) - (1 << ((s) - 1))) >> 31) & (((NEG_1) << (s)) + 1))) |
139 | | |
140 | | #else |
141 | | |
142 | | #define HUFF_EXTEND(x, s) \ |
143 | | ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) |
144 | | |
145 | | static const int extend_test[16] = { /* entry n is 2**(n-1) */ |
146 | | 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, |
147 | | 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 |
148 | | }; |
149 | | |
150 | | static const int extend_offset[16] = { /* entry n is (-1 << n) + 1 */ |
151 | | 0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1, |
152 | | ((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1, |
153 | | ((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1, |
154 | | ((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1 |
155 | | }; |
156 | | |
157 | | #endif /* AVOID_TABLES */ |
158 | | |
159 | | |
160 | | /* |
161 | | * Check for a restart marker & resynchronize decoder. |
162 | | * Returns FALSE if must suspend. |
163 | | */ |
164 | | |
165 | | LOCAL(boolean) |
166 | | process_restart(j_decompress_ptr cinfo) |
167 | 34.1M | { |
168 | 34.1M | lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy; |
169 | | |
170 | | /* Throw away any unused bits remaining in bit buffer; */ |
171 | | /* include any full bytes in next_marker's count of discarded bytes */ |
172 | 34.1M | cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; |
173 | 34.1M | entropy->bitstate.bits_left = 0; |
174 | | |
175 | | /* Advance past the RSTn marker */ |
176 | 34.1M | if (!(*cinfo->marker->read_restart_marker) (cinfo)) |
177 | 0 | return FALSE; |
178 | | |
179 | | /* Reset out-of-data flag, unless read_restart_marker left us smack up |
180 | | * against a marker. In that case we will end up treating the next data |
181 | | * segment as empty, and we can avoid producing bogus output pixels by |
182 | | * leaving the flag set. |
183 | | */ |
184 | 34.1M | if (cinfo->unread_marker == 0) |
185 | 12.2k | entropy->pub.insufficient_data = FALSE; |
186 | | |
187 | 34.1M | return TRUE; |
188 | 34.1M | } |
189 | | |
190 | | |
191 | | /* |
192 | | * Decode and return nMCU MCUs' worth of Huffman-compressed differences. |
193 | | * Each MCU is also disassembled and placed accordingly in diff_buf. |
194 | | * |
195 | | * MCU_col_num specifies the column of the first MCU being requested within |
196 | | * the MCU row. This tells us where to position the output row pointers in |
197 | | * diff_buf. |
198 | | * |
199 | | * Returns the number of MCUs decoded. This may be less than nMCU MCUs if |
200 | | * data source requested suspension. In that case no changes have been made |
201 | | * to permanent state. (Exception: some output differences may already have |
202 | | * been assigned. This is harmless for this module, since we'll just |
203 | | * re-assign them on the next call.) |
204 | | */ |
205 | | |
206 | | METHODDEF(JDIMENSION) |
207 | | decode_mcus(j_decompress_ptr cinfo, JDIFFIMAGE diff_buf, |
208 | | JDIMENSION MCU_row_num, JDIMENSION MCU_col_num, JDIMENSION nMCU) |
209 | 611M | { |
210 | 611M | lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy; |
211 | 611M | int sampn, ci, yoffset, MCU_width, ptrn; |
212 | 611M | JDIMENSION mcu_num; |
213 | 611M | BITREAD_STATE_VARS; |
214 | | |
215 | | /* Set output pointer locations based on MCU_col_num */ |
216 | 1.30G | for (ptrn = 0; ptrn < entropy->num_output_ptrs; ptrn++) { |
217 | 696M | ci = entropy->output_ptr_info[ptrn].ci; |
218 | 696M | yoffset = entropy->output_ptr_info[ptrn].yoffset; |
219 | 696M | MCU_width = entropy->output_ptr_info[ptrn].MCU_width; |
220 | 696M | entropy->output_ptr[ptrn] = |
221 | 696M | diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width); |
222 | 696M | } |
223 | | |
224 | | /* |
225 | | * If we've run out of data, zero out the buffers and return. |
226 | | * By resetting the undifferencer, the output samples will be CENTERJSAMPLE. |
227 | | * |
228 | | * NB: We should find a way to do this without interacting with the |
229 | | * undifferencer module directly. |
230 | | */ |
231 | 611M | if (entropy->pub.insufficient_data) { |
232 | 1.30G | for (ptrn = 0; ptrn < entropy->num_output_ptrs; ptrn++) |
233 | 693M | jzero_far((void FAR *)entropy->output_ptr[ptrn], |
234 | 693M | nMCU * entropy->output_ptr_info[ptrn].MCU_width * |
235 | 693M | sizeof(JDIFF)); |
236 | | |
237 | 609M | (*cinfo->idct->start_pass) (cinfo); |
238 | | |
239 | 609M | } else { |
240 | | |
241 | | /* Load up working state */ |
242 | 1.43M | BITREAD_LOAD_STATE(cinfo, entropy->bitstate); |
243 | | |
244 | | /* Outer loop handles the number of MCUs requested */ |
245 | | |
246 | 101M | for (mcu_num = 0; mcu_num < nMCU; mcu_num++) { |
247 | | |
248 | | /* Inner loop handles the samples in the MCU */ |
249 | 450M | for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) { |
250 | 350M | d_derived_tbl *dctbl = entropy->cur_tbls[sampn]; |
251 | 350M | register int s, r; |
252 | | |
253 | | /* Section H.2.2: decode the sample difference */ |
254 | 350M | HUFF_DECODE(s, br_state, dctbl, return mcu_num, label1); |
255 | 350M | if (s) { |
256 | 325M | if (s == 16) /* special case: always output 32768 */ |
257 | 133k | s = 32768; |
258 | 325M | else { /* normal case: fetch subsequent bits */ |
259 | 325M | CHECK_BIT_BUFFER(br_state, s, return mcu_num); |
260 | 325M | r = GET_BITS(s); |
261 | 325M | s = HUFF_EXTEND(r, s); |
262 | 325M | } |
263 | 325M | } |
264 | | |
265 | | /* Output the sample difference */ |
266 | 350M | *entropy->output_ptr[entropy->output_ptr_index[sampn]]++ = (JDIFF)s; |
267 | 350M | } |
268 | | |
269 | | /* Completed MCU, so update state */ |
270 | 100M | BITREAD_SAVE_STATE(cinfo, entropy->bitstate); |
271 | 100M | } |
272 | 1.43M | } |
273 | | |
274 | 611M | return nMCU; |
275 | 611M | } |
276 | | |
277 | | |
278 | | /* |
279 | | * Module initialization routine for lossless mode Huffman entropy decoding. |
280 | | */ |
281 | | |
282 | | GLOBAL(void) |
283 | | jinit_lhuff_decoder(j_decompress_ptr cinfo) |
284 | 44.6k | { |
285 | 44.6k | lhuff_entropy_ptr entropy; |
286 | 44.6k | int i; |
287 | | |
288 | 44.6k | entropy = (lhuff_entropy_ptr) |
289 | 44.6k | (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, |
290 | 44.6k | sizeof(lhuff_entropy_decoder)); |
291 | 44.6k | cinfo->entropy = (struct jpeg_entropy_decoder *)entropy; |
292 | 44.6k | entropy->pub.start_pass = start_pass_lhuff_decoder; |
293 | 44.6k | entropy->pub.decode_mcus = decode_mcus; |
294 | 44.6k | entropy->pub.process_restart = process_restart; |
295 | | |
296 | | /* Mark tables unallocated */ |
297 | 223k | for (i = 0; i < NUM_HUFF_TBLS; i++) { |
298 | 178k | entropy->derived_tbls[i] = NULL; |
299 | 178k | } |
300 | 44.6k | } |
301 | | |
302 | | #endif /* D_LOSSLESS_SUPPORTED */ |