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

📄 jdmainct.pas

📁 用pascal寫的jpeg codec, 測試過的
💻 PAS
📖 第 1 页 / 共 2 页
字号:
    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 + -