📄 jpegdecode.pas
字号:
end
else
begin
lastbyte:=ReadByte;
dec(BitPos);
newbyte:=CurByte and MyAnd[BitPos];
tempcode:=BYTE(lastbyte shr 7);
CurByte:=newbyte;
end;
thiscode:=(thiscode shl 1)+tempcode;
inc(codelen);
if(codelen>16) then
begin
Result:=FUNC_FORMAT_ERROR;
Exit;
end;
end; //while
temp:=thiscode-huf_min_value[HufTabIndex,codelen-1]+code_pos_table[HufTabIndex,codelen-1];
hufexbyte:=BYTE(code_value_table[HufTabIndex,temp]);
rrun:=SmallInt(hufexbyte shr 4); //一个字节中,高四位是其前面的零的个数。
runsize:=hufexbyte and $0f; //后四位为后面字的尺寸
if(runsize=0) then
begin
vvalue:=0;
Result:=FUNC_OK;
Exit;
end;
tempsize:=runsize;
if(BitPos>=runsize) then
begin
BitPos:=BitPos-runsize;
valueex:=BYTE(CurByte shr BitPos);
CurByte:=CurByte and MyAnd[BitPos];
end
else
begin
valueex:=CurByte;
tempsize:=tempsize-BitPos;
while(tempsize>8) do
begin
lastbyte:=ReadByte;
valueex:=(valueex shl 8)+BYTE(lastbyte);
tempsize:=tempsize-8;
end; //while
lastbyte:=ReadByte;
BitPos:=BitPos-tempsize;
valueex:=(valueex shl tempsize)+(lastbyte shr BitPos);
CurByte:=lastbyte and MyAnd[BitPos];
end; //else
sign:=valueex shr (runsize-1);
if(sign<>0) then
vvalue:=valueex //解出的码值
else
begin
valueex:=valueex xor $ffff;
temp:=$ffff shl runsize;
vvalue:=-SmallInt(valueex xor temp);
end;
Result:=FUNC_OK;
end;
/////////////////////////////////////////////////////////////////////////////////////
//反量化MCU中的每个组件 入口 MCUBuffer 出口 QtZzMCUBuffer
/////////////////////////////////////////////////////////////////////////////////////
procedure IQtIZzMCUComponent(flag:SmallInt);
var
H,VV:SmallInt;
i,j:SmallInt;
pQtZzMCUBuffer,tempbuf1:Pint;
pMCUBuffer,tempbuf2:PSmallInt;
begin
case flag of
0:
begin
H:=SampRate_Y_H;
VV:=SampRate_Y_V;
pMCUBuffer:=PSmallInt(@MCUBuffer); //Huffman Decoded
pQtZzMCUBuffer:=Pint(@QtZzMCUBuffer);
end;
1:
begin
H:=SampRate_U_H;
VV:=SampRate_U_V;
pMCUBuffer:=PSmallInt(@MCUBuffer);
inc(pMCUBuffer,Y_in_MCU*64);
pQtZzMCUBuffer:=Pint(@QtZzMCUBuffer);
inc(pQtZzMCUBuffer,Y_in_MCU*64);
end;
2:
begin
H:=SampRate_V_H;
VV:=SampRate_V_V;
pMCUBuffer:=PSmallInt(@MCUBuffer);
inc(pMCUBuffer,(Y_in_MCU+U_in_MCU)*64);
pQtZzMCUBuffer:=Pint(@QtZzMCUBuffer);
inc(pQtZzMCUBuffer,(Y_in_MCU+U_in_MCU)*64);
end;
else
begin
H:=0;pQtZzMCUBuffer:=nil;pMCUBuffer:=nil;VV:=0;
end;
end;//case
for i:=0 to VV-1 do
for j:=0 to H-1 do
begin
tempbuf2:=pMCUBuffer;inc(tempbuf2,(i*H+j)*64);
tempbuf1:=pQtZzMCUBuffer;inc(tempbuf1,(i*H+j)*64);
IQtIZzBlock(tempbuf2,tempbuf1,flag); //8*8DU
end;
end;
//要量化的字
//////////////////////////////////////////////////////////////////////////////////////////
//反量化 8*8 DU
//////////////////////////////////////////////////////////////////////////////////////////
procedure IQtIZzBlock(s:PSmallInt;d:PInt;flag:SmallInt);
var
i,j:SmallInt;
tag:SmallInt;
pQt,temp1,temp3:PSmallInt;
buffer2 :MyInt;
temp2:Pint;
offset:SmallInt;
begin
case flag of
0: //亮度
begin
pQt:=YQtTable; //量化表地址
// ShowMessage(IntTostr(YQtTable^));
offset:=128;
end;
1: //红
begin
pQt:=UQtTable;
offset:=0;
end;
2: //蓝
begin
pQt:=VQtTable;
offset:=0;
end;
else
pQt:=nil;offset:=0;
end;
for i:=0 to 7 do
for j:=0 to 7 do
begin
tag:=Zig_Zag[i,j];
temp1:=s;inc(temp1,tag);temp3:=pQt;inc(temp3,tag);
buffer2[i,j]:=integer(temp1^*temp3^);
end;
Fast_IDCT(buffer2); //反DCT
for i:=0 to 7 do
for j:=0 to 7 do
begin
temp2:=d;inc(temp2,i*8+j);
temp2^:=buffer2[i,j]+offset;
end;
end;
///////////////////////////////////////////////////////////////////////////////
procedure Fast_IDCT(var block:MyInt);
begin
idctrow(block);
idctcol(block);
end;
///////////////////////////////////////////////////////////////////////////////
function ReadByte:BYTE;
var
i:BYTE;
begin
i:=Byte(lp^); // lp 为解码的起始位置
lp:=lp+1;
if(i=$ff) then
lp:=lp+1;
BitPos:=8;
CurByte:=i;
Result:=i;
end;
///////////////////////////////////////////////////////////////////////
procedure Initialize_Fast_IDCT;
var
i:SmallInt;
begin
for i:= -512 to 511 do
begin
if i<-256 then iclip[512+i]:=-256;
if i>255 then iclip[512+i]:=255;
if (i>=-256) and (i<=255) then iclip[512+i]:=i;
end;
end;
////////////////////////////////////////////////////////////////////////
procedure idctrow(var blk:MyInt);
var
i,x0, x1, x2, x3, x4, x5, x6, x7, x8:integer;
begin
//intcut
for i:=0 to 7 do
begin
x1:=blk[i,4] shl 11;
x2:=blk[i,6];
x3:=blk[i,2];
x4:=blk[i,1];
x5:=blk[i,7];
x6:=blk[i,5];
x7:=blk[i,3];
if ((x1 or x2 or x3 or x4 or x5 or x6 or x7) = 0) then
begin
blk[i,1]:=blk[i,0] shl 3;
blk[i,2]:=blk[i,0] shl 3;
blk[i,3]:=blk[i,0] shl 3;
blk[i,4]:=blk[i,0] shl 3;
blk[i,5]:=blk[i,0] shl 3;
blk[i,6]:=blk[i,0] shl 3;
blk[i,7]:=blk[i,0] shl 3;
blk[i,0]:=blk[i,0] shl 3;
Continue;
end;
x0 := (blk[i,0] shl 11) + 128; // for proper rounding in the fourth stage
//first stage
x8 := W7*(x4+x5);
x4 := x8 + (W1-W7)*x4;
x5 := x8 - (W1+W7)*x5;
x8 := W3*(x6+x7);
x6 := x8 - (W3-W5)*x6;
x7 := x8 - (W3+W5)*x7;
//second stage
x8 := x0 + x1;
x0 := x0-x1;
x1 := W6*(x3+x2);
x2 := x1 - (W2+W6)*x2;
x3 := x1 + (W2-W6)*x3;
x1 := x4 + x6;
x4 := x4-x6;
x6 := x5 + x7;
x5 := x5-x7;
//third stage
x7 := x8 + x3;
x8 := x8-x3;
x3 := x0 + x2;
x0 := x0-x2;
if (181*(x4+x5)+128)<0 then
x2:= ((181*(x4+x5)+128) shr 8) or ((not Integer(0)) shl (32-8))
else
x2 := (181*(x4+x5)+128) shr 8;
if (181*(x4-x5)+128)<0 then
x4:= ((181*(x4-x5)+128) shr 8) or ((not Integer(0)) shl (32-8))
else
x4 := (181*(x4-x5)+128) shr 8;
//fourth stage
if x7+x1<0 then
blk[i,0]:=((x7+x1) shr 8) or ((not Integer(0)) shl (32-8))
else
blk[i,0]:=(x7+x1) shr 8;
if x3+x2<0 then
blk[i,1]:=((x3+x2) shr 8) or ((not Integer(0)) shl (32-8))
else
blk[i,1]:=(x3+x2) shr 8;
if x0+x4<0 then
blk[i,2]:=((x0+x4) shr 8) or ((not Integer(0)) shl (32-8))
else
blk[i,2]:=(x0+x4) shr 8;
if x8+x6<0 then
blk[i,3]:=((x8+x6) shr 8) or ((not Integer(0)) shl (32-8))
else
blk[i,3]:=(x8+x6) shr 8;
if x8-x6<0 then
blk[i,4]:=((x8-x6) shr 8) or ((not Integer(0)) shl (32-8))
else
blk[i,4]:= (x8-x6) shr 8;
if x0-x4<0 then
blk[i,5]:=((x0-x4) shr 8) or ((not Integer(0)) shl (32-8))
else
blk[i,5]:= (x0-x4) shr 8;
if x3-x2<0 then
blk[i,6]:=((x3-x2) shr 8) or ((not Integer(0)) shl (32-8))
else
blk[i,6]:= (x3-x2) shr 8;
if x7-x1<0 then
blk[i,7]:=((x7-x1) shr 8) or ((not Integer(0)) shl (32-8))
else
blk[i,7]:= (x7-x1) shr 8;
end;
end;
//////////////////////////////////////////////////////////////////////////////
procedure idctcol(var blk:MyInt);
var
j,x0, x1, x2, x3, x4, x5, x6, x7, x8:integer;
Temp:Integer;
begin
//intcut
for j:=0 to 7 do
begin
x1:=blk[4,j] shl 8;
x2:=blk[6,j];
x3:=blk[2,j];
x4:=blk[1,j];
x5:=blk[7,j];
x6:=blk[5,j];
x7:=blk[3,j];
if ((x1 or x2 or x3 or x4 or x5 or x6 or x7)=0) then
begin
if (blk[0,j]+32)<0 then
Temp:=((blk[0,j]+32) shr 6) or (not (Integer(0)) shl (32-6))
else
Temp:=(blk[0,j]+32) shr 6;
blk[1,j]:=iclip[512+Temp];
blk[2,j]:=iclip[512+Temp];
blk[3,j]:=iclip[512+Temp];
blk[4,j]:=iclip[512+Temp];
blk[5,j]:=iclip[512+Temp];
blk[6,j]:=iclip[512+Temp];
blk[7,j]:=iclip[512+Temp];
blk[0,j]:=iclip[512+Temp];
Continue;
end;
x0 := (blk[0,j] shl 8) + 8192;
//first stage
x8 := W7*(x4+x5) + 4;
if (x8+(W1-W7)*x4)<0 then
x4:=((x8+(W1-W7)*x4) shr 3) or (not (Integer(0)) shl (32-3))
else
x4:= (x8+(W1-W7)*x4) shr 3;
if (x8-(W1+W7)*x5)<0 then
x5:=((x8-(W1+W7)*x5) shr 3) or (not (Integer(0)) shl (32-3))
else
x5 := (x8-(W1+W7)*x5) shr 3;
x8 := W3*(x6+x7) + 4;
if (x8-(W3-W5)*x6)<0 then
x6:=((x8-(W3-W5)*x6) shr 3) or (not (Integer(0)) shl (32-3))
else
x6:=(x8-(W3-W5)*x6) shr 3;
if (x8-(W3+W5)*x7)<0 then
x7:=((x8-(W3+W5)*x7) shr 3) or (not (Integer(0)) shl (32-3))
else
x7 := (x8-(W3+W5)*x7) shr 3;
//second stage
x8 := x0 + x1;
x0 := x0-x1;
x1 := W6*(x3+x2) + 4;
if (x1-(W2+W6)*x2)<0 then
x2:=((x1-(W2+W6)*x2) shr 3) or (not (Integer(0)) shl (32-3))
else
x2 := (x1-(W2+W6)*x2) shr 3;
if (x1+(W2-W6)*x3)<0 then
x3:=((x1+(W2-W6)*x3) shr 3) or (not (Integer(0)) shl (32-3))
else
x3 := (x1+(W2-W6)*x3) shr 3;
x1 := x4 + x6;
x4 := x4-x6;
x6 := x5 + x7;
x5 := x5-x7;
//third stage
x7 := x8 + x3;
x8 := x8-x3;
x3 := x0 + x2;
x0 := x0-x2;
if (181*(x4+x5)+128)<0 then
x2:=((181*(x4+x5)+128) shr 8) or (not (Integer(0)) shl (32-8))
else
x2 := (181*(x4+x5)+128) shr 8;
if (181*(x4-x5)+128)<0 then
x4:=((181*(x4-x5)+128) shr 8) or (not (Integer(0)) shl (32-8))
else
x4 := (181*(x4-x5)+128) shr 8;
//fourth stage
if x7+x1<0 then
Temp:=((x7+x1) shr 14) or (not (Integer(0)) shl (32-14))
else
Temp:=(x7+x1) shr 14;
blk[0,j]:=iclip[512+Temp];
if x3+x2<0 then
Temp:=((x3+x2) shr 14) or (not (Integer(0)) shl (32-14))
else
Temp:=(x3+x2) shr 14;
blk[1,j]:=iclip[512+Temp];
if x0+x4<0 then
Temp:=((x0+x4) shr 14) or (not (Integer(0)) shl (32-14))
else
Temp:=(x0+x4) shr 14;
blk[2,j]:=iclip[512+Temp];
if x8+x6<0 then
Temp:=((x8+x6) shr 14) or (not (Integer(0)) shl (32-14))
else
Temp:=(x8+x6) shr 14;
blk[3,j]:=iclip[512+Temp];
if x8-x6<0 then
Temp:=((x8-x6) shr 14) or (not (Integer(0)) shl (32-14))
else
Temp:=(x8-x6) shr 14;
blk[4,j]:=iclip[512+Temp];
if x0-x4<0 then
Temp:=((x0-x4) shr 14) or (not (Integer(0)) shl (32-14))
else
Temp:=(x0-x4) shr 14;
blk[5,j]:=iclip[512+Temp];
if x3-x2<0 then
Temp:=((x3-x2) shr 14) or (not (Integer(0)) shl (32-14))
else
Temp:=(x3-x2) shr 14;
blk[6,j]:=iclip[512+Temp];
if x7-x1<0 then
Temp:=((x7-x1) shr 14) or (not (Integer(0)) shl (32-14))
else
Temp:=(x7-x1) shr 14;
blk[7,j]:=iclip[512+Temp];
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -