📄 jdmaster.pas
字号:
end;
{ Master selection of decompression modules.
This is done once at jpeg_start_decompress time. We determine
which modules will be used and give them appropriate initialization calls.
We also initialize the decompressor input side to begin consuming data.
Since jpeg_read_header has finished, we know what is in the SOF
and (first) SOS markers. We also have all the application parameter
settings. }
{LOCAL}
procedure master_selection (cinfo : j_decompress_ptr);
var
master : my_master_ptr;
use_c_buffer : boolean;
samplesperrow : long;
jd_samplesperrow : JDIMENSION;
var
nscans : int;
begin
master := my_master_ptr (cinfo^.master);
{ Initialize dimensions and other stuff }
jpeg_calc_output_dimensions(cinfo);
prepare_range_limit_table(cinfo);
{ Width of an output scanline must be representable as JDIMENSION. }
samplesperrow := long(cinfo^.output_width) * long (cinfo^.out_color_components);
jd_samplesperrow := JDIMENSION (samplesperrow);
if (long(jd_samplesperrow) <> samplesperrow) then
ERREXIT(j_common_ptr(cinfo), JERR_WIDTH_OVERFLOW);
{ Initialize my private state }
master^.pass_number := 0;
master^.using_merged_upsample := use_merged_upsample(cinfo);
{ Color quantizer selection }
master^.quantizer_1pass := NIL;
master^.quantizer_2pass := NIL;
{ No mode changes if not using buffered-image mode. }
if (not cinfo^.quantize_colors) or (not cinfo^.buffered_image) then
begin
cinfo^.enable_1pass_quant := FALSE;
cinfo^.enable_external_quant := FALSE;
cinfo^.enable_2pass_quant := FALSE;
end;
if (cinfo^.quantize_colors) then
begin
if (cinfo^.raw_data_out) then
ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL);
{ 2-pass quantizer only works in 3-component color space. }
if (cinfo^.out_color_components <> 3) then
begin
cinfo^.enable_1pass_quant := TRUE;
cinfo^.enable_external_quant := FALSE;
cinfo^.enable_2pass_quant := FALSE;
cinfo^.colormap := NIL;
end
else
if (cinfo^.colormap <> NIL) then
begin
cinfo^.enable_external_quant := TRUE;
end
else
if (cinfo^.two_pass_quantize) then
begin
cinfo^.enable_2pass_quant := TRUE;
end
else
begin
cinfo^.enable_1pass_quant := TRUE;
end;
if (cinfo^.enable_1pass_quant) then
begin
{$ifdef QUANT_1PASS_SUPPORTED}
jinit_1pass_quantizer(cinfo);
master^.quantizer_1pass := cinfo^.cquantize;
{$else}
ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
{$endif}
end;
{ We use the 2-pass code to map to external colormaps. }
if (cinfo^.enable_2pass_quant) or (cinfo^.enable_external_quant) then
begin
{$ifdef QUANT_2PASS_SUPPORTED}
jinit_2pass_quantizer(cinfo);
master^.quantizer_2pass := cinfo^.cquantize;
{$else}
ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
{$endif}
end;
{ If both quantizers are initialized, the 2-pass one is left active;
this is necessary for starting with quantization to an external map. }
end;
{ Post-processing: in particular, color conversion first }
if (not cinfo^.raw_data_out) then
begin
if (master^.using_merged_upsample) then
begin
{$ifdef UPSAMPLE_MERGING_SUPPORTED}
jinit_merged_upsampler(cinfo); { does color conversion too }
{$else}
ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
{$endif}
end
else
begin
jinit_color_deconverter(cinfo);
jinit_upsampler(cinfo);
end;
jinit_d_post_controller(cinfo, cinfo^.enable_2pass_quant);
end;
{ Inverse DCT }
jinit_inverse_dct(cinfo);
{ Entropy decoding: either Huffman or arithmetic coding. }
if (cinfo^.arith_code) then
begin
ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL);
end
else
begin
if (cinfo^.progressive_mode) then
begin
{$ifdef D_PROGRESSIVE_SUPPORTED}
jinit_phuff_decoder(cinfo);
{$else}
ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
{$endif}
end
else
jinit_huff_decoder(cinfo);
end;
{ Initialize principal buffer controllers. }
use_c_buffer := cinfo^.inputctl^.has_multiple_scans or cinfo^.buffered_image;
jinit_d_coef_controller(cinfo, use_c_buffer);
if (not cinfo^.raw_data_out) then
jinit_d_main_controller(cinfo, FALSE { never need full buffer here });
{ We can now tell the memory manager to allocate virtual arrays. }
cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo));
{ Initialize input side of decompressor to consume first scan. }
cinfo^.inputctl^.start_input_pass (cinfo);
{$ifdef D_MULTISCAN_FILES_SUPPORTED}
{ If jpeg_start_decompress will read the whole file, initialize
progress monitoring appropriately. The input step is counted
as one pass. }
if (cinfo^.progress <> NIL) and (not cinfo^.buffered_image) and
(cinfo^.inputctl^.has_multiple_scans) then
begin
{ Estimate number of scans to set pass_limit. }
if (cinfo^.progressive_mode) then
begin
{ Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. }
nscans := 2 + 3 * cinfo^.num_components;
end
else
begin
{ For a nonprogressive multiscan file, estimate 1 scan per component. }
nscans := cinfo^.num_components;
end;
cinfo^.progress^.pass_counter := Long(0);
cinfo^.progress^.pass_limit := long (cinfo^.total_iMCU_rows) * nscans;
cinfo^.progress^.completed_passes := 0;
if cinfo^.enable_2pass_quant then
cinfo^.progress^.total_passes := 3
else
cinfo^.progress^.total_passes := 2;
{ Count the input pass as done }
Inc(master^.pass_number);
end;
{$endif} { D_MULTISCAN_FILES_SUPPORTED }
end;
{ Per-pass setup.
This is called at the beginning of each output pass. We determine which
modules will be active during this pass and give them appropriate
start_pass calls. We also set is_dummy_pass to indicate whether this
is a "real" output pass or a dummy pass for color quantization.
(In the latter case, jdapi.c will crank the pass to completion.) }
{METHODDEF}
procedure prepare_for_output_pass (cinfo : j_decompress_ptr); far;
var
master : my_master_ptr;
begin
master := my_master_ptr (cinfo^.master);
if (master^.pub.is_dummy_pass) then
begin
{$ifdef QUANT_2PASS_SUPPORTED}
{ Final pass of 2-pass quantization }
master^.pub.is_dummy_pass := FALSE;
cinfo^.cquantize^.start_pass (cinfo, FALSE);
cinfo^.post^.start_pass (cinfo, JBUF_CRANK_DEST);
cinfo^.main^.start_pass (cinfo, JBUF_CRANK_DEST);
{$else}
ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
{$endif} { QUANT_2PASS_SUPPORTED }
end
else
begin
if (cinfo^.quantize_colors) and (cinfo^.colormap = NIL) then
begin
{ Select new quantization method }
if (cinfo^.two_pass_quantize) and (cinfo^.enable_2pass_quant) then
begin
cinfo^.cquantize := master^.quantizer_2pass;
master^.pub.is_dummy_pass := TRUE;
end
else
if (cinfo^.enable_1pass_quant) then
begin
cinfo^.cquantize := master^.quantizer_1pass;
end
else
begin
ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE);
end;
end;
cinfo^.idct^.start_pass (cinfo);
cinfo^.coef^.start_output_pass (cinfo);
if (not cinfo^.raw_data_out) then
begin
if (not master^.using_merged_upsample) then
cinfo^.cconvert^.start_pass (cinfo);
cinfo^.upsample^.start_pass (cinfo);
if (cinfo^.quantize_colors) then
cinfo^.cquantize^.start_pass (cinfo, master^.pub.is_dummy_pass);
if master^.pub.is_dummy_pass then
cinfo^.post^.start_pass (cinfo, JBUF_SAVE_AND_PASS)
else
cinfo^.post^.start_pass (cinfo, JBUF_PASS_THRU);
cinfo^.main^.start_pass (cinfo, JBUF_PASS_THRU);
end;
end;
{ Set up progress monitor's pass info if present }
if (cinfo^.progress <> NIL) then
begin
cinfo^.progress^.completed_passes := master^.pass_number;
if master^.pub.is_dummy_pass then
cinfo^.progress^.total_passes := master^.pass_number + 2
else
cinfo^.progress^.total_passes := master^.pass_number + 1;
{ In buffered-image mode, we assume one more output pass if EOI not
yet reached, but no more passes if EOI has been reached. }
if (cinfo^.buffered_image) and (not cinfo^.inputctl^.eoi_reached) then
begin
if cinfo^.enable_2pass_quant then
Inc(cinfo^.progress^.total_passes, 2)
else
Inc(cinfo^.progress^.total_passes, 1);
end;
end;
end;
{ Finish up at end of an output pass. }
{METHODDEF}
procedure finish_output_pass (cinfo : j_decompress_ptr); far;
var
master : my_master_ptr;
begin
master := my_master_ptr (cinfo^.master);
if (cinfo^.quantize_colors) then
cinfo^.cquantize^.finish_pass (cinfo);
Inc(master^.pass_number);
end;
{$ifdef D_MULTISCAN_FILES_SUPPORTED}
{ Switch to a new external colormap between output passes. }
{GLOBAL}
procedure jpeg_new_colormap (cinfo : j_decompress_ptr);
var
master : my_master_ptr;
begin
master := my_master_ptr (cinfo^.master);
{ Prevent application from calling me at wrong times }
if (cinfo^.global_state <> DSTATE_BUFIMAGE) then
ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state);
if (cinfo^.quantize_colors) and (cinfo^.enable_external_quant) and
(cinfo^.colormap <> NIL) then
begin
{ Select 2-pass quantizer for external colormap use }
cinfo^.cquantize := master^.quantizer_2pass;
{ Notify quantizer of colormap change }
cinfo^.cquantize^.new_color_map (cinfo);
master^.pub.is_dummy_pass := FALSE; { just in case }
end
else
ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE);
end;
{$endif} { D_MULTISCAN_FILES_SUPPORTED }
{ Initialize master decompression control and select active modules.
This is performed at the start of jpeg_start_decompress. }
{GLOBAL}
procedure jinit_master_decompress (cinfo : j_decompress_ptr);
var
master : my_master_ptr;
begin
master := my_master_ptr (
cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
SIZEOF(my_decomp_master)) );
cinfo^.master := jpeg_decomp_master_ptr(master);
master^.pub.prepare_for_output_pass := prepare_for_output_pass;
master^.pub.finish_output_pass := finish_output_pass;
master^.pub.is_dummy_pass := FALSE;
master_selection(cinfo);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -