Recon.cpp
上传用户:panstart
上传日期:2022-04-12
资源大小:199k
文件大小:22k
源码类别:

IP电话/视频会议

开发平台:

C++ Builder

  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. //    Project     : VideoNet version 1.1.
  5. //    Description : Peer to Peer Video Conferencing over the LAN.
  6. //   Author      : Nagareshwar Y Talekar ( nsry2002@yahoo.co.in)
  7. //    Date        : 15-6-2004.
  8. //
  9. //    This is the modified version of tmndecode (H.263 decoder) 
  10. //    written by Karl & Robert.It was in ANSI C. I have converted into C++
  11. //    so that it can be integrated into any windows application. I have 
  12. //    removed some of the files which had display and file storing 
  13. //    functions.I have removed the unnecessary code and also added some
  14. //    new files..
  15. //   Original library dealt with files. Input & Output , both were files.
  16. //    I have done some major changes so that it can be used for real time 
  17. //    decoding process. Now one can use this library for decoding H263 frames. 
  18. //
  19. //
  20. //    File description : 
  21. //    Name    :Recon.cpp
  22. //
  23. /////////////////////////////////////////////////////////////////////////////
  24. /************************************************************************
  25.  *
  26.  *  recon.c, motion compensation routines for tmndecode (H.263 decoder)
  27.  *  Copyright (C) 1996  Telenor R&D, Norway
  28.  *        Karl Olav Lillevold <Karl.Lillevold@nta.no>
  29.  *
  30.  *  This program is free software; you can redistribute it and/or modify
  31.  *  it under the terms of the GNU General Public License as published by
  32.  *  the Free Software Foundation; either version 2 of the License, or
  33.  *  (at your option) any later version.
  34.  *
  35.  *  This program is distributed in the hope that it will be useful,
  36.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  37.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  38.  *  GNU General Public License for more details.
  39.  *
  40.  *  You should have received a copy of the GNU General Public License
  41.  *  along with this program; if not, write to the Free Software
  42.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  43.  *
  44.  *  Karl Olav Lillevold               <Karl.Lillevold@nta.no>
  45.  *  Telenor Research and Development
  46.  *  P.O.Box 83                        tel.:   +47 63 84 84 00
  47.  *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76
  48.  *
  49.  *  Robert Danielsen                  e-mail: Robert.Danielsen@nta.no
  50.  *  Telenor Research and Development  www:    http://www.nta.no/brukere/DVC/
  51.  *  P.O.Box 83                        tel.:   +47 63 84 84 00
  52.  *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76
  53.  *  
  54.  ************************************************************************/
  55. /*
  56.  * based on mpeg2decode, (C) 1994, MPEG Software Simulation Group
  57.  * and mpeg2play, (C) 1994 Stefan Eckart
  58.  *                         <stefan@lis.e-technik.tu-muenchen.de>
  59.  *
  60.  */
  61. #include "Recon.h"
  62. void reconstruct(int bx,int by,int P,int bdx,int bdy)
  63. {
  64.   int w,h,lx,lx2,dx,dy,xp,yp,comp,sum;
  65.   int x,y,mode,xvec,yvec;
  66.   unsigned char *src[3];
  67.   x = bx/16+1; y = by/16+1;
  68.   lx = coded_picture_width;
  69.   if (mv_outside_frame) {
  70.     lx2 = coded_picture_width + 64;
  71.     src[0] = edgeframe[0];
  72.     src[1] = edgeframe[1];
  73.     src[2] = edgeframe[2];
  74.   }
  75.   else {
  76.     lx2 = coded_picture_width;
  77.     src[0] = oldrefframe[0];
  78.     src[1] = oldrefframe[1];
  79.     src[2] = oldrefframe[2];
  80.   }
  81.   mode = modemap[y][x];
  82.   if (P) {
  83.     /* P prediction */
  84.     if (adv_pred_mode) {
  85.       w = 8; h = 8;
  86.       /* Y*/
  87.       for (comp = 0; comp < 4; comp++) {
  88.         xp = bx + ((comp&1)<<3);
  89.         yp = by + ((comp&2)<<2);
  90.         recon_comp_obmc(src[0],newframe[0], lx,lx2,comp,w,h,xp,yp);
  91.       }
  92.       if (mode == MODE_INTER4V) {
  93.         sum = MV[0][1][y][x]+MV[0][2][y][x]+ MV[0][3][y][x]+MV[0][4][y][x];
  94.         dx = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
  95.         sum = MV[1][1][y][x]+MV[1][2][y][x]+ MV[1][3][y][x]+MV[1][4][y][x];
  96.         dy = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
  97.       }
  98.       else {
  99.         dx = MV[0][0][y][x];
  100.         dy = MV[1][0][y][x];
  101.         /* chroma rounding */
  102.         dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
  103.         dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
  104.       }
  105.       lx>>=1;bx>>=1; lx2>>=1; 
  106.       by>>=1;
  107.       /* Chroma */
  108.       recon_comp(src[1],newframe[1], lx,lx2,w,h,bx,by,dx,dy,1);
  109.       recon_comp(src[2],newframe[2], lx,lx2,w,h,bx,by,dx,dy,2);
  110.     }
  111.     else { /* normal prediction mode */
  112.       /* P prediction */
  113.       w = 16; h = 16;
  114.       dx = MV[0][0][y][x];
  115.       dy = MV[1][0][y][x];
  116.       
  117.       /* Y */
  118.       recon_comp(src[0],newframe[0], lx,lx2,w,h,bx,by,dx,dy,0);
  119.       
  120.       lx>>=1; w>>=1; bx>>=1; lx2>>=1; 
  121.       h>>=1; by>>=1;  
  122.       /* chroma rounding */
  123.       dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
  124.       dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
  125.       /* Chroma */
  126.       recon_comp(src[1],newframe[1], lx,lx2,w,h,bx,by,dx,dy,1);
  127.       recon_comp(src[2],newframe[2], lx,lx2,w,h,bx,by,dx,dy,2);
  128.     }
  129.   }
  130.   else {
  131.     /* B forward prediction */
  132.     if (adv_pred_mode) {
  133.       if (mode == MODE_INTER4V) {
  134.         w = 8; h = 8;
  135.         /* Y*/
  136.         xvec = yvec = 0;
  137.         for (comp = 0; comp < 4; comp++) {
  138.           xvec += dx = (trb)*MV[0][comp+1][y][x]/trd + bdx;
  139.           yvec += dy = (trb)*MV[1][comp+1][y][x]/trd + bdy;
  140.           xp = bx + ((comp&1)<<3);
  141.           yp = by + ((comp&2)<<2);
  142.           recon_comp(src[0],bframe[0], lx,lx2,w,h,xp,yp,dx,dy,0);
  143.         }
  144.         /* chroma rounding (table 16/H.263) */
  145.         dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  146.         dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  147.         lx>>=1;bx>>=1; lx2>>=1;
  148.         by>>=1;
  149.         /* Chroma */
  150.         recon_comp(src[1],bframe[1], lx,lx2,w,h,bx,by,dx,dy,1);
  151.         recon_comp(src[2],bframe[2], lx,lx2,w,h,bx,by,dx,dy,2);
  152.       }
  153.       else {  /* adv_pred_mode but 16x16 vector */
  154.         w = 16; h = 16;
  155.         dx = (trb)*MV[0][0][y][x]/trd + bdx;
  156.         dy = (trb)*MV[1][0][y][x]/trd + bdy;
  157.         /* Y */
  158.         recon_comp(src[0],bframe[0], lx,lx2,w,h,bx,by,dx,dy,0);
  159.         
  160.         lx>>=1; w>>=1; bx>>=1; lx2>>=1;
  161.         h>>=1; by>>=1;  
  162.         xvec = 4*dx;
  163.         yvec = 4*dy;
  164.         /* chroma rounding (table 16/H.263) */
  165.         dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  166.         dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  167.         /* Chroma */
  168.         recon_comp(src[1],bframe[1], lx,lx2,w,h,bx,by,dx,dy,1);
  169.         recon_comp(src[2],bframe[2], lx,lx2,w,h,bx,by,dx,dy,2);
  170.       }
  171.     }
  172.     else { /* normal B forward prediction */
  173.       w = 16; h = 16;
  174.       dx = (trb)*MV[0][0][y][x]/trd + bdx;
  175.       dy = (trb)*MV[1][0][y][x]/trd + bdy;
  176.       /* Y */
  177.       recon_comp(src[0],bframe[0], lx,lx2,w,h,bx,by,dx,dy,0);
  178.       lx>>=1; w>>=1; bx>>=1; lx2>>=1;
  179.       h>>=1; by>>=1;  
  180.       xvec = 4*dx;
  181.       yvec = 4*dy;
  182.       /* chroma rounding (table 16/H.263) */ 
  183.       dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  184.       dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  185.       /* Chroma */
  186.       recon_comp(src[1],bframe[1], lx,lx2,w,h,bx,by,dx,dy,1);
  187.       recon_comp(src[2],bframe[2], lx,lx2,w,h,bx,by,dx,dy,2);
  188.     }
  189.   }
  190. }
  191. static void recon_comp(unsigned char* src,unsigned char* dst,int lx,int lx2,int w,int h,int x,int y,int dx,int dy,int chroma)
  192. {
  193.   int xint, xh, yint, yh;
  194.   unsigned char *s, *d;
  195.   xint = dx>>1;
  196.   xh = dx & 1;
  197.   yint = dy>>1;
  198.   yh = dy & 1;
  199.   /* origins */
  200.   s = src + lx2*(y+yint) + x + xint;
  201.   d = dst + lx*y + x;
  202.   if (!xh && !yh)
  203.     if (w!=8)
  204.       rec(s,d,lx,lx2,h);
  205.     else
  206.       recc(s,d,lx,lx2,h);
  207.   else if (!xh && yh)
  208.     if (w!=8)
  209.       recv(s,d,lx,lx2,h);
  210.     else 
  211.       recvc(s,d,lx,lx2,h);
  212.   else if (xh && !yh)
  213.     if (w!=8)
  214.       rech(s,d,lx,lx2,h);
  215.     else
  216.       rechc(s,d,lx,lx2,h);
  217.   else /* if (xh && yh) */
  218.     if (w!=8)
  219.       rec4(s,d,lx,lx2,h);
  220.     else
  221.       rec4c(s,d,lx,lx2,h);
  222. }
  223. static void rec(unsigned char* s,unsigned char* d,int lx,int lx2,int h)
  224. {
  225.   int j;
  226.   for (j=0; j<h; j++)
  227.   {
  228.     d[0] = s[0];
  229.     d[1] = s[1];
  230.     d[2] = s[2];
  231.     d[3] = s[3];
  232.     d[4] = s[4];
  233.     d[5] = s[5];
  234.     d[6] = s[6];
  235.     d[7] = s[7];
  236.     d[8] = s[8];
  237.     d[9] = s[9];
  238.     d[10] = s[10];
  239.     d[11] = s[11];
  240.     d[12] = s[12];
  241.     d[13] = s[13];
  242.     d[14] = s[14];
  243.     d[15] = s[15];
  244.     s+= lx2;
  245.     d+= lx;
  246.   }
  247. }
  248. static void recc(unsigned char* s,unsigned char* d,int lx,int lx2,int h)
  249. {
  250.   int j;
  251.   for (j=0; j<h; j++)
  252.   {
  253.     d[0] = s[0];
  254.     d[1] = s[1];
  255.     d[2] = s[2];
  256.     d[3] = s[3];
  257.     d[4] = s[4];
  258.     d[5] = s[5];
  259.     d[6] = s[6];
  260.     d[7] = s[7];
  261.     s+= lx2;
  262.     d+= lx;
  263.   }
  264. }
  265. static void reco(unsigned char* s,int *d,int lx,int lx2,int addflag,int c,int xa,int xb,int ya,int yb)
  266. {
  267.   int i,j;
  268.   int *om;
  269.   om = &OM[c][ya][0];
  270.   if (!addflag) {
  271.     for (j = ya; j < yb; j++) {
  272.       for (i = xa; i < xb; i++) {
  273.         d[i] = s[i] * om[i];
  274.       }
  275.       s+= lx2;
  276.       d+= lx;
  277.       om+= 8;
  278.     }
  279.   }
  280.   else {
  281.     for (j = ya; j < yb; j++) {
  282.       for (i = xa; i < xb; i++) {
  283.         d[i] += s[i] * om[i];
  284.       }
  285.       s+= lx2;
  286.       d+= lx;
  287.       om+= 8;
  288.     }
  289.   }
  290. }
  291. static void rech(unsigned char* s,unsigned char* d,int lx,int lx2,int h)
  292. {
  293.   unsigned char *dp,*sp;
  294.   int j;
  295.   unsigned int s1,s2;
  296.   sp = s;
  297.   dp = d;
  298.   for (j=0; j<h; j++)
  299.   {
  300.     s1=sp[0];
  301.     dp[0] = (unsigned int)(s1+(s2=sp[1])+1)>>1;
  302.     dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1;
  303.     dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1;
  304.     dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1;
  305.     dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1;
  306.     dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1;
  307.     dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1;
  308.     dp[7] = (unsigned int)(s2+(s1=sp[8])+1)>>1;
  309.     dp[8] = (unsigned int)(s1+(s2=sp[9])+1)>>1;
  310.     dp[9] = (unsigned int)(s2+(s1=sp[10])+1)>>1;
  311.     dp[10] = (unsigned int)(s1+(s2=sp[11])+1)>>1;
  312.     dp[11] = (unsigned int)(s2+(s1=sp[12])+1)>>1;
  313.     dp[12] = (unsigned int)(s1+(s2=sp[13])+1)>>1;
  314.     dp[13] = (unsigned int)(s2+(s1=sp[14])+1)>>1;
  315.     dp[14] = (unsigned int)(s1+(s2=sp[15])+1)>>1;
  316.     dp[15] = (unsigned int)(s2+sp[16]+1)>>1;
  317.     sp+= lx2;
  318.     dp+= lx;
  319.   }
  320. }
  321. static void rechc(unsigned char* s,unsigned char* d,int lx,int lx2,int h)
  322. {
  323.   unsigned char *dp,*sp;
  324.   int j;
  325.   unsigned int s1,s2;
  326.   sp = s;
  327.   dp = d;
  328.   for (j=0; j<h; j++)
  329.   {
  330.     s1=sp[0];
  331.     dp[0] = (unsigned int)(s1+(s2=sp[1])+1)>>1;
  332.     dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1;
  333.     dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1;
  334.     dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1;
  335.     dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1;
  336.     dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1;
  337.     dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1;
  338.     dp[7] = (unsigned int)(s2+sp[8]+1)>>1;
  339.     sp+= lx2;
  340.     dp+= lx;
  341.   }
  342. }
  343. static void recho(unsigned char* s,int *d,int lx,int lx2,int addflag,int c,int xa,int xb,int ya,int yb)
  344. {
  345.   int *dp,*om;
  346.   unsigned char *sp;
  347.   int i,j;
  348.   sp = s;
  349.   dp = d;
  350.   om = &OM[c][ya][0];
  351.   if (!addflag) {
  352.     for (j = ya; j < yb; j++) {
  353.       for (i = xa; i < xb; i++) {
  354.         dp[i] = (((unsigned int)(sp[i] + sp[i+1]+1))>>1)*om[i];
  355.       }
  356.       sp+= lx2;
  357.       dp+= lx;
  358.       om+= 8;
  359.     }
  360.   }
  361.   else {
  362.     for (j = ya; j < yb; j++) {
  363.       for (i = xa; i < xb; i++) {
  364.         dp[i] += (((unsigned int)(sp[i] + sp[i+1]+1))>>1)*OM[c][j][i];
  365.       }
  366.       sp+= lx2;
  367.       dp+= lx;
  368.       om+= 8;
  369.     }
  370.   }
  371. }
  372. static void recv(unsigned char* s,unsigned char* d,int lx,int lx2,int h)
  373. {
  374.   unsigned char *dp,*sp,*sp2;
  375.   int j;
  376.   sp = s;
  377.   sp2 = s+lx2;
  378.   dp = d;
  379.   for (j=0; j<h; j++)
  380.   {
  381.     dp[0] = (unsigned int)(sp[0]+sp2[0]+1)>>1;
  382.     dp[1] = (unsigned int)(sp[1]+sp2[1]+1)>>1;
  383.     dp[2] = (unsigned int)(sp[2]+sp2[2]+1)>>1;
  384.     dp[3] = (unsigned int)(sp[3]+sp2[3]+1)>>1;
  385.     dp[4] = (unsigned int)(sp[4]+sp2[4]+1)>>1;
  386.     dp[5] = (unsigned int)(sp[5]+sp2[5]+1)>>1;
  387.     dp[6] = (unsigned int)(sp[6]+sp2[6]+1)>>1;
  388.     dp[7] = (unsigned int)(sp[7]+sp2[7]+1)>>1;
  389.     dp[8] = (unsigned int)(sp[8]+sp2[8]+1)>>1;
  390.     dp[9] = (unsigned int)(sp[9]+sp2[9]+1)>>1;
  391.     dp[10] = (unsigned int)(sp[10]+sp2[10]+1)>>1;
  392.     dp[11] = (unsigned int)(sp[11]+sp2[11]+1)>>1;
  393.     dp[12] = (unsigned int)(sp[12]+sp2[12]+1)>>1;
  394.     dp[13] = (unsigned int)(sp[13]+sp2[13]+1)>>1;
  395.     dp[14] = (unsigned int)(sp[14]+sp2[14]+1)>>1;
  396.     dp[15] = (unsigned int)(sp[15]+sp2[15]+1)>>1;
  397.     sp+= lx2;
  398.     sp2+= lx2;
  399.     dp+= lx;
  400.   }
  401. }
  402. static void recvc(unsigned char* s,unsigned char* d,int lx,int lx2,int h)
  403. {
  404.   unsigned char *dp,*sp,*sp2;
  405.   int j;
  406.   sp = s;
  407.   sp2 = s+lx2;
  408.   dp = d;
  409.   for (j=0; j<h; j++)
  410.   {
  411.     dp[0] = (unsigned int)(sp[0]+sp2[0]+1)>>1;
  412.     dp[1] = (unsigned int)(sp[1]+sp2[1]+1)>>1;
  413.     dp[2] = (unsigned int)(sp[2]+sp2[2]+1)>>1;
  414.     dp[3] = (unsigned int)(sp[3]+sp2[3]+1)>>1;
  415.     dp[4] = (unsigned int)(sp[4]+sp2[4]+1)>>1;
  416.     dp[5] = (unsigned int)(sp[5]+sp2[5]+1)>>1;
  417.     dp[6] = (unsigned int)(sp[6]+sp2[6]+1)>>1;
  418.     dp[7] = (unsigned int)(sp[7]+sp2[7]+1)>>1;
  419.     sp+= lx2;
  420.     sp2+= lx2;
  421.     dp+= lx;
  422.   }
  423. }
  424. static void recvo(unsigned char* s,int *d,int lx,int lx2,int addflag,int c,int xa,int xb,int ya,int yb)
  425. {
  426.   int *dp,*om;
  427.   unsigned char *sp,*sp2;
  428.   int i,j;
  429.   sp = s;
  430.   sp2 = s+lx2;
  431.   dp = d;
  432.   om = &OM[c][ya][0];
  433.   if (!addflag) {
  434.     for (j = ya; j < yb; j++) {
  435.       for (i = xa; i < xb; i++) {
  436.         dp[i] = (((unsigned int)(sp[i] + sp2[i]+1))>>1)*om[i];
  437.       }
  438.       sp+= lx2;
  439.       sp2+= lx2;
  440.       dp+= lx;
  441.       om+= 8;
  442.     }
  443.   }
  444.   else {
  445.     for (j = ya; j < yb; j++) {
  446.       for (i = xa; i < xb; i++) {
  447.         dp[i] += (((unsigned int)(sp[i] + sp2[i]+1))>>1)*om[i];
  448.       }
  449.       sp+= lx2;
  450.       sp2+= lx2;
  451.       dp+= lx;
  452.       om+= 8;
  453.     }
  454.   }
  455. }
  456. static void rec4(unsigned char* s,unsigned char* d,int lx,int lx2,int h)
  457. {
  458.   unsigned char *dp,*sp,*sp2;
  459.   int j;
  460.   unsigned int s1,s2,s3,s4;
  461.   sp = s;
  462.   sp2 = s+lx2;
  463.   dp = d;
  464.   for (j=0; j<h; j++)
  465.   {
  466.     s1=sp[0]; s3=sp2[0];
  467.     dp[0] = (unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2;
  468.     dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2;
  469.     dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2;
  470.     dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2;
  471.     dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2;
  472.     dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2;
  473.     dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2;
  474.     dp[7] = (unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2;
  475.     dp[8] = (unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2;
  476.     dp[9] = (unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2;
  477.     dp[10] = (unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2;
  478.     dp[11] = (unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2;
  479.     dp[12] = (unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2;
  480.     dp[13] = (unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2;
  481.     dp[14] = (unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2;
  482.     dp[15] = (unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2;
  483.     sp+= lx2;
  484.     sp2+= lx2;
  485.     dp+= lx;
  486.   }
  487. }
  488. static void rec4c(unsigned char *s ,unsigned char *d,int lx,int lx2,int h)
  489. {
  490.   unsigned char *dp,*sp,*sp2;
  491.   int j;
  492.   unsigned int s1,s2,s3,s4;
  493.   sp = s;
  494.   sp2 = s+lx2;
  495.   dp = d;
  496.   for (j=0; j<h; j++)
  497.   {
  498.     s1=sp[0]; s3=sp2[0];
  499.     dp[0] = (unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2;
  500.     dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2;
  501.     dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2;
  502.     dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2;
  503.     dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2;
  504.     dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2;
  505.     dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2;
  506.     dp[7] = (unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2;
  507.     sp+= lx2;
  508.     sp2+= lx2;
  509.     dp+= lx;
  510.   }
  511. }
  512. static void rec4o(unsigned char* s,int *d,int lx,int lx2,int addflag,int c,int xa,int xb,int ya,int yb)
  513. {
  514.   int *dp,*om;
  515.   unsigned char *sp,*sp2;
  516.   int i,j;
  517.   sp = s;
  518.   sp2 = s+lx2;
  519.   dp = d;
  520.   om = &OM[c][ya][0];
  521.   if (!addflag) {
  522.     for (j = ya; j < yb; j++) {
  523.       for (i = xa; i < xb; i++) {
  524.         dp[i] = (((unsigned int)(sp[i]+sp2[i]+sp[i+1]+sp2[i+1]+2))>>2)*om[i];
  525.       }
  526.       sp+= lx2;
  527.       sp2+= lx2;
  528.       dp+= lx;
  529.       om+= 8;
  530.     }
  531.   }
  532.   else {
  533.     for (j = ya; j < yb; j++) {
  534.       for (i = xa; i < xb; i++) {
  535.         dp[i] += (((unsigned int)(sp[i]+sp2[i]+sp[i+1]+sp2[i+1]+2))>>2)*om[i];
  536.       }
  537.       sp+= lx2;
  538.       sp2+= lx2;
  539.       dp+= lx;
  540.       om += 8;
  541.     }
  542.   }
  543. }
  544. static void recon_comp_obmc(unsigned char* src,unsigned char* dst,int lx,int lx2,int comp,int w,int h,int x,int y)
  545. {
  546.   int j,k;
  547.   int xmb,ymb;
  548.   int c8,t8,l8,r8;
  549.   int ti8,li8,ri8;
  550.   int xit,xib,xir,xil;
  551.   int yit,yib,yir,yil;
  552.   int vect,vecb,vecr,vecl;
  553.   int nx[5],ny[5],xint[5],yint[5],xh[5],yh[5];
  554.   int p[64],*pd;
  555.   unsigned char *d,*s[5];
  556.   xmb = (x>>4)+1;
  557.   ymb = (y>>4)+1;
  558.   c8  = (modemap[ymb][xmb] == MODE_INTER4V ? 1 : 0);
  559.   t8  = (modemap[ymb-1][xmb] == MODE_INTER4V ? 1 : 0);
  560.   ti8 = (modemap[ymb-1][xmb] == MODE_INTRA ? 1 : 0);
  561.   ti8 = (modemap[ymb-1][xmb] == MODE_INTRA_Q ? 1 : ti8);
  562.   l8  = (modemap[ymb][xmb-1] == MODE_INTER4V ? 1 : 0);
  563.   li8 = (modemap[ymb][xmb-1] == MODE_INTRA ? 1 : 0);
  564.   li8 = (modemap[ymb][xmb-1] == MODE_INTRA_Q ? 1 : li8);
  565.   
  566.   r8  = (modemap[ymb][xmb+1] == MODE_INTER4V ? 1 : 0);
  567.   ri8 = (modemap[ymb][xmb+1] == MODE_INTRA ? 1 : 0);
  568.   ri8 = (modemap[ymb][xmb+1] == MODE_INTRA_Q ? 1 : ri8);
  569.   if (pb_frame) {
  570.     ti8 = li8 = ri8 = 0;
  571.   }
  572.   switch (comp+1) {
  573.   case 1:
  574.     vect = (ti8 ? (c8 ? 1 : 0) : (t8 ? 3 : 0)); 
  575.     yit  = (ti8 ? ymb : ymb - 1); 
  576.     xit = xmb;
  577.     vecb = (c8 ? 3 : 0) ; yib = ymb; xib = xmb;
  578.     vecl = (li8 ? (c8 ? 1 : 0) : (l8 ? 2 : 0)); 
  579.     yil = ymb; 
  580.     xil = (li8 ? xmb : xmb-1);
  581.     vecr = (c8 ? 2 : 0) ; yir = ymb; xir = xmb;
  582.     /* edge handling */
  583.     if (ymb == 1) {
  584.       yit = ymb;
  585.       vect = (c8 ? 1 : 0);
  586.     }
  587.     if (xmb == 1) {
  588.       xil = xmb;
  589.       vecl = (c8 ? 1 : 0);
  590.     }
  591.     break;
  592.   
  593.   case 2:
  594.     vect = (ti8 ? (c8 ? 2 : 0) : (t8 ? 4 : 0)); 
  595.     yit = (ti8 ? ymb : ymb-1); 
  596.     xit = xmb;
  597.     vecb = (c8 ? 4 : 0) ; yib = ymb; xib = xmb;
  598.     vecl = (c8 ? 1 : 0) ; yil = ymb; xil = xmb;
  599.     vecr = (ri8 ? (c8 ? 2 : 0) : (r8 ? 1 : 0)); 
  600.     yir = ymb; 
  601.     xir = (ri8 ? xmb : xmb+1);
  602.     /* edge handling */
  603.     if (ymb == 1) {
  604.       yit = ymb;
  605.       vect = (c8 ? 2 : 0);
  606.     }
  607.     if (xmb == mb_width) {
  608.       xir = xmb;
  609.       vecr = (c8 ? 2 : 0);
  610.     }
  611.     break;
  612.   case 3:
  613.     vect = (c8 ? 1 : 0) ; yit = ymb  ; xit = xmb;
  614.     vecb = (c8 ? 3 : 0) ; yib = ymb  ; xib = xmb;
  615.       
  616.     vecl = (li8 ? (c8 ? 3 : 0) : (l8 ? 4 : 0)); 
  617.     yil = ymb;  
  618.     xil = (li8 ? xmb : xmb-1);
  619.     
  620.     vecr = (c8 ? 4 : 0) ; yir = ymb  ; xir = xmb;
  621.     /* edge handling */
  622.     if (xmb == 1) {
  623.       xil = xmb;
  624.       vecl = (c8 ? 3 : 0);
  625.     }
  626.     break;
  627.   case 4:
  628.     vect = (c8 ? 2 : 0) ; yit = ymb  ; xit = xmb;
  629.     vecb = (c8 ? 4 : 0) ; yib = ymb  ; xib = xmb;
  630.     vecl = (c8 ? 3 : 0) ; yil = ymb  ; xil = xmb;
  631.     vecr = (ri8 ? (c8 ? 4 : 0) : (r8 ? 3 : 0)); 
  632.     yir = ymb; 
  633.     xir = (ri8 ? xmb : xmb+1);
  634.     /* edge handling */
  635.     if (xmb == mb_width) {
  636.       xir = xmb;
  637.       vecr = (c8 ? 4 : 0);
  638.     }
  639.     break;
  640.   default:
  641.     if(trace)
  642. fputs("Illegal block number in recon_comp_obmc (recon.c)n",dlog);
  643.     return;
  644.     break;
  645.   }
  646.   nx[0] = MV[0][c8 ? comp + 1 : 0][ymb][xmb];
  647.   ny[0] = MV[1][c8 ? comp + 1 : 0][ymb][xmb];
  648.   
  649.   nx[1] = MV[0][vect][yit][xit]; ny[1] = MV[1][vect][yit][xit];
  650.   nx[2] = MV[0][vecb][yib][xib]; ny[2] = MV[1][vecb][yib][xib];
  651.   nx[3] = MV[0][vecr][yir][xir]; ny[3] = MV[1][vecr][yir][xir];
  652.   nx[4] = MV[0][vecl][yil][xil]; ny[4] = MV[1][vecl][yil][xil];
  653.   for (k = 0; k < 5; k++) {
  654.     xint[k] = nx[k]>>1;
  655.     xh[k] = nx[k] & 1;
  656.     yint[k] = ny[k]>>1;
  657.     yh[k] = ny[k] & 1;
  658.     s[k] = src + lx2*(y+yint[k]) + x + xint[k];
  659.   }
  660.   
  661.   d = dst + lx*y + x;
  662.   if (!xh[0] && !yh[0])
  663.     reco(s[0],&p[0],8,lx2,0,0,0,8,0,8);
  664.   else if (!xh[0] && yh[0])
  665.     recvo(s[0],&p[0],8,lx2,0,0,0,8,0,8);
  666.   else if (xh[0] && !yh[0])
  667.     recho(s[0],&p[0],8,lx2,0,0,0,8,0,8);
  668.   else /* if (xh[] && yh[]) */
  669.     rec4o(s[0],&p[0],8,lx2,0,0,0,8,0,8);
  670.   if (!xh[1] && !yh[1])
  671.     reco(s[1],&p[0],8,lx2,1,1,0,8,0,4);
  672.   else if (!xh[1] && yh[1])
  673.     recvo(s[1],&p[0],8,lx2,1,1,0,8,0,4);
  674.   else if (xh[1] && !yh[1])
  675.     recho(s[1],&p[0],8,lx2,1,1,0,8,0,4);
  676.   else /* if (xh[] && yh[]) */
  677.     rec4o(s[1],&p[0],8,lx2,1,1,0,8,0,4);
  678.   if (!xh[2] && !yh[2])
  679.     reco(s[2]+(lx2<<2),&p[32],8,lx2,1,2,0,8,4,8);
  680.   else if (!xh[2] && yh[2])
  681.     recvo(s[2]+(lx2<<2),&p[32],8,lx2,1,2,0,8,4,8);
  682.   else if (xh[2] && !yh[2])
  683.     recho(s[2]+(lx2<<2),&p[32],8,lx2,1,2,0,8,4,8);
  684.   else /* if (xh[] && yh[]) */
  685.     rec4o(s[2]+(lx2<<2),&p[32],8,lx2,1,2,0,8,4,8);
  686.   if (!xh[3] && !yh[3])
  687.     reco(s[3],&p[0],8,lx2,1,3,4,8,0,8);
  688.   else if (!xh[3] && yh[3])
  689.     recvo(s[3],&p[0],8,lx2,1,3,4,8,0,8);
  690.   else if (xh[3] && !yh[3])
  691.     recho(s[3],&p[0],8,lx2,1,3,4,8,0,8);
  692.   else /* if (xh[] && yh[]) */
  693.     rec4o(s[3],&p[0],8,lx2,1,3,4,8,0,8);
  694.   if (!xh[4] && !yh[4])
  695.     reco(s[4],&p[0],8,lx2,1,4,0,4,0,8);
  696.   else if (!xh[4] && yh[4])
  697.     recvo(s[4],&p[0],8,lx2,1,4,0,4,0,8);
  698.   else if (xh[4] && !yh[4])
  699.     recho(s[4],&p[0],8,lx2,1,4,0,4,0,8);
  700.   else /* if (xh[] && yh[]) */
  701.     rec4o(s[4],&p[0],8,lx2,1,4,0,4,0,8);
  702.   pd = &p[0];
  703.   for (j = 0; j < 8; j++) {
  704.     d[0] = (pd[0] + 4 )>>3;
  705.     d[1] = (pd[1] + 4 )>>3;
  706.     d[2] = (pd[2] + 4 )>>3;
  707.     d[3] = (pd[3] + 4 )>>3;
  708.     d[4] = (pd[4] + 4 )>>3;
  709.     d[5] = (pd[5] + 4 )>>3;
  710.     d[6] = (pd[6] + 4 )>>3;
  711.     d[7] = (pd[7] + 4 )>>3;
  712.     d += lx;
  713.     pd += 8;
  714.   }
  715. }