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

📄 jcsample.pas

📁 DELPHI版的JPEG文件解码源程序
💻 PAS
📖 第 1 页 / 共 2 页
字号:
		           GETJSAMPLE(inptr1^) +
                           GETJSAMPLE(JSAMPROW(inptr1)^[1]) + bias) shr 2);
      Inc(outptr);
      bias := bias xor 3;       { 1=>2, 2=>1 }
      Inc(inptr0, 2);
      Inc(inptr1, 2);
    end;
    Inc(inrow, 2);
  end;
end;


{$ifdef INPUT_SMOOTHING_SUPPORTED}

{ Downsample pixel values of a single component.
  This version handles the standard case of 2:1 horizontal and 2:1 vertical,
  with smoothing.  One row of context is required. }

{METHODDEF}
procedure h2v2_smooth_downsample (cinfo : j_compress_ptr;
                                  compptr : jpeg_component_info_ptr;
                                  input_data : JSAMPARRAY;
                                  output_data : JSAMPARRAY); far;
var
  inrow, outrow : int;
  colctr : JDIMENSION;
  output_cols : JDIMENSION;
  {register} inptr0, inptr1, above_ptr, below_ptr, outptr : JSAMPLE_PTR;
  membersum, neighsum, memberscale, neighscale : INT32;
var
  prev_input_data : JSAMPARRAY;
  prev_inptr0, prev_inptr1, prev_above_ptr, prev_below_ptr : JSAMPLE_PTR;
begin
  output_cols := compptr^.width_in_blocks * DCTSIZE;

  { Expand input data enough to let all the output samples be generated
    by the standard loop.  Special-casing padded output would be more
    efficient. }

  prev_input_data := input_data;
  Dec(JSAMPROW_PTR(prev_input_data));
  expand_right_edge(prev_input_data, cinfo^.max_v_samp_factor + 2,
		    cinfo^.image_width, output_cols * 2);

  { We don't bother to form the individual "smoothed" input pixel values;
    we can directly compute the output which is the average of the four
    smoothed values.  Each of the four member pixels contributes a fraction
    (1-8*SF) to its own smoothed image and a fraction SF to each of the three
    other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
    output.  The four corner-adjacent neighbor pixels contribute a fraction
    SF to just one smoothed pixel, or SF/4 to the final output; while the
    eight edge-adjacent neighbors contribute SF to each of two smoothed
    pixels, or SF/2 overall.  In order to use integer arithmetic, these
    factors are scaled by 2^16 := 65536.
    Also recall that SF := smoothing_factor / 1024. }

  memberscale := 16384 - cinfo^.smoothing_factor * 80; { scaled (1-5*SF)/4 }
  neighscale := cinfo^.smoothing_factor * 16; { scaled SF/4 }

  inrow := 0;
  for outrow := 0 to pred(compptr^.v_samp_factor) do
  begin
    outptr := JSAMPLE_PTR(output_data^[outrow]);
    inptr0 := JSAMPLE_PTR(input_data^[inrow]);
    inptr1 := JSAMPLE_PTR(input_data^[inrow+1]);
    above_ptr := JSAMPLE_PTR(input_data^[inrow-1]);
    below_ptr := JSAMPLE_PTR(input_data^[inrow+2]);

    { Special case for first column: pretend column -1 is same as column 0 }
    membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
		GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
    neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
	       GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) +
	       GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[2]) +
	       GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[2]);
    Inc(neighsum, neighsum);
    Inc(neighsum, GETJSAMPLE(above_ptr^) +
                  GETJSAMPLE(JSAMPROW(above_ptr)^[2]) +
		  GETJSAMPLE(below_ptr^) +
                  GETJSAMPLE(JSAMPROW(below_ptr)^[2]) );
    membersum := membersum * memberscale + neighsum * neighscale;
    outptr^ := JSAMPLE ((membersum + 32768) shr 16);
    Inc(outptr);
    prev_inptr0 := inptr0;
    prev_inptr1 := inptr1;
    Inc(prev_inptr0);
    Inc(prev_inptr1);
    Inc(inptr0, 2);
    Inc(inptr1, 2);
    prev_above_ptr := above_ptr;
    prev_below_ptr := below_ptr;
    Inc(above_ptr, 2);
    Inc(below_ptr, 2);
    Inc(prev_above_ptr, 1);
    Inc(prev_below_ptr, 1);

    for colctr := pred(output_cols - 2) downto 0 do
    begin
      { sum of pixels directly mapped to this output element }
      membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
                   GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
      { sum of edge-neighbor pixels }
      neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
                  GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) +
                  GETJSAMPLE(prev_inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[2]) +
                  GETJSAMPLE(prev_inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[2]);
      { The edge-neighbors count twice as much as corner-neighbors }
      Inc(neighsum, neighsum);
      { Add in the corner-neighbors }
      Inc(neighsum, GETJSAMPLE(prev_above_ptr^) +
                    GETJSAMPLE(JSAMPROW(above_ptr)^[2]) +
		    GETJSAMPLE(prev_below_ptr^) +
                    GETJSAMPLE(JSAMPROW(below_ptr)^[2]) );
      { form final output scaled up by 2^16 }
      membersum := membersum * memberscale + neighsum * neighscale;
      { round, descale and output it }
      outptr^ := JSAMPLE ((membersum + 32768) shr 16);
      Inc(outptr);
      Inc(inptr0, 2);
      Inc(inptr1, 2);
      Inc(prev_inptr0, 2);
      Inc(prev_inptr1, 2);
      Inc(above_ptr, 2);
      Inc(below_ptr, 2);
      Inc(prev_above_ptr, 2);
      Inc(prev_below_ptr, 2);
    end;

    { Special case for last column }
    membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
		 GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
    neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
	        GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) +
	        GETJSAMPLE(prev_inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
	        GETJSAMPLE(prev_inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
    Inc(neighsum, neighsum);
    Inc(neighsum, GETJSAMPLE(prev_above_ptr^) +
                  GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
		  GETJSAMPLE(prev_below_ptr^) +
                  GETJSAMPLE(JSAMPROW(below_ptr)^[1]) );
    membersum := membersum * memberscale + neighsum * neighscale;
    outptr^ := JSAMPLE ((membersum + 32768) shr 16);

    Inc(inrow, 2);
  end;
end;


{ Downsample pixel values of a single component.
  This version handles the special case of a full-size component,
  with smoothing.  One row of context is required. }

{METHODDEF}
procedure fullsize_smooth_downsample (cinfo : j_compress_ptr;
                                      compptr : jpeg_component_info_ptr;
			              input_data : JSAMPARRAY;
                                      output_data : JSAMPARRAY); far;
var
  outrow : int;
  colctr : JDIMENSION;
  output_cols : JDIMENSION;
  {register} inptr, above_ptr, below_ptr, outptr : JSAMPLE_PTR;
  membersum, neighsum, memberscale, neighscale : INT32;
  colsum, lastcolsum, nextcolsum : int;
var
  prev_input_data : JSAMPARRAY;
begin
  output_cols := compptr^.width_in_blocks * DCTSIZE;

  { Expand input data enough to let all the output samples be generated
    by the standard loop.  Special-casing padded output would be more
    efficient. }

  prev_input_data := input_data;
  Dec(JSAMPROW_PTR(prev_input_data));
  expand_right_edge(prev_input_data, cinfo^.max_v_samp_factor + 2,
		    cinfo^.image_width, output_cols);

  { Each of the eight neighbor pixels contributes a fraction SF to the
    smoothed pixel, while the main pixel contributes (1-8*SF).  In order
    to use integer arithmetic, these factors are multiplied by 2^16 := 65536.
    Also recall that SF := smoothing_factor / 1024. }

  memberscale := long(65536) - cinfo^.smoothing_factor * long(512); { scaled 1-8*SF }
  neighscale := cinfo^.smoothing_factor * 64; { scaled SF }

  for outrow := 0 to pred(compptr^.v_samp_factor) do
  begin
    outptr := JSAMPLE_PTR(output_data^[outrow]);
    inptr := JSAMPLE_PTR(input_data^[outrow]);
    above_ptr := JSAMPLE_PTR(input_data^[outrow-1]);
    below_ptr := JSAMPLE_PTR(input_data^[outrow+1]);

    { Special case for first column }
    colsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) +
	     GETJSAMPLE(inptr^);
    Inc(above_ptr);
    Inc(below_ptr);
    membersum := GETJSAMPLE(inptr^);
    Inc(inptr);
    nextcolsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) +
		  GETJSAMPLE(inptr^);
    neighsum := colsum + (colsum - membersum) + nextcolsum;
    membersum := membersum * memberscale + neighsum * neighscale;
    outptr^ := JSAMPLE ((membersum + 32768) shr 16);
    Inc(outptr);
    lastcolsum := colsum; colsum := nextcolsum;

    for colctr := pred(output_cols - 2) downto 0 do
    begin
      membersum := GETJSAMPLE(inptr^);
      Inc(inptr);
      Inc(above_ptr);
      Inc(below_ptr);
      nextcolsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) +
		    GETJSAMPLE(inptr^);
      neighsum := lastcolsum + (colsum - membersum) + nextcolsum;
      membersum := membersum * memberscale + neighsum * neighscale;
      outptr^ := JSAMPLE ((membersum + 32768) shr 16);
      Inc(outptr);
      lastcolsum := colsum; colsum := nextcolsum;
    end;

    { Special case for last column }
    membersum := GETJSAMPLE(inptr^);
    neighsum := lastcolsum + (colsum - membersum) + colsum;
    membersum := membersum * memberscale + neighsum * neighscale;
    outptr^ := JSAMPLE ((membersum + 32768) shr 16);
  end;
end;

{$endif} { INPUT_SMOOTHING_SUPPORTED }


{ Module initialization routine for downsampling.
  Note that we must select a routine for each component. }

{GLOBAL}
procedure jinit_downsampler (cinfo : j_compress_ptr);
var
  downsample : my_downsample_ptr;
  ci : int;
  compptr : jpeg_component_info_ptr;
  smoothok : boolean;
begin
  smoothok := TRUE;

  downsample := my_downsample_ptr(
    cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
				SIZEOF(my_downsampler)) );
  cinfo^.downsample := jpeg_downsampler_ptr (downsample);
  downsample^.pub.start_pass := start_pass_downsample;
  downsample^.pub.downsample := sep_downsample;
  downsample^.pub.need_context_rows := FALSE;

  if (cinfo^.CCIR601_sampling) then
    ERREXIT(j_common_ptr(cinfo), JERR_CCIR601_NOTIMPL);

  { Verify we can handle the sampling factors, and set up method pointers }
  compptr := jpeg_component_info_ptr(cinfo^.comp_info);
  for ci := 0 to pred(cinfo^.num_components) do
  begin
    if (compptr^.h_samp_factor = cinfo^.max_h_samp_factor) and
       (compptr^.v_samp_factor = cinfo^.max_v_samp_factor) then
    begin
{$ifdef INPUT_SMOOTHING_SUPPORTED}
      if (cinfo^.smoothing_factor <> 0) then
      begin
	downsample^.methods[ci] := fullsize_smooth_downsample;
	downsample^.pub.need_context_rows := TRUE;
      end
      else
{$endif}
	downsample^.methods[ci] := fullsize_downsample;
    end
    else
      if (compptr^.h_samp_factor * 2 = cinfo^.max_h_samp_factor) and
         (compptr^.v_samp_factor = cinfo^.max_v_samp_factor) then
      begin
        smoothok := FALSE;
        downsample^.methods[ci] := h2v1_downsample;
      end
      else
        if (compptr^.h_samp_factor * 2 = cinfo^.max_h_samp_factor) and
	   (compptr^.v_samp_factor * 2 = cinfo^.max_v_samp_factor) then
        begin
  {$ifdef INPUT_SMOOTHING_SUPPORTED}
        if (cinfo^.smoothing_factor <> 0) then
        begin
	  downsample^.methods[ci] := h2v2_smooth_downsample;
	  downsample^.pub.need_context_rows := TRUE;
        end
        else
  {$endif}
          downsample^.methods[ci] := h2v2_downsample;
        end
        else
          if ((cinfo^.max_h_samp_factor mod compptr^.h_samp_factor) = 0) and
	     ((cinfo^.max_v_samp_factor mod compptr^.v_samp_factor) = 0) then
          begin
            smoothok := FALSE;
            downsample^.methods[ci] := int_downsample;
          end
          else
            ERREXIT(j_common_ptr(cinfo), JERR_FRACT_SAMPLE_NOTIMPL);
    Inc(compptr);
  end;

{$ifdef INPUT_SMOOTHING_SUPPORTED}
  if (cinfo^.smoothing_factor <> 0) and (not smoothok) then
    TRACEMS(j_common_ptr(cinfo), 0, JTRC_SMOOTH_NOTIMPL);
{$endif}
end;

end.

⌨️ 快捷键说明

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