Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
JpegDecode.pas
Package: JPEG解码源码.rar [view]
Upload User: lvs5012005
Upload Date: 2007-03-06
Package Size: 11k
Code Size: 40k
Category:
Graph program
Development Platform:
Delphi
- //------------------------------------------------------------------//
- // Copyright (c) 2001-2003, 智能认知工作室.
- // All rights reserved.
- //
- // 文件名称: JpegDecode.pas
- // 文件标识:
- //
- // 摘 要: JPEG图片的解码程序
- //
- // 当前版本: 4.0
- // 作 者: Rain(wangzp@try2it.com)
- // 网 站: http://www.try2it.com
- // 完成日期: 2001年4月20日
- //
- // 取代版本: 3.0
- //------------------------------------------------------------------//
- unit JpegDecode;
- interface
- uses Windows,SysUtils,Classes,WinTypes;
- const
- FUNC_OK= 0;
- FUNC_MEMORY_ERROR = 1;
- FUNC_FILE_ERROR = 2 ;
- FUNC_FORMAT_ERROR = 3;
- M_SOF0 = $c0;
- M_DHT = $c4;
- M_EOI = $d9;
- M_SOS = $da;
- M_DQT = $db;
- M_DRI = $dd;
- M_APP0 = $e0;
- W1 = 2841; // 2048*sqrt(2)*cos(1*pi/16)
- W2 = 2676; // 2048*sqrt(2)*cos(2*pi/16)
- W3 = 2408; // 2048*sqrt(2)*cos(3*pi/16)
- W5 = 1609; // 2048*sqrt(2)*cos(5*pi/16)
- W6 = 1108; // 2048*sqrt(2)*cos(6*pi/16)
- W7 = 565; // 2048*sqrt(2)*cos(7*pi/16)
- Zig_Zag:array[0..7,0..7] of integer =
- ((0,1,5,6,14,15,27,28),
- (2,4,7,13,16,26,29,42),
- (3,8,12,17,25,30,41,43),
- (9,11,18,24,31,40,44,53),
- (10,19,23,32,39,45,52,54),
- (20,22,33,38,46,51,55,60),
- (21,34,37,47,50,56,59,61),
- (35,36,48,49,57,58,62,63));
- type
- PShortInt = ^ShortInt;
- PSmallInt = ^SmallInt;
- PLongInt = ^LongInt;
- PByte = ^Byte;
- PInt = ^integer;
- MyInt = array[0..7,0..7] of integer;
- function LoadJpegFile(JpegFileName:string;var pImg:Pointer):Boolean;
- function InitTag:integer;
- procedure InitTable;
- function Decode:integer;
- function DecodeMCUBlock:integer;
- function HufBlock(dchufindex:Byte;achufindex:Byte):integer;
- function DecodeElement:integer;
- procedure IQtIZzMCUComponent(flag:SmallInt);
- procedure IQtIZzBlock(s:PSmallInt;d:PInt;flag:SmallInt);
- procedure GetYUV(flag:SmallInt);
- procedure StoreBuffer;
- function ReadByte:Byte;
- procedure Initialize_Fast_IDCT;
- procedure Fast_IDCT(var block:MyInt);
- procedure idctrow(var blk:MyInt);
- procedure idctcol(var blk:MyInt);
- implementation
- var
- //////////////////////////////////////////////////
- ImgWidth :DWORD =0;
- ImgHeight:DWORD = 0;
- lpImgData:PChar;
- bf:BITMAPFILEHEADER;
- bi:BITMAPINFOHEADER;
- //////////////////////////////////////////////////////////
- SampRate_Y_H,SampRate_Y_V:SmallInt;
- SampRate_U_H,SampRate_U_V:SmallInt;
- SampRate_V_H,SampRate_V_V:SmallInt;
- H_YtoU,V_YtoU,H_YtoV,V_YtoV:SmallInt;
- Y_in_MCU,U_in_MCU,V_in_MCU:SmallInt;
- lpJpegBuf:PChar;
- lp,lpPtr:PChar;
- qt_table:array[0..2,0..63] of SmallInt;
- comp_num:SmallInt;
- comp_index:array[0..3] of BYTE;
- YDcIndex,YAcIndex,UVDcIndex,UVAcIndex:BYTE;
- HufTabIndex:BYTE;
- YQtTable,UQtTable,VQtTable:PSmallInt;
- MyAnd:array[0..8] of BYTE =(0,1,3,7,$0f,$1f,$3f,$7f,$ff);
- code_pos_table,code_len_table:array[0..3,0..15] of SmallInt;
- code_value_table:array[0..3,0..255] of Word;
- huf_max_value,huf_min_value:array [0..3,0..15] of Word;
- BitPos,CurByte:SmallInt;
- rrun,vvalue:SmallInt;
- MCUBuffer:array[0..10*64-1] of SmallInt;
- QtZzMCUBuffer:array[0..10*64-1] of integer;
- BlockBuffer:array[0..63] of SmallInt;
- ycoef,ucoef,vcoef:SmallInt;
- IntervalFlag:Boolean;
- interval:SmallInt=0;
- Y,U,V:array[0..4*64-1] of integer;
- sizei,sizej:DWORD;
- restart:SmallInt;
- iclip:array[0..1023] of longint;
- LineBytes,NumColors:DWORD;
- ////////////////////////////////////////////////////////////////
- function LoadJpegFile (JpegFileName:string;var pImg:Pointer):Boolean;
- var
- fjpg:TFileStream;
- ImgSize:DWORD;
- JpegBufSize:DWORD;
- funcret:integer;
- lpImgDataTemp:PChar;
- begin
- fjpg:=TFileStream.Create(JpegFileName,fmOpenRead); //将Jpeg文件读入内存
- JpegBufSize:=fjpg.Size;
- GetMem(lpJpegBuf,JpegBufSize);
- fjpg.Read(lpJpegBuf^,JpegBufSize);
- fjpg.Free;
- InitTable;
- funcret:=InitTag;
- if(funcret<>FUNC_OK) then //初始化表头不成功
- begin
- FreeMem(lpJpegBuf,JpegBufSize);
- Result:=False;
- Exit;
- end;
- bi.biSize:=sizeof(BITMAPINFOHEADER); //定义BMP头
- bi.biWidth:=ImgWidth;
- bi.biHeight:=ImgHeight;
- bi.biPlanes:=1;
- bi.biBitCount:=24;
- bi.biClrUsed:=0;
- bi.biClrImportant:=0;
- bi.biCompression:=BI_RGB;
- NumColors:=0;
- LineBytes:=DWORD((bi.biWidth*bi.biBitCount+31) div 32 * 4);
- ImgSize:=LineBytes*DWORD(bi.biHeight); //变化后的图象空间
- bf.bfType:=$4d42; //'BM'
- bf.bfSize:=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
- NumColors*sizeof(RGBQUAD)+ImgSize;
- bf.bfOffBits:=DWORD(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
- GetMem(lpImgData,bf.bfSize); //分配变换后的存储空间
- lpImgDataTemp:=lpImgData;
- CopyMemory(lpImgDataTemp,@bf,sizeof(BITMAPFILEHEADER));
- lpImgDataTemp:=lpImgDataTemp+sizeof(BITMAPFILEHEADER);
- CopyMemory(lpImgDataTemp,@bi,sizeof(BITMAPINFOHEADER));
- lpPtr:=lpImgData+bf.bfOffBits; //实际图象数据位置
- if((SampRate_Y_H=0) or (SampRate_Y_V=0)) then
- begin
- FreeMem(lpJpegBuf);
- FreeMem(lpImgData);
- Result:=False;
- Exit;
- end;
- funcret:=Decode;
- if(funcret=FUNC_OK) then //解码成功
- begin
- Result:=True;
- pImg:=lpImgData;
- FreeMem(lpJpegBuf);
- Exit;
- end
- else
- begin
- FreeMem(lpImgData);
- FreeMem(lpJpegBuf);
- Result:=False;Exit;
- end;
- end;
- ////////////////////////////////////////////////////////////////////////////////
- function InitTag:integer;
- var
- finish:Boolean;
- id:Byte;
- llength:SmallInt;
- i,j,k:SmallInt;
- huftab1,huftab2:SmallInt;
- huftabindex:SmallInt;
- hf_table_index:BYTE;
- qt_table_index:BYTE;
- comnum:BYTE;
- lptemp:PChar;
- ccount:SmallInt;
- begin
- finish:=False;
- lp:=lpJpegBuf+2;//跳过两个字节SOI(0xFF,0xD8 Start of Image)
- while ( not finish) do
- begin
- id:=Byte((lp+1)^); //取出低位字节(高位在前,低位在后)
- lp:=lp+2; //跳过取出的字节
- case id of
- M_APP0: //JFIF APP0 segment marker (0xE0)
- begin
- llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));//MAKEWORD 转换Motorlora 与 intel 数据格式
- lp:=lp+llength;//Skip JFIF segment marker
- end;
- M_DQT: //定义量化表(0xFF,0xDB)
- begin
- llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));//(量化表长度)
- qt_table_index:=(Byte((lp+2)^) and $0f);//量化表信息bit 0..3: QT 号(0..3, 否则错误)
- //bit 4..7: QT 精度, 0 = 8 bit, 否则 16 bit
- lptemp:=lp+3; //n 字节的 QT, n = 64*(精度+1)
- if(llength<80) then //精度为 8 bit
- begin
- for i:=0 to 63 do
- begin
- qt_table[qt_table_index,i]:=SmallInt(lptemp^);
- inc(lptemp);
- end;
- end
- else //精度为 16 bit
- begin
- for i:=0 to 63 do
- begin
- qt_table[qt_table_index,i]:=SmallInt(lptemp^);
- inc(lptemp);
- end;
- qt_table_index:=Byte(lptemp^) and $0f;
- inc(lptemp);
- for i:=0 to 63 do
- begin
- qt_table[qt_table_index,i]:=SmallInt(lptemp^);
- inc(lptemp);
- end;
- end;
- lp:=lp+llength; //跳过量化表
- end;
- M_SOF0: //帧开始 (baseline JPEG 0xFF,0xC0)
- begin
- llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^)); //长度 (高字节, 低字节), 8+components*3
- ImgHeight:=MAKEWORD(Byte((lp+4)^),Byte((lp+3)^));//图片高度 (高字节, 低字节), 如果不支持 DNL 就必须 >0
- ImgWidth:=MAKEWORD(Byte((lp+6)^),Byte((lp+5)^)); //图片宽度 (高字节, 低字节), 如果不支持 DNL 就必须 >0
- comp_num:=Byte((lp+7)^); //components 数量(1 byte), 灰度图是 1, YCbCr/YIQ 彩色图是 3, CMYK 彩色图是 4
- if((comp_num<>1) and (comp_num<>3)) then
- begin
- Result:=FUNC_FORMAT_ERROR;
- Exit;
- end;
- if(comp_num = 3) then //YCbCr/YIQ 彩色图
- begin
- comp_index[0]:=Byte((lp+8)^); //component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q)
- SampRate_Y_H:=Byte((lp+9)^) shr 4; //水平采样系数
- SampRate_Y_V:=Byte((lp+9)^) and $0f; //水平采样系数
- YQtTable:=PSmallInt(@qt_table[Byte((lp+10)^)]); //通过量化表号取得量化表地址
- /// ShowMessage(IntToStr(YQtTable^));
- comp_index[1]:=Byte((lp+11)^); //component id
- SampRate_U_H:=Byte((lp+12)^) shr 4; //水平采样系数
- SampRate_U_V:=Byte((lp+12)^) and $0f; //水平采样系数
- UQtTable:=PSmallInt(@qt_table[Byte((lp+13)^)]); //通过量化表号取得量化表地址
- comp_index[2]:=Byte((lp+14)^); //component id
- SampRate_V_H:=Byte((lp+15)^) shr 4; //水平采样系数
- SampRate_V_V:=Byte((lp+15)^) and $0f; //水平采样系数
- VQtTable:=PSmallInt(@qt_table[Byte((lp+16)^)]); //通过量化表号取得量化表地址
- end
- else //灰度图
- begin
- comp_index[0]:=Byte((lp+8)^);
- SampRate_Y_H:=Byte((lp+9)^) shr 4;
- SampRate_Y_V:=Byte((lp+9)^) and $0f;
- YQtTable:=PSmallInt(@qt_table[Byte((lp+10)^)]); //灰度图的量化表都一样
- comp_index[1]:=Byte((lp+8)^);
- SampRate_U_H:=1;
- SampRate_U_V:=1;
- UQtTable:=PSmallInt(@qt_table[Byte((lp+10)^)]);
- comp_index[2]:=Byte((lp+8)^);
- SampRate_V_H:=1;
- SampRate_V_V:=1;
- VQtTable:=PSmallInt(@qt_table[Byte((lp+10)^)]);
- end;
- lp:=lp+llength;
- end;
- M_DHT: //定义 Huffman Table(0xFF,0xC4)
- begin
- llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^)); //长度 (高字节, 低字节)
- if (llength< $d0) then // Huffman Table信息 (1 byte)
- begin
- huftab1:=SmallInt(Byte((lp+2)^) shr 4); //huftab1=0,1(HT 类型,0 = DC 1 = AC)
- huftab2:=SmallInt(Byte((lp+2)^) and $0f); //huftab2=0,1(HT 号 ,0 = Y 1 = UV)
- huftabindex:=huftab1*2+huftab2; //0 = YDC 1 = UVDC 2 = YAC 3 = UVAC
- lptemp:=lp+3;
- for i:=0 to 15 do //16 bytes: 长度是 1..16 代码的符号数
- begin
- code_len_table[huftabindex,i]:=SmallInt(lptemp^);//码长为
- inc(lptemp); //i的码字个数
- end;
- j:=0;
- for i:=0 to 15 do //得出HT的所有码字的对应值
- begin
- if(code_len_table[huftabindex,i] <> 0) then
- begin
- k:=0;
- while(k<code_len_table[huftabindex,i]) do
- begin
- code_value_table[huftabindex,k+j]:=SmallInt(lptemp^);
- lptemp:=lptemp+1;
- k:=k+1;
- end;
- j:=j+k;
- end;
- end;
- i:=0;
- while (code_len_table[huftabindex,i]=0) do //去掉代码的符号数为零
- i:=i+1;
- for j:=0 to i-1 do
- begin
- huf_min_value[huftabindex,j]:=0; //码长为j的最小码字
- huf_max_value[huftabindex,j]:=0; //码长为j的最大码字
- end;
- huf_min_value[huftabindex,i]:=0;
- huf_max_value[huftabindex,i]:=code_len_table[huftabindex,i]-1;
- for j:=i+1 to 15 do
- begin //码长为j的最小码字与最大码字
- huf_min_value[huftabindex,j]:=(huf_max_value[huftabindex,j-1]+1) shl 1;
- huf_max_value[huftabindex,j]:=huf_min_value[huftabindex,j]+code_len_table[huftabindex,j]-1;
- end;
- code_pos_table[huftabindex,0]:=0; //码起始位置
- for j:=1 to 15 do
- code_pos_table[huftabindex,j]:=code_len_table[huftabindex,j-1]+code_pos_table[huftabindex,j-1];
- lp:=lp+llength;
- end //if
- else
- begin
- hf_table_index:=Byte((lp+2)^);
- lp:=lp+2;
- while (hf_table_index<> $ff) do
- begin
- huftab1:=SmallInt(hf_table_index shr 4); //huftab1=0,1
- huftab2:=SmallInt(hf_table_index and $0f); //huftab2=0,1
- huftabindex:=huftab1*2+huftab2;
- lptemp:=lp;inc(lptemp);
- ccount:=0;
- for i:=0 to 15 do
- begin
- code_len_table[huftabindex,i]:=SmallInt(lptemp^);
- inc(lptemp);
- ccount:=ccount+code_len_table[huftabindex,i];
- end;
- ccount:=ccount+17;
- j:=0;
- for i:=0 to 15 do
- if(code_len_table[huftabindex,i]<>0) then
- begin
- k:=0;
- while(k<code_len_table[huftabindex,i]) do
- begin
- code_value_table[huftabindex,k+j]:=SmallInt(lptemp^);
- inc(lptemp);
- inc(k);
- end;
- j:=j+k;
- end;
- i:=0;
- while (code_len_table[huftabindex,i]=0) do
- inc(i);
- for j:=0 to i-1 do
- begin
- huf_min_value[huftabindex,j]:=0;
- huf_max_value[huftabindex,j]:=0;
- end;
- huf_min_value[huftabindex,i]:=0;
- huf_max_value[huftabindex,i]:=code_len_table[huftabindex,i]-1;
- for j:=i+1 to 15 do
- begin
- huf_min_value[huftabindex,j]:=(huf_max_value[huftabindex,j-1]+1) shl 1;
- huf_max_value[huftabindex,j]:=huf_min_value[huftabindex,j]+code_len_table[huftabindex,j]-1;
- end;
- code_pos_table[huftabindex,0]:=0;
- for j:=1 to 15 do
- code_pos_table[huftabindex,j]:=code_len_table[huftabindex,j-1]+code_pos_table[huftabindex,j-1];
- lp:=lp+ccount;
- hf_table_index:=Byte(lp^);
- end; //while
- end; //else
- end;
- M_DRI: //定义重新开始间隔, 细节附后
- begin
- llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));
- restart:=MAKEWORD(Byte((lp+3)^),Byte((lp+2)^));
- lp:=lp+llength;
- end;
- M_SOS: //扫描行开始0xff, 0xda (SOS)
- begin
- llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));//长度 (高字节, 低字节),
- comnum:=Byte((lp+2)^); //扫描行内组件的数量 (1 byte), 必须 >:= 1 , <:=4 (否则是错的) 通常是 3
- if(comnum<>comp_num) then //必须是 6+2*(扫描行内组件的数量)
- begin
- Result:=FUNC_FORMAT_ERROR;
- Exit;
- end;
- lptemp:=lp+3;
- for i:=0 to comp_num-1 do
- begin //每组件的信息
- if(Byte(lptemp^)=comp_index[0]) then
- begin //1 byte :Component id
- YDcIndex:=Byte((lptemp+1)^) shr 4; //Y 使用的 Huffman 表
- YAcIndex:=(Byte((lptemp+1)^) and $0f) +2;
- end
- else
- begin
- UVDcIndex:=Byte((lptemp+1)^) shr 4; //U,V
- UVAcIndex:=(Byte((lptemp+1)^) and $0f) +2;
- end;
- lptemp:=lptemp+2;
- end; // for
- lp:=lp+llength;
- finish:=TRUE;
- end;
- M_EOI: //图片结束
- begin
- Result:=FUNC_FORMAT_ERROR;
- Exit;
- end;
- else
- begin
- if ((id and $f0)<>$d0) then
- begin
- llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));
- lp:=lp+llength;
- end
- else lp:=lp+2;
- end;
- end;
- end; //while
- Result:=FUNC_OK;
- end;
- /////////////////////////////////////////////////////////////////
- procedure InitTable;
- var
- i,j:SmallInt;
- begin
- sizei:=0;
- sizej:=0;
- ImgWidth:=0;
- ImgHeight:=0;
- rrun:=0;
- vvalue:=0;
- BitPos:=0;
- CurByte:=0;
- IntervalFlag:=FALSE;
- restart:=0;
- for i:=0 to 2 do
- for j:=0 to 63 do
- qt_table[i,j]:=0; //量化表
- comp_num:=0;
- HufTabIndex:=0;
- for i:=0 to 2 do
- comp_index[i]:=0;
- for i:=0 to 3 do
- for j:=0 to 15 do
- begin
- code_len_table[i,j]:=0;
- code_pos_table[i,j]:=0;
- huf_max_value[i,j]:=0;
- huf_min_value[i,j]:=0;
- end;
- for i:=0 to 3 do
- for j:=0 to 255 do
- code_value_table[i,j]:=0;
- for i:=0 to 10*64-1 do
- begin
- MCUBuffer[i]:=0;
- QtZzMCUBuffer[i]:=0;
- end;
- for i:=0 to 63 do
- begin
- Y[i]:=0;
- U[i]:=0;
- V[i]:=0;
- BlockBuffer[i]:=0;
- end;
- ycoef:=0;ucoef:=0;vcoef:=0;
- end;
- /////////////////////////////////////////////////////////////////////////
- //调用顺序: Initialize_Fast_IDCT() :初始化
- // DecodeMCUBlock() Huffman Decode
- // IQtIZzMCUComponent() 反量化、反DCT
- // GetYUV() Get Y U V
- // StoreBuffer() YUV to RGB
- /////////////////////////////////////////////////////////////////////////
- function Decode:integer;
- var
- funcret:integer;
- begin
- Y_in_MCU:=SampRate_Y_H*SampRate_Y_V; //YDU YDU YDU YDU
- U_in_MCU:=SampRate_U_H*SampRate_U_V; //cRDU
- V_in_MCU:=SampRate_V_H*SampRate_V_V; //cBDU
- H_YtoU:=SampRate_Y_H div SampRate_U_H;
- V_YtoU:=SampRate_Y_V div SampRate_U_V;
- H_YtoV:=SampRate_Y_H div SampRate_V_H;
- V_YtoV:=SampRate_Y_V div SampRate_V_V;
- Initialize_Fast_IDCT;
- funcret:=DecodeMCUBlock;
- while(funcret=FUNC_OK) do
- begin //After Call DecodeMCUBUBlock()
- inc(interval); //The Digital has been Huffman Decoded and
- if((restart<>0) and ((interval mod restart)=0)) then //be stored in MCUBuffer(YDU,YDU,YDU,YDU
- IntervalFlag:=TRUE // UDU,VDU) Every DU := 8*8
- else
- IntervalFlag:=FALSE;
- IQtIZzMCUComponent(0); //反量化 and IDCT The Data in QtZzMCUBuffer
- IQtIZzMCUComponent(1);
- IQtIZzMCUComponent(2);
- GetYUV(0); //得到Y cR cB
- GetYUV(1);
- GetYUV(2);
- StoreBuffer; //To RGB
- sizej:=sizej+DWORD(SampRate_Y_H*8);
- if(sizej>=ImgWidth) then
- begin
- sizej:=0;
- sizei:=sizei+DWORD(SampRate_Y_V*8);
- end;
- if ((sizej=0) and (sizei>=ImgHeight)) then
- break;
- funcret:=DecodeMCUBlock;
- end;//while
- Result:=funcret;
- end;
- ////////////////////////////////////////////////////////////////////////////////
- // 入口 QtZzMCUBuffer 出口 Y[] U[] V[]
- ////////////////////////////////////////////////////////////////////////////////
- procedure GetYUV(flag:SmallInt);
- var
- H,VV:SmallInt;
- temp:Integer;
- i,j,k,hk:SmallInt;
- buf,tempbuf:Pint;
- pQtZzMCU:Pint;
- begin
- case flag of
- 0: //亮度分量
- begin
- H:=SampRate_Y_H;
- VV:=SampRate_Y_V;
- buf:=@Y;
- pQtZzMCU:=Pint(@QtZzMCUBuffer);
- end;
- 1: //红色分量
- begin
- H:=SampRate_U_H;
- VV:=SampRate_U_V;
- buf:=@U;
- pQtZzMCU:=Pint(@QtZzMCUBuffer);
- inc(pQtZzMCU,Y_in_MCU*64);
- end;
- 2: //蓝色分量
- begin
- H:=SampRate_V_H;
- VV:=SampRate_V_V;
- buf:=@V;
- pQtZzMCU:=Pint(@QtZzMCUBuffer);
- inc(pQtZzMCU,(Y_in_MCU+U_in_MCU)*64);
- end;
- else
- begin
- H:=0;VV:=0;buf:=nil;pQtZzMCU:=nil;
- end;
- end;//end case
- for i:=0 to VV-1 do
- for j:=0 to H-1 do
- for k:=0 to 7 do
- for hk:=0 to 7 do
- begin
- temp:=(i*8+k)*SampRate_Y_H*8+j*8+hk;
- tempbuf:=buf;
- inc(tempbuf,temp);
- tempbuf^:=Integer(pQtZzMCU^);
- inc(pQtZzMCU);
- end;
- end;
- ///////////////////////////////////////////////////////////////////////////////
- //将解出的字按RGB形式存储 lpbmp (BGR),(BGR) ......入口Y[] U[] V[] 出口lpPtr
- ///////////////////////////////////////////////////////////////////////////////
- procedure StoreBuffer;
- var
- i,j:SmallInt;
- lpbmp:PChar;
- R,G,B:Byte;
- yy,uu,vv,rr,gg,bb:integer;
- begin
- for i:=0 to SampRate_Y_V*8-1 do
- begin // sizei表示行 sizej 表示列
- if((sizei+DWORD(i))<ImgHeight) then
- begin
- lpbmp:=lpPtr+DWORD((ImgHeight-sizei-DWORD(i)-1)*LineBytes+sizej*3);
- for j:=0 to SampRate_Y_H*8-1 do
- begin
- if((sizej+DWORD(j))<ImgWidth) then
- begin
- yy:=Y[i*8*SampRate_Y_H+j];
- uu:=U[(i div V_YtoU)*8*SampRate_Y_H+j div H_YtoU]; //内插
- vv:=V[(i div V_YtoV)*8*SampRate_Y_H+j div H_YtoV];
- rr:=((yy shl 8)+18*uu+367*vv);
- if rr<0 then
- rr:=(rr shr 8) or (not (Integer(0)) shl (32-8))
- else rr:=rr shr 8;
- gg:=((yy shl 8)-159*uu-220*vv);
- if gg<0 then
- gg:=(gg shr 8) or (not (integer(0)) shl (32-8))
- else gg:=gg shr 8;
- bb:=((yy shl 8)+411*uu-29*vv);
- if bb<0 then
- bb:=(bb shr 8) or (not (Integer(0)) shl (32-8))
- else bb:=bb shr 8;
- R:=Byte(rr);
- G:=Byte(gg);
- B:=Byte(bb);
- if ((rr and $ffffff00) <>0) then
- if (rr>255) then R:=255
- else if (rr<0) then R:=0;
- if (gg and $ffffff00 <>0) then
- if (gg>255) then G:=255
- else if (gg<0) then G:=0;
- if (bb and $ffffff00 <>0) then
- if (bb>255) then B:=255
- else if (bb<0) then B:=0;
- lpbmp^:=Char(B);
- inc(lpbmp);
- lpbmp^:=Char(G);
- inc(lpbmp);
- lpbmp^:=Char(R);
- inc(lpbmp);
- end
- else break;
- end;
- end
- else break;
- end;
- end;
- ///////////////////////////////////////////////////////////////////////////////
- //Huffman Decode MCU 出口 MCUBuffer 入口Blockbuffer[ ]
- ///////////////////////////////////////////////////////////////////////////////
- function DecodeMCUBlock:integer;
- var
- lpMCUBuffer:PSmallInt;
- i,j:SmallInt;
- funcret:integer;
- begin
- if (IntervalFlag) then
- begin
- inc(lp,2);
- ycoef:=0; //差值复位
- ucoef:=0;
- vcoef:=0;
- BitPos:=0;
- CurByte:=0;
- end;
- case comp_num of
- //comp_num 指图的类型(彩色图、灰度图)
- 3: //彩色图
- begin
- lpMCUBuffer:=@MCUBuffer;
- for i:=0 to SampRate_Y_H*SampRate_Y_V-1 do //Y
- begin
- funcret:=HufBlock(YDcIndex,YAcIndex); //解码4 * (8*8)
- if (funcret<>FUNC_OK) then
- begin
- Result:=funcret;
- Exit;
- end;
- BlockBuffer[0]:=BlockBuffer[0]+ycoef; //直流分量是差值,所以要累加。
- ycoef:=BlockBuffer[0];
- for j:=0 to 63 do
- begin
- lpMCUBuffer^:=BlockBuffer[j];
- inc(lpMCUBuffer);
- end;
- end;
- for i:=0 to SampRate_U_H*SampRate_U_V-1 do //U
- begin
- funcret:=HufBlock(UVDcIndex,UVAcIndex);
- if (funcret<>FUNC_OK) then
- begin
- Result:=funcret;
- Exit;
- end;
- BlockBuffer[0]:=BlockBuffer[0]+ucoef;
- ucoef:=BlockBuffer[0];
- for j:=0 to 63 do
- begin
- lpMCUBuffer^:=BlockBuffer[j];
- inc(lpMCUBuffer);
- end;
- end;
- for i:=0 to SampRate_V_H*SampRate_V_V-1 do //V
- begin
- funcret:=HufBlock(UVDcIndex,UVAcIndex);
- if (funcret<>FUNC_OK) then
- begin
- Result:=funcret;
- Exit;
- end;
- BlockBuffer[0]:=BlockBuffer[0]+vcoef;
- vcoef:=BlockBuffer[0];
- for j:=0 to 63 do
- begin
- lpMCUBuffer^:=BlockBuffer[j];
- inc(lpMCUBuffer);
- end;
- end;
- end;
- 1: //Gray Picture
- begin
- lpMCUBuffer:=@MCUBuffer;
- funcret:=HufBlock(YDcIndex,YAcIndex);
- if (funcret<>FUNC_OK) then
- begin
- Result:=funcret;
- Exit;
- end;
- BlockBuffer[0]:=BlockBuffer[0]+ycoef;
- ycoef:=BlockBuffer[0];
- for j:=0 to 63 do
- begin
- lpMCUBuffer^:=BlockBuffer[j];
- inc(lpMCUBuffer);
- end;
- for i:=0 to 127 do
- begin
- lpMCUBuffer^:=0;
- inc(lpMCUBuffer);
- end;
- end;
- else
- begin
- Result:=FUNC_FORMAT_ERROR;
- Exit;
- end;
- end;//case
- Result:=FUNC_OK;
- end;
- //////////////////////////////////////////////////////////////////
- //Huffman Decode (8*8) DU 出口 Blockbuffer[ ] 入口 vvalue
- //////////////////////////////////////////////////////////////////
- function HufBlock(dchufindex:BYTE;achufindex:BYTE):integer;
- var
- count:SmallInt;
- i:SmallInt;
- funcret:integer;
- begin
- count:=0;
- //dc
- HufTabIndex:=dchufindex;
- funcret:=DecodeElement; //Read Byte Dc
- if(funcret<>FUNC_OK) then
- begin
- result:=funcret;
- Exit;
- end;
- BlockBuffer[count]:=vvalue;//解出的直流系数
- inc(count);
- //ac
- HufTabIndex:=achufindex;
- while (count<64) do
- begin //63 Bytes AC
- funcret:=DecodeElement;
- if(funcret<> FUNC_OK) then
- begin
- Result:= funcret;
- Exit;
- end;
- if ((rrun=0) and (vvalue=0)) then
- begin
- for i:=count to 63 do
- BlockBuffer[i]:=0;
- count:=64;
- end
- else
- begin
- for i:=0 to rrun-1 do //前面的零
- begin
- BlockBuffer[count]:=0;
- inc(count);
- end;
- BlockBuffer[count]:=vvalue;//解出的值
- inc(count);
- end;
- end;
- Result:=FUNC_OK;
- end;
- //////////////////////////////////////////////////////////////////////////////
- //Huffman 解码 每个元素 出口 vvalue 入口 读文件ReadByte
- //////////////////////////////////////////////////////////////////////////////
- function DecodeElement:integer;
- var
- thiscode,tempcode:integer;
- temp,valueex:Word;
- codelen:SmallInt;
- hufexbyte,runsize,tempsize,sign:BYTE;
- newbyte,lastbyte:BYTE;
- begin
- if(BitPos>=1) then //BitPos指示当前比特位置
- begin
- dec(BitPos);
- thiscode:=BYTE(CurByte shr BitPos); //取一个比特
- CurByte:=CurByte and MyAnd[BitPos]; //清除取走的比特位
- end
- else //取出的一个字节已用完
- begin //新取
- lastbyte:=ReadByte; //读出一个字节
- dec(BitPos); //and[]:=0x0,0x1,0x3,0x7,0xf,0x1f,0x2f,0x3f,0x4f
- newbyte:=CurByte and MyAnd[BitPos]; //
- thiscode:=lastbyte shr 7;
- CurByte:=newbyte;
- end;
- codelen:=1;
- //与Huffman表中的码字匹配,直自找到为止
- while ((thiscode<huf_min_value[HufTabIndex,codelen-1]) or
- (code_len_table[HufTabIndex,codelen-1]=0) or
- (thiscode>huf_max_value[HufTabIndex,codelen-1])) do
- begin
- if(BitPos>=1) then begin //取出的一个字节还有
- dec(BitPos);
- tempcode:=BYTE(CurByte shr BitPos);
- CurByte:=CurByte and MyAnd[BitPos];
- 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.