Coverage Report

Created: 2026-06-30 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dcmtk/dcmjpeg/libijg16/jdpred.c
Line
Count
Source
1
/*
2
 * jdpred.c
3
 *
4
 * Copyright (C) 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 sample undifferencing (reconstruction) for lossless JPEG.
9
 *
10
 * In order to avoid paying the performance penalty of having to check the
11
 * predictor being used and the row being processed for each call of the
12
 * undifferencer, and to promote optimization, we have separate undifferencing
13
 * functions for each case.
14
 *
15
 * We are able to avoid duplicating source code by implementing the predictors
16
 * and undifferencers as macros.  Each of the undifferencing functions are
17
 * simply wrappers around an UNDIFFERENCE macro with the appropriate PREDICTOR
18
 * macro passed as an argument.
19
 */
20
21
#define JPEG_INTERNALS
22
#include "jinclude16.h"
23
#include "jpeglib16.h"
24
#include "jlossls16.h"      /* Private declarations for lossless codec */
25
26
27
#ifdef D_LOSSLESS_SUPPORTED
28
29
/* Predictor for the first column of the first row: 2^(P-Pt-1) */
30
#define INITIAL_PREDICTORx  (1 << (cinfo->data_precision - cinfo->Al - 1))
31
32
/* Predictor for the first column of the remaining rows: Rb */
33
#define INITIAL_PREDICTOR2  GETJSAMPLE(prev_row[0])
34
35
36
/*
37
 * 1-Dimensional undifferencer routine.
38
 *
39
 * This macro implements the 1-D horizontal predictor (1).  INITIAL_PREDICTOR
40
 * is used as the special case predictor for the first column, which must be
41
 * either INITIAL_PREDICTOR2 or INITIAL_PREDICTORx.  The remaining samples
42
 * use PREDICTOR1.
43
 *
44
 * The reconstructed sample is supposed to be calculated modulo 2^16, so we
45
 * logically AND the result with 0xFFFF.
46
*/
47
48
#define UNDIFFERENCE_1D(INITIAL_PREDICTOR) \
49
    unsigned int xindex; \
50
    int Ra; \
51
 \
52
    Ra = (diff_buf[0] + INITIAL_PREDICTOR) & 0xFFFF; \
53
    undiff_buf[0] = Ra; \
54
 \
55
    for (xindex = 1; xindex < width; xindex++) { \
56
      Ra = (diff_buf[xindex] + PREDICTOR1) & 0xFFFF; \
57
      undiff_buf[xindex] = Ra; \
58
    }
59
60
/*
61
 * 2-Dimensional undifferencer routine.
62
 *
63
 * This macro implements the 2-D horizontal predictors (#2-7).  PREDICTOR2 is
64
 * used as the special case predictor for the first column.  The remaining
65
 * samples use PREDICTOR, which is a function of Ra, Rb, Rc.
66
 *
67
 * Because prev_row and output_buf may point to the same storage area (in an
68
 * interleaved image with Vi=1, for example), we must take care to buffer Rb/Rc
69
 * before writing the current reconstructed sample value into output_buf.
70
 *
71
 * The reconstructed sample is supposed to be calculated modulo 2^16, so we
72
 * logically AND the result with 0xFFFF.
73
 */
74
75
#define UNDIFFERENCE_2D(PREDICTOR) \
76
0
    unsigned int xindex; \
77
0
    int Ra, Rb, Rc; \
78
0
 \
79
0
    Rb = GETJSAMPLE(prev_row[0]); \
80
0
    Ra = (diff_buf[0] + PREDICTOR2) & 0xFFFF; \
81
0
    undiff_buf[0] = Ra; \
82
0
 \
83
0
    for (xindex = 1; xindex < width; xindex++) { \
84
0
      Rc = Rb; \
85
0
      Rb = GETJSAMPLE(prev_row[xindex]); \
86
0
      Ra = (diff_buf[xindex] + PREDICTOR) & 0xFFFF; \
87
0
      undiff_buf[xindex] = Ra; \
88
0
    }
89
90
0
#define JPEG_UNUSED(x) ((void)x)
91
92
/*
93
 * Undifferencers for the all rows but the first in a scan or restart interval.
94
 * The first sample in the row is undifferenced using the vertical
95
 * predictor (2).  The rest of the samples are undifferenced using the
96
 * predictor specified in the scan header.
97
 */
98
99
METHODDEF(void)
100
jpeg_undifference1(j_decompress_ptr cinfo, int comp_index,
101
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
102
           JDIFFROW undiff_buf, JDIMENSION width)
103
{
104
  (void)cinfo;
105
  (void)comp_index;
106
  UNDIFFERENCE_1D(INITIAL_PREDICTOR2);
107
}
108
109
METHODDEF(void)
110
jpeg_undifference2(j_decompress_ptr cinfo, int comp_index,
111
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
112
           JDIFFROW undiff_buf, JDIMENSION width)
113
{
114
   (void)cinfo;
115
  (void)comp_index;
116
 UNDIFFERENCE_2D(PREDICTOR2);
117
  JPEG_UNUSED(Rc);
118
  JPEG_UNUSED(Rb);
119
}
120
121
METHODDEF(void)
122
jpeg_undifference3(j_decompress_ptr cinfo, int comp_index,
123
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
124
           JDIFFROW undiff_buf, JDIMENSION width)
125
{
126
  (void)cinfo;
127
  (void)comp_index;
128
  UNDIFFERENCE_2D(PREDICTOR3);
129
  JPEG_UNUSED(Rc);
130
  JPEG_UNUSED(Rb);
131
}
132
133
METHODDEF(void)
134
jpeg_undifference4a(j_decompress_ptr cinfo, int comp_index,
135
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
136
           JDIFFROW undiff_buf, JDIMENSION width)
137
0
{
138
0
  (void)cinfo;
139
0
  (void)comp_index;
140
0
  UNDIFFERENCE_2D(PREDICTOR4A);
141
0
  JPEG_UNUSED(Rc);
142
0
  JPEG_UNUSED(Rb);
143
0
}
144
145
METHODDEF(void)
146
jpeg_undifference4(j_decompress_ptr cinfo, int comp_index,
147
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
148
           JDIFFROW undiff_buf, JDIMENSION width)
149
{
150
  (void)cinfo;
151
  (void)comp_index;
152
  UNDIFFERENCE_2D(PREDICTOR4);
153
  JPEG_UNUSED(Rc);
154
  JPEG_UNUSED(Rb);
155
}
156
157
METHODDEF(void)
158
jpeg_undifference5(j_decompress_ptr cinfo, int comp_index,
159
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
160
           JDIFFROW undiff_buf, JDIMENSION width)
161
{
162
  (void)cinfo;
163
  (void)comp_index;
164
  SHIFT_TEMPS
165
  UNDIFFERENCE_2D(PREDICTOR5);
166
  JPEG_UNUSED(Rc);
167
  JPEG_UNUSED(Rb);
168
}
169
170
METHODDEF(void)
171
jpeg_undifference5a(j_decompress_ptr cinfo, int comp_index,
172
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
173
           JDIFFROW undiff_buf, JDIMENSION width)
174
0
{
175
0
  (void)cinfo;
176
0
  (void)comp_index;
177
0
  SHIFT_TEMPS
178
0
  UNDIFFERENCE_2D(PREDICTOR5A);
179
0
  JPEG_UNUSED(Rc);
180
0
  JPEG_UNUSED(Rb);
181
0
}
182
183
METHODDEF(void)
184
jpeg_undifference6(j_decompress_ptr cinfo, int comp_index,
185
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
186
           JDIFFROW undiff_buf, JDIMENSION width)
187
{
188
  (void)cinfo;
189
  (void)comp_index;
190
  SHIFT_TEMPS
191
  UNDIFFERENCE_2D(PREDICTOR6);
192
  JPEG_UNUSED(Rc);
193
  JPEG_UNUSED(Rb);
194
}
195
196
METHODDEF(void)
197
jpeg_undifference6a(j_decompress_ptr cinfo, int comp_index,
198
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
199
           JDIFFROW undiff_buf, JDIMENSION width)
200
0
{
201
0
  (void)cinfo;
202
0
  (void)comp_index;
203
0
  SHIFT_TEMPS
204
0
  UNDIFFERENCE_2D(PREDICTOR6A);
205
0
  JPEG_UNUSED(Rc);
206
0
  JPEG_UNUSED(Rb);
207
0
}
208
209
METHODDEF(void)
210
jpeg_undifference7(j_decompress_ptr cinfo, int comp_index,
211
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
212
           JDIFFROW undiff_buf, JDIMENSION width)
213
{
214
  (void)cinfo;
215
  (void)comp_index;
216
  SHIFT_TEMPS
217
  UNDIFFERENCE_2D(PREDICTOR7);
218
  JPEG_UNUSED(Rc);
219
  JPEG_UNUSED(Rb);
220
}
221
222
METHODDEF(void)
223
jpeg_undifference7a(j_decompress_ptr cinfo, int comp_index,
224
           const JDIFFROW diff_buf, const JDIFFROW prev_row,
225
           JDIFFROW undiff_buf, JDIMENSION width)
226
0
{
227
0
  (void)cinfo;
228
0
  (void)comp_index;
229
0
  SHIFT_TEMPS
230
0
  UNDIFFERENCE_2D(PREDICTOR7A);
231
0
  JPEG_UNUSED(Rc);
232
0
  JPEG_UNUSED(Rb);
233
0
}
234
235
236
/*
237
 * Undifferencer for the first row in a scan or restart interval.  The first
238
 * sample in the row is undifferenced using the special predictor constant
239
 * x=2^(P-Pt-1).  The rest of the samples are undifferenced using the
240
 * 1-D horizontal predictor (1).
241
 */
242
243
METHODDEF(void)
244
jpeg_undifference_first_row(j_decompress_ptr cinfo, int comp_index,
245
                const JDIFFROW diff_buf, JDIFFROW prev_row,
246
                JDIFFROW undiff_buf, JDIMENSION width)
247
{
248
  (void)prev_row;
249
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
250
251
  UNDIFFERENCE_1D(INITIAL_PREDICTORx);
252
253
  /*
254
   * Now that we have undifferenced the first row, we want to use the
255
   * undifferencer which corresponds to the predictor specified in the
256
   * scan header.
257
   */
258
  switch (cinfo->Ss) {
259
  case 1:
260
    losslsd->predict_undifference[comp_index] = jpeg_undifference1;
261
    break;
262
  case 2:
263
    losslsd->predict_undifference[comp_index] = jpeg_undifference2;
264
    break;
265
  case 3:
266
    losslsd->predict_undifference[comp_index] = jpeg_undifference3;
267
    break;
268
  case 4:
269
    /* DCMTK specific code that is only needed in the 16-bit library.
270
     * Enables workaround for faulty images with integer overflow in predictor 6.
271
     */
272
    if (cinfo->workaround_options & WORKAROUND_PREDICTOR6OVERFLOW)
273
      losslsd->predict_undifference[comp_index] = jpeg_undifference4a;
274
      else losslsd->predict_undifference[comp_index] = jpeg_undifference4;
275
    break;
276
  case 5:
277
    /* DCMTK specific code that is only needed in the 16-bit library.
278
     * Enables workaround for faulty images with integer overflow in predictor 6.
279
     */
280
    if (cinfo->workaround_options & WORKAROUND_PREDICTOR6OVERFLOW)
281
      losslsd->predict_undifference[comp_index] = jpeg_undifference5a;
282
      else losslsd->predict_undifference[comp_index] = jpeg_undifference5;
283
    break;
284
  case 6:
285
    /* DCMTK specific code that is only needed in the 16-bit library.
286
     * Enables workaround for faulty images with integer overflow in predictor 6.
287
     */
288
    if (cinfo->workaround_options & WORKAROUND_PREDICTOR6OVERFLOW)
289
      losslsd->predict_undifference[comp_index] = jpeg_undifference6a;
290
      else losslsd->predict_undifference[comp_index] = jpeg_undifference6;
291
    break;
292
  case 7:
293
    /* DCMTK specific code that is only needed in the 16-bit library.
294
     * Enables workaround for faulty images with integer overflow in predictor 6.
295
     */
296
    if (cinfo->workaround_options & WORKAROUND_PREDICTOR6OVERFLOW)
297
      losslsd->predict_undifference[comp_index] = jpeg_undifference7a;
298
      else losslsd->predict_undifference[comp_index] = jpeg_undifference7;
299
    break;
300
  }
301
}
302
303
304
/*
305
 * Initialize for an input processing pass.
306
 */
307
308
METHODDEF(void)
309
predict_start_pass (j_decompress_ptr cinfo)
310
{
311
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
312
  int ci;
313
314
  /* Check that the scan parameters Ss, Se, Ah, Al are OK for lossless JPEG.
315
   *
316
   * Ss is the predictor selection value (psv).  Legal values for sequential
317
   * lossless JPEG are: 1 <= psv <= 7.
318
   *
319
   * Se and Ah are not used and should be zero.
320
   *
321
   * Al specifies the point transform (Pt).  Legal values are: 0 <= Pt <= 15.
322
   */
323
  if (cinfo->Ss < 1 || cinfo->Ss > 7 ||
324
      cinfo->Se != 0 || cinfo->Ah != 0 ||
325
      cinfo->Al > 15)               /* need not check for < 0 */
326
    ERREXIT4(cinfo, JERR_BAD_LOSSLESS,
327
         cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
328
329
  /* Set undifference functions to first row function */
330
  for (ci = 0; ci < cinfo->num_components; ci++)
331
    losslsd->predict_undifference[ci] = jpeg_undifference_first_row;
332
}
333
334
335
/*
336
 * Module initialization routine for the undifferencer.
337
 */
338
339
GLOBAL(void)
340
jinit_undifferencer (j_decompress_ptr cinfo)
341
0
{
342
0
  j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
343
344
0
  losslsd->predict_start_pass = predict_start_pass;
345
0
  losslsd->predict_process_restart = predict_start_pass;
346
0
}
347
348
#endif /* D_LOSSLESS_SUPPORTED */
349