Display.cpp
上传用户:szklck
上传日期:2007-01-22
资源大小:925k
文件大小:12k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "视频编解码器.h"
  3. #include "Display.h"
  4. #ifdef _DEBUG
  5. #undef THIS_FILE
  6. static char THIS_FILE[]=__FILE__;
  7. #define new DEBUG_NEW
  8. #endif
  9. #define START 0
  10. #define STOP    5
  11. static unsigned char *dithered_image;
  12. static unsigned char ytab[256+16];
  13. static unsigned char utab[128+16];
  14. static unsigned char vtab[128+16];
  15. static unsigned char pixel[256];
  16. CDisplay::CDisplay()
  17. {
  18.       image  =NULL;
  19.       hPalPrev=NULL;
  20.       pbmi    =NULL;
  21. }
  22. CDisplay::~CDisplay()
  23. {
  24. }
  25.  unsigned char *refframe[3],*bframe[3],*newframe[3];
  26.  unsigned char *edgeframe[3], *edgeframeorig[3], *exnewframe[3];
  27.  extern unsigned char *oldrefframe[3];
  28.  int verbose,outtype,expand,refidct,trace;
  29.  CFile h263file;
  30.  CString outputname;
  31.  unsigned char *clp;
  32.  int MBC, MBR;
  33.  int horizontal_size,vertical_size,mb_width,mb_height;
  34.  int coded_picture_width, coded_picture_height;
  35.  int chrom_width,chrom_height,blk_cnt;
  36.  int pict_type,newgob,tr_framenum;
  37.  int matrix_coefficients,source_format;
  38.  extern ldecode *ld,base;
  39.  extern int quant;
  40.  void ditherframe(unsigned char *src[]);
  41. void CDisplay::play_movie(CDC *pDC,CString szFileName)
  42. {
  43. verbose = 0;
  44.     outtype = T_X11;  //结果输出类型
  45.     nDitherType=8;    //图像变换类型 每象素8比特
  46.     ld = &base;        
  47. trace = 0;   
  48. expand = 0; 
  49.     hDC=pDC->GetSafeHdc();
  50.     unsigned short gusState =START; 
  51.     int loopflag(0);
  52.     int framenum, first;
  53.     if ((base.infile=h263file.Open(szFileName,CFile::modeRead))==0)
  54. {   //打开263文件
  55. AfxMessageBox("Can not open input file!");
  56.     return;
  57. }
  58.     first = 1;
  59.     pDC->SetBkColor(0xffffff);
  60.     pDC->SetTextColor(RGB(255,100,0));
  61.     pDC->TextOut(480,50,"解码图像信息");
  62.     CString out;
  63.     int inum(0),pnum(0);
  64.     do
  65. {
  66.   if(first!=1)
  67.           h263file.Seek(0l,CFile::begin);//change
  68.       m_getbits.initbits();
  69.       framenum = tr_framenum = 0;
  70.     
  71.       while (m_gethdr.getheader())
  72.   {
  73.         if (first)//第一帧
  74. {
  75.           initdecoder();//初始化解码器
  76.   if (outtype==T_X11)
  77.   {
  78.             init_dither(nDitherType);//初始化显示图像的类型
  79.             init_display();          //初始化显示的调色板,bmp文件头
  80.   }
  81. pDC->TextOut(450,80,szPictureFormat);
  82.         out.Format("初始量化因子Q=%d   ",quant);
  83. pDC->TextOut(450,100,out);
  84.         first = 0;
  85. }
  86.     //开始解码图像
  87.     m_getpic.getpicture(&framenum);//解码一帧图象
  88.     out.Format("量化因子Q=%d    ",quant);
  89.         pDC->TextOut(450,120,out);
  90.     if(pict_type==0)
  91. {
  92.   out="该帧编码类型是:帧内";
  93.   inum++;
  94. }
  95.     else 
  96. {
  97.   out="该帧编码类型是:帧间";
  98.   pnum++;
  99. }
  100.     pDC->TextOut(450,140,out);
  101.         framenum++;
  102.     tr_framenum++;
  103.   
  104.         dither(refframe);//显示解码图像
  105.      
  106.     if (gusState==STOP) //控制显示
  107.           break;
  108.   }
  109. }
  110. while(loopflag);//结束
  111.     pDC->SetTextColor(RGB(255,255,100));
  112.     out.Format("共解码 %d 帧,其中I帧=%d(F),P帧=%d(F)",framenum,inum,pnum);
  113.     conclusion=out;
  114.     h263file.Close();
  115.     if (outtype==T_X11)//释放掉分配的空间
  116.       exit_display();
  117. toDeleteNewSpace();
  118. }
  119. /*****************************************************************************/
  120. //初始化解码器
  121. void CDisplay::initdecoder()
  122. {
  123.   int i, cc, size;
  124.   if (!(clp=new unsigned char[1024]))
  125.   {
  126.   AfxMessageBox("new failed!");
  127.       return;
  128.   }
  129.   clp += 384;
  130.   for (i=-384; i<640; i++) //区间[0,255]
  131.     clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
  132.   matrix_coefficients = 5;
  133.   if (source_format == SF_CIF) 
  134.   {  // 输入码流为 CIF
  135.     MBC = 22;
  136.     MBR = 18;
  137. szPictureFormat="图像格式是:352*288";
  138.   }
  139.   else if (source_format == SF_QCIF) 
  140.   {   // 输入码流为 QCIF
  141.     MBC = 11;
  142.     MBR = 9;
  143.    szPictureFormat="图像格式是:176*144";
  144.   }
  145.   else if (source_format == SF_SQCIF)
  146.   {  // 输入码流为 SQCIF
  147. MBC = 8;
  148.     MBR = 6;
  149.     szPictureFormat="图像格式是:120*96";
  150.   }
  151.   else
  152.     exit(1);
  153.   horizontal_size = MBC*16;
  154.   vertical_size = MBR*16;
  155.   mb_width = horizontal_size/16;
  156.   mb_height = vertical_size/16;
  157.   coded_picture_width = 16*mb_width;
  158.   coded_picture_height = 16*mb_height;
  159.   chrom_width =  coded_picture_width>>1;
  160.   chrom_height = coded_picture_height>>1;
  161.   blk_cnt = 6;
  162.      //初始化帧存储器
  163.   for (cc=0; cc<3; cc++)
  164.   {
  165.     if (cc==0)
  166.       size = coded_picture_width*coded_picture_height;
  167.     else
  168.       size = chrom_width*chrom_height;
  169.     if (!(refframe[cc] = new unsigned char[size]))
  170. {
  171. AfxMessageBox("new failed!");
  172. return;
  173. }
  174.     if (!(oldrefframe[cc] =new unsigned char[size]))
  175. {
  176. AfxMessageBox("new failed!");
  177. return;
  178. }
  179.     if (!(bframe[cc] =new unsigned char[size]))
  180. {
  181. AfxMessageBox("new failed!");
  182. return;
  183. }
  184.   }
  185.   for (cc=0; cc<3; cc++) 
  186.   {
  187.     if (cc==0) 
  188. {
  189.       size = (coded_picture_width+64)*(coded_picture_height+64);
  190.       if (!(edgeframeorig[cc] =new unsigned char[size]))
  191.   {
  192.   AfxMessageBox("new failed!");
  193.   return;
  194.   }
  195.       edgeframe[cc] = edgeframeorig[cc] + (coded_picture_width+64) * 32 + 32;
  196.     }
  197.     else
  198. {
  199.       size = (chrom_width+32)*(chrom_height+32);
  200.       if (!(edgeframeorig[cc] =new unsigned char[size]))
  201.   {
  202.   AfxMessageBox("new failed!");
  203.   return;
  204.   }
  205.       edgeframe[cc] = edgeframeorig[cc] + (chrom_width+32) * 16 + 16;
  206.     }
  207.   }
  208.   if (expand) 
  209.   {
  210.     for (cc=0; cc<3; cc++) 
  211. {
  212.       if (cc==0)
  213.      size = coded_picture_width*coded_picture_height*4;
  214.       else
  215.          size = chrom_width*chrom_height*4;
  216.       
  217.       if (!(exnewframe[cc] = new unsigned char[size]))
  218.   {
  219.   AfxMessageBox("new failed!");
  220.   return;
  221.   }
  222. }
  223.   } 
  224.   m_idct.init_idct();  // IDCT
  225. }
  226. /*****************************************************************************/
  227. void CDisplay::init_dither(int bpp)
  228. {
  229.   int i, v;
  230.   if ( bpp!=8 )
  231.   { 
  232.      AfxMessageBox("unsuported dither type!");
  233.      return;
  234.   }
  235.   bpp/=8;
  236.   int  size;
  237.   size=bpp*coded_picture_width*coded_picture_height;
  238.   if(!(dithered_image = new unsigned char[size]))
  239.   {
  240.   AfxMessageBox("new failed!");
  241.   return;
  242.   }
  243.   for (i=-8; i<256+8; i++)
  244.   {
  245.     v = i>>4;
  246.     if (v<1)
  247.       v = 1;
  248.     else if (v>14)
  249.       v = 14;
  250.     ytab[i+8] = v<<4;
  251.   }
  252.   for (i=0; i<128+16; i++)
  253.   {
  254.     v = (i-40)>>4;
  255.     if (v<0)
  256.       v = 0;
  257.     else if (v>3)
  258.       v = 3;
  259.     utab[i] = v<<2;
  260.     vtab[i] = v;
  261.   }
  262.   for (i=0; i<256; i++)
  263.      pixel[i]=i;
  264. }
  265. /*****************************************************************************/
  266. void CDisplay::init_display()//初始化显示,创建调色板
  267. {
  268.   pbmi= (PBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 240 * sizeof(RGBQUAD));
  269.   pbmi->bmiHeader.biSize = (LONG)sizeof(BITMAPINFOHEADER);
  270.   pbmi->bmiHeader.biPlanes = 1;
  271.   pbmi->bmiHeader.biCompression = 0l;
  272.   pbmi->bmiHeader.biSizeImage = 0l;
  273.   pbmi->bmiHeader.biXPelsPerMeter = 0l;
  274.   pbmi->bmiHeader.biYPelsPerMeter = 0l;
  275.   pbmi->bmiHeader.biClrUsed = 240;
  276.   pbmi->bmiHeader.biClrImportant = 240;
  277.   pbmi->bmiHeader.biBitCount = nDitherType;
  278.   pbmi->bmiHeader.biWidth = coded_picture_width ;
  279.   pbmi->bmiHeader.biHeight= coded_picture_height;
  280.   if ( pbmi->bmiHeader.biBitCount==8 )
  281.   {
  282.      // 8 BPP,建立调色板 
  283.      LOGPALETTE *plgpl;
  284.      short      *pPalIndex;
  285.      int         crv, cbu, cgu, cgv;
  286.      int         y, u, v;
  287.      int         i;
  288.      plgpl = (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + 240 * sizeof(PALETTEENTRY));
  289.      plgpl->palNumEntries = 240;
  290.      plgpl->palVersion = 0x300;
  291.      pPalIndex=(short *)pbmi->bmiColors;
  292.      // 矩阵参数 
  293.      crv = convmat[matrix_coefficients][0];
  294.      cbu = convmat[matrix_coefficients][1];
  295.      cgu = convmat[matrix_coefficients][2];
  296.      cgv = convmat[matrix_coefficients][3];
  297.      for (i=16; i<240; i++)
  298.      {
  299.        // 颜色空间转换
  300.        y = 16*((i>>4)&15) + 8;
  301.        u = 32*((i>>2)&3)  - 48;
  302.        v = 32*(i&3)       - 48;
  303.        y = 76309 * (y - 16); // (255/219)*65536 
  304.        plgpl->palPalEntry[i].peRed   = clp[(y + crv*v + 32768)>>16];
  305.        plgpl->palPalEntry[i].peGreen = clp[(y - cgu*u -cgv*v + 32768)>>16];
  306.        plgpl->palPalEntry[i].peBlue  = clp[(y + cbu*u + 32786)>>16];
  307.        pPalIndex[i]=i;
  308.      }
  309.      hpal = CreatePalette(plgpl);
  310.      free(plgpl);
  311.      hPalPrev=SelectPalette(hDC,hpal,FALSE);
  312.      RealizePalette(hDC);
  313.   }
  314. }
  315. /*****************************************************************************/
  316. void CDisplay::dither(unsigned char *src[])
  317. {
  318.   ditherframe(src);
  319.   SetDIBitsToDevice(hDC,60,60,coded_picture_width,
  320.                       coded_picture_height,
  321.                0,0,0,coded_picture_height,
  322.                 dithered_image,pbmi,DIB_PAL_COLORS);
  323.   
  324. }
  325. /*****************************************************************************/
  326. void ditherframe(unsigned char *src[])
  327. {
  328.   int i,j;
  329.   int y,u,v;
  330.   unsigned char *py,*pu,*pv,*dst;
  331.   py = src[0];
  332.   pu = src[1];
  333.   pv = src[2];
  334. #ifdef _WIN32
  335.   dst = dithered_image+(coded_picture_height-1)*coded_picture_width;
  336. #else
  337.   dst = dithered_image;
  338. #endif
  339.   for (j=0; j<coded_picture_height; j+=4)
  340.   {
  341.     // line j + 0 
  342.     for (i=0; i<coded_picture_width; i+=4)
  343.     {
  344.       y = *py++;
  345.       u = *pu++ >> 1;
  346.       v = *pv++ >> 1;
  347.       *dst++ = pixel[ytab[y]|utab[u]|vtab[v]];
  348.       y = *py++;
  349.       
  350.       *dst++ = pixel[ytab[y+8]|utab[u+8]|vtab[v+8]];
  351.       y = *py++;
  352.       u = *pu++ >> 1;
  353.       v = *pv++ >> 1;
  354.       *dst++ = pixel[ytab[y+2]|utab[u+2]|vtab[v+2]];
  355.       y = *py++;
  356.       
  357.       *dst++ = pixel[ytab[y+10]|utab[u+10]|vtab[v+10]];
  358.     }
  359.    
  360.     pu -= chrom_width;
  361.     pv -= chrom_width;
  362.   
  363. #ifdef _WIN32
  364.     dst -= 2*coded_picture_width;
  365. #endif
  366.     /* line j + 1 */
  367.     for (i=0; i<coded_picture_width; i+=4)
  368.     {
  369.       y = *py++;
  370.       u = *pu++ >> 1;
  371.       v = *pv++ >> 1;
  372.       *dst++ = pixel[ytab[y+12]|utab[u+12]|vtab[v+12]];
  373.       y = *py++;
  374.       
  375.       *dst++ = pixel[ytab[y+4]|utab[u+4]|vtab[v+4]];
  376.       y = *py++;
  377.       u = *pu++ >> 1;
  378.       v = *pv++ >> 1;
  379.       *dst++ = pixel[ytab[y+14]|utab[u+14]|vtab[v+14]];
  380.       y = *py++;
  381.       
  382.       *dst++ = pixel[ytab[y+6]|utab[u+6]|vtab[v+6]];
  383.     }
  384. #ifdef _WIN32
  385.     dst -= 2*coded_picture_width;
  386. #endif
  387.     // line j + 2 
  388.     for (i=0; i<coded_picture_width; i+=4)
  389.     {
  390.       y = *py++;
  391.       u = *pu++ >> 1;
  392.       v = *pv++ >> 1;
  393.       *dst++ = pixel[ytab[y+3]|utab[u+3]|vtab[v+3]];
  394.       y = *py++;
  395.       
  396.       *dst++ = pixel[ytab[y+11]|utab[u+11]|vtab[v+11]];
  397.       y = *py++;
  398.       u = *pu++ >> 1;
  399.       v = *pv++ >> 1;
  400.       *dst++ = pixel[ytab[y+1]|utab[u+1]|vtab[v+1]];
  401.       y = *py++;
  402.       
  403.       *dst++ = pixel[ytab[y+9]|utab[u+9]|vtab[v+9]];
  404.     }
  405.     pu -= chrom_width;
  406.     pv -= chrom_width;
  407.   
  408. #ifdef _WIN32
  409.     dst -= 2*coded_picture_width;
  410. #endif
  411.     // line j + 3 
  412.     for (i=0; i<coded_picture_width; i+=4)
  413.     {
  414.       y = *py++;
  415.       u = *pu++ >> 1;
  416.       v = *pv++ >> 1;
  417.       *dst++ = pixel[ytab[y+15]|utab[u+15]|vtab[v+15]];
  418.       y = *py++;
  419.      *dst++ = pixel[ytab[y+7]|utab[u+7]|vtab[v+7]];
  420.       y = *py++;
  421.       u = *pu++ >> 1;
  422.       v = *pv++ >> 1;
  423.       *dst++ = pixel[ytab[y+13]|utab[u+13]|vtab[v+13]];
  424.       y = *py++;
  425.       
  426.       *dst++ = pixel[ytab[y+5]|utab[u+5]|vtab[v+5]];
  427.     }
  428. #ifdef _WIN32
  429.     dst -= 2*coded_picture_width;
  430. #endif
  431.   }
  432. }
  433. /*****************************************************************************/
  434. //释放所分配的内存及调色板
  435. void CDisplay::exit_display()
  436. {
  437.    if (pbmi)
  438.    {
  439.       free(pbmi);
  440.       pbmi=NULL;
  441.    }
  442.    if (hPalPrev)
  443.    {
  444.        SelectPalette(hDC,hPalPrev,FALSE);
  445.        DeleteObject(hpal);
  446.        hPalPrev=NULL;
  447.    }
  448. }
  449. /*****************************************************************************/
  450. void CDisplay::toDeleteNewSpace()
  451. {
  452.     delete []clp;
  453. delete []dithered_image;
  454. for(int i=0;i<3;i++)
  455. {
  456.    delete []refframe[i];
  457.    delete []bframe[i];
  458.    delete []edgeframeorig[i];
  459.    if(expand) 
  460.      delete []exnewframe[i];
  461.        delete []oldrefframe[i];
  462. }
  463. }