Main Page | File List

RECON.C

00001 /************************************************************************
00002  *
00003  *  recon.c, motion compensation routines for tmndecode (H.263 decoder)
00004  *  Copyright (C) 1995, 1996  Telenor R&D, Norway
00005  *
00006  *  Contacts:
00007  *  Robert Danielsen                  <Robert.Danielsen@nta.no>
00008  *
00009  *  Telenor Research and Development  http://www.nta.no/brukere/DVC/
00010  *  P.O.Box 83                        tel.:   +47 63 84 84 00
00011  *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76
00012  *
00013  *  Copyright (C) 1997  University of BC, Canada
00014  *  Modified by: Michael Gallant <mikeg@ee.ubc.ca>
00015  *               Guy Cote <guyc@ee.ubc.ca>
00016  *               Berna Erol <bernae@ee.ubc.ca>
00017  *
00018  *  Contacts:
00019  *  Michael Gallant                   <mikeg@ee.ubc.ca>
00020  *
00021  *  UBC Image Processing Laboratory   http://www.ee.ubc.ca/image
00022  *  2356 Main Mall                    tel.: +1 604 822 4051
00023  *  Vancouver BC Canada V6T1Z4        fax.: +1 604 822 5949
00024  *
00025  ************************************************************************/
00026 
00027 /* Disclaimer of Warranty
00028  * 
00029  * These software programs are available to the user without any license fee
00030  * or royalty on an "as is" basis. The University of British Columbia
00031  * disclaims any and all warranties, whether express, implied, or
00032  * statuary, including any implied warranties or merchantability or of
00033  * fitness for a particular purpose.  In no event shall the
00034  * copyright-holder be liable for any incidental, punitive, or
00035  * consequential damages of any kind whatsoever arising from the use of
00036  * these programs.
00037  * 
00038  * This disclaimer of warranty extends to the user of these programs and
00039  * user's customers, employees, agents, transferees, successors, and
00040  * assigns.
00041  * 
00042  * The University of British Columbia does not represent or warrant that the
00043  * programs furnished hereunder are free of infringement of any
00044  * third-party patents.
00045  * 
00046  * Commercial implementations of H.263, including shareware, are subject to
00047  * royalty fees to patent holders.  Many of these patents are general
00048  * enough such that they are unavoidable regardless of implementation
00049  * design.
00050  * 
00051  */
00052 
00053 
00054 
00055 /* based on mpeg2decode, (C) 1994, MPEG Software Simulation Group and
00056  * mpeg2play, (C) 1994 Stefan Eckart <stefan@lis.e-technik.tu-muenchen.de>
00057  * 
00058  */
00059 
00060 
00061 #include <stdio.h>
00062 #include <stdlib.h>
00063 
00064 #include "config.h"
00065 #include "tmndec.h"
00066 #include "global.h"
00067 
00068 /* private prototypes */
00069 static void recon_comp _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst,
00070  int lx, int lx2, int w, int h, int x, int y, int dx, int dy, int flag));
00071 static void recon_comp_obmc _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst, int lx, int lx2, int comp, int w, int h, int x, int y, int newgob));
00072 static void rec _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
00073 static void recon_bidir_average _ANSI_ARGS_ ((int bx, int by));
00074 static void recc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
00075 static void reco _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));
00076 static void rech _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
00077 static void rechc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
00078 static void recho _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));
00079 static void recv_new _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
00080 static void recvc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
00081 static void recvo _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));
00082 static void rec4 _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
00083 static void rec4c _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
00084 static void rec4o _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));
00085 
00086 void reconstruct (int bx, int by, int P, int bdx, int bdy, int MODB, int newgob)
00087 {
00088   int w, h, lx, lx2, dx, dy, xp, yp, comp, sum;
00089   int x, y, mode, xvec, yvec;
00090   unsigned char *src[3];
00091   int store_rtype;
00092 
00093   x = bx / 16 + 1;
00094   y = by / 16 + 1;
00095   lx = coded_picture_width;
00096 
00097   if (mv_outside_frame)
00098   {
00099     lx2 = coded_picture_width + 64;
00100     src[0] = edgeframe[0];
00101     src[1] = edgeframe[1];
00102     src[2] = edgeframe[2];
00103   } else
00104   {
00105     lx2 = coded_picture_width;
00106     src[0] = prev_I_P_frame[0];
00107     src[1] = prev_I_P_frame[1];
00108     src[2] = prev_I_P_frame[2];
00109   }
00110 
00111   mode = modemap[y][x];
00112 
00113   if (P)
00114   {
00115     /* P prediction */
00116     if (use_4mv)
00117     {
00118       w = 8;
00119       h = 8;
00120       /* Y */
00121       /* 4 MV can be used without OBMC in        * deblocking filter mode                  */
00122       if (overlapping_MC)
00123       {
00124         for (comp = 0; comp < 4; comp++)
00125         {
00126           xp = bx + ((comp & 1) << 3);
00127           yp = by + ((comp & 2) << 2);
00128           recon_comp_obmc (src[0], current_frame[0], lx, lx2, comp, w, h, xp, yp, newgob);
00129         }
00130       } else
00131       {
00132         if (mode == MODE_INTER4V || mode == MODE_INTER4V_Q)
00133         {
00134           for (comp = 0; comp < 4; comp++)
00135           {
00136             dx = MV[0][comp + 1][y][x];
00137             dy = MV[1][comp + 1][y][x];
00138 
00139             xp = bx + ((comp & 1) << 3);
00140             yp = by + ((comp & 2) << 2);
00141             recon_comp (src[0], current_frame[0], lx, lx2, w, h, xp, yp, dx, dy, 0);
00142           }
00143         } else
00144         {
00145           dx = MV[0][0][y][x];
00146           dy = MV[1][0][y][x];
00147           recon_comp (src[0], current_frame[0], lx, lx2, w << 1, h << 1, bx, by, dx, dy, 0);
00148         }
00149       }
00150       /* Chroma */
00151       if (mode == MODE_INTER4V || mode == MODE_INTER4V_Q)
00152       {
00153         sum = MV[0][1][y][x] + MV[0][2][y][x] + MV[0][3][y][x] + MV[0][4][y][x];
00154         dx = sign (sum) * (roundtab[abs (sum) % 16] + (abs (sum) / 16) * 2);
00155 
00156         sum = MV[1][1][y][x] + MV[1][2][y][x] + MV[1][3][y][x] + MV[1][4][y][x];
00157         dy = sign (sum) * (roundtab[abs (sum) % 16] + (abs (sum) / 16) * 2);
00158 
00159       } else
00160       {
00161         dx = MV[0][0][y][x];
00162         dy = MV[1][0][y][x];
00163         /* chroma rounding */
00164         dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);
00165         dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);
00166       }
00167       lx >>= 1;
00168       bx >>= 1;
00169       lx2 >>= 1;
00170       by >>= 1;
00171       /* Chroma */
00172       recon_comp (src[1], current_frame[1], lx, lx2, w, h, bx, by, dx, dy, 1);
00173       recon_comp (src[2], current_frame[2], lx, lx2, w, h, bx, by, dx, dy, 2);
00174     } else
00175     {                           /* normal prediction mode */
00176       /* P prediction */
00177       w = 16;
00178       h = 16;
00179       dx = MV[0][0][y][x];
00180       dy = MV[1][0][y][x];
00181 
00182       /* Y */
00183       recon_comp (src[0], current_frame[0], lx, lx2, w, h, bx, by, dx, dy, 0);
00184 
00185       lx >>= 1;
00186       w >>= 1;
00187       bx >>= 1;
00188       lx2 >>= 1;
00189       h >>= 1;
00190       by >>= 1;
00191       /* chroma rounding */
00192       dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);
00193       dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);
00194 
00195       /* Chroma */
00196       recon_comp (src[1], current_frame[1], lx, lx2, w, h, bx, by, dx, dy, 1);
00197       recon_comp (src[2], current_frame[2], lx, lx2, w, h, bx, by, dx, dy, 2);
00198     }
00199   } else
00200   {
00201     store_rtype = rtype;
00202     rtype = 0;
00203     /* B forward prediction */
00204     if (pb_frame == IM_PB_FRAMES && (MODB == PBMODE_CBPB_FRW_PRED || MODB == PBMODE_FRW_PRED))
00205     {
00206       w = 16;
00207       h = 16;
00208       dx = bdx;
00209       dy = bdy;
00210 
00211       /* Y */
00212       recon_comp (src[0], bframe[0], lx, lx2, w, h, bx, by, dx, dy, 0);
00213 
00214       lx >>= 1;
00215       w >>= 1;
00216       bx >>= 1;
00217       lx2 >>= 1;
00218       h >>= 1;
00219       by >>= 1;
00220       /* chroma rounding */
00221       dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);
00222       dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);
00223 
00224       /* Chroma */
00225       recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);
00226       recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);
00227     } else if (pb_frame == IM_PB_FRAMES && (MODB == PBMODE_CBPB_BCKW_PRED || MODB == PBMODE_BCKW_PRED))
00228     {
00229       lx2 = coded_picture_width;
00230       src[0] = prev_I_P_frame[0];
00231       src[1] = prev_I_P_frame[1];
00232       src[2] = prev_I_P_frame[2];
00233 
00234       w = 16;
00235       h = 16;
00236 
00237       /* Y */
00238       recon_comp (current_frame[0], bframe[0], lx, lx2, w, h, bx, by, 0, 0, 0);
00239 
00240       lx >>= 1;
00241       w >>= 1;
00242       bx >>= 1;
00243       lx2 >>= 1;
00244       h >>= 1;
00245       by >>= 1;
00246 
00247       /* Chroma */
00248       recon_comp (current_frame[1], bframe[1], lx, lx2, w, h, bx, by, 0, 0, 1);
00249       recon_comp (current_frame[2], bframe[2], lx, lx2, w, h, bx, by, 0, 0, 2);
00250     } else
00251     {
00252       /* B bidir prediction */
00253       if (pb_frame == IM_PB_FRAMES)
00254       {
00255         bdx = 0;
00256         bdy = 0;
00257       }
00258       if (use_4mv && (mode == MODE_INTER4V || mode == MODE_INTER4V_Q))
00259       {
00260         w = 8;
00261         h = 8;
00262         /* Y */
00263         xvec = yvec = 0;
00264         for (comp = 0; comp < 4; comp++)
00265         {
00266           xvec += dx = (trb) * MV[0][comp + 1][y][x] / trd + bdx;
00267           yvec += dy = (trb) * MV[1][comp + 1][y][x] / trd + bdy;
00268           xp = bx + ((comp & 1) << 3);
00269           yp = by + ((comp & 2) << 2);
00270           recon_comp (src[0], bframe[0], lx, lx2, w, h, xp, yp, dx, dy, 0);
00271         }
00272 
00273         /* chroma rounding (table 16/H.263) */
00274         dx = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2);
00275         dy = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2);
00276 
00277         lx >>= 1;
00278         bx >>= 1;
00279         lx2 >>= 1;
00280         by >>= 1;
00281         /* Chroma */
00282         recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);
00283         recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);
00284       } else
00285       {
00286         /* B bidir prediction with 16x16 blocks */
00287         w = 16;
00288         h = 16;
00289 
00290         dx = (trb) * MV[0][0][y][x] / trd + bdx;
00291         dy = (trb) * MV[1][0][y][x] / trd + bdy;
00292         /* Y */
00293         recon_comp (src[0], bframe[0], lx, lx2, w, h, bx, by, dx, dy, 0);
00294 
00295         lx >>= 1;
00296         w >>= 1;
00297         bx >>= 1;
00298         lx2 >>= 1;
00299         h >>= 1;
00300         by >>= 1;
00301 
00302         xvec = 4 * dx;
00303         yvec = 4 * dy;
00304 
00305         /* chroma rounding (table 16/H.263) */
00306         dx = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2);
00307         dy = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2);
00308 
00309         /* Chroma */
00310         recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);
00311         recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);
00312       }
00313     }
00314     rtype = store_rtype;
00315   }
00316 }
00317 
00318 /**********************************************************************
00319  *
00320  *      Name:        reconstruct_true_B
00321  *      Description: Reconstructs true B MB 
00322  *
00323  *      Input:       position, mb prediction type
00324  *      Returns:     
00325  *      Side effects:
00326  *
00327  *      Date: 970831 Author: Michael Gallant --- mikeg@ee.ubc.ca
00328  *
00329  ***********************************************************************/
00330 
00331 void reconstruct_true_B (int bx, int by, int true_B_prediction_type)
00332 {
00333   int w, h, lx, lx2, dxf, dyf, dxb, dyb;
00334   int x, y, mode, anchorframemode;
00335   int bx_chroma, by_chroma;
00336   unsigned char *src_f[3], *src_b[3];
00337   int sumx = 0, sumy = 0, comp, dx, dy, xp, yp;
00338 
00339   x = bx / 16 + 1;
00340   y = by / 16 + 1;
00341   lx = coded_picture_width;
00342   w = 16;
00343   h = 16;
00344 
00345   lx2 = coded_picture_width + 64;
00346   src_f[0] = edgeframe[0];
00347   src_f[1] = edgeframe[1];
00348   src_f[2] = edgeframe[2];
00349   src_b[0] = nextedgeframe[0];
00350   src_b[1] = nextedgeframe[1];
00351   src_b[2] = nextedgeframe[2];
00352 
00353   mode = modemap[y][x];
00354   anchorframemode = anchorframemodemap[y][x];
00355 
00356   switch (true_B_prediction_type)
00357   {
00358 
00359     case B_DIRECT_PREDICTION:
00360 
00361       if (MODE_INTER4V == anchorframemode || MODE_INTER4V_Q == anchorframemode)
00362       {
00363         w = 8;
00364         h = 8;
00365     
00366         for (comp = 0; comp < 4; comp++)
00367         {
00368           dx = true_B_direct_mode_MV[0][comp + 1][y][x];
00369           dy = true_B_direct_mode_MV[1][comp + 1][y][x];
00370 
00371           dxf = (true_b_trb) * dx / trd;
00372           dyf = (true_b_trb) * dy / trd;
00373           dxb = (true_b_trb - trd) * dx / trd;
00374           dyb = (true_b_trb - trd) * dy / trd;
00375 
00376           xp = bx + ((comp & 1) << 3);
00377           yp = by + ((comp & 2) << 2);
00378           
00379           /* Y */
00380           recon_comp (src_f[0], tmp_f[0], lx, lx2, w, h, xp, yp, dxf, dyf, 0);
00381           recon_comp (src_b[0], tmp_b[0], lx, lx2, w, h, xp, yp, dxb, dyb, 0);
00382         }
00383 
00384         dxf = dyf = dxb = dyb = 0;
00385 
00386         for (comp=0; comp<4; comp++)
00387         {
00388           dx = true_B_direct_mode_MV[0][comp + 1][y][x];
00389           dy = true_B_direct_mode_MV[1][comp + 1][y][x];
00390 
00391           dxf += (true_b_trb) * dx / trd;
00392           dyf += (true_b_trb) * dy / trd;
00393           dxb += (true_b_trb - trd) * dx / trd;
00394           dyb += (true_b_trb - trd) * dy / trd;
00395         }
00396 
00397         dxf = sign (dxf) * (roundtab[abs (dxf) % 16] + (abs (dxf) / 16) * 2);
00398         dyf = sign (dyf) * (roundtab[abs (dyf) % 16] + (abs (dyf) / 16) * 2);
00399         dxb = sign (dxb) * (roundtab[abs (dxb) % 16] + (abs (dxb) / 16) * 2);
00400         dyb = sign (dyb) * (roundtab[abs (dyb) % 16] + (abs (dyb) / 16) * 2);
00401 
00402         lx >>= 1;
00403         bx >>= 1;
00404         lx2 >>= 1;
00405         by >>= 1;
00406 
00407         /* Chroma */
00408         recon_comp (src_f[1], tmp_f[1], lx, lx2, w, h, bx, by, dxf, dyf, 1);
00409         recon_comp (src_f[2], tmp_f[2], lx, lx2, w, h, bx, by, dxf, dyf, 2);
00410         recon_comp (src_b[1], tmp_b[1], lx, lx2, w, h, bx, by, dxb, dyb, 1);
00411         recon_comp (src_b[2], tmp_b[2], lx, lx2, w, h, bx, by, dxb, dyb, 2);
00412 
00413         bx <<= 1;
00414         by <<= 1;
00415       }
00416       else
00417       {
00418         dxf = (true_b_trb) * true_B_direct_mode_MV[0][0][y][x] / trd;
00419         dyf = (true_b_trb) * true_B_direct_mode_MV[1][0][y][x] / trd;
00420         dxb = (true_b_trb - trd) * true_B_direct_mode_MV[0][0][y][x] / trd;
00421         dyb = (true_b_trb - trd) * true_B_direct_mode_MV[1][0][y][x] / trd;
00422 
00423         /* Y */
00424         recon_comp (src_f[0], tmp_f[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
00425         recon_comp (src_b[0], tmp_b[0], lx, lx2, w, h, bx, by, dxb, dyb, 0);
00426 
00427         lx >>= 1;
00428         w >>= 1;
00429         bx >>= 1;
00430         lx2 >>= 1;
00431         h >>= 1;
00432         by >>= 1;
00433 
00434         /* Chroma rounding (table 16/H.263) */
00435         dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
00436         dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
00437         dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1);
00438         dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1);
00439 
00440         /* Chroma */
00441         recon_comp (src_f[1], tmp_f[1], lx, lx2, w, h, bx, by, dxf, dyf, 1);
00442         recon_comp (src_f[2], tmp_f[2], lx, lx2, w, h, bx, by, dxf, dyf, 2);
00443         recon_comp (src_b[1], tmp_b[1], lx, lx2, w, h, bx, by, dxb, dyb, 1);
00444         recon_comp (src_b[2], tmp_b[2], lx, lx2, w, h, bx, by, dxb, dyb, 2);
00445 
00446         bx <<= 1;
00447         by <<= 1;
00448       }
00449   
00450       /* Average forward and backward prediction. */
00451       recon_bidir_average (bx, by);
00452 
00453       break;
00454 
00455     case B_FORWARD_PREDICTION:
00456 
00457       w = 16;
00458       h = 16;
00459       dxf = MV[0][0][y][x];
00460       dyf = MV[1][0][y][x];
00461 
00462       /* Y */
00463       recon_comp (src_f[0], bframe[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
00464 
00465       lx >>= 1;
00466       w >>= 1;
00467       bx >>= 1;
00468       lx2 >>= 1;
00469       h >>= 1;
00470       by >>= 1;
00471 
00472       /* chroma rounding */
00473       dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
00474       dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
00475 
00476       /* Chroma */
00477       recon_comp (src_f[1], bframe[1], lx, lx2, w, h, bx, by, dxf, dyf, 1);
00478       recon_comp (src_f[2], bframe[2], lx, lx2, w, h, bx, by, dxf, dyf, 2);
00479 
00480       break;
00481 
00482     case B_BACKWARD_PREDICTION:
00483 
00484       w = 16;
00485       h = 16;
00486       dxb = MV[0][5][y][x];
00487       dyb = MV[1][5][y][x];
00488 
00489       /* Y */
00490       recon_comp (src_b[0], bframe[0], lx, lx2, w, h, bx, by, dxb, dyb, 0);
00491 
00492       lx >>= 1;
00493       w >>= 1;
00494       bx >>= 1;
00495       lx2 >>= 1;
00496       h >>= 1;
00497       by >>= 1;
00498       /* chroma rounding */
00499       dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1);
00500       dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1);
00501 
00502       /* Chroma */
00503       recon_comp (src_b[1], bframe[1], lx, lx2, w, h, bx, by, dxb, dyb, 1);
00504       recon_comp (src_b[2], bframe[2], lx, lx2, w, h, bx, by, dxb, dyb, 2);
00505 
00506       break;
00507 
00508     case B_BIDIRECTIONAL_PREDICTION:
00509 
00510       w = 16;
00511       h = 16;
00512 
00513       dxf = MV[0][0][y][x];
00514       dyf = MV[1][0][y][x];
00515       dxb = MV[0][5][y][x];
00516       dyb = MV[1][5][y][x];
00517 
00518       /* Y */
00519       recon_comp (src_f[0], tmp_f[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
00520       recon_comp (src_b[0], tmp_b[0], lx, lx2, w, h, bx, by, dxb, dyb, 0);
00521 
00522       lx >>= 1;
00523       w >>= 1;
00524       lx2 >>= 1;
00525       h >>= 1;
00526 
00527       bx_chroma = bx >> 1;
00528       by_chroma = by >> 1;
00529 
00530 
00531       dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
00532       dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
00533       dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1);
00534       dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1);
00535 
00536       /* Chroma */
00537       recon_comp (src_f[1], tmp_f[1], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 1);
00538       recon_comp (src_f[2], tmp_f[2], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 2);
00539       recon_comp (src_b[1], tmp_b[1], lx, lx2, w, h, bx_chroma, by_chroma, dxb, dyb, 1);
00540       recon_comp (src_b[2], tmp_b[2], lx, lx2, w, h, bx_chroma, by_chroma, dxb, dyb, 2);
00541 
00542       /* Average forward and backward prediction. */
00543       recon_bidir_average (bx, by);
00544 
00545       break;
00546 
00547     default:
00548 
00549           exit (-1);
00550       break;
00551 
00552   }
00553 }
00554 
00555 /**********************************************************************
00556   *
00557  *      Name:        reconstruct_ei_ep
00558  *      Description: Reconstructs ei and ep MBs
00559  *
00560  *      Input:       position, mb prediction type
00561  *      Returns:     
00562  *      Side effects:
00563  *
00564  *      Date: 971102 Author: Michael Gallant --- mikeg@ee.ubc.ca
00565  *
00566  ***********************************************************************/
00567 void reconstruct_ei_ep (int bx, int by, int ei_ep_prediction_type)
00568 {
00569   int w, h, lx, lx2, dxf, dyf;
00570   int x, y, mode;
00571   int bx_chroma, by_chroma;
00572   unsigned char *src_fwd[3], *src_up[3], *tmp_fwd[3], *tmp_up[3];
00573 
00574   /* current_refererence frame should be upsampled already if spatial scalbility is in use */
00575 
00576   x = bx / 16 + 1;
00577   y = by / 16 + 1;
00578   lx = coded_picture_width;
00579   w = 16;
00580   h = 16;
00581 
00582   lx2 = coded_picture_width + 64;
00583   src_fwd[0] = enhance_edgeframe[enhancement_layer_num-2][0];
00584   src_fwd[1] = enhance_edgeframe[enhancement_layer_num-2][1];
00585   src_fwd[2] = enhance_edgeframe[enhancement_layer_num-2][2];
00586   src_up[0] = curr_reference_frame[0];
00587   src_up[1] = curr_reference_frame[1];
00588   src_up[2] = curr_reference_frame[2];
00589 
00590   tmp_fwd[0] = tmp_enhance_fwd[enhancement_layer_num-2][0];
00591   tmp_fwd[1] = tmp_enhance_fwd[enhancement_layer_num-2][1];
00592   tmp_fwd[2] = tmp_enhance_fwd[enhancement_layer_num-2][2];
00593   tmp_up[0] = tmp_enhance_up[enhancement_layer_num-2][0];
00594   tmp_up[1] = tmp_enhance_up[enhancement_layer_num-2][1];
00595   tmp_up[2] = tmp_enhance_up[enhancement_layer_num-2][2];
00596 
00597   mode = modemap[y][x];
00598 
00599   switch (ei_ep_prediction_type)
00600   {
00601 
00602     case EP_FORWARD_PREDICTION:
00603 
00604       w = 16;
00605       h = 16;
00606       dxf = MV[0][0][y][x];
00607       dyf = MV[1][0][y][x];
00608 
00609       /* Y */
00610       recon_comp (src_fwd[0], current_enhancement_frame[enhancement_layer_num-2][0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
00611 
00612       lx >>= 1;
00613       w >>= 1;
00614       bx >>= 1;
00615       lx2 >>= 1;
00616       h >>= 1;
00617       by >>= 1;
00618 
00619       /* chroma rounding */
00620       dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
00621       dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
00622 
00623       /* Chroma */
00624       recon_comp (src_fwd[1], current_enhancement_frame[enhancement_layer_num-2][1], lx, lx2, w, h, bx, by, dxf, dyf, 1);
00625       recon_comp (src_fwd[2], current_enhancement_frame[enhancement_layer_num-2][2], lx, lx2, w, h, bx, by, dxf, dyf, 2);
00626 
00627       break;
00628 
00629     case EI_EP_UPWARD_PREDICTION:
00630 
00631       /* Inter 16x16 */
00632       w = 16;
00633       h = 16;
00634 
00635       /* Y */
00636       recon_comp (src_up[0], current_enhancement_frame[enhancement_layer_num-2][0], lx, lx, w, h, bx, by, 0, 0, 0);
00637 
00638       lx >>= 1;
00639       w >>= 1;
00640       bx >>= 1;
00641       lx2 >>= 1;
00642       h >>= 1;
00643       by >>= 1;
00644 
00645       /* Chroma */
00646       recon_comp (src_up[1], current_enhancement_frame[enhancement_layer_num-2][1], lx, lx, w, h, bx, by, 0, 0, 1);
00647       recon_comp (src_up[2], current_enhancement_frame[enhancement_layer_num-2][2], lx, lx, w, h, bx, by, 0, 0, 2);
00648 
00649       break;
00650 
00651     case EP_BIDIRECTIONAL_PREDICTION:
00652 
00653       w = 16;
00654       h = 16;
00655 
00656       dxf = MV[0][0][y][x];
00657       dyf = MV[1][0][y][x];
00658 
00659       /* Y */
00660       recon_comp (src_fwd[0], tmp_fwd[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
00661       recon_comp (src_up[0], tmp_up[0], lx, lx, w, h, bx, by, 0, 0, 0);
00662 
00663       lx >>= 1;
00664       w >>= 1;
00665       lx2 >>= 1;
00666       h >>= 1;
00667 
00668       bx_chroma = bx >> 1;
00669       by_chroma = by >> 1;
00670 
00671 
00672       dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
00673       dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
00674 
00675       /* Chroma */
00676       recon_comp (src_fwd[1], tmp_fwd[1], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 1);
00677       recon_comp (src_fwd[2], tmp_fwd[2], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 2);
00678       recon_comp (src_up[1], tmp_up[1], lx, lx, w, h, bx_chroma, by_chroma, 0, 0, 1);
00679       recon_comp (src_up[2], tmp_up[2], lx, lx, w, h, bx_chroma, by_chroma, 0, 0, 2);
00680 
00681       /* Average forward and backward prediction. */
00682       recon_bidir_average (bx, by);
00683 
00684       break;
00685 
00686     default:
00687 
00688     
00689       exit (-1);
00690 
00691       break;
00692 
00693   }
00694 }
00695 
00696 static void recon_comp (unsigned char *src, unsigned char *dst, 
00697                         int lx, int lx2, int w, int h, int x, 
00698                         int y, int dx, int dy, int chroma)
00699 {
00700   int xint, xh, yint, yh;
00701   unsigned char *s, *d;
00702   int store_rtype;
00703   
00704   store_rtype = rtype;
00705 
00706   xint = dx >> 1;
00707   xh = dx & 1;
00708   yint = dy >> 1;
00709   yh = dy & 1;
00710 
00711   /* origins */
00712   s = src + lx2 * (y + yint) + x + xint;
00713   d = dst + lx * y + x;
00714 
00715   if (!xh && !yh)
00716     if (w != 8)
00717       rec (s, d, lx, lx2, h);
00718     else
00719       recc (s, d, lx, lx2, h);
00720   else if (!xh && yh)
00721     if (w != 8)
00722       recv_new (s, d, lx, lx2, h);
00723     else
00724       recvc (s, d, lx, lx2, h);
00725   else if (xh && !yh)
00726     if (w != 8)
00727       rech (s, d, lx, lx2, h);
00728     else
00729       rechc (s, d, lx, lx2, h);
00730   else
00731    /* if (xh && yh) */ if (w != 8)
00732     rec4 (s, d, lx, lx2, h);
00733   else
00734     rec4c (s, d, lx, lx2, h);
00735 
00736   rtype = store_rtype;
00737 }
00738 
00739 static void rec (unsigned char *s, unsigned char *d, 
00740                  int lx, int lx2, int h)
00741 {
00742   int j;
00743 
00744   for (j = 0; j < h; j++)
00745   {
00746     d[0] = s[0];
00747     d[1] = s[1];
00748     d[2] = s[2];
00749     d[3] = s[3];
00750     d[4] = s[4];
00751     d[5] = s[5];
00752     d[6] = s[6];
00753     d[7] = s[7];
00754     d[8] = s[8];
00755     d[9] = s[9];
00756     d[10] = s[10];
00757     d[11] = s[11];
00758     d[12] = s[12];
00759     d[13] = s[13];
00760     d[14] = s[14];
00761     d[15] = s[15];
00762     s += lx2;
00763     d += lx;
00764   }
00765 }
00766 
00767 /**********************************************************************
00768  *
00769  *      Name:        recon_bidir_average
00770  *      Description: move average of bidir predicted blocks into current frame
00771  *
00772  *      Input:       absolute position of current MB
00773  *
00774  *      Returns:
00775  *      Side effects:
00776  *
00777  *      Date: 971102 Author: Michael Gallant --- mikeg@ee.ubc.ca
00778  *
00779  ***********************************************************************/
00780 static void recon_bidir_average (int bx, int by)
00781 {
00782   int i, iincr, cc, comp;
00783   unsigned char *avg, *forw, *backw;
00784   unsigned char *prev_frame[3], *next_frame[3], *curr[3];
00785 
00786   /* B picture */
00787   if (PCT_B == pict_type)
00788   {
00789     prev_frame[0] = tmp_f[0];
00790     prev_frame[1] = tmp_f[1];
00791     prev_frame[2] = tmp_f[2];
00792     next_frame[0] = tmp_b[0];
00793     next_frame[1] = tmp_b[1];
00794     next_frame[2] = tmp_b[2];
00795     curr[0] = current_frame[0];
00796     curr[1] = current_frame[1];
00797     curr[2] = current_frame[2];
00798   }
00799   /* EP picture */
00800   else
00801   {
00802     prev_frame[0] = tmp_enhance_fwd[enhancement_layer_num-2][0];
00803     prev_frame[1] = tmp_enhance_fwd[enhancement_layer_num-2][1];
00804     prev_frame[2] = tmp_enhance_fwd[enhancement_layer_num-2][2];
00805     next_frame[0] = tmp_enhance_up[enhancement_layer_num-2][0];
00806     next_frame[1] = tmp_enhance_up[enhancement_layer_num-2][1];
00807     next_frame[2] = tmp_enhance_up[enhancement_layer_num-2][2];
00808     curr[0] = current_enhancement_frame[enhancement_layer_num-2][0];
00809     curr[1] = current_enhancement_frame[enhancement_layer_num-2][1];
00810     curr[2] = current_enhancement_frame[enhancement_layer_num-2][2];
00811   }
00812 
00813   for (comp = 0; comp < 6; ++comp)
00814   {
00815     cc = (comp < 4) ? 0 : (comp & 1) + 1; /* color component index */
00816 
00817     /* luminance */
00818     if (cc == 0)
00819     {
00820       avg = curr[cc] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
00821       forw = prev_frame[cc] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
00822       backw = next_frame[cc] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
00823       iincr = coded_picture_width;
00824     }
00825     /* chrominance */
00826     else
00827     {
00828       /* scale coordinates */
00829       if (4 == comp)
00830       {
00831         bx >>= 1;
00832         by >>= 1;
00833       }
00834       avg = curr[cc] + chrom_width * by + bx;
00835       forw = prev_frame[cc] + chrom_width * by + bx;
00836       backw = next_frame[cc] + chrom_width * by + bx;
00837       iincr = chrom_width;
00838     }
00839 
00840     for (i = 0; i < 8; i++)
00841     {
00842       avg[0] = (forw[0] + backw[0]) / 2;
00843       avg[1] = (forw[1] + backw[1]) / 2;
00844       avg[2] = (forw[2] + backw[2]) / 2;
00845       avg[3] = (forw[3] + backw[3]) / 2;
00846       avg[4] = (forw[4] + backw[4]) / 2;
00847       avg[5] = (forw[5] + backw[5]) / 2;
00848       avg[6] = (forw[6] + backw[6]) / 2;
00849       avg[7] = (forw[7] + backw[7]) / 2;
00850       avg += iincr;
00851       forw += iincr;
00852       backw += iincr;
00853     }
00854   }
00855 }
00856 
00857 
00858 static void recc (unsigned char *s, unsigned char *d, 
00859                   int lx, int lx2, int h)
00860 {
00861   int j;
00862 
00863   for (j = 0; j < h; j++)
00864   {
00865     d[0] = s[0];
00866     d[1] = s[1];
00867     d[2] = s[2];
00868     d[3] = s[3];
00869     d[4] = s[4];
00870     d[5] = s[5];
00871     d[6] = s[6];
00872     d[7] = s[7];
00873     s += lx2;
00874     d += lx;
00875   }
00876 }
00877 
00878 static void reco (unsigned char *s, int *d, int lx, int lx2, 
00879                   int addflag, int c, int xa, int xb, 
00880                   int ya, int yb)
00881 {
00882   int i, j;
00883   int *om;
00884 
00885   om = &OM[c][ya][0];
00886 
00887   if (!addflag)
00888   {
00889     for (j = ya; j < yb; j++)
00890     {
00891       for (i = xa; i < xb; i++)
00892       {
00893         d[i] = s[i] * om[i];
00894       }
00895       s += lx2;
00896       d += lx;
00897       om += 8;
00898     }
00899   } else
00900   {
00901     for (j = ya; j < yb; j++)
00902     {
00903       for (i = xa; i < xb; i++)
00904       {
00905         d[i] += s[i] * om[i];
00906       }
00907       s += lx2;
00908       d += lx;
00909       om += 8;
00910     }
00911   }
00912 }
00913 
00914 static void rech (unsigned char *s, unsigned char *d, 
00915                   int lx, int lx2, int h)
00916 {
00917   unsigned char *dp, *sp;
00918   int j;
00919   unsigned int s1, s2;
00920 
00921   sp = s;
00922   dp = d;
00923   for (j = 0; j < h; j++)
00924   {
00925     s1 = sp[0];
00926     dp[0] = (unsigned int) (s1 + (s2 = sp[1]) + 1 - rtype) >> 1;
00927     dp[1] = (unsigned int) (s2 + (s1 = sp[2]) + 1 - rtype) >> 1;
00928     dp[2] = (unsigned int) (s1 + (s2 = sp[3]) + 1 - rtype) >> 1;
00929     dp[3] = (unsigned int) (s2 + (s1 = sp[4]) + 1 - rtype) >> 1;
00930     dp[4] = (unsigned int) (s1 + (s2 = sp[5]) + 1 - rtype) >> 1;
00931     dp[5] = (unsigned int) (s2 + (s1 = sp[6]) + 1 - rtype) >> 1;
00932     dp[6] = (unsigned int) (s1 + (s2 = sp[7]) + 1 - rtype) >> 1;
00933     dp[7] = (unsigned int) (s2 + (s1 = sp[8]) + 1 - rtype) >> 1;
00934     dp[8] = (unsigned int) (s1 + (s2 = sp[9]) + 1 - rtype) >> 1;
00935     dp[9] = (unsigned int) (s2 + (s1 = sp[10]) + 1 - rtype) >> 1;
00936     dp[10] = (unsigned int) (s1 + (s2 = sp[11]) + 1 - rtype) >> 1;
00937     dp[11] = (unsigned int) (s2 + (s1 = sp[12]) + 1 - rtype) >> 1;
00938     dp[12] = (unsigned int) (s1 + (s2 = sp[13]) + 1 - rtype) >> 1;
00939     dp[13] = (unsigned int) (s2 + (s1 = sp[14]) + 1 - rtype) >> 1;
00940     dp[14] = (unsigned int) (s1 + (s2 = sp[15]) + 1 - rtype) >> 1;
00941     dp[15] = (unsigned int) (s2 + sp[16] + 1 - rtype) >> 1;
00942     sp += lx2;
00943     dp += lx;
00944   }
00945 }
00946 
00947 static void rechc (unsigned char *s, unsigned char *d, 
00948                    int lx, int lx2, int h)
00949 {
00950   unsigned char *dp, *sp;
00951   int j;
00952   unsigned int s1, s2;
00953 
00954   sp = s;
00955   dp = d;
00956   for (j = 0; j < h; j++)
00957   {
00958     s1 = sp[0];
00959     dp[0] = (unsigned int) (s1 + (s2 = sp[1]) + 1 - rtype) >> 1;
00960     dp[1] = (unsigned int) (s2 + (s1 = sp[2]) + 1 - rtype) >> 1;
00961     dp[2] = (unsigned int) (s1 + (s2 = sp[3]) + 1 - rtype) >> 1;
00962     dp[3] = (unsigned int) (s2 + (s1 = sp[4]) + 1 - rtype) >> 1;
00963     dp[4] = (unsigned int) (s1 + (s2 = sp[5]) + 1 - rtype) >> 1;
00964     dp[5] = (unsigned int) (s2 + (s1 = sp[6]) + 1 - rtype) >> 1;
00965     dp[6] = (unsigned int) (s1 + (s2 = sp[7]) + 1 - rtype) >> 1;
00966     dp[7] = (unsigned int) (s2 + sp[8] + 1 - rtype) >> 1;
00967     sp += lx2;
00968     dp += lx;
00969   }
00970 }
00971 
00972 static void recho (unsigned char *s, int *d, int lx, int lx2, 
00973                    int addflag, int c, int xa, int xb, int ya, int yb)
00974 {
00975   int *dp, *om;
00976   unsigned char *sp;
00977   int i, j;
00978 
00979   sp = s;
00980   dp = d;
00981   om = &OM[c][ya][0];
00982 
00983   if (!addflag)
00984   {
00985     for (j = ya; j < yb; j++)
00986     {
00987       for (i = xa; i < xb; i++)
00988       {
00989         dp[i] = (((unsigned int) (sp[i] + sp[i + 1] + 1 - rtype)) >> 1) * om[i];
00990       }
00991       sp += lx2;
00992       dp += lx;
00993       om += 8;
00994     }
00995   } else
00996   {
00997     for (j = ya; j < yb; j++)
00998     {
00999       for (i = xa; i < xb; i++)
01000       {
01001         dp[i] += (((unsigned int) (sp[i] + sp[i + 1] + 1 - rtype)) >> 1) * OM[c][j][i];
01002       }
01003       sp += lx2;
01004       dp += lx;
01005       om += 8;
01006     }
01007   }
01008 }
01009 
01010 static void recv_new (unsigned char *s, unsigned char *d, 
01011                   int lx, int lx2, int h)
01012 {
01013   unsigned char *dp, *sp, *sp2;
01014   int j;
01015 
01016   sp = s;
01017   sp2 = s + lx2;
01018   dp = d;
01019   for (j = 0; j < h; j++)
01020   {
01021     dp[0] = (unsigned int) (sp[0] + sp2[0] + 1 - rtype) >> 1;
01022     dp[1] = (unsigned int) (sp[1] + sp2[1] + 1 - rtype) >> 1;
01023     dp[2] = (unsigned int) (sp[2] + sp2[2] + 1 - rtype) >> 1;
01024     dp[3] = (unsigned int) (sp[3] + sp2[3] + 1 - rtype) >> 1;
01025     dp[4] = (unsigned int) (sp[4] + sp2[4] + 1 - rtype) >> 1;
01026     dp[5] = (unsigned int) (sp[5] + sp2[5] + 1 - rtype) >> 1;
01027     dp[6] = (unsigned int) (sp[6] + sp2[6] + 1 - rtype) >> 1;
01028     dp[7] = (unsigned int) (sp[7] + sp2[7] + 1 - rtype) >> 1;
01029     dp[8] = (unsigned int) (sp[8] + sp2[8] + 1 - rtype) >> 1;
01030     dp[9] = (unsigned int) (sp[9] + sp2[9] + 1 - rtype) >> 1;
01031     dp[10] = (unsigned int) (sp[10] + sp2[10] + 1 - rtype) >> 1;
01032     dp[11] = (unsigned int) (sp[11] + sp2[11] + 1 - rtype) >> 1;
01033     dp[12] = (unsigned int) (sp[12] + sp2[12] + 1 - rtype) >> 1;
01034     dp[13] = (unsigned int) (sp[13] + sp2[13] + 1 - rtype) >> 1;
01035     dp[14] = (unsigned int) (sp[14] + sp2[14] + 1 - rtype) >> 1;
01036     dp[15] = (unsigned int) (sp[15] + sp2[15] + 1 - rtype) >> 1;
01037     sp += lx2;
01038     sp2 += lx2;
01039     dp += lx;
01040   }
01041 }
01042 
01043 static void recvc (unsigned char *s, unsigned char *d, 
01044                    int lx, int lx2, int h)
01045 {
01046   unsigned char *dp, *sp, *sp2;
01047   int j;
01048 
01049   sp = s;
01050   sp2 = s + lx2;
01051   dp = d;
01052 
01053   for (j = 0; j < h; j++)
01054   {
01055     dp[0] = (unsigned int) (sp[0] + sp2[0] + 1 - rtype) >> 1;
01056     dp[1] = (unsigned int) (sp[1] + sp2[1] + 1 - rtype) >> 1;
01057     dp[2] = (unsigned int) (sp[2] + sp2[2] + 1 - rtype) >> 1;
01058     dp[3] = (unsigned int) (sp[3] + sp2[3] + 1 - rtype) >> 1;
01059     dp[4] = (unsigned int) (sp[4] + sp2[4] + 1 - rtype) >> 1;
01060     dp[5] = (unsigned int) (sp[5] + sp2[5] + 1 - rtype) >> 1;
01061     dp[6] = (unsigned int) (sp[6] + sp2[6] + 1 - rtype) >> 1;
01062     dp[7] = (unsigned int) (sp[7] + sp2[7] + 1 - rtype) >> 1;
01063     sp += lx2;
01064     sp2 += lx2;
01065     dp += lx;
01066   }
01067 }
01068 
01069 static void recvo (unsigned char *s, int *d, int lx, int lx2, 
01070                    int addflag, int c, int xa, int xb, int ya, 
01071                    int yb)
01072 {
01073   int *dp, *om;
01074   unsigned char *sp, *sp2;
01075   int i, j;
01076 
01077   sp = s;
01078   sp2 = s + lx2;
01079   dp = d;
01080   om = &OM[c][ya][0];
01081 
01082   if (!addflag)
01083   {
01084     for (j = ya; j < yb; j++)
01085     {
01086       for (i = xa; i < xb; i++)
01087       {
01088         dp[i] = (((unsigned int) (sp[i] + sp2[i] + 1 - rtype)) >> 1) * om[i];
01089       }
01090       sp += lx2;
01091       sp2 += lx2;
01092       dp += lx;
01093       om += 8;
01094     }
01095   } else
01096   {
01097     for (j = ya; j < yb; j++)
01098     {
01099       for (i = xa; i < xb; i++)
01100       {
01101         dp[i] += (((unsigned int) (sp[i] + sp2[i] + 1 - rtype)) >> 1) * om[i];
01102       }
01103       sp += lx2;
01104       sp2 += lx2;
01105       dp += lx;
01106       om += 8;
01107     }
01108   }
01109 }
01110 
01111 static void rec4 (unsigned char *s, unsigned char *d, 
01112                   int lx, int lx2, int h)
01113 {
01114   unsigned char *dp, *sp, *sp2;
01115   int j;
01116   unsigned int s1, s2, s3, s4;
01117 
01118   sp = s;
01119   sp2 = s + lx2;
01120   dp = d;
01121   for (j = 0; j < h; j++)
01122   {
01123     s1 = sp[0];
01124     s3 = sp2[0];
01125     dp[0] = (unsigned int) (s1 + (s2 = sp[1]) + s3 + (s4 = sp2[1]) + 2 - rtype) >> 2;
01126     dp[1] = (unsigned int) (s2 + (s1 = sp[2]) + s4 + (s3 = sp2[2]) + 2 - rtype) >> 2;
01127     dp[2] = (unsigned int) (s1 + (s2 = sp[3]) + s3 + (s4 = sp2[3]) + 2 - rtype) >> 2;
01128     dp[3] = (unsigned int) (s2 + (s1 = sp[4]) + s4 + (s3 = sp2[4]) + 2 - rtype) >> 2;
01129     dp[4] = (unsigned int) (s1 + (s2 = sp[5]) + s3 + (s4 = sp2[5]) + 2 - rtype) >> 2;
01130     dp[5] = (unsigned int) (s2 + (s1 = sp[6]) + s4 + (s3 = sp2[6]) + 2 - rtype) >> 2;
01131     dp[6] = (unsigned int) (s1 + (s2 = sp[7]) + s3 + (s4 = sp2[7]) + 2 - rtype) >> 2;
01132     dp[7] = (unsigned int) (s2 + (s1 = sp[8]) + s4 + (s3 = sp2[8]) + 2 - rtype) >> 2;
01133     dp[8] = (unsigned int) (s1 + (s2 = sp[9]) + s3 + (s4 = sp2[9]) + 2 - rtype) >> 2;
01134     dp[9] = (unsigned int) (s2 + (s1 = sp[10]) + s4 + (s3 = sp2[10]) + 2 - rtype) >> 2;
01135     dp[10] = (unsigned int) (s1 + (s2 = sp[11]) + s3 + (s4 = sp2[11]) + 2 - rtype) >> 2;
01136     dp[11] = (unsigned int) (s2 + (s1 = sp[12]) + s4 + (s3 = sp2[12]) + 2 - rtype) >> 2;
01137     dp[12] = (unsigned int) (s1 + (s2 = sp[13]) + s3 + (s4 = sp2[13]) + 2 - rtype) >> 2;
01138     dp[13] = (unsigned int) (s2 + (s1 = sp[14]) + s4 + (s3 = sp2[14]) + 2 - rtype) >> 2;
01139     dp[14] = (unsigned int) (s1 + (s2 = sp[15]) + s3 + (s4 = sp2[15]) + 2 - rtype) >> 2;
01140     dp[15] = (unsigned int) (s2 + sp[16] + s4 + sp2[16] + 2 - rtype) >> 2;
01141     sp += lx2;
01142     sp2 += lx2;
01143     dp += lx;
01144   }
01145 }
01146 
01147 static void rec4c (unsigned char *s, unsigned char *d, 
01148                    int lx, int lx2, int h)
01149 {
01150   unsigned char *dp, *sp, *sp2;
01151   int j;
01152   unsigned int s1, s2, s3, s4;
01153 
01154   sp = s;
01155   sp2 = s + lx2;
01156   dp = d;
01157   for (j = 0; j < h; j++)
01158   {
01159     s1 = sp[0];
01160     s3 = sp2[0];
01161     dp[0] = (unsigned int) (s1 + (s2 = sp[1]) + s3 + (s4 = sp2[1]) + 2 - rtype) >> 2;
01162     dp[1] = (unsigned int) (s2 + (s1 = sp[2]) + s4 + (s3 = sp2[2]) + 2 - rtype) >> 2;
01163     dp[2] = (unsigned int) (s1 + (s2 = sp[3]) + s3 + (s4 = sp2[3]) + 2 - rtype) >> 2;
01164     dp[3] = (unsigned int) (s2 + (s1 = sp[4]) + s4 + (s3 = sp2[4]) + 2 - rtype) >> 2;
01165     dp[4] = (unsigned int) (s1 + (s2 = sp[5]) + s3 + (s4 = sp2[5]) + 2 - rtype) >> 2;
01166     dp[5] = (unsigned int) (s2 + (s1 = sp[6]) + s4 + (s3 = sp2[6]) + 2 - rtype) >> 2;
01167     dp[6] = (unsigned int) (s1 + (s2 = sp[7]) + s3 + (s4 = sp2[7]) + 2 - rtype) >> 2;
01168     dp[7] = (unsigned int) (s2 + sp[8] + s4 + sp2[8] + 2 - rtype) >> 2;
01169     sp += lx2;
01170     sp2 += lx2;
01171     dp += lx;
01172   }
01173 }
01174 
01175 static void rec4o (unsigned char *s, int *d, int lx, int lx2, 
01176                    int addflag, int c, int xa, int xb, int ya, 
01177                    int yb)
01178 {
01179   int *dp, *om;
01180   unsigned char *sp, *sp2;
01181   int i, j;
01182 
01183   sp = s;
01184   sp2 = s + lx2;
01185   dp = d;
01186   om = &OM[c][ya][0];
01187 
01188   if (!addflag)
01189   {
01190     for (j = ya; j < yb; j++)
01191     {
01192       for (i = xa; i < xb; i++)
01193       {
01194         dp[i] = (((unsigned int) (sp[i] + sp2[i] + sp[i + 1] + sp2[i + 1] + 2 - rtype)) >> 2) * om[i];
01195       }
01196       sp += lx2;
01197       sp2 += lx2;
01198       dp += lx;
01199       om += 8;
01200     }
01201   } else
01202   {
01203     for (j = ya; j < yb; j++)
01204     {
01205       for (i = xa; i < xb; i++)
01206       {
01207         dp[i] += (((unsigned int) (sp[i] + sp2[i] + sp[i + 1] + sp2[i + 1] + 2 - rtype)) >> 2) * om[i];
01208       }
01209       sp += lx2;
01210       sp2 += lx2;
01211       dp += lx;
01212       om += 8;
01213     }
01214   }
01215 }
01216 
01217 static void recon_comp_obmc (unsigned char *src, unsigned char *dst, 
01218                              int lx, int lx2, int comp, int w, int h, 
01219                              int x, int y, int newgob)
01220 {
01221   int j, k;
01222   int xmb, ymb;
01223   int c8, t8, l8, r8;
01224   int ti8, li8, ri8;
01225   int xit, xib, xir, xil;
01226   int yit, yib, yir, yil;
01227   int vect, vecb, vecr, vecl;
01228   int nx[5], ny[5], xint[5], yint[5], xh[5], yh[5];
01229   int p[64], *pd;
01230   unsigned char *d, *s[5];
01231 
01232   xmb = (x >> 4) + 1;
01233   ymb = (y >> 4) + 1;
01234 
01235   c8 = (modemap[ymb][xmb] == MODE_INTER4V ? 1 : 0);
01236   c8 = (modemap[ymb][xmb] == MODE_INTER4V_Q ? 1 : c8);
01237 
01238   t8 = (modemap[ymb - 1][xmb] == MODE_INTER4V ? 1 : 0);
01239   t8 = (modemap[ymb - 1][xmb] == MODE_INTER4V_Q ? 1 : t8);
01240   ti8 = (modemap[ymb - 1][xmb] == MODE_INTRA ? 1 : 0);
01241   ti8 = (modemap[ymb - 1][xmb] == MODE_INTRA_Q ? 1 : ti8);
01242 
01243   l8 = (modemap[ymb][xmb - 1] == MODE_INTER4V ? 1 : 0);
01244   l8 = (modemap[ymb][xmb - 1] == MODE_INTER4V_Q ? 1 : l8);
01245   li8 = (modemap[ymb][xmb - 1] == MODE_INTRA ? 1 : 0);
01246   li8 = (modemap[ymb][xmb - 1] == MODE_INTRA_Q ? 1 : li8);
01247 
01248   r8 = (modemap[ymb][xmb + 1] == MODE_INTER4V ? 1 : 0);
01249   r8 = (modemap[ymb][xmb + 1] == MODE_INTER4V_Q ? 1 : r8);
01250   ri8 = (modemap[ymb][xmb + 1] == MODE_INTRA ? 1 : 0);
01251   ri8 = (modemap[ymb][xmb + 1] == MODE_INTRA_Q ? 1 : ri8);
01252 
01253   if (pb_frame)
01254   {
01255     ti8 = li8 = ri8 = 0;
01256   }
01257   switch (comp + 1)
01258   {
01259 
01260     case 1:
01261       vect = (ti8 ? (c8 ? 1 : 0) : (t8 ? 3 : 0));
01262       yit = (ti8 ? ymb : ymb - 1);
01263       xit = xmb;
01264 
01265       vecb = (c8 ? 3 : 0);
01266       yib = ymb;
01267       xib = xmb;
01268 
01269       vecl = (li8 ? (c8 ? 1 : 0) : (l8 ? 2 : 0));
01270       yil = ymb;
01271       xil = (li8 ? xmb : xmb - 1);
01272 
01273       vecr = (c8 ? 2 : 0);
01274       yir = ymb;
01275       xir = xmb;
01276 
01277       /* edge handling */
01278       if (ymb == 1 || newgob)
01279       {
01280         yit = ymb;
01281         vect = (c8 ? 1 : 0);
01282       }
01283       if (xmb == 1)
01284       {
01285         xil = xmb;
01286         vecl = (c8 ? 1 : 0);
01287       }
01288       break;
01289 
01290     case 2:
01291       vect = (ti8 ? (c8 ? 2 : 0) : (t8 ? 4 : 0));
01292       yit = (ti8 ? ymb : ymb - 1);
01293       xit = xmb;
01294 
01295       vecb = (c8 ? 4 : 0);
01296       yib = ymb;
01297       xib = xmb;
01298       vecl = (c8 ? 1 : 0);
01299       yil = ymb;
01300       xil = xmb;
01301 
01302       vecr = (ri8 ? (c8 ? 2 : 0) : (r8 ? 1 : 0));
01303       yir = ymb;
01304       xir = (ri8 ? xmb : xmb + 1);
01305 
01306       /* edge handling */
01307       if (ymb == 1 || newgob)
01308       {
01309         yit = ymb;
01310         vect = (c8 ? 2 : 0);
01311       }
01312       if (xmb == mb_width)
01313       {
01314         xir = xmb;
01315         vecr = (c8 ? 2 : 0);
01316       }
01317       break;
01318 
01319     case 3:
01320       vect = (c8 ? 1 : 0);
01321       yit = ymb;
01322       xit = xmb;
01323       vecb = (c8 ? 3 : 0);
01324       yib = ymb;
01325       xib = xmb;
01326 
01327       vecl = (li8 ? (c8 ? 3 : 0) : (l8 ? 4 : 0));
01328       yil = ymb;
01329       xil = (li8 ? xmb : xmb - 1);
01330 
01331       vecr = (c8 ? 4 : 0);
01332       yir = ymb;
01333       xir = xmb;
01334 
01335       /* edge handling */
01336       if (xmb == 1)
01337       {
01338         xil = xmb;
01339         vecl = (c8 ? 3 : 0);
01340       }
01341       break;
01342 
01343     case 4:
01344       vect = (c8 ? 2 : 0);
01345       yit = ymb;
01346       xit = xmb;
01347       vecb = (c8 ? 4 : 0);
01348       yib = ymb;
01349       xib = xmb;
01350       vecl = (c8 ? 3 : 0);
01351       yil = ymb;
01352       xil = xmb;
01353 
01354       vecr = (ri8 ? (c8 ? 4 : 0) : (r8 ? 3 : 0));
01355       yir = ymb;
01356       xir = (ri8 ? xmb : xmb + 1);
01357 
01358       /* edge handling */
01359       if (xmb == mb_width)
01360       {
01361         xir = xmb;
01362         vecr = (c8 ? 4 : 0);
01363       }
01364       break;
01365 
01366     default:
01367     
01368       exit (1);
01369       break;
01370   }
01371 
01372   nx[0] = MV[0][c8 ? comp + 1 : 0][ymb][xmb];
01373   ny[0] = MV[1][c8 ? comp + 1 : 0][ymb][xmb];
01374 
01375   nx[1] = MV[0][vect][yit][xit];
01376   ny[1] = MV[1][vect][yit][xit];
01377   nx[2] = MV[0][vecb][yib][xib];
01378   ny[2] = MV[1][vecb][yib][xib];
01379   nx[3] = MV[0][vecr][yir][xir];
01380   ny[3] = MV[1][vecr][yir][xir];
01381   nx[4] = MV[0][vecl][yil][xil];
01382   ny[4] = MV[1][vecl][yil][xil];
01383 
01384   for (k = 0; k < 5; k++)
01385   {
01386     xint[k] = nx[k] >> 1;
01387     xh[k] = nx[k] & 1;
01388     yint[k] = ny[k] >> 1;
01389     yh[k] = ny[k] & 1;
01390     s[k] = src + lx2 * (y + yint[k]) + x + xint[k];
01391   }
01392 
01393   d = dst + lx * y + x;
01394 
01395   if (!xh[0] && !yh[0])
01396     reco (s[0], &p[0], 8, lx2, 0, 0, 0, 8, 0, 8);
01397   else if (!xh[0] && yh[0])
01398     recvo (s[0], &p[0], 8, lx2, 0, 0, 0, 8, 0, 8);
01399   else if (xh[0] && !yh[0])
01400     recho (s[0], &p[0], 8, lx2, 0, 0, 0, 8, 0, 8);
01401   else                          /* if (xh[] && yh[]) */
01402     rec4o (s[0], &p[0], 8, lx2, 0, 0, 0, 8, 0, 8);
01403 
01404   if (!xh[1] && !yh[1])
01405     reco (s[1], &p[0], 8, lx2, 1, 1, 0, 8, 0, 4);
01406   else if (!xh[1] && yh[1])
01407     recvo (s[1], &p[0], 8, lx2, 1, 1, 0, 8, 0, 4);
01408   else if (xh[1] && !yh[1])
01409     recho (s[1], &p[0], 8, lx2, 1, 1, 0, 8, 0, 4);
01410   else                          /* if (xh[] && yh[]) */
01411     rec4o (s[1], &p[0], 8, lx2, 1, 1, 0, 8, 0, 4);
01412 
01413   if (!xh[2] && !yh[2])
01414     reco (s[2] + (lx2 << 2), &p[32], 8, lx2, 1, 2, 0, 8, 4, 8);
01415   else if (!xh[2] && yh[2])
01416     recvo (s[2] + (lx2 << 2), &p[32], 8, lx2, 1, 2, 0, 8, 4, 8);
01417   else if (xh[2] && !yh[2])
01418     recho (s[2] + (lx2 << 2), &p[32], 8, lx2, 1, 2, 0, 8, 4, 8);
01419   else                          /* if (xh[] && yh[]) */
01420     rec4o (s[2] + (lx2 << 2), &p[32], 8, lx2, 1, 2, 0, 8, 4, 8);
01421 
01422   if (!xh[3] && !yh[3])
01423     reco (s[3], &p[0], 8, lx2, 1, 3, 4, 8, 0, 8);
01424   else if (!xh[3] && yh[3])
01425     recvo (s[3], &p[0], 8, lx2, 1, 3, 4, 8, 0, 8);
01426   else if (xh[3] && !yh[3])
01427     recho (s[3], &p[0], 8, lx2, 1, 3, 4, 8, 0, 8);
01428   else                          /* if (xh[] && yh[]) */
01429     rec4o (s[3], &p[0], 8, lx2, 1, 3, 4, 8, 0, 8);
01430 
01431   if (!xh[4] && !yh[4])
01432     reco (s[4], &p[0], 8, lx2, 1, 4, 0, 4, 0, 8);
01433   else if (!xh[4] && yh[4])
01434     recvo (s[4], &p[0], 8, lx2, 1, 4, 0, 4, 0, 8);
01435   else if (xh[4] && !yh[4])
01436     recho (s[4], &p[0], 8, lx2, 1, 4, 0, 4, 0, 8);
01437   else                          /* if (xh[] && yh[]) */
01438     rec4o (s[4], &p[0], 8, lx2, 1, 4, 0, 4, 0, 8);
01439 
01440   pd = &p[0];
01441   for (j = 0; j < 8; j++)
01442   {
01443     d[0] = (pd[0] + 4) >> 3;
01444     d[1] = (pd[1] + 4) >> 3;
01445     d[2] = (pd[2] + 4) >> 3;
01446     d[3] = (pd[3] + 4) >> 3;
01447     d[4] = (pd[4] + 4) >> 3;
01448     d[5] = (pd[5] + 4) >> 3;
01449     d[6] = (pd[6] + 4) >> 3;
01450     d[7] = (pd[7] + 4) >> 3;
01451     d += lx;
01452     pd += 8;
01453   }
01454 
01455 }

Generated on Mon May 8 22:27:08 2006 by  doxygen 1.3.9.1