3
{ This file contains the main buffer controller for compression.
4
The main buffer lies between the pre-processor and the JPEG
5
compressor proper; it holds downsampled data in the JPEG colorspace. }
7
{ Original : jcmainct.c ; Copyright (C) 1994-1996, Thomas G. Lane. }
13
{ Note: currently, there is no operating mode in which a full-image buffer
14
is needed at this step. If there were, that mode could not be used with
15
"raw data" input, since this module is bypassed in that case. However,
16
we've left the code here for possible use in special applications. }
18
{$undef FULL_MAIN_BUFFER_SUPPORTED}
25
{$ifdef FULL_MAIN_BUFFER_SUPPORTED}
30
{ Initialize main buffer controller. }
33
procedure jinit_c_main_controller (cinfo : j_compress_ptr;
34
need_full_buffer : boolean);
39
{ Private buffer controller object }
42
my_main_ptr = ^my_main_controller;
43
my_main_controller = record
44
pub : jpeg_c_main_controller; { public fields }
46
cur_iMCU_row : JDIMENSION; { number of current iMCU row }
47
rowgroup_ctr : JDIMENSION; { counts row groups received in iMCU row }
48
suspended : boolean; { remember if we suspended output }
49
pass_mode : J_BUF_MODE; { current operating mode }
51
{ If using just a strip buffer, this points to the entire set of buffers
52
(we allocate one for each component). In the full-image case, this
53
points to the currently accessible strips of the virtual arrays. }
55
buffer : array[0..MAX_COMPONENTS-1] of JSAMPARRAY;
57
{$ifdef FULL_MAIN_BUFFER_SUPPORTED}
58
{ If using full-image storage, this array holds pointers to virtual-array
59
control blocks for each component. Unused if not full-image storage. }
61
whole_image : array[0..MAX_COMPONENTS-1] of jvirt_sarray_ptr;
63
end; {my_main_controller}
66
{ Forward declarations }
68
procedure process_data_simple_main(cinfo : j_compress_ptr;
69
input_buf : JSAMPARRAY;
70
var in_row_ctr: JDIMENSION;
71
in_rows_avail : JDIMENSION); far; forward;
73
{$ifdef FULL_MAIN_BUFFER_SUPPORTED}
75
procedure process_data_buffer_main(cinfo : j_compress_ptr;
76
input_buf : JSAMPARRAY;
77
var in_row_ctr : JDIMENSION;
78
in_rows_avail : JDIMENSION); far; forward;
82
{ Initialize for a processing pass. }
85
procedure start_pass_main (cinfo : j_compress_ptr;
86
pass_mode : J_BUF_MODE); far;
90
main := my_main_ptr (cinfo^.main);
92
{ Do nothing in raw-data mode. }
93
if (cinfo^.raw_data_in) then
96
main^.cur_iMCU_row := 0; { initialize counters }
97
main^.rowgroup_ctr := 0;
98
main^.suspended := FALSE;
99
main^.pass_mode := pass_mode; { save mode for use by process_data }
104
{$ifdef FULL_MAIN_BUFFER_SUPPORTED}
105
if (main^.whole_image[0] <> NIL) then
106
ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE);
108
main^.pub.process_data := process_data_simple_main;
110
{$ifdef FULL_MAIN_BUFFER_SUPPORTED}
115
if (main^.whole_image[0] = NIL) then
116
ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE);
117
main^.pub.process_data := process_data_buffer_main;
121
ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE);
127
This routine handles the simple pass-through mode,
128
where we have only a strip buffer. }
131
procedure process_data_simple_main (cinfo : j_compress_ptr;
132
input_buf : JSAMPARRAY;
133
var in_row_ctr : JDIMENSION;
134
in_rows_avail : JDIMENSION);
138
main := my_main_ptr (cinfo^.main);
140
while (main^.cur_iMCU_row < cinfo^.total_iMCU_rows) do
142
{ Read input data if we haven't filled the main buffer yet }
143
if (main^.rowgroup_ctr < DCTSIZE) then
144
cinfo^.prep^.pre_process_data (cinfo,
148
JSAMPIMAGE(@main^.buffer),
150
JDIMENSION(DCTSIZE));
152
{ If we don't have a full iMCU row buffered, return to application for
153
more data. Note that preprocessor will always pad to fill the iMCU row
154
at the bottom of the image. }
155
if (main^.rowgroup_ctr <> DCTSIZE) then
158
{ Send the completed row to the compressor }
159
if (not cinfo^.coef^.compress_data (cinfo, JSAMPIMAGE(@main^.buffer))) then
161
{ If compressor did not consume the whole row, then we must need to
162
suspend processing and return to the application. In this situation
163
we pretend we didn't yet consume the last input row; otherwise, if
164
it happened to be the last row of the image, the application would
165
think we were done. }
167
if (not main^.suspended) then
170
main^.suspended := TRUE;
174
{ We did finish the row. Undo our little suspension hack if a previous
175
call suspended; then mark the main buffer empty. }
177
if (main^.suspended) then
180
main^.suspended := FALSE;
182
main^.rowgroup_ctr := 0;
183
Inc(main^.cur_iMCU_row);
188
{$ifdef FULL_MAIN_BUFFER_SUPPORTED}
191
This routine handles all of the modes that use a full-size buffer. }
194
procedure process_data_buffer_main (cinfo : j_compress_ptr;
195
input_buf : JSAMPARRAY;
196
var in_row_ctr : JDIMENSION;
197
in_rows_avail : JDIMENSION);
201
compptr : jpeg_component_info_ptr;
204
main := my_main_ptr (cinfo^.main);
205
writing := (main^.pass_mode <> JBUF_CRANK_DEST);
207
while (main^.cur_iMCU_row < cinfo^.total_iMCU_rows) do
209
{ Realign the virtual buffers if at the start of an iMCU row. }
210
if (main^.rowgroup_ctr = 0) then
212
compptr := cinfo^.comp_info;
213
for ci := 0 to pred(cinfo^.num_components) do
215
main^.buffer[ci] := cinfo^.mem^.access_virt_sarray
216
(j_common_ptr (cinfo), main^.whole_image[ci],
217
main^.cur_iMCU_row * (compptr^.v_samp_factor * DCTSIZE),
218
JDIMENSION (compptr^.v_samp_factor * DCTSIZE), writing);
221
{ In a read pass, pretend we just read some source data. }
222
if (not writing) then
224
Inc(in_row_ctr, cinfo^.max_v_samp_factor * DCTSIZE);
225
main^.rowgroup_ctr := DCTSIZE;
229
{ If a write pass, read input data until the current iMCU row is full. }
230
{ Note: preprocessor will pad if necessary to fill the last iMCU row. }
233
cinfo^.prep^.pre_process_data (cinfo,
234
input_buf, in_row_ctr, in_rows_avail,
235
JSAMPIMAGE(@main^.buffer),
237
JDIMENSION (DCTSIZE));
239
{ Return to application if we need more data to fill the iMCU row. }
240
if (main^.rowgroup_ctr < DCTSIZE) then
244
{ Emit data, unless this is a sink-only pass. }
245
if (main^.pass_mode <> JBUF_SAVE_SOURCE) then
247
if (not cinfo^.coef^.compress_data (cinfo,
248
JSAMPIMAGE(@main^.buffer))) then
250
{ If compressor did not consume the whole row, then we must need to
251
suspend processing and return to the application. In this situation
252
we pretend we didn't yet consume the last input row; otherwise, if
253
it happened to be the last row of the image, the application would
254
think we were done. }
256
if (not main^.suspended) then
259
main^.suspended := TRUE;
263
{ We did finish the row. Undo our little suspension hack if a previous
264
call suspended; then mark the main buffer empty. }
266
if (main^.suspended) then
269
main^.suspended := FALSE;
273
{ If get here, we are done with this iMCU row. Mark buffer empty. }
274
main^.rowgroup_ctr := 0;
275
Inc(main^.cur_iMCU_row);
279
{$endif} { FULL_MAIN_BUFFER_SUPPORTED }
282
{ Initialize main buffer controller. }
285
procedure jinit_c_main_controller (cinfo : j_compress_ptr;
286
need_full_buffer : boolean);
290
compptr : jpeg_component_info_ptr;
293
cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
294
SIZEOF(my_main_controller)) );
295
cinfo^.main := jpeg_c_main_controller_ptr(main);
296
main^.pub.start_pass := start_pass_main;
298
{ We don't need to create a buffer in raw-data mode. }
299
if (cinfo^.raw_data_in) then
302
{ Create the buffer. It holds downsampled data, so each component
303
may be of a different size. }
305
if (need_full_buffer) then
307
{$ifdef FULL_MAIN_BUFFER_SUPPORTED}
308
{ Allocate a full-image virtual array for each component }
309
{ Note we pad the bottom to a multiple of the iMCU height }
310
compptr := cinfo^.comp_info;
311
for ci := 0 to pred(cinfo^.num_components) do
313
main^.whole_image[ci] := cinfo^.mem^.request_virt_sarray
314
(j_common_ptr(cinfo), JPOOL_IMAGE, FALSE,
315
compptr^.width_in_blocks * DCTSIZE,
316
JDIMENSION (jround_up( long (compptr^.height_in_blocks),
317
long (compptr^.v_samp_factor)) * DCTSIZE),
318
JDIMENSION (compptr^.v_samp_factor * DCTSIZE));
322
ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE);
327
{$ifdef FULL_MAIN_BUFFER_SUPPORTED}
328
main^.whole_image[0] := NIL; { flag for no virtual arrays }
330
{ Allocate a strip buffer for each component }
331
compptr := jpeg_component_info_ptr(cinfo^.comp_info);
332
for ci := 0 to pred(cinfo^.num_components) do
334
main^.buffer[ci] := cinfo^.mem^.alloc_sarray
335
(j_common_ptr(cinfo), JPOOL_IMAGE,
336
compptr^.width_in_blocks * DCTSIZE,
337
JDIMENSION (compptr^.v_samp_factor * DCTSIZE));