JpegDecode.pas
Upload User: lvs5012005
Upload Date: 2007-03-06
Package Size: 11k
Code Size: 40k
Category:

Graph program

Development Platform:

Delphi

  1. //------------------------------------------------------------------//
  2. // Copyright (c) 2001-2003, 智能认知工作室.
  3. // All rights reserved.
  4. //
  5. // 文件名称: JpegDecode.pas
  6. // 文件标识:
  7. //
  8. // 摘    要: JPEG图片的解码程序
  9. //
  10. // 当前版本: 4.0
  11. // 作    者: Rain(wangzp@try2it.com)
  12. // 网    站: http://www.try2it.com
  13. // 完成日期: 2001年4月20日
  14. //
  15. // 取代版本: 3.0
  16. //------------------------------------------------------------------//
  17. unit JpegDecode;
  18. interface
  19.  uses   Windows,SysUtils,Classes,WinTypes;
  20. const
  21.   FUNC_OK= 0;
  22.   FUNC_MEMORY_ERROR = 1;
  23.   FUNC_FILE_ERROR = 2 ;
  24.   FUNC_FORMAT_ERROR = 3;
  25.   M_SOF0 = $c0;
  26.   M_DHT = $c4;
  27.   M_EOI = $d9;
  28.   M_SOS = $da;
  29.   M_DQT = $db;
  30.   M_DRI = $dd;
  31.   M_APP0 = $e0;
  32.   W1 = 2841; // 2048*sqrt(2)*cos(1*pi/16)
  33.   W2 = 2676; // 2048*sqrt(2)*cos(2*pi/16)
  34.   W3 = 2408; // 2048*sqrt(2)*cos(3*pi/16)
  35.   W5 = 1609; // 2048*sqrt(2)*cos(5*pi/16)
  36.   W6 = 1108; // 2048*sqrt(2)*cos(6*pi/16)
  37.   W7 = 565;  // 2048*sqrt(2)*cos(7*pi/16)
  38.   Zig_Zag:array[0..7,0..7] of integer =
  39.           ((0,1,5,6,14,15,27,28),
  40.       (2,4,7,13,16,26,29,42),
  41.       (3,8,12,17,25,30,41,43),
  42.       (9,11,18,24,31,40,44,53),
  43.       (10,19,23,32,39,45,52,54),
  44.       (20,22,33,38,46,51,55,60),
  45.       (21,34,37,47,50,56,59,61),
  46.       (35,36,48,49,57,58,62,63));
  47. type
  48.       PShortInt = ^ShortInt;
  49.       PSmallInt = ^SmallInt;
  50.       PLongInt = ^LongInt;
  51.       PByte = ^Byte;
  52.       PInt = ^integer;
  53.       MyInt = array[0..7,0..7] of integer;
  54. function  LoadJpegFile(JpegFileName:string;var pImg:Pointer):Boolean;
  55. function  InitTag:integer;
  56. procedure InitTable;
  57. function  Decode:integer;
  58. function  DecodeMCUBlock:integer;
  59. function  HufBlock(dchufindex:Byte;achufindex:Byte):integer;
  60. function  DecodeElement:integer;
  61. procedure IQtIZzMCUComponent(flag:SmallInt);
  62. procedure IQtIZzBlock(s:PSmallInt;d:PInt;flag:SmallInt);
  63. procedure GetYUV(flag:SmallInt);
  64. procedure StoreBuffer;
  65. function  ReadByte:Byte;
  66. procedure Initialize_Fast_IDCT;
  67. procedure Fast_IDCT(var block:MyInt);
  68. procedure idctrow(var blk:MyInt);
  69. procedure idctcol(var blk:MyInt);
  70. implementation
  71. var
  72. //////////////////////////////////////////////////
  73.   ImgWidth :DWORD =0;
  74.   ImgHeight:DWORD = 0;
  75.   lpImgData:PChar;
  76.   bf:BITMAPFILEHEADER;
  77.   bi:BITMAPINFOHEADER;
  78. //////////////////////////////////////////////////////////
  79.   SampRate_Y_H,SampRate_Y_V:SmallInt;
  80.   SampRate_U_H,SampRate_U_V:SmallInt;
  81.   SampRate_V_H,SampRate_V_V:SmallInt;
  82.   H_YtoU,V_YtoU,H_YtoV,V_YtoV:SmallInt;
  83.   Y_in_MCU,U_in_MCU,V_in_MCU:SmallInt;
  84.   lpJpegBuf:PChar;
  85.   lp,lpPtr:PChar;
  86.   qt_table:array[0..2,0..63] of SmallInt;
  87.   comp_num:SmallInt;
  88.   comp_index:array[0..3] of BYTE;
  89.   YDcIndex,YAcIndex,UVDcIndex,UVAcIndex:BYTE;
  90.   HufTabIndex:BYTE;
  91.   YQtTable,UQtTable,VQtTable:PSmallInt;
  92.   MyAnd:array[0..8] of BYTE =(0,1,3,7,$0f,$1f,$3f,$7f,$ff);
  93.   code_pos_table,code_len_table:array[0..3,0..15] of SmallInt;
  94.   code_value_table:array[0..3,0..255] of Word;
  95.   huf_max_value,huf_min_value:array [0..3,0..15] of Word;
  96.   BitPos,CurByte:SmallInt;
  97.   rrun,vvalue:SmallInt;
  98.   MCUBuffer:array[0..10*64-1] of SmallInt;
  99.   QtZzMCUBuffer:array[0..10*64-1] of integer;
  100.   BlockBuffer:array[0..63] of SmallInt;
  101.   ycoef,ucoef,vcoef:SmallInt;
  102.   IntervalFlag:Boolean;
  103.   interval:SmallInt=0;
  104.   Y,U,V:array[0..4*64-1] of integer;
  105.   sizei,sizej:DWORD;
  106.   restart:SmallInt;
  107.   iclip:array[0..1023] of longint;
  108.   LineBytes,NumColors:DWORD;
  109. ////////////////////////////////////////////////////////////////
  110. function LoadJpegFile (JpegFileName:string;var pImg:Pointer):Boolean;
  111. var
  112.      fjpg:TFileStream;
  113.      ImgSize:DWORD;
  114.      JpegBufSize:DWORD;
  115.      funcret:integer;
  116.      lpImgDataTemp:PChar;
  117. begin
  118.         fjpg:=TFileStream.Create(JpegFileName,fmOpenRead); //将Jpeg文件读入内存
  119.         JpegBufSize:=fjpg.Size;
  120.         GetMem(lpJpegBuf,JpegBufSize);
  121.         fjpg.Read(lpJpegBuf^,JpegBufSize);
  122.         fjpg.Free;
  123. InitTable;
  124.         funcret:=InitTag;
  125. if(funcret<>FUNC_OK) then        //初始化表头不成功
  126.         begin
  127.           FreeMem(lpJpegBuf,JpegBufSize);
  128.           Result:=False;
  129.   Exit;
  130. end;
  131. bi.biSize:=sizeof(BITMAPINFOHEADER);  //定义BMP头
  132. bi.biWidth:=ImgWidth;
  133. bi.biHeight:=ImgHeight;
  134. bi.biPlanes:=1;
  135. bi.biBitCount:=24;
  136. bi.biClrUsed:=0;
  137. bi.biClrImportant:=0;
  138. bi.biCompression:=BI_RGB;
  139. NumColors:=0;
  140. LineBytes:=DWORD((bi.biWidth*bi.biBitCount+31) div 32 * 4);
  141. ImgSize:=LineBytes*DWORD(bi.biHeight); //变化后的图象空间
  142. bf.bfType:=$4d42;                     //'BM'
  143. bf.bfSize:=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
  144.                            NumColors*sizeof(RGBQUAD)+ImgSize;
  145. bf.bfOffBits:=DWORD(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
  146.         GetMem(lpImgData,bf.bfSize);  //分配变换后的存储空间
  147.         lpImgDataTemp:=lpImgData;
  148.         CopyMemory(lpImgDataTemp,@bf,sizeof(BITMAPFILEHEADER));
  149.         lpImgDataTemp:=lpImgDataTemp+sizeof(BITMAPFILEHEADER);
  150.         CopyMemory(lpImgDataTemp,@bi,sizeof(BITMAPINFOHEADER));
  151.         lpPtr:=lpImgData+bf.bfOffBits;              //实际图象数据位置
  152. if((SampRate_Y_H=0) or (SampRate_Y_V=0)) then
  153.         begin
  154.                 FreeMem(lpJpegBuf);
  155.                 FreeMem(lpImgData);
  156.                 Result:=False;
  157. Exit;
  158. end;
  159. funcret:=Decode;
  160. if(funcret=FUNC_OK) then        //解码成功
  161.         begin
  162.                 Result:=True;
  163.                 pImg:=lpImgData;
  164.                 FreeMem(lpJpegBuf);
  165.                 Exit;
  166. end
  167. else
  168.         begin
  169.                 FreeMem(lpImgData);
  170.                 FreeMem(lpJpegBuf);
  171.                 Result:=False;Exit;
  172. end;
  173. end;
  174. ////////////////////////////////////////////////////////////////////////////////
  175. function InitTag:integer;
  176. var
  177. finish:Boolean;
  178. id:Byte;
  179. llength:SmallInt;
  180.         i,j,k:SmallInt;
  181.         huftab1,huftab2:SmallInt;
  182.         huftabindex:SmallInt;
  183.         hf_table_index:BYTE;
  184.         qt_table_index:BYTE;
  185.         comnum:BYTE;
  186. lptemp:PChar;
  187.         ccount:SmallInt;
  188. begin
  189.         finish:=False;
  190.         lp:=lpJpegBuf+2;//跳过两个字节SOI(0xFF,0xD8 Start of Image)
  191. while ( not finish) do
  192.         begin
  193. id:=Byte((lp+1)^);  //取出低位字节(高位在前,低位在后)
  194. lp:=lp+2;       //跳过取出的字节
  195. case id  of
  196. M_APP0:   //JFIF APP0 segment marker (0xE0)
  197.                 begin
  198.                        llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));//MAKEWORD 转换Motorlora 与 intel 数据格式
  199.        lp:=lp+llength;//Skip JFIF segment marker
  200.                 end;
  201. M_DQT:   //定义量化表(0xFF,0xDB)
  202.                 begin
  203. llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));//(量化表长度)
  204. qt_table_index:=(Byte((lp+2)^) and $0f);//量化表信息bit 0..3: QT 号(0..3, 否则错误)
  205.                                           //bit 4..7: QT 精度, 0 = 8 bit, 否则 16 bit
  206.                         lptemp:=lp+3;                  //n 字节的 QT, n = 64*(精度+1)
  207. if(llength<80)  then               //精度为 8 bit
  208.                         begin
  209. for i:=0 to 63 do
  210.                                 begin
  211. qt_table[qt_table_index,i]:=SmallInt(lptemp^);
  212.                                         inc(lptemp);
  213.                                 end;
  214. end
  215. else                         //精度为 16 bit
  216.                         begin
  217. for i:=0 to 63 do
  218.                                 begin
  219.                                  qt_table[qt_table_index,i]:=SmallInt(lptemp^);
  220.                                         inc(lptemp);
  221.                                 end;
  222.                                 qt_table_index:=Byte(lptemp^) and $0f;
  223.                                 inc(lptemp);
  224.                     for i:=0 to 63 do
  225.                                 begin
  226.                qt_table[qt_table_index,i]:=SmallInt(lptemp^);
  227.                                         inc(lptemp);
  228.                                 end;
  229.                         end;
  230.    lp:=lp+llength; //跳过量化表
  231.                 end;
  232. M_SOF0:   //帧开始 (baseline JPEG 0xFF,0xC0)
  233.                 begin
  234.   llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));         //长度 (高字节, 低字节), 8+components*3
  235.   ImgHeight:=MAKEWORD(Byte((lp+4)^),Byte((lp+3)^));//图片高度 (高字节, 低字节), 如果不支持 DNL 就必须 >0
  236.   ImgWidth:=MAKEWORD(Byte((lp+6)^),Byte((lp+5)^)); //图片宽度 (高字节, 低字节), 如果不支持 DNL 就必须 >0
  237.                         comp_num:=Byte((lp+7)^);                   //components 数量(1 byte), 灰度图是 1, YCbCr/YIQ 彩色图是 3, CMYK 彩色图是 4
  238.                 if((comp_num<>1) and (comp_num<>3)) then
  239.                         begin
  240.    Result:=FUNC_FORMAT_ERROR;
  241.                                 Exit;
  242.                         end;
  243. if(comp_num = 3)  then                  //YCbCr/YIQ 彩色图
  244.                         begin
  245. comp_index[0]:=Byte((lp+8)^);          //component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q)
  246.    SampRate_Y_H:=Byte((lp+9)^) shr 4;      //水平采样系数
  247. SampRate_Y_V:=Byte((lp+9)^) and $0f;    //水平采样系数
  248.    YQtTable:=PSmallInt(@qt_table[Byte((lp+10)^)]); //通过量化表号取得量化表地址
  249.                               ///  ShowMessage(IntToStr(YQtTable^));
  250. comp_index[1]:=Byte((lp+11)^);         //component id
  251. SampRate_U_H:=Byte((lp+12)^) shr 4;     //水平采样系数
  252.    SampRate_U_V:=Byte((lp+12)^) and $0f;   //水平采样系数
  253.    UQtTable:=PSmallInt(@qt_table[Byte((lp+13)^)]);  //通过量化表号取得量化表地址
  254.    comp_index[2]:=Byte((lp+14)^);         //component id
  255.    SampRate_V_H:=Byte((lp+15)^) shr 4;     //水平采样系数
  256.    SampRate_V_V:=Byte((lp+15)^) and $0f;   //水平采样系数
  257. VQtTable:=PSmallInt(@qt_table[Byte((lp+16)^)]);   //通过量化表号取得量化表地址
  258.    end
  259. else                                       //灰度图
  260.                         begin
  261.    comp_index[0]:=Byte((lp+8)^);
  262. SampRate_Y_H:=Byte((lp+9)^) shr 4;
  263.    SampRate_Y_V:=Byte((lp+9)^) and $0f;
  264.    YQtTable:=PSmallInt(@qt_table[Byte((lp+10)^)]);  //灰度图的量化表都一样
  265. comp_index[1]:=Byte((lp+8)^);
  266.    SampRate_U_H:=1;
  267.    SampRate_U_V:=1;
  268.    UQtTable:=PSmallInt(@qt_table[Byte((lp+10)^)]);
  269. comp_index[2]:=Byte((lp+8)^);
  270. SampRate_V_H:=1;
  271.    SampRate_V_V:=1;
  272.    VQtTable:=PSmallInt(@qt_table[Byte((lp+10)^)]);
  273. end;
  274.    lp:=lp+llength;
  275.                 end;
  276. M_DHT:   //定义 Huffman Table(0xFF,0xC4)
  277.                 begin
  278. llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));       //长度 (高字节, 低字节)
  279. if (llength< $d0)    then               // Huffman Table信息 (1 byte)
  280.                         begin
  281. huftab1:=SmallInt(Byte((lp+2)^) shr 4);     //huftab1=0,1(HT 类型,0 = DC 1 = AC)
  282.   huftab2:=SmallInt(Byte((lp+2)^) and $0f);   //huftab2=0,1(HT 号  ,0 = Y  1 = UV)
  283. huftabindex:=huftab1*2+huftab2;           //0 = YDC 1 = UVDC 2 = YAC 3 = UVAC
  284.   lptemp:=lp+3;
  285. for i:=0 to 15 do                     //16 bytes: 长度是 1..16 代码的符号数
  286.                                 begin
  287. code_len_table[huftabindex,i]:=SmallInt(lptemp^);//码长为
  288.                                         inc(lptemp);                                //i的码字个数
  289.                                 end;
  290. j:=0;
  291. for i:=0 to 15 do             //得出HT的所有码字的对应值
  292.                                 begin
  293. if(code_len_table[huftabindex,i] <> 0)  then
  294.                                         begin
  295. k:=0;
  296. while(k<code_len_table[huftabindex,i]) do
  297.                                                 begin
  298. code_value_table[huftabindex,k+j]:=SmallInt(lptemp^);
  299.                                                         lptemp:=lptemp+1;
  300. k:=k+1;
  301. end;
  302. j:=j+k;
  303. end;
  304.                                 end;
  305. i:=0;
  306. while (code_len_table[huftabindex,i]=0) do //去掉代码的符号数为零
  307.   i:=i+1;
  308. for j:=0 to i-1 do
  309.                                 begin
  310. huf_min_value[huftabindex,j]:=0;            //码长为j的最小码字
  311. huf_max_value[huftabindex,j]:=0;            //码长为j的最大码字
  312. end;
  313. huf_min_value[huftabindex,i]:=0;
  314. huf_max_value[huftabindex,i]:=code_len_table[huftabindex,i]-1;
  315. for j:=i+1 to 15 do
  316.                                 begin                                              //码长为j的最小码字与最大码字
  317. huf_min_value[huftabindex,j]:=(huf_max_value[huftabindex,j-1]+1) shl 1;
  318. huf_max_value[huftabindex,j]:=huf_min_value[huftabindex,j]+code_len_table[huftabindex,j]-1;
  319. end;
  320. code_pos_table[huftabindex,0]:=0; //码起始位置
  321. for j:=1 to 15 do
  322.    code_pos_table[huftabindex,j]:=code_len_table[huftabindex,j-1]+code_pos_table[huftabindex,j-1];
  323.    lp:=lp+llength;
  324. end  //if
  325. else
  326.                         begin
  327.   hf_table_index:=Byte((lp+2)^);
  328. lp:=lp+2;
  329. while (hf_table_index<> $ff) do
  330.                                 begin
  331. huftab1:=SmallInt(hf_table_index shr 4);     //huftab1=0,1
  332.   huftab2:=SmallInt(hf_table_index and $0f);   //huftab2=0,1
  333. huftabindex:=huftab1*2+huftab2;
  334. lptemp:=lp;inc(lptemp);
  335. ccount:=0;
  336. for i:=0 to 15 do
  337.                                         begin
  338.                                          code_len_table[huftabindex,i]:=SmallInt(lptemp^);
  339.                                                 inc(lptemp);
  340. ccount:=ccount+code_len_table[huftabindex,i];
  341. end;
  342. ccount:=ccount+17;
  343. j:=0;
  344. for i:=0 to 15 do
  345. if(code_len_table[huftabindex,i]<>0)   then
  346.                                                 begin
  347. k:=0;
  348. while(k<code_len_table[huftabindex,i]) do
  349. begin
  350. code_value_table[huftabindex,k+j]:=SmallInt(lptemp^);
  351.                                                                 inc(lptemp);
  352. inc(k);
  353. end;
  354. j:=j+k;
  355. end;
  356. i:=0;
  357. while (code_len_table[huftabindex,i]=0) do
  358. inc(i);
  359. for j:=0 to i-1 do
  360.                                         begin
  361. huf_min_value[huftabindex,j]:=0;
  362. huf_max_value[huftabindex,j]:=0;
  363. end;
  364. huf_min_value[huftabindex,i]:=0;
  365. huf_max_value[huftabindex,i]:=code_len_table[huftabindex,i]-1;
  366. for j:=i+1 to 15 do
  367.                                         begin
  368. huf_min_value[huftabindex,j]:=(huf_max_value[huftabindex,j-1]+1) shl 1;
  369. huf_max_value[huftabindex,j]:=huf_min_value[huftabindex,j]+code_len_table[huftabindex,j]-1;
  370. end;
  371. code_pos_table[huftabindex,0]:=0;
  372. for j:=1 to 15 do
  373. code_pos_table[huftabindex,j]:=code_len_table[huftabindex,j-1]+code_pos_table[huftabindex,j-1];
  374. lp:=lp+ccount;
  375. hf_table_index:=Byte(lp^);
  376. end;  //while
  377. end;  //else
  378.                 end;
  379. M_DRI: //定义重新开始间隔, 细节附后
  380.                 begin
  381. llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));
  382. restart:=MAKEWORD(Byte((lp+3)^),Byte((lp+2)^));
  383. lp:=lp+llength;
  384.                 end;
  385. M_SOS: //扫描行开始0xff, 0xda (SOS)
  386.                 begin
  387. llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));//长度 (高字节, 低字节),
  388. comnum:=Byte((lp+2)^);               //扫描行内组件的数量 (1 byte), 必须 >:= 1 , <:=4 (否则是错的) 通常是 3
  389.         if(comnum<>comp_num)  then        //必须是 6+2*(扫描行内组件的数量)
  390.                         begin
  391.      Result:=FUNC_FORMAT_ERROR;
  392.                              Exit;
  393.                         end;
  394.                         lptemp:=lp+3;
  395. for i:=0 to comp_num-1 do
  396.                         begin                   //每组件的信息
  397. if(Byte(lptemp^)=comp_index[0]) then
  398.                                 begin  //1 byte :Component id
  399. YDcIndex:=Byte((lptemp+1)^) shr 4;   //Y 使用的 Huffman 表
  400. YAcIndex:=(Byte((lptemp+1)^) and $0f) +2;
  401. end
  402. else
  403.                                 begin
  404. UVDcIndex:=Byte((lptemp+1)^) shr 4;   //U,V
  405. UVAcIndex:=(Byte((lptemp+1)^) and $0f) +2;
  406. end;
  407.                                 lptemp:=lptemp+2;
  408. end;  // for
  409. lp:=lp+llength;
  410. finish:=TRUE;
  411.                 end;
  412. M_EOI:    //图片结束
  413.                 begin
  414. Result:=FUNC_FORMAT_ERROR;
  415. Exit;
  416. end;
  417.                 else
  418.                 begin
  419.   if ((id and $f0)<>$d0) then
  420.                         begin
  421. llength:=MAKEWORD(Byte((lp+1)^),Byte(lp^));
  422.   lp:=lp+llength;
  423. end
  424. else lp:=lp+2;
  425.    end;
  426.          end;
  427. end; //while
  428. Result:=FUNC_OK;
  429. end;
  430. /////////////////////////////////////////////////////////////////
  431. procedure InitTable;
  432. var
  433.       i,j:SmallInt;
  434. begin
  435. sizei:=0;
  436.         sizej:=0;
  437. ImgWidth:=0;
  438.         ImgHeight:=0;
  439. rrun:=0;
  440.         vvalue:=0;
  441. BitPos:=0;
  442. CurByte:=0;
  443. IntervalFlag:=FALSE;
  444. restart:=0;
  445. for i:=0 to 2 do
  446.             for j:=0 to 63 do
  447.   qt_table[i,j]:=0;           //量化表
  448. comp_num:=0;
  449. HufTabIndex:=0;
  450. for i:=0 to 2 do
  451. comp_index[i]:=0;
  452. for i:=0 to 3 do
  453.     for j:=0 to 15 do
  454.             begin
  455.      code_len_table[i,j]:=0;
  456.      code_pos_table[i,j]:=0;
  457.      huf_max_value[i,j]:=0;
  458.      huf_min_value[i,j]:=0;
  459.     end;
  460. for i:=0 to 3 do
  461.     for j:=0 to 255 do
  462.        code_value_table[i,j]:=0;
  463. for i:=0 to 10*64-1 do
  464.         begin
  465. MCUBuffer[i]:=0;
  466. QtZzMCUBuffer[i]:=0;
  467. end;
  468. for i:=0 to 63 do
  469.         begin
  470. Y[i]:=0;
  471. U[i]:=0;
  472. V[i]:=0;
  473. BlockBuffer[i]:=0;
  474. end;
  475. ycoef:=0;ucoef:=0;vcoef:=0;
  476. end;
  477. /////////////////////////////////////////////////////////////////////////
  478. //调用顺序: Initialize_Fast_IDCT() :初始化
  479. //          DecodeMCUBlock()       Huffman Decode
  480. //          IQtIZzMCUComponent()   反量化、反DCT
  481. //          GetYUV()               Get Y U V
  482. //          StoreBuffer()          YUV to RGB
  483. /////////////////////////////////////////////////////////////////////////
  484. function  Decode:integer;
  485. var
  486.      funcret:integer;
  487. begin
  488. Y_in_MCU:=SampRate_Y_H*SampRate_Y_V;     //YDU YDU YDU YDU
  489. U_in_MCU:=SampRate_U_H*SampRate_U_V;     //cRDU
  490. V_in_MCU:=SampRate_V_H*SampRate_V_V;     //cBDU
  491. H_YtoU:=SampRate_Y_H div SampRate_U_H;
  492. V_YtoU:=SampRate_Y_V div SampRate_U_V;
  493. H_YtoV:=SampRate_Y_H div SampRate_V_H;
  494. V_YtoV:=SampRate_Y_V div SampRate_V_V;
  495. Initialize_Fast_IDCT;
  496.         funcret:=DecodeMCUBlock;
  497. while(funcret=FUNC_OK) do
  498.         begin                                           //After Call DecodeMCUBUBlock()
  499. inc(interval);                             //The Digital has been Huffman Decoded and
  500. if((restart<>0) and ((interval mod restart)=0))  then //be stored in MCUBuffer(YDU,YDU,YDU,YDU
  501.  IntervalFlag:=TRUE                          // UDU,VDU) Every DU := 8*8
  502. else
  503. IntervalFlag:=FALSE;
  504. IQtIZzMCUComponent(0);   //反量化 and IDCT The Data in QtZzMCUBuffer
  505. IQtIZzMCUComponent(1);
  506. IQtIZzMCUComponent(2);
  507. GetYUV(0);                    //得到Y cR cB
  508. GetYUV(1);
  509. GetYUV(2);
  510. StoreBuffer;               //To RGB
  511. sizej:=sizej+DWORD(SampRate_Y_H*8);
  512. if(sizej>=ImgWidth) then
  513.                 begin
  514. sizej:=0;
  515. sizei:=sizei+DWORD(SampRate_Y_V*8);
  516. end;
  517. if ((sizej=0) and (sizei>=ImgHeight)) then
  518. break;
  519.                 funcret:=DecodeMCUBlock;
  520.         end;//while
  521. Result:=funcret;
  522. end;
  523. ////////////////////////////////////////////////////////////////////////////////
  524. // 入口 QtZzMCUBuffer 出口 Y[] U[] V[]
  525. ////////////////////////////////////////////////////////////////////////////////
  526. procedure  GetYUV(flag:SmallInt);
  527. var
  528.        H,VV:SmallInt;
  529.        temp:Integer;
  530.        i,j,k,hk:SmallInt;
  531.        buf,tempbuf:Pint;
  532.        pQtZzMCU:Pint;
  533. begin
  534.        case flag of
  535. 0:                             //亮度分量
  536.         begin
  537. H:=SampRate_Y_H;
  538. VV:=SampRate_Y_V;
  539. buf:=@Y;
  540. pQtZzMCU:=Pint(@QtZzMCUBuffer);
  541.         end;
  542.         1:                             //红色分量
  543.         begin
  544. H:=SampRate_U_H;
  545. VV:=SampRate_U_V;
  546. buf:=@U;
  547. pQtZzMCU:=Pint(@QtZzMCUBuffer);
  548.                 inc(pQtZzMCU,Y_in_MCU*64);
  549.         end;
  550.         2:                            //蓝色分量
  551.         begin
  552. H:=SampRate_V_H;
  553. VV:=SampRate_V_V;
  554. buf:=@V;
  555. pQtZzMCU:=Pint(@QtZzMCUBuffer);
  556.                 inc(pQtZzMCU,(Y_in_MCU+U_in_MCU)*64);
  557.         end;
  558.        else
  559.         begin
  560.            H:=0;VV:=0;buf:=nil;pQtZzMCU:=nil;
  561.         end;
  562.        end;//end case
  563.        for i:=0 to VV-1 do
  564.    for j:=0 to H-1 do
  565.        for k:=0 to 7 do
  566.     for hk:=0 to 7 do
  567.                     begin
  568.                         temp:=(i*8+k)*SampRate_Y_H*8+j*8+hk;
  569.                         tempbuf:=buf;
  570.                         inc(tempbuf,temp);
  571.                         tempbuf^:=Integer(pQtZzMCU^);
  572.                         inc(pQtZzMCU);
  573.                     end;
  574. end;
  575. ///////////////////////////////////////////////////////////////////////////////
  576. //将解出的字按RGB形式存储 lpbmp (BGR),(BGR) ......入口Y[] U[] V[] 出口lpPtr
  577. ///////////////////////////////////////////////////////////////////////////////
  578. procedure StoreBuffer;
  579. var
  580.  i,j:SmallInt;
  581.          lpbmp:PChar;
  582.  R,G,B:Byte;
  583.  yy,uu,vv,rr,gg,bb:integer;
  584. begin
  585. for i:=0 to SampRate_Y_V*8-1 do
  586.         begin                                  // sizei表示行 sizej 表示列
  587. if((sizei+DWORD(i))<ImgHeight) then
  588.                 begin
  589. lpbmp:=lpPtr+DWORD((ImgHeight-sizei-DWORD(i)-1)*LineBytes+sizej*3);
  590. for j:=0 to SampRate_Y_H*8-1 do
  591.                         begin
  592. if((sizej+DWORD(j))<ImgWidth) then
  593.                                 begin
  594. yy:=Y[i*8*SampRate_Y_H+j];
  595. uu:=U[(i div V_YtoU)*8*SampRate_Y_H+j div H_YtoU];  //内插
  596. vv:=V[(i div V_YtoV)*8*SampRate_Y_H+j div H_YtoV];
  597. rr:=((yy shl 8)+18*uu+367*vv);
  598.                                         if rr<0 then
  599.                                           rr:=(rr shr 8) or (not (Integer(0)) shl (32-8))
  600.                                         else rr:=rr shr 8;
  601. gg:=((yy shl 8)-159*uu-220*vv);
  602.                                         if gg<0 then
  603.                                           gg:=(gg shr 8) or (not (integer(0)) shl (32-8))
  604.                                         else gg:=gg shr 8;
  605. bb:=((yy shl 8)+411*uu-29*vv);
  606.                                         if bb<0 then
  607.                                           bb:=(bb shr 8) or (not (Integer(0)) shl (32-8))
  608.                                         else bb:=bb shr 8;
  609. R:=Byte(rr);
  610. G:=Byte(gg);
  611. B:=Byte(bb);
  612. if ((rr and $ffffff00) <>0) then
  613.                                              if (rr>255) then R:=255
  614.                                                     else if (rr<0) then R:=0;
  615. if (gg and $ffffff00 <>0) then
  616.                                              if (gg>255) then G:=255
  617.                                                     else if (gg<0) then G:=0;
  618. if (bb and $ffffff00 <>0) then
  619.                                              if (bb>255) then B:=255
  620.                                                     else if (bb<0) then B:=0;
  621. lpbmp^:=Char(B);
  622.                                         inc(lpbmp);
  623. lpbmp^:=Char(G);
  624.                                         inc(lpbmp);
  625. lpbmp^:=Char(R);
  626.                                         inc(lpbmp);
  627. end
  628. else  break;
  629. end;
  630. end
  631. else break;
  632. end;
  633. end;
  634. ///////////////////////////////////////////////////////////////////////////////
  635. //Huffman Decode   MCU 出口 MCUBuffer  入口Blockbuffer[  ]
  636. ///////////////////////////////////////////////////////////////////////////////
  637. function DecodeMCUBlock:integer;
  638. var
  639.  lpMCUBuffer:PSmallInt;
  640.  i,j:SmallInt;
  641.  funcret:integer;
  642. begin
  643. if (IntervalFlag) then
  644.         begin
  645. inc(lp,2);
  646. ycoef:=0;   //差值复位
  647.                 ucoef:=0;
  648.                 vcoef:=0;
  649. BitPos:=0;
  650. CurByte:=0;
  651. end;
  652. case comp_num of
  653.                                  //comp_num 指图的类型(彩色图、灰度图)
  654.   3:   //彩色图
  655.           begin
  656. lpMCUBuffer:=@MCUBuffer;
  657. for i:=0 to SampRate_Y_H*SampRate_Y_V-1 do  //Y
  658. begin
  659. funcret:=HufBlock(YDcIndex,YAcIndex);   //解码4 * (8*8)
  660. if (funcret<>FUNC_OK) then
  661.                         begin
  662. Result:=funcret;
  663.                                 Exit;
  664.                         end;
  665. BlockBuffer[0]:=BlockBuffer[0]+ycoef;   //直流分量是差值,所以要累加。
  666. ycoef:=BlockBuffer[0];
  667. for j:=0 to 63 do
  668.                         begin
  669. lpMCUBuffer^:=BlockBuffer[j];
  670.                                 inc(lpMCUBuffer);
  671.                         end;
  672. end;
  673. for i:=0 to SampRate_U_H*SampRate_U_V-1 do  //U
  674. begin
  675. funcret:=HufBlock(UVDcIndex,UVAcIndex);
  676. if (funcret<>FUNC_OK) then
  677.                         begin
  678. Result:=funcret;
  679.                                 Exit;
  680.                         end;
  681. BlockBuffer[0]:=BlockBuffer[0]+ucoef;
  682. ucoef:=BlockBuffer[0];
  683. for j:=0 to 63 do
  684.                         begin
  685. lpMCUBuffer^:=BlockBuffer[j];
  686.                                 inc(lpMCUBuffer);
  687.                         end;
  688. end;
  689. for i:=0 to SampRate_V_H*SampRate_V_V-1 do  //V
  690. begin
  691. funcret:=HufBlock(UVDcIndex,UVAcIndex);
  692. if (funcret<>FUNC_OK) then
  693.                         begin
  694. Result:=funcret;
  695.                                 Exit;
  696.                         end;
  697. BlockBuffer[0]:=BlockBuffer[0]+vcoef;
  698. vcoef:=BlockBuffer[0];
  699. for j:=0 to 63 do
  700.                         begin
  701. lpMCUBuffer^:=BlockBuffer[j];
  702.                                 inc(lpMCUBuffer);
  703.                         end;
  704. end;
  705.           end;
  706.   1:   //Gray Picture
  707.            begin
  708. lpMCUBuffer:=@MCUBuffer;
  709. funcret:=HufBlock(YDcIndex,YAcIndex);
  710. if (funcret<>FUNC_OK) then
  711.                 begin
  712. Result:=funcret;
  713.                         Exit;
  714.                 end;
  715. BlockBuffer[0]:=BlockBuffer[0]+ycoef;
  716. ycoef:=BlockBuffer[0];
  717. for j:=0 to 63 do
  718.                 begin
  719. lpMCUBuffer^:=BlockBuffer[j];
  720.                         inc(lpMCUBuffer);
  721.                 end;
  722. for i:=0 to 127 do
  723.                 begin
  724. lpMCUBuffer^:=0;
  725.                         inc(lpMCUBuffer);
  726.                 end;
  727.           end;
  728.         else
  729.           begin
  730. Result:=FUNC_FORMAT_ERROR;
  731.                 Exit;
  732.           end;
  733. end;//case
  734. Result:=FUNC_OK;
  735. end;
  736. //////////////////////////////////////////////////////////////////
  737. //Huffman Decode (8*8) DU   出口 Blockbuffer[ ] 入口 vvalue
  738. //////////////////////////////////////////////////////////////////
  739. function HufBlock(dchufindex:BYTE;achufindex:BYTE):integer;
  740. var
  741.  count:SmallInt;
  742.  i:SmallInt;
  743.  funcret:integer;
  744. begin
  745.         count:=0;
  746. //dc
  747. HufTabIndex:=dchufindex;
  748. funcret:=DecodeElement;  //Read Byte Dc
  749. if(funcret<>FUNC_OK) then
  750.         begin
  751. result:=funcret;
  752.                 Exit;
  753.         end;
  754. BlockBuffer[count]:=vvalue;//解出的直流系数
  755.         inc(count);
  756. //ac
  757. HufTabIndex:=achufindex;
  758. while (count<64) do
  759.         begin         //63 Bytes AC
  760. funcret:=DecodeElement;
  761. if(funcret<> FUNC_OK) then
  762.                 begin
  763. Result:= funcret;
  764.                         Exit;
  765.                 end;
  766. if ((rrun=0) and (vvalue=0)) then
  767.                 begin
  768. for i:=count to 63 do
  769. BlockBuffer[i]:=0;
  770. count:=64;
  771. end
  772. else
  773.                 begin
  774. for i:=0 to rrun-1 do    //前面的零
  775.                         begin
  776. BlockBuffer[count]:=0;
  777.                                 inc(count);
  778.                         end;
  779. BlockBuffer[count]:=vvalue;//解出的值
  780.                         inc(count);
  781. end;
  782. end;
  783. Result:=FUNC_OK;
  784. end;
  785. //////////////////////////////////////////////////////////////////////////////
  786. //Huffman 解码  每个元素   出口 vvalue 入口 读文件ReadByte
  787. //////////////////////////////////////////////////////////////////////////////
  788. function DecodeElement:integer;
  789. var
  790. thiscode,tempcode:integer;
  791. temp,valueex:Word;
  792. codelen:SmallInt;
  793. hufexbyte,runsize,tempsize,sign:BYTE;
  794. newbyte,lastbyte:BYTE;
  795. begin
  796. if(BitPos>=1) then            //BitPos指示当前比特位置
  797.         begin
  798. dec(BitPos);
  799. thiscode:=BYTE(CurByte shr BitPos); //取一个比特
  800. CurByte:=CurByte and MyAnd[BitPos]; //清除取走的比特位
  801. end
  802. else                                        //取出的一个字节已用完
  803.         begin                                       //新取
  804. lastbyte:=ReadByte; //读出一个字节
  805. dec(BitPos);                     //and[]:=0x0,0x1,0x3,0x7,0xf,0x1f,0x2f,0x3f,0x4f
  806. newbyte:=CurByte and MyAnd[BitPos];  //
  807. thiscode:=lastbyte shr 7;
  808. CurByte:=newbyte;
  809. end;
  810. codelen:=1;
  811. //与Huffman表中的码字匹配,直自找到为止
  812. while ((thiscode<huf_min_value[HufTabIndex,codelen-1]) or
  813.   (code_len_table[HufTabIndex,codelen-1]=0) or
  814.   (thiscode>huf_max_value[HufTabIndex,codelen-1])) do
  815. begin
  816. if(BitPos>=1) then begin  //取出的一个字节还有
  817. dec(BitPos);
  818. tempcode:=BYTE(CurByte shr BitPos);
  819. CurByte:=CurByte and MyAnd[BitPos];
  820. end
  821. else
  822.                 begin
  823. lastbyte:=ReadByte;
  824. dec(BitPos);
  825. newbyte:=CurByte and MyAnd[BitPos];
  826. tempcode:=BYTE(lastbyte shr 7);
  827. CurByte:=newbyte;
  828. end;
  829. thiscode:=(thiscode shl 1)+tempcode;
  830. inc(codelen);
  831. if(codelen>16)  then
  832.                 begin
  833. Result:=FUNC_FORMAT_ERROR;
  834.                         Exit;
  835.                 end;
  836. end;  //while
  837. temp:=thiscode-huf_min_value[HufTabIndex,codelen-1]+code_pos_table[HufTabIndex,codelen-1];
  838. hufexbyte:=BYTE(code_value_table[HufTabIndex,temp]);
  839. rrun:=SmallInt(hufexbyte shr 4);  //一个字节中,高四位是其前面的零的个数。
  840. runsize:=hufexbyte and $0f;      //后四位为后面字的尺寸
  841. if(runsize=0) then
  842.         begin
  843. vvalue:=0;
  844. Result:=FUNC_OK;
  845.                 Exit;
  846. end;
  847. tempsize:=runsize;
  848. if(BitPos>=runsize) then
  849.         begin
  850. BitPos:=BitPos-runsize;
  851. valueex:=BYTE(CurByte shr BitPos);
  852. CurByte:=CurByte and MyAnd[BitPos];
  853. end
  854. else
  855.         begin
  856. valueex:=CurByte;
  857. tempsize:=tempsize-BitPos;
  858. while(tempsize>8) do
  859.                 begin
  860. lastbyte:=ReadByte;
  861. valueex:=(valueex shl 8)+BYTE(lastbyte);
  862. tempsize:=tempsize-8;
  863. end;  //while
  864. lastbyte:=ReadByte;
  865. BitPos:=BitPos-tempsize;
  866. valueex:=(valueex shl tempsize)+(lastbyte shr BitPos);
  867. CurByte:=lastbyte and MyAnd[BitPos];
  868. end;  //else
  869. sign:=valueex shr (runsize-1);
  870. if(sign<>0) then
  871. vvalue:=valueex             //解出的码值
  872. else
  873.         begin
  874. valueex:=valueex xor $ffff;
  875. temp:=$ffff shl runsize;
  876. vvalue:=-SmallInt(valueex xor temp);
  877. end;
  878. Result:=FUNC_OK;
  879. end;
  880. /////////////////////////////////////////////////////////////////////////////////////
  881. //反量化MCU中的每个组件   入口 MCUBuffer 出口 QtZzMCUBuffer
  882. /////////////////////////////////////////////////////////////////////////////////////
  883. procedure IQtIZzMCUComponent(flag:SmallInt);
  884. var
  885.  H,VV:SmallInt;
  886.  i,j:SmallInt;
  887.  pQtZzMCUBuffer,tempbuf1:Pint;
  888.  pMCUBuffer,tempbuf2:PSmallInt;
  889. begin
  890. case flag of
  891. 0:
  892.         begin
  893. H:=SampRate_Y_H;
  894. VV:=SampRate_Y_V;
  895. pMCUBuffer:=PSmallInt(@MCUBuffer);  //Huffman Decoded
  896. pQtZzMCUBuffer:=Pint(@QtZzMCUBuffer);
  897.         end;
  898. 1:
  899.         begin
  900. H:=SampRate_U_H;
  901. VV:=SampRate_U_V;
  902. pMCUBuffer:=PSmallInt(@MCUBuffer);
  903.                 inc(pMCUBuffer,Y_in_MCU*64);
  904. pQtZzMCUBuffer:=Pint(@QtZzMCUBuffer);
  905.                 inc(pQtZzMCUBuffer,Y_in_MCU*64);
  906.         end;
  907. 2:
  908.         begin
  909. H:=SampRate_V_H;
  910. VV:=SampRate_V_V;
  911. pMCUBuffer:=PSmallInt(@MCUBuffer);
  912.                 inc(pMCUBuffer,(Y_in_MCU+U_in_MCU)*64);
  913. pQtZzMCUBuffer:=Pint(@QtZzMCUBuffer);
  914.                 inc(pQtZzMCUBuffer,(Y_in_MCU+U_in_MCU)*64);
  915.         end;
  916.         else
  917.         begin
  918.           H:=0;pQtZzMCUBuffer:=nil;pMCUBuffer:=nil;VV:=0;
  919.         end;
  920. end;//case
  921. for i:=0 to VV-1 do
  922. for j:=0 to H-1 do
  923.                 begin
  924.                     tempbuf2:=pMCUBuffer;inc(tempbuf2,(i*H+j)*64);
  925.                     tempbuf1:=pQtZzMCUBuffer;inc(tempbuf1,(i*H+j)*64);
  926.     IQtIZzBlock(tempbuf2,tempbuf1,flag);      //8*8DU
  927.                 end;
  928. end;
  929.              //要量化的字
  930. //////////////////////////////////////////////////////////////////////////////////////////
  931. //反量化 8*8 DU
  932. //////////////////////////////////////////////////////////////////////////////////////////
  933. procedure IQtIZzBlock(s:PSmallInt;d:PInt;flag:SmallInt);
  934. var
  935.  i,j:SmallInt;
  936.  tag:SmallInt;
  937.  pQt,temp1,temp3:PSmallInt;
  938.  buffer2 :MyInt;
  939.  temp2:Pint;
  940.  offset:SmallInt;
  941. begin
  942. case flag of
  943. 0:                //亮度
  944.          begin
  945. pQt:=YQtTable;      //量化表地址
  946.     //            ShowMessage(IntTostr(YQtTable^));
  947. offset:=128;
  948.          end;
  949. 1:                //红
  950.          begin
  951. pQt:=UQtTable;
  952. offset:=0;
  953.          end;
  954. 2:               //蓝
  955.          begin
  956. pQt:=VQtTable;
  957.          offset:=0;
  958.          end;
  959.         else
  960.            pQt:=nil;offset:=0;
  961. end;
  962. for i:=0 to 7 do
  963. for j:=0 to 7 do
  964.                 begin
  965. tag:=Zig_Zag[i,j];
  966.                         temp1:=s;inc(temp1,tag);temp3:=pQt;inc(temp3,tag);
  967. buffer2[i,j]:=integer(temp1^*temp3^);
  968. end;
  969. Fast_IDCT(buffer2);    //反DCT
  970. for i:=0 to 7 do
  971. for j:=0 to 7 do
  972.                 begin
  973.                         temp2:=d;inc(temp2,i*8+j);
  974. temp2^:=buffer2[i,j]+offset;
  975.                 end;
  976. end;
  977. ///////////////////////////////////////////////////////////////////////////////
  978. procedure Fast_IDCT(var block:MyInt);
  979. begin
  980.         idctrow(block);
  981.         idctcol(block);
  982. end;
  983. ///////////////////////////////////////////////////////////////////////////////
  984. function  ReadByte:BYTE;
  985. var
  986. i:BYTE;
  987. begin
  988. i:=Byte(lp^); // lp 为解码的起始位置
  989.         lp:=lp+1;
  990. if(i=$ff) then
  991. lp:=lp+1;
  992. BitPos:=8;
  993. CurByte:=i;
  994. Result:=i;
  995. end;
  996. ///////////////////////////////////////////////////////////////////////
  997. procedure Initialize_Fast_IDCT;
  998. var
  999.  i:SmallInt;
  1000. begin
  1001. for i:= -512 to 511 do
  1002.         begin
  1003.            if i<-256 then iclip[512+i]:=-256;
  1004.            if i>255 then  iclip[512+i]:=255;
  1005.            if (i>=-256) and (i<=255) then iclip[512+i]:=i;
  1006.         end;
  1007. end;
  1008. ////////////////////////////////////////////////////////////////////////
  1009. procedure idctrow(var blk:MyInt);
  1010. var
  1011. i,x0, x1, x2, x3, x4, x5, x6, x7, x8:integer;
  1012. begin
  1013. //intcut
  1014.       for i:=0 to 7 do
  1015.       begin
  1016.         x1:=blk[i,4] shl 11;
  1017.         x2:=blk[i,6];
  1018.         x3:=blk[i,2];
  1019.         x4:=blk[i,1];
  1020.         x5:=blk[i,7];
  1021.         x6:=blk[i,5];
  1022.         x7:=blk[i,3];
  1023. if ((x1 or x2 or x3 or x4 or x5 or x6 or x7) = 0) then
  1024. begin
  1025.                 blk[i,1]:=blk[i,0] shl 3;
  1026.                 blk[i,2]:=blk[i,0] shl 3;
  1027.                 blk[i,3]:=blk[i,0] shl 3;
  1028.                 blk[i,4]:=blk[i,0] shl 3;
  1029.                 blk[i,5]:=blk[i,0] shl 3;
  1030.                 blk[i,6]:=blk[i,0] shl 3;
  1031.                 blk[i,7]:=blk[i,0] shl 3;
  1032.                 blk[i,0]:=blk[i,0] shl 3;
  1033.         Continue;
  1034. end;
  1035. x0 := (blk[i,0] shl 11) + 128; // for proper rounding in the fourth stage
  1036. //first stage
  1037. x8 := W7*(x4+x5);
  1038. x4 := x8 + (W1-W7)*x4;
  1039. x5 := x8 - (W1+W7)*x5;
  1040. x8 := W3*(x6+x7);
  1041. x6 := x8 - (W3-W5)*x6;
  1042. x7 := x8 - (W3+W5)*x7;
  1043. //second stage
  1044. x8 := x0 + x1;
  1045. x0 := x0-x1;
  1046. x1 := W6*(x3+x2);
  1047. x2 := x1 - (W2+W6)*x2;
  1048. x3 := x1 + (W2-W6)*x3;
  1049. x1 := x4 + x6;
  1050. x4 := x4-x6;
  1051. x6 := x5 + x7;
  1052. x5 := x5-x7;
  1053. //third stage
  1054. x7 := x8 + x3;
  1055. x8 := x8-x3;
  1056. x3 := x0 + x2;
  1057. x0 := x0-x2;
  1058.         if (181*(x4+x5)+128)<0 then
  1059.               x2:=  ((181*(x4+x5)+128) shr 8) or ((not Integer(0)) shl (32-8))
  1060.         else
  1061.               x2 := (181*(x4+x5)+128) shr 8;
  1062.         if (181*(x4-x5)+128)<0 then
  1063.               x4:=  ((181*(x4-x5)+128) shr 8) or ((not Integer(0)) shl (32-8))
  1064.         else
  1065.               x4 := (181*(x4-x5)+128) shr 8;
  1066. //fourth stage
  1067.         if x7+x1<0 then
  1068.            blk[i,0]:=((x7+x1) shr 8) or ((not Integer(0)) shl (32-8))
  1069.         else
  1070.            blk[i,0]:=(x7+x1) shr 8;
  1071.         if x3+x2<0 then
  1072.            blk[i,1]:=((x3+x2) shr 8) or ((not Integer(0)) shl (32-8))
  1073.         else
  1074.         blk[i,1]:=(x3+x2) shr 8;
  1075.         if x0+x4<0 then
  1076.            blk[i,2]:=((x0+x4) shr 8) or ((not Integer(0)) shl (32-8))
  1077.         else
  1078.         blk[i,2]:=(x0+x4) shr 8;
  1079.         if x8+x6<0 then
  1080.            blk[i,3]:=((x8+x6) shr 8) or ((not Integer(0)) shl (32-8))
  1081.         else
  1082.            blk[i,3]:=(x8+x6) shr 8;
  1083.         if x8-x6<0 then
  1084.            blk[i,4]:=((x8-x6) shr 8) or ((not Integer(0)) shl (32-8))
  1085.         else
  1086.        blk[i,4]:= (x8-x6) shr 8;
  1087.         if x0-x4<0 then
  1088.            blk[i,5]:=((x0-x4) shr 8) or ((not Integer(0)) shl (32-8))
  1089.         else
  1090.    blk[i,5]:= (x0-x4) shr 8;
  1091.         if x3-x2<0 then
  1092.            blk[i,6]:=((x3-x2) shr 8) or ((not Integer(0)) shl (32-8))
  1093.         else
  1094.       blk[i,6]:= (x3-x2) shr 8;
  1095.         if x7-x1<0 then
  1096.            blk[i,7]:=((x7-x1) shr 8) or ((not Integer(0)) shl (32-8))
  1097.         else
  1098.       blk[i,7]:= (x7-x1) shr 8;
  1099.       end;
  1100. end;
  1101. //////////////////////////////////////////////////////////////////////////////
  1102. procedure idctcol(var blk:MyInt);
  1103. var
  1104. j,x0, x1, x2, x3, x4, x5, x6, x7, x8:integer;
  1105.         Temp:Integer;
  1106. begin
  1107. //intcut
  1108.       for j:=0 to 7 do
  1109.       begin
  1110.         x1:=blk[4,j] shl 8;
  1111.         x2:=blk[6,j];
  1112.         x3:=blk[2,j];
  1113.         x4:=blk[1,j];
  1114.         x5:=blk[7,j];
  1115.         x6:=blk[5,j];
  1116.         x7:=blk[3,j];
  1117. if ((x1 or x2 or x3 or x4 or x5 or x6 or x7)=0) then
  1118. begin
  1119.            if (blk[0,j]+32)<0 then
  1120.                Temp:=((blk[0,j]+32) shr 6) or (not (Integer(0)) shl (32-6))
  1121.            else
  1122.                Temp:=(blk[0,j]+32) shr 6;
  1123.            blk[1,j]:=iclip[512+Temp];
  1124.            blk[2,j]:=iclip[512+Temp];
  1125.            blk[3,j]:=iclip[512+Temp];
  1126.            blk[4,j]:=iclip[512+Temp];
  1127.            blk[5,j]:=iclip[512+Temp];
  1128.            blk[6,j]:=iclip[512+Temp];
  1129.            blk[7,j]:=iclip[512+Temp];
  1130.    blk[0,j]:=iclip[512+Temp];
  1131.            Continue;
  1132. end;
  1133. x0 := (blk[0,j] shl 8) + 8192;
  1134. //first stage
  1135. x8 := W7*(x4+x5) + 4;
  1136.         if (x8+(W1-W7)*x4)<0 then
  1137.            x4:=((x8+(W1-W7)*x4) shr 3) or (not (Integer(0)) shl (32-3))
  1138.         else
  1139.    x4:= (x8+(W1-W7)*x4) shr 3;
  1140.         if (x8-(W1+W7)*x5)<0 then
  1141.            x5:=((x8-(W1+W7)*x5) shr 3) or (not (Integer(0)) shl (32-3))
  1142.         else
  1143.        x5 := (x8-(W1+W7)*x5) shr 3;
  1144.         x8 := W3*(x6+x7) + 4;
  1145.         if (x8-(W3-W5)*x6)<0 then
  1146.            x6:=((x8-(W3-W5)*x6) shr 3) or (not (Integer(0)) shl (32-3))
  1147.         else
  1148.       x6:=(x8-(W3-W5)*x6) shr 3;
  1149.         if (x8-(W3+W5)*x7)<0 then
  1150.            x7:=((x8-(W3+W5)*x7) shr 3) or (not (Integer(0)) shl (32-3))
  1151.         else
  1152.    x7 := (x8-(W3+W5)*x7) shr 3;
  1153. //second stage
  1154. x8 := x0 + x1;
  1155. x0 := x0-x1;
  1156. x1 := W6*(x3+x2) + 4;
  1157.         if (x1-(W2+W6)*x2)<0 then
  1158.            x2:=((x1-(W2+W6)*x2) shr 3) or (not (Integer(0)) shl (32-3))
  1159.         else
  1160.    x2 := (x1-(W2+W6)*x2) shr 3;
  1161.         if (x1+(W2-W6)*x3)<0 then
  1162.            x3:=((x1+(W2-W6)*x3) shr 3) or (not (Integer(0)) shl (32-3))
  1163.         else
  1164.    x3 := (x1+(W2-W6)*x3) shr 3;
  1165. x1 := x4 + x6;
  1166. x4 := x4-x6;
  1167. x6 := x5 + x7;
  1168. x5 := x5-x7;
  1169. //third stage
  1170. x7 := x8 + x3;
  1171. x8 := x8-x3;
  1172. x3 := x0 + x2;
  1173. x0 := x0-x2;
  1174.         if (181*(x4+x5)+128)<0 then
  1175.            x2:=((181*(x4+x5)+128) shr 8) or (not (Integer(0)) shl (32-8))
  1176.         else
  1177.      x2 := (181*(x4+x5)+128) shr 8;
  1178.         if (181*(x4-x5)+128)<0 then
  1179.            x4:=((181*(x4-x5)+128) shr 8) or (not (Integer(0)) shl (32-8))
  1180.         else
  1181.    x4 := (181*(x4-x5)+128) shr 8;
  1182. //fourth stage
  1183.         if x7+x1<0 then
  1184.            Temp:=((x7+x1) shr 14) or (not (Integer(0)) shl (32-14))
  1185.         else
  1186.            Temp:=(x7+x1) shr 14;
  1187.         blk[0,j]:=iclip[512+Temp];
  1188.         if x3+x2<0 then
  1189.            Temp:=((x3+x2) shr 14) or (not (Integer(0)) shl (32-14))
  1190.         else
  1191.            Temp:=(x3+x2) shr 14;
  1192.         blk[1,j]:=iclip[512+Temp];
  1193.         if x0+x4<0 then
  1194.            Temp:=((x0+x4) shr 14) or (not (Integer(0)) shl (32-14))
  1195.         else
  1196.            Temp:=(x0+x4) shr 14;
  1197.         blk[2,j]:=iclip[512+Temp];
  1198.         if x8+x6<0 then
  1199.            Temp:=((x8+x6) shr 14) or (not (Integer(0)) shl (32-14))
  1200.         else
  1201.            Temp:=(x8+x6) shr 14;
  1202.         blk[3,j]:=iclip[512+Temp];
  1203.         if x8-x6<0 then
  1204.            Temp:=((x8-x6) shr 14) or (not (Integer(0)) shl (32-14))
  1205.         else
  1206.            Temp:=(x8-x6) shr 14;
  1207.         blk[4,j]:=iclip[512+Temp];
  1208.         if x0-x4<0 then
  1209.            Temp:=((x0-x4) shr 14) or (not (Integer(0)) shl (32-14))
  1210.         else
  1211.            Temp:=(x0-x4) shr 14;
  1212.         blk[5,j]:=iclip[512+Temp];
  1213.         if x3-x2<0 then
  1214.            Temp:=((x3-x2) shr 14) or (not (Integer(0)) shl (32-14))
  1215.         else
  1216.            Temp:=(x3-x2) shr 14;
  1217.         blk[6,j]:=iclip[512+Temp];
  1218.         if x7-x1<0 then
  1219.            Temp:=((x7-x1) shr 14) or (not (Integer(0)) shl (32-14))
  1220.         else
  1221.            Temp:=(x7-x1) shr 14;
  1222.         blk[7,j]:=iclip[512+Temp];
  1223.       end;
  1224. end;
  1225. end.