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

📄 jdcoefct.pas

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

{ This code applies interblock smoothing as described by section K.8
  of the JPEG standard: the first 5 AC coefficients are estimated from
  the DC values of a DCT block and its 8 neighboring blocks.
  We apply smoothing only for progressive JPEG decoding, and only if
  the coefficients it can estimate are not yet known to full precision. }

{ Natural-order array positions of the first 5 zigzag-order coefficients }
const
  Q01_POS = 1;
  Q10_POS = 8;
  Q20_POS = 16;
  Q11_POS = 9;
  Q02_POS = 2;

{ Determine whether block smoothing is applicable and safe.
  We also latch the current states of the coef_bits[] entries for the
  AC coefficients; otherwise, if the input side of the decompressor
  advances into a new scan, we might think the coefficients are known
  more accurately than they really are. }

{LOCAL}
function smoothing_ok (cinfo : j_decompress_ptr) : boolean;
var
  coef : my_coef_ptr;
  smoothing_useful : boolean;
  ci, coefi : int;
  compptr : jpeg_component_info_ptr;
  qtable : JQUANT_TBL_PTR;
  coef_bits : coef_bits_ptr;
  coef_bits_latch : Latch_Ptr;
begin
  coef := my_coef_ptr (cinfo^.coef);
  smoothing_useful := FALSE;

  if (not cinfo^.progressive_mode) or (cinfo^.coef_bits = NIL) then
  begin
    smoothing_ok := FALSE;
    exit;
  end;

  { Allocate latch area if not already done }
  if (coef^.coef_bits_latch = NIL) then
    coef^.coef_bits_latch := Latch_Ptr(
      cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE,
                               cinfo^.num_components *
                               (SAVED_COEFS * SIZEOF(int))) );
  coef_bits_latch := (coef^.coef_bits_latch);

  compptr := cinfo^.comp_info;
  for ci := 0 to pred(cinfo^.num_components) do
  begin
    { All components' quantization values must already be latched. }
    qtable := compptr^.quant_table;
    if (qtable = NIL) then
    begin
      smoothing_ok := FALSE;
      exit;
    end;
    { Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. }
    if (qtable^.quantval[0] = 0) or
       (qtable^.quantval[Q01_POS] = 0) or
       (qtable^.quantval[Q10_POS] = 0) or
       (qtable^.quantval[Q20_POS] = 0) or
       (qtable^.quantval[Q11_POS] = 0) or
       (qtable^.quantval[Q02_POS] = 0) then
    begin
      smoothing_ok := FALSE;
      exit;
    end;
    { DC values must be at least partly known for all components. }
    coef_bits := @cinfo^.coef_bits^[ci];  { Nomssi }
    if (coef_bits^[0] < 0) then
    begin
      smoothing_ok := FALSE;
      exit;
    end;
    { Block smoothing is helpful if some AC coefficients remain inaccurate. }
    for coefi := 1 to 5 do
    begin
      coef_bits_latch^[coefi] := coef_bits^[coefi];
      if (coef_bits^[coefi] <> 0) then
	smoothing_useful := TRUE;
    end;
    Inc(coef_bits_latch {SAVED_COEFS});
    Inc(compptr);
  end;

  smoothing_ok := smoothing_useful;
end;


{ Variant of decompress_data for use when doing block smoothing. }

{METHODDEF}
function decompress_smooth_data (cinfo : j_decompress_ptr;
                        output_buf : JSAMPIMAGE) : int;
var
  coef : my_coef_ptr;
  last_iMCU_row : JDIMENSION;
  block_num, last_block_column : JDIMENSION;
  ci, block_row, block_rows, access_rows : int;
  buffer : JBLOCKARRAY;
  buffer_ptr, prev_block_row, next_block_row : JBLOCKROW;
  output_ptr : JSAMPARRAY;
  output_col : JDIMENSION;
  compptr : jpeg_component_info_ptr;
  inverse_DCT : inverse_DCT_method_ptr;
  first_row, last_row : boolean;
  workspace : JBLOCK;
  coef_bits : Latch_Ptr; { coef_bits_ptr;  }
  quanttbl : JQUANT_TBL_PTR;
  Q00,Q01,Q02,Q10,Q11,Q20, num : INT32;
  DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9 : int;
  Al, pred : int;
var
  delta : JDIMENSION;
begin
  coef := my_coef_ptr (cinfo^.coef);
  last_iMCU_row := cinfo^.total_iMCU_rows - 1;

  { Force some input to be done if we are getting ahead of the input. }
  while (cinfo^.input_scan_number <= cinfo^.output_scan_number) and
        (not cinfo^.inputctl^.eoi_reached) do
  begin
    if (cinfo^.input_scan_number = cinfo^.output_scan_number) then
    begin
      { If input is working on current scan, we ordinarily want it to
        have completed the current row.  But if input scan is DC,
        we want it to keep one row ahead so that next block row's DC
        values are up to date. }

      if (cinfo^.Ss = 0) then
        delta := 1
      else
        delta := 0;
      if (cinfo^.input_iMCU_row > cinfo^.output_iMCU_row+delta) then
	break;
    end;
    if (cinfo^.inputctl^.consume_input(cinfo) = JPEG_SUSPENDED) then
    begin
      decompress_smooth_data := JPEG_SUSPENDED;
      exit;
    end;
  end;

  { OK, output from the virtual arrays. }
  compptr := cinfo^.comp_info;
  for ci := 0 to (cinfo^.num_components-1) do
  begin
    { Don't bother to IDCT an uninteresting component. }
    if (not compptr^.component_needed) then
      continue;
    { Count non-dummy DCT block rows in this iMCU row. }
    if (cinfo^.output_iMCU_row < last_iMCU_row) then
    begin
      block_rows := compptr^.v_samp_factor;
      access_rows := block_rows * 2; { this and next iMCU row }
      last_row := FALSE;
    end
    else
    begin
      { NB: can't use last_row_height here; it is input-side-dependent! }
      block_rows := int (compptr^.height_in_blocks mod compptr^.v_samp_factor);
      if (block_rows = 0) then
        block_rows := compptr^.v_samp_factor;
      access_rows := block_rows; { this iMCU row only }
      last_row := TRUE;
    end;
    { Align the virtual buffer for this component. }
    if (cinfo^.output_iMCU_row > 0) then
    begin
      Inc(access_rows, compptr^.v_samp_factor); { prior iMCU row too }
      buffer := cinfo^.mem^.access_virt_barray
	(j_common_ptr (cinfo), coef^.whole_image[ci],
	 (cinfo^.output_iMCU_row - 1) * compptr^.v_samp_factor,
	 JDIMENSION (access_rows), FALSE);
      Inc(JBLOCKROW_PTR(buffer), compptr^.v_samp_factor); { point to current iMCU row }
      first_row := FALSE;
    end
    else
    begin
      buffer := cinfo^.mem^.access_virt_barray
	(j_common_ptr (cinfo), coef^.whole_image[ci],
	 JDIMENSION (0), JDIMENSION (access_rows), FALSE);
      first_row := TRUE;
    end;
    { Fetch component-dependent info }
    coef_bits := coef^.coef_bits_latch;
    Inc(coef_bits,  ci);                        { ci * SAVED_COEFS}
    quanttbl := compptr^.quant_table;
    Q00 := quanttbl^.quantval[0];
    Q01 := quanttbl^.quantval[Q01_POS];
    Q10 := quanttbl^.quantval[Q10_POS];
    Q20 := quanttbl^.quantval[Q20_POS];
    Q11 := quanttbl^.quantval[Q11_POS];
    Q02 := quanttbl^.quantval[Q02_POS];
    inverse_DCT := cinfo^.idct^.inverse_DCT[ci];
    output_ptr := output_buf^[ci];
    { Loop over all DCT blocks to be processed. }
    for block_row := 0 to (block_rows-1) do
    begin
      buffer_ptr := buffer^[block_row];
      if (first_row) and (block_row = 0) then
	prev_block_row := buffer_ptr
      else
	prev_block_row := buffer^[block_row-1];
      if (last_row) and (block_row = block_rows-1) then
	next_block_row := buffer_ptr
      else
	next_block_row := buffer^[block_row+1];
      { We fetch the surrounding DC values using a sliding-register approach.
        Initialize all nine here so as to do the right thing on narrow pics.}

      DC3 := int(prev_block_row^[0][0]);
      DC2 := DC3;
      DC1 := DC2;
      DC6 := int(buffer_ptr^[0][0]);
      DC5 := DC6;
      DC4 := DC5;
      DC9 := int(next_block_row^[0][0]);
      DC8 := DC9;
      DC7 := DC8 ;
      output_col := 0;
      last_block_column := compptr^.width_in_blocks - 1;
      for block_num := 0 to last_block_column do
      begin
	{ Fetch current DCT block into workspace so we can modify it. }
	jcopy_block_row(buffer_ptr, JBLOCKROW (@workspace), JDIMENSION(1));
	{ Update DC values }
	if (block_num < last_block_column) then
        begin
	  DC3 := int (prev_block_row^[1][0]);
	  DC6 := int (buffer_ptr^[1][0]);
	  DC9 := int (next_block_row^[1][0]);
	end;
	{ Compute coefficient estimates per K.8.
	  An estimate is applied only if coefficient is still zero,
	  and is not known to be fully accurate. }

	{ AC01 }
	Al := coef_bits^[1];
	if (Al <> 0) and (workspace[1] = 0) then
        begin
	  num := 36 * Q00 * (DC4 - DC6);
	  if (num >= 0) then
          begin
	    pred := int (((Q01 shl 7) + num) div (Q01 shl 8));
	    if (Al > 0) and (pred >= (1 shl Al)) then
	      pred := (1 shl Al)-1;
	  end
          else
          begin
	    pred := int (((Q01 shl 7) - num) div (Q01 shl 8));
	    if (Al > 0) and (pred >= (1 shl Al)) then
	      pred := (1 shl Al)-1;
	    pred := -pred;
	  end;
	  workspace[1] := JCOEF (pred);
	end;
	{ AC10 }
	Al := coef_bits^[2];
	if (Al <> 0) and (workspace[8] = 0) then
        begin
	  num := 36 * Q00 * (DC2 - DC8);
	  if (num >= 0) then
          begin
	    pred := int (((Q10 shl 7) + num) div (Q10 shl 8));
	    if (Al > 0) and (pred >= (1 shl Al)) then
	      pred := (1 shl Al)-1;
	  end
          else
          begin
	    pred := int (((Q10 shl 7) - num) div (Q10 shl 8));
	    if (Al > 0) and (pred >= (1 shl Al)) then
	      pred := (1 shl Al)-1;
	    pred := -pred;
	  end;
	  workspace[8] := JCOEF (pred);
	end;
	{ AC20 }
	Al := coef_bits^[3];
	if (Al <> 0) and (workspace[16] = 0) then
        begin
	  num := 9 * Q00 * (DC2 + DC8 - 2*DC5);
	  if (num >= 0) then
          begin
	    pred := int (((Q20 shl 7) + num) div (Q20 shl 8));
	    if (Al > 0) and (pred >= (1 shl Al)) then
	      pred := (1 shl Al)-1;
	  end
          else
          begin
	    pred := int (((Q20 shl 7) - num) div (Q20 shl 8));
	    if (Al > 0) and (pred >= (1 shl Al)) then
	      pred := (1 shl Al)-1;
	    pred := -pred;
	  end;
	  workspace[16] := JCOEF (pred);
	end;
	{ AC11 }
	Al := coef_bits^[4];
	if (Al <> 0) and (workspace[9] = 0) then
        begin
	  num := 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
	  if (num >= 0) then
          begin
	    pred := int (((Q11 shl 7) + num) div (Q11 shl 8));
	    if (Al > 0) and (pred >= (1 shl Al)) then
	      pred := (1 shl Al)-1;
	  end
          else
          begin
	    pred := int (((Q11 shl 7) - num) div (Q11 shl 8));
	    if (Al > 0) and (pred >= (1 shl Al)) then
	      pred := (1 shl Al)-1;
	    pred := -pred;
	  end;
	  workspace[9] := JCOEF (pred);
	end;
	{ AC02 }
	Al := coef_bits^[5];
	if (Al <> 0) and (workspace[2] = 0) then
        begin
	  num := 9 * Q00 * (DC4 + DC6 - 2*DC5);
	  if (num >= 0) then
          begin
	    pred := int (((Q02 shl 7) + num) div (Q02 shl 8));
	    if (Al > 0) and (pred >= (1 shl Al)) then
	      pred := (1 shl Al)-1;
	  end
          else
          begin
	    pred := int (((Q02 shl 7) - num) div (Q02 shl 8));
	    if (Al > 0) and (pred >= (1 shl Al)) then
	      pred := (1 shl Al)-1;
	    pred := -pred;
	  end;
	  workspace[2] := JCOEF (pred);
	end;
	{ OK, do the IDCT }
	inverse_DCT (cinfo, compptr, JCOEFPTR (@workspace),
			output_ptr, output_col);
	{ Advance for next column }
	DC1 := DC2; DC2 := DC3;
	DC4 := DC5; DC5 := DC6;
	DC7 := DC8; DC8 := DC9;
	Inc(JBLOCK_PTR(buffer_ptr));
        Inc(JBLOCK_PTR(prev_block_row));
        Inc(JBLOCK_PTR(next_block_row));
	Inc(output_col, compptr^.DCT_scaled_size);
      end;
      Inc(JSAMPROW_PTR(output_ptr), compptr^.DCT_scaled_size);
    end;
    Inc(compptr);
  end;

  Inc(cinfo^.output_iMCU_row);
  if (cinfo^.output_iMCU_row < cinfo^.total_iMCU_rows) then
  begin
    decompress_smooth_data := JPEG_ROW_COMPLETED;
    exit;
  end;
  decompress_smooth_data := JPEG_SCAN_COMPLETED;
end;

{$endif} { BLOCK_SMOOTHING_SUPPORTED }


{ Initialize coefficient buffer controller. }

{GLOBAL}
procedure jinit_d_coef_controller (cinfo : j_decompress_ptr;
                                   need_full_buffer : boolean);
var
  coef : my_coef_ptr;
{$ifdef D_MULTISCAN_FILES_SUPPORTED}
var
  ci, access_rows : int;
  compptr : jpeg_component_info_ptr;
{$endif}
var
  buffer : JBLOCK_PTR;
  i : int;
begin
  coef := my_coef_ptr(
    cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE,
				SIZEOF(my_coef_controller)) );
  cinfo^.coef := jpeg_d_coef_controller_ptr(coef);
  coef^.pub.start_input_pass := start_input_pass;
  coef^.pub.start_output_pass := start_output_pass;
{$ifdef BLOCK_SMOOTHING_SUPPORTED}
  coef^.coef_bits_latch := NIL;
{$endif}

  { Create the coefficient buffer. }
  if (need_full_buffer) then
  begin
{$ifdef D_MULTISCAN_FILES_SUPPORTED}
    { Allocate a full-image virtual array for each component, }
    { padded to a multiple of samp_factor DCT blocks in each direction. }
    { Note we ask for a pre-zeroed array. }

    compptr := cinfo^.comp_info;
    for ci := 0 to pred(cinfo^.num_components) do
    begin
      access_rows := compptr^.v_samp_factor;
{$ifdef BLOCK_SMOOTHING_SUPPORTED}
      { If block smoothing could be used, need a bigger window }
      if (cinfo^.progressive_mode) then
	access_rows := access_rows * 3;
{$endif}
      coef^.whole_image[ci] := cinfo^.mem^.request_virt_barray
	(j_common_ptr (cinfo), JPOOL_IMAGE, TRUE,
	 JDIMENSION (jround_up( long(compptr^.width_in_blocks),
                                long(compptr^.h_samp_factor) )),
	 JDIMENSION (jround_up( long(compptr^.height_in_blocks),
				long(compptr^.v_samp_factor) )),
	 JDIMENSION (access_rows));
      Inc(compptr);
    end;
    coef^.pub.consume_data := consume_data;
    coef^.pub.decompress_data := decompress_data;
    coef^.pub.coef_arrays := @(coef^.whole_image);
                          { link to virtual arrays }
{$else}
    ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED);
{$endif}
  end
  else
  begin
    { We only need a single-MCU buffer. }
    buffer := JBLOCK_PTR (
      cinfo^.mem^.alloc_large (j_common_ptr (cinfo), JPOOL_IMAGE,
				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)) );
    for i := 0 to pred(D_MAX_BLOCKS_IN_MCU) do
    begin
      coef^.MCU_buffer[i] := JBLOCKROW(buffer);
      Inc(buffer);
    end;
    coef^.pub.consume_data := dummy_consume_data;
    coef^.pub.decompress_data := decompress_onepass;
    coef^.pub.coef_arrays := NIL; { flag for no virtual arrays }
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -