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

📄 jidct2d.pas

📁 DELPHI版的JPEG文件解码源程序
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{GLOBAL}
procedure jpeg_idct_i2d (cinfo : j_decompress_ptr;
                         compptr : jpeg_component_info_ptr;
		         coef_block : JCOEFPTR;
		         output_buf : JSAMPARRAY;
                         output_col : JDIMENSION);

procedure Feig_2D_IDCT(coef_block :imatrix;
                       output_buf : JSAMPARRAY);
Const
  CONST_IC4 = 1.414213562; { 1/0.707106781; }
  FP_IC4    = Integer(Round(IFX_CONST*CONST_IC4));
  FP_I_C4_2  = FP_IC4;

  Function Descale(x : integer):integer;
  begin
    DeScale := (x+ (4 shl PASS_BITS)) div (8 shl PASS_BITS);
    { DeScale := x sar (3 + PASS_BITS);
      Borland Pascal SHR is unsigned }
  end;
  {
  function Multiply(X, Y: Integer): integer;
  begin
    Multiply := Integer( X*LongInt(Y) div IFX_CONST);
  end;
  }
  function Multiply(X, Y: Integer): integer; assembler;
  asm
    mov ax, X
    imul Y
    mov al, ah
    mov ah, dl
  end;


var
  z10, z11, z12, z13,
  tmp0,tmp1,tmp2,tmp3,
  tmp4,tmp5,tmp6,tmp7,
  tmp10,tmp11,
  tmp12,tmp13 : integer;
  column, row : byte;

  Procedure N1(var x, y : integer);   { rotator 1 }
  Const
    FP_a5 = Integer(Round(IFX_CONST*1.847759065));
    FP_a4 = Integer(Round(IFX_CONST*2.613125930));
    FP_a2 = Integer(Round(IFX_CONST*1.082392200));
  var
    z5, tmp : integer;
  begin
    tmp := x;

    z5 := Multiply(tmp + y, FP_a5);  { c6 }
    x := Multiply(y, FP_a2) - z5;  { c2-c6 }
    y := Multiply(tmp, -FP_a4) + z5;  { c2+c6 }
  end;

  Procedure N2(var x, y : integer); { N1 scaled by c4 }
  Const
    FP_b5 = Integer(Round(IFX_CONST*1.847759065*CONST_IC4));
    FP_b4 = Integer(Round(IFX_CONST*2.613125930*CONST_IC4));
    FP_b2 = Integer(Round(IFX_CONST*1.082392200*CONST_IC4));
  var
    z5, tmp : integer;
  begin
    tmp := x;

    z5 := Multiply(tmp + y, FP_b5);
    x := Multiply(y, FP_b2) - z5;
    y := Multiply(tmp,-FP_b4) + z5;
  end;

var
  tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : DCTELEM;
  tmp10, tmp11, tmp12, tmp13 : DCTELEM;
  z10, z11, z12, z13 : DCTELEM;
  inptr : JCOEFPTR;

  quantptr : IFAST_MULT_TYPE_FIELD_PTR;
  wsptr : PWorkspace;
  outptr : JSAMPROW;
  range_limit : JSAMPROW;
  ctr : int;
  workspace : TWorkspace;       { buffers data between passes }
  {SHIFT_TEMPS			{ for DESCALE }
  {ISHIFT_TEMPS			{ for IDESCALE }
var
  dcval : int;
var
  dcval_ : JSAMPLE;
begin
{ Each IDCT routine is responsible for range-limiting its results and
  converting them to unsigned form (0..MAXJSAMPLE).  The raw outputs could
  be quite far out of range if the input data is corrupt, so a bulletproof
  range-limiting step is required.  We use a mask-and-table-lookup method
  to do the combined operations quickly.  See the comments with
  prepare_range_limit_table (in jdmaster.c) for more info. }

  range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE]));
  { Pass 1: process columns from input, store into work array. }

  inptr := coef_block;
  quantptr := IFAST_MULT_TYPE_FIELD_PTR(compptr^.dct_table);
  wsptr := @workspace;

  { R1 x R1 }
  for ctr := pred(DCTSIZE) downto 0 do
  BEGIN
    { even part }
    tmp1 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]);
    tmp3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]);

    wsptr^[DCTSIZE*0] := int (DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]));
    wsptr^[DCTSIZE*1] := int (DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]);

    { Odd part }

    tmp6 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]);
    tmp4 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]);
    tmp7 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]);
    tmp5 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]);


    z13 := tmp6 + tmp5;
    wsptr^[DCTSIZE*4] := int (tmp6 - tmp5);

    z11 := tmp4 + tmp7;
    wsptr^[DCTSIZE*6] := int (tmp4 - tmp7);

    wsptr^[DCTSIZE*7] := int (z11 + z13);
    wsptr^[DCTSIZE*5] := int (z11 - z13);

    wsptr^[DCTSIZE*3] := int (tmp1 + tmp3);
    wsptr^[DCTSIZE*2] := int (tmp1 - tmp3);

    Inc(JCOEF_PTR(inptr));		{ advance pointers to next column }
    Inc(IFAST_MULT_TYPE_PTR(quantptr));
    Inc(int_ptr(wsptr));
  END;

  wsptr := @workspace[DCTSIZE*pred(DCTSIZE)];
  for row := pred(DCTSIZE) downto 0 do
  BEGIN
    { Odd part }
    tmp5 := DCTELEM(wsptr^[1]);
    tmp7 := DCTELEM(wsptr^[3]);

    { even part }

    {noop:
    tmp0 := DCTELEM(wsptr^[0]);
    wsptr^[0] := DCTELEM(tmp0);}

    {tmp2 := DCTELEM(wsptr^[4]);}
    wsptr^[1] := wsptr^[4];

    tmp1 := DCTELEM(wsptr^[2]);
    tmp3 := DCTELEM(wsptr^[6]);

    wsptr^[2] := DCTELEM(tmp1 - tmp3);
    wsptr^[3] := DCTELEM(tmp1 + tmp3);

    { Odd part }
    tmp4 := DCTELEM(wsptr^[5]);
    tmp6 := DCTELEM(wsptr^[7]);

    z13 := tmp4 + tmp7;
    wsptr^[4] := DCTELEM(tmp4 - tmp7);

    z11 := tmp5 + tmp6;
    wsptr^[6] := DCTELEM(tmp5 - tmp6);

    wsptr^[7] := DCTELEM(z11 + z13);
    wsptr^[5] := DCTELEM(z11 - z13);
    Dec(int_ptr(wsptr), DCTSIZE);	{ advance pointer to previous row }
  END;

  { M x M tensor }
  wsptr := @workspace[DCTSIZE*0];
  for row := 0 to pred(DCTSIZE) do
  begin
    Case row of
    0,1,3,7: { M1 }
      begin
        wsptr^[2] := Multiply(wsptr^[2], FP_IC4);     { 2/c4 }
        wsptr^[5] := Multiply(wsptr^[5], FP_IC4);     { 2/c4 }

        N1(wsptr^[ 4], wsptr^[ 6]);
      end;
    2,5: { M2 }
      begin
        wsptr^[0] := Multiply(wsptr^[0], FP_IC4);
        wsptr^[1] := Multiply(wsptr^[1], FP_IC4);
        wsptr^[3] := Multiply(wsptr^[3], FP_IC4);
        wsptr^[7] := Multiply(wsptr^[7], FP_IC4);

        wsptr^[2] := wsptr^[2] * 2;  { shift }
        wsptr^[5] := wsptr^[5] * 2;

        N2(wsptr^[4], wsptr^[6]);
      end;
    end; { Case }
    Inc(int_ptr(wsptr), DCTSIZE);	{ advance pointer to next row }
  end;

  { M x N tensor }
  { rows 4,6 }
  begin
    N1(workspace[DCTSIZE*4+0], workspace[DCTSIZE*6+0]);
    N1(workspace[DCTSIZE*4+1], workspace[DCTSIZE*6+1]);
    N1(workspace[DCTSIZE*4+3], workspace[DCTSIZE*6+3]);
    N1(workspace[DCTSIZE*4+7], workspace[DCTSIZE*6+7]);

    N2(workspace[DCTSIZE*4+2], workspace[DCTSIZE*6+2]);
    N2(workspace[DCTSIZE*4+5], workspace[DCTSIZE*6+5]);

    { N3 }
    tmp0 := workspace[DCTSIZE*4,4];
    tmp1 := workspace[DCTSIZE*6,4];
    tmp2 := workspace[DCTSIZE*4,6];
    tmp3 := workspace[DCTSIZE*6,6];

    { two inverse matrices => same as FDCT }
    z10 := tmp0 - tmp3;
    z11 := tmp1 + tmp2;

    z12 := tmp0 + tmp3;
    z13 := tmp1 - tmp2;

    tmp0 := Multiply(z10 + z11, FP_I_C4_2);
    tmp1 := Multiply(z10 - z11, FP_I_C4_2);

    tmp2 := z12 * 2;       { shifts }
    tmp3 := z13 * (-2);


    workspace[DCTSIZE*4,4] := tmp2 + tmp0;
    workspace[DCTSIZE*6,4] := tmp1 + tmp3;

    workspace[DCTSIZE*4,6] := tmp1 - tmp3;
    workspace[DCTSIZE*6,6] := tmp2 - tmp0;
  end;

  { R2 x R2 }

  wsptr := @workspace;
  for row := 0 to pred(DCTSIZE) do
  BEGIN
    { even part }
    tmp0 := wsptr^[0];
    tmp2 := wsptr^[1];
    tmp1 := wsptr^[2];
    tmp3 := wsptr^[3];

    tmp10 := tmp0 + tmp2;
    tmp11 := tmp0 - tmp2;

    tmp12 := tmp1 - tmp3;
    tmp13 := tmp3;

    tmp0 := tmp10 + tmp13;
    tmp3 := tmp10 - tmp13;

    tmp2 := tmp11 + tmp12;
    tmp1 := tmp11 - tmp12;

    { Odd part }
    tmp4 := wsptr^[4];
    tmp5 := wsptr^[5];
    tmp6 := wsptr^[6];
    tmp7 := wsptr^[7];

    tmp6 := tmp6 - tmp7;
    tmp5 := tmp5 - tmp6;
    tmp4 :=-tmp4 - tmp5;

    wsptr^[0] := (tmp0 + tmp7);
    wsptr^[7] := (tmp0 - tmp7);

    wsptr^[1] := (tmp2 + tmp6);
    wsptr^[6] := (tmp2 - tmp6);

    wsptr^[2] := (tmp1 + tmp5);
    wsptr^[5] := (tmp1 - tmp5);

    wsptr^[3] := (tmp3 + tmp4);
    wsptr^[4] := (tmp3 - tmp4);

    Inc(int_ptr(wsptr), DCTSIZE);	{ advance pointer to next row }
  END;

  wsptr := @workspace;
  for ctr := 0 to pred(DCTSIZE) do
  BEGIN
    outptr := JSAMPROW(@output_buf^[ctr]^[output_col]);
    { even part }
    tmp0 := wsptr[0];
    tmp1 := wsptr[1];
    tmp2 := wsptr[2];
    tmp3 := wsptr[3];

    tmp10 := tmp0 + tmp1;
    tmp11 := tmp0 - tmp1;

    tmp13 := tmp3;
    tmp12 := tmp2 - tmp3;

    tmp0 := tmp10 + tmp13;
    tmp3 := tmp10 - tmp13;

    tmp1 := tmp11 + tmp12;
    tmp2 := tmp11 - tmp12;

    { Odd part }
    tmp4 := wsptr[4];
    tmp5 := wsptr[5];
    tmp6 := wsptr[6];
    tmp7 := wsptr[7];

    tmp6 := tmp6 - tmp7;
    tmp5 := tmp5 - tmp6;
    tmp4 :=-tmp4 - tmp5;

    { Final output stage: scale down by a factor of 8 and range-limit }

    outptr^[0] := range_limit^[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
			    and RANGE_MASK];
    outptr^[7] := range_limit^[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
			    and RANGE_MASK];
    outptr^[1] := range_limit^[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
			    and RANGE_MASK];
    outptr^[6] := range_limit^[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
			    and RANGE_MASK];
    outptr^[2] := range_limit^[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
			    and RANGE_MASK];
    outptr^[5] := range_limit^[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
			    and RANGE_MASK];
    outptr^[4] := range_limit^[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
			    and RANGE_MASK];
    outptr^[3] := range_limit^[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
			    and RANGE_MASK];
    Inc(int_ptr(wsptr));
  END;
End; {----------------------------------------}


{----------------------------------------------------------------------}

⌨️ 快捷键说明

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