compress.c
上传用户:s6549606
上传日期:2015-11-11
资源大小:12002k
文件大小:31k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////
  2. //Name:compress.c
  3. //Purpose: Run length algorithm and Jpeg decoding
  4. //Author: phoenix, CS, TshingHua, Beijing, P.R.C.
  5. //Email: bjlufengjun@www.163.net or lufengjun@hotmail.com
  6. //Date:April 3, 1998
  7. //header file
  8. #include "bmp.h"
  9. #include "jpeg.h"
  10. #include "memory.h"
  11. #include "math.h"
  12. #include "stdio.h"
  13. //macro definition
  14. #define WIDTHBYTES(i)    ((i+31)/32*4)
  15. #define PI 3.1415926535
  16. //define return value of function
  17. #define FUNC_OK 0
  18. #define FUNC_MEMORY_ERROR 1
  19. #define FUNC_FILE_ERROR 2
  20. #define FUNC_FORMAT_ERROR 3
  21. //function declaration
  22. int PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
  23. LRESULT CALLBACK MainWndProc(HWND , UINT,WPARAM, LPARAM);
  24. BOOL LoadPcxFile(HWND hWnd,char *BmpFileName);
  25. void ReadPcxLine(unsigned char *p,FILE *fp);
  26. //////////////////////////////////////////////////
  27. //Jpeg functions
  28. BOOL LoadJpegFile(HWND hWnd,char *BmpFileName);
  29. void showerror(int funcret);
  30. int  InitTag();
  31. void InitTable();
  32. int  Decode();
  33. int  DecodeMCUBlock();
  34. int  HufBlock(BYTE dchufindex,BYTE achufindex);
  35. int  DecodeElement();
  36. void IQtIZzMCUComponent(short flag);
  37. void IQtIZzBlock(short  *s ,int * d,short flag);
  38. void GetYUV(short flag);
  39. void StoreBuffer();
  40. BYTE ReadByte();
  41. void Initialize_Fast_IDCT();
  42. void Fast_IDCT(int * block);
  43. void idctrow(int * blk);
  44. void idctcol(int * blk);
  45. //////////////////////////////////////////////////
  46. //global variable declaration
  47. BITMAPFILEHEADER   bf;
  48. BITMAPINFOHEADER   bi;
  49. HPALETTE           hPalette=NULL;
  50. HBITMAP            hBitmap=NULL;
  51. HGLOBAL            hImgData=NULL;
  52. DWORD              NumColors;
  53. DWORD              LineBytes;
  54. DWORD              ImgWidth=0 , ImgHeight=0;
  55. unsigned int       PcxBytesPerLine;
  56. LPSTR              lpPtr;
  57. //////////////////////////////////////////////////
  58. //variables used in jpeg function
  59. short SampRate_Y_H,SampRate_Y_V;
  60. short SampRate_U_H,SampRate_U_V;
  61. short SampRate_V_H,SampRate_V_V;
  62. short H_YtoU,V_YtoU,H_YtoV,V_YtoV;
  63. short Y_in_MCU,U_in_MCU,V_in_MCU;
  64. unsigned char   *lpJpegBuf;
  65. unsigned char   *lp;
  66. short qt_table[3][64];
  67. short comp_num;
  68. BYTE comp_index[3];
  69. BYTE     YDcIndex,YAcIndex,UVDcIndex,UVAcIndex;
  70. BYTE HufTabIndex;
  71. short     *YQtTable,*UQtTable,*VQtTable;
  72. BYTE And[9]={0,1,3,7,0xf,0x1f,0x3f,0x7f,0xff};
  73. short     code_pos_table[4][16],code_len_table[4][16];
  74. unsigned short code_value_table[4][256];
  75. unsigned short huf_max_value[4][16],huf_min_value[4][16];
  76. short BitPos,CurByte;
  77. short rrun,vvalue;
  78. short MCUBuffer[10*64];
  79. int QtZzMCUBuffer[10*64];
  80. short BlockBuffer[64];
  81. short ycoef,ucoef,vcoef;
  82. BOOL IntervalFlag;
  83. short interval=0;
  84. int Y[4*64],U[4*64],V[4*64];
  85. DWORD     sizei,sizej;
  86. short  restart;
  87. static  long iclip[1024];
  88. static  long *iclp;
  89. ///////////////////////////////////////////////////////////
  90. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  91.     LPSTR lpszCmdLine, int nCmdShow)
  92. {
  93. MSG       msg;
  94. WNDCLASS  wndclass;
  95. HWND      hWnd;
  96. if ( ! hPrevInstance ){
  97. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  98. wndclass.lpfnWndProc = MainWndProc;
  99. wndclass.cbClsExtra = 0;
  100. wndclass.cbWndExtra = 0;
  101. wndclass.hInstance = hInstance;
  102. wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  103. wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
  104. wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
  105. wndclass.lpszMenuName =  "BMPMENU";
  106. wndclass.lpszClassName = "phoenix ip system";
  107.     }
  108.     if ( ! RegisterClass (&wndclass) )
  109.     return FALSE;
  110. hWnd = CreateWindow ("phoenix ip system","Run length algorithm and Jpeg decoding",
  111.  WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
  112.  CW_USEDEFAULT, CW_USEDEFAULT, NULL,NULL,
  113.  hInstance, NULL);
  114. if (!hWnd)
  115. return FALSE;
  116. ShowWindow (hWnd, SW_SHOWMAXIMIZED);
  117. UpdateWindow (hWnd);
  118. while ( GetMessage (&msg, NULL, 0, 0) ){
  119. TranslateMessage (&msg);
  120. DispatchMessage (&msg);
  121.     }
  122. return msg.wParam;
  123. }
  124. ////////////////////////////////////////////////////////////////
  125. LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam)
  126. {
  127.     static  HDC    hDC,hMemDC;
  128.     PAINTSTRUCT    ps;
  129.     switch (message){
  130.     case WM_PAINT:
  131. {         
  132. hDC = BeginPaint(hWnd, &ps);
  133. if (hBitmap)
  134. hMemDC = CreateCompatibleDC(hDC);
  135. if (hPalette)
  136. {           
  137. SelectPalette (hDC, hPalette, FALSE); 
  138. SelectPalette (hMemDC, hPalette, FALSE);
  139. RealizePalette (hDC);
  140. }   
  141. SelectObject(hMemDC, hBitmap); 
  142. BitBlt(hDC, 0, 0, ImgWidth,ImgHeight, hMemDC, 0, 0, SRCCOPY);
  143. DeleteDC(hMemDC);
  144. }
  145. EndPaint(hWnd, &ps);
  146. break;
  147. }
  148. case WM_DESTROY: //注意释放内存和位图,调色板句柄
  149.         if(hBitmap!=NULL)
  150.         DeleteObject(hBitmap);
  151.     
  152. if(hPalette!=NULL)                     
  153.         DeleteObject(hPalette);
  154. if(hImgData!=NULL){
  155. GlobalUnlock(hImgData);
  156. GlobalFree(hImgData);
  157. }         
  158.     PostQuitMessage (0);
  159.     return 0;
  160. case WM_COMMAND:
  161.     switch (wParam){
  162. case IDM_RUNLENGTH:
  163. //注意重新分配内存和调色板,位图句柄时,先释放原来的
  164.         if(hBitmap!=NULL){     
  165. DeleteObject(hBitmap);
  166.             hBitmap=NULL;
  167.         }
  168.         if(hPalette!=NULL){                     
  169. DeleteObject(hPalette);
  170.             hPalette=NULL;
  171.         }
  172. if(hImgData!=NULL){
  173. GlobalUnlock(hImgData);
  174. GlobalFree(hImgData);  
  175. hImgData=NULL;
  176. }         
  177. if(LoadPcxFile(hWnd,"c:\test.pcx")) //成功,则重画窗口
  178.                 InvalidateRect(hWnd,NULL,TRUE);
  179.         break;
  180. case IDM_JPEG:
  181. //注意重新分配内存和调色板,位图句柄时,先释放原来的
  182.         if(hBitmap!=NULL){     
  183. DeleteObject(hBitmap);
  184.             hBitmap=NULL;
  185.         }
  186.         if(hPalette!=NULL){                     
  187. DeleteObject(hPalette);
  188.             hPalette=NULL;
  189.         }
  190. if(hImgData!=NULL){
  191. GlobalUnlock(hImgData);
  192. GlobalFree(hImgData);  
  193. hImgData=NULL;
  194. }         
  195. if(LoadJpegFile(hWnd,"c:\test.jpg")) //成功,则重画窗口
  196.                 InvalidateRect(hWnd,NULL,TRUE);
  197.         break;
  198. case IDM_EXIT:
  199.         SendMessage(hWnd,WM_DESTROY,0,0L);
  200.         break;
  201.     }
  202. break;                
  203.     }
  204.     return DefWindowProc (hWnd, message, wParam, lParam);
  205. }
  206. ////////////////////////////////////////////////////////////////
  207. BOOL LoadPcxFile (HWND hWnd,char *PcxFileName)
  208. {   
  209. //pcx header
  210. typedef struct{
  211.  char manufacturer;
  212.  char version;
  213.  char encoding;
  214.  char bits_per_pixel;
  215.  WORD xmin,ymin;
  216.  WORD xmax,ymax;
  217.  WORD hres;
  218.  WORD vres;
  219.  char palette[48];
  220.  char reserved;
  221.  char colour_planes;
  222.  WORD bytes_per_line;
  223.  WORD palette_type;
  224.  char filler[58];
  225.       } PCXHEAD;
  226. FILE               *PCXfp;
  227. PCXHEAD    header;
  228.     LOGPALETTE         *pPal;
  229.     HPALETTE           hPrevPalette; 
  230.     HDC                hDc;
  231. HLOCAL             hPal;
  232. DWORD         ImgSize;
  233. DWORD              BufSize;
  234. LPBITMAPINFOHEADER lpImgData;
  235. DWORD              i;
  236. LONG               x,y;
  237. int                PcxTag;
  238. unsigned char      LineBuffer[6400];
  239. LPSTR              lpPtr;
  240. HFILE              hfbmp;
  241.     if((PCXfp=fopen(PcxFileName,"rb"))==NULL){
  242.         MessageBox(hWnd,"File c:\test.pcx not found!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  243.         return FALSE;
  244. }
  245.     fread((char*)&header,1,sizeof(PCXHEAD),PCXfp);
  246.     if(header.manufacturer!=0x0a){
  247.     MessageBox(hWnd,"Not a valid Pcx file!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  248.     fclose(PCXfp);
  249.     return FALSE;
  250. }
  251. fseek(PCXfp,-769L,SEEK_END);
  252. PcxTag=fgetc(PCXfp)&0xff;
  253. if(PcxTag!=12){
  254.     MessageBox(hWnd,"Not a 256 colors Pcx file!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  255. fclose(PCXfp);
  256. return FALSE;
  257. }
  258. //create new bitmapfileheader and bitmapinfoheader
  259. memset((char *)&bf,0,sizeof(BITMAPFILEHEADER));
  260. memset((char *)&bi,0,sizeof(BITMAPINFOHEADER));
  261. bi.biSize=sizeof(BITMAPINFOHEADER);
  262. bi.biWidth=header.xmax-header.xmin+1;
  263. bi.biHeight=header.ymax-header.ymin+1;
  264. bi.biPlanes=1;
  265. bi.biBitCount=8;
  266. bi.biCompression=BI_RGB;
  267. ImgWidth=bi.biWidth;
  268. ImgHeight=bi.biHeight;
  269. NumColors=256;
  270. LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
  271. ImgSize=(DWORD)LineBytes*bi.biHeight;
  272. bf.bfType=0x4d42;
  273. bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
  274. bf.bfOffBits=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
  275. if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+
  276.      NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
  277. {
  278.      MessageBox(hWnd,"Error alloc memory!","ErrorMessage",MB_OK|
  279.                    MB_ICONEXCLAMATION);
  280.     fclose(PCXfp);
  281. return FALSE;
  282. }
  283. lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData); 
  284. memcpy(lpImgData,(char *)&bi,sizeof(BITMAPINFOHEADER));
  285. lpPtr=(char *)lpImgData+sizeof(BITMAPINFOHEADER);
  286.     hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NumColors* sizeof(PALETTEENTRY));
  287.     pPal =(LOGPALETTE *)LocalLock(hPal);
  288.     pPal->palNumEntries =256;
  289. pPal->palVersion    = 0x300;
  290. for (i = 0; i < 256; i++) {
  291.     pPal->palPalEntry[i].peRed=(BYTE)fgetc(PCXfp);
  292. pPal->palPalEntry[i].peGreen=(BYTE)fgetc(PCXfp);
  293. pPal->palPalEntry[i].peBlue=(BYTE)fgetc(PCXfp);
  294. pPal->palPalEntry[i].peFlags=(BYTE)0;
  295. *(lpPtr++)=(unsigned char)pPal->palPalEntry[i].peBlue;
  296. *(lpPtr++)=(unsigned char)pPal->palPalEntry[i].peGreen;
  297. *(lpPtr++)=(unsigned char)pPal->palPalEntry[i].peRed;
  298. *(lpPtr++)=0;
  299. }
  300. hPalette=CreatePalette(pPal);
  301. LocalUnlock(hPal);
  302. LocalFree(hPal);
  303. hDc=GetDC(hWnd);
  304. if(hPalette){
  305.         hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
  306. RealizePalette(hDc);
  307. }
  308. PcxBytesPerLine=(unsigned int)header.bytes_per_line;
  309. fseek(PCXfp,(LONG)sizeof(PCXHEAD),SEEK_SET);
  310. BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
  311. for(y=0;y<bi.biHeight;y++){
  312. lpPtr=(char *)lpImgData+BufSize-LineBytes-y*LineBytes;
  313. ReadPcxLine(LineBuffer,PCXfp);
  314. for(x=0;x<bi.biWidth;x++)
  315. *(lpPtr++)=LineBuffer[x];
  316. }
  317. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData, (LONG)CBM_INIT,
  318. (LPSTR)lpImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  319.     (LPBITMAPINFO)lpImgData, DIB_RGB_COLORS);
  320. if(hPalette && hPrevPalette){
  321. SelectPalette(hDc,hPrevPalette,FALSE);
  322. RealizePalette(hDc);
  323. }
  324. hfbmp=_lcreat("c:\pcx2bmp.bmp",0);
  325. _lwrite(hfbmp,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  326. _lwrite(hfbmp,(LPSTR)lpImgData,BufSize);
  327. _lclose(hfbmp);
  328. fclose(PCXfp); 
  329. ReleaseDC(hWnd,hDc);
  330. GlobalUnlock(hImgData);
  331. return TRUE; 
  332. }
  333. ////////////////////////////////////////////////////////////////
  334. void ReadPcxLine(unsigned char *p,FILE *fp) //decode one line of pcx file
  335. {
  336. unsigned int n=0,i;
  337. char c;
  338. memset(p,0,PcxBytesPerLine);
  339. do{
  340. //get a key byte
  341. c=fgetc(fp)&0xff;
  342. //if it's a run of BytePerLine field
  343. if((c&0xc0)==0xc0){
  344. //mask off the high bits
  345. i=c&0x3f;
  346. //get the run byte
  347. c=fgetc(fp);
  348. //run the byte  
  349. while(i--) p[n++]=c;
  350. }
  351. else p[n++]=c;
  352. }while (n<PcxBytesPerLine);
  353. }
  354. ////////////////////////////////////////////////////////////////
  355. BOOL LoadJpegFile (HWND hWnd,char *JpegFileName)
  356. {
  357. HFILE    hfjpg;
  358.     HDC                hDc;
  359. DWORD         ImgSize;
  360. DWORD              BufSize,JpegBufSize;
  361. HFILE              hfbmp;
  362. HGLOBAL    hJpegBuf;
  363. int    funcret;
  364. LPBITMAPINFOHEADER lpImgData;
  365. if((hfjpg=_lopen(JpegFileName,OF_READ))==HFILE_ERROR){
  366. showerror(FUNC_FILE_ERROR);
  367. return FALSE;
  368. }
  369. //get jpg file length
  370. JpegBufSize=_llseek(hfjpg,0L,SEEK_END);
  371. //rewind to the beginning of the file
  372. _llseek(hfjpg,0L,SEEK_SET);
  373. if((hJpegBuf=GlobalAlloc(GHND,JpegBufSize))==NULL){
  374. _lclose(hfjpg);
  375. showerror(FUNC_MEMORY_ERROR);
  376. return FALSE;
  377. }
  378. lpJpegBuf=(unsigned char  *)GlobalLock(hJpegBuf);
  379. _hread(hfjpg,(unsigned char  *)lpJpegBuf,JpegBufSize);
  380. _lclose(hfjpg);
  381. InitTable();
  382. if((funcret=InitTag())!=FUNC_OK){
  383. GlobalUnlock(hJpegBuf);
  384. GlobalFree(hJpegBuf);
  385. showerror(funcret);
  386. return FALSE;
  387. }
  388. //create new bitmapfileheader and bitmapinfoheader
  389. memset((char *)&bf,0,sizeof(BITMAPFILEHEADER));
  390. memset((char *)&bi,0,sizeof(BITMAPINFOHEADER));
  391. bi.biSize=(DWORD)sizeof(BITMAPINFOHEADER);
  392. bi.biWidth=(LONG)(ImgWidth);
  393. bi.biHeight=(LONG)(ImgHeight);
  394. bi.biPlanes=1;
  395. bi.biBitCount=24;
  396. bi.biClrUsed=0;
  397. bi.biClrImportant=0;
  398. bi.biCompression=BI_RGB;
  399. NumColors=0;
  400. LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
  401. ImgSize=(DWORD)LineBytes*bi.biHeight;
  402. bf.bfType=0x4d42;
  403. bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
  404. bf.bfOffBits=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
  405. BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
  406. if((hImgData=GlobalAlloc(GHND,BufSize))==NULL){
  407. GlobalUnlock(hJpegBuf);
  408. GlobalFree(hJpegBuf);
  409. showerror(FUNC_MEMORY_ERROR);
  410. return FALSE;
  411. }
  412. lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData); 
  413. memcpy(lpImgData,(char *)&bi,sizeof(BITMAPINFOHEADER));
  414. lpPtr=(char *)lpImgData+sizeof(BITMAPINFOHEADER);
  415. if((SampRate_Y_H==0)||(SampRate_Y_V==0)){
  416. GlobalUnlock(hJpegBuf);
  417. GlobalFree(hJpegBuf);
  418. GlobalUnlock(hImgData);
  419. GlobalFree(hImgData);
  420. hImgData=NULL;
  421. showerror(FUNC_FORMAT_ERROR);
  422. return FALSE ;
  423. }
  424. funcret=Decode();
  425. if(funcret==FUNC_OK){
  426. hDc=GetDC(hWnd);
  427. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData, (LONG)CBM_INIT,
  428. (LPSTR)lpImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  429.     (LPBITMAPINFO)lpImgData, DIB_RGB_COLORS);
  430. hfbmp=_lcreat("c:\jpeg2bmp.bmp",0);
  431. _lwrite(hfbmp,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  432. _lwrite(hfbmp,(LPSTR)lpImgData,BufSize);
  433. _lclose(hfbmp);
  434. ReleaseDC(hWnd,hDc);
  435. GlobalUnlock(hJpegBuf);
  436. GlobalFree(hJpegBuf);
  437. GlobalUnlock(hImgData);
  438. return TRUE;
  439. }
  440. else{
  441. GlobalUnlock(hJpegBuf);
  442. GlobalFree(hJpegBuf);
  443. GlobalUnlock(hImgData);
  444. GlobalFree(hImgData);
  445. hImgData=NULL;
  446. showerror(funcret);
  447. return FALSE;
  448. }
  449. }
  450. /////////////////////////////////////////////////
  451. void showerror(int funcret)
  452. {
  453. switch(funcret){
  454. case FUNC_MEMORY_ERROR:
  455.      MessageBox(NULL,"Error alloc memory!","ErrorMessage",MB_OK|MB_ICONEXCLAMATION);
  456. break;
  457. case FUNC_FILE_ERROR:
  458.      MessageBox(NULL,"File not found!","ErrorMessage",MB_OK|MB_ICONEXCLAMATION);
  459. break;
  460. case FUNC_FORMAT_ERROR:
  461. MessageBox(NULL,"File format error!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  462. break;
  463. }
  464. }
  465. ////////////////////////////////////////////////////////////////////////////////
  466. int InitTag()
  467. {
  468. BOOL finish=FALSE;
  469. BYTE id;
  470. short  llength;
  471. short  i,j,k;
  472. short  huftab1,huftab2;
  473. short  huftabindex;
  474. BYTE hf_table_index;
  475. BYTE qt_table_index;
  476. BYTE comnum;
  477. unsigned char  *lptemp;
  478. short  ccount;
  479. lp=lpJpegBuf+2;
  480. while (!finish){
  481. id=*(lp+1);
  482. lp+=2;
  483. switch (id){
  484. case M_APP0:
  485. llength=MAKEWORD(*(lp+1),*lp);
  486. lp+=llength;
  487. break;
  488. case M_DQT:
  489. llength=MAKEWORD(*(lp+1),*lp);
  490. qt_table_index=(*(lp+2))&0x0f;
  491. lptemp=lp+3;
  492. if(llength<80){
  493. for(i=0;i<64;i++)
  494. qt_table[qt_table_index][i]=(short)*(lptemp++);
  495. }
  496. else{
  497. for(i=0;i<64;i++)
  498. qt_table[qt_table_index][i]=(short)*(lptemp++);
  499.                 qt_table_index=(*(lptemp++))&0x0f;
  500.    for(i=0;i<64;i++)
  501. qt_table[qt_table_index][i]=(short)*(lptemp++);
  502.    }
  503.    lp+=llength;
  504. break;
  505. case M_SOF0:
  506.   llength=MAKEWORD(*(lp+1),*lp);
  507.   ImgHeight=MAKEWORD(*(lp+4),*(lp+3));
  508.   ImgWidth=MAKEWORD(*(lp+6),*(lp+5));
  509.             comp_num=*(lp+7);
  510.     if((comp_num!=1)&&(comp_num!=3))
  511.    return FUNC_FORMAT_ERROR;
  512. if(comp_num==3){
  513. comp_index[0]=*(lp+8);
  514.    SampRate_Y_H=(*(lp+9))>>4;
  515.    SampRate_Y_V=(*(lp+9))&0x0f;
  516.    YQtTable=(short *)qt_table[*(lp+10)];
  517. comp_index[1]=*(lp+11);
  518. SampRate_U_H=(*(lp+12))>>4;
  519.    SampRate_U_V=(*(lp+12))&0x0f;
  520.    UQtTable=(short *)qt_table[*(lp+13)];
  521.    comp_index[2]=*(lp+14);
  522.    SampRate_V_H=(*(lp+15))>>4;
  523.    SampRate_V_V=(*(lp+15))&0x0f;
  524. VQtTable=(short *)qt_table[*(lp+16)];
  525.    }
  526. else{
  527.    comp_index[0]=*(lp+8);
  528. SampRate_Y_H=(*(lp+9))>>4;
  529.    SampRate_Y_V=(*(lp+9))&0x0f;
  530.    YQtTable=(short *)qt_table[*(lp+10)];
  531. comp_index[1]=*(lp+8);
  532.    SampRate_U_H=1;
  533.    SampRate_U_V=1;
  534.    UQtTable=(short *)qt_table[*(lp+10)];
  535. comp_index[2]=*(lp+8);
  536. SampRate_V_H=1;
  537.    SampRate_V_V=1;
  538.    VQtTable=(short *)qt_table[*(lp+10)];
  539. }
  540.    lp+=llength;     
  541. break;
  542. case M_DHT:             
  543. llength=MAKEWORD(*(lp+1),*lp);
  544. if (llength<0xd0){
  545. huftab1=(short)(*(lp+2))>>4;     //huftab1=0,1
  546.   huftab2=(short)(*(lp+2))&0x0f;   //huftab2=0,1
  547. huftabindex=huftab1*2+huftab2;
  548.   lptemp=lp+3;
  549. for (i=0; i<16; i++)
  550. code_len_table[huftabindex][i]=(short)(*(lptemp++));
  551. j=0;
  552. for (i=0; i<16; i++)
  553. if(code_len_table[huftabindex][i]!=0){
  554. k=0;
  555. while(k<code_len_table[huftabindex][i]){
  556. code_value_table[huftabindex][k+j]=(short)(*(lptemp++));
  557. k++;
  558. }
  559. j+=k;
  560. }
  561. i=0;
  562. while (code_len_table[huftabindex][i]==0)
  563.   i++;
  564. for (j=0;j<i;j++){
  565. huf_min_value[huftabindex][j]=0;
  566. huf_max_value[huftabindex][j]=0;
  567. }
  568. huf_min_value[huftabindex][i]=0;
  569. huf_max_value[huftabindex][i]=code_len_table[huftabindex][i]-1;
  570. for (j=i+1;j<16;j++){
  571. huf_min_value[huftabindex][j]=(huf_max_value[huftabindex][j-1]+1)<<1;
  572. huf_max_value[huftabindex][j]=huf_min_value[huftabindex][j]+code_len_table[huftabindex][j]-1;
  573. }
  574. code_pos_table[huftabindex][0]=0;
  575. for (j=1;j<16;j++)
  576.    code_pos_table[huftabindex][j]=code_len_table[huftabindex][j-1]+code_pos_table[huftabindex][j-1];
  577.    lp+=llength;
  578. }  //if
  579. else{
  580.   hf_table_index=*(lp+2);
  581. lp+=2;
  582. while (hf_table_index!=0xff){
  583. huftab1=(short)hf_table_index>>4;     //huftab1=0,1
  584.   huftab2=(short)hf_table_index&0x0f;   //huftab2=0,1
  585. huftabindex=huftab1*2+huftab2;
  586. lptemp=lp+1;
  587. ccount=0;
  588. for (i=0; i<16; i++){
  589. code_len_table[huftabindex][i]=(short)(*(lptemp++));
  590. ccount+=code_len_table[huftabindex][i];
  591. }
  592. ccount+=17;
  593. j=0;
  594. for (i=0; i<16; i++)
  595. if(code_len_table[huftabindex][i]!=0){
  596. k=0;
  597. while(k<code_len_table[huftabindex][i])
  598. {
  599. code_value_table[huftabindex][k+j]=(short)(*(lptemp++));
  600. k++;
  601. }
  602. j+=k;
  603. }
  604. i=0;
  605. while (code_len_table[huftabindex][i]==0)
  606. i++;
  607. for (j=0;j<i;j++){
  608. huf_min_value[huftabindex][j]=0;
  609. huf_max_value[huftabindex][j]=0;
  610. }
  611. huf_min_value[huftabindex][i]=0;
  612. huf_max_value[huftabindex][i]=code_len_table[huftabindex][i]-1;
  613. for (j=i+1;j<16;j++){
  614. huf_min_value[huftabindex][j]=(huf_max_value[huftabindex][j-1]+1)<<1;
  615. huf_max_value[huftabindex][j]=huf_min_value[huftabindex][j]+code_len_table[huftabindex][j]-1;
  616. }
  617. code_pos_table[huftabindex][0]=0;
  618. for (j=1;j<16;j++)
  619. code_pos_table[huftabindex][j]=code_len_table[huftabindex][j-1]+code_pos_table[huftabindex][j-1];
  620. lp+=ccount;
  621. hf_table_index=*lp;
  622. }  //while
  623. }  //else
  624. break;
  625. case M_DRI:
  626. llength=MAKEWORD(*(lp+1),*lp);
  627. restart=MAKEWORD(*(lp+3),*(lp+2));
  628. lp+=llength;
  629. break;
  630. case M_SOS:
  631. llength=MAKEWORD(*(lp+1),*lp);
  632. comnum=*(lp+2);
  633. if(comnum!=comp_num)
  634. return FUNC_FORMAT_ERROR;
  635. lptemp=lp+3;
  636. for (i=0;i<comp_num;i++){
  637. if(*lptemp==comp_index[0]){
  638. YDcIndex=(*(lptemp+1))>>4;   //Y
  639. YAcIndex=((*(lptemp+1))&0x0f)+2;
  640. }
  641. else{
  642. UVDcIndex=(*(lptemp+1))>>4;   //U,V
  643. UVAcIndex=((*(lptemp+1))&0x0f)+2;
  644. }
  645. lptemp+=2;
  646. }
  647. lp+=llength;
  648. finish=TRUE;
  649. break;
  650. case M_EOI:    
  651. return FUNC_FORMAT_ERROR;
  652. break;
  653. default:
  654.   if ((id&0xf0)!=0xd0){
  655. llength=MAKEWORD(*(lp+1),*lp);
  656.   lp+=llength;
  657. }
  658. else lp+=2;
  659. break;
  660.    }  //switch
  661. } //while
  662. return FUNC_OK;
  663. }
  664. /////////////////////////////////////////////////////////////////
  665. void InitTable()
  666. {
  667. short i,j;
  668. sizei=sizej=0;
  669. ImgWidth=ImgHeight=0;
  670. rrun=vvalue=0;
  671. BitPos=0;
  672. CurByte=0;
  673. IntervalFlag=FALSE;
  674. restart=0;
  675. for(i=0;i<3;i++)
  676. for(j=0;j<64;j++)
  677. qt_table[i][j]=0;
  678. comp_num=0;
  679. HufTabIndex=0;
  680. for(i=0;i<3;i++)
  681. comp_index[i]=0;
  682. for(i=0;i<4;i++)
  683. for(j=0;j<16;j++){
  684. code_len_table[i][j]=0;
  685. code_pos_table[i][j]=0;
  686. huf_max_value[i][j]=0;
  687. huf_min_value[i][j]=0;
  688. }
  689. for(i=0;i<4;i++)
  690. for(j=0;j<256;j++)
  691. code_value_table[i][j]=0;
  692. for(i=0;i<10*64;i++){
  693. MCUBuffer[i]=0;
  694. QtZzMCUBuffer[i]=0;
  695. }
  696. for(i=0;i<64;i++){
  697. Y[i]=0;
  698. U[i]=0;
  699. V[i]=0;
  700. BlockBuffer[i]=0;
  701. }
  702. ycoef=ucoef=vcoef=0;
  703. }
  704. /////////////////////////////////////////////////////////////////////////
  705. int Decode()
  706. {
  707. int funcret;
  708. Y_in_MCU=SampRate_Y_H*SampRate_Y_V;
  709. U_in_MCU=SampRate_U_H*SampRate_U_V;
  710. V_in_MCU=SampRate_V_H*SampRate_V_V;
  711. H_YtoU=SampRate_Y_H/SampRate_U_H;
  712. V_YtoU=SampRate_Y_V/SampRate_U_V;
  713. H_YtoV=SampRate_Y_H/SampRate_V_H;
  714. V_YtoV=SampRate_Y_V/SampRate_V_V;
  715. Initialize_Fast_IDCT();
  716. while((funcret=DecodeMCUBlock())==FUNC_OK){
  717. interval++;
  718. if((restart)&&(interval % restart==0))
  719.  IntervalFlag=TRUE;
  720. else
  721. IntervalFlag=FALSE;
  722. IQtIZzMCUComponent(0);
  723. IQtIZzMCUComponent(1);
  724. IQtIZzMCUComponent(2);
  725. GetYUV(0);
  726. GetYUV(1);
  727. GetYUV(2);
  728. StoreBuffer();
  729. sizej+=SampRate_Y_H*8;
  730. if(sizej>=ImgWidth){
  731. sizej=0;
  732. sizei+=SampRate_Y_V*8;
  733. }
  734. if ((sizej==0)&&(sizei>=ImgHeight))
  735. break;
  736. }
  737. return funcret;
  738. }
  739. /////////////////////////////////////////////////////////////////////////////////////////
  740. void  GetYUV(short flag)
  741. {
  742. short H,VV;
  743. short i,j,k,h;
  744. int *buf;
  745. int *pQtZzMCU;
  746. switch(flag){
  747. case 0:
  748. H=SampRate_Y_H;
  749. VV=SampRate_Y_V;
  750. buf=Y;
  751. pQtZzMCU=QtZzMCUBuffer;
  752. break;
  753. case 1:
  754. H=SampRate_U_H;
  755. VV=SampRate_U_V;
  756. buf=U;
  757. pQtZzMCU=QtZzMCUBuffer+Y_in_MCU*64;
  758. break;
  759. case 2:
  760. H=SampRate_V_H;
  761. VV=SampRate_V_V;
  762. buf=V;
  763. pQtZzMCU=QtZzMCUBuffer+(Y_in_MCU+U_in_MCU)*64;
  764. break;
  765. }
  766. for (i=0;i<VV;i++)
  767. for(j=0;j<H;j++)
  768. for(k=0;k<8;k++)
  769. for(h=0;h<8;h++)
  770. buf[(i*8+k)*SampRate_Y_H*8+j*8+h]=*pQtZzMCU++;
  771. }
  772. ///////////////////////////////////////////////////////////////////////////////
  773. void StoreBuffer()
  774. {
  775. short i,j;
  776. unsigned char  *lpbmp;
  777. unsigned char R,G,B;
  778. int y,u,v,rr,gg,bb;
  779. for(i=0;i<SampRate_Y_V*8;i++){
  780. if((sizei+i)<ImgHeight){
  781. lpbmp=((unsigned char *)lpPtr+(DWORD)(ImgHeight-sizei-i-1)*LineBytes+sizej*3);
  782. for(j=0;j<SampRate_Y_H*8;j++){
  783. if((sizej+j)<ImgWidth){
  784. y=Y[i*8*SampRate_Y_H+j];
  785. u=U[(i/V_YtoU)*8*SampRate_Y_H+j/H_YtoU];
  786. v=V[(i/V_YtoV)*8*SampRate_Y_H+j/H_YtoV];
  787. rr=((y<<8)+18*u+367*v)>>8;
  788. gg=((y<<8)-159*u-220*v)>>8;
  789. bb=((y<<8)+411*u-29*v)>>8;
  790. R=(unsigned char)rr;
  791. G=(unsigned char)gg;
  792. B=(unsigned char)bb;
  793. if (rr&0xffffff00) if (rr>255) R=255; else if (rr<0) R=0;
  794. if (gg&0xffffff00) if (gg>255) G=255; else if (gg<0) G=0;
  795. if (bb&0xffffff00) if (bb>255) B=255; else if (bb<0) B=0;
  796. *lpbmp++=B;
  797. *lpbmp++=G;
  798. *lpbmp++=R;
  799. }
  800. else  break;
  801. }
  802. }
  803. else break;
  804. }
  805. }
  806. ///////////////////////////////////////////////////////////////////////////////
  807. int DecodeMCUBlock()
  808. {
  809. short *lpMCUBuffer;
  810. short i,j;
  811. int funcret;
  812. if (IntervalFlag){
  813. lp+=2;
  814. ycoef=ucoef=vcoef=0;
  815. BitPos=0;
  816. CurByte=0;
  817. }
  818. switch(comp_num){
  819. case 3:
  820. lpMCUBuffer=MCUBuffer;
  821. for (i=0;i<SampRate_Y_H*SampRate_Y_V;i++)  //Y
  822. {
  823. funcret=HufBlock(YDcIndex,YAcIndex);
  824. if (funcret!=FUNC_OK)
  825. return funcret;
  826. BlockBuffer[0]=BlockBuffer[0]+ycoef;
  827. ycoef=BlockBuffer[0];
  828. for (j=0;j<64;j++)
  829. *lpMCUBuffer++=BlockBuffer[j];
  830. }
  831. for (i=0;i<SampRate_U_H*SampRate_U_V;i++)  //U
  832. {
  833. funcret=HufBlock(UVDcIndex,UVAcIndex);
  834. if (funcret!=FUNC_OK)
  835. return funcret;
  836. BlockBuffer[0]=BlockBuffer[0]+ucoef;
  837. ucoef=BlockBuffer[0];
  838. for (j=0;j<64;j++)
  839. *lpMCUBuffer++=BlockBuffer[j];
  840. }
  841. for (i=0;i<SampRate_V_H*SampRate_V_V;i++)  //V
  842. {
  843. funcret=HufBlock(UVDcIndex,UVAcIndex);
  844. if (funcret!=FUNC_OK)
  845. return funcret;
  846. BlockBuffer[0]=BlockBuffer[0]+vcoef;
  847. vcoef=BlockBuffer[0];
  848. for (j=0;j<64;j++)
  849. *lpMCUBuffer++=BlockBuffer[j];
  850. }
  851. break;
  852. case 1:
  853. lpMCUBuffer=MCUBuffer;
  854. funcret=HufBlock(YDcIndex,YAcIndex);
  855. if (funcret!=FUNC_OK)
  856. return funcret;
  857. BlockBuffer[0]=BlockBuffer[0]+ycoef;
  858. ycoef=BlockBuffer[0];
  859. for (j=0;j<64;j++)
  860. *lpMCUBuffer++=BlockBuffer[j];
  861. for (i=0;i<128;i++)
  862. *lpMCUBuffer++=0;
  863. break;
  864. default:
  865. return FUNC_FORMAT_ERROR;
  866. }
  867. return FUNC_OK;
  868. }
  869. //////////////////////////////////////////////////////////////////
  870. int HufBlock(BYTE dchufindex,BYTE achufindex)
  871. {
  872. short count=0;
  873. short i;
  874. int funcret;
  875. //dc
  876. HufTabIndex=dchufindex;
  877. funcret=DecodeElement();
  878. if(funcret!=FUNC_OK)
  879. return funcret;
  880. BlockBuffer[count++]=vvalue;
  881. //ac
  882. HufTabIndex=achufindex;
  883. while (count<64){
  884. funcret=DecodeElement();
  885. if(funcret!=FUNC_OK)
  886. return funcret;
  887. if ((rrun==0)&&(vvalue==0)){
  888. for (i=count;i<64;i++)
  889. BlockBuffer[i]=0;
  890. count=64;
  891. }
  892. else{
  893. for (i=0;i<rrun;i++)
  894. BlockBuffer[count++]=0;
  895. BlockBuffer[count++]=vvalue;
  896. }
  897. }
  898. return FUNC_OK;
  899. }
  900. //////////////////////////////////////////////////////////////////////////////
  901. int DecodeElement()
  902. {
  903. int thiscode,tempcode;
  904. unsigned short temp,valueex;
  905. short codelen;
  906. BYTE hufexbyte,runsize,tempsize,sign;
  907. BYTE newbyte,lastbyte;
  908. if(BitPos>=1){
  909. BitPos--;
  910. thiscode=(BYTE)CurByte>>BitPos;
  911. CurByte=CurByte&And[BitPos];
  912. }
  913. else{
  914. lastbyte=ReadByte();
  915. BitPos--;
  916. newbyte=CurByte&And[BitPos];
  917. thiscode=lastbyte>>7;
  918. CurByte=newbyte;
  919. }
  920. codelen=1;
  921. while ((thiscode<huf_min_value[HufTabIndex][codelen-1])||
  922.   (code_len_table[HufTabIndex][codelen-1]==0)||
  923.   (thiscode>huf_max_value[HufTabIndex][codelen-1]))
  924. {
  925. if(BitPos>=1){
  926. BitPos--;
  927. tempcode=(BYTE)CurByte>>BitPos;
  928. CurByte=CurByte&And[BitPos];
  929. }
  930. else{
  931. lastbyte=ReadByte();
  932. BitPos--;
  933. newbyte=CurByte&And[BitPos];
  934. tempcode=(BYTE)lastbyte>>7;
  935. CurByte=newbyte;
  936. }
  937. thiscode=(thiscode<<1)+tempcode;
  938. codelen++;
  939. if(codelen>16)
  940. return FUNC_FORMAT_ERROR;
  941. }  //while
  942. temp=thiscode-huf_min_value[HufTabIndex][codelen-1]+code_pos_table[HufTabIndex][codelen-1];
  943. hufexbyte=(BYTE)code_value_table[HufTabIndex][temp];
  944. rrun=(short)(hufexbyte>>4);
  945. runsize=hufexbyte&0x0f;
  946. if(runsize==0){
  947. vvalue=0;
  948. return FUNC_OK;
  949. }
  950. tempsize=runsize;
  951. if(BitPos>=runsize){
  952. BitPos-=runsize;
  953. valueex=(BYTE)CurByte>>BitPos;
  954. CurByte=CurByte&And[BitPos];
  955. }
  956. else{
  957. valueex=CurByte;
  958. tempsize-=BitPos;
  959. while(tempsize>8){
  960. lastbyte=ReadByte();
  961. valueex=(valueex<<8)+(BYTE)lastbyte;
  962. tempsize-=8;
  963. }  //while
  964. lastbyte=ReadByte();
  965. BitPos-=tempsize;
  966. valueex=(valueex<<tempsize)+(lastbyte>>BitPos);
  967. CurByte=lastbyte&And[BitPos];
  968. }  //else
  969. sign=valueex>>(runsize-1);
  970. if(sign)
  971. vvalue=valueex;
  972. else{
  973. valueex=valueex^0xffff;
  974. temp=0xffff<<runsize;
  975. vvalue=-(short)(valueex^temp);
  976. }
  977. return FUNC_OK;
  978. }
  979. /////////////////////////////////////////////////////////////////////////////////////
  980. void IQtIZzMCUComponent(short flag)
  981. {
  982. short H,VV;
  983. short i,j;
  984. int *pQtZzMCUBuffer;
  985. short  *pMCUBuffer;
  986. switch(flag){
  987. case 0:
  988. H=SampRate_Y_H;
  989. VV=SampRate_Y_V;
  990. pMCUBuffer=MCUBuffer;
  991. pQtZzMCUBuffer=QtZzMCUBuffer;
  992. break;
  993. case 1:
  994. H=SampRate_U_H;
  995. VV=SampRate_U_V;
  996. pMCUBuffer=MCUBuffer+Y_in_MCU*64;
  997. pQtZzMCUBuffer=QtZzMCUBuffer+Y_in_MCU*64;
  998. break;
  999. case 2:
  1000. H=SampRate_V_H;
  1001. VV=SampRate_V_V;
  1002. pMCUBuffer=MCUBuffer+(Y_in_MCU+U_in_MCU)*64;
  1003. pQtZzMCUBuffer=QtZzMCUBuffer+(Y_in_MCU+U_in_MCU)*64;
  1004. break;
  1005. }
  1006. for(i=0;i<VV;i++)
  1007. for (j=0;j<H;j++)
  1008. IQtIZzBlock(pMCUBuffer+(i*H+j)*64,pQtZzMCUBuffer+(i*H+j)*64,flag);
  1009. }
  1010. //////////////////////////////////////////////////////////////////////////////////////////
  1011. void IQtIZzBlock(short  *s ,int * d,short flag)
  1012. {
  1013. short i,j;
  1014. short tag;
  1015. short *pQt;
  1016. int buffer2[8][8];
  1017. int *buffer1;
  1018. short offset;
  1019. switch(flag){
  1020. case 0:
  1021. pQt=YQtTable;
  1022. offset=128;
  1023. break;
  1024. case 1:
  1025. pQt=UQtTable;
  1026. offset=0;
  1027. break;
  1028. case 2:
  1029. pQt=VQtTable;
  1030. offset=0;
  1031. break;
  1032. }
  1033. for(i=0;i<8;i++)
  1034. for(j=0;j<8;j++){
  1035. tag=Zig_Zag[i][j];
  1036. buffer2[i][j]=(int)s[tag]*(int)pQt[tag];
  1037. }
  1038. buffer1=(int *)buffer2;
  1039. Fast_IDCT(buffer1);
  1040. for(i=0;i<8;i++)
  1041. for(j=0;j<8;j++)
  1042. d[i*8+j]=buffer2[i][j]+offset;
  1043. }
  1044. ///////////////////////////////////////////////////////////////////////////////
  1045. void Fast_IDCT(int * block)
  1046. {
  1047. short i;
  1048. for (i=0; i<8; i++)
  1049. idctrow(block+8*i);
  1050. for (i=0; i<8; i++)
  1051. idctcol(block+i);
  1052. }
  1053. ///////////////////////////////////////////////////////////////////////////////
  1054. BYTE  ReadByte()
  1055. {
  1056. BYTE  i;
  1057. i=*(lp++);
  1058. if(i==0xff)
  1059. lp++;
  1060. BitPos=8;
  1061. CurByte=i;
  1062. return i;
  1063. }
  1064. ///////////////////////////////////////////////////////////////////////
  1065. void Initialize_Fast_IDCT()
  1066. {
  1067. short i;
  1068. iclp = iclip+512;
  1069. for (i= -512; i<512; i++)
  1070. iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
  1071. }
  1072. ////////////////////////////////////////////////////////////////////////
  1073. void idctrow(int * blk)
  1074. {
  1075. int x0, x1, x2, x3, x4, x5, x6, x7, x8;
  1076. //intcut
  1077. if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
  1078. (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
  1079. {
  1080. blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
  1081. return;
  1082. }
  1083. x0 = (blk[0]<<11) + 128; // for proper rounding in the fourth stage 
  1084. //first stage
  1085. x8 = W7*(x4+x5);
  1086. x4 = x8 + (W1-W7)*x4;
  1087. x5 = x8 - (W1+W7)*x5;
  1088. x8 = W3*(x6+x7);
  1089. x6 = x8 - (W3-W5)*x6;
  1090. x7 = x8 - (W3+W5)*x7;
  1091. //second stage
  1092. x8 = x0 + x1;
  1093. x0 -= x1;
  1094. x1 = W6*(x3+x2);
  1095. x2 = x1 - (W2+W6)*x2;
  1096. x3 = x1 + (W2-W6)*x3;
  1097. x1 = x4 + x6;
  1098. x4 -= x6;
  1099. x6 = x5 + x7;
  1100. x5 -= x7;
  1101. //third stage
  1102. x7 = x8 + x3;
  1103. x8 -= x3;
  1104. x3 = x0 + x2;
  1105. x0 -= x2;
  1106. x2 = (181*(x4+x5)+128)>>8;
  1107. x4 = (181*(x4-x5)+128)>>8;
  1108. //fourth stage
  1109. blk[0] = (x7+x1)>>8;
  1110. blk[1] = (x3+x2)>>8;
  1111. blk[2] = (x0+x4)>>8;
  1112. blk[3] = (x8+x6)>>8;
  1113. blk[4] = (x8-x6)>>8;
  1114. blk[5] = (x0-x4)>>8;
  1115. blk[6] = (x3-x2)>>8;
  1116. blk[7] = (x7-x1)>>8;
  1117. }
  1118. //////////////////////////////////////////////////////////////////////////////
  1119. void idctcol(int * blk)
  1120. {
  1121. int x0, x1, x2, x3, x4, x5, x6, x7, x8;
  1122. //intcut
  1123. if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) |
  1124. (x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3])))
  1125. {
  1126. blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]
  1127. =blk[8*6]=blk[8*7]=iclp[(blk[8*0]+32)>>6];
  1128. return;
  1129. }
  1130. x0 = (blk[8*0]<<8) + 8192;
  1131. //first stage
  1132. x8 = W7*(x4+x5) + 4;
  1133. x4 = (x8+(W1-W7)*x4)>>3;
  1134. x5 = (x8-(W1+W7)*x5)>>3;
  1135. x8 = W3*(x6+x7) + 4;
  1136. x6 = (x8-(W3-W5)*x6)>>3;
  1137. x7 = (x8-(W3+W5)*x7)>>3;
  1138. //second stage
  1139. x8 = x0 + x1;
  1140. x0 -= x1;
  1141. x1 = W6*(x3+x2) + 4;
  1142. x2 = (x1-(W2+W6)*x2)>>3;
  1143. x3 = (x1+(W2-W6)*x3)>>3;
  1144. x1 = x4 + x6;
  1145. x4 -= x6;
  1146. x6 = x5 + x7;
  1147. x5 -= x7;
  1148. //third stage
  1149. x7 = x8 + x3;
  1150. x8 -= x3;
  1151. x3 = x0 + x2;
  1152. x0 -= x2;
  1153. x2 = (181*(x4+x5)+128)>>8;
  1154. x4 = (181*(x4-x5)+128)>>8;
  1155. //fourth stage
  1156. blk[8*0] = iclp[(x7+x1)>>14];
  1157. blk[8*1] = iclp[(x3+x2)>>14];
  1158. blk[8*2] = iclp[(x0+x4)>>14];
  1159. blk[8*3] = iclp[(x8+x6)>>14];
  1160. blk[8*4] = iclp[(x8-x6)>>14];
  1161. blk[8*5] = iclp[(x0-x4)>>14];
  1162. blk[8*6] = iclp[(x3-x2)>>14];
  1163. blk[8*7] = iclp[(x7-x1)>>14];
  1164. }