⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jdmaster.pas

📁 用pascal寫的jpeg codec, 測試過的
💻 PAS
📖 第 1 页 / 共 2 页
字号:

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 + -