Coverage Report

Created: 2026-06-30 07:05

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