📄 jidct2d.pas
字号:
{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 + -