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.
8 * This file contains sample undifferencing (reconstruction) for lossless JPEG.
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.
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.
21 #define JPEG_INTERNALS
24 #include "jlossls.h" /* Private declarations for lossless codec */
27 #ifdef D_LOSSLESS_SUPPORTED
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))
32 /* Predictor for the first column of the remaining rows: Rb */
33 #define INITIAL_PREDICTOR2 GETJSAMPLE(prev_row[0])
37 * 1-Dimensional undifferencer routine.
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
44 * The reconstructed sample is supposed to be calculated modulo 2^16, so we
45 * logically AND the result with 0xFFFF.
48 #define UNDIFFERENCE_1D(INITIAL_PREDICTOR) \
49 unsigned int xindex; \
52 Ra = (diff_buf[0] + INITIAL_PREDICTOR) & 0xFFFF; \
55 for (xindex = 1; xindex < width; xindex++) { \
56 Ra = (diff_buf[xindex] + PREDICTOR1) & 0xFFFF; \
57 undiff_buf[xindex] = Ra; \
61 * 2-Dimensional undifferencer routine.
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.
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.
71 * The reconstructed sample is supposed to be calculated modulo 2^16, so we
72 * logically AND the result with 0xFFFF.
75 #define UNDIFFERENCE_2D_BUG(PREDICTOR) \
76 Rb = GETJSAMPLE(prev_row[0]); \
77 Ra = (diff_buf[0] + PREDICTOR2) & 0xFFFF; \
80 for (xindex = 1; xindex < width; xindex++) { \
82 Rb = GETJSAMPLE(prev_row[xindex]); \
83 Ra = (diff_buf[xindex] + PREDICTOR) & 0xFFFF; \
84 undiff_buf[xindex] = Ra; \
87 #define UNDIFFERENCE_2D(PREDICTOR) \
88 unsigned int xindex; \
91 Rb = GETJSAMPLE(prev_row[0]); \
92 Ra = (diff_buf[0] + PREDICTOR2) & 0xFFFF; \
95 for (xindex = 1; xindex < width; xindex++) { \
97 Rb = GETJSAMPLE(prev_row[xindex]); \
98 Ra = (diff_buf[xindex] + PREDICTOR) & 0xFFFF; \
99 undiff_buf[xindex] = Ra; \
104 * Undifferencers for the all rows but the first in a scan or restart interval.
105 * The first sample in the row is undifferenced using the vertical
106 * predictor (2). The rest of the samples are undifferenced using the
107 * predictor specified in the scan header.
111 jpeg_undifference1(j_decompress_ptr cinfo, int comp_index,
112 JDIFFROW diff_buf, JDIFFROW prev_row,
113 JDIFFROW undiff_buf, JDIMENSION width)
115 UNDIFFERENCE_1D(INITIAL_PREDICTOR2);
116 (void)cinfo;(void)comp_index;(void)diff_buf;(void)prev_row;(void)undiff_buf;(void)width;
120 jpeg_undifference2(j_decompress_ptr cinfo, int comp_index,
121 JDIFFROW diff_buf, JDIFFROW prev_row,
122 JDIFFROW undiff_buf, JDIMENSION width)
124 UNDIFFERENCE_2D(PREDICTOR2);
125 (void)cinfo;(void)comp_index;(void)diff_buf;(void)prev_row;(void)undiff_buf;(void)width;
129 jpeg_undifference3(j_decompress_ptr cinfo, int comp_index,
130 JDIFFROW diff_buf, JDIFFROW prev_row,
131 JDIFFROW undiff_buf, JDIMENSION width)
133 UNDIFFERENCE_2D(PREDICTOR3);
134 (void)cinfo;(void)comp_index;(void)diff_buf;(void)prev_row;(void)undiff_buf;(void)width;
138 jpeg_undifference4(j_decompress_ptr cinfo, int comp_index,
139 JDIFFROW diff_buf, JDIFFROW prev_row,
140 JDIFFROW undiff_buf, JDIMENSION width)
142 UNDIFFERENCE_2D(PREDICTOR4);
143 (void)cinfo;(void)comp_index;(void)diff_buf;(void)prev_row;(void)undiff_buf;(void)width;
147 jpeg_undifference5(j_decompress_ptr cinfo, int comp_index,
148 JDIFFROW diff_buf, JDIFFROW prev_row,
149 JDIFFROW undiff_buf, JDIMENSION width)
152 UNDIFFERENCE_2D(PREDICTOR5);
153 (void)cinfo;(void)comp_index;(void)diff_buf;(void)prev_row;(void)undiff_buf;(void)width;
156 #ifdef SUPPORT_DICOMOBJECTS_BUG
158 static int dicomobjectsbug = -1; /* 0 == nobug, 1 == bug */
162 jpeg_undifference6(j_decompress_ptr cinfo, int comp_index,
163 JDIFFROW diff_buf, JDIFFROW prev_row,
164 JDIFFROW undiff_buf, JDIMENSION width)
166 #ifdef SUPPORT_DICOMOBJECTS_BUG
171 if( dicomobjectsbug == -1 )
173 dicomobjectsbug = 0; /* no bug by default */
175 Rb = GETJSAMPLE(prev_row[0]);
176 Ra = (diff_buf[0] + PREDICTOR2) & 0xFFFF;
178 temp = min = max = undiff_buf[0];
180 for (xindex = 1; xindex < width; xindex++) {
182 Rb = GETJSAMPLE(prev_row[xindex]);
183 Ra = (diff_buf[xindex] + PREDICTOR6) & 0xFFFF;
185 min = temp < min ? temp : min;
186 max = temp > max ? temp : max;
188 if( (max - min) > 50000) /* magic number */
195 UNDIFFERENCE_2D_BUG(PREDICTOR6_BUG);
199 UNDIFFERENCE_2D_BUG(PREDICTOR6);
203 UNDIFFERENCE_2D(PREDICTOR6);
205 (void)comp_index;(void)cinfo;
209 jpeg_undifference7(j_decompress_ptr cinfo, int comp_index,
210 JDIFFROW diff_buf, JDIFFROW prev_row,
211 JDIFFROW undiff_buf, JDIMENSION width)
214 UNDIFFERENCE_2D(PREDICTOR7);
215 (void)cinfo;(void)comp_index;(void)diff_buf;(void)prev_row;(void)undiff_buf;(void)width;
220 * Undifferencer for the first row in a scan or restart interval. The first
221 * sample in the row is undifferenced using the special predictor constant
222 * x=2^(P-Pt-1). The rest of the samples are undifferenced using the
223 * 1-D horizontal predictor (1).
227 jpeg_undifference_first_row(j_decompress_ptr cinfo, int comp_index,
228 JDIFFROW diff_buf, JDIFFROW prev_row,
229 JDIFFROW undiff_buf, JDIMENSION width)
231 j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
233 UNDIFFERENCE_1D(INITIAL_PREDICTORx);
237 * Now that we have undifferenced the first row, we want to use the
238 * undifferencer which corresponds to the predictor specified in the
243 losslsd->predict_undifference[comp_index] = jpeg_undifference1;
246 losslsd->predict_undifference[comp_index] = jpeg_undifference2;
249 losslsd->predict_undifference[comp_index] = jpeg_undifference3;
252 losslsd->predict_undifference[comp_index] = jpeg_undifference4;
255 losslsd->predict_undifference[comp_index] = jpeg_undifference5;
258 losslsd->predict_undifference[comp_index] = jpeg_undifference6;
261 losslsd->predict_undifference[comp_index] = jpeg_undifference7;
268 * Initialize for an input processing pass.
272 predict_start_pass (j_decompress_ptr cinfo)
274 j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
277 /* Check that the scan parameters Ss, Se, Ah, Al are OK for lossless JPEG.
279 * Ss is the predictor selection value (psv). Legal values for sequential
280 * lossless JPEG are: 1 <= psv <= 7.
282 * Se and Ah are not used and should be zero.
284 * Al specifies the point transform (Pt). Legal values are: 0 <= Pt <= 15.
286 if (cinfo->Ss < 1 || cinfo->Ss > 7 ||
287 cinfo->Se != 0 || cinfo->Ah != 0 ||
288 cinfo->Al > 15) /* need not check for < 0 */
289 ERREXIT4(cinfo, JERR_BAD_LOSSLESS,
290 cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
292 /* Set undifference functions to first row function */
293 for (ci = 0; ci < cinfo->num_components; ci++)
294 losslsd->predict_undifference[ci] = jpeg_undifference_first_row;
299 * Module initialization routine for the undifferencer.
303 jinit_undifferencer (j_decompress_ptr cinfo)
305 j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec;
307 losslsd->predict_start_pass = predict_start_pass;
308 losslsd->predict_process_restart = predict_start_pass;
311 #endif /* D_LOSSLESS_SUPPORTED */