Coverage Report

Created: 2024-01-20 12:28

/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 */