8 * Copyright (C) 1994-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 the [un]difference buffer controller for decompression.
13 * This controller is the top level of the lossless JPEG decompressor proper.
14 * The difference buffer lies between the entropy decoding and
15 * prediction/undifferencing steps. The undifference buffer lies between the
16 * prediction/undifferencing and scaling steps.
18 * In buffered-image mode, this controller is the interface between
19 * input-oriented processing and output-oriented processing.
22 #define JPEG_INTERNALS
28 #ifdef D_LOSSLESS_SUPPORTED
30 /* Private buffer controller object */
33 /* These variables keep track of the current location of the input side. */
34 /* cinfo->input_iMCU_row is also used for this. */
35 JDIMENSION MCU_ctr
; /* counts MCUs processed in current row */
36 unsigned int restart_rows_to_go
; /* MCU-rows left in this restart interval */
37 unsigned int MCU_vert_offset
; /* counts MCU rows within iMCU row */
38 unsigned int MCU_rows_per_iMCU_row
; /* number of such rows needed */
40 /* The output side's location is represented by cinfo->output_iMCU_row. */
42 JDIFFARRAY diff_buf
[MAX_COMPONENTS
]; /* iMCU row of differences */
43 JDIFFARRAY undiff_buf
[MAX_COMPONENTS
]; /* iMCU row of undiff'd samples */
45 #ifdef D_MULTISCAN_FILES_SUPPORTED
46 /* In multi-pass modes, we need a virtual sample array for each component. */
47 jvirt_sarray_ptr whole_image
[MAX_COMPONENTS
];
51 typedef d_diff_controller
* d_diff_ptr
;
53 /* Forward declarations */
54 METHODDEF(int) decompress_data
55 JPP((j_decompress_ptr cinfo
, JSAMPIMAGE output_buf
));
56 #ifdef D_MULTISCAN_FILES_SUPPORTED
57 METHODDEF(int) output_data
58 JPP((j_decompress_ptr cinfo
, JSAMPIMAGE output_buf
));
63 start_iMCU_row (j_decompress_ptr cinfo
)
64 /* Reset within-iMCU-row counters for a new row (input side) */
66 j_lossless_d_ptr losslsd
= (j_lossless_d_ptr
) cinfo
->codec
;
67 d_diff_ptr diff
= (d_diff_ptr
) losslsd
->diff_private
;
69 /* In an interleaved scan, an MCU row is the same as an iMCU row.
70 * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
71 * But at the bottom of the image, process only what's left.
73 if (cinfo
->comps_in_scan
> 1) {
74 diff
->MCU_rows_per_iMCU_row
= 1;
76 if (cinfo
->input_iMCU_row
< (cinfo
->total_iMCU_rows
-1))
77 diff
->MCU_rows_per_iMCU_row
= cinfo
->cur_comp_info
[0]->v_samp_factor
;
79 diff
->MCU_rows_per_iMCU_row
= cinfo
->cur_comp_info
[0]->last_row_height
;
83 diff
->MCU_vert_offset
= 0;
88 * Initialize for an input processing pass.
92 start_input_pass (j_decompress_ptr cinfo
)
94 j_lossless_d_ptr losslsd
= (j_lossless_d_ptr
) cinfo
->codec
;
95 d_diff_ptr diff
= (d_diff_ptr
) losslsd
->diff_private
;
97 /* Check that the restart interval is an integer multiple of the number
98 * of MCU in an MCU-row.
100 if (cinfo
->restart_interval
% cinfo
->MCUs_per_row
!= 0)
101 ERREXIT2(cinfo
, JERR_BAD_RESTART
,
102 cinfo
->restart_interval
, cinfo
->MCUs_per_row
);
104 /* Initialize restart counter */
105 diff
->restart_rows_to_go
= cinfo
->restart_interval
/ cinfo
->MCUs_per_row
;
107 cinfo
->input_iMCU_row
= 0;
108 start_iMCU_row(cinfo
);
113 * Check for a restart marker & resynchronize decoder, undifferencer.
114 * Returns FALSE if must suspend.
118 process_restart (j_decompress_ptr cinfo
)
120 j_lossless_d_ptr losslsd
= (j_lossless_d_ptr
) cinfo
->codec
;
121 d_diff_ptr diff
= (d_diff_ptr
) losslsd
->diff_private
;
123 if (! (*losslsd
->entropy_process_restart
) (cinfo
))
126 (*losslsd
->predict_process_restart
) (cinfo
);
128 /* Reset restart counter */
129 diff
->restart_rows_to_go
= cinfo
->restart_interval
/ cinfo
->MCUs_per_row
;
136 * Initialize for an output processing pass.
140 start_output_pass (j_decompress_ptr cinfo
)
142 cinfo
->output_iMCU_row
= 0;
147 * Decompress and return some data in the supplied buffer.
148 * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
149 * Input and output must run in lockstep since we have only a one-MCU buffer.
150 * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
152 * NB: output_buf contains a plane for each component in image,
153 * which we index according to the component's SOF position.
157 decompress_data (j_decompress_ptr cinfo
, JSAMPIMAGE output_buf
)
159 j_lossless_d_ptr losslsd
= (j_lossless_d_ptr
) cinfo
->codec
;
160 d_diff_ptr diff
= (d_diff_ptr
) losslsd
->diff_private
;
161 JDIMENSION MCU_col_num
; /* index of current MCU within row */
162 JDIMENSION MCU_count
; /* number of MCUs decoded */
163 JDIMENSION last_iMCU_row
= cinfo
->total_iMCU_rows
- 1;
164 int comp
, ci
, yoffset
, row
, prev_row
;
165 jpeg_component_info
*compptr
;
167 /* Loop to process as much as one whole iMCU row */
168 for (yoffset
= diff
->MCU_vert_offset
; yoffset
< diff
->MCU_rows_per_iMCU_row
;
171 /* Process restart marker if needed; may have to suspend */
172 if (cinfo
->restart_interval
) {
173 if (diff
->restart_rows_to_go
== 0)
174 if (! process_restart(cinfo
))
175 return JPEG_SUSPENDED
;
178 MCU_col_num
= diff
->MCU_ctr
;
179 /* Try to fetch an MCU-row (or remaining portion of suspended MCU-row). */
181 (*losslsd
->entropy_decode_mcus
) (cinfo
,
182 diff
->diff_buf
, yoffset
, MCU_col_num
,
183 cinfo
->MCUs_per_row
- MCU_col_num
);
184 if (MCU_count
!= cinfo
->MCUs_per_row
- MCU_col_num
) {
185 /* Suspension forced; update state counters and exit */
186 diff
->MCU_vert_offset
= yoffset
;
187 diff
->MCU_ctr
+= MCU_count
;
188 return JPEG_SUSPENDED
;
191 /* Account for restart interval (no-op if not using restarts) */
192 diff
->restart_rows_to_go
--;
194 /* Completed an MCU row, but perhaps not an iMCU row */
199 * Undifference and scale each scanline of the disassembled MCU-row
200 * separately. We do not process dummy samples at the end of a scanline
201 * or dummy rows at the end of the image.
203 for (comp
= 0; comp
< cinfo
->comps_in_scan
; comp
++) {
204 compptr
= cinfo
->cur_comp_info
[comp
];
205 ci
= compptr
->component_index
;
206 for (row
= 0, prev_row
= compptr
->v_samp_factor
- 1;
207 row
< (cinfo
->input_iMCU_row
== last_iMCU_row
?
208 compptr
->last_row_height
: compptr
->v_samp_factor
);
209 prev_row
= row
, row
++) {
210 (*losslsd
->predict_undifference
[ci
]) (cinfo
, ci
,
211 diff
->diff_buf
[ci
][row
],
212 diff
->undiff_buf
[ci
][prev_row
],
213 diff
->undiff_buf
[ci
][row
],
214 compptr
->width_in_data_units
);
215 (*losslsd
->scaler_scale
) (cinfo
, diff
->undiff_buf
[ci
][row
],
217 compptr
->width_in_data_units
);
221 /* Completed the iMCU row, advance counters for next one.
223 * NB: output_data will increment output_iMCU_row.
224 * This counter is not needed for the single-pass case
225 * or the input side of the multi-pass case.
227 if (++(cinfo
->input_iMCU_row
) < cinfo
->total_iMCU_rows
) {
228 start_iMCU_row(cinfo
);
229 return JPEG_ROW_COMPLETED
;
231 /* Completed the scan */
232 (*cinfo
->inputctl
->finish_input_pass
) (cinfo
);
233 return JPEG_SCAN_COMPLETED
;
238 * Dummy consume-input routine for single-pass operation.
242 dummy_consume_data (j_decompress_ptr cinfo
)
244 return JPEG_SUSPENDED
; /* Always indicate nothing was done */
248 #ifdef D_MULTISCAN_FILES_SUPPORTED
251 * Consume input data and store it in the full-image sample buffer.
252 * We read as much as one fully interleaved MCU row ("iMCU" row) per call,
253 * ie, v_samp_factor rows for each component in the scan.
254 * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
258 consume_data (j_decompress_ptr cinfo
)
260 j_lossless_d_ptr losslsd
= (j_lossless_d_ptr
) cinfo
->codec
;
261 d_diff_ptr diff
= (d_diff_ptr
) losslsd
->diff_private
;
262 JDIMENSION MCU_col_num
; /* index of current MCU within row */
263 JDIMENSION MCU_count
; /* number of MCUs decoded */
264 JDIMENSION last_iMCU_row
= cinfo
->total_iMCU_rows
- 1;
265 int comp
, ci
, yoffset
, row
, prev_row
;
266 JSAMPARRAY buffer
[MAX_COMPS_IN_SCAN
];
267 jpeg_component_info
*compptr
;
269 /* Align the virtual buffers for the components used in this scan. */
270 for (comp
= 0; comp
< cinfo
->comps_in_scan
; comp
++) {
271 compptr
= cinfo
->cur_comp_info
[comp
];
272 ci
= compptr
->component_index
;
273 buffer
[ci
] = (*cinfo
->mem
->access_virt_sarray
)
274 ((j_common_ptr
) cinfo
, diff
->whole_image
[ci
],
275 cinfo
->input_iMCU_row
* compptr
->v_samp_factor
,
276 (JDIMENSION
) compptr
->v_samp_factor
, TRUE
);
279 return decompress_data(cinfo
, buffer
);
284 * Output some data from the full-image buffer sample in the multi-pass case.
285 * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
286 * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
288 * NB: output_buf contains a plane for each component in image.
292 output_data (j_decompress_ptr cinfo
, JSAMPIMAGE output_buf
)
294 j_lossless_d_ptr losslsd
= (j_lossless_d_ptr
) cinfo
->codec
;
295 d_diff_ptr diff
= (d_diff_ptr
) losslsd
->diff_private
;
296 JDIMENSION last_iMCU_row
= cinfo
->total_iMCU_rows
- 1;
297 int ci
, samp_rows
, row
;
299 jpeg_component_info
*compptr
;
301 /* Force some input to be done if we are getting ahead of the input. */
302 while (cinfo
->input_scan_number
< cinfo
->output_scan_number
||
303 (cinfo
->input_scan_number
== cinfo
->output_scan_number
&&
304 cinfo
->input_iMCU_row
<= cinfo
->output_iMCU_row
)) {
305 if ((*cinfo
->inputctl
->consume_input
)(cinfo
) == JPEG_SUSPENDED
)
306 return JPEG_SUSPENDED
;
309 /* OK, output from the virtual arrays. */
310 for (ci
= 0, compptr
= cinfo
->comp_info
; ci
< cinfo
->num_components
;
312 /* Align the virtual buffer for this component. */
313 buffer
= (*cinfo
->mem
->access_virt_sarray
)
314 ((j_common_ptr
) cinfo
, diff
->whole_image
[ci
],
315 cinfo
->output_iMCU_row
* compptr
->v_samp_factor
,
316 (JDIMENSION
) compptr
->v_samp_factor
, FALSE
);
318 if (cinfo
->output_iMCU_row
< last_iMCU_row
)
319 samp_rows
= compptr
->v_samp_factor
;
321 /* NB: can't use last_row_height here; it is input-side-dependent! */
322 samp_rows
= (int) (compptr
->height_in_data_units
% compptr
->v_samp_factor
);
323 if (samp_rows
== 0) samp_rows
= compptr
->v_samp_factor
;
326 for (row
= 0; row
< samp_rows
; row
++) {
327 MEMCOPY(output_buf
[ci
][row
], buffer
[row
],
328 compptr
->width_in_data_units
* SIZEOF(JSAMPLE
));
332 if (++(cinfo
->output_iMCU_row
) < cinfo
->total_iMCU_rows
)
333 return JPEG_ROW_COMPLETED
;
334 return JPEG_SCAN_COMPLETED
;
337 #endif /* D_MULTISCAN_FILES_SUPPORTED */
341 * Initialize difference buffer controller.
345 jinit_d_diff_controller (j_decompress_ptr cinfo
, boolean need_full_buffer
)
347 j_lossless_d_ptr losslsd
= (j_lossless_d_ptr
) cinfo
->codec
;
350 jpeg_component_info
*compptr
;
353 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
354 SIZEOF(d_diff_controller
));
355 losslsd
->diff_private
= (void *) diff
;
356 losslsd
->diff_start_input_pass
= start_input_pass
;
357 losslsd
->pub
.start_output_pass
= start_output_pass
;
359 /* Create the [un]difference buffers. */
360 for (ci
= 0, compptr
= cinfo
->comp_info
; ci
< cinfo
->num_components
;
362 diff
->diff_buf
[ci
] = (*cinfo
->mem
->alloc_darray
)
363 ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
364 (JDIMENSION
) jround_up((long) compptr
->width_in_data_units
,
365 (long) compptr
->h_samp_factor
),
366 (JDIMENSION
) compptr
->v_samp_factor
);
367 diff
->undiff_buf
[ci
] = (*cinfo
->mem
->alloc_darray
)
368 ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
369 (JDIMENSION
) jround_up((long) compptr
->width_in_data_units
,
370 (long) compptr
->h_samp_factor
),
371 (JDIMENSION
) compptr
->v_samp_factor
);
374 if (need_full_buffer
) {
375 #ifdef D_MULTISCAN_FILES_SUPPORTED
376 /* Allocate a full-image virtual array for each component. */
379 for (ci
= 0, compptr
= cinfo
->comp_info
; ci
< cinfo
->num_components
;
381 access_rows
= compptr
->v_samp_factor
;
382 diff
->whole_image
[ci
] = (*cinfo
->mem
->request_virt_sarray
)
383 ((j_common_ptr
) cinfo
, JPOOL_IMAGE
, FALSE
,
384 (JDIMENSION
) jround_up((long) compptr
->width_in_data_units
,
385 (long) compptr
->h_samp_factor
),
386 (JDIMENSION
) jround_up((long) compptr
->height_in_data_units
,
387 (long) compptr
->v_samp_factor
),
388 (JDIMENSION
) access_rows
);
390 losslsd
->pub
.consume_data
= consume_data
;
391 losslsd
->pub
.decompress_data
= output_data
;
393 ERREXIT(cinfo
, JERR_NOT_COMPILED
);
396 losslsd
->pub
.consume_data
= dummy_consume_data
;
397 losslsd
->pub
.decompress_data
= decompress_data
;
398 diff
->whole_image
[0] = NULL
; /* flag for no virtual arrays */
402 #endif /* D_LOSSLESS_SUPPORTED */