📄 jdmainct.pas
字号:
help_xbuf1 := xbuf1;
Dec(JSAMPROW_PTR(help_xbuf1), rgroup);
for i := 0 to pred(rgroup) do
begin
{xbuf0^[i - rgroup] := xbuf0^[rgroup*(M+1) + i];
xbuf1^[i - rgroup] := xbuf1^[rgroup*(M+1) + i];}
help_xbuf0^[i] := xbuf0^[rgroup*(M+1) + i];
help_xbuf1^[i] := xbuf1^[rgroup*(M+1) + i];
xbuf0^[rgroup*(M+2) + i] := xbuf0^[i];
xbuf1^[rgroup*(M+2) + i] := xbuf1^[i];
end;
Inc(compptr);
end;
end;
{LOCAL}
procedure set_bottom_pointers (cinfo : j_decompress_ptr);
{ Change the pointer lists to duplicate the last sample row at the bottom
of the image. whichptr indicates which xbuffer holds the final iMCU row.
Also sets rowgroups_avail to indicate number of nondummy row groups in row. }
var
main : my_main_ptr;
ci, i, rgroup, iMCUheight, rows_left : int;
compptr : jpeg_component_info_ptr;
xbuf : JSAMPARRAY;
begin
main := my_main_ptr (cinfo^.main);
compptr := cinfo^.comp_info;
for ci := 0 to pred(cinfo^.num_components) do
begin
{ Count sample rows in one iMCU row and in one row group }
iMCUheight := compptr^.v_samp_factor * compptr^.DCT_scaled_size;
rgroup := iMCUheight div cinfo^.min_DCT_scaled_size;
{ Count nondummy sample rows remaining for this component }
rows_left := int (compptr^.downsampled_height mod JDIMENSION (iMCUheight));
if (rows_left = 0) then
rows_left := iMCUheight;
{ Count nondummy row groups. Should get same answer for each component,
so we need only do it once. }
if (ci = 0) then
begin
main^.rowgroups_avail := JDIMENSION ((rows_left-1) div rgroup + 1);
end;
{ Duplicate the last real sample row rgroup*2 times; this pads out the
last partial rowgroup and ensures at least one full rowgroup of context. }
xbuf := main^.xbuffer[main^.whichptr]^[ci];
for i := 0 to pred(rgroup * 2) do
begin
xbuf^[rows_left + i] := xbuf^[rows_left-1];
end;
Inc(compptr);
end;
end;
{ Initialize for a processing pass. }
{METHODDEF}
procedure start_pass_main (cinfo : j_decompress_ptr;
pass_mode : J_BUF_MODE); far;
var
main : my_main_ptr;
begin
main := my_main_ptr (cinfo^.main);
case (pass_mode) of
JBUF_PASS_THRU:
begin
if (cinfo^.upsample^.need_context_rows) then
begin
main^.pub.process_data := process_data_context_main;
make_funny_pointers(cinfo); { Create the xbuffer[] lists }
main^.whichptr := 0; { Read first iMCU row into xbuffer[0] }
main^.context_state := CTX_PREPARE_FOR_IMCU;
main^.iMCU_row_ctr := 0;
end
else
begin
{ Simple case with no context needed }
main^.pub.process_data := process_data_simple_main;
end;
main^.buffer_full := FALSE; { Mark buffer empty }
main^.rowgroup_ctr := 0;
end;
{$ifdef QUANT_2PASS_SUPPORTED}
JBUF_CRANK_DEST:
{ For last pass of 2-pass quantization, just crank the postprocessor }
main^.pub.process_data := process_data_crank_post;
{$endif}
else
ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE);
end;
end;
{ Process some data.
This handles the simple case where no context is required. }
{METHODDEF}
procedure process_data_simple_main (cinfo : j_decompress_ptr;
output_buf : JSAMPARRAY;
var out_row_ctr : JDIMENSION;
out_rows_avail : JDIMENSION);
var
main : my_main_ptr;
rowgroups_avail : JDIMENSION;
var
main_buffer_ptr : JSAMPIMAGE;
begin
main := my_main_ptr (cinfo^.main);
main_buffer_ptr := JSAMPIMAGE(@(main^.buffer));
{ Read input data if we haven't filled the main buffer yet }
if (not main^.buffer_full) then
begin
if (cinfo^.coef^.decompress_data (cinfo, main_buffer_ptr)=0) then
exit; { suspension forced, can do nothing more }
main^.buffer_full := TRUE; { OK, we have an iMCU row to work with }
end;
{ There are always min_DCT_scaled_size row groups in an iMCU row. }
rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size);
{ Note: at the bottom of the image, we may pass extra garbage row groups
to the postprocessor. The postprocessor has to check for bottom
of image anyway (at row resolution), so no point in us doing it too. }
{ Feed the postprocessor }
cinfo^.post^.post_process_data (cinfo, main_buffer_ptr,
main^.rowgroup_ctr, rowgroups_avail,
output_buf, out_row_ctr, out_rows_avail);
{ Has postprocessor consumed all the data yet? If so, mark buffer empty }
if (main^.rowgroup_ctr >= rowgroups_avail) then
begin
main^.buffer_full := FALSE;
main^.rowgroup_ctr := 0;
end;
end;
{ Process some data.
This handles the case where context rows must be provided. }
{METHODDEF}
procedure process_data_context_main (cinfo : j_decompress_ptr;
output_buf : JSAMPARRAY;
var out_row_ctr : JDIMENSION;
out_rows_avail : JDIMENSION);
var
main : my_main_ptr;
begin
main := my_main_ptr (cinfo^.main);
{ Read input data if we haven't filled the main buffer yet }
if (not main^.buffer_full) then
begin
if (cinfo^.coef^.decompress_data (cinfo,
main^.xbuffer[main^.whichptr])=0) then
exit; { suspension forced, can do nothing more }
main^.buffer_full := TRUE; { OK, we have an iMCU row to work with }
Inc(main^.iMCU_row_ctr); { count rows received }
end;
{ Postprocessor typically will not swallow all the input data it is handed
in one call (due to filling the output buffer first). Must be prepared
to exit and restart. This switch lets us keep track of how far we got.
Note that each case falls through to the next on successful completion. }
case (main^.context_state) of
CTX_POSTPONED_ROW:
begin
{ Call postprocessor using previously set pointers for postponed row }
cinfo^.post^.post_process_data (cinfo, main^.xbuffer[main^.whichptr],
main^.rowgroup_ctr, main^.rowgroups_avail,
output_buf, out_row_ctr, out_rows_avail);
if (main^.rowgroup_ctr < main^.rowgroups_avail) then
exit; { Need to suspend }
main^.context_state := CTX_PREPARE_FOR_IMCU;
if (out_row_ctr >= out_rows_avail) then
exit; { Postprocessor exactly filled output buf }
end;
end;
case (main^.context_state) of
CTX_POSTPONED_ROW,
CTX_PREPARE_FOR_IMCU: {FALLTHROUGH}
begin
{ Prepare to process first M-1 row groups of this iMCU row }
main^.rowgroup_ctr := 0;
main^.rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size - 1);
{ Check for bottom of image: if so, tweak pointers to "duplicate"
the last sample row, and adjust rowgroups_avail to ignore padding rows. }
if (main^.iMCU_row_ctr = cinfo^.total_iMCU_rows) then
set_bottom_pointers(cinfo);
main^.context_state := CTX_PROCESS_IMCU;
end;
end;
case (main^.context_state) of
CTX_POSTPONED_ROW,
CTX_PREPARE_FOR_IMCU, {FALLTHROUGH}
CTX_PROCESS_IMCU:
begin
{ Call postprocessor using previously set pointers }
cinfo^.post^.post_process_data (cinfo, main^.xbuffer[main^.whichptr],
main^.rowgroup_ctr, main^.rowgroups_avail,
output_buf, out_row_ctr, out_rows_avail);
if (main^.rowgroup_ctr < main^.rowgroups_avail) then
exit; { Need to suspend }
{ After the first iMCU, change wraparound pointers to normal state }
if (main^.iMCU_row_ctr = 1) then
set_wraparound_pointers(cinfo);
{ Prepare to load new iMCU row using other xbuffer list }
main^.whichptr := main^.whichptr xor 1; { 0=>1 or 1=>0 }
main^.buffer_full := FALSE;
{ Still need to process last row group of this iMCU row, }
{ which is saved at index M+1 of the other xbuffer }
main^.rowgroup_ctr := JDIMENSION (cinfo^.min_DCT_scaled_size + 1);
main^.rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size + 2);
main^.context_state := CTX_POSTPONED_ROW;
end;
end;
end;
{ Process some data.
Final pass of two-pass quantization: just call the postprocessor.
Source data will be the postprocessor controller's internal buffer. }
{$ifdef QUANT_2PASS_SUPPORTED}
{METHODDEF}
procedure process_data_crank_post (cinfo : j_decompress_ptr;
output_buf : JSAMPARRAY;
var out_row_ctr : JDIMENSION;
out_rows_avail : JDIMENSION);
var
in_row_group_ctr : JDIMENSION;
begin
in_row_group_ctr := 0;
cinfo^.post^.post_process_data (cinfo, JSAMPIMAGE (NIL),
in_row_group_ctr,
JDIMENSION(0),
output_buf,
out_row_ctr,
out_rows_avail);
end;
{$endif} { QUANT_2PASS_SUPPORTED }
{ Initialize main buffer controller. }
{GLOBAL}
procedure jinit_d_main_controller (cinfo : j_decompress_ptr;
need_full_buffer : boolean);
var
main : my_main_ptr;
ci, rgroup, ngroups : int;
compptr : jpeg_component_info_ptr;
begin
main := my_main_ptr(
cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
SIZEOF(my_main_controller)) );
cinfo^.main := jpeg_d_main_controller_ptr(main);
main^.pub.start_pass := start_pass_main;
if (need_full_buffer) then { shouldn't happen }
ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE);
{ Allocate the workspace.
ngroups is the number of row groups we need.}
if (cinfo^.upsample^.need_context_rows) then
begin
if (cinfo^.min_DCT_scaled_size < 2) then { unsupported, see comments above }
ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL);
alloc_funny_pointers(cinfo); { Alloc space for xbuffer[] lists }
ngroups := cinfo^.min_DCT_scaled_size + 2;
end
else
begin
ngroups := cinfo^.min_DCT_scaled_size;
end;
compptr := cinfo^.comp_info;
for ci := 0 to pred(cinfo^.num_components) do
begin
rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div
cinfo^.min_DCT_scaled_size; { height of a row group of component }
main^.buffer[ci] := cinfo^.mem^.alloc_sarray
(j_common_ptr(cinfo), JPOOL_IMAGE,
compptr^.width_in_blocks * compptr^.DCT_scaled_size,
JDIMENSION (rgroup * ngroups));
Inc(compptr);
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -