Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / compiler / libjpeg / main / jcpred.c
blobeb97b75f852ef4e6132afefa9bad9ce044947d2f
1 /*
2 $Id$
3 */
5 /*
6 * jcpred.c
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
26 #include "jinclude.h"
27 #include "jpeglib.h"
28 #include "jlossls.h" /* Private declarations for lossless codec */
31 #ifdef C_LOSSLESS_SUPPORTED
33 /* Private predictor object */
35 typedef struct {
36 /* MCU-rows left in the restart interval for each component */
37 unsigned int restart_rows_to_go[MAX_COMPONENTS];
38 } c_predictor;
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
62 * use PREDICTOR1.
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; \
69 int xindex; \
70 int samp, Ra; \
72 samp = GETJSAMPLE(input_buf[0]); \
73 diff_buf[0] = samp - INITIAL_PREDICTOR; \
75 for (xindex = 1; xindex < width; xindex++) { \
76 Ra = samp; \
77 samp = GETJSAMPLE(input_buf[xindex]); \
78 diff_buf[xindex] = samp - PREDICTOR1; \
79 } \
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); \
85 restart = TRUE; \
86 } \
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; \
105 int xindex; \
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++) { \
113 Rc = Rb; \
114 Rb = GETJSAMPLE(prev_row[xindex]); \
115 Ra = samp; \
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.
134 METHODDEF(void)
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);
142 METHODDEF(void)
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);
150 METHODDEF(void)
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);
158 METHODDEF(void)
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);
166 METHODDEF(void)
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);
174 METHODDEF(void)
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);
182 METHODDEF(void)
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).
198 METHODDEF(void)
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
208 * scan header.
210 * Note that we don't to do this if we have just reset the predictor
211 * for a new restart interval.
213 if (!restart) {
214 switch (cinfo->Ss) {
215 case 1:
216 losslsc->predict_difference[ci] = jpeg_difference1;
217 break;
218 case 2:
219 losslsc->predict_difference[ci] = jpeg_difference2;
220 break;
221 case 3:
222 losslsc->predict_difference[ci] = jpeg_difference3;
223 break;
224 case 4:
225 losslsc->predict_difference[ci] = jpeg_difference4;
226 break;
227 case 5:
228 losslsc->predict_difference[ci] = jpeg_difference5;
229 break;
230 case 6:
231 losslsc->predict_difference[ci] = jpeg_difference6;
232 break;
233 case 7:
234 losslsc->predict_difference[ci] = jpeg_difference7;
235 break;
241 * Reset predictor at the start of a pass or restart interval.
244 LOCAL(void)
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.
263 METHODDEF(void)
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;
268 int ci;
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.
287 JGLOBAL(void)
288 jinit_differencer (j_compress_ptr cinfo)
290 j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec;
291 c_pred_ptr pred;
293 pred = (c_pred_ptr)
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 */