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 differencing 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 differencing
13 * functions for each case.
15 * We are able to avoid duplicating source code by implementing the predictors
16 * and differencers as macros. Each of the differencing functions are
17 * simply wrappers around a DIFFERENCE 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 C_LOSSLESS_SUPPORTED
29 /* Private predictor object */
32 /* MCU-rows left in the restart interval for each component */
33 unsigned int restart_rows_to_go[MAX_COMPONENTS];
36 typedef c_predictor * c_pred_ptr;
38 /* Forward declarations */
39 LOCAL(void) reset_predictor
40 JPP((j_compress_ptr cinfo, int ci));
41 METHODDEF(void) start_pass
42 JPP((j_compress_ptr cinfo));
45 /* Predictor for the first column of the first row: 2^(P-Pt-1) */
46 #define INITIAL_PREDICTORx (1 << (cinfo->data_precision - cinfo->Al - 1))
48 /* Predictor for the first column of the remaining rows: Rb */
49 #define INITIAL_PREDICTOR2 GETJSAMPLE(prev_row[0])
53 * 1-Dimensional differencer routine.
55 * This macro implements the 1-D horizontal predictor (1). INITIAL_PREDICTOR
56 * is used as the special case predictor for the first column, which must be
57 * either INITIAL_PREDICTOR2 or INITIAL_PREDICTORx. The remaining samples
61 #define DIFFERENCE_1D(INITIAL_PREDICTOR) \
62 j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; \
63 c_pred_ptr pred = (c_pred_ptr) losslsc->pred_private; \
64 boolean restart = FALSE; \
65 unsigned int xindex; \
68 samp = GETJSAMPLE(input_buf[0]); \
69 diff_buf[0] = samp - INITIAL_PREDICTOR; \
71 for (xindex = 1; xindex < width; xindex++) { \
73 samp = GETJSAMPLE(input_buf[xindex]); \
74 diff_buf[xindex] = samp - PREDICTOR1; \
77 /* Account for restart interval (no-op if not using restarts) */ \
78 if (cinfo->restart_interval) { \
79 if (--(pred->restart_rows_to_go[ci]) == 0) { \
80 reset_predictor(cinfo, ci); \
87 * 2-Dimensional differencer routine.
89 * This macro implements the 2-D horizontal predictors (#2-7). PREDICTOR2 is
90 * used as the special case predictor for the first column. The remaining
91 * samples use PREDICTOR, which is a function of Ra, Rb, Rc.
93 * Because prev_row and output_buf may point to the same storage area (in an
94 * interleaved image with Vi=1, for example), we must take care to buffer Rb/Rc
95 * before writing the current reconstructed sample value into output_buf.
98 #define DIFFERENCE_2D(PREDICTOR) \
99 j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; \
100 c_pred_ptr pred = (c_pred_ptr) losslsc->pred_private; \
101 unsigned int xindex; \
102 int samp, Ra, Rb, Rc; \
104 Rb = GETJSAMPLE(prev_row[0]); \
105 samp = GETJSAMPLE(input_buf[0]); \
106 diff_buf[0] = samp - PREDICTOR2; \
108 for (xindex = 1; xindex < width; xindex++) { \
110 Rb = GETJSAMPLE(prev_row[xindex]); \
112 samp = GETJSAMPLE(input_buf[xindex]); \
113 diff_buf[xindex] = samp - PREDICTOR; \
116 /* Account for restart interval (no-op if not using restarts) */ \
117 if (cinfo->restart_interval) { \
118 if (--pred->restart_rows_to_go[ci] == 0) \
119 reset_predictor(cinfo, ci); \
124 * Differencers for the all rows but the first in a scan or restart interval.
125 * The first sample in the row is differenced using the vertical
126 * predictor (2). The rest of the samples are differenced using the
127 * predictor specified in the scan header.
131 jpeg_difference1(j_compress_ptr cinfo, int ci,
132 JSAMPROW input_buf, JSAMPROW prev_row,
133 JDIFFROW diff_buf, JDIMENSION width)
135 DIFFERENCE_1D(INITIAL_PREDICTOR2);
139 jpeg_difference2(j_compress_ptr cinfo, int ci,
140 JSAMPROW input_buf, JSAMPROW prev_row,
141 JDIFFROW diff_buf, JDIMENSION width)
143 DIFFERENCE_2D(PREDICTOR2);
147 jpeg_difference3(j_compress_ptr cinfo, int ci,
148 JSAMPROW input_buf, JSAMPROW prev_row,
149 JDIFFROW diff_buf, JDIMENSION width)
151 DIFFERENCE_2D(PREDICTOR3);
155 jpeg_difference4(j_compress_ptr cinfo, int ci,
156 JSAMPROW input_buf, JSAMPROW prev_row,
157 JDIFFROW diff_buf, JDIMENSION width)
159 DIFFERENCE_2D(PREDICTOR4);
163 jpeg_difference5(j_compress_ptr cinfo, int ci,
164 JSAMPROW input_buf, JSAMPROW prev_row,
165 JDIFFROW diff_buf, JDIMENSION width)
168 DIFFERENCE_2D(PREDICTOR5);
172 jpeg_difference6(j_compress_ptr cinfo, int ci,
173 JSAMPROW input_buf, JSAMPROW prev_row,
174 JDIFFROW diff_buf, JDIMENSION width)
177 DIFFERENCE_2D(PREDICTOR6);
181 jpeg_difference7(j_compress_ptr cinfo, int ci,
182 JSAMPROW input_buf, JSAMPROW prev_row,
183 JDIFFROW diff_buf, JDIMENSION width)
186 DIFFERENCE_2D(PREDICTOR7);
191 * Differencer for the first row in a scan or restart interval. The first
192 * sample in the row is differenced using the special predictor constant
193 * x=2^(P-Pt-1). The rest of the samples are differenced using the
194 * 1-D horizontal predictor (1).
198 jpeg_difference_first_row(j_compress_ptr cinfo, int ci,
199 JSAMPROW input_buf, JSAMPROW prev_row,
200 JDIFFROW diff_buf, JDIMENSION width)
202 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 */