📄 jidct2d.pas
字号:
{ Pass 2: process rows from work array, store into output array. }
{ Note that we must descale the results by a factor of 8 == 2**3, }
{ and also undo the PASS1_BITS scaling. }
wsptr := @workspace;
for ctr := 0 to pred(DCTSIZE) do
begin
outptr := JSAMPROW(@output_buf^[ctr]^[output_col]);
{ Rows of zeroes can be exploited in the same way as we did with columns.
However, the column calculation has created many nonzero AC terms, so
the simplification applies less often (typically 5% to 10% of the time).
On machines with very fast multiplication, it's possible that the
test takes more time than it's worth. In that case this section
may be commented out. }
{$ifndef NO_ZERO_ROW_TEST}
if ((wsptr^[1]) or (wsptr^[2]) or (wsptr^[3]) or (wsptr^[4]) or (wsptr^[5]) or
(wsptr^[6]) or (wsptr^[7]) = 0) then
begin
{ AC terms all zero }
JSAMPLE(dcval_) := range_limit^[IDESCALE(wsptr^[0], PASS1_BITS+3)
and RANGE_MASK];
outptr^[0] := dcval_;
outptr^[1] := dcval_;
outptr^[2] := dcval_;
outptr^[3] := dcval_;
outptr^[4] := dcval_;
outptr^[5] := dcval_;
outptr^[6] := dcval_;
outptr^[7] := dcval_;
Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row }
continue;
end;
{$endif}
{ Even part }
tmp10 := (DCTELEM(wsptr^[0]) + DCTELEM(wsptr^[4]));
tmp11 := (DCTELEM(wsptr^[0]) - DCTELEM(wsptr^[4]));
tmp13 := (DCTELEM(wsptr^[2]) + DCTELEM(wsptr^[6]));
tmp12 := MULTIPLY(DCTELEM(wsptr^[2]) - DCTELEM(wsptr^[6]), FIX_1_414213562)
- tmp13;
tmp0 := tmp10 + tmp13;
tmp3 := tmp10 - tmp13;
tmp1 := tmp11 + tmp12;
tmp2 := tmp11 - tmp12;
{ Odd part }
z13 := DCTELEM(wsptr^[5]) + DCTELEM(wsptr^[3]);
z10 := DCTELEM(wsptr^[5]) - DCTELEM(wsptr^[3]);
z11 := DCTELEM(wsptr^[1]) + DCTELEM(wsptr^[7]);
z12 := DCTELEM(wsptr^[1]) - DCTELEM(wsptr^[7]);
tmp7 := z11 + z13; { phase 5 }
tmp11 := MULTIPLY(z11 - z13, FIX_1_414213562); { 2*c4 }
z5 := MULTIPLY(z10 + z12, FIX_1_847759065); { 2*c2 }
tmp10 := MULTIPLY(z12, FIX_1_082392200) - z5; { 2*(c2-c6) }
tmp12 := MULTIPLY(z10, - FIX_2_613125930) + z5; { -2*(c2+c6) }
tmp6 := tmp12 - tmp7; { phase 2 }
tmp5 := tmp11 - tmp6;
tmp4 := tmp10 + 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), DCTSIZE); { advance pointer to next row }
end;
end;
end.
----------------------------------------------------------
type
matasm = array[0..DCTSIZE2-1] of integer;
bmatrix = array[0..DCTSIZE2-1] of byte;
bmatrixptr = ^bmatrix;
procedure ANN_IDCT(var coef_block :matasm;
var outptr :bmatrix);
var coeffs :matasm; = coef_block
var outptr :bmatrix); output_buf
Const
CONST_IC4 = 1.414213562; { 1/0.707106781; }
FP_IC4 = FIX_1_414213562;
FP_I_C4_2 = FP_IC4;
Function Descale(x : integer):byte;
var y : integer;
begin
y := (x + (1 shl (16-1))+ (4 shl PASS_BITS)) div (8 shl PASS_BITS);
{ DeScale := x sar (3 + PASS_BITS);
Borland Pascal SHR is unsigned }
if y < 0 then
descale := 0
else
if y > $ff then
descale := $ff
else
descale := y;
end;
function Multiply(X, Y: Integer): integer; assembler;
asm
mov ax, X
imul Y
mov al, ah
mov ah, dl
end;
Const
RowSize = 8;
var
a, b : integer;
inptr : JCOEFPTR;
outptr : bmatrixptr;
num : integer;
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; + ctr*RowSize
quantptr := IFAST_MULT_TYPE_FIELD_PTR(compptr^.dct_table);
for ctr := pred(DCTSIZE) downto 0 do
BEGIN
tmp5 := inptr^[1];
inptr^[1] := inptr^[4];
tmp7 := inptr^[3];
a := inptr^[2];
b := inptr^[6];
inptr^[2] := a - b;
inptr^[3] := a + b;
a := inptr^[5];
inptr^[+ 4] := a - tmp7;
z13 := a + tmp7;
b := inptr^[7];
inptr^[6] := tmp5 - b;
z11 := tmp5 + b;
inptr^[5] := z11 - z13;
inptr^[7] := z11 + z13;
END;
{ M x M tensor }
for row := 0 to 7 do
Case row of
0,1,3,7: { M1 }
begin
inptr^[row*RowSize + 2] := Multiply(inptr^[row*RowSize + 2], FP_IC4); { 2/c4 }
inptr^[row*RowSize + 5] := Multiply(inptr^[row*RowSize + 5], FP_IC4); { 2/c4 }
N1(inptr^[row*RowSize + 4], inptr^[row*RowSize + 6]);
end;
2,5: { M2 }
begin
inptr^[row*RowSize + 0] := Multiply(inptr^[row*RowSize + 0], FP_IC4);
inptr^[row*RowSize + 1] := Multiply(inptr^[row*RowSize + 1], FP_IC4);
inptr^[row*RowSize + 3] := Multiply(inptr^[row*RowSize + 3], FP_IC4);
inptr^[row*RowSize + 7] := Multiply(inptr^[row*RowSize + 7], FP_IC4);
inptr^[row*RowSize + 2] := inptr^[row*RowSize + 2] * 2; { shift }
inptr^[row*RowSize + 5] := inptr^[row*RowSize + 5] * 2;
N2(inptr^[row*RowSize + 4], inptr^[row*RowSize + 6]);
end;
end; { Case }
{ M x N tensor }
{ rows 4,6 }
begin
N1(inptr^[4*RowSize + 0], inptr^[6*RowSize + 0]);
N1(inptr^[4*RowSize + 1], inptr^[6*RowSize + 1]);
N1(inptr^[4*RowSize + 3], inptr^[6*RowSize + 3]);
N1(inptr^[4*RowSize + 7], inptr^[6*RowSize + 7]);
N2(inptr^[4*RowSize + 2], inptr^[6*RowSize + 2]);
N2(inptr^[4*RowSize + 5], inptr^[6*RowSize + 5]);
{ N3 }
{ two inverse matrices => same as FDCT }
tmp0 := inptr^[4*RowSize + 4];
tmp3 := inptr^[6*RowSize + 6];
tmp12 := (tmp0 + tmp3) * 2;
z10 := tmp0 - tmp3;
tmp1 := inptr^[6*RowSize + 4];
tmp2 := inptr^[4*RowSize + 6];
tmp13 :=-(tmp1 - tmp2)*2;
z11 := tmp1 + tmp2;
tmp0 := Multiply(z10 + z11, FP_I_C4_2);
tmp1 := Multiply(z10 - z11, FP_I_C4_2);
inptr^[4*RowSize + 4] := tmp12 + tmp0;
inptr^[6*RowSize + 4] := tmp1 + tmp13;
inptr^[4*RowSize + 6] := tmp1 - tmp13;
inptr^[6*RowSize + 6] := tmp12 - tmp0;
end;
{ R2 x R2 }
for row := 0 to 7 do
BEGIN
{ Odd part }
tmp7 := inptr^[row*RowSize + 7];
tmp6 := inptr^[row*RowSize + 6] - tmp7;
tmp5 := inptr^[row*RowSize + 5] - tmp6;
tmp4 :=-inptr^[row*RowSize + 4] - tmp5;
{ even part }
tmp0 := inptr^[row*RowSize + 0];
tmp1 := inptr^[row*RowSize + 1];
tmp10 := tmp0 + tmp1;
tmp11 := tmp0 - tmp1;
tmp2 := inptr^[row*RowSize + 2];
tmp13 := inptr^[row*RowSize + 3];
tmp12 := tmp2 - tmp13;
tmp0 := tmp10 + tmp13;
tmp3 := tmp10 - tmp13;
inptr^[row*RowSize + 0] := (tmp0 + tmp7);
inptr^[row*RowSize + 7] := (tmp0 - tmp7);
inptr^[row*RowSize + 3] := (tmp3 + tmp4);
inptr^[row*RowSize + 4] := (tmp3 - tmp4);
tmp1 := tmp11 + tmp12;
tmp2 := tmp11 - tmp12;
inptr^[row*RowSize + 1] := (tmp1 + tmp6);
inptr^[row*RowSize + 6] := (tmp1 - tmp6);
inptr^[row*RowSize + 2] := (tmp2 + tmp5);
inptr^[row*RowSize + 5] := (tmp2 - tmp5);
END;
for ctr := 0 to pred(DCTSIZE) do
BEGIN
outptr := JSAMPROW(@output_buf^[ctr]^[output_col]);
{ even part }
tmp0 := inptr^[0*RowSize + ctr];
tmp1 := inptr^[1*RowSize + ctr];
tmp2 := inptr^[2*RowSize + ctr];
tmp3 := inptr^[3*RowSize + ctr];
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 := inptr^[4*RowSize + ctr];
tmp5 := inptr^[5*RowSize + ctr];
tmp6 := inptr^[6*RowSize + ctr];
tmp7 := inptr^[7*RowSize + ctr];
tmp6 := tmp6 - tmp7;
tmp5 := tmp5 - tmp6;
tmp4 :=-tmp4 - tmp5;
outptr^[0*RowSize + ctr] := DeScale(tmp0 + tmp7);
outptr^[7*RowSize + ctr] := DeScale(tmp0 - tmp7);
outptr^[1*RowSize + ctr] := DeScale(tmp1 + tmp6);
outptr^[6*RowSize + ctr] := DeScale(tmp1 - tmp6);
outptr^[2*RowSize + ctr] := DeScale(tmp2 + tmp5);
outptr^[5*RowSize + ctr] := DeScale(tmp2 - tmp5);
outptr^[3*RowSize + ctr] := DeScale(tmp3 + tmp4);
outptr^[4*RowSize + ctr] := DeScale(tmp3 - tmp4);
{ 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];
END;
Inc(bbo);
Inc(inptr);
End;
End; {----------------------------------------}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -