~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/codec/tmndec/recon.c

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 /************************************************************************
  2  *
  3  *  recon.c, motion compensation routines for tmndecode (H.263 decoder)
  4  *  Copyright (C) 1995, 1996  Telenor R&D, Norway
  5  *
  6  *  Contacts:
  7  *  Robert Danielsen                  <Robert.Danielsen@nta.no>
  8  *
  9  *  Telenor Research and Development  http://www.nta.no/brukere/DVC/
 10  *  P.O.Box 83                        tel.:   +47 63 84 84 00
 11  *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76
 12  *
 13  *  Copyright (C) 1997  University of BC, Canada
 14  *  Modified by: Michael Gallant <mikeg@ee.ubc.ca>
 15  *               Guy Cote <guyc@ee.ubc.ca>
 16  *               Berna Erol <bernae@ee.ubc.ca>
 17  *
 18  *  Contacts:
 19  *  Michael Gallant                   <mikeg@ee.ubc.ca>
 20  *
 21  *  UBC Image Processing Laboratory   http://www.ee.ubc.ca/image
 22  *  2356 Main Mall                    tel.: +1 604 822 4051
 23  *  Vancouver BC Canada V6T1Z4        fax.: +1 604 822 5949
 24  *
 25  ************************************************************************/
 26 
 27 /* Disclaimer of Warranty
 28  * 
 29  * These software programs are available to the user without any license fee
 30  * or royalty on an "as is" basis. The University of British Columbia
 31  * disclaims any and all warranties, whether express, implied, or
 32  * statuary, including any implied warranties or merchantability or of
 33  * fitness for a particular purpose.  In no event shall the
 34  * copyright-holder be liable for any incidental, punitive, or
 35  * consequential damages of any kind whatsoever arising from the use of
 36  * these programs.
 37  * 
 38  * This disclaimer of warranty extends to the user of these programs and
 39  * user's customers, employees, agents, transferees, successors, and
 40  * assigns.
 41  * 
 42  * The University of British Columbia does not represent or warrant that the
 43  * programs furnished hereunder are free of infringement of any
 44  * third-party patents.
 45  * 
 46  * Commercial implementations of H.263, including shareware, are subject to
 47  * royalty fees to patent holders.  Many of these patents are general
 48  * enough such that they are unavoidable regardless of implementation
 49  * design.
 50  * 
 51  */
 52 
 53 
 54 
 55 /* based on mpeg2decode, (C) 1994, MPEG Software Simulation Group and
 56  * mpeg2play, (C) 1994 Stefan Eckart <stefan@lis.e-technik.tu-muenchen.de>
 57  * 
 58  */
 59 
 60 
 61 #include <stdio.h>
 62 #include <stdlib.h>
 63 
 64 #include "config.h"
 65 #include "tmndec.h"
 66 #include "global.h"
 67 
 68 /* private prototypes */
 69 static void recon_comp _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst,
 70  int lx, int lx2, int w, int h, int x, int y, int dx, int dy, int flag));
 71 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));
 72 static void rec _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
 73 static void recon_bidir_average _ANSI_ARGS_ ((int bx, int by));
 74 static void recc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
 75 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));
 76 static void rech _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
 77 static void rechc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
 78 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));
 79 static void recv _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
 80 static void recvc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
 81 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));
 82 static void rec4 _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
 83 static void rec4c _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));
 84 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));
 85 
 86 void reconstruct (int bx, int by, int P, int bdx, int bdy, int MODB)
 87 {
 88   int w, h, lx, lx2, dx, dy, xp, yp, comp, sum;
 89   int x, y, mode, xvec, yvec;
 90   unsigned char *src[3];
 91   int store_rtype;
 92 
 93   x = bx / 16 + 1;
 94   y = by / 16 + 1;
 95   lx = coded_picture_width;
 96 
 97   if (mv_outside_frame)
 98   {
 99     lx2 = coded_picture_width + 64;
100     src[0] = edgeframe[0];
101     src[1] = edgeframe[1];
102     src[2] = edgeframe[2];
103   } else
104   {
105     lx2 = coded_picture_width;
106     src[0] = prev_I_P_frame[0];
107     src[1] = prev_I_P_frame[1];
108     src[2] = prev_I_P_frame[2];
109   }
110 
111   mode = modemap[y][x];
112 
113   if (P)
114   {
115     /* P prediction */
116     if (use_4mv)
117     {
118       w = 8;
119       h = 8;
120       /* Y */
121       /* 4 MV can be used without OBMC in        * deblocking filter mode                  */
122       if (overlapping_MC)
123       {
124         for (comp = 0; comp < 4; comp++)
125         {
126           xp = bx + ((comp & 1) << 3);
127           yp = by + ((comp & 2) << 2);
128           recon_comp_obmc (src[0], current_frame[0], lx, lx2, comp, w, h, xp, yp);
129         }
130       } else
131       {
132         if (mode == MODE_INTER4V || mode == MODE_INTER4V_Q)
133         {
134           for (comp = 0; comp < 4; comp++)
135           {
136             dx = MV[0][comp + 1][y][x];
137             dy = MV[1][comp + 1][y][x];
138 
139             xp = bx + ((comp & 1) << 3);
140             yp = by + ((comp & 2) << 2);
141             recon_comp (src[0], current_frame[0], lx, lx2, w, h, xp, yp, dx, dy, 0);
142           }
143         } else
144         {
145           dx = MV[0][0][y][x];
146           dy = MV[1][0][y][x];
147           recon_comp (src[0], current_frame[0], lx, lx2, w << 1, h << 1, bx, by, dx, dy, 0);
148         }
149       }
150       /* Chroma */
151       if (mode == MODE_INTER4V || mode == MODE_INTER4V_Q)
152       {
153 
154         sum = MV[0][1][y][x] + MV[0][2][y][x] + MV[0][3][y][x] + MV[0][4][y][x];
155         dx = sign (sum) * (roundtab[abs (sum) % 16] + (abs (sum) / 16) * 2);
156 
157         sum = MV[1][1][y][x] + MV[1][2][y][x] + MV[1][3][y][x] + MV[1][4][y][x];
158         dy = sign (sum) * (roundtab[abs (sum) % 16] + (abs (sum) / 16) * 2);
159 
160       } else
161       {
162         dx = MV[0][0][y][x];
163         dy = MV[1][0][y][x];
164         /* chroma rounding */
165         dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);
166         dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);
167       }
168       lx >>= 1;
169       bx >>= 1;
170       lx2 >>= 1;
171       by >>= 1;
172       /* Chroma */
173       recon_comp (src[1], current_frame[1], lx, lx2, w, h, bx, by, dx, dy, 1);
174       recon_comp (src[2], current_frame[2], lx, lx2, w, h, bx, by, dx, dy, 2);
175     } else
176     {                           /* normal prediction mode */
177       /* P prediction */
178       w = 16;
179       h = 16;
180       dx = MV[0][0][y][x];
181       dy = MV[1][0][y][x];
182 
183       /* Y */
184       recon_comp (src[0], current_frame[0], lx, lx2, w, h, bx, by, dx, dy, 0);
185 
186       lx >>= 1;
187       w >>= 1;
188       bx >>= 1;
189       lx2 >>= 1;
190       h >>= 1;
191       by >>= 1;
192       /* chroma rounding */
193       dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);
194       dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);
195 
196       /* Chroma */
197       recon_comp (src[1], current_frame[1], lx, lx2, w, h, bx, by, dx, dy, 1);
198       recon_comp (src[2], current_frame[2], lx, lx2, w, h, bx, by, dx, dy, 2);
199     }
200   } else
201   {
202     store_rtype = rtype;
203     rtype = 0;
204     /* B forward prediction */
205     if (pb_frame == IM_PB_FRAMES && (MODB == PBMODE_CBPB_FRW_PRED || MODB == PBMODE_FRW_PRED))
206     {
207       w = 16;
208       h = 16;
209       dx = bdx;
210       dy = bdy;
211 
212       /* Y */
213       recon_comp (src[0], bframe[0], lx, lx2, w, h, bx, by, dx, dy, 0);
214 
215       lx >>= 1;
216       w >>= 1;
217       bx >>= 1;
218       lx2 >>= 1;
219       h >>= 1;
220       by >>= 1;
221       /* chroma rounding */
222       dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);
223       dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);
224 
225       /* Chroma */
226       recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);
227       recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);
228     } else if (pb_frame == IM_PB_FRAMES && (MODB == PBMODE_CBPB_BCKW_PRED || MODB == PBMODE_BCKW_PRED))
229     {
230       lx2 = coded_picture_width;
231       src[0] = prev_I_P_frame[0];
232       src[1] = prev_I_P_frame[1];
233       src[2] = prev_I_P_frame[2];
234 
235       w = 16;
236       h = 16;
237 
238       /* Y */
239       recon_comp (current_frame[0], bframe[0], lx, lx2, w, h, bx, by, 0, 0, 0);
240 
241       lx >>= 1;
242       w >>= 1;
243       bx >>= 1;
244       lx2 >>= 1;
245       h >>= 1;
246       by >>= 1;
247 
248       /* Chroma */
249       recon_comp (current_frame[1], bframe[1], lx, lx2, w, h, bx, by, 0, 0, 1);
250       recon_comp (current_frame[2], bframe[2], lx, lx2, w, h, bx, by, 0, 0, 2);
251     } else
252     {
253       /* B bidir prediction */
254       if (pb_frame == IM_PB_FRAMES)
255       {
256         bdx = 0;
257         bdy = 0;
258       }
259       if (use_4mv && (mode == MODE_INTER4V || mode == MODE_INTER4V_Q))
260       {
261         w = 8;
262         h = 8;
263         /* Y */
264         xvec = yvec = 0;
265         for (comp = 0; comp < 4; comp++)
266         {
267           xvec += dx = (trb) * MV[0][comp + 1][y][x] / trd + bdx;
268           yvec += dy = (trb) * MV[1][comp + 1][y][x] / trd + bdy;
269           xp = bx + ((comp & 1) << 3);
270           yp = by + ((comp & 2) << 2);
271           recon_comp (src[0], bframe[0], lx, lx2, w, h, xp, yp, dx, dy, 0);
272         }
273 
274         /* chroma rounding (table 16/H.263) */
275         dx = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2);
276         dy = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2);
277 
278         lx >>= 1;
279         bx >>= 1;
280         lx2 >>= 1;
281         by >>= 1;
282         /* Chroma */
283         recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);
284         recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);
285       } else
286       {
287         /* B bidir prediction with 16x16 blocks */
288         w = 16;
289         h = 16;
290 
291         dx = (trb) * MV[0][0][y][x] / trd + bdx;
292         dy = (trb) * MV[1][0][y][x] / trd + bdy;
293         /* Y */
294         recon_comp (src[0], bframe[0], lx, lx2, w, h, bx, by, dx, dy, 0);
295 
296         lx >>= 1;
297         w >>= 1;
298         bx >>= 1;
299         lx2 >>= 1;
300         h >>= 1;
301         by >>= 1;
302 
303         xvec = 4 * dx;
304         yvec = 4 * dy;
305 
306         /* chroma rounding (table 16/H.263) */
307         dx = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2);
308         dy = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2);
309 
310         /* Chroma */
311         recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);
312         recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);
313       }
314     }
315     rtype = store_rtype;
316   }
317 }
318 
319 /**********************************************************************
320  *
321  *      Name:        reconstruct_true_B
322  *      Description: Reconstructs true B MB 
323  *
324  *      Input:       position, mb prediction type
325  *      Returns:     
326  *      Side effects:
327  *
328  *      Date: 970831 Author: Michael Gallant --- mikeg@ee.ubc.ca
329  *
330  ***********************************************************************/
331 
332 void reconstruct_true_B (int bx, int by, int true_B_prediction_type)
333 {
334   int w, h, lx, lx2, dxf, dyf, dxb, dyb;
335   int x, y, mode;
336   int bx_chroma, by_chroma;
337   unsigned char *src_f[3], *src_b[3];
338 
339   x = bx / 16 + 1;
340   y = by / 16 + 1;
341   lx = coded_picture_width;
342   w = 16;
343   h = 16;
344 
345   lx2 = coded_picture_width + 64;
346   src_f[0] = edgeframe[0];
347   src_f[1] = edgeframe[1];
348   src_f[2] = edgeframe[2];
349   src_b[0] = nextedgeframe[0];
350   src_b[1] = nextedgeframe[1];
351   src_b[2] = nextedgeframe[2];
352 
353   mode = modemap[y][x];
354 
355   switch (true_B_prediction_type)
356   {
357 
358     case B_DIRECT_PREDICTION:
359 
360       dxf = (true_b_trb) * true_B_direct_mode_MV[0][y][x] / trd;
361       dyf = (true_b_trb) * true_B_direct_mode_MV[1][y][x] / trd;
362       dxb = (true_b_trb - trd) * true_B_direct_mode_MV[0][y][x] / trd;
363       dyb = (true_b_trb - trd) * true_B_direct_mode_MV[1][y][x] / trd;
364 
365       /* Y */
366       recon_comp (src_f[0], tmp_f[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
367       recon_comp (src_b[0], tmp_b[0], lx, lx2, w, h, bx, by, dxb, dyb, 0);
368 
369       lx >>= 1;
370       w >>= 1;
371       bx >>= 1;
372       lx2 >>= 1;
373       h >>= 1;
374       by >>= 1;
375 
376       /* Chroma rounding (table 16/H.263) */
377       dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
378       dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
379       dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1);
380       dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1);
381 
382       /* Chroma */
383       recon_comp (src_f[1], tmp_f[1], lx, lx2, w, h, bx, by, dxf, dyf, 1);
384       recon_comp (src_f[2], tmp_f[2], lx, lx2, w, h, bx, by, dxf, dyf, 2);
385       recon_comp (src_b[1], tmp_b[1], lx, lx2, w, h, bx, by, dxb, dyb, 1);
386       recon_comp (src_b[2], tmp_b[2], lx, lx2, w, h, bx, by, dxb, dyb, 2);
387 
388       bx <<= 1;
389       by <<= 1;
390 
391       /* Average forward and backward prediction. */
392       recon_bidir_average (bx, by);
393 
394       break;
395 
396     case B_FORWARD_PREDICTION:
397 
398       w = 16;
399       h = 16;
400       dxf = MV[0][0][y][x];
401       dyf = MV[1][0][y][x];
402 
403       /* Y */
404       recon_comp (src_f[0], bframe[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
405 
406       lx >>= 1;
407       w >>= 1;
408       bx >>= 1;
409       lx2 >>= 1;
410       h >>= 1;
411       by >>= 1;
412 
413       /* chroma rounding */
414       dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
415       dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
416 
417       /* Chroma */
418       recon_comp (src_f[1], bframe[1], lx, lx2, w, h, bx, by, dxf, dyf, 1);
419       recon_comp (src_f[2], bframe[2], lx, lx2, w, h, bx, by, dxf, dyf, 2);
420 
421       break;
422 
423     case B_BACKWARD_PREDICTION:
424 
425       w = 16;
426       h = 16;
427       dxb = MV[0][5][y][x];
428       dyb = MV[1][5][y][x];
429 
430       /* Y */
431       recon_comp (src_b[0], bframe[0], lx, lx2, w, h, bx, by, dxb, dyb, 0);
432 
433       lx >>= 1;
434       w >>= 1;
435       bx >>= 1;
436       lx2 >>= 1;
437       h >>= 1;
438       by >>= 1;
439       /* chroma rounding */
440       dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1);
441       dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1);
442 
443       /* Chroma */
444       recon_comp (src_b[1], bframe[1], lx, lx2, w, h, bx, by, dxb, dyb, 1);
445       recon_comp (src_b[2], bframe[2], lx, lx2, w, h, bx, by, dxb, dyb, 2);
446 
447       break;
448 
449     case B_BIDIRECTIONAL_PREDICTION:
450 
451       w = 16;
452       h = 16;
453 
454       dxf = MV[0][0][y][x];
455       dyf = MV[1][0][y][x];
456       dxb = MV[0][5][y][x];
457       dyb = MV[1][5][y][x];
458 
459       /* Y */
460       recon_comp (src_f[0], tmp_f[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
461       recon_comp (src_b[0], tmp_b[0], lx, lx2, w, h, bx, by, dxb, dyb, 0);
462 
463       lx >>= 1;
464       w >>= 1;
465       lx2 >>= 1;
466       h >>= 1;
467 
468       bx_chroma = bx >> 1;
469       by_chroma = by >> 1;
470 
471 
472       dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
473       dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
474       dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1);
475       dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1);
476 
477       /* Chroma */
478       recon_comp (src_f[1], tmp_f[1], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 1);
479       recon_comp (src_f[2], tmp_f[2], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 2);
480       recon_comp (src_b[1], tmp_b[1], lx, lx2, w, h, bx_chroma, by_chroma, dxb, dyb, 1);
481       recon_comp (src_b[2], tmp_b[2], lx, lx2, w, h, bx_chroma, by_chroma, dxb, dyb, 2);
482 
483       /* Average forward and backward prediction. */
484       recon_bidir_average (bx, by);
485 
486       break;
487 
488     default:
489 
490       fprintf (stderr, "Illegal scalable prediction type in reconstruct_true_B (recon.c)\n");
491       exit (-1);
492       break;
493 
494   }
495 }
496 
497 /**********************************************************************
498   *
499  *      Name:        reconstruct_ei_ep
500  *      Description: Reconstructs ei and ep MBs
501  *
502  *      Input:       position, mb prediction type
503  *      Returns:     
504  *      Side effects:
505  *
506  *      Date: 971102 Author: Michael Gallant --- mikeg@ee.ubc.ca
507  *
508  ***********************************************************************/
509 void reconstruct_ei_ep (int bx, int by, int ei_ep_prediction_type)
510 {
511   int w, h, lx, lx2, dxf, dyf;
512   int x, y, mode;
513   int bx_chroma, by_chroma;
514   unsigned char *src_fwd[3], *src_up[3], *tmp_fwd[3], *tmp_up[3];
515 
516   /* current_refererence frame should be upsampled already if spatial scalbility is in use */
517 
518   x = bx / 16 + 1;
519   y = by / 16 + 1;
520   lx = coded_picture_width;
521   w = 16;
522   h = 16;
523 
524   lx2 = coded_picture_width + 64;
525   src_fwd[0] = enhance_edgeframe[enhancement_layer_num-2][0];
526   src_fwd[1] = enhance_edgeframe[enhancement_layer_num-2][1];
527   src_fwd[2] = enhance_edgeframe[enhancement_layer_num-2][2];
528   src_up[0] = curr_reference_frame[0];
529   src_up[1] = curr_reference_frame[1];
530   src_up[2] = curr_reference_frame[2];
531 
532   tmp_fwd[0] = tmp_enhance_fwd[enhancement_layer_num-2][0];
533   tmp_fwd[1] = tmp_enhance_fwd[enhancement_layer_num-2][1];
534   tmp_fwd[2] = tmp_enhance_fwd[enhancement_layer_num-2][2];
535   tmp_up[0] = tmp_enhance_up[enhancement_layer_num-2][0];
536   tmp_up[1] = tmp_enhance_up[enhancement_layer_num-2][1];
537   tmp_up[2] = tmp_enhance_up[enhancement_layer_num-2][2];
538 
539   mode = modemap[y][x];
540 
541   switch (ei_ep_prediction_type)
542   {
543 
544     case EP_FORWARD_PREDICTION:
545 
546       w = 16;
547       h = 16;
548       dxf = MV[0][0][y][x];
549       dyf = MV[1][0][y][x];
550 
551       /* Y */
552       recon_comp (src_fwd[0], current_enhancement_frame[enhancement_layer_num-2][0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
553 
554       lx >>= 1;
555       w >>= 1;
556       bx >>= 1;
557       lx2 >>= 1;
558       h >>= 1;
559       by >>= 1;
560 
561       /* chroma rounding */
562       dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
563       dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
564 
565       /* Chroma */
566       recon_comp (src_fwd[1], current_enhancement_frame[enhancement_layer_num-2][1], lx, lx2, w, h, bx, by, dxf, dyf, 1);
567       recon_comp (src_fwd[2], current_enhancement_frame[enhancement_layer_num-2][2], lx, lx2, w, h, bx, by, dxf, dyf, 2);
568 
569       break;
570 
571     case EI_EP_UPWARD_PREDICTION:
572 
573       /* Inter 16x16 */
574       w = 16;
575       h = 16;
576 
577       /* Y */
578       recon_comp (src_up[0], current_enhancement_frame[enhancement_layer_num-2][0], lx, lx, w, h, bx, by, 0, 0, 0);
579 
580       lx >>= 1;
581       w >>= 1;
582       bx >>= 1;
583       lx2 >>= 1;
584       h >>= 1;
585       by >>= 1;
586 
587       /* Chroma */
588       recon_comp (src_up[1], current_enhancement_frame[enhancement_layer_num-2][1], lx, lx, w, h, bx, by, 0, 0, 1);
589       recon_comp (src_up[2], current_enhancement_frame[enhancement_layer_num-2][2], lx, lx, w, h, bx, by, 0, 0, 2);
590 
591       break;
592 
593     case EP_BIDIRECTIONAL_PREDICTION:
594 
595       w = 16;
596       h = 16;
597 
598       dxf = MV[0][0][y][x];
599       dyf = MV[1][0][y][x];
600 
601       /* Y */
602       recon_comp (src_fwd[0], tmp_fwd[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);
603       recon_comp (src_up[0], tmp_up[0], lx, lx, w, h, bx, by, 0, 0, 0);
604 
605       lx >>= 1;
606       w >>= 1;
607       lx2 >>= 1;
608       h >>= 1;
609 
610       bx_chroma = bx >> 1;
611       by_chroma = by >> 1;
612 
613 
614       dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);
615       dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);
616 
617       /* Chroma */
618       recon_comp (src_fwd[1], tmp_fwd[1], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 1);
619       recon_comp (src_fwd[2], tmp_fwd[2], lx, lx2, w, h, bx_chroma, by_chroma, dxf, dyf, 2);
620       recon_comp (src_up[1], tmp_up[1], lx, lx, w, h, bx_chroma, by_chroma, 0, 0, 1);
621       recon_comp (src_up[2], tmp_up[2], lx, lx, w, h, bx_chroma, by_chroma, 0, 0, 2);
622 
623       /* Average forward and backward prediction. */
624       recon_bidir_average (bx, by);
625 
626       break;
627 
628     default:
629 
630       fprintf (stderr, "Illegal scalable prediction type in reconstruct_ei_ep (recon.c)\n");
631       exit (-1);
632 
633       break;
634 
635   }
636 }
637 
638 static void recon_comp (unsigned char *src, unsigned char *dst, 
639                         int lx, int lx2, int w, int h, int x, 
640                         int y, int dx, int dy, int chroma)
641 {
642   int xint, xh, yint, yh;
643   unsigned char *s, *d;
644 
645   xint = dx >> 1;
646   xh = dx & 1;
647   yint = dy >> 1;
648   yh = dy & 1;
649 
650   /* origins */
651   s = src + lx2 * (y + yint) + x + xint;
652   d = dst + lx * y + x;
653 
654   if (!xh && !yh)
655     if (w != 8)
656       rec (s, d, lx, lx2, h);
657     else
658       recc (s, d, lx, lx2, h);
659   else if (!xh && yh)
660     if (w != 8)
661       recv (s, d, lx, lx2, h);
662     else
663       recvc (s, d, lx, lx2, h);
664   else if (xh && !yh)
665     if (w != 8)
666       rech (s, d, lx, lx2, h);
667     else
668       rechc (s, d, lx, lx2, h);
669   else
670    /* if (xh && yh) */ if (w != 8)
671     rec4 (s, d, lx, lx2, h);
672   else
673     rec4c (s, d, lx, lx2, h);
674 }
675 
676 static void rec (unsigned char *s, unsigned char *d, 
677                  int lx, int lx2, int h)
678 {
679   int j;
680 
681   for (j = 0; j < h; j++)
682   {
683     d[0] = s[0];
684     d[1] = s[1];
685     d[2] = s[2];
686     d[3] = s[3];
687     d[4] = s[4];
688     d[5] = s[5];
689     d[6] = s[6];
690     d[7] = s[7];
691     d[8] = s[8];
692     d[9] = s[9];
693     d[10] = s[10];
694     d[11] = s[11];
695     d[12] = s[12];
696     d[13] = s[13];
697     d[14] = s[14];
698     d[15] = s[15];
699     s += lx2;
700     d += lx;
701   }
702 }
703 
704 /**********************************************************************
705  *
706  *      Name:        recon_bidir_average
707  *      Description: move average of bidir predicted blocks into current frame
708  *
709  *      Input:       absolute position of current MB
710  *
711  *      Returns:
712  *      Side effects:
713  *
714  *      Date: 971102 Author: Michael Gallant --- mikeg@ee.ubc.ca
715  *
716  ***********************************************************************/
717 static void recon_bidir_average (int bx, int by)
718 {
719   int i, iincr, cc, comp;
720   unsigned char *avg, *forw, *backw;
721   unsigned char *prev_frame[3], *next_frame[3], *curr[3];
722 
723   /* B picture */
724   if (PCT_B == pict_type)
725   {
726     prev_frame[0] = tmp_f[0];
727     prev_frame[1] = tmp_f[1];
728     prev_frame[2] = tmp_f[2];
729     next_frame[0] = tmp_b[0];
730     next_frame[1] = tmp_b[1];
731     next_frame[2] = tmp_b[2];
732     curr[0] = current_frame[0];
733     curr[1] = current_frame[1];
734     curr[2] = current_frame[2];
735   }
736   /* EP picture */
737   else
738   {
739     prev_frame[0] = tmp_enhance_fwd[enhancement_layer_num-2][0];
740     prev_frame[1] = tmp_enhance_fwd[enhancement_layer_num-2][1];
741     prev_frame[2] = tmp_enhance_fwd[enhancement_layer_num-2][2];
742     next_frame[0] = tmp_enhance_up[enhancement_layer_num-2][0];
743     next_frame[1] = tmp_enhance_up[enhancement_layer_num-2][1];
744     next_frame[2] = tmp_enhance_up[enhancement_layer_num-2][2];
745     curr[0] = current_enhancement_frame[enhancement_layer_num-2][0];
746     curr[1] = current_enhancement_frame[enhancement_layer_num-2][1];
747     curr[2] = current_enhancement_frame[enhancement_layer_num-2][2];
748   }
749 
750   for (comp = 0; comp < 6; ++comp)
751   {
752     cc = (comp < 4) ? 0 : (comp & 1) + 1; /* color component index */
753 
754     /* luminance */
755     if (cc == 0)
756     {
757       avg = curr[cc] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
758       forw = prev_frame[cc] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
759       backw = next_frame[cc] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
760       iincr = coded_picture_width;
761     }
762     /* chrominance */
763     else
764     {
765       /* scale coordinates */
766       if (4 == comp)
767       {
768         bx >>= 1;
769         by >>= 1;
770       }
771       avg = curr[cc] + chrom_width * by + bx;
772       forw = prev_frame[cc] + chrom_width * by + bx;
773       backw = next_frame[cc] + chrom_width * by + bx;
774       iincr = chrom_width;
775     }
776 
777     for (i = 0; i < 8; i++)
778     {
779       avg[0] = (forw[0] + backw[0]) / 2;
780       avg[1] = (forw[1] + backw[1]) / 2;
781       avg[2] = (forw[2] + backw[2]) / 2;
782       avg[3] = (forw[3] + backw[3]) / 2;
783       avg[4] = (forw[4] + backw[4]) / 2;
784       avg[5] = (forw[5] + backw[5]) / 2;
785       avg[6] = (forw[6] + backw[6]) / 2;
786       avg[7] = (forw[7] + backw[7]) / 2;
787       avg += iincr;
788       forw += iincr;
789       backw += iincr;
790     }
791   }
792 }
793 
794 
795 static void recc (unsigned char *s, unsigned char *d, 
796                   int lx, int lx2, int h)
797 {
798   int j;
799 
800   for (j = 0; j < h; j++)
801   {
802     d[0] = s[0];
803     d[1] = s[1];
804     d[2] = s[2];
805     d[3] = s[3];
806     d[4] = s[4];
807     d[5] = s[5];
808     d[6] = s[6];
809     d[7] = s[7];
810     s += lx2;
811     d += lx;
812   }
813 }
814 
815 static void reco (unsigned char *s, int *d, int lx, int lx2, 
816                   int addflag, int c, int xa, int xb, 
817                   int ya, int yb)
818 {
819   int i, j;
820   int *om;
821 
822   om = &OM[c][ya][0];
823 
824   if (!addflag)
825   {
826     for (j = ya; j < yb; j++)
827     {
828       for (i = xa; i < xb; i++)
829       {
830         d[i] = s[i] * om[i];
831       }
832       s += lx2;
833       d += lx;
834       om += 8;
835     }
836   } else
837   {
838     for (j = ya; j < yb; j++)
839     {
840       for (i = xa; i < xb; i++)
841       {
842         d[i] += s[i] * om[i];
843       }
844       s += lx2;
845       d += lx;
846       om += 8;
847     }
848   }
849 }
850 
851 static void rech (unsigned char *s, unsigned char *d, 
852                   int lx, int lx2, int h)
853 {
854   unsigned char *dp, *sp;
855   int j;
856   unsigned int s1, s2;
857 
858   sp = s;
859   dp = d;
860   for (j = 0; j < h; j++)
861   {
862     s1 = sp[0];
863     dp[0] = (unsigned int) (s1 + (s2 = sp[1]) + 1 - rtype) >> 1;
864     dp[1] = (unsigned int) (s2 + (s1 = sp[2]) + 1 - rtype) >> 1;
865     dp[2] = (unsigned int) (s1 + (s2 = sp[3]) + 1 - rtype) >> 1;
866     dp[3] = (unsigned int) (s2 + (s1 = sp[4]) + 1 - rtype) >> 1;
867     dp[4] = (unsigned int) (s1 + (s2 = sp[5]) + 1 - rtype) >> 1;
868     dp[5] = (unsigned int) (s2 + (s1 = sp[6]) + 1 - rtype) >> 1;
869     dp[6] = (unsigned int) (s1 + (s2 = sp[7]) + 1 - rtype) >> 1;
870     dp[7] = (unsigned int) (s2 + (s1 = sp[8]) + 1 - rtype) >> 1;
871     dp[8] = (unsigned int) (s1 + (s2 = sp[9]) + 1 - rtype) >> 1;
872     dp[9] = (unsigned int) (s2 + (s1 = sp[10]) + 1 - rtype) >> 1;
873     dp[10] = (unsigned int) (s1 + (s2 = sp[11]) + 1 - rtype) >> 1;
874     dp[11] = (unsigned int) (s2 + (s1 = sp[12]) + 1 - rtype) >> 1;
875     dp[12] = (unsigned int) (s1 + (s2 = sp[13]) + 1 - rtype) >> 1;
876     dp[13] = (unsigned int) (s2 + (s1 = sp[14]) + 1 - rtype) >> 1;
877     dp[14] = (unsigned int) (s1 + (s2 = sp[15]) + 1 - rtype) >> 1;
878     dp[15] = (unsigned int) (s2 + sp[16] + 1 - rtype) >> 1;
879     sp += lx2;
880     dp += lx;
881   }
882 }
883 
884 static void rechc (unsigned char *s, unsigned char *d, 
885                    int lx, int lx2, int h)
886 {
887   unsigned char *dp, *sp;
888   int j;
889   unsigned int s1, s2;
890 
891   sp = s;
892   dp = d;
893   for (j = 0; j < h; j++)
894   {
895     s1 = sp[0];
896     dp[0] = (unsigned int) (s1 + (s2 = sp[1]) + 1 - rtype) >> 1;
897     dp[1] = (unsigned int) (s2 + (s1 = sp[2]) + 1 - rtype) >> 1;
898     dp[2] = (unsigned int) (s1 + (s2 = sp[3]) + 1 - rtype) >> 1;
899     dp[3] = (unsigned int) (s2 + (s1 = sp[4]) + 1 - rtype) >> 1;
900     dp[4] = (unsigned int) (s1 + (s2 = sp[5]) + 1 - rtype) >> 1;
901     dp[5] = (unsigned int) (s2 + (s1 = sp[6]) + 1 - rtype) >> 1;
902     dp[6] = (unsigned int) (s1 + (s2 = sp[7]) + 1 - rtype) >> 1;
903     dp[7] = (unsigned int) (s2 + sp[8] + 1 - rtype) >> 1;
904     sp += lx2;
905     dp += lx;
906   }
907 }
908 
909 static void recho (unsigned char *s, int *d, int lx, int lx2, 
910                    int addflag, int c, int xa, int xb, int ya, int yb)
911 {
912   int *dp, *om;
913   unsigned char *sp;
914   int i, j;
915 
916   sp = s;
917   dp = d;
918   om = &OM[c][ya][0];
919 
920   if (!addflag)
921   {
922     for (j = ya; j < yb; j++)
923     {
924       for (i = xa; i < xb; i++)
925       {
926         dp[i] = (((unsigned int) (sp[i] + sp[i + 1] + 1 - rtype)) >> 1) * om[i];
927       }
928       sp += lx2;
929       dp += lx;
930       om += 8;
931     }
932   } else
933   {
934     for (j = ya; j < yb; j++)
935     {
936       for (i = xa; i < xb; i++)
937       {
938         dp[i] += (((unsigned int) (sp[i] + sp[i + 1] + 1 - rtype)) >> 1) * OM[c][j][i];
939       }
940       sp += lx2;
941       dp += lx;
942       om += 8;
943     }
944   }
945 }
946 
947 static void recv (unsigned char *s, unsigned char *d, 
948                   int lx, int lx2, int h)
949 {
950   unsigned char *dp, *sp, *sp2;
951   int j;
952 
953   sp = s;
954   sp2 = s + lx2;
955   dp = d;
956   for (j = 0; j < h; j++)
957   {
958     dp[0] = (unsigned int) (sp[0] + sp2[0] + 1 - rtype) >> 1;
959     dp[1] = (unsigned int) (sp[1] + sp2[1] + 1 - rtype) >> 1;
960     dp[2] = (unsigned int) (sp[2] + sp2[2] + 1 - rtype) >> 1;
961     dp[3] = (unsigned int) (sp[3] + sp2[3] + 1 - rtype) >> 1;
962     dp[4] = (unsigned int) (sp[4] + sp2[4] + 1 - rtype) >> 1;
963     dp[5] = (unsigned int) (sp[5] + sp2[5] + 1 - rtype) >> 1;
964     dp[6] = (unsigned int) (sp[6] + sp2[6] + 1 - rtype) >> 1;
965     dp[7] = (unsigned int) (sp[7] + sp2[7] + 1 - rtype) >> 1;
966     dp[8] = (unsigned int) (sp[8] + sp2[8] + 1 - rtype) >> 1;
967     dp[9] = (unsigned int) (sp[9] + sp2[9] + 1 - rtype) >> 1;
968     dp[10] = (unsigned int) (sp[10] + sp2[10] + 1 - rtype) >> 1;
969     dp[11] = (unsigned int) (sp[11] + sp2[11] + 1 - rtype) >> 1;
970     dp[12] = (unsigned int) (sp[12] + sp2[12] + 1 - rtype) >> 1;
971     dp[13] = (unsigned int) (sp[13] + sp2[13] + 1 - rtype) >> 1;
972     dp[14] = (unsigned int) (sp[14] + sp2[14] + 1 - rtype) >> 1;
973     dp[15] = (unsigned int) (sp[15] + sp2[15] + 1 - rtype) >> 1;
974     sp += lx2;
975     sp2 += lx2;
976     dp += lx;
977   }
978 }
979 
980 static void recvc (unsigned char *s, unsigned char *d, 
981                    int lx, int lx2, int h)
982 {
983   unsigned char *dp, *sp, *sp2;
984   int j;
985 
986   sp = s;
987   sp2 = s + lx2;
988   dp = d;
989 
990   for (j = 0; j < h; j++)
991   {
992     dp[0] = (unsigned int) (sp[0] + sp2[0] + 1 - rtype) >> 1;
993     dp[1] = (unsigned int) (sp[1] + sp2[1] + 1 - rtype) >> 1;
994     dp[2] = (unsigned int) (sp[2] + sp2[2] + 1 - rtype) >> 1;
995     dp[3] = (unsigned int) (sp[3] + sp2[3] + 1 - rtype) >> 1;
996     dp[4] = (unsigned int) (sp[4] + sp2[4] + 1 - rtype) >> 1;
997     dp[5] = (unsigned int) (sp[5] + sp2[5] + 1 - rtype) >> 1;
998     dp[6] = (unsigned int) (sp[6] + sp2[6] + 1 - rtype) >> 1;
999     dp[7] = (unsigned int) (sp[7] + sp2[7] + 1 - rtype) >> 1;
1000     sp += lx2;
1001     sp2 += lx2;
1002     dp += lx;
1003   }
1004 }
1005 
1006 static void recvo (unsigned char *s, int *d, int lx, int lx2, 
1007                    int addflag, int c, int xa, int xb, int ya, 
1008