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