4
{ This file is part of the Independent JPEG Group's software.
5
For conditions of distribution and use, see the accompanying README file.
7
This file contains the main buffer controller for decompression.
8
The main buffer lies between the JPEG decompressor proper and the
9
post-processor; it holds downsampled data in the JPEG colorspace.
11
Note that this code is bypassed in raw-data mode, since the application
12
supplies the equivalent of the main buffer in that case. }
14
{ Original: jdmainct.c ; Copyright (C) 1994-1996, Thomas G. Lane. }
17
{ In the current system design, the main buffer need never be a full-image
18
buffer; any full-height buffers will be found inside the coefficient or
19
postprocessing controllers. Nonetheless, the main controller is not
20
trivial. Its responsibility is to provide context rows for upsampling/
21
rescaling, and doing this in an efficient fashion is a bit tricky.
23
Postprocessor input data is counted in "row groups". A row group
24
is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
25
sample rows of each component. (We require DCT_scaled_size values to be
26
chosen such that these numbers are integers. In practice DCT_scaled_size
27
values will likely be powers of two, so we actually have the stronger
28
condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
29
Upsampling will typically produce max_v_samp_factor pixel rows from each
30
row group (times any additional scale factor that the upsampler is
33
The coefficient controller will deliver data to us one iMCU row at a time;
34
each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or
35
exactly min_DCT_scaled_size row groups. (This amount of data corresponds
36
to one row of MCUs when the image is fully interleaved.) Note that the
37
number of sample rows varies across components, but the number of row
38
groups does not. Some garbage sample rows may be included in the last iMCU
39
row at the bottom of the image.
41
Depending on the vertical scaling algorithm used, the upsampler may need
42
access to the sample row(s) above and below its current input row group.
43
The upsampler is required to set need_context_rows TRUE at global
45
time if so. When need_context_rows is FALSE, this controller can simply
46
obtain one iMCU row at a time from the coefficient controller and dole it
47
out as row groups to the postprocessor.
49
When need_context_rows is TRUE, this controller guarantees that the buffer
50
passed to postprocessing contains at least one row group's worth of samples
51
above and below the row group(s) being processed. Note that the context
52
rows "above" the first passed row group appear at negative row offsets in
53
the passed buffer. At the top and bottom of the image, the required
54
context rows are manufactured by duplicating the first or last real sample
55
row; this avoids having special cases in the upsampling inner loops.
57
The amount of context is fixed at one row group just because that's a
58
convenient number for this controller to work with. The existing
59
upsamplers really only need one sample row of context. An upsampler
60
supporting arbitrary output rescaling might wish for more than one row
61
group of context when shrinking the image; tough, we don't handle that.
62
(This is justified by the assumption that downsizing will be handled mostly
63
by adjusting the DCT_scaled_size values, so that the actual scale factor at
64
the upsample step needn't be much less than one.)
66
To provide the desired context, we have to retain the last two row groups
67
of one iMCU row while reading in the next iMCU row. (The last row group
68
can't be processed until we have another row group for its below-context,
69
and so we have to save the next-to-last group too for its above-context.)
70
We could do this most simply by copying data around in our buffer, but
71
that'd be very slow. We can avoid copying any data by creating a rather
72
strange pointer structure. Here's how it works. We allocate a workspace
73
consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
74
of row groups per iMCU row). We create two sets of redundant pointers to
75
the workspace. Labeling the physical row groups 0 to M+1, the synthesized
76
pointer lists look like this:
78
master pointer --> 0 master pointer --> 0
87
We read alternate iMCU rows using each master pointer; thus the last two
88
row groups of the previous iMCU row remain un-overwritten in the workspace.
89
The pointer lists are set up so that the required context rows appear to
90
be adjacent to the proper places when we pass the pointer lists to the
93
The above pictures describe the normal state of the pointer lists.
94
At top and bottom of the image, we diddle the pointer lists to duplicate
95
the first or last sample row as necessary (this is cheaper than copying
98
This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that
99
situation each iMCU row provides only one row group so the buffering logic
100
must be different (eg, we must read two iMCU rows before we can emit the
101
first row group). For now, we simply do not support providing context
102
rows when min_DCT_scaled_size is 1. That combination seems unlikely to
103
be worth providing --- if someone wants a 1/8th-size preview, they probably
104
want it quick and dirty, so a context-free upsampler is sufficient. }
113
{$ifdef QUANT_2PASS_SUPPORTED}
122
procedure jinit_d_main_controller (cinfo : j_decompress_ptr;
123
need_full_buffer : boolean);
128
{ Private buffer controller object }
131
my_main_ptr = ^my_main_controller;
132
my_main_controller = record
133
pub : jpeg_d_main_controller; { public fields }
135
{ Pointer to allocated workspace (M or M+2 row groups). }
136
buffer : array[0..MAX_COMPONENTS-1] of JSAMPARRAY;
138
buffer_full : boolean; { Have we gotten an iMCU row from decoder? }
139
rowgroup_ctr : JDIMENSION ; { counts row groups output to postprocessor }
141
{ Remaining fields are only used in the context case. }
143
{ These are the master pointers to the funny-order pointer lists. }
144
xbuffer : array[0..2-1] of JSAMPIMAGE; { pointers to weird pointer lists }
146
whichptr : int; { indicates which pointer set is now in use }
147
context_state : int; { process_data state machine status }
148
rowgroups_avail : JDIMENSION; { row groups available to postprocessor }
149
iMCU_row_ctr : JDIMENSION; { counts iMCU rows to detect image top/bot }
150
end; { my_main_controller; }
153
{ context_state values: }
155
CTX_PREPARE_FOR_IMCU = 0; { need to prepare for MCU row }
156
CTX_PROCESS_IMCU = 1; { feeding iMCU to postprocessor }
157
CTX_POSTPONED_ROW = 2; { feeding postponed row group }
160
{ Forward declarations }
162
procedure process_data_simple_main(cinfo : j_decompress_ptr;
163
output_buf : JSAMPARRAY;
164
var out_row_ctr : JDIMENSION;
165
out_rows_avail : JDIMENSION); far; forward;
167
procedure process_data_context_main (cinfo : j_decompress_ptr;
168
output_buf : JSAMPARRAY;
169
var out_row_ctr : JDIMENSION;
170
out_rows_avail : JDIMENSION); far; forward;
172
{$ifdef QUANT_2PASS_SUPPORTED}
174
procedure process_data_crank_post (cinfo : j_decompress_ptr;
175
output_buf : JSAMPARRAY;
176
var out_row_ctr : JDIMENSION;
177
out_rows_avail : JDIMENSION); far; forward;
182
procedure alloc_funny_pointers (cinfo : j_decompress_ptr);
183
{ Allocate space for the funny pointer lists.
184
This is done only once, not once per pass. }
189
compptr : jpeg_component_info_ptr;
192
main := my_main_ptr (cinfo^.main);
193
M := cinfo^.min_DCT_scaled_size;
195
{ Get top-level space for component array pointers.
196
We alloc both arrays with one call to save a few cycles. }
198
main^.xbuffer[0] := JSAMPIMAGE (
199
cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
200
cinfo^.num_components * 2 * SIZEOF(JSAMPARRAY)) );
201
main^.xbuffer[1] := JSAMPIMAGE(@( main^.xbuffer[0]^[cinfo^.num_components] ));
203
compptr := jpeg_component_info_ptr(cinfo^.comp_info);
204
for ci := 0 to pred(cinfo^.num_components) do
206
rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div
207
cinfo^.min_DCT_scaled_size; { height of a row group of component }
208
{ Get space for pointer lists --- M+4 row groups in each list.
209
We alloc both pointer lists with one call to save a few cycles. }
212
cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
213
2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)) );
214
Inc(JSAMPROW_PTR(xbuf), rgroup); { want one row group at negative offsets }
215
main^.xbuffer[0]^[ci] := xbuf;
216
Inc(JSAMPROW_PTR(xbuf), rgroup * (M + 4));
217
main^.xbuffer[1]^[ci] := xbuf;
223
procedure make_funny_pointers (cinfo : j_decompress_ptr);
224
{ Create the funny pointer lists discussed in the comments above.
225
The actual workspace is already allocated (in main^.buffer),
226
and the space for the pointer lists is allocated too.
227
This routine just fills in the curiously ordered lists.
228
This will be repeated at the beginning of each pass. }
233
compptr : jpeg_component_info_ptr;
234
buf, xbuf0, xbuf1 : JSAMPARRAY;
236
help_xbuf0 : JSAMPARRAY; { work around negative offsets }
238
main := my_main_ptr (cinfo^.main);
239
M := cinfo^.min_DCT_scaled_size;
241
compptr := jpeg_component_info_ptr(cinfo^.comp_info);
242
for ci := 0 to pred(cinfo^.num_components) do
244
rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div
245
cinfo^.min_DCT_scaled_size; { height of a row group of component }
246
xbuf0 := main^.xbuffer[0]^[ci];
247
xbuf1 := main^.xbuffer[1]^[ci];
248
{ First copy the workspace pointers as-is }
249
buf := main^.buffer[ci];
250
for i := 0 to pred(rgroup * (M + 2)) do
252
xbuf0^[i] := buf^[i];
253
xbuf1^[i] := buf^[i];
255
{ In the second list, put the last four row groups in swapped order }
256
for i := 0 to pred(rgroup * 2) do
258
xbuf1^[rgroup*(M-2) + i] := buf^[rgroup*M + i];
259
xbuf1^[rgroup*M + i] := buf^[rgroup*(M-2) + i];
261
{ The wraparound pointers at top and bottom will be filled later
262
(see set_wraparound_pointers, below). Initially we want the "above"
263
pointers to duplicate the first actual data line. This only needs
264
to happen in xbuffer[0]. }
267
Dec(JSAMPROW_PTR(help_xbuf0), rgroup);
269
for i := 0 to pred(rgroup) do
271
{xbuf0^[i - rgroup] := xbuf0^[0];}
272
help_xbuf0^[i] := xbuf0^[0];
280
procedure set_wraparound_pointers (cinfo : j_decompress_ptr);
281
{ Set up the "wraparound" pointers at top and bottom of the pointer lists.
282
This changes the pointer list state from top-of-image to the normal state. }
287
compptr : jpeg_component_info_ptr;
288
xbuf0, xbuf1 : JSAMPARRAY;
291
help_xbuf1 : JSAMPARRAY; { work around negative offsets }
293
main := my_main_ptr (cinfo^.main);
294
M := cinfo^.min_DCT_scaled_size;
296
compptr := jpeg_component_info_ptr(cinfo^.comp_info);
297
for ci := 0 to pred(cinfo^.num_components) do
299
rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div
300
cinfo^.min_DCT_scaled_size; { height of a row group of component }
301
xbuf0 := main^.xbuffer[0]^[ci];
302
xbuf1 := main^.xbuffer[1]^[ci];
305
Dec(JSAMPROW_PTR(help_xbuf0), rgroup);
307
Dec(JSAMPROW_PTR(help_xbuf1), rgroup);
309
for i := 0 to pred(rgroup) do
311
{xbuf0^[i - rgroup] := xbuf0^[rgroup*(M+1) + i];
312
xbuf1^[i - rgroup] := xbuf1^[rgroup*(M+1) + i];}
314
help_xbuf0^[i] := xbuf0^[rgroup*(M+1) + i];
315
help_xbuf1^[i] := xbuf1^[rgroup*(M+1) + i];
317
xbuf0^[rgroup*(M+2) + i] := xbuf0^[i];
318
xbuf1^[rgroup*(M+2) + i] := xbuf1^[i];
326
procedure set_bottom_pointers (cinfo : j_decompress_ptr);
327
{ Change the pointer lists to duplicate the last sample row at the bottom
328
of the image. whichptr indicates which xbuffer holds the final iMCU row.
329
Also sets rowgroups_avail to indicate number of nondummy row groups in row. }
332
ci, i, rgroup, iMCUheight, rows_left : int;
333
compptr : jpeg_component_info_ptr;
336
main := my_main_ptr (cinfo^.main);
338
compptr := jpeg_component_info_ptr(cinfo^.comp_info);
339
for ci := 0 to pred(cinfo^.num_components) do
341
{ Count sample rows in one iMCU row and in one row group }
342
iMCUheight := compptr^.v_samp_factor * compptr^.DCT_scaled_size;
343
rgroup := iMCUheight div cinfo^.min_DCT_scaled_size;
344
{ Count nondummy sample rows remaining for this component }
345
rows_left := int (compptr^.downsampled_height mod JDIMENSION (iMCUheight));
346
if (rows_left = 0) then
347
rows_left := iMCUheight;
348
{ Count nondummy row groups. Should get same answer for each component,
349
so we need only do it once. }
352
main^.rowgroups_avail := JDIMENSION ((rows_left-1) div rgroup + 1);
354
{ Duplicate the last real sample row rgroup*2 times; this pads out the
355
last partial rowgroup and ensures at least one full rowgroup of context. }
357
xbuf := main^.xbuffer[main^.whichptr]^[ci];
358
for i := 0 to pred(rgroup * 2) do
360
xbuf^[rows_left + i] := xbuf^[rows_left-1];
367
{ Initialize for a processing pass. }
370
procedure start_pass_main (cinfo : j_decompress_ptr;
371
pass_mode : J_BUF_MODE); far;
375
main := my_main_ptr (cinfo^.main);
380
if (cinfo^.upsample^.need_context_rows) then
382
main^.pub.process_data := process_data_context_main;
383
make_funny_pointers(cinfo); { Create the xbuffer[] lists }
384
main^.whichptr := 0; { Read first iMCU row into xbuffer[0] }
385
main^.context_state := CTX_PREPARE_FOR_IMCU;
386
main^.iMCU_row_ctr := 0;
390
{ Simple case with no context needed }
391
main^.pub.process_data := process_data_simple_main;
393
main^.buffer_full := FALSE; { Mark buffer empty }
394
main^.rowgroup_ctr := 0;
396
{$ifdef QUANT_2PASS_SUPPORTED}
398
{ For last pass of 2-pass quantization, just crank the postprocessor }
399
main^.pub.process_data := process_data_crank_post;
402
ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE);
408
This handles the simple case where no context is required. }
411
procedure process_data_simple_main (cinfo : j_decompress_ptr;
412
output_buf : JSAMPARRAY;
413
var out_row_ctr : JDIMENSION;
414
out_rows_avail : JDIMENSION);
417
rowgroups_avail : JDIMENSION;
419
main_buffer_ptr : JSAMPIMAGE;
421
main := my_main_ptr (cinfo^.main);
422
main_buffer_ptr := JSAMPIMAGE(@(main^.buffer));
424
{ Read input data if we haven't filled the main buffer yet }
425
if (not main^.buffer_full) then
427
if (cinfo^.coef^.decompress_data (cinfo, main_buffer_ptr)=0) then
428
exit; { suspension forced, can do nothing more }
429
main^.buffer_full := TRUE; { OK, we have an iMCU row to work with }
432
{ There are always min_DCT_scaled_size row groups in an iMCU row. }
433
rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size);
434
{ Note: at the bottom of the image, we may pass extra garbage row groups
435
to the postprocessor. The postprocessor has to check for bottom
436
of image anyway (at row resolution), so no point in us doing it too. }
438
{ Feed the postprocessor }
439
cinfo^.post^.post_process_data (cinfo, main_buffer_ptr,
440
main^.rowgroup_ctr, rowgroups_avail,
441
output_buf, out_row_ctr, out_rows_avail);
443
{ Has postprocessor consumed all the data yet? If so, mark buffer empty }
444
if (main^.rowgroup_ctr >= rowgroups_avail) then
446
main^.buffer_full := FALSE;
447
main^.rowgroup_ctr := 0;
453
This handles the case where context rows must be provided. }
456
procedure process_data_context_main (cinfo : j_decompress_ptr;
457
output_buf : JSAMPARRAY;
458
var out_row_ctr : JDIMENSION;
459
out_rows_avail : JDIMENSION);
463
main := my_main_ptr (cinfo^.main);
465
{ Read input data if we haven't filled the main buffer yet }
466
if (not main^.buffer_full) then
468
if (cinfo^.coef^.decompress_data (cinfo,
469
main^.xbuffer[main^.whichptr])=0) then
470
exit; { suspension forced, can do nothing more }
471
main^.buffer_full := TRUE; { OK, we have an iMCU row to work with }
472
Inc(main^.iMCU_row_ctr); { count rows received }
475
{ Postprocessor typically will not swallow all the input data it is handed
476
in one call (due to filling the output buffer first). Must be prepared
477
to exit and restart. This switch lets us keep track of how far we got.
478
Note that each case falls through to the next on successful completion. }
480
case (main^.context_state) of
483
{ Call postprocessor using previously set pointers for postponed row }
484
cinfo^.post^.post_process_data (cinfo, main^.xbuffer[main^.whichptr],
485
main^.rowgroup_ctr, main^.rowgroups_avail,
486
output_buf, out_row_ctr, out_rows_avail);
487
if (main^.rowgroup_ctr < main^.rowgroups_avail) then
488
exit; { Need to suspend }
489
main^.context_state := CTX_PREPARE_FOR_IMCU;
490
if (out_row_ctr >= out_rows_avail) then
491
exit; { Postprocessor exactly filled output buf }
494
case (main^.context_state) of
496
CTX_PREPARE_FOR_IMCU: {FALLTHROUGH}
498
{ Prepare to process first M-1 row groups of this iMCU row }
499
main^.rowgroup_ctr := 0;
500
main^.rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size - 1);
501
{ Check for bottom of image: if so, tweak pointers to "duplicate"
502
the last sample row, and adjust rowgroups_avail to ignore padding rows. }
504
if (main^.iMCU_row_ctr = cinfo^.total_iMCU_rows) then
505
set_bottom_pointers(cinfo);
506
main^.context_state := CTX_PROCESS_IMCU;
510
case (main^.context_state) of
512
CTX_PREPARE_FOR_IMCU, {FALLTHROUGH}
515
{ Call postprocessor using previously set pointers }
516
cinfo^.post^.post_process_data (cinfo, main^.xbuffer[main^.whichptr],
517
main^.rowgroup_ctr, main^.rowgroups_avail,
518
output_buf, out_row_ctr, out_rows_avail);
519
if (main^.rowgroup_ctr < main^.rowgroups_avail) then
520
exit; { Need to suspend }
521
{ After the first iMCU, change wraparound pointers to normal state }
522
if (main^.iMCU_row_ctr = 1) then
523
set_wraparound_pointers(cinfo);
524
{ Prepare to load new iMCU row using other xbuffer list }
525
main^.whichptr := main^.whichptr xor 1; { 0=>1 or 1=>0 }
526
main^.buffer_full := FALSE;
527
{ Still need to process last row group of this iMCU row, }
528
{ which is saved at index M+1 of the other xbuffer }
529
main^.rowgroup_ctr := JDIMENSION (cinfo^.min_DCT_scaled_size + 1);
530
main^.rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size + 2);
531
main^.context_state := CTX_POSTPONED_ROW;
538
Final pass of two-pass quantization: just call the postprocessor.
539
Source data will be the postprocessor controller's internal buffer. }
541
{$ifdef QUANT_2PASS_SUPPORTED}
544
procedure process_data_crank_post (cinfo : j_decompress_ptr;
545
output_buf : JSAMPARRAY;
546
var out_row_ctr : JDIMENSION;
547
out_rows_avail : JDIMENSION);
549
in_row_group_ctr : JDIMENSION;
551
in_row_group_ctr := 0;
552
cinfo^.post^.post_process_data (cinfo, JSAMPIMAGE (NIL),
560
{$endif} { QUANT_2PASS_SUPPORTED }
563
{ Initialize main buffer controller. }
566
procedure jinit_d_main_controller (cinfo : j_decompress_ptr;
567
need_full_buffer : boolean);
570
ci, rgroup, ngroups : int;
571
compptr : jpeg_component_info_ptr;
574
cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
575
SIZEOF(my_main_controller)) );
576
cinfo^.main := jpeg_d_main_controller_ptr(main);
577
main^.pub.start_pass := start_pass_main;
579
if (need_full_buffer) then { shouldn't happen }
580
ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE);
582
{ Allocate the workspace.
583
ngroups is the number of row groups we need.}
585
if (cinfo^.upsample^.need_context_rows) then
587
if (cinfo^.min_DCT_scaled_size < 2) then { unsupported, see comments above }
588
ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL);
589
alloc_funny_pointers(cinfo); { Alloc space for xbuffer[] lists }
590
ngroups := cinfo^.min_DCT_scaled_size + 2;
594
ngroups := cinfo^.min_DCT_scaled_size;
597
compptr := jpeg_component_info_ptr(cinfo^.comp_info);
598
for ci := 0 to pred(cinfo^.num_components) do
600
rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div
601
cinfo^.min_DCT_scaled_size; { height of a row group of component }
602
main^.buffer[ci] := cinfo^.mem^.alloc_sarray
603
(j_common_ptr(cinfo), JPOOL_IMAGE,
604
compptr^.width_in_blocks * compptr^.DCT_scaled_size,
605
JDIMENSION (rgroup * ngroups));