8 * Copyright (C) 1998, Thomas G. Lane.
9 * This file is part of the Independent JPEG Group's software.
10 * For conditions of distribution and use, see the accompanying README file.
12 * This file contains sample differencing for lossless JPEG.
14 * In order to avoid paying the performance penalty of having to check the
15 * predictor being used and the row being processed for each call of the
16 * undifferencer, and to promote optimization, we have separate differencing
17 * functions for each case.
19 * We are able to avoid duplicating source code by implementing the predictors
20 * and differencers as macros. Each of the differencing functions are
21 * simply wrappers around a DIFFERENCE macro with the appropriate PREDICTOR
22 * macro passed as an argument.
25 #define JPEG_INTERNALS
28 #include "jlossls.h" /* Private declarations for lossless codec */
31 #ifdef C_LOSSLESS_SUPPORTED
33 /* Private predictor object */
36 /* MCU-rows left in the restart interval for each component */
37 unsigned int restart_rows_to_go
[MAX_COMPONENTS
];
40 typedef c_predictor
* c_pred_ptr
;
42 /* Forward declarations */
43 LOCAL(void) reset_predictor
44 JPP((j_compress_ptr cinfo
, int ci
));
45 METHODDEF(void) start_pass
46 JPP((j_compress_ptr cinfo
));
49 /* Predictor for the first column of the first row: 2^(P-Pt-1) */
50 #define INITIAL_PREDICTORx (1 << (cinfo->data_precision - cinfo->Al - 1))
52 /* Predictor for the first column of the remaining rows: Rb */
53 #define INITIAL_PREDICTOR2 GETJSAMPLE(prev_row[0])
57 * 1-Dimensional differencer routine.
59 * This macro implements the 1-D horizontal predictor (1). INITIAL_PREDICTOR
60 * is used as the special case predictor for the first column, which must be
61 * either INITIAL_PREDICTOR2 or INITIAL_PREDICTORx. The remaining samples
65 #define DIFFERENCE_1D(INITIAL_PREDICTOR) \
66 j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; \
67 c_pred_ptr pred = (c_pred_ptr) losslsc->pred_private; \
68 boolean restart = FALSE; \
72 samp = GETJSAMPLE(input_buf[0]); \
73 diff_buf[0] = samp - INITIAL_PREDICTOR; \
75 for (xindex = 1; xindex < width; xindex++) { \
77 samp = GETJSAMPLE(input_buf[xindex]); \
78 diff_buf[xindex] = samp - PREDICTOR1; \
81 /* Account for restart interval (no-op if not using restarts) */ \
82 if (cinfo->restart_interval) { \
83 if (--(pred->restart_rows_to_go[ci]) == 0) { \
84 reset_predictor(cinfo, ci); \
91 * 2-Dimensional differencer routine.
93 * This macro implements the 2-D horizontal predictors (#2-7). PREDICTOR2 is
94 * used as the special case predictor for the first column. The remaining
95 * samples use PREDICTOR, which is a function of Ra, Rb, Rc.
97 * Because prev_row and output_buf may point to the same storage area (in an
98 * interleaved image with Vi=1, for example), we must take care to buffer Rb/Rc
99 * before writing the current reconstructed sample value into output_buf.
102 #define DIFFERENCE_2D(PREDICTOR) \
103 j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; \
104 c_pred_ptr pred = (c_pred_ptr) losslsc->pred_private; \
106 int samp, Ra, Rb, Rc; \
108 Rb = GETJSAMPLE(prev_row[0]); \
109 samp = GETJSAMPLE(input_buf[0]); \
110 diff_buf[0] = samp - PREDICTOR2; \
112 for (xindex = 1; xindex < width; xindex++) { \
114 Rb = GETJSAMPLE(prev_row[xindex]); \
116 samp = GETJSAMPLE(input_buf[xindex]); \
117 diff_buf[xindex] = samp - PREDICTOR; \
120 /* Account for restart interval (no-op if not using restarts) */ \
121 if (cinfo->restart_interval) { \
122 if (--pred->restart_rows_to_go[ci] == 0) \
123 reset_predictor(cinfo, ci); \
128 * Differencers for the all rows but the first in a scan or restart interval.
129 * The first sample in the row is differenced using the vertical
130 * predictor (2). The rest of the samples are differenced using the
131 * predictor specified in the scan header.
135 jpeg_difference1(j_compress_ptr cinfo
, int ci
,
136 JSAMPROW input_buf
, JSAMPROW prev_row
,
137 JDIFFROW diff_buf
, JDIMENSION width
)
139 DIFFERENCE_1D(INITIAL_PREDICTOR2
);
143 jpeg_difference2(j_compress_ptr cinfo
, int ci
,
144 JSAMPROW input_buf
, JSAMPROW prev_row
,
145 JDIFFROW diff_buf
, JDIMENSION width
)
147 DIFFERENCE_2D(PREDICTOR2
);
151 jpeg_difference3(j_compress_ptr cinfo
, int ci
,
152 JSAMPROW input_buf
, JSAMPROW prev_row
,
153 JDIFFROW diff_buf
, JDIMENSION width
)
155 DIFFERENCE_2D(PREDICTOR3
);
159 jpeg_difference4(j_compress_ptr cinfo
, int ci
,
160 JSAMPROW input_buf
, JSAMPROW prev_row
,
161 JDIFFROW diff_buf
, JDIMENSION width
)
163 DIFFERENCE_2D(PREDICTOR4
);
167 jpeg_difference5(j_compress_ptr cinfo
, int ci
,
168 JSAMPROW input_buf
, JSAMPROW prev_row
,
169 JDIFFROW diff_buf
, JDIMENSION width
)
171 DIFFERENCE_2D(PREDICTOR5
);
175 jpeg_difference6(j_compress_ptr cinfo
, int ci
,
176 JSAMPROW input_buf
, JSAMPROW prev_row
,
177 JDIFFROW diff_buf
, JDIMENSION width
)
179 DIFFERENCE_2D(PREDICTOR6
);
183 jpeg_difference7(j_compress_ptr cinfo
, int ci
,
184 JSAMPROW input_buf
, JSAMPROW prev_row
,
185 JDIFFROW diff_buf
, JDIMENSION width
)
187 DIFFERENCE_2D(PREDICTOR7
);
192 * Differencer for the first row in a scan or restart interval. The first
193 * sample in the row is differenced using the special predictor constant
194 * x=2^(P-Pt-1). The rest of the samples are differenced using the
195 * 1-D horizontal predictor (1).
199 jpeg_difference_first_row(j_compress_ptr cinfo
, int ci
,
200 JSAMPROW input_buf
, JSAMPROW prev_row
,
201 JDIFFROW diff_buf
, JDIMENSION width
)
203 DIFFERENCE_1D(INITIAL_PREDICTORx
);
206 * Now that we have differenced the first row, we want to use the
207 * differencer which corresponds to the predictor specified in the
210 * Note that we don't to do this if we have just reset the predictor
211 * for a new restart interval.
216 losslsc
->predict_difference
[ci
] = jpeg_difference1
;
219 losslsc
->predict_difference
[ci
] = jpeg_difference2
;
222 losslsc
->predict_difference
[ci
] = jpeg_difference3
;
225 losslsc
->predict_difference
[ci
] = jpeg_difference4
;
228 losslsc
->predict_difference
[ci
] = jpeg_difference5
;
231 losslsc
->predict_difference
[ci
] = jpeg_difference6
;
234 losslsc
->predict_difference
[ci
] = jpeg_difference7
;
241 * Reset predictor at the start of a pass or restart interval.
245 reset_predictor (j_compress_ptr cinfo
, int ci
)
247 j_lossless_c_ptr losslsc
= (j_lossless_c_ptr
) cinfo
->codec
;
248 c_pred_ptr pred
= (c_pred_ptr
) losslsc
->pred_private
;
250 /* Initialize restart counter */
251 pred
->restart_rows_to_go
[ci
] =
252 cinfo
->restart_interval
/ cinfo
->MCUs_per_row
;
254 /* Set difference function to first row function */
255 losslsc
->predict_difference
[ci
] = jpeg_difference_first_row
;
260 * Initialize for an input processing pass.
264 start_pass (j_compress_ptr cinfo
)
266 j_lossless_c_ptr losslsc
= (j_lossless_c_ptr
) cinfo
->codec
;
267 c_pred_ptr pred
= (c_pred_ptr
) losslsc
->pred_private
;
270 /* Check that the restart interval is an integer multiple of the number
271 * of MCU in an MCU-row.
273 if (cinfo
->restart_interval
% cinfo
->MCUs_per_row
!= 0)
274 ERREXIT2(cinfo
, JERR_BAD_RESTART
,
275 cinfo
->restart_interval
, cinfo
->MCUs_per_row
);
277 /* Set predictors for start of pass */
278 for (ci
= 0; ci
< cinfo
->num_components
; ci
++)
279 reset_predictor(cinfo
, ci
);
284 * Module initialization routine for the differencer.
288 jinit_differencer (j_compress_ptr cinfo
)
290 j_lossless_c_ptr losslsc
= (j_lossless_c_ptr
) cinfo
->codec
;
294 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
295 SIZEOF(c_predictor
));
296 losslsc
->pred_private
= (void *) pred
;
297 losslsc
->predict_start_pass
= start_pass
;
300 #endif /* C_LOSSLESS_SUPPORTED */