/*****************************************************************************
 *
 * This software module was originally developed by
 *
 *   Isabelle Corset (Philips / ACTS-MoMuSyS)       	       	     
 *   Michael Wollborn (TUH / ACTS-MoMuSyS)                    	          
 *   Cor Quist (KPN / ACTS-MoMuSyS)        	                          
 *   Angel Pacheco (UPM / ACTS-MoMuSyS)        	                          
 *   J.Ignacio Ronda (UPM / ACTS-MoMuSyS) 
 *
 * and edited by
 * 
 *   Paulo Nunes (IST / ACTS-MoMuSyS)        	                         
 *   Robert Danielsen (Telenor / ACTS-MoMuSyS)                            
 *   Jan De Lameillieure (Heinrich-Hertz-Institut Berlin / ACTS-MoMuSyS) 
 *   Minhua Zhou   (Heinrich-Hertz-Institut Berlin / ACTS-MoMuSyS)  
 *   Aasmund Sandvand (Telenor / ACTS-MoMuSyS)                                 
 *   Fernando Jaureguizar (UPM / ACTS-MoMuSyS)                 	     
 *   Luis Ducla-Soares (IST / ACTS-MoMuSys)
 *   Bob Eifrig (NextLevel Systems)
 *   Michael Frater (UNSW)
 *
 * in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard.
 * This software module is an implementation of a part of one or more MPEG-4
 * Video (ISO/IEC 14496-2) tools as specified by the MPEG-4 Video (ISO/IEC
 * 14496-2) standard.
 *
 * ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard free
 * license to this software module or modifications thereof for use in hardware
 * or software products claiming conformance to the MPEG-4 Video (ISO/IEC
 * 14496-2) standard.
 *
 * Those intending to use this software module in hardware or software products
 * are advised that its use may infringe existing patents. The original
 * developer of this software module and his/her company, the subsequent
 * editors and their companies, and ISO/IEC have no liability for use of this
 * software module or modifications thereof in an implementation. Copyright is
 * not released for non MPEG-4 Video (ISO/IEC 14496-2) Standard conforming
 * products.
 *
 * ACTS-MoMuSys partners retain full right to use the code for his/her own
 * purpose, assign or donate the code to a third party and to inhibit third
 * parties from using the code for non MPEG-4 Video (ISO/IEC 14496-2) Standard
 * conforming products. This copyright notice must be included in all copies or
 * derivative works.
 *
 * Copyright (c) 1996
 *
 *****************************************************************************/

/***********************************************************HeaderBegin*******
 *                                                                         
 * File:	combined_decode.c
 *
 * Author:	Jan De Lameillieure (HHI) <jan@hhi.de>
 * Created:	18-Jan-97
 *                                                                         
 * Description: Decoding VOP in combined mode
 *
 * Notes: 	
 *              starting point of this file was text_decode.c of 16-Jan-97
 *
 * Modified: 04.02.97 Noel O'Connor : removed all calls to assert()
 *           07-Feb-1997, M.Wollborn: changed in order to treat skipped MBs
 *	                      correctly
 *           15-APR-97 Jan De Lameillieure : removed unused variables which were 
 *                       obsolete since upgrade from MMR to M4R
 *           15-APR-97 Jan De Lameillieure : added the inverse SA-DCT 
 *           22-APR-97 Michael Wollborn: changed name of BlockDequant to 
 *	                      BlockDequantH263 and changed
 *	                      stuff for MPEG-like quantization
 *           01.05.97 Luis Ducla-Soares:added functions for the error resilient
 *                       combined mode with data partitioning:
 *                       DecodeVopCombinedShapeTextureIntraErrRes(),
 *                       DecodeVopCombinedMotionShapeTextureInterErrRes(), 
 *                       GetMBheaderErrRes(), GetMBheaderMotionErrRes(),
 *                       GetMBheaderTextErrRes(), GetMBvectorsErrRes()
 *	 	                   and GetMBblockdataErrRes().
 *           15.05.97 Luis Ducla-Soares: corrected the remultiplexing of the DCT data
 *                       in the combined error resilient mode with 
 *                       data partitioning. Cleaned up the code.
 *           21.05.97 A. Pacheco (UPM): Modifications in several functions
 *                       to have just one function to compute the MVs prediction
 *                       in both encoder/decoder (find_pmvs)
 *           26.05.97 Minhua Zhou: added mot_padding.h and VopPadding() 
 *           16.06.97 Angel Pacheco: unified the TRANSPARENT modes.
 *      16-JUN-97 Jan De Lameillieure : renaming some include files to sadct_*
 *      16-JUN-97 Jan De Lameillieure : added Kaup-SADCT
 *           24.07.97 Minhua Zhou: added B-VOP decoding
 *           04.08.97 Minhua Zhou: renamed advanced_prediction_disable
 *      04.08.97 Minhua Zhou: added intra_dc_vlc_thr (switched)
 *      12.08.97 Minhua Zhou: added decoding of DQUANT in combined mode 
 *      05.09.97 Fernando Jaureguizar: deleted unnecessary code with aux_vop
 *      04.01.98 Michael Frater: support for non-8-bit video
 *			13.01.98 Noel Brady: support for error resileint shape in B-VOPs
 *      17.04.98 Minhua Zhou: added shape coding modifications for B-VOPs,
 *				in non-error resilience and error resilience
 *				mode, in temporal scalability
 *
 ***********************************************************HeaderEnd*********/

/************************    INCLUDE FILES    ********************************/

#include "io_generic.h"
#include "vm_common_defs.h"
#include "combined_decode.h"
#include "text_decode_mb.h"
#include "zigzag.h"
#include "mot_decode.h"
#include "mot_util.h"
#include "mot_comp.h"
#include "alp_common_def.h"
#include "alp_dec_mom.h" 
#include "alp_dec_header.h" 
#ifndef _WD_MODE_
#include "sadct_momusys.h"
#include "sadct_momusys_kaup.h"
#endif
#include "mot_padding.h"
#include "concealment.h"
#include "alp_common_util.h"


#define VM5_DEBUG_

/*** 8/18 TPS */
#include "vm_dec_main.h"
extern Int   temporal_scalability;
/* 8/18 TPS ***/

/*** 10/27 TPS */
/* extern Int prev_ref;
extern Int next_ref; */
/* 10/27 TPS ***/

#ifdef _DEBUG_SPSC2_
static Int tmp_cnt=0;
#endif

/*** 4/19 changed by SHARP */
#include "scal_dec.h"
/* 4/19 changed by SHARP ***/

/***********************************************************CommentBegin******
 *
 * -- DecodeVopCombinedShapeTextureIntra -- 
 *
 * Author :		
 *	Jan De Lameillieure (HHI) <jan@hhi.de>
 *
 * Created :		
 *	18-Jan-97
 *
 * Purpose :		
 *      Decodes combined shape / texture for INTRA VOPs
 *
 * Arguments in : 	
 *	Bitstream *stream	combined shape / texture bitstream
 *	Trace  *trace		flag for tracing the process.
 *
 *
 * Arguments in/out :	
 *	Vop *rec_vop		alpha plane is supposed to be filled
 *				already / YUV components.
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *      Starting point for this function was DecodeVopTextureIntra() as of 16-Jan-97
 *
 * See also :
 *	
 *
 * Modified : 
 *	  06.08.97: Noel Brady: Added mods for BINARY_SHAPE_ONLY
 *    04.11.97: Minhua Zhou: updated DC/AC prediction 
 *    12.12.97: Bob Eifrig: interlaced video decode
 *
 ***********************************************************CommentEnd********/

Void DecodeVopCombinedShapeTextureIntra(Bitstream * stream, Int vo_id, 
							Trace *trace, Vop * rec_vop)
{
		Int 	vol_id = GetVopId(rec_vop);
    Int 	      	ef=0, *error_flag = &ef; 
    Int                 mbnum, x_pos, y_pos, i, j;
    Int                 rec_height;
    Int 		rec_width;
    Int			MB_in_height, MB_in_width;
    Int                 B_in_width, B_in_height;
    Macroblock          *mblock;
    Image               *Y_rec, *U_rec, *V_rec, *A_rec;
    Short		*alpha;
    Int                 vop_quant,intra_dcpred_disable;
    Int                 skipped_flag=0;
    Image               *MB_decisions;
    UInt		new_vop;
    SInt		*pMB_decisions;
    Int 		MB_transp_pattern[4];
    Int 		***DC_store;
    Int 		m, n, QP;
    Int                 coded;
    UInt CBP;
    Int  ACpred_flag=-1;
    UInt mode;
    Int amb_type=0,mvda=0;
    SInt *QP_store;
    Int MB_non_trans_count=0;
    Int interlace_info;
 /* for Low Latency Static SPRITE */	
    Int	*tab_transmit	= GetVopSpriteTabTransmit(rec_vop);
    Int	numblocks_x	= GetVopSpriteHdim(rec_vop)/16;
    Int	*tab_amb_type	= GetVopSpriteTabAmbType(rec_vop);
    Int	***tab_DC_store = GetVopSpriteTabDCStore(rec_vop);
    Int	*tab_mvda	= GetVopSpriteTabMvda(rec_vop);
    SInt *tab_QP_store	= GetVopSpriteTabQPStore(rec_vop);
    Int	u, comp, vop_quant_prev;

 
    /*****
     *
     *	Set some useful parameters
     *
     *****/
    rec_height = GetVopHeight (rec_vop);
    rec_width = GetVopWidth (rec_vop);
    MB_in_height = rec_height / MB_SIZE;
    MB_in_width = rec_width / MB_SIZE;
    B_in_width = 2 * MB_in_width;
    B_in_height = 2 * MB_in_height;
    QP_store = (SInt *) GetImageData(GetVopQP(rec_vop));
  
    /* allocate space for 3D matrix to keep track of prediction values
       for DC/AC prediction */
    
    DC_store = (Int ***)calloc(MB_in_width*MB_in_height,
				       sizeof(Int **));
    for (i = 0; i < MB_in_width*MB_in_height; i++)
    {
	DC_store[i] = (Int **)calloc(6, sizeof(Int *));
	for (j = 0; j < 6; j++)
	    DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
    }
    
    intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
  
    MB_decisions    = AllocImage(MB_in_width,MB_in_height,SHORT_TYPE);

    /*****
     *
     *	Get the image fields of the VOP
     *
     *****/
    Y_rec = GetVopY (rec_vop);
    U_rec = GetVopU (rec_vop);
    V_rec = GetVopV (rec_vop);
    A_rec = GetVopA (rec_vop);
    alpha=(Short *)GetImageData(A_rec);
  
    /*****
     *
     *	Get VOP quantizer and allocate MB structure
     *
     *****/
    vop_quant = GetVopQuantizer (rec_vop);
    QP = vop_quant;
    vop_quant_prev = vop_quant;

    mblock = (Macroblock *) malloc (sizeof (Macroblock));

    if (mblock == NULL)
    {
	printf (" Error allocating macroblock\n");
	exit(1);
    }

if (GetVopSpriteUsage(rec_vop)==STATIC_SPRITE)
      if (GetVopLowLatencySpriteEnable(rec_vop))
	printf("\tStart I VOP decoding (object-piece of low latency static sprite)\n");
      else
	printf("\tStart I VOP decoding of the basic static sprite\n");
else
    printf("Start I VOP decoding \n");

    /*****
     *
     *	Loop over all MBs, decode texture of each MB
     *
     *****/
    new_vop = 1;
    pMB_decisions = (SInt *)GetImageData(MB_decisions);
  
    for (y_pos = 0; y_pos < MB_in_height; y_pos++)
      for (x_pos = 0; x_pos < MB_in_width; x_pos++)
	{

	  coded=0;
	  mbnum = y_pos * MB_in_width + x_pos;
         if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY) {
	  if (MB_non_trans_count>=MB_trace_thres)
             SetTraceLevelsZero(trace);
          else
             SetTraceLevelsDefault(trace);
          }
         

	  /* Store the QP value for later use in AC prediction */
	  QP_store[mbnum] = (SInt) QP;
 	  
	  trace->trace = trace->MB_header;
	  if (trace->trace)
	    {
              fprintf (trace->fp_trace,
                 "\n>>>   Decoding Macroblock %d @ %d - Combined Motion/Shape/Text\n",
                 (int)mbnum, stream->bitcnt);
	    }

	  trace->trace = trace->MB_shape;
         if (GetVopShape(rec_vop)) {
	 if (GetVopSpriteUsage(rec_vop) != STATIC_SPRITE ||
		  GetVopLowLatencySpriteEnable(rec_vop) == 0 ||
		  (GetVopLowLatencySpriteEnable(rec_vop) &&
			tab_transmit[y_pos*numblocks_x+x_pos] == 0))
	 {
	  DecodeFirst(  stream, 
		        vo_id, 
		        vol_id, 
			y_pos, 
			x_pos, 
			&amb_type, 
			&mvda, 
			0,
			0, 
			rec_vop,
                        GetVopPrevTemp(rec_vop),
			trace);

	  /* fill the alpha map with the decoded pixels for this MB */
	  AlphaDecodeMB(rec_vop, 
			(Vop *)NULL, 
			vo_id,
			vol_id,
			y_pos, 
			x_pos, 
			&amb_type,
			&mvda, 
			0,
			MB_decisions,
			(Image *)NULL,
			(Image *)NULL,
			(Image *)NULL,
			(Image *)NULL,	
			(Image *)NULL,
			(Image *)NULL,
			0,
			stream,
			trace,
			error_flag);
			
	if (GetVopSpriteUsage(rec_vop) == STATIC_SPRITE &&
		  GetVopLowLatencySpriteEnable(rec_vop))
		{
		tab_amb_type[y_pos*numblocks_x+x_pos] = amb_type;
		tab_mvda[y_pos*numblocks_x+x_pos] = mvda;
		}
             } /* STATIC_SPRITE */
           }/* GetVopShape */

	if (GetVopSpriteUsage(rec_vop) == STATIC_SPRITE &&
		  GetVopLowLatencySpriteEnable(rec_vop))
		if (tab_transmit[y_pos*numblocks_x+x_pos] != 0)
		{
         	if (GetVopShape(rec_vop)) 
			{
			amb_type=tab_amb_type[y_pos*numblocks_x+x_pos];
			mvda=tab_mvda[y_pos*numblocks_x+x_pos];
			MakeMBtype2(amb_type,y_pos,x_pos,rec_vop);
			}
		for (comp=0 ; comp<6 ; comp++)
		for (u=0 ; u<15 ; u++)
		     DC_store[mbnum][comp][u] = 
			tab_DC_store[y_pos*numblocks_x+x_pos][comp][u];
	  if (amb_type != 1) /* if this is MB not all_0 */
		vop_quant = (Int)tab_QP_store[y_pos*numblocks_x+x_pos];
		}

	  if(trace->trace)
	  fprintf(trace->fp_trace, "----------\n");
	  trace->trace = trace->MB_header;
        
	if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY)   /* BSO_NOEL */
	{
	  if (amb_type != 1) /* if this is MB not all_0 */
	    {
             /* calculating MB_transp_pattern */
	      for(i=0;i<4;i++)
	        MB_transp_pattern[i]=1;
	      
	      for(i=0;i<B_SIZE;i++)
	        for(j=0;j<B_SIZE;j++)
		if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			 (x_pos * MB_SIZE) +j] != 0)
		  MB_transp_pattern[0]=0;
	  
	      for(i=0;i<B_SIZE;i++)
	        for(j=B_SIZE;j<2*B_SIZE;j++)
		if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			 (x_pos * MB_SIZE) +j] != 0)
		  MB_transp_pattern[1]=0;
	      
	      for(i=B_SIZE;i<2*B_SIZE;i++)
	        for(j=0;j<B_SIZE;j++)
		if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			 (x_pos * MB_SIZE) +j] != 0)
		  MB_transp_pattern[2]=0;
	      
	      for(i=B_SIZE;i<2*B_SIZE;i++)
	        for(j=B_SIZE;j<2*B_SIZE;j++)
		  if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   (x_pos * MB_SIZE) +j] != 0)
		  MB_transp_pattern[3]=0;


	      /* set MB_decisions for this MB on intra */
	      *((SInt *) GetImageData (MB_decisions) + mbnum) = INTRA;

		 interlace_info = GetVopInterlaced(rec_vop);
	       
	     if (GetVopSpriteUsage(rec_vop) != STATIC_SPRITE ||
		  GetVopLowLatencySpriteEnable(rec_vop)==0 ||
		  (GetVopLowLatencySpriteEnable(rec_vop) &&
	     		tab_transmit[y_pos*numblocks_x+x_pos] == 0))
	      {
	      vop_quant = vop_quant_prev;
	      GetMBheader(INTRA_VOP,&new_vop,
			  intra_dcpred_disable,
			  &vop_quant,stream,mbnum,trace,MB_decisions,
			  mblock,&skipped_flag, error_flag,
			  DC_store, QP_store, QP, &coded, 
			  &CBP, &ACpred_flag, &mode,
			  &interlace_info,
              MB_transp_pattern,rec_vop);
	      vop_quant_prev = vop_quant;
	      if (*error_flag == RETURN) exit(1);
	      if (GetVopSpriteUsage(rec_vop) == STATIC_SPRITE &&
		    GetVopLowLatencySpriteEnable(rec_vop))
	      		tab_QP_store[y_pos*numblocks_x+x_pos] =
				 (SInt) vop_quant;
	      }
              QP_store[mbnum] = (SInt) vop_quant;
	  
	    }
	  	  	  
	  if (amb_type == 2) 
	    { /* if this MB is a multilevel MB */
	      
	    }
	  
	  if (amb_type != 1) /* if it is not a transparent MB */
	    {
               MB_non_trans_count++;
	    	if (GetVopSpriteUsage(rec_vop) != STATIC_SPRITE ||
		  	GetVopLowLatencySpriteEnable(rec_vop) == 0 ||
		  	(GetVopLowLatencySpriteEnable(rec_vop) &&
	    			tab_transmit[y_pos*numblocks_x+x_pos] == 0))
		{
	    	if (coded)
	        GetMBblockdata(MB_transp_pattern,
			       intra_dcpred_disable,
			       vop_quant,stream,mbnum,trace,
			       mblock,&skipped_flag, error_flag, 
			       MB_in_width, 
			       DC_store, QP_store, QP,
			       CBP, ACpred_flag, mode,
			       alpha,
				   interlace_info,
				   rec_vop);
	       if (*error_flag == RETURN) exit(1);
 	       }
	      
              QP =vop_quant;
	      
	      
	      if (skipped_flag == 1)
	      /* (skipped_flag==1) Clear the skipped MB */
	        MBzero (mblock);
	    }
	  else 
	    {			/* transparent MB */
	      MBzero (mblock);
	      /* set all alpha block pixels to zero */
	      /* Fill DC_store with default coeff values */
	      for (m = 0; m < 6; m++) 
		{
		  DC_store[mbnum][m][0] = GetVopMidGrey(rec_vop)*8;
		  for (n = 1; n < 15; n++)
		    DC_store[mbnum][m][n] = 0;
		}
	    }
	  
	if (GetVopSpriteUsage(rec_vop) == STATIC_SPRITE &&
		    GetVopLowLatencySpriteEnable(rec_vop))
	    if (tab_transmit[y_pos*numblocks_x+x_pos] == 0)
	       for (comp=0 ; comp<6 ; comp++)
	       for (u=0 ; u<15 ; u++)
			tab_DC_store[y_pos*numblocks_x+x_pos][comp][u] = 
						DC_store[mbnum][comp][u];
	    
	if (GetVopSpriteUsage(rec_vop) != STATIC_SPRITE ||
		GetVopLowLatencySpriteEnable(rec_vop) == 0 ||
		  (GetVopLowLatencySpriteEnable(rec_vop) &&
			tab_transmit[y_pos*numblocks_x+x_pos] == 0))
	  FillVop (mblock, mbnum, Y_rec, U_rec, V_rec);

	if (GetVopSpriteUsage(rec_vop) == STATIC_SPRITE &&
		GetVopLowLatencySpriteEnable(rec_vop))
		  if (tab_transmit[y_pos*numblocks_x+x_pos] == 0)
			tab_transmit[y_pos*numblocks_x+x_pos] = 1;

	} /* BSO_NOEL */
	else 
		{
		if (trace->MB_sdata)
			PrintMBShapeData(rec_vop,x_pos,y_pos,trace);
		}
	}
    
    /* Free allocated memory for 3D matrix */
    
    for (i = 0; i < MB_in_width*MB_in_height; i++)
      {
	for (j = 0; j < 6; j++) 
	  free((Char *)DC_store[i][j]);
	free((Char *)DC_store[i]);
      }
    free((Char *)DC_store);
    
    FreeImage(MB_decisions);
    free ((Char *)mblock);
    
    return;
}


/***********************************************************CommentBegin******
 *
 * -- DecodeVopDataPartitioningIntraErrRes -- 
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	1-May-97
 *
 * Purpose :		
 *      Decodes shape / texture for INTRA VOPs for the combined error
 *      resilient mode with data partitioning
 *
 * Arguments in : 	
 *	Bitstream *stream	combined shape / texture bitstream
 *      Int vo_id               video object identification
 *	Trace  *trace		flag for tracing the process.
 *
 *
 * Arguments in/out :	
 *	Vop *rec_vop		alpha plane is supposed to be filled
 *				already / YUV components.
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *      based on DecodeVopCombinedShapeTextureIntra() as of 01.05.97
 *
 * See also :
 *	
 *
 * Modified : 
 *      15.05.97 Luis Ducla-Soares: corrected the remultiplexing of the DCT data
 *                                  in the combined error resilient mode with 
 *                                  data partitioning. Cleaned up the code.
 *      04.11.97 Minhua Zhou: updated DC/AC prediction
 *			19.11.97 Noel Brady: quant scale is not present when in shape only mode
 *      09.12.97 Luis Ducla-Soares: changed the name of the function from
 *                                  DecodeVopCombinedShapeTextureIntraErrRes to
 *                                  DecodeVopDataPartitioningIntraErrRes.
 *      10.12.97 Luis Ducla-Soares: restructured the code. moved the code in
 *                                  the macroblock loop to a new function: 
 *                                  DecodeVideoPacketDataPartitioningIntraErrRes.
 *
 ***********************************************************CommentEnd********/

Void DecodeVopDataPartitioningIntraErrRes(Bitstream * stream, Int vo_id, 
					Trace *trace, Vop * rec_vop)
{
  Int 	      	ef=0, *error_flag = &ef; 
  Int           mbnum, i, j;
  Int           rec_height;
  Int 		rec_width;
  Int		MB_in_height, MB_in_width;
  Int           B_in_width, B_in_height;
  Macroblock    *mblock;
  Image         *Y_rec, *U_rec, *V_rec, *A_rec;
  Short		*alpha;
  Int           vop_quant, intra_dcpred_disable;
  Image         *MB_decisions;
  UInt		new_vop;
  SInt		*pMB_decisions;
  Int           ***DC_store;
  Int           **slice_nb;
  Int           slice_counter;
  SInt          *QP_store;
  Int           QP;
  Int           counter, next_MB;
  Int           MB_in_VOP;
  Int           MB_in_VOP_length;
  HeaderInfo    *header_data;
  Int           skip_texture;
  Int           stop_decoding;
  Int           mb_a, mb_b;


  /*****
     *
     *	Set some useful parameters
     *
     *****/
  rec_height = GetVopHeight (rec_vop);
  rec_width = GetVopWidth (rec_vop);
  MB_in_height = rec_height / MB_SIZE;
  MB_in_width = rec_width / MB_SIZE;
  B_in_width = 2 * MB_in_width;
  B_in_height = 2 * MB_in_height;
  QP_store = (SInt *) GetImageData(GetVopQP(rec_vop));
  MB_in_VOP = MB_in_width * MB_in_height;
  MB_in_VOP_length = (Int) ceil(log(MB_in_VOP)/log(2));

  /* allocate space for 3D matrix to keep track of prediction values
     for DC/AC prediction */
  
  DC_store = (Int ***)calloc(MB_in_width*MB_in_height,
			     sizeof(Int **));
  for (i = 0; i < MB_in_width*MB_in_height; i++)
    {
      DC_store[i] = (Int **)calloc(6, sizeof(Int *));
      for (j = 0; j < 6; j++)
	DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
    }
    
  /* allocate space for 2D matrix to keep track of the slice numbers */
  
  slice_nb = (Int **)calloc(MB_in_width,sizeof(Int *));

  for (i = 0; i < MB_in_width; i++)
    slice_nb[i] = (Int *)calloc(MB_in_height, sizeof(Int));
    
    
  intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
 
  header_data = (HeaderInfo *)calloc(MB_in_width*MB_in_height,sizeof(HeaderInfo));

  MB_decisions    = AllocImage(MB_in_width,MB_in_height,SHORT_TYPE);

  
  /*****
   *
   *	Get the image fields of the VOP
   *
   *****/
  Y_rec = GetVopY (rec_vop);
  U_rec = GetVopU (rec_vop);
  V_rec = GetVopV (rec_vop);
  A_rec = GetVopA (rec_vop);
  alpha=(Short *)GetImageData(A_rec);
    
  /*****
   *
   *	Get VOP quantizer and allocate MB structure
   *
   *****/
  vop_quant = GetVopQuantizer (rec_vop);
  QP = vop_quant;
    
  mblock = (Macroblock *) malloc (sizeof (Macroblock));
  
  if (mblock == NULL)
    {
      printf (" Error allocating macroblock\n");
      exit(1);
    }

  printf("Start I VOP decoding \n");
  
  /*****
   *
   *	Loop over all MBs, decode texture of each MB
   *
   *****/
  new_vop = 1;
  pMB_decisions = (SInt *)GetImageData(MB_decisions);
  
  mbnum = 0;
  counter = 0;
  skip_texture = 0;
  slice_counter = 0;
  stop_decoding = 0;
  mb_a = mb_b = 0;
  
	if (GetVopShape(rec_vop)) AllocShapePacket2(rec_vop);

  while(!stop_decoding)
    {
      mb_a = mb_b;

      DecodeVideoPacketDataPartitioningIntraErrRes(stream, rec_vop, &mbnum, 
						   &counter,
						   &next_MB, MB_decisions, 
						   DC_store,
						   QP_store, QP, vop_quant,
						   mblock, error_flag,
						   slice_nb, &slice_counter,
						   header_data, trace,
						   &stop_decoding);
      mb_b = next_MB;

    if (counter != mb_b - mb_a)
        {
            mbnum = mb_b;
            ConcealVideoPacket(rec_vop, GetVopNextTemp(rec_vop),
                               (Image *)NULL,(Image *)NULL,
                               MB_decisions, (Image*)NULL,
                               mb_a, mb_b);
       }
    }
 
 /* Free allocated memory for 3D matrix */
  
  for (i = 0; i < MB_in_width*MB_in_height; i++)
    {
      for (j = 0; j < 6; j++) 
	free((Char *)DC_store[i][j]);
      free((Char *)DC_store[i]);
    }
  free((Char *)DC_store);
  
  
	if (GetVopShape(rec_vop)) FreeShapePacket2();

  /* Free allocated memory for 2D matrix */
  
  for (i = 0; i < MB_in_width; i++)
    free(slice_nb[i]);
  free(slice_nb);
  
  FreeImage(MB_decisions);
  free ((Char *)mblock);
  
  free(header_data);
  
  return;
}


/***********************************************************CommentBegin******
 *
 * -- DecodeVideoPacketDataPartitioningIntraErrRes --
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	18-Nov-97
 *
 * Purpose : decodes all the data in a video packet of a I-VOP in the
 *           error resilient mode with data partitioning.		
 *
 *
 * Arguments in : 	
 *
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
DecodeVideoPacketDataPartitioningIntraErrRes(Bitstream *stream,
					     Vop *rec_vop,
					     Int *mbnum,
					     Int *mb_counter,
					     Int *next_MB,
					     Image *MB_decisions,
					     Int ***DC_store,
					     SInt *QP_store,
					     Int QP,
					     Int vop_quant,
					     Macroblock *mblock,
					     Int *error_flag,
					     Int **slice_nb,
					     Int *slice_counter,
					     HeaderInfo *header_data,
					     Trace *trace,
					     Int *stop_decoding)
{
  Int mb_a, mb_b;

  mb_a = *mbnum;
  /*****
   *
   *  Decode packet
   *
   *****/

  DecodeFirstPartitionIntraErrRes(stream, rec_vop, mbnum, mb_counter,
				  MB_decisions, DC_store, QP_store,
				  QP, vop_quant, mblock, error_flag,
				  slice_nb, *slice_counter,
				  header_data, trace);

 if (*error_flag)
    {
        LookForMarker(stream, rec_vop);
        ReadVideoPacketHeader(stream, rec_vop, slice_counter, trace,
			      next_MB, stop_decoding);
        mb_b = *next_MB;
        ConcealVideoPacket(rec_vop, GetVopNextTemp(rec_vop),
                           (Image *)NULL, (Image *)NULL,
                            MB_decisions, (Image *)NULL,
                            mb_a, mb_b);
        *error_flag = 0;
        return;
    }

  
  DecodeSecondPartitionIntraErrRes(stream, rec_vop, *mbnum, *mb_counter,
				   MB_decisions, DC_store, QP_store,
				   QP, vop_quant, mblock, error_flag,
				   slice_nb, header_data, trace);

 if (*error_flag)
    {
      LookForMarker(stream, rec_vop);
      ReadVideoPacketHeader(stream, rec_vop, slice_counter, trace,
			    next_MB, stop_decoding);
      mb_b = *next_MB;
      ConcealTexture(rec_vop, (Image *)NULL, (Image *)NULL,
		     MB_decisions, mb_a, mb_b);
      *error_flag = 0;
      return;
    }
  ReadVideoPacketHeader(stream, rec_vop, slice_counter, trace, next_MB, stop_decoding);

  return;
}

/***********************************************************CommentBegin******
 *
 * -- DecodeFirstPartitionIntraErrRes --
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	18-Nov-97
 *
 * Purpose : decodes the data in the first partition of a video packet 
 *           of a I-VOP in the error resilient mode with data partitioning.		
 *
 *
 * Arguments in : 	
 *
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
DecodeFirstPartitionIntraErrRes(Bitstream *stream,
				Vop *rec_vop, 
				Int *mb_number,
				Int *mb_counter,
				Image *MB_decisions,
				Int ***DC_store,
				SInt *QP_store,
				Int QP,
				Int vop_quant,
				Macroblock *mblock,
				Int *error_flag,
				Int **slice_nb,
				Int slice_counter,
				HeaderInfo *header_data,
				Trace *trace)
{


  Int         rec_height, rec_width;
  Int         MB_in_height, MB_in_width;
  Int         intra_dcpred_disable;
  Int         mbnum;
  Int         x_pos, y_pos;
  Int         amb_type;
  Int         vo_id, vol_id;
  Int         i,m,n;
  Int         start_of_packet;
  
  /*****
   *
   *  Set some useful parameters
   *
   *****/
  rec_height = GetVopHeight(rec_vop);
  rec_width  = GetVopWidth(rec_vop);
  MB_in_height = rec_height / MB_SIZE;
  MB_in_width  = rec_width / MB_SIZE;
  intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
  vo_id = GetVopVOId(rec_vop);
  vol_id = GetVopId(rec_vop);
  mbnum = *mb_number;
  start_of_packet = 1;

  /*****
   *
   *  Loop over the MBs, decode the information in the first partition
   *
   *****/

  do{
    
    x_pos = mbnum % MB_in_width;
    y_pos = mbnum / MB_in_width;
    
    slice_nb[x_pos][y_pos] = slice_counter;
    
    trace->trace = trace->MB_header;
    if (trace->trace)
      {
	fprintf (trace->fp_trace, "\n>>>   Decoding Macroblock %d ........- Combined Shape/Text\n",(int)mbnum);
      }
    
    /* Store the QP value for later use in AC prediction */
    QP_store[mbnum] = (SInt) QP;
    
    /* decode COD, MCPC, ACpred_flag, CPBY and DQUANT */
    header_data[mbnum].coded = 0;
    header_data[mbnum].skipped_flag = 1;
    
    amb_type = 0;

    /* set all blocks to opaque */
    for(i=0;i<4;i++) 
      header_data[mbnum].MB_transp_pattern[i]=0;
    
    if (GetVopShape(rec_vop)) 
      {
	GetMBIntraShapeErrRes(stream,vo_id,vol_id,y_pos,x_pos,
			      MB_decisions,start_of_packet,&amb_type,
			      header_data[mbnum].MB_transp_pattern,
			      error_flag,rec_vop,trace);
	start_of_packet = 0;
      }
    
    if (amb_type != 1)   /* no further data if the MB is fully transparent */
      {
	GetMBheaderErrRes(intra_dcpred_disable,&vop_quant,
			  stream,mbnum,trace,MB_decisions,
			  &header_data[mbnum].skipped_flag, error_flag,
			  &header_data[mbnum].coded, 
			  &header_data[mbnum].CBP,
			  &header_data[mbnum].mode,
			  header_data[mbnum].IntraDC,
			  header_data[mbnum].MB_transp_pattern,
			  rec_vop);
    
	QP_store[mbnum] = (SInt) vop_quant;
      }
    else
      {                    /* transparent MB */
	MBzero (mblock);
	/* set all alpha block pixels to zero */
	/* Fill DC_store with default coeff values */
	for (m = 0; m < 6; m++) 
	  {
	    DC_store[mbnum][m][0] = GetVopMidGrey(rec_vop)*8;
	    for (n = 1; n < 15; n++)
	      DC_store[mbnum][m][n] = 0;
	  }
	
      }
    
    if (*error_flag)
      return;
      
    mbnum++;
    
  } while (((BitstreamShowBits(stream,DC_MARKER_LENGTH))!=DC_MARKER) && (mbnum < MB_in_width*MB_in_height));

  if (mbnum > MB_in_width*MB_in_height)
    {
      *error_flag = 1;
      return;
    }
    
  *mb_counter = mbnum - *mb_number;
  *mb_number = mbnum;

  BitstreamReadBits(stream,DC_MARKER_LENGTH,"dc marker",trace,NUM); 

  return;

}                   /* DecodeFirstPartitionIntraErrRes */


/***********************************************************CommentBegin******
 *
 * -- DecodeSecondPartitionIntraErrRes --
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	18-Nov-97
 *
 * Purpose : decodes the data in the second partition of a video packet 
 *           of a I-VOP in the error resilient mode with data partitioning.		
 *
 *
 * Arguments in : 	
 *
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
DecodeSecondPartitionIntraErrRes(Bitstream *stream,
				 Vop *rec_vop,
				 Int mbnum,
				 Int mb_counter,
				 Image *MB_decisions,
				 Int ***DC_store,
				 SInt *QP_store,
				 Int QP,
				 Int vop_quant,
				 Macroblock *mblock,
				 Int *error_flag,
				 Int **slice_nb,
				 HeaderInfo *header_data,
				 Trace *trace
				 )
{

  Image *Y_rec, *U_rec, *V_rec;
  Int         rec_height, rec_width;
  Int         MB_in_height, MB_in_width;
  Int intra_dcpred_disable;
  Int counter1, counter2;

  /*****
   *
   *  Set some useful parameters
   *
   *****/
  rec_height = GetVopHeight(rec_vop);
  rec_width  = GetVopWidth(rec_vop);
  MB_in_height = rec_height / MB_SIZE;
  MB_in_width  = rec_width / MB_SIZE;

  intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);


  /*****
   *
   *    Get the image fields of the VOP
   *
   *****/
  Y_rec = GetVopY (rec_vop);
  U_rec = GetVopU (rec_vop);
  V_rec = GetVopV (rec_vop);
  

  /*****
   *
   *   Loop over the MBs, decode the information in the second partition
   *
   *****/
  counter1 = counter2 = mbnum - mb_counter;

  while (counter1 < mbnum)
    {
      if (header_data[counter1].coded)
	{
	  GetMBheaderTextErrRes(intra_dcpred_disable,/*&vop_quant,*/stream,
				counter1,trace,MB_decisions,
				error_flag,&header_data[counter1].coded, 
				&header_data[counter1].CBP, 
				&header_data[counter1].ACpred_flag,
				&header_data[counter1].mode,
						
				header_data[counter1].MB_transp_pattern,
				rec_vop);	  
	}
      counter1++;
    }

  if (*error_flag)
    return;

  while (counter2 < mbnum)
    {
      if (header_data[counter2].coded)
	{
	  GetMBblockdataErrRes(header_data[counter2].MB_transp_pattern,
			       intra_dcpred_disable,vop_quant,
			       stream,counter2,trace,
			       mblock,error_flag, MB_in_width,
			       DC_store,QP_store,QP,
			       header_data[counter2].CBP,
			       header_data[counter2].ACpred_flag,
			       header_data[counter2].mode,
			       header_data[counter2].IntraDC,
			       rec_vop,slice_nb);
	  QP = vop_quant;
	}
      
      
      /* (skipped_flag==1) Clear the skipped MB */
      if (header_data[counter2].skipped_flag == 1)
	MBzero (mblock);
      
      
      FillVop (mblock, counter2, Y_rec, U_rec, V_rec);
      counter2++;
    }
  
  
  return;
}                        /* DecodeSecondPartitionIntraErrRes */



/***********************************************************CommentBegin******
 *
 * -- DecodeVopCombinedShapeTextureIntraErrRes -- 
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	1-May-97
 *
 * Purpose :		
 *      Decodes shape / texture for INTRA VOPs for the combined error
 *      resilient mode
 *
 * Arguments in : 	
 *	Bitstream *stream	combined shape / texture bitstream
 *      Int vo_id               video object identification
 *	Trace  *trace		flag for tracing the process.
 *
 *
 * Arguments in/out :	
 *	Vop *rec_vop		alpha plane is supposed to be filled
 *				already / YUV components.
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *      based on DecodeVopCombinedShapeTextureIntra() as of 01.05.97
 *
 * See also :
 *	
 *
 * Modified : 
 *      15.05.97 Luis Ducla-Soares: corrected the remultiplexing of the DCT data
 *                                  in the combined error resilient mode with 
 *                                  data partitioning. Cleaned up the code.
 *			19.11.97 Noel Brady: quant_scale not present when in shape only mode
 *      09.12.97 Luis Ducla-Soares: changed the name of the function from
 *                                  DecodeVopCombNoDataPartShapeTextureIntraErrRes to
 *                                  DecodeVopCombinedShapeTextureIntraErrRes.
 *      10.12.97 Luis Ducla-Soares: restructured the code. moved the code in
 *                                  the macroblock loop to a new function: 
 *                                  DecodeVideoPacketCombinedIntraErrRes.
 *
 ***********************************************************CommentEnd********/

Void DecodeVopCombinedShapeTextureIntraErrRes(Bitstream * stream, Int vo_id, 
					      Trace *trace, Vop * rec_vop)
{
  Int 	      	ef=0, *error_flag = &ef; 
  Int           mbnum, i, j;
  Int           rec_height;
  Int 		rec_width;
  Int		MB_in_height, MB_in_width;
  Int           B_in_width, B_in_height;
  Macroblock    *mblock;
  Image         *Y_rec, *U_rec, *V_rec, *A_rec;
  Short		*alpha;
  Int           vop_quant, intra_dcpred_disable;
  Image         *MB_decisions;
  UInt		new_vop;
  SInt		*pMB_decisions;
  Int           ***DC_store;
  Int           **slice_nb;
  Int           slice_counter;
  SInt          *QP_store;
  Int           QP;
  Int           counter, next_MB;
  Int           MB_in_VOP;
  Int           MB_in_VOP_length;
  HeaderInfo    *header_data;
  Int           skip_texture;
  Int           stop_decoding;
  Int           mb_a, mb_b;

  /*****
     *
     *	Set some useful parameters
     *
     *****/
  rec_height = GetVopHeight (rec_vop);
  rec_width = GetVopWidth (rec_vop);
  MB_in_height = rec_height / MB_SIZE;
  MB_in_width = rec_width / MB_SIZE;
  B_in_width = 2 * MB_in_width;
  B_in_height = 2 * MB_in_height;
  QP_store = (SInt *) GetImageData(GetVopQP(rec_vop));
  MB_in_VOP = MB_in_width * MB_in_height;
  MB_in_VOP_length = (Int) ceil(log(MB_in_VOP)/log(2));


  /* allocate space for 3D matrix to keep track of prediction values
     for DC/AC prediction */
  
  DC_store = (Int ***)calloc(MB_in_width*MB_in_height,
			     sizeof(Int **));
  for (i = 0; i < MB_in_width*MB_in_height; i++)
    {
      DC_store[i] = (Int **)calloc(6, sizeof(Int *));
      for (j = 0; j < 6; j++)
	DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
    }

  
  /* allocate space for 2D matrix to keep track of the slice numbers */

  slice_nb = (Int **)calloc(MB_in_width,sizeof(Int *));

  for (i = 0; i < MB_in_width; i++)
    slice_nb[i] = (Int *)calloc(MB_in_height, sizeof(Int));
    
  
  intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);

  header_data = (HeaderInfo *)calloc(MB_in_width*MB_in_height,sizeof(HeaderInfo));

  MB_decisions    = AllocImage(MB_in_width,MB_in_height,SHORT_TYPE);

  /*****
   *
   *	Get the image fields of the VOP
   *
   *****/
  Y_rec = GetVopY (rec_vop);
  U_rec = GetVopU (rec_vop);
  V_rec = GetVopV (rec_vop);
  A_rec = GetVopA (rec_vop);
  alpha=(Short *)GetImageData(A_rec);
    
  /*****
   *
   *	Get VOP quantizer and allocate MB structure
   *
   *****/
  vop_quant = GetVopQuantizer (rec_vop);
  QP = vop_quant;
    
  mblock = (Macroblock *) malloc (sizeof (Macroblock));
  
  if (mblock == NULL)
    {
      printf (" Error allocating macroblock\n");
      exit(1);
    }

  printf("Start I VOP decoding \n");
  
  /*****
   *
   *	Loop over all MBs, decode texture of each MB
   *
   *****/
  new_vop = 1;
  pMB_decisions = (SInt *)GetImageData(MB_decisions);
  
  mbnum = 0;
  counter = 0;
  skip_texture = 0;
  slice_counter = 0;
  stop_decoding = 0;
  mb_a = mb_b = 0;

	if (GetVopShape(rec_vop)) AllocShapePacket2(rec_vop);

  while(!stop_decoding)
    {
      mb_a = mb_b;
      
      DecodeVideoPacketCombinedIntraErrRes(stream, rec_vop, &mbnum,
					   &counter, &next_MB,
					   MB_decisions, DC_store, QP_store,
					   QP, vop_quant, error_flag,
					   slice_nb, &slice_counter,
					   header_data, trace,
					   &stop_decoding);
      mb_b = next_MB;

     if (counter != mb_b - mb_a)
      {
        mbnum = mb_b;
        ConcealVideoPacket(rec_vop, GetVopNextTemp(rec_vop),
                           (Image *)NULL, (Image *)NULL,
                            MB_decisions, (Image *)NULL,
                            mb_a, mb_b);
         }    
     }
        
  /* Free allocated memory for 3D matrix */
  
  for (i = 0; i < MB_in_width*MB_in_height; i++)
    {
      for (j = 0; j < 6; j++) 
	free((Char *)DC_store[i][j]);
      free((Char *)DC_store[i]);
    }
  free((Char *)DC_store);
  

	if (GetVopShape(rec_vop)) FreeShapePacket2();

  /* Free allocated memory for 2D matrix */
  
  for (i = 0; i < MB_in_width; i++)
    free(slice_nb[i]);
  free(slice_nb);
  

  FreeImage(MB_decisions);
  free ((Char *)mblock);
  
  free(header_data);
  
  return;
}


/***********************************************************CommentBegin******
 *
 * -- DecodeVideoPacketCombinedIntraErrRes --
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	20-Nov-97
 *
 * Purpose : decodes all the data in a video packet of a I-VOP in the
 *           error resilient combined mode		
 *
 *
 * Arguments in : 	
 *
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
DecodeVideoPacketCombinedIntraErrRes(Bitstream *stream,
				     Vop *rec_vop,
				     Int *mbnum,
				     Int *mb_counter,
				     Int *next_MB,
				     Image *MB_decisions,
				     Int ***DC_store,
				     SInt *QP_store,
				     Int QP,
				     Int vop_quant,
				     Int *error_flag,
				     Int **slice_nb,
				     Int *slice_counter,
				     HeaderInfo *header_data,
				     Trace *trace,
				     Int *stop_decoding)
{
  Int mb_a, mb_b;

  mb_a = *mbnum;
  /*****
   *
   *  Decode packet
   *
   *****/

  DecodeCombinedPacketInfoIntraErrRes(stream, rec_vop, mbnum, mb_counter,
				      MB_decisions, DC_store, QP_store,
				      QP, vop_quant, error_flag, slice_nb,
				      *slice_counter, header_data, trace);
  
  if (*error_flag)
    {
      LookForMarker(stream, rec_vop);
      ReadVideoPacketHeader(stream, rec_vop, slice_counter, trace,
			    next_MB, stop_decoding);
      mb_b = *next_MB;
      ConcealVideoPacket(rec_vop, GetVopNextTemp(rec_vop),
                         (Image *)NULL, (Image *)NULL,
                         MB_decisions, (Image *)NULL,
                         mb_a, mb_b);
      *error_flag = 0;
      return;
    }
  ReadVideoPacketHeader(stream, rec_vop, slice_counter, trace, next_MB, stop_decoding);

  return;
}

/***********************************************************CommentBegin******
 *
 * -- DecodeCombinedPacketInfoIntraErrRes --
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	20-Nov-97
 *
 * Purpose : decodes the video data in a video packet 
 *           of a I-VOP in the error resilient combined mode.		
 *
 *
 * Arguments in : 	
 *
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
DecodeCombinedPacketInfoIntraErrRes(Bitstream *stream,
				    Vop *rec_vop,
				    Int *mb_number,
				    Int *mb_counter,
				    Image *MB_decisions,
				    Int ***DC_store,
				    SInt *QP_store,
				    Int QP,
				    Int vop_quant,
				    Int *error_flag,
				    Int **slice_nb,
				    Int slice_counter,
				    HeaderInfo *header_data,
				    Trace *trace)
{

  Image *Y_rec, *U_rec, *V_rec;
  Macroblock *mblock;
  Int         rec_height, rec_width;
  Int         MB_in_height, MB_in_width;
  Int         intra_dcpred_disable;
  Int         vo_id, vol_id;
  Int         mbnum;
  Int         x_pos, y_pos;
  Int         i, m, n;
  Int         amb_type;
  Int         resync_marker_length;
  Int         start_of_packet;

  /*****
   *
   *  Set some useful parameters
   *
   *****/
  rec_height = GetVopHeight(rec_vop);
  rec_width  = GetVopWidth(rec_vop);
  MB_in_height = rec_height / MB_SIZE;
  MB_in_width  = rec_width / MB_SIZE;
  intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
  vo_id = GetVopVOId(rec_vop);
  vol_id = GetVopId(rec_vop);
  resync_marker_length = 17;
  mbnum = *mb_number;
  start_of_packet = 1;

  mblock = (Macroblock *) malloc (sizeof (Macroblock));
  
  if (mblock == NULL)
    {
      printf (" Error allocating macroblock\n");
      exit(1);
    }
  
  /*****
   *
   *    Get the image fields of the VOP
   *
   *****/
  Y_rec = GetVopY (rec_vop);
  U_rec = GetVopU (rec_vop);
  V_rec = GetVopV (rec_vop);
  

  /*****
   *
   *   Decode the MBs in the Video Packet 
   *
   *****/
  do {
    
    x_pos = mbnum % MB_in_width;
    y_pos = mbnum / MB_in_width;
    
    slice_nb[x_pos][y_pos] = slice_counter;
    
    trace->trace = trace->MB_header;
    if (trace->trace)
      {
	fprintf (trace->fp_trace, "\n>>>   Decoding Macroblock %d ........- Combined Shape/Text\n",(int)mbnum);
      }
    
    /* Store the QP value for later use in AC prediction */
    QP_store[mbnum] = (SInt) QP;
    
    /* decode COD, MCPC, ACpred_flag, CPBY and DQUANT */
    header_data[mbnum].coded = 0;
    header_data[mbnum].skipped_flag = 1;
    
    amb_type = 0;
    
    /* set all blocks to opaque */
    for(i=0;i<4;i++) 
      header_data[mbnum].MB_transp_pattern[i]=0;
    
    if (GetVopShape(rec_vop)) 
      {
	GetMBIntraShapeErrRes(stream,vo_id,vol_id,y_pos,x_pos,
			      MB_decisions,start_of_packet,&amb_type,
			      header_data[mbnum].MB_transp_pattern,
			      error_flag,rec_vop,trace);
	start_of_packet = 0;
      }
    
    
    if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY)
      {
	if (amb_type != 1)
	  {
	    GetMBheaderNoDataPartIntraErrRes(stream,intra_dcpred_disable,
					     mbnum,trace,MB_decisions,
					     &header_data[mbnum].skipped_flag, error_flag,
					     &header_data[mbnum].coded, 
					     &header_data[mbnum].CBP,
					     &header_data[mbnum].ACpred_flag,
					     &header_data[mbnum].mode,
					     header_data[mbnum].MB_transp_pattern,rec_vop);
    
	    QP_store[mbnum] = (SInt) vop_quant;
    
	    
	    if (header_data[mbnum].coded)
	      {
		GetMBblockdataNoDataPartErrRes(header_data[mbnum].MB_transp_pattern,
					       intra_dcpred_disable,
					       vop_quant,stream,mbnum,
					       trace,mblock,error_flag, 
					       MB_in_width,
					       DC_store,QP_store,QP,
					       header_data[mbnum].CBP,
					       header_data[mbnum].ACpred_flag,
					       header_data[mbnum].mode,
					       rec_vop, slice_nb);
		QP = vop_quant;
	      }
	    
	    
	    /* (skipped_flag==1) Clear the skipped MB */
	    if (header_data[mbnum].skipped_flag == 1)
	      MBzero (mblock);
	  }
	else
	  {
	    MBzero (mblock);
	    /* set all alpha block pixels to zero */
	    /* Fill DC_store with default coeff values */
	    for (m = 0; m < 6; m++) 
	      {
		DC_store[mbnum][m][0] = GetVopMidGrey(rec_vop)*8;
		for (n = 1; n < 15; n++)
		  DC_store[mbnum][m][n] = 0;
	      }
	  }
	
        FillVop (mblock, mbnum, Y_rec, U_rec, V_rec);
      }
    
    mbnum++;
  
  } while ((mbnum < MB_in_width*MB_in_height) && (!MarkerFound(stream,resync_marker_length)));

  if (mbnum > MB_in_width*MB_in_height)
    {
      *error_flag = 1;
      return;
    }
  
  *mb_counter = mbnum - *mb_number;
  *mb_number = mbnum;

  free ((Char *)mblock);

  return;
}


/***********************************************************CommentBegin******
 *
 * -- DecodeVopCombinedMotionShapeTextureInter -- 
 *
 * Author :		
 *	Jan De Lameillieure (HHI) <jan@hhi.de>
 *
 * Created :		
 *	19-Jan-97
 *
 * Purpose :		
 *      Decodes combined motion / shape / texture for INTER VOPs
 *
 * Arguments in : 	
 *	Bitstream *stream	combined shape / texture bitstream
 *	Trace  *trace		flag for tracing the process.
 *
 *
 * Arguments in/out :	
 *	Vop *rec_vop		alpha plane is supposed to be filled
 *				already / YUV components.
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *      Starting point for this function was 
 *      DecodeVopCombinedShapeTextureIntra() as of 18-Jan-97
 *
 * See also :
 *	
 *
 * Modified : 
 *      24-Jan-97 Jan De Lameillieure : moved alpha clampling after motion 
 *	                                compensation inside the MB loop
 *	07-Feb-1997, M.Wollborn: changed in order to treat skipped MBs
 *			         correctly
 *	30.07.97 F. Jaureguizar: changed in order to treat spatial
 *          scalability (SpSc)
 *  05.09.97 Fernando Jaureguizar: deleted unnecessary code with aux_vop to
 *          solve a memory leak
 *  04.11.97 Minhua Zhou: updated DC/AC prediction
 *  12.12.97 Bob Eifrig: interlaced video decoding
 *
 ***********************************************************CommentEnd********/

Void DecodeVopCombinedMotionShapeTextureInter(
    Bitstream * stream,
    Int vo_id,
    Trace *trace,
    Vop *rec_vop,
    Image **mot_x_out,
    Image **mot_y_out,
    Image **MB_decisions_out)
{
    Int         vol_id = GetVopId(rec_vop);
    Int         ef=0, *error_flag = &ef;
    Int         mbnum, x_pos, y_pos, i, j;
    Int         rec_height;
    Int         rec_width;
    Int         MB_in_height, MB_in_width;
    Int         B_in_width, B_in_height;
    Macroblock  *mblock;
    Image       *Y_rec, *U_rec, *V_rec;
    Short       *alpha, *alpha_prev;
    Int         vop_quant,intra_dcpred_disable;
    Int         skipped_flag=0;
    Image       *alpha_decisions,*MB_decisions;
    UInt        new_vop;
    SInt        *palpha_decisions,*pMB_decisions;
    Int         MB_transp_pattern[4];
    Int         ***DC_store;
    Int         m, n, QP;
    Int         coded;
    UInt        CBP;
    Int         ACpred_flag=-1;
    UInt        mode;
    Int         f_code=GetVopFCodeFor(rec_vop);
    Image       *mot_x, *mot_y;
    Float       *motx_ptr, *moty_ptr;
    Vop         *tmp_vop;
    SInt        *QP_store;
    /*>SpSc*/
    Int         spatial_scalability=0;
    Int         scalability  = GetVopScalability(rec_vop);
    Int         ref_sel_code = GetVopRefSelCode(rec_vop);
    Int 	MB_non_trans_count=0;     
    UChar       *skipped;    
    /*SpSc<*/
#ifdef _DEBUG_SPSC_
    static Int count=0;
    Char       name[81];
#endif
	Int interlace_info;

    /*****
    *
    *   Stuff for motion compensation of alpha plane (copied by JDL 
    *   from AlphaMotionCompensate() in vm_common/src/mot_comp.c,
    *   a function written by Noel Brady
    *
    *****/
    Image       *motA2_x=NULL,*motA2_y=NULL,*modeA2=NULL;
    Int         amb_type=0,mvda=0;
    
/* SPRITE */	
    Vop         *sprite=NULL;
/* Low Latency Static SPRITE */	
  /* Note: the case STATIC_SPRITE only CONCERNS LOW-LATENCY SPRITES */
  /* BASIC STATIC SPRITES ARE ONLY CONCERNED WITH I_VOP not handled here */	
    Int	*tab_transmit	= GetVopSpriteTabTransmit(rec_vop);
    Int	numblocks_x	= GetVopSpriteHdim(rec_vop)/16;
    Int	*tab_amb_type	= GetVopSpriteTabAmbType(rec_vop);
    Int	*tab_mvda	= GetVopSpriteTabMvda(rec_vop);


  if (GetVopSpriteUsage(rec_vop)!=SPRITE_NOT_USED)
	sprite = GetVopSprite(rec_vop);
  

    /*****
     *
     *	Set some useful parameters
     *
     *****/
    rec_height = GetVopHeight (rec_vop);
    rec_width = GetVopWidth (rec_vop);
    MB_in_height = rec_height / MB_SIZE;
    MB_in_width = rec_width / MB_SIZE;
    B_in_width = 2 * MB_in_width;
    B_in_height = 2 * MB_in_height;
    QP_store = (SInt *) GetImageData(GetVopQP(rec_vop));
    /*>SpSc*/
    /* P-VOP with Sp.Sc. => ref_sel_code = 3 */
    if (scalability == 1 && ref_sel_code == 3)
      spatial_scalability = 1;
    /*SpSc<*/
  
    mot_x = AllocImage((UInt) B_in_width,(UInt) B_in_height,FLOAT_TYPE);
    mot_y = AllocImage((UInt) B_in_width,(UInt) B_in_height,FLOAT_TYPE);
    motx_ptr = (Float *)GetImageData(mot_x);
    moty_ptr = (Float *)GetImageData(mot_y);

    SetConstantImage(mot_x,0.0);
    SetConstantImage(mot_y,0.0);
    

    skipped = (UChar *)calloc(MB_in_width*MB_in_height,sizeof(UChar));
    if (GetVopShape(rec_vop))
      {
	/* Allocate shape ME/MC */
	modeA2 = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
			    GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
	motA2_x = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
			     GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
	motA2_y = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
			     GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
      }

    /* allocate space for 3D matrix to keep track of prediction values
       for DC/AC prediction */
    
    DC_store = (Int ***)calloc(MB_in_width*MB_in_height,
			       sizeof(Int **));
    for (i = 0; i < MB_in_width*MB_in_height; i++)
      {
	DC_store[i] = (Int **)calloc(6, sizeof(Int *));
	for (j = 0; j < 6; j++)
	  DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
      }
    
    intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
    
    alpha_decisions = AllocImage(B_in_width,B_in_height,SHORT_TYPE);
    MB_decisions    = AllocImage(MB_in_width,MB_in_height,SHORT_TYPE);

    tmp_vop = AllocVop(GetVopWidth(rec_vop),GetVopHeight(rec_vop));
    CopyVopNonImageField(rec_vop,tmp_vop);

    /*****
     *
     *	Get the image fields of the VOP
     *
     *****/
    Y_rec = GetVopY (rec_vop);
    U_rec = GetVopU (rec_vop);
    V_rec = GetVopV (rec_vop);
    alpha = (Short *) GetImageData( GetVopA(rec_vop) );
    /* for inter shape */
    alpha_prev = (Short *) GetImageData( GetVopA( GetVopNextTemp(rec_vop) ) );
    

    /*****
     *
     *	Get VOP quantizer and allocate MB structure
     *
     *****/
    vop_quant = GetVopQuantizer (rec_vop);
    QP = vop_quant;

    mblock = (Macroblock *) malloc (sizeof (Macroblock));

    if (mblock == NULL)
      {
	printf (" Error allocating macroblock\n");
	exit(1);
      }

if (scalability == 1)
   printf("Enhancement Layer: \n");

if (GetVopSpriteUsage(rec_vop)==ONLINE_SPRITE)
	printf("Start SPRITE VOP decoding\n");
else
if (GetVopSpriteUsage(rec_vop)==GMC_SPRITE)
	printf("Start GMC VOP decoding\n");
else
if (GetVopSpriteUsage(rec_vop)==STATIC_SPRITE)
	printf("\tStart P VOP decoding (update-piece of low latency static sprite)\n");
else
	printf("Start P VOP decoding\n");

    /*****
     *
     *	Loop over all MBs, decode texture of each MB
     *
     *****/
    new_vop = 1;
    pMB_decisions = (SInt *)GetImageData(MB_decisions);
    palpha_decisions = (SInt *)GetImageData(alpha_decisions);

    for (i = 0; i < B_in_width*B_in_height; i++)
      palpha_decisions[i] = MBM_TRANSPARENT;

   
    /*****
    *
    * the macroblock loop
    *
    *****/
   
    for (y_pos = 0; y_pos < MB_in_height; y_pos++)
      for (x_pos = 0; x_pos < MB_in_width; x_pos++)
	{
	  mbnum = y_pos * MB_in_width + x_pos;
	  
	  /* Store the QP value for later use in AC prediction */
	  QP_store[mbnum] = (SInt) QP;
        if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY) {
	  if (MB_non_trans_count>=MB_trace_thres)
             SetTraceLevelsZero(trace);
          else
             SetTraceLevelsDefault(trace);
          }

	  
	  trace->trace = trace->MB_header;
	  
	  if (trace->trace)
	    {
              fprintf (trace->fp_trace,
                 "\n>>>   Decoding Macroblock %d @ %d - Combined Motion/Shape/Text\n",
                 (int)mbnum, stream->bitcnt);
	    }
	  
	  if (GetVopShape(rec_vop)&&GetVopSpriteUsage(rec_vop)!=STATIC_SPRITE) 
	    {
			  trace->trace = trace->MB_shape;
	      DecodeFirst(stream, vo_id, vol_id, y_pos, x_pos, &amb_type, 
			  &mvda, 1, 0, rec_vop,GetVopNextTemp(rec_vop), trace);

	      /* fill the alpha map with the decoded pixels for this MB */
	      AlphaDecodeMB(rec_vop,GetVopNextTemp(rec_vop),vo_id,vol_id,y_pos,x_pos,
			    &amb_type,&mvda,1,MB_decisions,alpha_decisions,mot_x,mot_y,modeA2,
			    motA2_x,motA2_y,0,stream,trace, error_flag);
	
	  		if(trace->trace)
	  		fprintf(trace->fp_trace, "----------\n");
				trace->trace = trace->MB_header;

	      if (amb_type == 1) 
		{	/* if the alpha MV is all_0 */
		  /* for a correct motion vector prediction in the MB's */
		  /* below the actual MB   --- JDL                      */
		  palpha_decisions[2*y_pos*B_in_width + 2*x_pos] = MBM_TRANSPARENT;
		  palpha_decisions[2*y_pos*B_in_width + 2*x_pos + 1] = MBM_TRANSPARENT;
		  palpha_decisions[(2*y_pos + 1)*B_in_width + 2*x_pos] = MBM_TRANSPARENT;
		  palpha_decisions[(2*y_pos + 1)*B_in_width + 2*x_pos + 1] = MBM_TRANSPARENT;
		}
	    }

	if (GetVopSpriteUsage(rec_vop)==STATIC_SPRITE)
		{
         	if (GetVopShape(rec_vop)) 
			{
			amb_type = tab_amb_type[y_pos*numblocks_x+x_pos];
			mvda = tab_mvda[y_pos*numblocks_x+x_pos];
	      if (amb_type == 1) 
		{	/* if the alpha MV is all_0 */
		  /* for a correct motion vector prediction in the MB's */
		  /* below the actual MB   --- JDL                      */
		  palpha_decisions[2*y_pos*B_in_width + 2*x_pos] = MBM_TRANSPARENT;
		  palpha_decisions[2*y_pos*B_in_width + 2*x_pos + 1] = MBM_TRANSPARENT;
		  palpha_decisions[(2*y_pos + 1)*B_in_width + 2*x_pos] = MBM_TRANSPARENT;
		  palpha_decisions[(2*y_pos + 1)*B_in_width + 2*x_pos + 1] = MBM_TRANSPARENT;
		}
			}
		}


		if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY)			/* BSO_NOEL */
		{

	  /* decode COD, MCPC, ACpred_flag, CPBY and DQUANT */
	  coded = 0;
	  skipped_flag = 1;

	  if (amb_type != 1)  /* if not transparent */
	    {
              for (i=0;i<4;i++) MB_transp_pattern[i]=1;
              for(i=0;i<B_SIZE;i++)
	        for(j=0;j<B_SIZE;j++)
		  if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   (x_pos * MB_SIZE) +j] != 0)
		    MB_transp_pattern[0]=0;
	
	      for(i=0;i<B_SIZE;i++)		
	        for(j=B_SIZE;j<2*B_SIZE;j++)
		  if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   (x_pos * MB_SIZE) +j] != 0)
		    MB_transp_pattern[1]=0;
	      
	      for(i=B_SIZE;i<2*B_SIZE;i++)
	        for(j=0;j<B_SIZE;j++)
		  if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   (x_pos * MB_SIZE) +j] != 0)
		    MB_transp_pattern[2]=0;
	      
	      for(i=B_SIZE;i<2*B_SIZE;i++)
	        for(j=B_SIZE;j<2*B_SIZE;j++)
		  if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   (x_pos * MB_SIZE) +j] != 0)
		    MB_transp_pattern[3]=0;

	      /* set MB_decisions for this MB to MBM_SKIPPED => mot. comp. */ 
	      /* with zero vector when MB skipped                         */
/* 	      *((SInt *) GetImageData (MB_decisions) + mbnum) = MBM_SKIPPED; */
	  if (GetVopPredictionType(rec_vop) == SPRITE_VOP)
	    /* set MB_decisions for this MB to MBM_SPRITE => mot. comp. with zero vector when MB skipped */
	    *((SInt *) GetImageData (MB_decisions) + mbnum) = MBM_SPRITE;
	  else   /* P_VOP */
		/* Temporarily changed to ONEVEC. RID 970211. */
	      *((SInt *) GetImageData (MB_decisions) + mbnum) = MBM_INTER16;
          interlace_info = GetVopInterlaced(rec_vop);
	      GetMBheader(GetVopPredictionType(rec_vop),&new_vop,
			  intra_dcpred_disable,
			  &vop_quant,stream,mbnum,trace,MB_decisions,
			  mblock,&skipped_flag, error_flag,
			  DC_store, QP_store, QP, &coded, 
			  &CBP, &ACpred_flag, &mode,
              &interlace_info,    /* not implemented yet */
			  MB_transp_pattern,rec_vop);
           skipped[mbnum] = skipped_flag;
           QP_store[mbnum] = (SInt) vop_quant;

	       if (GetVopSpriteUsage(rec_vop)== STATIC_SPRITE)
	       	  if (coded==1)
	  		tab_transmit[y_pos*numblocks_x+x_pos]=2;
		  else
	  		tab_transmit[y_pos*numblocks_x+x_pos]=1;
	      
	      if (*error_flag == RETURN)
	        exit(1);
	    }

	  /* if the MB is multilevel */
	  if ((amb_type != 0) || (amb_type != 1))
	    SetAlphaDecisions(GetVopA(rec_vop),x_pos,y_pos,alpha_decisions);

	  /* decode the MV for texture */
	  if (amb_type != 1)  /* if not transparent */
	    {
              MB_non_trans_count++;
	      if ((coded) && (mode == MODE_INTER || mode == MODE_INTER_Q || 
			      mode == MODE_INTER4V || mode == MODE_DYN_SP) &&
			      !spatial_scalability /*SpSc*/&&
			      GetVopSpriteUsage(rec_vop)!=STATIC_SPRITE
				)
	        GetMBvectors(GetVopPredictionType(rec_vop),
			     intra_dcpred_disable, &vop_quant,stream,mbnum,
			     MB_in_width,f_code,trace,MB_decisions,
			     alpha_decisions,mot_x,mot_y,&skipped_flag, 
			     error_flag,DC_store, QP_store, QP, &coded,
			     &ACpred_flag, mode, GetVopShape(rec_vop));
	    }

	  /* calculate MB_transp_pattern */
	  
	  if (amb_type == 0) /* alpha MB is all_255 */
	    for(i=0;i<4;i++) 
	      MB_transp_pattern[i]=0;
	  else if (amb_type==1) 
	    for(i=0;i<4;i++) 
	      MB_transp_pattern[i]=1;
		
	 
	  /* in the case that we have rectangular shape set the */
	  /* alpha blocks to OPAQUE                             */
	  if (!GetVopShape(rec_vop))
	    {	
	      /* no shape ("rectangular" shape) */
	      for(i=0;i<MB_SIZE;i++)
	        for(j=0;j<MB_SIZE;j++)
		  alpha[((y_pos * MB_SIZE) +i)*rec_width 
		       + (x_pos * MB_SIZE) +j] = BINARY_ALPHA;
	    }

	  /* decode the DCT coeficients for the MB */
	  if (amb_type!=1 && coded)
	    {
	      GetMBblockdata(MB_transp_pattern,
			     intra_dcpred_disable,
			     vop_quant,stream,mbnum,trace,
			     mblock,&skipped_flag, error_flag, 
			     MB_in_width, 
			     DC_store, QP_store, QP,
			     CBP, ACpred_flag, mode,
			     alpha,
                 interlace_info,
				 rec_vop);
	      QP = vop_quant;
	      if (*error_flag == RETURN) exit(1);
	    }
	  
	  if (skipped_flag == 1) MBzero (mblock);
	  
	  if (amb_type == 1) /* transparent MB */
	    {			
	      MBzero (mblock);
	      /* Fill DC_store with default coeff values */
	      for (m = 0; m < 6; m++) 
		{
		  DC_store[mbnum][m][0] = GetVopMidGrey(rec_vop)*8;
		  for (n = 1; n < 15; n++)
		    DC_store[mbnum][m][n] = 0;
		}
	    }
	  
	  FillVop (mblock, mbnum, Y_rec, U_rec, V_rec);
	}																								/* BSO_NOEL */
	else 
		{
			if (trace->MB_sdata)
				PrintMBShapeData(rec_vop, x_pos, y_pos, trace);
		}
	}

 

	if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY)  /* BSO_NOEL */
		{

    /* mapping MB_decisions to alpha_decisions in order to make */
    /* VopMotionCompensate() work                               */
    
    RemapAlphaDecisions(alpha_decisions);


   VopMotionCompensate(GetVopNextTemp(rec_vop),mot_x,mot_y,MB_decisions,
			alpha_decisions,tmp_vop, 
			GetVopOBMCDisable(rec_vop),
			sprite); 

    
    

    
    VopTextureUpdate(tmp_vop,rec_vop,trace);
    


		}					
    /* Free allocated memory for 3D matrix */
    
    for (i = 0; i < MB_in_width*MB_in_height; i++)
      {
	for (j = 0; j < 6; j++)
	  free((Char *)DC_store[i][j]);
	free((Char *)DC_store[i]);
      }
    free((Char *)DC_store);

    if (GetVopShape(rec_vop))
      {
	/* Deallocate shape ME/MC */
	/* Removed cast to (Char *), 05-FEB-1997 MW */
	FreeImage(modeA2);			  
	FreeImage(motA2_x);			  
	FreeImage(motA2_y);			  
      }

    FreeImage(alpha_decisions);
    free ((Char *)mblock);
    *mot_x_out=mot_x;
    *mot_y_out=mot_y;

   for (i = 0; i < MB_in_width*MB_in_height; i++)
      if (skipped[i])  pMB_decisions[i] = MBM_SKIPPED;
    free(skipped); 
    *MB_decisions_out = MB_decisions;
    FreeVop(tmp_vop);
    
    
    return;
}


/***********************************************************CommentBegin******
 *
 * -- DecodeVopDataPartitioningInterErrRes -- 
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	1-May-97
 *
 * Purpose :		
 *      Decodes error resilient combined motion / shape / texture for INTER
 *      VOPs with data partitioning
 *
 * Arguments in : 	
 *	Bitstream *stream	combined shape / texture bitstream
 *      Int vo_id               video object identification
 *	Trace  *trace		flag for tracing the process.
 *
 *
 * Arguments in/out :	
 *	Vop *rec_vop		alpha plane is supposed to be filled
 *				already / YUV components.
 *
 * Arguments out :	
 *      Image **mot_x_out           x-component of motion vectors needed for B-VOPs
 *      Image **mot_y_out           y-component of motion vectors needed for B-VOPs
 *      Image **MB_decisions_out    macroblock modes also needed for B-VOPs
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : based on DecodeVopCombinedMotionShapeTextureInter() as of 01.05.97
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *      15.05.97 Luis Ducla-Soares: corrected the remultiplexing of the DCT data
 *                                  in the combined error resilient mode with 
 *                                  data partitioning. Cleaned up the code.
 *      04.11.97 Minhua Zhou: updated DC/AC prediction
 *			19.11.97 Noel Brady: quant_scale not present when in shape only mode
 *			19.11.97 Noel Brady: fcodes are now in HEC (except for shape only mode)
 *			19.11.97 Noel Brady: added support for shape decoding
 *      09.12.97 Luis Ducla-Soares: changes to allow the use of B-VOPs.
 *      09.12.97 Luis Ducla-Soares: changed the name of the function from
 *                                  DecodeVopCombinedMotionShapeTextureInterErrRes to
 *                                  DecodeVopDataPartitioningInterErrRes.
 *      10.12.97 Luis Ducla-Soares: restructured the code. moved the code in
 *                                  the macroblock loop to a new function: 
 *                                  DecodeVideoPacketDataPartitioningInterErrRes.
 *
 ***********************************************************CommentEnd********/
Void DecodeVopDataPartitioningInterErrRes(Bitstream * stream, 
					  Int vo_id,
					  Trace *trace,
					  Vop *rec_vop,
					  Image **mot_x_out,
					  Image **mot_y_out,
					  Image **MB_decisions_out)
{
		
  Int           ef=0, *error_flag = &ef; 
  Int           mbnum, i, j;
  Int           rec_height;
  Int 		rec_width;
  Int		MB_in_height, MB_in_width;
  Int           B_in_width, B_in_height;
  Macroblock    *mblock;
  Image         *Y_rec, *U_rec, *V_rec;
  Int           vop_quant, intra_dcpred_disable;
  Image         *alpha_decisions,*MB_decisions;
  SInt		*palpha_decisions;
  Int           ***DC_store;
  Int           **slice_nb;
  Int           slice_counter;
  Int           f_code=GetVopFCodeFor(rec_vop);
  Image         *mot_x, *mot_y;
  Vop           *tmp_vop;
  SInt          *QP_store;
  Int           QP;
  Int           counter, next_MB;
  Int           MB_in_VOP;
  Int           MB_in_VOP_length;
  HeaderInfo    *header_data;
  Int           skip_texture;
  Int           resync_marker_length;
  Int           stop_decoding;
  Int           mb_a, mb_b;

	Image *modeA=0,*motA_x=0,*motA_y=0;
	SInt *mb_mode;

    /*****
    *
    *   Stuff for motion compensation of alpha plane (copied by JDL 
    *   from AlphaMotionCompensate() in vm_common/src/mot_comp.c,
    *   a function written by Noel Brady
    *
    *****/

    
/* SPRITE */	
  Vop *sprite=NULL;

  if (GetVopSpriteUsage(rec_vop)!=SPRITE_NOT_USED)
  	{ 
	sprite = GetVopSprite(rec_vop);
	}


    /*****
     *
     *	Set some useful parameters
     *
     *****/
    rec_height = GetVopHeight (rec_vop);
    rec_width = GetVopWidth (rec_vop);
    MB_in_height = rec_height / MB_SIZE;
    MB_in_width = rec_width / MB_SIZE;
    B_in_width = 2 * MB_in_width;
    B_in_height = 2 * MB_in_height;
    QP_store = (SInt *) GetImageData(GetVopQP(rec_vop));
    MB_in_VOP = MB_in_width * MB_in_height;
    MB_in_VOP_length = (Int) ceil(log(MB_in_VOP)/log(2));
    if (GetVopShape(rec_vop) == BINARY_SHAPE_ONLY)
      resync_marker_length = 17;
    else
      resync_marker_length = 16 + f_code;
    
  
    mot_x = AllocImage((UInt) B_in_width,(UInt) B_in_height,FLOAT_TYPE);
    mot_y = AllocImage((UInt) B_in_width,(UInt) B_in_height,FLOAT_TYPE);

		if (GetVopShape(rec_vop))
			{
  			/* Allocate shape ME/MC */
  			modeA = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
		      GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
  			motA_x = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
		       GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
  			motA_y = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
		       GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
				if (GetVopShape(rec_vop)) AllocShapePacket2(rec_vop);
			}

    header_data = (HeaderInfo *)calloc(MB_in_width*MB_in_height,sizeof(HeaderInfo));


    SetConstantImage(mot_x,0.0);
    SetConstantImage(mot_y,0.0);

    /* allocate space for 3D matrix to keep track of prediction values
       for DC/AC prediction */
    
    DC_store = (Int ***)calloc(MB_in_width*MB_in_height,
			       sizeof(Int **));
    for (i = 0; i < MB_in_width*MB_in_height; i++)
      {
	DC_store[i] = (Int **)calloc(6, sizeof(Int *));
	for (j = 0; j < 6; j++)
	  DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
      }
    
    
    /* allocate space for 2D matrix to keep track of the slice numbers */
    
    slice_nb = (Int **)calloc(MB_in_width,sizeof(Int *));
    
    for (i = 0; i < MB_in_width; i++)
      slice_nb[i] = (Int *)calloc(MB_in_height, sizeof(Int));
      
      
    intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
    
    alpha_decisions = AllocImage(B_in_width,B_in_height,SHORT_TYPE);
    MB_decisions    = AllocImage(MB_in_width,MB_in_height,SHORT_TYPE);
		mb_mode = (SInt *) GetImageData(MB_decisions);

    tmp_vop = AllocVop(GetVopWidth(rec_vop),GetVopHeight(rec_vop));
    CopyVopNonImageField(rec_vop,tmp_vop);

    /*****
     *
     *	Get the image fields of the VOP
     *
     *****/
    Y_rec = GetVopY (rec_vop);
    U_rec = GetVopU (rec_vop);
    V_rec = GetVopV (rec_vop);

    
    /*****
     *
     *	Get VOP quantizer and allocate MB structure
     *
     *****/
    vop_quant = GetVopQuantizer (rec_vop);
    QP = vop_quant;

    mblock = (Macroblock *) malloc (sizeof (Macroblock));

    if (mblock == NULL)
      {
	printf (" Error allocating macroblock\n");
	exit(1);
      }

if (GetVopSpriteUsage(rec_vop)==ONLINE_SPRITE)
	printf("Start SPRITE VOP decoding\n");
else
if (GetVopSpriteUsage(rec_vop)==GMC_SPRITE)
	printf("Start GMC VOP decoding\n");
else
        printf("Start P VOP decoding\n");

    /*****
     *
     *	Loop over all MBs, decode texture of each MB
     *
     *****/
    palpha_decisions = (SInt *)GetImageData(alpha_decisions);

    /* initialise values that indicate blockwise whether */
    /* the block is transparent                          */
    for (i = 0; i < B_in_width*B_in_height; i++)
      palpha_decisions[i] = 0; /*MBM_TRANSPARENT;*/


    /*****
    *
    * the macroblock loop
    *
    *****/
    mbnum = 0;
    counter = 0;
    skip_texture = 0;
    slice_counter = 0;
    stop_decoding = 0;
    mb_a = mb_b = 0;

    while(!stop_decoding)
      {
	mb_a = mb_b;

	DecodeVideoPacketDataPartitioningInterErrRes(stream,rec_vop, &mbnum,
						     &counter, &next_MB, 
						     mot_x, mot_y,
						     MB_decisions,
						     alpha_decisions, modeA,
						     motA_x, motA_y,
						     DC_store, QP_store, QP,
						     vop_quant, mblock,
						     error_flag, slice_nb,
						     &slice_counter,
						     header_data, trace,
						     &stop_decoding);
	mb_b = next_MB;
	
if (counter != mb_b - mb_a)
   {
     mbnum = mb_b;
     ConcealVideoPacket(rec_vop, GetVopNextTemp(rec_vop),
                        mot_x, mot_y, MB_decisions,
                        alpha_decisions, mb_a, mb_b);
    }      
 }
     
    /* mapping MB_decisions to alpha_decisions in order to make */
    /* VopMotionCompensate() work                               */
    
    RemapAlphaDecisions(alpha_decisions);

      VopMotionCompensate(GetVopNextTemp(rec_vop),mot_x,mot_y,MB_decisions,
			alpha_decisions,tmp_vop, 
			GetVopOBMCDisable(rec_vop),
			sprite); 
			
    
    VopTextureUpdate(tmp_vop,rec_vop,trace);
    
    /* Free allocated memory for 3D matrix */
    
    for (i = 0; i < MB_in_width*MB_in_height; i++)
      {
	for (j = 0; j < 6; j++)
	  free((Char *)DC_store[i][j]);
	free((Char *)DC_store[i]);
      }
    free((Char *)DC_store);
    

    /* Free allocated memory for 2D matrix */
    
    for (i = 0; i < MB_in_width; i++)
      free(slice_nb[i]);
    free(slice_nb);


    if (GetVopShape(rec_vop))
      {
	FreeImage(modeA);
	FreeImage(motA_x);
	FreeImage(motA_y);
	FreeShapePacket2();
      }
    
    FreeImage(alpha_decisions);
    free ((Char *)mblock);
    *mot_x_out = mot_x;
    *mot_y_out = mot_y;
    
  
    *MB_decisions_out = MB_decisions;

    FreeVop(tmp_vop);
    
    free(header_data);
    
    return;
}


/***********************************************************CommentBegin******
 *
 * -- DecodeVideoPacketDataPartitioningInterErrRes --
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	18-Nov-97
 *
 * Purpose : decodes all the data in a video packet of a P-VOP in the
 *           error resilient mode with data partitioning.		
 *
 *
 * Arguments in : 	
 *
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
DecodeVideoPacketDataPartitioningInterErrRes(Bitstream *stream,
					     Vop *rec_vop,
					     Int *mbnum,
					     Int *mb_counter,
					     Int *next_MB,
					     Image *mot_x,
					     Image *mot_y,
					     Image *MB_decisions,
					     Image *alpha_decisions,
					     Image *modeA,
					     Image *motA_x,
					     Image *motA_y,
					     Int ***DC_store,
					     SInt *QP_store,
					     Int QP,
					     Int vop_quant,
					     Macroblock *mblock,
					     Int *error_flag,
					     Int **slice_nb,
					     Int *slice_counter,
					     HeaderInfo *header_data,
					     Trace *trace,
					     Int *stop_decoding)
{
  Int mb_a, mb_b;

  mb_a = *mbnum;
  /*****
   *
   *  Decode packet
   *
   *****/

  DecodeFirstPartitionInterErrRes(stream, rec_vop, mbnum, mb_counter, mot_x, mot_y,
				  MB_decisions, alpha_decisions, modeA,
				  motA_x, motA_y, DC_store, QP_store,
				  QP, vop_quant, mblock, error_flag, slice_nb, *slice_counter,
				  header_data, trace);

 if (*error_flag)
    {
      LookForMarker(stream, rec_vop);
      ReadVideoPacketHeader(stream, rec_vop, slice_counter, trace,
			    next_MB, stop_decoding);
      mb_b = *next_MB;
      ConcealVideoPacket(rec_vop, GetVopNextTemp(rec_vop),
                         mot_x, mot_y,
                         MB_decisions,alpha_decisions,
                         mb_a, mb_b);
      *error_flag = 0;
      return;
    }

  DecodeSecondPartitionInterErrRes(stream, rec_vop, *mbnum, *mb_counter, MB_decisions, 
				   DC_store, QP_store, QP, vop_quant, error_flag, 
				   slice_nb, header_data, trace);

if (*error_flag)
    {
      LookForMarker(stream, rec_vop);
      ReadVideoPacketHeader(stream, rec_vop, slice_counter, trace,
		            next_MB, stop_decoding);
      mb_b = *next_MB;
      ConcealTexture(rec_vop, mot_x, mot_y, MB_decisions, mb_a, mb_b);
      *error_flag = 0;
      return;
    }

  ReadVideoPacketHeader(stream, rec_vop, slice_counter, trace, next_MB, stop_decoding);


  return;
}


/***********************************************************CommentBegin******
 *
 * -- DecodeFirstPartitionInterErrRes --
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	18-Nov-97
 *
 * Purpose : decodes the data in the first partition of a video packet 
 *           of a P-VOP in the error resilient mode with data partitioning.		
 *
 *
 * Arguments in : 	
 *
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
DecodeFirstPartitionInterErrRes(Bitstream *stream,
				Vop *rec_vop,
				Int *mb_number,
				Int *mb_counter,
				Image *mot_x,
				Image *mot_y,
				Image *MB_decisions,
				Image *alpha_decisions,
				Image *modeA,
				Image *motA_x,
				Image *motA_y,
				Int ***DC_store,
				SInt *QP_store,
				Int QP,
				Int vop_quant,
				Macroblock *mblock,
				Int *error_flag,
				Int **slice_nb,
				Int slice_counter,
				HeaderInfo *header_data,
				Trace *trace)
{

  Int         rec_height, rec_width;
  Int         MB_in_height, MB_in_width;
  Int         intra_dcpred_disable;
  Int         mbnum;
  Int         x_pos, y_pos;
  Int         mode = 0;
  Int         f_code;
  Int         i, m, n;
  SInt        *mb_mode;
  Int         vo_id, vol_id;
  Int         start_of_packet;
  Int         amb_type;

  /*****
   *
   *  Set some useful parameters
   *
   *****/
  rec_height = GetVopHeight(rec_vop);
  rec_width  = GetVopWidth(rec_vop);
  MB_in_height = rec_height / MB_SIZE;
  MB_in_width  = rec_width / MB_SIZE;
  intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
  f_code=GetVopFCodeFor(rec_vop);
  vo_id = GetVopVOId(rec_vop);
  vol_id = GetVopId(rec_vop);
  mb_mode = (SInt *) GetImageData(MB_decisions);
  mbnum = *mb_number;
  start_of_packet = 1;

  /*****
   *
   *  Loop over the MBs, decode the information in the first partition
   *
   *****/

  do{
      
    x_pos = mbnum % MB_in_width;
    y_pos = mbnum / MB_in_width;
    
    slice_nb[x_pos][y_pos] = slice_counter;
    
    trace->trace = trace->MB_header;
    
    if (trace->trace)
      {
	fprintf (trace->fp_trace,"\n>>>   Decoding Macroblock %d ........- Combined Motion/Shape/Text\n",(int)mbnum);
      }
    
    /* Store the QP value for later use in AC prediction */
    QP_store[mbnum] = (SInt) QP;
    
    /* decode COD, MCPC, ACpred_flag, CPBY and DQUANT */
    header_data[mbnum].coded = 0;
    header_data[mbnum].skipped_flag = 1;
    
    /* set all blocks to opaque */
    for(i=0;i<4;i++) 
      header_data[mbnum].MB_transp_pattern[i]=0;
    
    if (GetVopPredictionType(rec_vop) == SPRITE_VOP)
      mb_mode[mbnum] = MBM_SPRITE;
    else   /* P_VOP */
      mb_mode[mbnum] = MBM_OPAQUE;
    
    if (GetVopShape(rec_vop)) 
      {

	GetMBInterShapeErrRes(stream,GetVopNextTemp(rec_vop),
			      vo_id,vol_id,y_pos,x_pos,mbnum,
			      MB_decisions,alpha_decisions,mot_x,mot_y,
			      modeA,motA_x,motA_y,start_of_packet,&amb_type,
			      header_data[mbnum].MB_transp_pattern,
			      error_flag,rec_vop,trace);
	start_of_packet = 0;
      }
	
    if (mb_mode[mbnum] != MBM_TRANSPARENT)
      {
	GetMBheaderMotionErrRes(stream,mbnum,trace,
				&header_data[mbnum].skipped_flag, 
				error_flag,DC_store,
				&header_data[mbnum].coded, 
				&header_data[mbnum].CBP,
				&header_data[mbnum].mode,
				header_data[mbnum].MB_transp_pattern,rec_vop);
	
	QP_store[mbnum] = (SInt) vop_quant;
	mode = header_data[mbnum].mode;
	
	if (!header_data[mbnum].coded)
	  mb_mode[mbnum] = SKIPPED;
      }
    else
      {
	MBzero (mblock);
	/* Fill DC_store with default coeff values */
	for (m = 0; m < 6; m++) 
	  {
	    DC_store[mbnum][m][0] = GetVopMidGrey(rec_vop)*8;
	    for (n = 1; n < 15; n++)
	      DC_store[mbnum][m][n] = 0;
	  }
      }
	 
    
    
    /* decode the MV for texture */
    
    if ((header_data[mbnum].coded) && (mode == MODE_INTER || mode == MODE_INTER_Q || 
				       mode == MODE_INTER4V || mode == MODE_INTRA || mode == MODE_INTRA_Q || mode == MODE_DYN_SP))
      GetMBvectorsErrRes(intra_dcpred_disable,stream,mbnum,
			 MB_in_width,f_code,trace,MB_decisions,
			 alpha_decisions, mot_x, mot_y, error_flag,
			 header_data[mbnum].mode, 
			 GetVopErrorResDisable(rec_vop), 
			 slice_nb, GetVopShape(rec_vop));
    
    if (*error_flag)
      return;
    
    mbnum++;
    
  } while (((BitstreamShowBits(stream,MOTION_MARKER_COMB_LENGTH))!=MOTION_MARKER_COMB) &&
	   (mbnum < MB_in_width * MB_in_height));
  
  
  if (mbnum > MB_in_width*MB_in_height)
    {
      *error_flag = 1;
      return;
    }
  
  *mb_counter = mbnum - *mb_number;
  *mb_number = mbnum;

  BitstreamReadBits(stream,MOTION_MARKER_COMB_LENGTH,"motion marker",trace,NUM); 
  
  return;
}                 /* DecodeFirstPartitionInterErrRes */


/***********************************************************CommentBegin******
 *
 * -- DecodeSecondPartitionInterErrRes --
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	18-Nov-97
 *
 * Purpose : decodes the data in the second partition of a video packet 
 *           of a P-VOP in the error resilient mode with data partitioning.		
 *
 *
 * Arguments in : 	
 *
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
DecodeSecondPartitionInterErrRes(Bitstream *stream,
				 Vop *rec_vop,
				 Int mbnum,
				 Int mb_counter,
				 Image *MB_decisions,
				 Int ***DC_store,
				 SInt *QP_store,
				 Int QP,
				 Int vop_quant,
				 Int *error_flag,
				 Int **slice_nb,
				 HeaderInfo *header_data,
				 Trace *trace)
{

  Image *Y_rec, *U_rec, *V_rec;
  Macroblock *mblock;
  Int         rec_height, rec_width;
  Int         MB_in_height, MB_in_width;
  Int intra_dcpred_disable;
  Int counter1, counter2;

  /*****
   *
   *  Set some useful parameters
   *
   *****/
  rec_height = GetVopHeight(rec_vop);
  rec_width  = GetVopWidth(rec_vop);
  MB_in_height = rec_height / MB_SIZE;
  MB_in_width  = rec_width / MB_SIZE;
  intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);

  mblock = (Macroblock *) malloc (sizeof (Macroblock));

  if (mblock == NULL)
    {
      printf (" Error allocating macroblock\n");
      exit(1);
    }
  
  /*****
   *
   *    Get the image fields of the VOP
   *
   *****/
  Y_rec = GetVopY (rec_vop);
  U_rec = GetVopU (rec_vop);
  V_rec = GetVopV (rec_vop);


  /*****
   *
   *   Loop over the MBs, decode the information in the second partition
   *
   *****/
  counter1 = counter2 = mbnum - mb_counter;

  while (counter1 < mbnum)
    {
      /* decode the DCT coeficients for the MB */
      if (header_data[counter1].coded)
	{
	  
	  GetMBheaderTextInterErrRes(intra_dcpred_disable,&vop_quant,
				     stream,counter1,trace,MB_decisions,
				     error_flag,&header_data[counter1].coded, 
				     &header_data[counter1].CBP, 
				     &header_data[counter1].ACpred_flag,
				     &header_data[counter1].mode,
				     header_data[counter1].MB_transp_pattern,
				     header_data[counter1].IntraDC,
				     rec_vop);
	  
	}
      counter1++;
    }


  if (*error_flag)
    return;

  while (counter2 < mbnum)
    {
      if (header_data[counter2].coded)
	{
	  GetMBblockdataErrRes(header_data[counter2].MB_transp_pattern,
			       intra_dcpred_disable,vop_quant,
			       stream,counter2,trace,
			       mblock,error_flag,MB_in_width,
			       DC_store,QP_store,QP,
			       header_data[counter2].CBP,
			       header_data[counter2].ACpred_flag,
			       header_data[counter2].mode,
			       header_data[counter2].IntraDC,
			       rec_vop,slice_nb);
	  
	  
	}
      
      /* (skipped_flag==1) Clear the skipped MB */
      if (header_data[counter2].skipped_flag == 1)
	MBzero (mblock);
      
      
      FillVop (mblock, counter2, Y_rec, U_rec, V_rec);
      counter2++;
    }

  free ((Char *)mblock);

  return;
}                   /* DecodeSecondPartitionInterErrRes */



/***********************************************************CommentBegin******
 *
 * -- DecodeVopCombinedMotionShapeTextureInterErrRes -- 
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	18-Sep-97
 *
 * Purpose :		
 *      Decodes error resilient combined motion / shape / texture for INTER
 *      VOPs
 *
 * Arguments in : 	
 *	Bitstream *stream	combined shape / texture bitstream
 *      Int vo_id               video object identification
 *	Trace  *trace		flag for tracing the process.
 *
 *
 * Arguments in/out :	
 *	Vop *rec_vop		alpha plane is supposed to be filled
 *				already / YUV components.
 *
 * Arguments out :	
 *      Image **mot_x_out           x-component of motion vectors needed for B-VOPs
 *      Image **mot_y_out           y-component of motion vectors needed for B-VOPs
 *      Image **MB_decisions_out    macroblock modes also needed for B-VOPs
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : based on DecodeVopCombinedMotionShapeTextureInter() as of 01.05.97
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *      15.05.97 Luis Ducla-Soares: corrected the remultiplexing of the DCT data
 *                                  in the combined error resilient mode with 
 *                                  data partitioning. Cleaned up the code.
 *			19.09.97 Noel Brady: quant_scale not present when in shape only mode
 *			19.09.97 Noel Brady: fcodes are now in HEC (except for shape only mode)
 *      09.12.97 Luis Ducla-Soares: changes to allow the use of B-VOPs.
 *      09.12.97 Luis Ducla-Soares: changed the name of the function from 
 *                                  DecodeVopCombNoDataPartMotionShapeTextureInterErrRes to
 *                                  DecodeVopCombinedMotionShapeTextureInterErrRes.
 *      10.12.97 Luis Ducla-Soares: restructured the code. moved the code in
 *                                  the macroblock loop to a new function: 
 *                                  DecodeVideoPacketCombinedInterErrRes.
 *
 ***********************************************************CommentEnd********/
Void DecodeVopCombinedMotionShapeTextureInterErrRes(Bitstream * stream, 
						    Int vo_id,
						    Trace *trace,
						    Vop *rec_vop,
						    Image **mot_x_out,
						    Image **mot_y_out,
						    Image **MB_decisions_out)
{
		
  Int           ef=0, *error_flag = &ef; 
  Int           mbnum, i, j;
  Int           rec_height;
  Int 		rec_width;
  Int		MB_in_height, MB_in_width;
  Int           B_in_width, B_in_height;
  Macroblock    *mblock;
  Image         *Y_rec, *U_rec, *V_rec;
  Int           vop_quant,intra_dcpred_disable;
  Image         *alpha_decisions,*MB_decisions;
  SInt		*palpha_decisions,*mb_mode;
  Int           ***DC_store;
  Int           **slice_nb;
  Int           slice_counter;
  Int           f_code=GetVopFCodeFor(rec_vop);
  Image         *mot_x, *mot_y;
  Vop           *tmp_vop;
  SInt          *QP_store;
  Int           QP;
  Int           counter, next_MB;
  Int           MB_in_VOP;
  Int           MB_in_VOP_length;
  HeaderInfo    *header_data;
  Int           skip_texture;
  Int           resync_marker_length;
  Int           stop_decoding;
  Int           mb_a, mb_b;

	Image *modeA =0; /* the flag of current alpha block is inter coded or not */
	Image *motA_x =0; /* the x compornent of shape MV */
	Image *motA_y = 0; /* the y compornent of shape MV */

    
/* SPRITE */	
  Vop *sprite=NULL;

  if (GetVopSpriteUsage(rec_vop)!=SPRITE_NOT_USED)
  	{ 
	sprite = GetVopSprite(rec_vop);
	}


    /*****
     *
     *	Set some useful parameters
     *
     *****/
    rec_height = GetVopHeight (rec_vop);
    rec_width = GetVopWidth (rec_vop);
    MB_in_height = rec_height / MB_SIZE;
    MB_in_width = rec_width / MB_SIZE;
    B_in_width = 2 * MB_in_width;
    B_in_height = 2 * MB_in_height;
    QP_store = (SInt *) GetImageData(GetVopQP(rec_vop));
    MB_in_VOP = MB_in_width * MB_in_height;
    MB_in_VOP_length = (Int) ceil(log(MB_in_VOP)/log(2));

		if (GetVopShape(rec_vop) == BINARY_SHAPE_ONLY)
    	resync_marker_length = 17;
		else
    	resync_marker_length = 16 + f_code;

  
    mot_x = AllocImage((UInt) B_in_width,(UInt) B_in_height,FLOAT_TYPE);
    mot_y = AllocImage((UInt) B_in_width,(UInt) B_in_height,FLOAT_TYPE);

		if (GetVopShape(rec_vop))
			{
  			/* Allocate shape ME/MC */
  			modeA = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
		      GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
  			motA_x = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
		       GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
  			motA_y = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
		       GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
			}

    header_data = (HeaderInfo *)calloc(MB_in_width*MB_in_height,sizeof(HeaderInfo));


    SetConstantImage(mot_x,0.0);
    SetConstantImage(mot_y,0.0);

    /* allocate space for 3D matrix to keep track of prediction values
       for DC/AC prediction */
    
    DC_store = (Int ***)calloc(MB_in_width*MB_in_height,
			       sizeof(Int **));
    for (i = 0; i < MB_in_width*MB_in_height; i++)
      {
	DC_store[i] = (Int **)calloc(6, sizeof(Int *));
	for (j = 0; j < 6; j++)
	  DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
      }
    

    /* allocate space for 2D matrix to keep track of the slice numbers */
    
    slice_nb = (Int **)calloc(MB_in_width,sizeof(Int *));
    
    for (i = 0; i < MB_in_width; i++)
      slice_nb[i] = (Int *)calloc(MB_in_height, sizeof(Int));


    intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
    
    alpha_decisions = AllocImage(B_in_width,B_in_height,SHORT_TYPE);
    MB_decisions    = AllocImage(MB_in_width,MB_in_height,SHORT_TYPE);

    tmp_vop = AllocVop(GetVopWidth(rec_vop),GetVopHeight(rec_vop));
    CopyVopNonImageField(rec_vop,tmp_vop);

    /*****
     *
     *	Get the image fields of the VOP
     *
     *****/
    Y_rec = GetVopY (rec_vop);
    U_rec = GetVopU (rec_vop);
    V_rec = GetVopV (rec_vop);

    
    /*****
     *
     *	Get VOP quantizer and allocate MB structure
     *
     *****/
    vop_quant = GetVopQuantizer (rec_vop);
    QP = vop_quant;

    mblock = (Macroblock *) malloc (sizeof (Macroblock));

    if (mblock == NULL)
      {
	printf (" Error allocating macroblock\n");
	exit(1);
      }

if (GetVopSpriteUsage(rec_vop)==ONLINE_SPRITE)
	printf("Start SPRITE VOP decoding\n");
else
if (GetVopSpriteUsage(rec_vop)==GMC_SPRITE)
	printf("Start GMC VOP decoding\n");
else
        printf("Start P VOP decoding\n");

    /*****
     *
     *	Loop over all MBs, decode texture of each MB
     *
     *****/
    mb_mode = (SInt *)GetImageData(MB_decisions);
    palpha_decisions = (SInt *)GetImageData(alpha_decisions);

    /* initialise values that indicate blockwise whether */
    /* the block is transparent                          */
    for (i = 0; i < B_in_width*B_in_height; i++)
      palpha_decisions[i] = 0; /*MBM_TRANSPARENT;*/

    /*****
    *
    * the macroblock loop
    *
    *****/
    mbnum = 0;
    counter = 0;
    skip_texture = 0;
    slice_counter = 0;
    stop_decoding = 0;
    mb_a = mb_b = 0;

		if (GetVopShape(rec_vop)) AllocShapePacket2(rec_vop);
		
    while(!stop_decoding)
      {
	mb_a = mb_b;
	
	DecodeVideoPacketCombinedInterErrRes(stream, rec_vop, &mbnum,&counter,
					     &next_MB, mot_x, mot_y, MB_decisions,
					     alpha_decisions, modeA, motA_x,
					     motA_y, DC_store, QP_store, QP,
					     vop_quant, error_flag,
					     slice_nb, &slice_counter,
					     header_data, trace,
					     &stop_decoding);
	mb_b = next_MB;
	
 if (counter != mb_b - mb_a)
   {
     mbnum = mb_b;
     ConcealVideoPacket(rec_vop, GetVopNextTemp(rec_vop),
                        mot_x, mot_y, MB_decisions,
                        alpha_decisions, mb_a, mb_b);
     }
   }
    
    
 
    /* mapping MB_decisions to alpha_decisions in order to make */
    /* VopMotionCompensate() work                               */
    
    RemapAlphaDecisions(alpha_decisions);

      VopMotionCompensate(GetVopNextTemp(rec_vop),mot_x,mot_y,MB_decisions,
			alpha_decisions,tmp_vop, 
			GetVopOBMCDisable(rec_vop),
			sprite); 
			

    VopTextureUpdate(tmp_vop,rec_vop,trace);

		if (GetVopShape(rec_vop)) FreeShapePacket2();

    /* Free allocated memory for 3D matrix */
    
    for (i = 0; i < MB_in_width*MB_in_height; i++)
      {
	for (j = 0; j < 6; j++)
	  free((Char *)DC_store[i][j]);
	free((Char *)DC_store[i]);
      }
    free((Char *)DC_store);
    

    /* Free allocated memory for 2D matrix */
    
    for (i = 0; i < MB_in_width; i++)
      free(slice_nb[i]);
    free(slice_nb);
    
    if (GetVopShape(rec_vop))
      {
	FreeImage(modeA);
	FreeImage(motA_x);
	FreeImage(motA_y);
      }

    FreeImage(alpha_decisions);
     free ((Char *)mblock);
    *mot_x_out = mot_x;
    *mot_y_out = mot_y;
    
    *MB_decisions_out = MB_decisions;
    
    FreeVop(tmp_vop);
    
    free(header_data);
    
    return;
}


/***********************************************************CommentBegin******
 *
 * -- DecodeVideoPacketCombinedInterErrRes --
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	20-Nov-97
 *
 * Purpose : decodes all the data in a video packet of a P-VOP in the
 *           error resilient combined mode.		
 *
 *
 * Arguments in : 	
 *
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
DecodeVideoPacketCombinedInterErrRes(Bitstream *stream,
				     Vop *rec_vop,
				     Int *mbnum,
				     Int *mb_counter,
				     Int *next_MB,
				     Image *mot_x,
				     Image *mot_y,
				     Image *MB_decisions,
				     Image *alpha_decisions,
				     Image *modeA,
				     Image *motA_x,
				     Image *motA_y,
				     Int ***DC_store,
				     SInt *QP_store,
				     Int QP,
				     Int vop_quant,
				     Int *error_flag,
				     Int **slice_nb,
				     Int *slice_counter,
				     HeaderInfo *header_data,
				     Trace *trace,
				     Int *stop_decoding
				     )
{
  Int mb_a, mb_b;

  mb_a = *mbnum;
  /*****
   *
   *  Decode packet
   *
   *****/

  DecodeCombinedPacketInfoInterErrRes(stream, rec_vop, mbnum, mb_counter,
				      mot_x, mot_y, MB_decisions,
				      alpha_decisions, modeA, motA_x,
				      motA_y, DC_store, QP_store,
				      QP, vop_quant, error_flag, slice_nb,
				      *slice_counter, header_data, trace);
if (*error_flag)
    {
      LookForMarker(stream, rec_vop);
      ReadVideoPacketHeader(stream, rec_vop, slice_counter, trace,
			    next_MB, stop_decoding);
      mb_b = *next_MB;
      ConcealVideoPacket(rec_vop, GetVopNextTemp(rec_vop),
                         mot_x, mot_y, MB_decisions,
                         alpha_decisions, mb_a, mb_b);
      *error_flag = 0;
      return;
    }  
  ReadVideoPacketHeader(stream, rec_vop, slice_counter, trace, next_MB, stop_decoding);

  return;
}

/***********************************************************CommentBegin******
 *
 * -- DecodeCombinedPacketInfoInterErrRes --
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	20-Nov-97
 *
 * Purpose : decodes the video data in a video packet 
 *           of a P-VOP in the error resilient combined mode.		
 *
 *
 * Arguments in : 	
 *
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
DecodeCombinedPacketInfoInterErrRes(Bitstream *stream,
				    Vop *rec_vop,
				    Int *mb_number,
				    Int *mb_counter,
				    Image *mot_x,
				    Image *mot_y,
				    Image *MB_decisions,
				    Image *alpha_decisions,
				    Image *modeA,
				    Image *motA_x,
				    Image *motA_y,
				    Int ***DC_store,
				    SInt *QP_store,
				    Int QP,
				    Int vop_quant,
				    Int *error_flag,
				    int **slice_nb,
				    Int slice_counter,
				    HeaderInfo *header_data,
				    Trace *trace)
{

  Image *Y_rec, *U_rec, *V_rec;
  Macroblock *mblock;
  Int         rec_height, rec_width;
  Int         MB_in_height, MB_in_width;
  Int         intra_dcpred_disable;
  Int         mbnum;
  Int         x_pos, y_pos;
  Int         amb_type;
  Int         mode =0 ;
  Int         f_code;
  Int         i, n, m;
  Int         resync_marker_length;
  Int         start_of_packet;
  SInt        *mb_mode;
  Int         vo_id, vol_id;

  /*****
   *
   *  Set some useful parameters
   *
   *****/
  rec_height = GetVopHeight(rec_vop);
  rec_width  = GetVopWidth(rec_vop);
  MB_in_height = rec_height / MB_SIZE;
  MB_in_width  = rec_width / MB_SIZE;
  intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
  f_code=GetVopFCodeFor(rec_vop);
  vo_id = GetVopVOId(rec_vop);
  vol_id = GetVopId(rec_vop);

  if (GetVopShape(rec_vop) == BINARY_SHAPE_ONLY)
    resync_marker_length = 17;
  else
    resync_marker_length = 16 + f_code;

  mbnum = *mb_number;
  start_of_packet = 1;

  mblock = (Macroblock *) malloc (sizeof (Macroblock));
  
  if (mblock == NULL)
    {
      printf (" Error allocating macroblock\n");
      exit(1);
    }

  mb_mode = (SInt *)GetImageData(MB_decisions);

  /*****
   *
   *    Get the image fields of the VOP
   *
   *****/
  Y_rec = GetVopY (rec_vop);
  U_rec = GetVopU (rec_vop);
  V_rec = GetVopV (rec_vop);


  do {
    x_pos = mbnum % MB_in_width;
    y_pos = mbnum / MB_in_width;
    
    slice_nb[x_pos][y_pos] = slice_counter;
    
    trace->trace = trace->MB_header;
    
    if (trace->trace)
      {
	fprintf (trace->fp_trace,"\n>>>   Decoding Macroblock %d ........- Combined Motion/Shape/Text\n",(int)mbnum);
      }
    
    /* Store the QP value for later use in AC prediction */
    QP_store[mbnum] = (SInt) QP;
    
    
    /* decode COD, MCPC, ACpred_flag, CPBY and DQUANT */
    header_data[mbnum].coded = 0;
    header_data[mbnum].skipped_flag = 1;
    
    amb_type = 0;
    
    /* set all blocks to opaque */
    for(i=0;i<4;i++) 
      header_data[mbnum].MB_transp_pattern[i]=0;
    
    if (GetVopPredictionType(rec_vop) == SPRITE_VOP)
      mb_mode[mbnum] = MBM_SPRITE;
    else   /* P_VOP */
      mb_mode[mbnum] = MBM_OPAQUE;
    
    if (GetVopShape(rec_vop)) 
      {
	GetMBInterShapeErrRes(stream,GetVopNextTemp(rec_vop),
			      vo_id,vol_id,y_pos,x_pos,mbnum,
			      MB_decisions,alpha_decisions,mot_x,mot_y,
			      modeA,motA_x,motA_y,start_of_packet,&amb_type,
			      header_data[mbnum].MB_transp_pattern,
			      error_flag,rec_vop,trace);
	start_of_packet = 0;
      }

   
    if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY)
      {
	if (mb_mode[mbnum] != MBM_TRANSPARENT)
	  {
	    GetMBheaderNoDataPartInterErrRes(stream,intra_dcpred_disable,
					     mbnum,trace,
					     &header_data[mbnum].skipped_flag,
					     error_flag,DC_store,
					     &header_data[mbnum].coded, 
					     &header_data[mbnum].CBP,
					     &header_data[mbnum].ACpred_flag,
					     &header_data[mbnum].mode,
					     header_data[mbnum].MB_transp_pattern,rec_vop);
	    
	    QP_store[mbnum] = (SInt) vop_quant;
	    mode = header_data[mbnum].mode;
	    if (!header_data[mbnum].coded)
	      mb_mode[mbnum] = SKIPPED;
	  }
	else
	  {
	    MBzero (mblock);
	    /* Fill DC_store with default coeff values */
	    for (m = 0; m < 6; m++) 
	      {
		DC_store[mbnum][m][0] = GetVopMidGrey(rec_vop)*8;
		for (n = 1; n < 15; n++)
		  DC_store[mbnum][m][n] = 0;
	      }
	  }
	
	
	if (!*error_flag)
	  {
	    /* decode the MV for texture */
	    
	    if ((header_data[mbnum].coded) && (mode == MODE_INTER || mode == MODE_INTER_Q || 
					       mode == MODE_INTER4V || mode == MODE_INTRA ||
					       mode == MODE_INTRA_Q || mode == MODE_DYN_SP))
	      GetMBvectorsNoDataPartErrRes(stream,mbnum, MB_in_width,f_code,trace,MB_decisions,
					   alpha_decisions, mot_x, mot_y, error_flag,
					   header_data[mbnum].mode, header_data[mbnum].IntraDC,
					   GetVopErrorResDisable(rec_vop),
					   slice_nb, GetVopShape(rec_vop));
	    
	  }
	
	
	
	if (header_data[mbnum].coded)
	  {
	    if (*error_flag != RETURN)
	      GetMBblockdataNoDataPartErrRes(header_data[mbnum].MB_transp_pattern,
					     intra_dcpred_disable,
					     vop_quant,stream,mbnum,
					     trace,mblock,error_flag, 
					     MB_in_width,
					     DC_store,QP_store,QP,
					     header_data[mbnum].CBP,
					     header_data[mbnum].ACpred_flag,
					     header_data[mbnum].mode,
					     rec_vop, slice_nb);
	    
	    QP = vop_quant;
	    
	  }
	
	/* (skipped_flag==1) Clear the skipped MB */
	if (header_data[mbnum].skipped_flag == 1)
	  MBzero (mblock);
	
	
	FillVop (mblock, mbnum, Y_rec, U_rec, V_rec);
      }
    mbnum++;
    
  } while ((mbnum < MB_in_width*MB_in_height) && (!MarkerFound(stream,resync_marker_length)));
  
  if (mbnum > MB_in_width*MB_in_height)
    {
      *error_flag = 1;
      return;
    }
  
  *mb_counter = mbnum - *mb_number;
  *mb_number = mbnum;
  
  free ((Char *)mblock);
  
  return;
}



Void RemapAlphaDecisions(Image *alpha)
{
  SInt *p = (SInt *) GetImageData(alpha),
    *pe = p + GetImageSize(alpha);
  
  while (p<pe)
    {
      if (*p == 0) *p = 1;
      if (*p == 2) *p = MBM_TRANSPARENT; /*MBM_TRANSPARENT;*/ /*2*/
      p++;
    }
}


Void SetAlphaDecisions(Image *alpha, Int mbx_pos, Int mby_pos,
		       Image *alpha_decisions)
{
	Int bx_pos = 2*mbx_pos,
			by_pos = 2*mby_pos,
			x_pos = mbx_pos*MB_SIZE, 
			y_pos = mby_pos*MB_SIZE,
			x,
			y,
			white_pel;

	Int width_out = GetImageSizeX(alpha_decisions),
			width_in = GetImageSizeX(alpha);

	SInt *p_out = (SInt *) GetImageData(alpha_decisions) 
				+ width_out*by_pos +bx_pos;

	SInt *p_in_mb = (SInt *)GetImageData(alpha)+y_pos*width_in+x_pos,
				*p_in;

	white_pel = 0;
	p_in = p_in_mb;
	for (y=0;y<MB_SIZE/2;y++,p_in+=width_in-MB_SIZE/2)
		for (x=0;x<MB_SIZE/2;x++,p_in++)
			if (*p_in) white_pel=1;
	if (white_pel) *p_out = 0;
	else *p_out = MBM_TRANSPARENT; /*apa*/

	white_pel = 0;
	p_in = p_in_mb+MB_SIZE/2;
	p_out++;
	for (y=0;y<MB_SIZE/2;y++,p_in+=width_in-MB_SIZE/2)
		for (x=0;x<MB_SIZE/2;x++,p_in++)
			if (*p_in) white_pel=1;
	if (white_pel) *p_out = 0;
	else *p_out = MBM_TRANSPARENT; /*apa*/

	white_pel = 0;
	p_in = p_in_mb + width_in*(MB_SIZE/2);
	p_out--;p_out+=width_out;
	for (y=0;y<MB_SIZE/2;y++,p_in+=width_in-MB_SIZE/2)
		for (x=0;x<MB_SIZE/2;x++,p_in++)
			if (*p_in) white_pel=1;
	if (white_pel) *p_out = 0;
	else *p_out = MBM_TRANSPARENT; /*apa*/

	white_pel = 0;
	p_out++;
	p_in = p_in_mb + width_in*(MB_SIZE/2) + MB_SIZE/2;
	for (y=0;y<MB_SIZE/2;y++,p_in+=width_in-MB_SIZE/2)
		for (x=0;x<MB_SIZE/2;x++,p_in++)
			if (*p_in) white_pel=1;
	if (white_pel) *p_out = 0;
	else *p_out = MBM_TRANSPARENT; /*apa*/
}
	

Void GetMBIntraShapeErrRes(Bitstream *stream, Int vo_id, 
			   Int vol_id, Int y_pos, Int x_pos,
			   Image *MB_decisions, Int start_of_packet, 	
			   Int *amb_type, Int *MB_transp_pattern,
			   Int *error_flag, Vop *rec_vop, Trace *trace)
{
  Int *mvda =0;
  SInt *alpha;
  Int rec_width;
  SInt i,j;

	/* decode the shape codes */
	
	  DecodeFirst(stream, 
		   	vo_id, 
		        vol_id, 
			y_pos, 
			x_pos, 
			amb_type, 
			mvda, 
			0, 
			start_of_packet,
			rec_vop,
                        GetVopPrevTemp(rec_vop),
			trace);

	/* fill the alpha map with the decoded pixels for this MB */
	AlphaDecodeMB(rec_vop, 
		      (Vop *)NULL, 
		      vo_id,
		      vol_id,
		      y_pos, 
		      x_pos, 
		      amb_type,
		      mvda, 
		      0,
		      MB_decisions,
		      (Image *)NULL,
		      (Image *)NULL,
		      (Image *)NULL,
		      (Image *)NULL,	
		      (Image *)NULL,
		      (Image *)NULL,
		      start_of_packet,
		      stream,
		      trace,
		      error_flag);

  /* calculating MB_transp_pattern */
	for(i=0;i<4;i++)
	  MB_transp_pattern[i]=1;

	if (*amb_type != 1) /* if not a transparent MB */
		{
			alpha = (SInt *) GetImageData(GetVopA(rec_vop));
			rec_width = GetVopWidth(rec_vop);
	      
	  	for(i=0;i<B_SIZE;i++)
	  		for(j=0;j<B_SIZE;j++)
					if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			 			(x_pos * MB_SIZE) +j] != 0)
		  				MB_transp_pattern[0]=0;
	  
			for(i=0;i<B_SIZE;i++)
				for(j=B_SIZE;j<2*B_SIZE;j++)
					if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			 			(x_pos * MB_SIZE) +j] != 0)
		  					MB_transp_pattern[1]=0;
	      
			for(i=B_SIZE;i<2*B_SIZE;i++)
	    	for(j=0;j<B_SIZE;j++)
					if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			 			(x_pos * MB_SIZE) +j] != 0)
		  				MB_transp_pattern[2]=0;
	      
			for(i=B_SIZE;i<2*B_SIZE;i++)
	    	for(j=B_SIZE;j<2*B_SIZE;j++)
		  		if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   		(x_pos * MB_SIZE) +j] != 0)
		  				MB_transp_pattern[3]=0;
 		}

}

Void GetMBInterShapeErrRes(Bitstream *stream, Vop *prev_vop,Int vo_id, 
			   Int vol_id, Int y_pos, Int x_pos, Int mbnum,
			   Image *MB_decisions, Image *alpha_decisions,
			   Image *mot_x, Image *mot_y, Image *modeA,
			   Image *motA_x, Image *motA_y, Int start_of_packet, 	
			   Int *amb_type, Int *MB_transp_pattern,
			   Int *error_flag, Vop *rec_vop, Trace *trace)
{
	Int mvda;
	SInt *alpha;
	Int rec_width;
        SInt i,j;
	SInt *mb_mode = (SInt *) GetImageData(MB_decisions);

	/* decode the shape codes */
	
	    DecodeFirst(stream, 
			vo_id, 
			vol_id, 
			y_pos, 
			x_pos, 
			amb_type, 
			&mvda, 
			1, 
			start_of_packet,
			rec_vop,
                        prev_vop,
			trace);

	/* fill the alpha map with the decoded pixels for this MB */
	AlphaDecodeMB(rec_vop, 
		      prev_vop, 
		      vo_id,
		      vol_id,
		      y_pos, 
		      x_pos, 
		      amb_type,
		      &mvda, 
		      1,
		      MB_decisions,
		      alpha_decisions,
		      mot_x,
		      mot_y,
		      modeA,
		      motA_x,
		      motA_y,		
		      start_of_packet,
		      stream,
		      trace,
		      error_flag);
	
  /* calculating MB_transp_pattern */
	for(i=0;i<4;i++)
	  MB_transp_pattern[i]=1;

	if (*amb_type != 1) /* if not a transparent MB */
		{
			alpha = (SInt *) GetImageData(GetVopA(rec_vop));
			rec_width = GetVopWidth(rec_vop);
	      
	  	for(i=0;i<B_SIZE;i++)
	  		for(j=0;j<B_SIZE;j++)
					if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			 			(x_pos * MB_SIZE) +j] != 0)
		  				MB_transp_pattern[0]=0;
	  
			for(i=0;i<B_SIZE;i++)
				for(j=B_SIZE;j<2*B_SIZE;j++)
					if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			 			(x_pos * MB_SIZE) +j] != 0)
		  					MB_transp_pattern[1]=0;
	      
			for(i=B_SIZE;i<2*B_SIZE;i++)
	    	for(j=0;j<B_SIZE;j++)
					if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			 			(x_pos * MB_SIZE) +j] != 0)
		  				MB_transp_pattern[2]=0;
	      
			for(i=B_SIZE;i<2*B_SIZE;i++)
	    	for(j=B_SIZE;j<2*B_SIZE;j++)
		  		if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   		(x_pos * MB_SIZE) +j] != 0)
		  				MB_transp_pattern[3]=0;
 		}

	if ((MB_transp_pattern[0] + 	
				MB_transp_pattern[1] +
						MB_transp_pattern[2] +
							MB_transp_pattern[3]) == 4)
		mb_mode[mbnum] = MBM_TRANSPARENT;
	 
	SetAlphaDecisions(GetVopA(rec_vop),x_pos,y_pos,alpha_decisions);  	  
}

/***********************************************************CommentBegin******
 *
 * -- GetMBheader --  
 *
 * Author :
 *      Jan De Lameillieure (HHI) <jan@hhi.de>
 *
 * Created :
 *      18-Jan-97
 *
 * Purpose :
 *       decodes the MCBPC, ACpred_flag, CBPY and DQUANT of a MB (for combined mode)
 *
 * Arguments in :
 *      Int vop_type,                   vop INTRA/INTER.
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int *quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Macroblock *mblock,             decoded macroblock.
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *      Int *coded,                     set if the MB contains coded texture
 *      UInt *CBP,                      Coded Block Pattern derived from MB header data
 *      Int *ACpred_flag                flag indicating the the use of AC prediction
 *      UInt *mode                      macroblock mode
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description :
 *      Starting point for this function was the first part of GetMBtext() of 
 *      the file text_decode_mb.c of 16-Jan-97
 *
 * See also :
 *
 *
 * Modified : 
 *     13.05.97 Minhua Zhou: added MB_transp_pattern
 *     12.08.97 Minhua Zhou: assigned skipped MB to mode=MODE_INTER
 *     12.12.97 Bob Eifrig: decode interlaced_information.
 *
 ***********************************************************CommentEnd********/


Void
GetMBheader(Int vop_type,
	    UInt *new_vop,
	    Int intra_dcpred_disable,
            Int *quant_step,
            Bitstream * texture_bits,
            Int mbnum,
            Trace *trace,
            Image * motion_mode,
            Macroblock * mblock,
            Int * skipped_flag,
            Int * error_flag,
	    Int ***DC_store,
	    SInt *QP_store,
	    Int QP,
	    Int *coded,
	    UInt *CBP,
	    Int *ACpred_flag,
	    UInt *mode,
            Int *interlace_info,
            Int *MB_transp_pattern,
	    Vop *rec_vop)
{
    UInt CBPY, CBPC;
    Int  MBtype;
    SInt *decis_ptr;
    Int  m, n;
    Int  MCBPC;
    Int  DQUANT;
    UInt no_dct_flag;
    Int  DQ_tab[4] = {-1, -2, 1, 2};

    Int MCSEL;

    if(vop_type == INTRA_VOP)
	no_dct_flag = 0;
    else
	no_dct_flag = BitstreamReadBits (texture_bits, 1,"NO DCT FLAG", 
					 trace, FLAG);
   
    decis_ptr = (SInt *) GetImageData (motion_mode);

    if (no_dct_flag)
    {
	/* skipped macroblock */
	*skipped_flag = 1;
        *coded=0;
        *mode=MODE_INTER; 
	      /* Fill DC_store with default coeff values */
	for (m = 0; m < 6; m++) {
	    DC_store[mbnum][m][0] = GetVopMidGrey(rec_vop)*8;
	    for (n = 1; n < 15; n++)
		DC_store[mbnum][m][n] = 0;
	}
    }
    else
    {
	/* coded macroblock */
        *coded=1;
	*skipped_flag = 0;

	if (vop_type == INTRA_VOP)
	    MCBPC = VlcDecMCBPC_com_intra (texture_bits, error_flag, trace);
	else
	    MCBPC = VlcDecMCBPC_com_inter (texture_bits, error_flag, trace);

	if (*error_flag == RETURN)
	{
	    printf ("Error decoding MCBPC of macroblock %d\n", (int)mbnum);
	    return;
	}

	MBtype = MCBPC & 7;
	if ( MBtype == 0 ) *mode = MODE_INTER;
	if ( MBtype == 1 ) *mode = MODE_INTER_Q;
	if ( MBtype == 2 ) *mode = MODE_INTER4V;
	if ( MBtype == 3 ) *mode = MODE_INTRA;
	if ( MBtype == 4 ) *mode = MODE_INTRA_Q;
    
	/* MCSEL syntax */
	if (((*mode == MODE_INTER || *mode == MODE_INTER_Q)) && (vop_type == SPRITE_VOP))
	{
	    MCSEL = BitstreamReadBits(texture_bits, 1, "MCSEL",
					    trace, FLAG);

	    if (MCSEL) {
	      if (*mode == MODE_INTER)
		*mode = MODE_DYN_SP;
	      if (*mode == MODE_INTER_Q)
		*mode = MODE_DYN_SP_Q;
	    }
	}
       	CBPC = (MCBPC >> 4) & 3;
    
	if ((*mode == MODE_INTRA || *mode == MODE_INTRA_Q) && intra_dcpred_disable == 0)
	{
	    *ACpred_flag = BitstreamReadBits(texture_bits, 1, "ACpred_flag",
					    trace, FLAG);
	}

	CBPY = VlcDecCBPY (texture_bits,
                           (*mode == MODE_INTRA || *mode == MODE_INTRA_Q),
                            MB_transp_pattern, error_flag, trace);
	if (*error_flag == RETURN)
	{
	    printf ("Error decoding CBPY of macroblock %d\n", (int)mbnum);
	    return;
	}

	if (*mode == MODE_INTRA || *mode == MODE_INTRA_Q)
		{
	  	*(decis_ptr + mbnum) = MBM_INTRA; /* added 30-JAN-1997 MW */
	} else if (*mode==MODE_INTER4V) *(decis_ptr + mbnum) = MBM_INTER16;
      
    
    
	*CBP = CBPY << 2 | CBPC;

	if (*mode == MODE_INTER_Q || *mode == MODE_INTRA_Q|| *mode == MODE_DYN_SP_Q) {
	    DQUANT = BitstreamReadBits(texture_bits, 2, "DQUANT", trace, NUM);
	    *quant_step = *quant_step + DQ_tab[DQUANT];
           
	    if (trace->trace)
		fprintf (trace->fp_trace, "DQUANT = %d   QUANT = %d\n",
			 (int)DQ_tab[DQUANT], (int)*quant_step);
	    if (*quant_step > 31 || *quant_step < 1)
	    {
		if (trace->trace)
		    fprintf(trace->fp_trace,"Quantizer out of range %d:clipping\n"
			    , (int)*quant_step);
		*quant_step = mmax (1, mmin (31, (*quant_step)));
	    }
        }

        if (*interlace_info) {
            *interlace_info = 0;
            if ((*mode == MODE_INTRA) || (*mode == MODE_INTRA_Q) || (*CBP != 0))
                if (BitstreamReadBits(texture_bits, 1, "DCT_TYPE", trace, FLAG))
                    *interlace_info = 1;
            if ((*mode == MODE_INTER) || (*mode == MODE_INTER_Q)) {
                if (BitstreamReadBits(texture_bits, 1, "FIELD_PREDICTION",
				    trace, FLAG)) {
                    decis_ptr[mbnum] = MBM_FIELD00;
                    if (BitstreamReadBits(texture_bits, 1,
						"forward_top_field_reference", trace, FLAG))
                        decis_ptr[mbnum] += MBM_FIELD10 - MBM_FIELD00;
                    if (BitstreamReadBits(texture_bits, 1,
						"forward_bottom_field_reference", trace, FLAG))
                        decis_ptr[mbnum] += MBM_FIELD01 - MBM_FIELD00;
                }
            }
        }
 
	trace->trace = trace->MB_texture;
	if(trace->trace)
	    fprintf(trace->fp_trace, "----------\n");
      }
}


/***********************************************************CommentBegin******
 *
 * -- GetMBheaderErrRes --  
 *
 * Author :
 *       Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :
 *      1-May-97
 *
 * Purpose :
 *       decodes the MCBPC and Intra DC coeffs for an Intra MB in an I-VOP
 *       for the combined error resilient mode with data partitioning.
 *
 * Arguments in :
 *      Int vop_type,                   vop INTRA/INTER.
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int *quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Macroblock *mblock,             decoded macroblock.
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *      Int *coded,                     set if the MB contains coded texture
 *      UInt *CBP,                      Coded Block Pattern derived from MB header data
 *      Int *ACpred_flag                flag indicating the the use of AC prediction
 *      UInt *mode                      macroblock mode
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description : based on GetMBheader; 
 *               called by DecodeVopCombinedShapeTextureIntraErrRes.
 *
 *
 * See also :
 *
 *
 * Modified : 
 *          13.05.97 Minhua Zhou: added MB_transp_pattern
 *          15.05.97 Luis Ducla-Soares: cleaned up the code.
 *
 ***********************************************************CommentEnd********/

Void
GetMBheaderErrRes (Int intra_dcpred_disable,
		   Int *quant_step,
		   Bitstream * texture_bits,
		   Int mbnum,
		   Trace *trace,
		   Image * motion_mode,
		   Int * skipped_flag,
		   Int * error_flag,
		   Int *coded,
		   Int *CBP,
		   Int *mode,
		   Int *DC_coeff,
				Int *MB_transp_pattern,
		   Vop *rec_vop)
{
    UInt CBPC;
    Int  MBtype;
    SInt *decis_ptr;
    Int  k;
    Int  MCBPC;
    Int  DQUANT=0;
    Int  DQ_tab[4] = {-1, -2, 1, 2};
    Int  switched;
   
    decis_ptr = (SInt *) GetImageData (motion_mode);
    
    switched = IntraDCSwitch_Decision(*mode,
				      GetVopIntraDCVlcThr(rec_vop),
				      *quant_step);
    
    /* coded macroblock */
    *coded=1;
    *skipped_flag = 0;

    MCBPC = VlcDecMCBPC_com_intra (texture_bits, error_flag, trace);
	
    if (*error_flag == RETURN)
      {
	printf ("Error decoding MCBPC of macroblock %d\n", (int)mbnum);
	return;
      }

    MBtype = MCBPC & 7;
    if ( MBtype == 0 ) *mode = MODE_INTER;
    if ( MBtype == 1 ) *mode = MODE_INTER_Q;
    if ( MBtype == 2 ) *mode = MODE_INTER4V;
    if ( MBtype == 3 ) *mode = MODE_INTRA;
    if ( MBtype == 4 ) *mode = MODE_INTRA_Q;
    if ( MBtype == 5 ) *mode = MODE_DYN_SP;
    if ( MBtype == 6 ) *mode = MODE_DYN_SP_Q;
	
    
    
    CBPC = (MCBPC >> 4) & 3;
    
    *CBP = CBPC;
	
    if (*mode == MODE_INTER_Q || *mode == MODE_INTRA_Q|| *mode == MODE_DYN_SP_Q) {
      DQUANT = BitstreamReadBits(texture_bits, 2, "DQUANT", trace, NUM);
      *quant_step = *quant_step + DQ_tab[DQUANT];
      if (trace->trace)
	fprintf (trace->fp_trace, "DQUANT = %d   QUANT = %d\n",
		 (int)DQ_tab[DQUANT], (int)*quant_step);
      if (*quant_step > 31 || *quant_step < 1)
	{
	  if (trace->trace)
	    fprintf(trace->fp_trace,"Quantizer out of range %d:clipping\n"
		    , (int)*quant_step);
	  *quant_step = mmax (1, mmin (31, (*quant_step)));
	}
    }
    
  
    if (*mode == MODE_INTRA || *mode == MODE_INTRA_Q) 
      {
	for (k = 0; k < 6; k++)
		{
			if ((k>3) || (MB_transp_pattern[k]!=1))
				{
	    		if (switched==0)
	      		{
			   if (intra_dcpred_disable)   /* No INTRA DC prediction */
		  		{
		    		 DC_coeff[k] = BitstreamReadBits (texture_bits, 8, "DC coeff",
						     		   trace, NUM);
	    
		    		if (DC_coeff[k] == 128) 
					{
		      			printf ("Illegal DC coeff: 1000000\n");
		      			*error_flag = RETURN;
		      			return;
		    			}
		    
				if (DC_coeff[k] == 255) DC_coeff[k] = 128;
		    
		  		}
				else
		  		DC_coeff[k] = DecodePredictedIntraDC(k, texture_bits, 
								     trace, NUM);
	      		 }
		}
	  }
	
	*(decis_ptr + mbnum) = INTRA;
	
      }
        
    trace->trace = trace->MB_texture;
    if(trace->trace)
      fprintf(trace->fp_trace, "----------\n");
    
}
	
/***********************************************************CommentBegin******
 *
 * -- GetMBheaderNoDataPartIntraErrRes --  
 *
 * Author :
 *       Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :
 *      8-Sep-97
 *
 * Purpose :
 *       decodes the MCBPC and Intra DC coeffs for an Intra MB in an I-VOP
 *       for the combined error resilient mode with data partitioning.
 *
 * Arguments in :
 *      Int vop_type,                   vop INTRA/INTER.
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int *quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Macroblock *mblock,             decoded macroblock.
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *      Int *coded,                     set if the MB contains coded texture
 *      UInt *CBP,                      Coded Block Pattern derived from MB header data
 *      Int *ACpred_flag                flag indicating the the use of AC prediction
 *      UInt *mode                      macroblock mode
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description : based on GetMBheader; 
 *               called by DecodeVopCombinedShapeTextureIntraErrRes.
 *
 *
 * See also :
 *
 *
 * Modified : 
 *          13.05.97 Minhua Zhou: added MB_transp_pattern
 *          15.05.97 Luis Ducla-Soares: cleaned up the code.
 *
 ***********************************************************CommentEnd********/

Void
GetMBheaderNoDataPartIntraErrRes (Bitstream * texture_bits,
				  Int intra_dcpred_disable,
				  Int mbnum,
				  Trace *trace,
				  Image * motion_mode,
				  Int * skipped_flag,
				  Int * error_flag,
				  Int *coded,
				  Int *CBP,
				  Int *ACpred_flag,
				  Int *mode,
				  Int *MB_transp_pattern,
				  Vop *rec_vop)
{
    UInt CBPY;
    UInt CBPC;
    Int  MBtype;
    SInt *decis_ptr;
    Int  MCBPC;
   

    decis_ptr = (SInt *) GetImageData (motion_mode);


    /* coded macroblock */
    *coded=1;
    *skipped_flag = 0;

    MCBPC = VlcDecMCBPC_com_intra (texture_bits, error_flag, trace);
	
    if (*error_flag == RETURN)
      {
	printf ("Error decoding MCBPC of macroblock %d\n", (int)mbnum);
	return;
      }

    MBtype = MCBPC & 7;
    if ( MBtype == 0 ) *mode = MODE_INTER;
    if ( MBtype == 1 ) *mode = MODE_INTER_Q;
    if ( MBtype == 2 ) *mode = MODE_INTER4V;
    if ( MBtype == 3 ) *mode = MODE_INTRA;
    if ( MBtype == 4 ) *mode = MODE_INTRA_Q;
    if ( MBtype == 5 ) *mode = MODE_DYN_SP;
    if ( MBtype == 6 ) *mode = MODE_DYN_SP_Q;
	
    
    
    CBPC = (MCBPC >> 4) & 3;

    if((*mode == MODE_INTRA || *mode == MODE_INTRA_Q) && intra_dcpred_disable == 0)
      {
	*ACpred_flag = BitstreamReadBits(texture_bits, 1, "ACpred_flag",
					 trace, FLAG);
      }
    
    CBPY = VlcDecCBPY (texture_bits,
		       (*mode == MODE_INTRA || *mode == MODE_INTRA_Q),
		       MB_transp_pattern,error_flag, trace);

    if (*error_flag == RETURN)
      {
	printf ("Error decoding CBPY of macroblock %d\n", (int)mbnum);
	return;
      }

    if (*mode == MODE_INTRA || *mode == MODE_INTRA_Q)
      {
	*(decis_ptr + mbnum) = INTRA; /* added 30-JAN-1997 MW */
	/* CBPY = CBPY ^ 15; removed by Minhua Zhou 15-05-97 */
      }
    
    
    *CBP = CBPY << 2 | (CBPC);
	

    
    trace->trace = trace->MB_texture;
    if(trace->trace)
      fprintf(trace->fp_trace, "----------\n");
    
}

/***********************************************************CommentBegin******
 *
 * -- GetMBheaderNoDataPartInterErrRes --  
 *
 * Author :
 *      Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :
 *      8-Sep-97
 *
 * Purpose :
 *       decodes the COD and MCBPC of a MB in a P-VOP for combined error resilient mode
 *       with data partitioning.
 *
 * Arguments in :
 *      Int vop_type,                   vop INTRA/INTER.
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int *quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Macroblock *mblock,             decoded macroblock.
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *      Int *coded,                     set if the MB contains coded texture
 *      UInt *CBP,                      Coded Block Pattern derived from MB header data
 *      Int *ACpred_flag                flag indicating the the use of AC prediction
 *      UInt *mode                      macroblock mode
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description : the function GetMBheader() was used as a starting point;
 *               called by DecodeVopCombinedMotionShapeTextureInterErrRes().
 *
 *
 * See also :
 *
 *
 * Modified : 
 *           13.05.97 Minhua Zhou: added MB_transp_pattern
 *           15.05.97 Luis Ducla-Soares: cleaned up the code.
 *
 ***********************************************************CommentEnd********/

Void
GetMBheaderNoDataPartInterErrRes (Bitstream * texture_bits,
				  Int intra_dcpred_disable,
				  Int mbnum,
				  Trace *trace,
				  Int * skipped_flag,
				  Int * error_flag,
				  Int ***DC_store,
				  Int *coded,
				  Int *CBP,
				  Int *ACpred_flag,
				  Int *mode,
				  Int *MB_transp_pattern,
				  Vop *rec_vop)
{
    UInt CBPY;
    UInt CBPC;
    Int  MBtype;
    Int  MCBPC;
    UInt no_dct_flag;
    Int  m,n;


    no_dct_flag = BitstreamReadBits (texture_bits, 1,"NO DCT FLAG", 
					 trace, FLAG);

    if (no_dct_flag)
      {
	/* skipped macroblock */
	*skipped_flag = 1;
	*coded=0;
        *mode=MODE_INTER; 
	/* Fill DC_store with default coeff values */
	for (m = 0; m < 6; m++) {
	  DC_store[mbnum][m][0] = GetVopMidGrey(rec_vop)*8;
	  for (n = 1; n < 15; n++)
	    DC_store[mbnum][m][n] = 0;
	}
      }
    else
      {
	/* coded macroblock */
        *coded=1;
	*skipped_flag = 0;
	
	MCBPC = VlcDecMCBPC_com_inter (texture_bits, error_flag, trace);
	
	if (*error_flag == RETURN)
	  {
	    printf ("Error decoding MCBPC of macroblock %d\n", (int)mbnum);
	    return;
	  }
	
	MBtype = MCBPC & 7;
	if ( MBtype == 0 ) *mode = MODE_INTER;
	if ( MBtype == 1 ) *mode = MODE_INTER_Q;
	if ( MBtype == 2 ) *mode = MODE_INTER4V;
	if ( MBtype == 3 ) *mode = MODE_INTRA;
	if ( MBtype == 4 ) *mode = MODE_INTRA_Q;
	if ( MBtype == 5 ) *mode = MODE_DYN_SP;
	if ( MBtype == 6 ) *mode = MODE_DYN_SP_Q;
	
	    
	CBPC = (MCBPC >> 4) & 3;
    
	if ((*mode == MODE_INTRA || *mode == MODE_INTRA_Q) && intra_dcpred_disable == 0)
	  {
	    *ACpred_flag = BitstreamReadBits(texture_bits, 1, "ACpred_flag",
					     trace, FLAG);
	  }

	CBPY = VlcDecCBPY (texture_bits,
			   (*mode == MODE_INTRA || *mode == MODE_INTRA_Q),
			   MB_transp_pattern,error_flag, trace);

	if (*error_flag == RETURN)
	  {
	    printf ("Error decoding CBPY of macroblock %d\n", (int)mbnum);
	    return;
	  }
	
	
	*CBP = CBPY << 2 | (CBPC);
	
	trace->trace = trace->MB_texture;
	if(trace->trace)
	    fprintf(trace->fp_trace, "----------\n");
      }
}


/***********************************************************CommentBegin******
 *
 * -- GetMBheaderMotionErrRes --  
 *
 * Author :
 *      Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :
 *      1-May-97
 *
 * Purpose :
 *       decodes the COD and MCBPC of a MB in a P-VOP for combined error resilient mode
 *       with data partitioning.
 *
 * Arguments in :
 *      Int vop_type,                   vop INTRA/INTER.
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int *quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Macroblock *mblock,             decoded macroblock.
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *      Int *coded,                     set if the MB contains coded texture
 *      UInt *CBP,                      Coded Block Pattern derived from MB header data
 *      Int *ACpred_flag                flag indicating the the use of AC prediction
 *      UInt *mode                      macroblock mode
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description : the function GetMBheader() was used as a starting point;
 *               called by DecodeVopCombinedMotionShapeTextureInterErrRes().
 *
 *
 * See also :
 *
 *
 * Modified : 
 *           13.05.97 Minhua Zhou: added MB_transp_pattern
 *           15.05.97 Luis Ducla-Soares: cleaned up the code.
 *
 ***********************************************************CommentEnd********/

Void
GetMBheaderMotionErrRes (Bitstream * texture_bits,
			 Int mbnum,
			 Trace *trace,
			 Int * skipped_flag,
			 Int * error_flag,
			 Int ***DC_store,
			 Int *coded,
			 Int *CBP,
			 Int *mode,
			 Int *transp_pattern,
			 Vop *rec_vop)
{
    UInt CBPC;
    Int  MBtype;
    Int  MCBPC;
    UInt no_dct_flag=1;
    Int  m,n;

    	no_dct_flag = BitstreamReadBits (texture_bits, 1,"NO DCT FLAG", 
					 trace, FLAG);

    if (no_dct_flag)
      {
	/* skipped macroblock */
	*skipped_flag = 1;
	*mode=INTER; 
	/* Fill DC_store with default coeff values */
	for (m = 0; m < 6; m++) {
	  DC_store[mbnum][m][0] = GetVopMidGrey(rec_vop)*8;
	  for (n = 1; n < 15; n++)
	    DC_store[mbnum][m][n] = 0;
	}
      }
    else
      {
	/* coded macroblock */
        *coded=1;
	*skipped_flag = 0;
	
	MCBPC = VlcDecMCBPC_com_inter (texture_bits, error_flag, trace);
	
	if (*error_flag == RETURN)
	  {
	    printf ("Error decoding MCBPC of macroblock %d\n", (int)mbnum);
	    return;
	  }
	
	MBtype = MCBPC & 7;
	if ( MBtype == 0 ) *mode = MODE_INTER;
	if ( MBtype == 1 ) *mode = MODE_INTER_Q;
	if ( MBtype == 2 ) *mode = MODE_INTER4V;
	if ( MBtype == 3 ) *mode = MODE_INTRA;
	if ( MBtype == 4 ) *mode = MODE_INTRA_Q;
	if ( MBtype == 5 ) *mode = MODE_DYN_SP;
	if ( MBtype == 6 ) *mode = MODE_DYN_SP_Q;
	
	    
	CBPC = (MCBPC >> 4) & 3;
    
	*CBP =  CBPC;


	trace->trace = trace->MB_texture;
	if(trace->trace)
	    fprintf(trace->fp_trace, "----------\n");
    }
}

/***********************************************************CommentBegin******
 *
 * -- GetMBheaderTextErrRes --  
 *
 * Author :
 *      Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :
 *      28-April-97
 *
 * Purpose :
 *       decodes the CBPY and DQUANT of a MB in a P-VOP for combined error resilient
 *       mode with data partitioning.
 *
 * Arguments in :
 *      Int vop_type,                   vop INTRA/INTER.
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int *quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Macroblock *mblock,             decoded macroblock.
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *      Int *coded,                     set if the MB contains coded texture
 *      UInt *CBP,                      Coded Block Pattern derived from MB header data
 *      Int *ACpred_flag                flag indicating the the use of AC prediction
 *      UInt *mode                      macroblock mode
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description : based on GetMBheader;
 *               called by DecodeVopCombinedMotionShapeTextureInterErrRes()
 *               and DecodeVopCombinedShapeTextureIntraErrRes()
 *
 *
 * See also :
 *
 *
 * Modified : 
 *           13.05.97 Minhua Zhou: added MB_transp_pattern
 *           15.05.97 Luis Ducla-Soares: cleaned up the code.
 *
 ***********************************************************CommentEnd********/

Void
GetMBheaderTextErrRes (Int intra_dcpred_disable,
		       /*Int *quant_step,*/
		       Bitstream * texture_bits,
		       Int mbnum,
		       Trace *trace,
		       Image * motion_mode,
		       Int * error_flag,
		       Int *coded,
		       Int *CBP,
		       Int *ACpred_flag,
		       Int *mode,
                       Int *MB_transp_pattern,
		       Vop *rec_vop)
{
    UInt CBPY;
    SInt *decis_ptr;
    /* Int  DQUANT=0;
    Int  DQ_tab[4] = {-1, -2, 1, 2};*/


    decis_ptr = (SInt *) GetImageData (motion_mode);
    

    if ((*mode == MODE_INTRA || *mode == MODE_INTRA_Q) && intra_dcpred_disable == 0)
      {
	*ACpred_flag = BitstreamReadBits(texture_bits, 1, "ACpred_flag",
					 trace, FLAG);
      }
    
    CBPY = VlcDecCBPY (texture_bits, (*mode == MODE_INTRA || *mode == MODE_INTRA_Q),
		      MB_transp_pattern,error_flag, trace);
    if (*error_flag == RETURN)
      {
	printf ("Error decoding CBPY of macroblock %d\n", (int)mbnum);
	return;
      }
    
    if (*mode == MODE_INTRA || *mode == MODE_INTRA_Q)
      {
	*(decis_ptr + mbnum) = INTRA; /* added 30-JAN-1997 MW */
      }
    
    
    *CBP = CBPY << 2 | (*CBP);
    

    trace->trace = trace->MB_texture;
    if(trace->trace)
      fprintf(trace->fp_trace, "----------\n");

}

/***********************************************************CommentBegin******
 *
 * -- GetMBheaderTextInterErrRes --  
 *
 * Author :
 *      Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :
 *      09-Oct-97
 *
 * Purpose :
 *       decodes the CBPY and DQUANT of a MB in a P-VOP for combined error resilient
 *       mode with data partitioning.
 *
 * Arguments in :
 *      Int vop_type,                   vop INTRA/INTER.
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int *quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Macroblock *mblock,             decoded macroblock.
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *      Int *coded,                     set if the MB contains coded texture
 *      UInt *CBP,                      Coded Block Pattern derived from MB header data
 *      Int *ACpred_flag                flag indicating the the use of AC prediction
 *      UInt *mode                      macroblock mode
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description : based on GetMBheader;
 *               called by DecodeVopCombinedMotionShapeTextureInterErrRes()
 *               and DecodeVopCombinedShapeTextureIntraErrRes()
 *
 *
 * See also :
 *
 *
 * Modified : 
 *           13.05.97 Minhua Zhou: added MB_transp_pattern
 *           15.05.97 Luis Ducla-Soares: cleaned up the code.
 *					 19.11.97 Noel Brady: added support of shape
 *
 ***********************************************************CommentEnd********/

Void
GetMBheaderTextInterErrRes (Int intra_dcpred_disable,
			    Int *quant_step,
			    Bitstream * texture_bits,
			    Int mbnum,
			    Trace *trace,
			    Image * motion_mode,
			    Int * error_flag,
			    Int *coded,
			    Int *CBP,
			    Int *ACpred_flag,
			    Int *mode,
			    Int *MB_transp_pattern,
			    Int *DC_coeff,
			    Vop *rec_vop)
{
    UInt CBPY;
    SInt *decis_ptr;
    Int  DQUANT=0;
    Int  DQ_tab[4] = {-1, -2, 1, 2};
    Int  k;
    Int  switched;

    decis_ptr = (SInt *) GetImageData (motion_mode);

    switched = IntraDCSwitch_Decision(*mode,
				      GetVopIntraDCVlcThr(rec_vop),
				      *quant_step);


    if ((*mode == MODE_INTRA || *mode == MODE_INTRA_Q) && intra_dcpred_disable == 0)
      {
	*ACpred_flag = BitstreamReadBits(texture_bits, 1, "ACpred_flag",
					 trace, FLAG);
      }
    

    CBPY = VlcDecCBPY (texture_bits, (*mode == MODE_INTRA || *mode == MODE_INTRA_Q),
		       MB_transp_pattern,error_flag, trace);
    if (*error_flag == RETURN)
      {
	printf ("Error decoding CBPY of macroblock %d\n", (int)mbnum);
	return;
      }

    if (*mode == MODE_INTRA || *mode == MODE_INTRA_Q)
      {
	*(decis_ptr + mbnum) = INTRA; /* added 30-JAN-1997 MW */
     }
    
    
    *CBP = CBPY << 2 | (*CBP);
    if (*mode == MODE_INTER_Q || *mode == MODE_INTRA_Q|| *mode == MODE_DYN_SP_Q) {
      DQUANT = BitstreamReadBits(texture_bits, 2, "DQUANT", trace, NUM);
      *quant_step = *quant_step + DQ_tab[DQUANT];
      if (trace->trace)
	fprintf (trace->fp_trace, "DQUANT = %d   QUANT = %d\n",
		 (int)DQ_tab[DQUANT], (int)*quant_step);
      if (*quant_step > 31 || *quant_step < 1)
	{
	  if (trace->trace)
	    fprintf(trace->fp_trace,"Quantizer out of range %d:clipping\n"
		    , (int)*quant_step);
	  *quant_step = mmax (1, mmin (31, (*quant_step)));
	}
    }
  
    if (*mode == MODE_INTRA || *mode == MODE_INTRA_Q) 
      {
	for (k = 0; k < 6; k++)
	  {
			if (k>3 || MB_transp_pattern[k]!=1)
				{
	    if (switched==0)
	      {
		if (intra_dcpred_disable)  /* No INTRA DC prediction */
		  {
		    DC_coeff[k] = BitstreamReadBits (texture_bits, 8, "DC coeff",
						     trace, NUM);
		    
		    if (DC_coeff[k] == 128) {
		      printf ("Illegal DC coeff: 1000000\n");
		      *error_flag = RETURN;
		      return;
		    }
		    if (DC_coeff[k] == 255)
		      DC_coeff[k] = 128;
		  }
		else
		  DC_coeff[k] = DecodePredictedIntraDC(k, texture_bits, trace, NUM);
	      }
	    }
	  }
	    
	*(decis_ptr + mbnum) = INTRA;
	
      }
    
    
    trace->trace = trace->MB_texture;
    if(trace->trace)
      fprintf(trace->fp_trace, "----------\n");

}


/***********************************************************CommentBegin******
 *
 * -- GetMBvectors --  
 *
 * Author :
 *      Jan De Lameillieure (HHI) <jan@hhi.de>
 *
 * Created :
 *      19-Jan-97
 *
 * Purpose :
 *       decodes the vectors of a MB (for combined mode)
 *
 * Arguments in :
 *      Int vop_type,                   vop INTRA/INTER.
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int *quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *      Int *coded,                     set if the MB contains coded texture
 *      Int *ACpred_flag                flag indicating the the use of AC prediction
 *      UInt *mode                      macroblock mode
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description :
 *      Starting point for this function was the first part of GetMBmottext() of 
 *      the file text_decode_mb.c of 16-Jan-97
 *
 * See also :
 *
 *
 * Modified : 08.10.1997 Minhua Zhou: added vector padding 
 *    12.12.97 Bob Eifrig: decode field motion vectors
 *
 ***********************************************************CommentEnd********/

Void
GetMBvectors (Int vop_type,
	      Int intra_dcpred_disable,
	      Int *quant_step,
	      Bitstream * bits,
	      Int mbnum,
	      Int MB_width,
	      Int f_code,
	      Trace *trace,
	      Image * motion_mode,
	      Image * block_decis,
	      Image * mot_x,
	      Image * mot_y,
	      Int * skipped_flag,
	      Int * error_flag,
	      Int ***DC_store,
	      SInt *QP_store,
	      Int QP,
	      Int *coded,
	      Int *ACpred_flag,
	      UInt mode,
        Int arbitrary_shape)
{
  Int k;
  SInt *decis_ptr, *bdecis_ptr;
  Int  x_pos = mbnum % MB_width;
  Int  y_pos = mbnum / MB_width;
  Float               *motx_ptr, *moty_ptr, mvx=0, mvy=0;
  Int                 B_in_width = 2 * MB_width;

  decis_ptr = (SInt *) GetImageData (motion_mode);
  bdecis_ptr = (SInt *) GetImageData (block_decis);
  motx_ptr = (Float *) GetImageData (mot_x);
  moty_ptr = (Float *) GetImageData (mot_y);

	
  /* Decoding of motion vectors */

  if (mode == MODE_INTER || mode == MODE_INTER_Q || mode == MODE_INTER4V)
  {

      if (mode == MODE_INTER4V)
      {
	  for (k = 0; k < 4; k++)
	  {
	      if (!B_TRANSP (bdecis_ptr,B_in_width,x_pos,y_pos,k & 0x1,k >> 1,MBM_TRANSPARENT))
	      {
	      *(decis_ptr+mbnum) = FOURVEC;
/* MVP/Noel */
	      DecodeMBVec (mot_x, mot_y, motion_mode, block_decis, 
			  bits, trace, x_pos, y_pos, k + 1, f_code, 1, 
        error_flag, &mvx, &mvy, (Int **)NULL,arbitrary_shape);
    
	      if (*error_flag == RETURN)
		  return;
    
		  BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvx;
		  BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvy;
	      }
	      else
	      {
		  BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
		  BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
	      }
	      if (trace->trace)
	      {
		  fprintf (trace->fp_trace, "  >> mvx: %g\n", mvx);
		  fprintf (trace->fp_trace, "  >> mvy: %g\n", mvy);
	      }
	  }

/* VPT / Minhua */
         if (B_TRANSP(bdecis_ptr, B_in_width, x_pos, y_pos, 0, 0, MBM_TRANSPARENT)) {
              if (!B_TRANSP(bdecis_ptr, B_in_width, x_pos, y_pos, 1, 0, MBM_TRANSPARENT)) {
                      BV(motx_ptr, B_in_width, x_pos, y_pos, 0, 0) = BV(motx_ptr, B_in_width, x_pos, y_pos, 1, 0); 
                      BV(moty_ptr, B_in_width, x_pos, y_pos, 0, 0) = BV(moty_ptr, B_in_width, x_pos, y_pos, 1, 0); 
                } else {
                      BV(motx_ptr, B_in_width, x_pos, y_pos, 0, 0) = BV(motx_ptr, B_in_width, x_pos, y_pos, 0, 1); 
                      BV(moty_ptr, B_in_width, x_pos, y_pos, 0, 0) = BV(moty_ptr, B_in_width, x_pos, y_pos, 0, 1); 
                     }
             }
          if (B_TRANSP(bdecis_ptr, B_in_width, x_pos, y_pos, 1, 0, MBM_TRANSPARENT)) {
              if (!B_TRANSP(bdecis_ptr, B_in_width, x_pos, y_pos, 0, 0, MBM_TRANSPARENT)) {
                      BV(motx_ptr, B_in_width, x_pos, y_pos, 1, 0) = BV(motx_ptr, B_in_width, x_pos, y_pos, 0, 0); 
                      BV(moty_ptr, B_in_width, x_pos, y_pos, 1, 0) = BV(moty_ptr, B_in_width, x_pos, y_pos, 0, 0); 
                } else {
                      BV(motx_ptr, B_in_width, x_pos, y_pos, 1, 0) = BV(motx_ptr, B_in_width, x_pos, y_pos, 1, 1); 
                      BV(moty_ptr, B_in_width, x_pos, y_pos, 1, 0) = BV(moty_ptr, B_in_width, x_pos, y_pos, 1, 1); 
                     }
             }
         if (B_TRANSP(bdecis_ptr, B_in_width, x_pos, y_pos, 0, 1, MBM_TRANSPARENT)) {
              if (!B_TRANSP(bdecis_ptr, B_in_width, x_pos, y_pos, 1, 1, MBM_TRANSPARENT)) {
                      BV(motx_ptr, B_in_width, x_pos, y_pos, 0, 1) = BV(motx_ptr, B_in_width, x_pos, y_pos, 1, 1); 
                      BV(moty_ptr, B_in_width, x_pos, y_pos, 0, 1) = BV(moty_ptr, B_in_width, x_pos, y_pos, 1, 1); 
                } else {
                      BV(motx_ptr, B_in_width, x_pos, y_pos, 0, 1) = BV(motx_ptr, B_in_width, x_pos, y_pos, 0, 0); 
                      BV(moty_ptr, B_in_width, x_pos, y_pos, 0, 1) = BV(moty_ptr, B_in_width, x_pos, y_pos, 0, 0); 
                     }
             }
          if (B_TRANSP(bdecis_ptr, B_in_width, x_pos, y_pos, 1, 1, MBM_TRANSPARENT)) {
              if (!B_TRANSP(bdecis_ptr, B_in_width, x_pos, y_pos, 0, 1, MBM_TRANSPARENT)) {
                      BV(motx_ptr, B_in_width, x_pos, y_pos, 1, 1) = BV(motx_ptr, B_in_width, x_pos, y_pos, 0, 1); 
                      BV(moty_ptr, B_in_width, x_pos, y_pos, 1, 1) = BV(moty_ptr, B_in_width, x_pos, y_pos, 0, 1); 
                } else {
                      BV(motx_ptr, B_in_width, x_pos, y_pos, 1, 1) = BV(motx_ptr, B_in_width, x_pos, y_pos, 1, 0); 
                      BV(moty_ptr, B_in_width, x_pos, y_pos, 1, 1) = BV(moty_ptr, B_in_width, x_pos, y_pos, 1, 0); 
                     }
             }


      }
      else
      /* For PVOPs, field MC can occur in MODE_INTER and MODE_INTER_Q only */
      if ((decis_ptr[mbnum] >= MBM_FIELD00) && (decis_ptr[mbnum] <= MBM_FIELD11)) {
          DecodeMBVec(mot_x, mot_y, motion_mode, block_decis, bits, trace,
              x_pos, y_pos, 0, f_code, 1, error_flag, &mvx, &mvy,
              (Int **)NULL, arbitrary_shape);
          if (*error_flag == RETURN)
              return;
          if (trace->trace) {
              fprintf (trace->fp_trace, "  >> top field mvx: %g\n", mvx);
              fprintf (trace->fp_trace, "  >> top field mvy: %g\n", mvy);
          }
          BV (motx_ptr, B_in_width, x_pos, y_pos, 0, 0) = mvx;
          BV (moty_ptr, B_in_width, x_pos, y_pos, 0, 0) = mvy;
          BV (motx_ptr, B_in_width, x_pos, y_pos, 0, 1) = mvx;
          BV (moty_ptr, B_in_width, x_pos, y_pos, 0, 1) = mvy;
          
          DecodeMBVec(mot_x, mot_y, motion_mode, block_decis, bits, trace,
              x_pos, y_pos, 0, f_code, 1, error_flag, &mvx, &mvy,
              (Int **)NULL, arbitrary_shape);
          if (*error_flag == RETURN)
              return;
          if (trace->trace) {
              fprintf (trace->fp_trace, "  >> bottom field mvx: %g\n", mvx);
              fprintf (trace->fp_trace, "  >> bottom field mvy: %g\n", mvy);
          }
          BV (motx_ptr, B_in_width, x_pos, y_pos, 1, 0) = mvx;
          BV (moty_ptr, B_in_width, x_pos, y_pos, 1, 0) = mvy;
          BV (motx_ptr, B_in_width, x_pos, y_pos, 1, 1) = mvx;
          BV (moty_ptr, B_in_width, x_pos, y_pos, 1, 1) = mvy;
      } else {
/* MVP/Noel */
      DecodeMBVec (mot_x, mot_y, motion_mode, block_decis, 
			bits, trace, x_pos, y_pos, 
			0, f_code, 1, error_flag, &mvx, &mvy, (Int **)NULL, arbitrary_shape); 

	  if (*error_flag == RETURN)
	      return;
	  if (trace->trace)
	  {
	      fprintf (trace->fp_trace, "  >> mvx: %g\n", mvx);
	      fprintf (trace->fp_trace, "  >> mvy: %g\n", mvy);
	  }
	  for (k = 0; k < 4; k++)
	  {
	      BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvx;
	      BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvy;
	      *(decis_ptr + mbnum) = ONEVEC;
	  }
      }
  }
  else   /* INTRA Macroblock or Sprite Macroblock*/
  {
     if (mode == MODE_INTRA) 
     	{
	if (vop_type != INTRA)
		for (k = 0; k < 4; k++)
		{
			BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
			BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
			*(decis_ptr + mbnum) = INTRA;
		}
	}
	else
	if (mode == MODE_DYN_SP)
		{
		for (k = 0; k < 4; k++)
			{
			BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
			BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
			*(decis_ptr + mbnum) = MBM_SPRITE;
			}
		}

  }

  trace->trace = trace->MB_texture;
  if(trace->trace)
      fprintf(trace->fp_trace, "----------\n");
}

/***********************************************************CommentBegin******
 *
 * -- GetMBvectorsErrRes --  
 *
 * Author :
 *      Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :
 *      01.05.97
 *
 * Purpose :
 *       decodes the vectors of a MB for the combined error resilient mode
 *       with data partitioning.
 *
 * Arguments in :
 *      Int vop_type,                   vop INTRA/INTER.
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int *quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *      Int *coded,                     set if the MB contains coded texture
 *      Int *ACpred_flag                flag indicating the the use of AC prediction
 *      UInt *mode                      macroblock mode
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description : based on GetMBvectors();
 *               called by DecodeVopCombinedMotionShapeTextureInterErrRes().
 *     
 *
 * See also :
 *
 *
 * Modified : 
 *      15.05.97 Luis Ducla-Soares: cleaned up the code.
 *      10.12.97 Luis Ducla-Soares: removed 'after_marker' from the
 *                                  arguments list.
 *
 ***********************************************************CommentEnd********/

Void
GetMBvectorsErrRes (Int intra_dcpred_disable,
		    Bitstream * bits,
		    Int mbnum,
		    Int MB_width,
		    Int f_code,
		    Trace *trace,
		    Image * motion_mode,
		    Image * block_decis,
		    Image * mot_x,
		    Image * mot_y,
		    Int * error_flag,
		    UInt mode,
		    Int error_res_disable,
		    Int **slice_nb,
        Int arbitrary_shape)
{
  Int k;
  SInt *decis_ptr, *bdecis_ptr;
  Int  x_pos = mbnum % MB_width;
  Int  y_pos = mbnum / MB_width;
  Float               *motx_ptr, *moty_ptr, mvx=0, mvy=0;
  Int                 B_in_width = 2 * MB_width;

  decis_ptr = (SInt *) GetImageData (motion_mode);
  bdecis_ptr = (SInt *) GetImageData (block_decis);
  motx_ptr = (Float *) GetImageData (mot_x);
  moty_ptr = (Float *) GetImageData (mot_y);

	
  /* Decoding of motion vectors */

  if (mode == MODE_INTER || mode == MODE_INTER_Q || mode == MODE_INTER4V)
  {

      if (mode == MODE_INTER4V)
      {
	  for (k = 0; k < 4; k++)
	  {
	      if (!B_TRANSP (bdecis_ptr,B_in_width,x_pos,y_pos,k & 0x1,k >> 1,MBM_TRANSPARENT))
	      {
	      *(decis_ptr+mbnum) = FOURVEC;

 /* MVP/Noel */
         DecodeMBVec (mot_x, mot_y, motion_mode, block_decis, 
		      bits, trace, x_pos, y_pos, 
                      k + 1, f_code, error_res_disable, 
		      error_flag, &mvx, &mvy, slice_nb,arbitrary_shape); 

	      if (*error_flag == RETURN)
		  return;
    
		  BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvx;
		  BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvy;
	      }
	      else
	      {
		  BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
		  BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
	      }
	      if (trace->trace)
	      {
		  fprintf (trace->fp_trace, "  >> mvx: %g\n", mvx);
		  fprintf (trace->fp_trace, "  >> mvy: %g\n", mvy);
	      }
	  }
      }
      else
      {

        /* MVP/Noel */
         DecodeMBVec (mot_x, mot_y, motion_mode, block_decis, 
		      bits, trace, x_pos, y_pos, 
                      0, f_code, error_res_disable, 
		      error_flag, &mvx, &mvy, slice_nb, arbitrary_shape); 

	  if (*error_flag == RETURN)
	      return;

	  if (trace->trace)
	  {
	      fprintf (trace->fp_trace, "  >> mvx: %g\n", mvx);
	      fprintf (trace->fp_trace, "  >> mvy: %g\n", mvy);
	  }
	  for (k = 0; k < 4; k++)
	  {
	      BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvx;
	      BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvy;
	      *(decis_ptr + mbnum) = ONEVEC;
	  }
      }
  }


  trace->trace = trace->MB_texture;
  if(trace->trace)
      fprintf(trace->fp_trace, "----------\n");
}

/***********************************************************CommentBegin******
 *
 * -- GetMBvectorsNoDataPartErrRes --  
 *
 * Author :
 *      Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :
 *      10.09.97
 *
 * Purpose :
 *       decodes the vectors of a MB for the combined error resilient mode
 *       with data partitioning.
 *
 * Arguments in :
 *      Int vop_type,                   vop INTRA/INTER.
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int *quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *      Int *coded,                     set if the MB contains coded texture
 *      Int *ACpred_flag                flag indicating the the use of AC prediction
 *      UInt *mode                      macroblock mode
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description : based on GetMBvectors();
 *               called by DecodeVopCombinedMotionShapeTextureInterErrRes().
 *     
 *
 * See also :
 *
 *
 * Modified : 
 *      15.05.97 Luis Ducla-Soares: cleaned up the code.
 *      10.12.97 Luis Ducla-Soares: removed 'after_marker' from the
 *                                  arguments list.
 *
 ***********************************************************CommentEnd********/

Void
GetMBvectorsNoDataPartErrRes (Bitstream * bits,
			      Int mbnum,
			      Int MB_width,
			      Int f_code,
			      Trace *trace,
			      Image * motion_mode,
			      Image * block_decis,
			      Image * mot_x,
			      Image * mot_y,
			      Int * error_flag,
			      UInt mode,
			      Int *DC_coeff,
			      Int error_res_disable,
			      Int **slice_nb,
            Int arbitrary_shape)
{
  Int k;
  SInt *decis_ptr, *bdecis_ptr;
  Int  x_pos = mbnum % MB_width;
  Int  y_pos = mbnum / MB_width;
  Float               *motx_ptr, *moty_ptr, mvx=0, mvy=0;
  Int                 B_in_width = 2 * MB_width;

  decis_ptr = (SInt *) GetImageData (motion_mode);
  bdecis_ptr = (SInt *) GetImageData (block_decis);
  motx_ptr = (Float *) GetImageData (mot_x);
  moty_ptr = (Float *) GetImageData (mot_y);

	
  /* Decoding of motion vectors */

  if (mode == MODE_INTER || mode == MODE_INTER_Q || mode == MODE_INTER4V)
  {

      if (mode == MODE_INTER4V)
      {
	  for (k = 0; k < 4; k++)
	  {
	      if (!B_TRANSP (bdecis_ptr,B_in_width,x_pos,y_pos,k & 0x1,k >> 1,MBM_TRANSPARENT))
	      {
	      *(decis_ptr+mbnum) = FOURVEC;


         DecodeMBVec (mot_x, mot_y, motion_mode, block_decis, bits, trace, x_pos, y_pos, 
                      k + 1, f_code, error_res_disable,
		      error_flag, &mvx, &mvy, slice_nb, arbitrary_shape); 

	      if (*error_flag == RETURN)
		  return;
    
		  BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvx;
		  BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvy;
	      }
	      else
	      {
		  BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
		  BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
	      }
	      if (trace->trace)
	      {
		  fprintf (trace->fp_trace, "  >> mvx: %g\n", mvx);
		  fprintf (trace->fp_trace, "  >> mvy: %g\n", mvy);
	      }
	  }
      }
      else
      {
         DecodeMBVec (mot_x, mot_y, motion_mode, block_decis, bits, trace, x_pos, y_pos, 
                      0, f_code, error_res_disable,
		      error_flag, &mvx, &mvy, slice_nb, arbitrary_shape); 

	  if (*error_flag == RETURN)
	      return;

	  if (trace->trace)
	  {
	      fprintf (trace->fp_trace, "  >> mvx: %g\n", mvx);
	      fprintf (trace->fp_trace, "  >> mvy: %g\n", mvy);
	  }
	  for (k = 0; k < 4; k++)
	  {
	      BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvx;
	      BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = mvy;
	      *(decis_ptr + mbnum) = ONEVEC;
	  }
      }
  }
  else   /* INTRA Macroblock or Sprite Macroblock*/
  {
     if (mode == MODE_INTRA || mode == MODE_INTRA_Q) 
     	{

	for (k = 0; k < 4; k++)
	  {
	    BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
	    BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
	    *(decis_ptr + mbnum) = INTRA;
	  }
	}
     else
	if (mode == MODE_DYN_SP)
	  {
	    for (k = 0; k < 4; k++)
	      {
		BV (motx_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
		BV (moty_ptr, B_in_width, x_pos, y_pos, k & 0x1, k >> 1) = 0.0;
		*(decis_ptr + mbnum) = MBM_SPRITE;
	      }
	  }
     
  }

  
  trace->trace = trace->MB_texture;
  if(trace->trace)
      fprintf(trace->fp_trace, "----------\n");
}



/***********************************************************CommentBegin******
 *
 * -- GetMBblockdata --  
 *
 * Author :
 *      Jan De Lameillieure (HHI) <jan@hhi.de>
 *
 * Created :
 *      18-Jan-97
 *
 * Purpose :
 *       decodes the block data (DCT coefficientsm, alias "texture") of a MB (for combined mode)
 *
 * Arguments in :
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int MB_width,
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *	UInt CBP			Coded Block Pattern derived from MB header data
 *      UChar disable_sadct             Flag indicating whether SADCT is disabled or not
 *      Short *alpha                    The object plane with alpha values
 *      UChar shape                     Indicator of shape type of the video object being decoded
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Macroblock *mblock,             decoded macroblock.
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description :
 *      Starting point for this function was the second part of GetMBtext() of 
 *      the file text_decode_mb.c of 16-Jan-97
 *
 * See also :
 *
 *
 * Modified :
 *	28.01.97 Robert Danielsen: Changed zigzag-scanning.
 *	27.02.97 Robert Danielsen: Added parameter to signal luma or
 *			chroma to the nonlinear quantization.
 *  15-APR-97 Jan De Lameillieure : called BlockIDCT() instead of idctref()
 *  15-APR-97 Jan De Lameillieure : added the inverse SADCT
 *	22-APR-97 Michael Wollborn: changed name of BlockDequant to 
 *			BlockDequantH263 and changed
 *			stuff for MPEG-like quantization
 *  14-05-97 Minhua Zhou: disable SADCT for rectangular VOP
 *  11-08-97 Minhua Zhou: added clipping for MODE_INTRA_Q mode
 *  12.12.97 Bob Eifrig: Alternate scan and inverse field DCT permutation.
 *
 ***********************************************************CommentEnd********/
Void GetMBblockdata(Int transp_pattern[],
		    Int intra_dcpred_disable,
		    Int quant_step,
		    Bitstream * texture_bits,
		    Int mbnum,
		    Trace *trace,
		    Macroblock * mblock,
		    Int * skipped_flag,
		    Int * error_flag,
		    Int MB_width,
		    Int ***DC_store,
		    SInt *QP_store,
		    Int QP,
		    UInt CBP,
		    Int ACpred_flag,
		    UInt mode,
		    Short *alpha,
			Int field_dct,
		    Vop *rec_vop)
{
  Int  comp;
  Int  DCT_block[B_SIZE * B_SIZE];
  Int  q_block[B_SIZE * B_SIZE];
  Int  r_block[B_SIZE * B_SIZE];
  Int  r_block_2D[B_SIZE][B_SIZE];
  Int  pcoeff[B_SIZE * B_SIZE];
  UInt DC_coeff;
  Int  pred_DC_coeff;
  Int  x_pos = mbnum % MB_width;
  Int  y_pos = mbnum / MB_width;
  Int  m, n;
  Int  i, j;
  Char level_3_trace;
  Int switched;

  UChar disable_sadct = GetVopSADCTDisable(rec_vop);
  UChar shape         = GetVopShape(rec_vop);
  
  /* variables because of contour-adaptive DCT */
  Short alpha_block[B_SIZE][B_SIZE];
  Short nrpix = MB_width * MB_SIZE;
  Short tmp; 
  SInt mb_shape[6][64],mb_dct_bf_iq[6][64],mb_dct_iq[6][64],mb_idct[6][64]; 

    /*added by Minhua Zhou 04.08.97 */
          switched = IntraDCSwitch_Decision(mode,
                                                  GetVopIntraDCVlcThr(rec_vop),
                                                  QP);
          QP = quant_step;
    
  MBzero (mblock);
  level_3_trace = trace->MB_sdata||trace->MB_tdata_before_IQ|| 
                  trace->MB_tdata_after_IQ||trace->MB_tdata_after_IDCT||
                  trace->MB_tdata_reconstructed;
  if (level_3_trace)
    for (i=0;i<6;i++)
     for (j=0;j<64;j++) mb_shape[i][j]=0;  

  if (shape==0) disable_sadct = 1;

  

  /*****
   *
   *	  Decoding of the 4 luminance blocks (depending on transparent pattern)
   *
   *****/
  for (comp=0; comp<4; comp++)
  {
      Bzero (q_block);

      if(transp_pattern[comp]==0) /* No decoding of transparent Y blocks */
      	{
	  	if ((disable_sadct==0)||(level_3_trace)) {
	    switch(comp) {
	      case 0 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + j)];
		break;
	      case 1 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
		break;
	      case 2 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + j)];
		break;
	      case 3 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
		break;
	      case 4 :
	      case 5 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++) {
		    if (shape == GREY_SCALE) {
		      tmp = alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)];
		      tmp += alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		      tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)];
		      tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		      tmp += 2;
		      tmp /= 4;
		      alpha_block[i][j] = (tmp > BINARY_ALPHA/2) ? BINARY_ALPHA : 0;
		    }
		    else { /* so-called "conservative" subsampling (JDL - 20-MAR-97) */
		      alpha_block[i][j] = 
		       ((alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
			(alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA) ||
			(alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
			(alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA))
			  ? BINARY_ALPHA : 0 ; 
		    }
		  }
		break;
	      default :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = BINARY_ALPHA;
	    }
           if (trace->trace)
            for (i=0;i<8;i++)
              for (j=0;j<8;j++)
                mb_shape[comp][i*8+j]=alpha_block[i][j]; 
	  }

	  if (mode == MODE_INTRA || mode == MODE_INTRA_Q) {
           if (switched==0) {
	      if(intra_dcpred_disable)	/* No INTRA DC prediction */
	      {
		  DC_coeff = BitstreamReadBits (texture_bits, 8, "DC coeff",
						trace, NUM);
    
		  if (DC_coeff == 128) {
		      printf ("Illegal DC coeff: 1000000\n");
		      exit(1);
		  }
		  if (DC_coeff == 255)
		      DC_coeff = 128;

		  q_block[0] = DC_coeff;

	      }
	      else				/* INTRA DC prediction (I-MBs) */
	      {
		/* This must be Int not UInt MW 15-NOV-1996 */
		  pred_DC_coeff = DecodePredictedIntraDC(comp,
							 texture_bits,
							 trace, 
							 NUM);
		  q_block[0] = pred_DC_coeff;
	      }
          }


	      if (CBP & (1 << (BLOCK_CNT - 1 - comp))) {
		  VlcGetBlock(texture_bits, q_block, INTRA,
			      trace, error_flag, 1, GetVopReverseVlc(rec_vop),switched);
              }

	      /* Do the DC/AC prediction, changing the qcoeff values as
		 appropriate */
	      if (intra_dcpred_disable == 0)
		  doDCACrecon(q_block, 64, DC_store, QP_store, QP,
			      x_pos, y_pos, MB_width, ACpred_flag,
                  GetVopAlternateScan(rec_vop), comp,GetVopMidGrey(rec_vop));
	      else
	      {
          if (GetVopAlternateScan(rec_vop)) {
              for (m = 0; m < 64; m ++)
                  pcoeff[m] = q_block[zigzag_v[m]];
          } else
		  /* Ordinary inverse zigzag-scanning */
		  for (m = 0; m < 64; m++)
			  pcoeff[m] = q_block[zigzag[m]];

		  for (m = 0; m < 8; m++)
		      for (n = 0; n < 8; n++)
			  q_block[m*8+n] = pcoeff[m*8+n];
  
	      }
            if (trace->MB_tdata_before_IQ)
             for (i=0;i<64;i++)
                   mb_dct_bf_iq[comp][i]=q_block[i]; 

	      /* Store the qcoeff-values needed later for prediction */
	      for (m = 0; m < 8; m++) {
		  DC_store[mbnum][comp][m] = q_block[m];
	      }
	      for (m = 0; m < 7; m++) {
		  DC_store[mbnum][comp][m+8] = q_block[(m+1)*8];
	      }

	      /* MW 22-APR-1997 Changes for MPEG dequantization */
	      if(GetVopQuantType(rec_vop))
	        BlockDequantMPEG(q_block,quant_step,INTRA,1,
				 GetVopIntraQuantMat(rec_vop),DCT_block);
	      else
	        BlockDequantH263(q_block,quant_step,INTRA,1,DCT_block);

	      DC_store[mbnum][comp][0] = DCT_block[0];

             if (trace->MB_tdata_after_IQ)
              for (i=0;i<64;i++)
                 mb_dct_iq[comp][i]=DCT_block[i]; 
    
              if (disable_sadct)
		BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
#ifndef _WD_MODE_
	      else 
		  BlockSAIDCT (DCT_block, r_block_2D, alpha_block); 
#endif
	      for (m = 0; m < B_SIZE; m++)
		for (n = 0; n < B_SIZE; n++)
	          r_block[m*B_SIZE+n] = r_block_2D[m][n];

           if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
                 mb_idct[comp][i]=r_block[i]; 

	  }
	  else /* MODE INTER */
	  {
	      if (CBP & (1 << (BLOCK_CNT - 1 - comp))) {
		  VlcGetBlock (texture_bits, q_block, INTER, trace,
			       error_flag, 0, GetVopReverseVlc(rec_vop),switched);
	      }
	      
          if (GetVopAlternateScan(rec_vop)) {
              for (m = 0; m < 64; m ++)
                  pcoeff[m] = q_block[zigzag_v[m]];
          } else
	      /* Inverse zigzag-scanning also here 12-11-96 MW */
	      for (m = 0; m < 64; m++)
		  pcoeff[m] = q_block[zigzag[m]];

	      for (m = 0; m < 8; m++)
		for (n = 0; n < 8; n++)
		  q_block[m*8+n] = pcoeff[m*8+n];

           if (trace->MB_tdata_before_IQ)
             for (i=0;i<64;i++)
                   mb_dct_bf_iq[comp][i]=q_block[i]; 

	      /* Fill DC_store with default coeff values */
	      DC_store[mbnum][comp][0] = GetVopMidGrey(rec_vop)*8;
	      for (n = 1; n < 15; n++)
		  DC_store[mbnum][comp][n] = 0;

	      /* MW 22-APR-1997 Changes for MPEG dequantization */
	      if(GetVopQuantType(rec_vop))
	        BlockDequantMPEG(q_block,quant_step,INTER,1,
				 GetVopNonintraQuantMat(rec_vop),DCT_block);
	      else
	        BlockDequantH263(q_block,quant_step,INTER,1,DCT_block);
    
           
             if (trace->MB_tdata_after_IQ)
              for (i=0;i<64;i++)
                 mb_dct_iq[comp][i]=DCT_block[i]; 
         
    
	      if (disable_sadct)
		BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
#ifndef _WD_MODE_
	      else
		BlockSAIDCT_Kaup (DCT_block, r_block_2D, alpha_block);
#endif
	      for (m = 0; m < B_SIZE; m++)
		for (n = 0; n < B_SIZE; n++)
	          r_block[m*B_SIZE+n] = r_block_2D[m][n];
          if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
                 mb_idct[comp][i]=r_block[i]; 

  
	  }
      }
      else /* clear r_block if transparent block */
      {
	  Bzero(r_block);
	  /* Fill DC_store with default coeff values */
	  DC_store[mbnum][comp][0] = GetVopMidGrey(rec_vop)*8;
	  for (n = 1; n < 15; n++)
	      DC_store[mbnum][comp][n] = 0;
      }

      PutBlock (comp, r_block, mblock);
  }

   if (field_dct) {
       /* Convert luma from field DCT order to frame order */
       static Char inv_shuffle[] = {
            1,  0,  8,  1,  4,  8,  2,  4,  0,  2,  3,  0,  9,  3, 12,  9,  6, 12,
            0,  6,  5,  0, 10,  5,  0, 10,  7,  0, 11,  7, 13, 11, 14, 13,  0, 14
        };
        Int tmp[MB_SIZE];
 
        for (n = 0; n < sizeof inv_shuffle; n += 2)
            memcpy(inv_shuffle[n+1] ? &mblock->lum[inv_shuffle[n+1]][0] : &tmp[0],
                   inv_shuffle[n+0] ? &mblock->lum[inv_shuffle[n+0]][0] : &tmp[0],
                   MB_SIZE * sizeof(Int));
   }

  /*****
   *
   *	  Decoding of 2 chrominance blocks (not dep. on 
   *        transparent pattern)
   *
   *****/
  for (comp=4; comp<6; comp++)
  {
      Bzero (q_block);

      if ((disable_sadct==0)||(level_3_trace)) {
	switch(comp) {
	  case 0 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + j)];
	    break;
	  case 1 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
	    break;
	  case 2 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + j)];
	    break;
	  case 3 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
	    break;
	  case 4 :
	  case 5 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++) {
		if (shape == GREY_SCALE) {
		  tmp = alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)];
		  tmp += alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		  tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)];
		  tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		  tmp += 2;
		  tmp /= 4;
		  alpha_block[i][j] = (tmp > BINARY_ALPHA/2) ? BINARY_ALPHA : 0;
		}
		else { /* so-called "conservative" subsampling (JDL - 20-MAR-97) */
		  alpha_block[i][j] = 
		   ((alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
		    (alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA) ||
		    (alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
		    (alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA))
		      ? BINARY_ALPHA : 0 ; 
		}
	      }
	    break;
	  default :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = BINARY_ALPHA;
	}
     if (trace->trace)
           for (i=0;i<8;i++)
             for (j=0;j<8;j++)
                mb_shape[comp][i*8+j]=alpha_block[i][j];
      }
      

      if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
      {
        if (switched==0) {
	  if(intra_dcpred_disable)	/* No INTRA DC prediction */
	  {
	      DC_coeff = BitstreamReadBits (texture_bits, 8, "DC coeff",
					    trace, NUM);
    
	      if (DC_coeff == 128)
	      {
		  printf ("Illegal DC coeff: 1000000\n");
		  exit(1);
	      }
    
	      if (DC_coeff == 255)
		  DC_coeff = 128;
	  }
	  else		 /* INTRA DC prediction (I-MBs) */
	  {
	      DC_coeff = DecodePredictedIntraDC(comp,
						texture_bits,
						trace,
						NUM);
	  }	
	  q_block[0] = DC_coeff;
         } 
	  if (CBP & (1 << (BLOCK_CNT - 1 - comp)))
	      VlcGetBlock (texture_bits, q_block, INTRA, trace,
			   error_flag, 1, GetVopReverseVlc(rec_vop),switched);
  
	  /* Do the DC/AC prediction, changing the qcoeff values as
	     appropriate */
	  if (intra_dcpred_disable == 0)
	      doDCACrecon(q_block, 64, DC_store, QP_store, QP,
			  x_pos, y_pos, MB_width, ACpred_flag,
              GetVopAlternateScan(rec_vop), comp,GetVopMidGrey(rec_vop));
	  else
	  {
          if (GetVopAlternateScan(rec_vop)) {
              for (m = 0; m < 64; m ++)
                  pcoeff[m] = q_block[zigzag_v[m]];
          } else
	      /* Ordinary inverse zigzag-scanning */
	          for (m = 0; m < 64; m++)
		          pcoeff[m] = q_block[zigzag[m]];

	      for (m = 0; m < 8; m++)
		  for (n = 0; n < 8; n++)
		      q_block[m*8+n] = pcoeff[m*8+n];
	  }
         if (trace->MB_tdata_before_IQ)
             for (i=0;i<64;i++)
                   mb_dct_bf_iq[comp][i]=q_block[i];

	  /* Store the qcoeff-values needed later for prediction */
	  for (m = 0; m < 8; m++) {
	      DC_store[mbnum][comp][m] = q_block[m];
	  }
	  for (m = 0; m < 7; m++) {
	      DC_store[mbnum][comp][m+8] = q_block[(m+1)*8];
	  }

	  /* MW 22-APR-1997 Changes for MPEG dequantization */
	  if(GetVopQuantType(rec_vop))
	    BlockDequantMPEG(q_block,quant_step,INTRA,2,
			     GetVopIntraQuantMat(rec_vop),DCT_block);
	  else
	    BlockDequantH263(q_block,quant_step,INTRA,2,DCT_block);
   
         DC_store[mbnum][comp][0] = DCT_block[0];

          if (trace->MB_tdata_after_IQ)
              for (i=0;i<64;i++)
                 mb_dct_iq[comp][i]=DCT_block[i]; 
    
  
	  if (disable_sadct)
	    BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
#ifndef _WD_MODE_
	  else
            BlockSAIDCT (DCT_block, r_block_2D, alpha_block);
#endif
	  for (m = 0; m < B_SIZE; m++)
	    for (n = 0; n < B_SIZE; n++)
	      r_block[m*B_SIZE+n] = r_block_2D[m][n];
         if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
                 mb_idct[comp][i]=r_block[i]; 

      }
      else		/* MODE_INTER */
      {
	  if (CBP & (1 << (BLOCK_CNT - 1 - comp)))
	      VlcGetBlock (texture_bits, q_block, INTER, trace,
			   error_flag, 0, GetVopReverseVlc(rec_vop),switched);

      if (GetVopAlternateScan(rec_vop)) {
          for (m = 0; m < 64; m ++)
              pcoeff[m] = q_block[zigzag_v[m]];
      } else
	  /* Inverse zigzag-scanning also here 12-11-96 MW */
	      for (m = 0; m < 64; m++)
	          pcoeff[m] = q_block[zigzag[m]];

	  for (m = 0; m < 8; m++)
	      for (n = 0; n < 8; n++)
		  q_block[m*8+n] = pcoeff[m*8+n];

        if (trace->MB_tdata_before_IQ)
              for (i=0;i<64;i++)
                 mb_dct_bf_iq[comp][i]=q_block[i]; 

	  /* Fill DC_store with default coeff values */
	  DC_store[mbnum][comp][0] = GetVopMidGrey(rec_vop)*8;
	  for (n = 1; n < 15; n++)
	      DC_store[mbnum][comp][n] = 0;

	  /* MW 22-APR-1997 Changes for MPEG dequantization */
	  if(GetVopQuantType(rec_vop))
	    BlockDequantMPEG(q_block,quant_step,INTER,2,
			     GetVopNonintraQuantMat(rec_vop),DCT_block);
	  else
	    BlockDequantH263(q_block,quant_step,INTER,2,DCT_block);
 
       if (trace->MB_tdata_after_IQ)
              for (i=0;i<64;i++)
                 mb_dct_iq[comp][i]=DCT_block[i]; 
  
	  if (disable_sadct)
	    BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
#ifndef _WD_MODE_
	  else
	    BlockSAIDCT_Kaup (DCT_block, r_block_2D, alpha_block);
#endif 
	  for (m = 0; m < B_SIZE; m++)
	    for (n = 0; n < B_SIZE; n++)
	      r_block[m*B_SIZE+n] = r_block_2D[m][n];
       if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
                 mb_idct[comp][i]=r_block[i]; 
      }

      PutBlock (comp, r_block, mblock);
  }

  /*****
   *
   *	  Clip reconstructed intra MBs
   *
   *****/
  if ((mode == MODE_INTRA)||(mode == MODE_INTRA_Q))
      MB_clip (mblock, GetVopBrightWhite(rec_vop));
  
  if (trace->MB_sdata) 
      PrintOutMBData("MB_shape_data",mb_shape,mb_shape,trace->fp_trace);
    if (trace->MB_tdata_before_IQ)
      PrintOutMBData("MB_tdata_before_IQ",mb_shape,mb_dct_bf_iq,trace->fp_trace); 
    if (trace->MB_tdata_after_IQ)
      PrintOutMBData("MB_tdata_after_IQ",mb_shape,mb_dct_iq,trace->fp_trace);
    if (trace->MB_tdata_after_IDCT)
      PrintOutMBData("MB_tdata_after_IDCT",mb_shape,mb_idct,trace->fp_trace);
   if ((mode == MODE_INTRA)&&(trace->MB_tdata_reconstructed)) {
      for (i=0;i<6;i++)
       for (j=0;j<64;j++)
        if (mb_idct[i][j]<0) mb_idct[i][j]=0;
         else if (mb_idct[i][j]>255) mb_idct[i][j]=255;

      PrintOutMBData("MB_tdata_reconstructed",mb_shape,mb_idct,trace->fp_trace);
   }


}                               /* GetMBblockdata */

/***********************************************************CommentBegin******
 *
 * -- GetMBblockdataErrRes --  
 *
 * Author :
 *      Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :
 *      01.05.97
 *
 * Purpose :
 *       decodes the block data (DCT coefficients, alias "texture") of a MB
 *       for the combined error resilient mode with data partitioning.
 *
 * Arguments in :
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int MB_width,
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *	UInt CBP			Coded Block Pattern derived from MB header data
 *      UChar disable_sadct             Flag indicating whether SADCT is disabled or not
 *      Short *alpha                    The object plane with alpha values
 *      UChar shape                     Indicator of shape type of the video object being decoded
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Macroblock *mblock,             decoded macroblock.
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description :
 *        This function was based on GetMBblockdata().
 *
 * See also :
 *
 *
 * Modified :
 *       14-05-97 Minhua Zhou: disable SADCT for rectangular VOP
 *       15.05.97 Luis Ducla-Soares: cleaned up the code.
 *				19.11.97 Noel Brady: Added traces for shape
 *
 ***********************************************************CommentEnd********/

Void GetMBblockdataErrRes(Int *transp_pattern,
				Int intra_dcpred_disable,
			  Int quant_step,
			  Bitstream * texture_bits,
			  Int mbnum,
			  Trace *trace,
			  Macroblock * mblock,
			  Int * error_flag,
			  Int MB_width,
			  Int ***DC_store,
			  SInt *QP_store,
			  Int QP,
			  UInt CBP,
			  Int ACpred_flag,
			  UInt mode,
			  Int *DC_coeff,
			  Vop *rec_vop,
			  Int **slice_nb)
{
  Int  comp;
  Int  DCT_block[B_SIZE * B_SIZE];
  Int  q_block[B_SIZE * B_SIZE];
  Int  r_block[B_SIZE * B_SIZE];
  Int  r_block_2D[B_SIZE][B_SIZE];
  Int  pcoeff[B_SIZE * B_SIZE];
  Int  m, n;
  Int  i,j;
  Int  x_pos = mbnum % MB_width;
  Int  y_pos = mbnum / MB_width;
  Int switched;

  UChar disable_sadct = 1;  /* Noel/E14 */
  UChar shape         = GetVopShape(rec_vop);
  
	SInt *alpha = (SInt *) GetImageData(GetVopA(rec_vop));

  /* variables because of contour-adaptive DCT */
  Short alpha_block[B_SIZE][B_SIZE];
  Short nrpix = MB_width * MB_SIZE;
  Short tmp; 

  Char level_3_trace;
  SInt mb_shape[6][64],mb_dct_bf_iq[6][64],mb_dct_iq[6][64],mb_idct[6][64]; 

  MBzero (mblock);
  level_3_trace = trace->MB_sdata||trace->MB_tdata_before_IQ|| 
                  trace->MB_tdata_after_IQ||trace->MB_tdata_after_IDCT||
                  trace->MB_tdata_reconstructed;
  if (level_3_trace)
    for (i=0;i<6;i++)
     for (j=0;j<64;j++) mb_shape[i][j]=0;
   /*added by Minhua Zhou 04.08.97 */
          switched = IntraDCSwitch_Decision(mode,
                                            GetVopIntraDCVlcThr(rec_vop),
                                            quant_step);



  /*****
   *
   *	  Decoding of the 4 luminance blocks (depending on transparent pattern)
   *
   *****/
  for (comp=0; comp<4; comp++)
  {
    Bzero (q_block);

      if(transp_pattern[comp]==0) /* No decoding of transparent Y blocks */
      	{
    
	  	if ((disable_sadct==0)||(level_3_trace)) {		
	    switch(comp) {
	      case 0 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + j)];
		break;
	      case 1 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
		break;
	      case 2 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + j)];
		break;
	      case 3 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
		break;
	      case 4 :
	      case 5 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++) {
		    if (shape == GREY_SCALE) {
		      tmp = alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)];
		      tmp += alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		      tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)];
		      tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		      tmp += 2;
		      tmp /= 4;
		      alpha_block[i][j] = (tmp > BINARY_ALPHA/2) ? BINARY_ALPHA : 0;
		    }
		    else { /* so-called "conservative" subsampling (JDL - 20-MAR-97) */
		      alpha_block[i][j] = 
		       ((alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
			(alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA) ||
			(alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
			(alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA))
			  ? BINARY_ALPHA : 0 ; 
		    }
		  }
		break;
	      default :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = BINARY_ALPHA;
	    }
           if (trace->trace)
            for (i=0;i<8;i++)
              for (j=0;j<8;j++)
                mb_shape[comp][i*8+j]=alpha_block[i][j]; 
	  }

    if (mode == MODE_INTRA || mode == MODE_INTRA_Q) {
      
      q_block[0] = DC_coeff[comp];
      
      if (CBP & (1 << (BLOCK_CNT - 1 - comp))) {
	VlcGetBlock(texture_bits, q_block, INTRA,
		    trace, error_flag, 1, GetVopReverseVlc(rec_vop),switched);
      }
      
      if (*error_flag == RETURN)
	return;
      
        
      if (intra_dcpred_disable == 0)
	doDCACreconErrRes(q_block, 64, DC_store, QP_store, QP,
			  x_pos, y_pos, MB_width, ACpred_flag, comp, slice_nb,GetVopMidGrey(rec_vop));
      else
	{
	  /* Ordinary inverse zigzag-scanning */
	  for (m = 0; m < 64; m++)
	    pcoeff[m] = q_block[zigzag[m]];
	  for (m = 0; m < 8; m++)
	    for (n = 0; n < 8; n++)
	      q_block[m*8+n] = pcoeff[m*8+n];
	}
      
      if (trace->MB_tdata_before_IQ)
	for (i=0;i<64;i++)
	  mb_dct_bf_iq[comp][i]=q_block[i]; 
      
      /* Store the qcoeff-values needed later for prediction */
      for (m = 0; m < 8; m++) {
	DC_store[mbnum][comp][m] = q_block[m];
      }
      for (m = 0; m < 7; m++) {
	DC_store[mbnum][comp][m+8] = q_block[(m+1)*8];
      }
      

      /* MW 22-APR-1997 Changes for MPEG dequantization */
      if(GetVopQuantType(rec_vop))
	BlockDequantMPEG(q_block,quant_step,INTRA,1,
			 GetVopIntraQuantMat(rec_vop),DCT_block);
      else
	BlockDequantH263(q_block,quant_step,INTRA,1,DCT_block);
      
      DC_store[mbnum][comp][0] = DCT_block[0];
      
      if (trace->MB_tdata_after_IQ)
	for (i=0;i<64;i++)
	  mb_dct_iq[comp][i]=DCT_block[i]; 
    

      
      BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
      
      for (m = 0; m < B_SIZE; m++)
	for (n = 0; n < B_SIZE; n++)
	  r_block[m*B_SIZE+n] = r_block_2D[m][n];
           
       if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
                 mb_idct[comp][i]=r_block[i]; 


    }
    else /* MODE INTER */
      {
	if (CBP & (1 << (BLOCK_CNT - 1 - comp))) {
	  VlcGetBlock (texture_bits, q_block, INTER, trace,
		       error_flag, 0, GetVopReverseVlc(rec_vop),switched);
	}
	
	if (*error_flag == RETURN)
	  return;
	
	/* Inverse zigzag-scanning also here 12-11-96 MW */
	for (m = 0; m < 64; m++)
	  pcoeff[m] = q_block[zigzag[m]];
	
	for (m = 0; m < 8; m++)
	  for (n = 0; n < 8; n++)
	    q_block[m*8+n] = pcoeff[m*8+n];
       if (trace->MB_tdata_before_IQ)
             for (i=0;i<64;i++)
                   mb_dct_bf_iq[comp][i]=q_block[i]; 

       /* Fill DC_store with default coeff values */
       DC_store[mbnum][comp][0] = GetVopMidGrey(rec_vop)*8;
       for (n = 1; n < 15; n++)
	 DC_store[mbnum][comp][n] = 0;
       
	
	/* MW 22-APR-1997 Changes for MPEG dequantization */
	if(GetVopQuantType(rec_vop))
	  BlockDequantMPEG(q_block,quant_step,INTER,1,
			   GetVopNonintraQuantMat(rec_vop),DCT_block);
	else
	  BlockDequantH263(q_block,quant_step,INTER,1,DCT_block);
	

       if (trace->MB_tdata_after_IQ)
              for (i=0;i<64;i++)
                 mb_dct_iq[comp][i]=DCT_block[i]; 
 	
	BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
	
	for (m = 0; m < B_SIZE; m++)
	  for (n = 0; n < B_SIZE; n++)
	    r_block[m*B_SIZE+n] = r_block_2D[m][n];
        
         if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
                 mb_idct[comp][i]=r_block[i]; 


      }
	}
	else
		{
			Bzero(r_block);
      DC_store[mbnum][comp][0] = GetVopMidGrey(rec_vop)*8;
      for (n = 1; n < 15; n++)
      	DC_store[mbnum][comp][n] = 0;
	
		}
    PutBlock (comp, r_block, mblock);
  }

  /*****
   *
   *	  Decoding of 2 chrominance blocks (not dep. on 
   *        transparent pattern)
   *
   *****/
  for (comp=4; comp<6; comp++)
  {
      Bzero (q_block);

      if ((disable_sadct==0)||(level_3_trace)) { /* Noel/E14 */
	switch(comp) {
	  case 0 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + j)];
	    break;
	  case 1 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
	    break;
	  case 2 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + j)];
	    break;
	  case 3 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
	    break;
	  case 4 :
	  case 5 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++) {
		if (shape == GREY_SCALE) {
		  tmp = alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)];
		  tmp += alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		  tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)];
		  tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		  tmp += 2;
		  tmp /= 4;
		  alpha_block[i][j] = (tmp > BINARY_ALPHA/2) ? BINARY_ALPHA : 0;
		}
		else { /* so-called "conservative" subsampling (JDL - 20-MAR-97) */
		  alpha_block[i][j] = 
		   ((alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
		    (alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA) ||
		    (alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
		    (alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA))
		      ? BINARY_ALPHA : 0 ; 
		}
	      }
	    break;
	  default :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = BINARY_ALPHA;
	}
     if (trace->trace)
           for (i=0;i<8;i++)
             for (j=0;j<8;j++)
                mb_shape[comp][i*8+j]=alpha_block[i][j];
      }
      if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
	{
	  q_block[0] = DC_coeff[comp];
	      
	  
	  if (CBP & (1 << (BLOCK_CNT - 1 - comp)))
	    VlcGetBlock (texture_bits, q_block, INTRA, trace,
			 error_flag, 1, GetVopReverseVlc(rec_vop),switched);
	 
	  if (*error_flag == RETURN)
	    return;
	  

	  /* Do the DC/AC prediction, changing the qcoeff values as
	     appropriate */
	  if (intra_dcpred_disable == 0)
	    doDCACreconErrRes(q_block, 64, DC_store, QP_store, QP,
			      x_pos, y_pos, MB_width, ACpred_flag, comp, slice_nb,GetVopMidGrey(rec_vop));
	  else
	    {
	      /* Ordinary inverse zigzag-scanning */
	      for (m = 0; m < 64; m++)
		pcoeff[m] = q_block[zigzag[m]];
	      for (m = 0; m < 8; m++)
		for (n = 0; n < 8; n++)
		  q_block[m*8+n] = pcoeff[m*8+n];
	    }
	  
	  if (trace->MB_tdata_before_IQ)
	    for (i=0;i<64;i++)
	      mb_dct_bf_iq[comp][i]=q_block[i];

	  /* Store the qcoeff-values needed later for prediction */
	  for (m = 0; m < 8; m++) {
	    DC_store[mbnum][comp][m] = q_block[m];
	  }
	  for (m = 0; m < 7; m++) {
	    DC_store[mbnum][comp][m+8] = q_block[(m+1)*8];
	  }
	
	  /* MW 22-APR-1997 Changes for MPEG dequantization */
	  if(GetVopQuantType(rec_vop))
	    BlockDequantMPEG(q_block,quant_step,INTRA,2,
			     GetVopIntraQuantMat(rec_vop),DCT_block);
	  else
	    BlockDequantH263(q_block,quant_step,INTRA,2,DCT_block);
   
	  DC_store[mbnum][comp][0] = DCT_block[0];
	 
	  if (trace->MB_tdata_after_IQ)
	    for (i=0;i<64;i++)
	      mb_dct_iq[comp][i]=DCT_block[i]; 
	  
	  
	  BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
	  
	  for (m = 0; m < B_SIZE; m++)
	    for (n = 0; n < B_SIZE; n++)
	      r_block[m*B_SIZE+n] = r_block_2D[m][n];
       if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
                 mb_idct[comp][i]=r_block[i]; 


	}
      else		/* MODE_INTER */
	{
	  if (CBP & (1 << (BLOCK_CNT - 1 - comp)))
	    VlcGetBlock (texture_bits, q_block, INTER, trace,
			 error_flag, 0, GetVopReverseVlc(rec_vop),switched);
	  
	  if (*error_flag == RETURN)
	    return;

	  
	  /* Inverse zigzag-scanning also here 12-11-96 MW */
	  for (m = 0; m < 64; m++)
	    pcoeff[m] = q_block[zigzag[m]];
	  
	  for (m = 0; m < 8; m++)
	    for (n = 0; n < 8; n++)
	      q_block[m*8+n] = pcoeff[m*8+n];
       if (trace->MB_tdata_before_IQ)
              for (i=0;i<64;i++)
                 mb_dct_bf_iq[comp][i]=q_block[i]; 

       /* Fill DC_store with default coeff values */
       DC_store[mbnum][comp][0] = GetVopMidGrey(rec_vop)*8;
       for (n = 1; n < 15; n++)
	 DC_store[mbnum][comp][n] = 0;
     
	  
	  /* MW 22-APR-1997 Changes for MPEG dequantization */
	  if(GetVopQuantType(rec_vop))
	    BlockDequantMPEG(q_block,quant_step,INTER,2,
			     GetVopNonintraQuantMat(rec_vop),DCT_block);
	  else
	    BlockDequantH263(q_block,quant_step,INTER,2,DCT_block);
 
       if (trace->MB_tdata_after_IQ)
              for (i=0;i<64;i++)
                 mb_dct_iq[comp][i]=DCT_block[i]; 
 
  
	  BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
	  
	  for (m = 0; m < B_SIZE; m++)
	    for (n = 0; n < B_SIZE; n++)
	      r_block[m*B_SIZE+n] = r_block_2D[m][n];
       if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
                 mb_idct[comp][i]=r_block[i];

	}

      PutBlock (comp, r_block, mblock);
  }

  /*****
   *
   *	  Clip reconstructed intra MBs
   *
   *****/
  if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
    MB_clip (mblock, GetVopBrightWhite(rec_vop));

 if (trace->MB_sdata) 
      PrintOutMBData("MB_shape_data",mb_shape,mb_shape,trace->fp_trace);
    if (trace->MB_tdata_before_IQ)
      PrintOutMBData("MB_tdata_before_IQ",mb_shape,mb_dct_bf_iq,trace->fp_trace); 
    if (trace->MB_tdata_after_IQ)
      PrintOutMBData("MB_tdata_after_IQ",mb_shape,mb_dct_iq,trace->fp_trace);
    if (trace->MB_tdata_after_IDCT)
      PrintOutMBData("MB_tdata_after_IDCT",mb_shape,mb_idct,trace->fp_trace);
   if ((mode == MODE_INTRA)&&(trace->MB_tdata_reconstructed)) {
      for (i=0;i<6;i++)
       for (j=0;j<64;j++)
        if (mb_idct[i][j]<0) mb_idct[i][j]=0;
         else if (mb_idct[i][j]>255) mb_idct[i][j]=255;

      PrintOutMBData("MB_tdata_reconstructed",mb_shape,mb_idct,trace->fp_trace);
   }

}                               /* GetMBblockdataErrRes */


/***********************************************************CommentBegin******
 *
 * -- GetMBblockdataNoDataPartErrRes --  
 *
 * Author :
 *      Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :
 *      08.09.97
 *
 * Purpose :
 *       decodes the block data (DCT coefficients, alias "texture") of a MB
 *       for the combined error resilient mode with data partitioning.
 *
 * Arguments in :
 *	Int intra_dcpred_disable	enable/disable pred. of INTRA DC
 *      Int quant_step,                 vop quantizer step (used for all MBs).
 *      Bitstream * texture_bits,       Image made of texture parameters.
 *      Int mbnum,                      macroblock number.
 *      Int trace,                      flag for tracing the process.
 *      Int *motion_mode,               already filled by MotionDecode.
 *	Int MB_width,
 *	Int DC_store[][6][15],		Stores DCAC prediction values
 *	SInt *QP_store,			Stores QPs for every MB
 *	Int QP				Current QPn
 *	UInt CBP			Coded Block Pattern derived from MB header data
 *      UChar disable_sadct             Flag indicating whether SADCT is disabled or not
 *      Short *alpha                    The object plane with alpha values
 *      UChar shape                     Indicator of shape type of the video object being decoded
 *
 * Arguments in/out :
 *
 *
 * Arguments out :
 *      Macroblock *mblock,             decoded macroblock.
 *      Int *skipped_flag,              1 = macroblock is skipped.
 *      Int *error_flag,                set if an error occured.
 *
 *
 * Return values :
 *
 *
 * Side effects :
 *
 *
 * Description :
 *        This function was based on GetMBblockdata().
 *
 * See also :
 *
 *
 * Modified :
 *       14-05-97 Minhua Zhou: disable SADCT for rectangular VOP
 *       15.05.97 Luis Ducla-Soares: cleaned up the code.
 *			 19.11.97 Noel Brady: Added trace stuff for shape
 ***********************************************************CommentEnd********/

Void GetMBblockdataNoDataPartErrRes(Int *transp_pattern,
						Int intra_dcpred_disable,
				    Int quant_step,
				    Bitstream * texture_bits,
				    Int mbnum,
				    Trace *trace,
				    Macroblock * mblock,
				    Int * error_flag,
				    Int MB_width,
				    Int ***DC_store,
				    SInt *QP_store,
				    Int QP,
				    UInt CBP,
				    Int ACpred_flag,
				    UInt mode,
				    Vop *rec_vop,
				    Int **slice_nb)
{
  Int  comp;
  Int  DCT_block[B_SIZE * B_SIZE];
  Int  q_block[B_SIZE * B_SIZE];
  Int  r_block[B_SIZE * B_SIZE];
  Int  r_block_2D[B_SIZE][B_SIZE];
  Int  pcoeff[B_SIZE * B_SIZE];
  UInt DC_coeff;
  Int  m, n;
  Int  i,j;
  Int  x_pos = mbnum % MB_width;
  Int  y_pos = mbnum / MB_width;
  Int  switched;

  UChar disable_sadct = 1;  /* Noel/E14 */
  UChar shape         = GetVopShape(rec_vop);
  
	SInt *alpha = (SInt *) GetImageData(GetVopA(rec_vop));

  /* variables because of contour-adaptive DCT */
  Short alpha_block[B_SIZE][B_SIZE];
  Short nrpix = MB_width * MB_SIZE;
  Short tmp; 

  Char level_3_trace;
  SInt mb_shape[6][64],mb_dct_bf_iq[6][64],mb_dct_iq[6][64],mb_idct[6][64]; 

  MBzero (mblock);
  level_3_trace = trace->MB_sdata||trace->MB_tdata_before_IQ|| 
                  trace->MB_tdata_after_IQ||trace->MB_tdata_after_IDCT||
                  trace->MB_tdata_reconstructed;
  if (level_3_trace)
    for (i=0;i<6;i++)
     for (j=0;j<64;j++) mb_shape[i][j]=0;
  /*added by Minhua Zhou 04.08.97 */
         switched = IntraDCSwitch_Decision(mode,
					   GetVopIntraDCVlcThr(rec_vop),
					   quant_step);



  /*****
   *
   *	  Decoding of the 4 luminance blocks (depending on transparent pattern)
   *
   *****/
  for (comp=0; comp<4; comp++)
  {
    Bzero (q_block);
    
      if(transp_pattern[comp]==0) /* No decoding of transparent Y blocks */
      	{
	  	if ((disable_sadct==0)||(level_3_trace)) {		
	    switch(comp) {
	      case 0 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + j)];
		break;
	      case 1 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
		break;
	      case 2 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + j)];
		break;
	      case 3 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
		break;
	      case 4 :
	      case 5 :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++) {
		    if (shape == GREY_SCALE) {
		      tmp = alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)];
		      tmp += alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		      tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)];
		      tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		      tmp += 2;
		      tmp /= 4;
		      alpha_block[i][j] = (tmp > BINARY_ALPHA/2) ? BINARY_ALPHA : 0;
		    }
		    else { /* so-called "conservative" subsampling (JDL - 20-MAR-97) */
		      alpha_block[i][j] = 
		       ((alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
			(alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA) ||
			(alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
			(alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA))
			  ? BINARY_ALPHA : 0 ; 
		    }
		  }
		break;
	      default :
		for (i=0; i<B_SIZE; i++)
		  for (j=0; j<B_SIZE; j++)
		    alpha_block[i][j] = BINARY_ALPHA;
	    }
           if (trace->trace)
            for (i=0;i<8;i++)
              for (j=0;j<8;j++)
                mb_shape[comp][i*8+j]=alpha_block[i][j]; 
	  }

    if (mode == MODE_INTRA || mode == MODE_INTRA_Q) {
      if (switched==0) {
	if (intra_dcpred_disable) /* No INTRA DC prediction */
	  {
	    DC_coeff = BitstreamReadBits(texture_bits, 8, "DC coeff", trace, NUM);
	    
	    if (DC_coeff == 128){
	      printf("Illegal DC coeff: 1000000\n");
	      exit(1);
	    }
	    if (DC_coeff == 255)
	      DC_coeff = 128;
	    
	    q_block[0] = DC_coeff;
	  }
	else   /* INTRA DC prediction (I-MBs) */
	  {
	    /* This must be Int not UInt MW 15-Nov-1996 */
	    q_block[0] = DecodePredictedIntraDC(comp,texture_bits,
						   trace,NUM);

	  }
      }


      if (CBP & (1 << (BLOCK_CNT - 1 - comp))) {
	VlcGetBlock(texture_bits, q_block, INTRA,
		    trace, error_flag, 1, GetVopReverseVlc(rec_vop),switched);
      }
      
      if (*error_flag == RETURN)
	return;
      
      if (intra_dcpred_disable == 0)
	doDCACreconErrRes(q_block, 64, DC_store, QP_store, QP,
			  x_pos, y_pos, MB_width, ACpred_flag, comp, slice_nb,GetVopMidGrey(rec_vop));
      else
	{
	  /* Ordinary inverse zigzag-scanning */
	  for (m = 0; m < 64; m++)
	    pcoeff[m] = q_block[zigzag[m]];
	  for (m = 0; m < 8; m++)
	    for (n = 0; n < 8; n++)
	      q_block[m*8+n] = pcoeff[m*8+n];
	}	  
      
      if (trace->MB_tdata_before_IQ)
	for (i=0;i<64;i++)
	  mb_dct_bf_iq[comp][i]=q_block[i]; 
      
      /* Store the qcoeff-values needed later for prediction */
      for (m = 0; m < 8; m++) {
	DC_store[mbnum][comp][m] = q_block[m];
      }
      for (m = 0; m < 7; m++) {
	DC_store[mbnum][comp][m+8] = q_block[(m+1)*8];
      }
      

      /* MW 22-APR-1997 Changes for MPEG dequantization */
      if(GetVopQuantType(rec_vop))
	BlockDequantMPEG(q_block,quant_step,INTRA,1,
			 GetVopIntraQuantMat(rec_vop),DCT_block);
      else
	BlockDequantH263(q_block,quant_step,INTRA,1,DCT_block);
      
      DC_store[mbnum][comp][0] = DCT_block[0];

      if (trace->MB_tdata_after_IQ)
	for (i=0;i<64;i++)
	  mb_dct_iq[comp][i]=DCT_block[i]; 
    
      
      BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
      for (m = 0; m < B_SIZE; m++)
	for (n = 0; n < B_SIZE; n++)
	  r_block[m*B_SIZE+n] = r_block_2D[m][n];
           
       if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
                 mb_idct[comp][i]=r_block[i]; 


    }
    else /* MODE INTER */
      {
	if (CBP & (1 << (BLOCK_CNT - 1 - comp))) {
	  VlcGetBlock (texture_bits, q_block, INTER, trace,
		       error_flag, 0, GetVopReverseVlc(rec_vop), switched);
	}
	
	if (*error_flag == RETURN)
	  return;
	
	/* Inverse zigzag-scanning also here 12-11-96 MW */
	for (m = 0; m < 64; m++)
	  pcoeff[m] = q_block[zigzag[m]];
	
	for (m = 0; m < 8; m++)
	  for (n = 0; n < 8; n++)
	    q_block[m*8+n] = pcoeff[m*8+n];
       if (trace->MB_tdata_before_IQ)
             for (i=0;i<64;i++)
                   mb_dct_bf_iq[comp][i]=q_block[i]; 


       /* Fill DC_store with default coeff values */
       DC_store[mbnum][comp][0] = GetVopMidGrey(rec_vop)*8;
       for (n = 1; n < 15; n++)
	 DC_store[mbnum][comp][n] = 0;
       
	
	/* MW 22-APR-1997 Changes for MPEG dequantization */
	if(GetVopQuantType(rec_vop))
	  BlockDequantMPEG(q_block,quant_step,INTER,1,
			   GetVopNonintraQuantMat(rec_vop),DCT_block);
	else
	  BlockDequantH263(q_block,quant_step,INTER,1,DCT_block);
	
	for (i=0;i<64;i++)
      DCT_block[i] =  MIN(((1<<(GetVopBitsPerPixel(rec_vop)+4))-1),
			  MAX((-(1<<(GetVopBitsPerPixel(rec_vop)+4))),DCT_block[i]));  /* VM31 Clp */

       if (trace->MB_tdata_after_IQ)
              for (i=0;i<64;i++)
                 mb_dct_iq[comp][i]=DCT_block[i]; 
 	
	BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
	
	for (m = 0; m < B_SIZE; m++)
	  for (n = 0; n < B_SIZE; n++)
	    r_block[m*B_SIZE+n] = r_block_2D[m][n];
        
         if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
                 mb_idct[comp][i]=r_block[i]; 



      }
    }
	else
		{
			Bzero(r_block);
      DC_store[mbnum][comp][0] = GetVopMidGrey(rec_vop)*8;
      for (n = 1; n < 15; n++)
      	DC_store[mbnum][comp][n] = 0;
	
		}
    PutBlock (comp, r_block, mblock);
  }

  /*****
   *
   *	  Decoding of 2 chrominance blocks (not dep. on 
   *        transparent pattern)
   *
   *****/
  for (comp=4; comp<6; comp++)
  {
      Bzero (q_block);

      if ((disable_sadct==0)||(level_3_trace)) { /* Noel/E14 */
	switch(comp) {
	  case 0 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + j)];
	    break;
	  case 1 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
	    break;
	  case 2 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + j)];
	    break;
	  case 3 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = alpha[(y_pos*MB_SIZE + 8 + i)*nrpix + (x_pos*MB_SIZE + 8 + j)];
	    break;
	  case 4 :
	  case 5 :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++) {
		if (shape == GREY_SCALE) {
		  tmp = alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)];
		  tmp += alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		  tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)];
		  tmp += alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)];
		  tmp += 2;
		  tmp /= 4;
		  alpha_block[i][j] = (tmp > BINARY_ALPHA/2) ? BINARY_ALPHA : 0;
		}
		else { /* so-called "conservative" subsampling (JDL - 20-MAR-97) */
		  alpha_block[i][j] = 
		   ((alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
		    (alpha[(y_pos*MB_SIZE + 2*i)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA) ||
		    (alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j)] == BINARY_ALPHA) ||
		    (alpha[(y_pos*MB_SIZE + 2*i+1)*nrpix + (x_pos*MB_SIZE + 2*j+1)] == BINARY_ALPHA))
		      ? BINARY_ALPHA : 0 ; 
		}
	      }
	    break;
	  default :
	    for (i=0; i<B_SIZE; i++)
	      for (j=0; j<B_SIZE; j++)
		alpha_block[i][j] = BINARY_ALPHA;
	}
     if (trace->trace)
           for (i=0;i<8;i++)
             for (j=0;j<8;j++)
                mb_shape[comp][i*8+j]=alpha_block[i][j];
      }
      if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
	{
	  if (switched==0) {
	    if (intra_dcpred_disable)    /* No INTRA DC prediction */
	      {
		DC_coeff = BitstreamReadBits(texture_bits, 8, "DC coeff", trace,
				       NUM);

		if (DC_coeff == 128){
		  printf("Illegal DC coeff: 1000000\n");
		  exit(1);
		}
		if (DC_coeff == 255)
		  DC_coeff = 128;
		
	      }
	    else            /* INTRA DC prediction (I-MBs) */
	      {
		DC_coeff = DecodePredictedIntraDC(comp, texture_bits,
						  trace, NUM);
	      }
	      
	    q_block[0] = DC_coeff;
	  }	     
	    
	  if (CBP & (1 << (BLOCK_CNT - 1 - comp)))
	    if (GetVopReverseVlc(rec_vop))
	      VlcGetBlock (texture_bits, q_block, INTRA, trace,
			   error_flag, 1, GetVopReverseVlc(rec_vop), switched);
	    else
	      VlcGetBlock (texture_bits, q_block, INTRA, trace,
			   error_flag, 1, GetVopReverseVlc(rec_vop), switched); /*it should be 1 */
	  
	  if (*error_flag == RETURN)
	    return;
	  
	  /* Do the DC/AC prediction, changing the qcoeff values as
	     appropriate */
	  if (intra_dcpred_disable == 0)
	    doDCACreconErrRes(q_block, 64, DC_store, QP_store, QP,
			      x_pos, y_pos, MB_width, ACpred_flag, comp, slice_nb,GetVopMidGrey(rec_vop));
	  else
	    {
	      /* Ordinary inverse zigzag-scanning */
	      for (m = 0; m < 64; m++)
		pcoeff[m] = q_block[zigzag[m]];
	      for (m = 0; m < 8; m++)
		for (n = 0; n < 8; n++)
		  q_block[m*8+n] = pcoeff[m*8+n];
	    }
	  
	  if (trace->MB_tdata_before_IQ)
	    for (i=0;i<64;i++)
	      mb_dct_bf_iq[comp][i]=q_block[i];
	  
	  /* Store the qcoeff-values needed later for prediction */
	  for (m = 0; m < 8; m++) {
	    DC_store[mbnum][comp][m] = q_block[m];
	  }
	  for (m = 0; m < 7; m++) {
	    DC_store[mbnum][comp][m+8] = q_block[(m+1)*8];
	  }
	  
	  /* MW 22-APR-1997 Changes for MPEG dequantization */
	  if(GetVopQuantType(rec_vop))
	    BlockDequantMPEG(q_block,quant_step,INTRA,2,
			     GetVopIntraQuantMat(rec_vop),DCT_block);
	  else
	    BlockDequantH263(q_block,quant_step,INTRA,2,DCT_block);
   
	  DC_store[mbnum][comp][0] = DCT_block[0];

	  if (trace->MB_tdata_after_IQ)
	    for (i=0;i<64;i++)
	      mb_dct_iq[comp][i]=DCT_block[i]; 
	  
	  
	  BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
	  
	  for (m = 0; m < B_SIZE; m++)
	    for (n = 0; n < B_SIZE; n++)
	      r_block[m*B_SIZE+n] = r_block_2D[m][n];
	  if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
	      mb_idct[comp][i]=r_block[i]; 


	}
      else		/* MODE_INTER */
	{
	  if (CBP & (1 << (BLOCK_CNT - 1 - comp)))
	    VlcGetBlock (texture_bits, q_block, INTER, trace,
			 error_flag, 0, GetVopReverseVlc(rec_vop),switched);
	  
	  if (*error_flag == RETURN)
	    return;

	  
	  /* Inverse zigzag-scanning also here 12-11-96 MW */
	  for (m = 0; m < 64; m++)
	    pcoeff[m] = q_block[zigzag[m]];
	  
	  for (m = 0; m < 8; m++)
	    for (n = 0; n < 8; n++)
	      q_block[m*8+n] = pcoeff[m*8+n];
	  if (trace->MB_tdata_before_IQ)
	    for (i=0;i<64;i++)
	      mb_dct_bf_iq[comp][i]=q_block[i]; 
	  
	  /* Fill DC_store with default coeff values */
	  DC_store[mbnum][comp][0] = GetVopMidGrey(rec_vop)*8;
	  for (n = 1; n < 15; n++)
	    DC_store[mbnum][comp][n] = 0;
	  
	  
	  /* MW 22-APR-1997 Changes for MPEG dequantization */
	  if(GetVopQuantType(rec_vop))
	    BlockDequantMPEG(q_block,quant_step,INTER,2,
			     GetVopNonintraQuantMat(rec_vop),DCT_block);
	  else
	    BlockDequantH263(q_block,quant_step,INTER,2,DCT_block);
	  


	  if (trace->MB_tdata_after_IQ)
	    for (i=0;i<64;i++)
	      mb_dct_iq[comp][i]=DCT_block[i]; 
	  
  
	  BlockIDCT(DCT_block, r_block_2D,GetVopBrightWhite(rec_vop));
	  
	  for (m = 0; m < B_SIZE; m++)
	    for (n = 0; n < B_SIZE; n++)
	      r_block[m*B_SIZE+n] = r_block_2D[m][n];
	  if (trace->MB_tdata_after_IDCT)
            for (i=0;i<64;i++)
	      mb_idct[comp][i]=r_block[i];

	}

	  PutBlock (comp, r_block, mblock);
	}

  /*****
   *
   *	  Clip reconstructed intra MBs
   *
   *****/
  if ((mode == MODE_INTRA)||(mode == MODE_INTRA_Q))
    MB_clip (mblock,GetVopBrightWhite(rec_vop));
  
  if (trace->MB_sdata) 
    PrintOutMBData("MB_shape_data",mb_shape,mb_shape,trace->fp_trace);
  if (trace->MB_tdata_before_IQ)
    PrintOutMBData("MB_tdata_before_IQ",mb_shape,mb_dct_bf_iq,trace->fp_trace); 
  if (trace->MB_tdata_after_IQ)
    PrintOutMBData("MB_tdata_after_IQ",mb_shape,mb_dct_iq,trace->fp_trace);
  if (trace->MB_tdata_after_IDCT)
    PrintOutMBData("MB_tdata_after_IDCT",mb_shape,mb_idct,trace->fp_trace);
  if ((mode == MODE_INTRA)&&(trace->MB_tdata_reconstructed)) {
    for (i=0;i<6;i++)
      for (j=0;j<64;j++)
        if (mb_idct[i][j]<0) mb_idct[i][j]=0;
	else if (mb_idct[i][j]>255) mb_idct[i][j]=255;
    
    PrintOutMBData("MB_tdata_reconstructed",mb_shape,mb_idct,trace->fp_trace);
  }
  
}                               /* GetMBblockdataNoDataPartErrRes */


/***********************************************************CommentBegin******
 *
 * -- ReadVideoPacketHeader --
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	19-Nov-97
 *
 * Purpose :		
 *    Decodes the video packet header
 *
 * Arguments in : 	
 *	Bitstream *stream	data bitstream
 *      Vop *rec_vop            various fields of the VOP structure are needed.
 *	Trace  *trace		flag for tracing the process.
 *
 * Arguments in/out :	
 *      Int *slice_counter      the number of the current slice is incremented.
 *
 * Arguments out :	
 *      Int *next_MB            number of the next macroblock to be decoded.
 *      Int *stop_decoding      indicates if this was the last video packet.
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description : The resync marker and the following fields are read. If no
 *               resync marker is found, then this is assumed to be the last video packet.	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified :	27.03.98 M.Wollborn: Modified due to N2171 Cl. 2.5.3
 *
 ***********************************************************CommentEnd********/
Void
ReadVideoPacketHeader(Bitstream *stream, Vop *rec_vop, Int *slice_counter, Trace *trace, 
		      Int *next_MB, Int *stop_decoding)
{
  
  Int rec_height, rec_width;
  Int MB_in_height, MB_in_width;
  Int MB_in_VOP;
  Int MB_in_VOP_length;
  Int tmpvar;
  Int bits;
  Int f_code_for;
  Int f_code_back;
  Int f_code_max;
  Int resync_marker_length;

  /*****
   *
   * Set some useful parameters
   *
   *****/
  rec_height = GetVopHeight (rec_vop);
  rec_width = GetVopWidth (rec_vop);
  MB_in_height = rec_height / MB_SIZE;
  MB_in_width = rec_width / MB_SIZE;
  MB_in_VOP = MB_in_width * MB_in_height;
  MB_in_VOP_length = (Int) ceil(log(MB_in_VOP)/log(2));
  f_code_for = GetVopFCodeFor(rec_vop);
  f_code_back = GetVopFCodeBack(rec_vop);
  f_code_max = (f_code_for > f_code_back) ? f_code_for : f_code_back;
  

  if (GetVopPredictionType(rec_vop) == I_VOP || GetVopShape(rec_vop) == BINARY_SHAPE_ONLY)
    resync_marker_length = 17;
  else if (GetVopPredictionType(rec_vop) == P_VOP)
    resync_marker_length = 16+f_code_for;
  else 
    resync_marker_length = 16+f_code_max;


  if ((BitstreamShowBitsByteAlign(stream,resync_marker_length)) == RESYNC_MARKER){
    BitstreamByteAlign(stream);
    BitstreamReadBits(stream,resync_marker_length,"resync_marker",trace,NUM);
    *next_MB = BitstreamReadBits(stream,MB_in_VOP_length,"macro_block_num",trace,NUM);
    if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY)
      BitstreamReadBits(stream,GetVopQuantPrecision(rec_vop),"quant_scale",trace,NUM);
    if (BitstreamReadBits(stream,1,"header_extension_code",trace,NUM)){
      /* modulo_time_base (? bits) */
      tmpvar = (Int) BitstreamReadBits(stream,1,"modulo_time_base",trace,FLAG);
      
      while(tmpvar == 1)
	{
	  tmpvar = (Int) BitstreamReadBits(stream,1,"modulo_time_base",trace,FLAG);
	}
      
      /* vop_time_increment (1-15 bits) */
      bits = ceil(log((double)GetVopTimeIncrementResolution(rec_vop))/log(2.0));
      if (bits<1) bits=1;
      BitstreamReadBits(stream,1,"marker_bit",trace,NUM);
      tmpvar = (Int) BitstreamReadBits(stream,bits,"vop_time_increment",trace,NUM);
      BitstreamReadBits(stream,1,"marker_bit",trace,NUM);
      
      /* vop_prediction_type (2 bits) */
      BitstreamReadBits(stream,2,"vop_prediction_type",trace,NUM);

      /* fcodes */
      if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY) /* Noel/E14 */
	{
	  /* Added intra_dc_vlc_thr reading due to N2171 Cl. 2.5.3 MW 27-MAR-1998 */
	  BitstreamReadBits(stream,3,"intra_dc_vlc_thr",trace,NUM);

	  if (GetVopPredictionType(rec_vop) != I_VOP)
	    BitstreamReadBits(stream,3,"fcode_for",trace,NUM);
	  if (GetVopPredictionType(rec_vop) == B_VOP) 
	    BitstreamReadBits(stream,3,"fcode_back",trace,NUM);
	}

    }
    ++*slice_counter;
  }
  else
    {
      *next_MB = MB_in_width * MB_in_height;
      *stop_decoding = 1;
    }
  
  

  return;
  
}

/***********************************************************CommentBegin******
 *
 * -- LookForMarker --
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	3-Dec-97
 *
 * Purpose : advances the read pointer until it finds a marker		
 *
 *
 * Arguments in : 	
 *     Bitstream *stream        data bitstream
 *     Vop *rec_vop             some fields of the VOP are needed
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description : the read pointer is advanced until a RESYNC_MARKER, a
 *               VOP_START_CODE, a GROUP_START_CODE or then END_OF_BITSTREAM
 *               is found. The pointer stops before the byte alignment.	
 *
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/
Void
LookForMarker(Bitstream *stream, Vop *rec_vop)
{
  
  Int f_code_for, f_code_back, f_code_max;
  Int resync_marker_length;

  /*****
   *
   * Set some useful parameters
   *
   *****/
  f_code_for = GetVopFCodeFor(rec_vop);
  f_code_back = GetVopFCodeBack(rec_vop);
  f_code_max = (f_code_for > f_code_back) ? f_code_for : f_code_back;
  
  if (GetVopPredictionType(rec_vop) == I_VOP || GetVopShape(rec_vop) == BINARY_SHAPE_ONLY)
    resync_marker_length = 17;
  else if (GetVopPredictionType(rec_vop) == P_VOP)
    resync_marker_length = 16+f_code_for;
  else
    resync_marker_length = 16+f_code_max;


  /*****
   *
   * Look for the marker and stop before the byte alignment
   *
   *****/
  
  while ((((BitstreamShowBitsByteAlign(stream,resync_marker_length)) != RESYNC_MARKER) &&
	  ((BitstreamShowBitsByteAlign(stream,VOP_START_CODE_LENGTH)) !=VOP_START_CODE) &&
	  ((BitstreamShowBitsByteAlign(stream,GROUP_START_CODE_LENGTH))!=GROUP_START_CODE) &&
	  ((BitstreamShowBitsByteAlign(stream,EOB_CODE_LENGTH)) != EOB_CODE))
	 || (!CheckBitStuffing(stream)))
    BitstreamFlushBits(stream,1);
  
  return;
  
}


/***********************************************************CommentBegin******
 *
 * -- receive_MODB_MTYPE -- receive_CBPB--- receive_DBQUANT---
 *
 * Author :		
 *	Minhua Zhou (HHI) <
 *
 * Created :		
 *	24-July-97
 *
 * Purpose :		
 *      decodes the MB header codes of a B-MB
 *
 * Arguments in : 	

 *
 * Arguments in/out :	
 * Arguments out :	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 * See also :
 *	
 *
 * Modified : 
 *   30.07.97 Fernando Jaureguizar: Added spatial_scalability
 *
 ***********************************************************CommentEnd********/

Void receive_MODB_MTYPE(Bitstream *stream, 
                         Int *CBPB,
                         Int *Mode,
                         Int spatial_scalability, /*SpSc*/
                         Trace *trace) {
      Int code;
     /* receive MODB */
      code = BitstreamShowBits (stream, 2);
      BitstreamFlushBits (stream, 2);
        if (code==2)  
          BitstreamTrace("10" , "MODB", trace);
         else
          BitstreamTrace("11" , "MODB", trace);
        *CBPB=(code==2)?0:1;
    
        code = BitstreamShowBits (stream, 4);
        if (code==1) {
            *Mode=0; /* forward MC */
            BitstreamFlushBits (stream, 4);
            BitstreamTrace("0001" , "MBTYPE", trace);
            /*>SpSc*/
            if(spatial_scalability)
              {
              fprintf(stderr,
                 "ERROR: MBTYPE '0001' unknown for Spat. Scal.\n"); 
              exit(-1);
              }
            /*SpSc<*/
        } else if (code<4) {
             *Mode=1; /* backward MC */
            BitstreamFlushBits (stream, 3);
            BitstreamTrace("001" , "MBTYPE", trace);
        }  else if (code<8) {
             *Mode=2; /* interploative MC */
             BitstreamFlushBits (stream, 2);
             BitstreamTrace("01" , "MBTYPE", trace);
         }  else {
             BitstreamFlushBits (stream, 1);
             BitstreamTrace("1" , "MBTYPE", trace);
             /*>SpSc*/
             if(spatial_scalability)
               *Mode=0; /* forward MC */
             else
             /*SpSc<*/
               *Mode=3; /* Direct MC */
           }
       return;
  }  

Void receive_CBPB(Bitstream *stream,
                  Int *MB_transp_pattern,
                  Int *CBPB,
                  Trace *trace) {
   Int code=0,k;
   for (k=0;k<6;k++) {
     code+=code;
     if ((k < 4 && MB_transp_pattern[k] != 1) || (k > 3)) 
       code += BitstreamReadBits (stream, 1, "CBPB", trace, CODE);
   } 
     
    *CBPB=code; 
   }
   
Void receive_B_DQUANT(Bitstream *stream,
                      Int Mode,
                      Int *DQUANT,
                      Trace *trace) {
           Int code;
           if (Mode==3) {*DQUANT=0;return;}
           code = BitstreamShowBits (stream, 2);
           if (code<2) {
             *DQUANT=0;
             BitstreamFlushBits (stream, 1);
             BitstreamTrace("0" , "DQUANT", trace);
           } else if (code==2) {
             BitstreamFlushBits (stream, 2);
             BitstreamTrace("10" , "DQUANT", trace);
             *DQUANT=-2;
           } else if (code==3) {
             BitstreamFlushBits (stream, 2);
             BitstreamTrace("11" , "DQUANT", trace);
             *DQUANT=2;
            }
  }

/***********************************************************CommentBegin******
 *
 * -- receive_B_Motion_Vector -- 
 *
 * Author :		
 *	Minhua Zhou (HHI) <
 *
 * Created :		
 *	24-July-97
 *
 * Purpose :		
 *      Forms the motion vector predictor and then decodes vectors for a MB
 *
 * Arguments in : 	
 *		Bitstream *stream,	bitstream
 *              Image *modes,          prediction modes
 *              Int i, Int j,          position of MB 
 *              Int f_code_for,
 *              Int f_code_back,       f_codes
 *              Int spatial_scalability  flag for Spat. Scal. (SpSc)
 *              Trace *trace           trace control

 *
 * Arguments in/out :	
 *              Image *mot_x, 		horizontal motion vector field 
 *		Image *mot_y,           vertical motion vector field
 * Arguments out :	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 * See also :
 *	
 *
 * Modified : 
 *   30.07.97 Fernando Jaureguizar: Added spatial_scalability
 *   09.12.97 Luis Ducla-Soares: modifications to allow the error resilient mode.
 *   12.12.97 Bob Eifrig: Support for field motion vectors
 *		13.1.98 Noel Brady: added parameter init_mvp in order to allow 
 *					error resilient B_VOPs with shape.
 *
 ***********************************************************CommentEnd********/

Void receive_B_Motion_Vector(Bitstream *stream,
			     Image *mot_x, 
			     Image *mot_y, 
			     Image *modes,
			     Int i, Int j, 
			     Int f_code_for, Int f_code_back,
			     Int spatial_scalability, /*SpSc*/
			     Trace *trace,
			     Int error_res_disable,
			     Int init_mvp) {
      Int     MB_num_x;  /* Dimensions in macroblocks */
      Float   *mv_x, *mv_y;    /* Motion vectors            */
      SInt    *pred_m;         /* Modes                     */
      Int     B_num_x,index,Mode,Mode_prevs;
      SInt vx,vy;
      static SInt Px_for,Py_for,Px_back,Py_back;
      static Int  prev_j = -1;
      static SInt Px_for_bot, Py_for_bot, Px_back_bot, Py_back_bot;
      if (prev_j != j){
        Px_for  = Py_for  = 0;
        Px_back = Py_back = 0;
        Px_for_bot = Py_for_bot = 0;
        Px_back_bot = Py_back_bot = 0;
        prev_j = j;
      }

      if (!error_res_disable)
	{
	  if (i != 0)
	    {
	      if (init_mvp)
		{
		  Px_for  = Py_for  = 0;
		  Px_back = Py_back = 0;
		}
	    }
	}

      MB_num_x=(Int)GetImageSizeX(modes);
      mv_x=(Float*)GetImageData(mot_x);
      mv_y=(Float*)GetImageData(mot_y);
      pred_m=(SInt*)GetImageData(modes);
      B_num_x=2*MB_num_x; 
      index = (j+j)*B_num_x+i+i;
      Mode = pred_m[j*MB_num_x+i];
      if (i>0)
        Mode_prevs =  pred_m[j*MB_num_x+i-1];
       else Mode_prevs = 2;

    if (Mode >= MBM_B_FWDFLD) {
        switch (Mode & MBM_B_MODE) {

        case MBM_B_FWDFLD:
        case MBM_B_AVEFLD:
            receive_vector(&Px_for, &vy, Px_for, Py_for/2,
			    f_code_for, f_code_for, trace, stream);
            mv_x[index] = 0.5 * Px_for;
            Py_for = 2 * vy;
            mv_y[index] = vy;

            receive_vector(&Px_for_bot, &vy, Px_for_bot, Py_for_bot/2,
			   f_code_for, f_code_for, trace, stream);
            mv_x[index + 1] = 0.5 * Px_for_bot;
            Py_for_bot = 2 * vy;
            mv_y[index + 1] = vy;

            if ((Mode & MBM_B_MODE) == MBM_B_FWDFLD)
                break;
            /*FALLINTO*/

        case MBM_B_BAKFLD:
            index += B_num_x;
            receive_vector(&Px_back, &vy, Px_back, Py_back/2,
			   f_code_back, f_code_back, trace, stream);
            mv_x[index] = 0.5 * Px_back;
            Py_back = 2 * vy;
            mv_y[index] = vy;

            receive_vector(&Px_back_bot, &vy, Px_back_bot,
			   Py_back_bot/2, f_code_back, f_code_back, trace, stream);
            mv_x[index + 1] = 0.5 * Px_back_bot;
            Py_back_bot = 2 * vy;
            mv_y[index + 1] = vy;
            break;
        }
        return;
    }

             if ((Mode==0)||(Mode==2)) {        /* forward + interplo. */
               receive_vector(&vx,&vy,Px_for,Py_for,f_code_for,f_code_for,trace,stream);
	       mv_x[index]=(Float)vx/2.0;
               mv_y[index]=(Float)vy/2.0;
               Px_for = vx; Py_for  = vy;
               Px_for_bot = vx; Py_for_bot = vy;
         } 

      if ((Mode==1)||(Mode==2)) { /* backward + interplo. */
           if(!spatial_scalability) /*SpSc*/{
               receive_vector(&vx,&vy,Px_back,Py_back,f_code_back,f_code_back,trace,stream);
 
	   mv_x[index+1]=(Float)vx/2.0;
           mv_y[index+1]=(Float)vy/2.0;
           Px_back = vx; Py_back = vy;
           Px_back_bot = vx; Py_back_bot = vy;
          }

        }  
       if (Mode==3) { /* direct mode */       
           receive_vector(&vx,&vy,0,0,1,1,trace,stream);
           mv_x[index+1+B_num_x]=(Float)vx/2.0;
           mv_y[index+1+B_num_x]=(Float)vy/2.0;
         }
  }


/***********************************************************CommentBegin******
 *
 * -- receive_vector -- 
 *
 * Author :		
 *	Minhua Zhou (HHI) <
 *
 * Created :		
 *	24-July-97
 *
 * Purpose :		
 *      Decodes a vector of  B-VOPs
 *
 * Arguments in : 	
 *	 SInt Px,SInt Py,			vector predictor
 *       Int f_code_horizontal,			horizontal f_code
 *       Int f_code_vertical,			vertical f_code
 *       Trace *trace,				trace control
 *       Bitstream *stream 			bitstream
 *
 * Arguments in/out :	
  *
 * Arguments out :	
 *       SInt *vx,SInt *vy			decoded vector
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 * See also :
 *	
 *
 * Modified : 
 *
 ***********************************************************CommentEnd********/

Void receive_vector(SInt *vx,SInt *vy,SInt Px,SInt Py,
                    Int f_code_horizontal,
                    Int f_code_vertical,
                    Trace *trace,
                    Bitstream *stream) {
   Int diff_vector,residual,vlc_code_magnitude;
   Int f_code,i,sign,*error_flag=NULL;
   static Int range[7]={32,64,128,256,512,1024,2048};  /* 2*range*/
   static Int scale_factor[7]={1,2,4,8,16,32,64};
   for (i=0;i<2;i++) {
    f_code=((i==0)?f_code_horizontal-1:f_code_vertical-1);
    vlc_code_magnitude = VlcDecMV(stream, error_flag,trace);
    if (vlc_code_magnitude==0) diff_vector=0;
      else {
         residual=BitstreamReadBits(stream, f_code, "MV residual",
                                  trace, CODE);
         if (vlc_code_magnitude<0) sign=1;else sign=0;
         if (sign)  vlc_code_magnitude=-vlc_code_magnitude;
         vlc_code_magnitude--;
         diff_vector=vlc_code_magnitude*scale_factor[f_code]+residual+1;
         if (sign) diff_vector=-diff_vector;
        } 
      diff_vector+=((i==0)?Px:Py);
      if (diff_vector<-range[f_code]) diff_vector+=range[f_code]+range[f_code];
        else if (diff_vector>range[f_code]-1)  diff_vector-=range[f_code]+range[f_code];
      if (i==0) *vx=diff_vector;
              *vy=diff_vector;
     }
   
 }


/***********************************************************CommentBegin******
 *
 * -- B_DecodeVopCombinedMotionShapeTextureInter -- 
 *
 * Author :		
 *	Minhua Zhou (HHI) <
 *
 * Created :		
 *	24-July-97
 *
 * Purpose :		
 *      Decodes combined motion / shape / texture for B-VOPs
 *
 * Arguments in : 	
 *	Bitstream *stream	combined shape / texture bitstream
 *	Trace  *trace		flag for tracing the process.
 *      Image *mot_x_P,
 *      Image *mot_y_P          motion vector of the next P-VOP or I-VOP
 *
 *
 * Arguments in/out :	
 *	Vop *rec_vop		alpha plane is supposed to be filled
 *				already / YUV components.
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 * See also :
 *	
 *
 * Modified : 
 *   30.07.97 Fernando Jaureguizar: Added spatial_scalability
 *	 14.10.97 shape MC for B-VOPs uses the backward reference i.e. the 
 *						most recently decoded I/P VOP.
 *   12.12.97 Bob Eifrig: interlaced video decoding
 *
 ***********************************************************CommentEnd********/

Void B_DecodeVopCombinedMotionShapeTextureInter(
    Bitstream * stream,
    Int vo_id,
    Trace *trace,
    Vop *rec_vop,
    Image *mot_x_P,
    Image *mot_y_P,
    Image *MB_decisions_P)
{
    Int         vol_id = GetVopId(rec_vop);
    Int         ef=0, *error_flag = &ef; 
    Int         mbnum, x_pos, y_pos, i, j;
    Int         rec_height;
    Int         rec_width;
    Int         MB_in_height, MB_in_width;
    Int         B_in_width, B_in_height;
    Macroblock  *mblock;
    Image       *Y_rec, *U_rec, *V_rec;
    Short       *alpha, *alpha_prev;
    Int         vop_quant,intra_dcpred_disable;
    Int         skipped_flag;
    Image       *alpha_decisions,*MB_decisions;
    UInt        new_vop;
    SInt        *palpha_decisions,*pMB_decisions;
    SInt        *mode_P = (SInt *)GetImageData(MB_decisions_P);
    Int         MB_transp_pattern[4];
    Int         ***DC_store;
    Int         QP;
    Int         COD,TRB,TRD;
    Int         CBP;
    Int         ACpred_flag=-1;
    Int         mode,DQUANT;
    Int         f_code_for=GetVopFCodeFor(rec_vop);
    Int         f_code_back=GetVopFCodeBack(rec_vop);
    Image       *mot_x, *mot_y;
    Float       *motx_ptr, *moty_ptr;
    Vop         *tmp_vop,*ref_vop;
    SInt        *QP_store;
    /*>SpSc*/
    Int         spatial_scalability=0;
    Int         scalability  = GetVopScalability(rec_vop);
    Int         ref_sel_code = GetVopRefSelCode(rec_vop);
    Int         offset_x,offset_y;
    Int         co_mbx,co_mby,edge=16;
    Int         MB_non_trans_count=0;
    Int         dct_type;

    /*****
    *
    *   Stuff for motion compensation of alpha plane (copied by JDL 
    *   from AlphaMotionCompensate() in vm_common/src/mot_comp.c,
    *   a function written by Noel Brady
    *
    *****/
    Image *motA2_x=NULL,*motA2_y=NULL,*modeA2=NULL;

    Int amb_type=0,mvda=0;
    


 
    /*****
     *
     *	Set some useful parameters
     *
     *****/
    rec_height = GetVopHeight (rec_vop);
    rec_width = GetVopWidth (rec_vop);
    MB_in_height = rec_height / MB_SIZE;
    MB_in_width = rec_width / MB_SIZE;
    B_in_width = 2 * MB_in_width;
    B_in_height = 2 * MB_in_height;
    QP_store = (SInt *) GetImageData(GetVopQP(rec_vop));
    /*>SpSc*/
    /* B-VOP with Sp.Sc. => ref_sel_code = 0 */
    if (scalability == 1 && ref_sel_code == 0)
      spatial_scalability = 1;
    /*SpSc<*/
  
    DC_store = (Int ***)calloc(MB_in_width*MB_in_height,
				       sizeof(Int **));
    for (i = 0; i < MB_in_width*MB_in_height; i++)
    {
	DC_store[i] = (Int **)calloc(6, sizeof(Int *));
	for (j = 0; j < 6; j++)
	    DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
    }

    mot_x = AllocImage((UInt) B_in_width,(UInt) B_in_height,FLOAT_TYPE);
    mot_y = AllocImage((UInt) B_in_width,(UInt) B_in_height,FLOAT_TYPE);
    motx_ptr = (Float *)GetImageData(mot_x);
    moty_ptr = (Float *)GetImageData(mot_y);

    SetConstantImage(mot_x,0.0);
    SetConstantImage(mot_y,0.0);

    if (GetVopShape(rec_vop))
      {
	/* Allocate shape ME/MC */
	modeA2 = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
			    GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
	motA2_x = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
			     GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
	motA2_y = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
			     GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
      }

        
    intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
    
    alpha_decisions = AllocImage(B_in_width,B_in_height,SHORT_TYPE);
    MB_decisions    = AllocImage(MB_in_width,MB_in_height,SHORT_TYPE);

    tmp_vop = AllocVop(GetVopWidth(rec_vop),GetVopHeight(rec_vop));
    CopyVopNonImageField(rec_vop,tmp_vop);

    /*****
     *
     *	Get the image fields of the VOP
     *
     *****/
    Y_rec = GetVopY (rec_vop);
    U_rec = GetVopU (rec_vop);
    V_rec = GetVopV (rec_vop);
    alpha = (Short *) GetImageData( GetVopA(rec_vop) );
    /* for inter shape */
    alpha_prev = (Short *) GetImageData( GetVopA( GetVopPrevTemp(rec_vop) ) ); 
    
    /*****
     *
     *	Get VOP quantizer and allocate MB structure
     *
     *****/
/*** 10/28 for TPS */
    /*if (GetVopScalability(rec_vop)==0)*/
    vop_quant = GetVopQuantizer(rec_vop);

    QP = vop_quant;

  
    mblock = (Macroblock *) malloc (sizeof (Macroblock));

    if (mblock == NULL)
      {
	printf (" Error allocating macroblock\n");
	exit(1);
      }

   if(!temporal_scalability && GetVopScalability(rec_vop))
      printf("Enhancement Layer: \n");
  
   printf("Start B VOP decoding \n");

    /*****
     *
     *	Loop over all MBs, decode texture of each MB
     *
     *****/
    new_vop = 1;
    pMB_decisions = (SInt *)GetImageData(MB_decisions);
    palpha_decisions = (SInt *)GetImageData(alpha_decisions);

    /* initialise values that indicate blockwise whether */
    /* the block is transparent                          */
    for (i = 0; i < B_in_width*B_in_height; i++)
      palpha_decisions[i] = MBM_TRANSPARENT;

    /*****
    *
    * the macroblock loop
    *
    *****/

    offset_x = GetVopHorSpatRef(rec_vop)-GetVopHorSpatRef(GetVopNextTemp(rec_vop))+8-edge;
    offset_y = GetVopVerSpatRef(rec_vop)-GetVopVerSpatRef(GetVopNextTemp(rec_vop))+8-edge;


{
   if (temporal_scalability && GetVopScalability(rec_vop)==1) {
/*** 4/19 changed by SHARP */
        if(GetVopRefSelCode(rec_vop) == 1){
	  Int now ,prev, next;
	  now  = CalcFrameNumber(rec_vop);
	  next = CalcFrameNumber(GetVopNextTemp(rec_vop));
	  prev = CalcFrameNumber(GetVopPrevTemp(rec_vop));
	  TRB = abs(now - prev);
          TRD = abs(now - prev) + abs(now - next);
        }
        else{
	  Int prev, next;
	  next = CalcFrameNumber(GetVopNextTemp(rec_vop));
	  prev = CalcFrameNumber(GetVopPrevTemp(rec_vop));
          TRD = next                    - prev;
	  TRB = CalcFrameNumber(rec_vop) - prev;
	}
/* 4/19 changed by SHARP ***/
   }
   else {
     TRD = CalcVopDisplayTime(GetVopNextTemp(rec_vop))
         - CalcVopDisplayTime(GetVopPrevTemp(rec_vop));
     TRB = CalcVopDisplayTime(rec_vop)
         - CalcVopDisplayTime(GetVopPrevTemp(rec_vop));
   } 
}

if (SelectRefVop(GetVopPrevTemp(rec_vop),rec_vop,GetVopNextTemp(rec_vop),TRB,TRD))
   ref_vop = GetVopNextTemp(rec_vop);
  else ref_vop = GetVopPrevTemp(rec_vop);


      for (y_pos = 0; y_pos < MB_in_height; y_pos++)
      for (x_pos = 0; x_pos < MB_in_width; x_pos++)
	{
       	  mbnum = y_pos * MB_in_width + x_pos;
	  MBzero (mblock);

         if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY) {
	  if (MB_non_trans_count>=MB_trace_thres)
             SetTraceLevelsZero(trace);
          else
             SetTraceLevelsDefault(trace);
          }


	  /* Store the QP value for later use in AC prediction */
	  QP_store[mbnum] = (SInt) QP;
	  pMB_decisions[mbnum]=-1;


	  trace->trace = trace->MB_header;
	  
	  if (trace->trace)
	    {
              fprintf (trace->fp_trace,
                 "\n>>>   Decoding Macroblock %d @ %d - Combined Motion/Shape/Text\n",
                 (int)mbnum, stream->bitcnt);
	    }
	  
	  if (GetVopShape(rec_vop)) 
	    {
			  trace->trace = trace->MB_shape;

	      DecodeFirst(stream, vo_id, vol_id, y_pos, x_pos, &amb_type, 
			  &mvda, 1, 0, rec_vop, ref_vop, trace);
	      /* fill the alpha map with the decoded pixels for this MB */
				/* 	Noel(B) - shape MC is done from most 
						recently decoded P-VOP i.e. GetVopNextTemp
				*/


	     AlphaDecodeMB(rec_vop,ref_vop,vo_id,vol_id,y_pos,x_pos,
			    &amb_type,&mvda,1,MB_decisions,alpha_decisions,mot_x,mot_y,modeA2,
			    motA2_x,motA2_y,0,stream,trace, error_flag);
	  		if(trace->trace)
	  		fprintf(trace->fp_trace, "----------\n");
				trace->trace = trace->MB_header;

	      if (amb_type == 1) 
		{	/* if the alpha MV is all_0 */
		  /* for a correct motion vector prediction in the MB's */
		  /* below the actual MB   --- JDL                      */
		  palpha_decisions[2*y_pos*B_in_width + 2*x_pos] = MBM_TRANSPARENT;
		  palpha_decisions[2*y_pos*B_in_width + 2*x_pos + 1] = MBM_TRANSPARENT;
		  palpha_decisions[(2*y_pos + 1)*B_in_width + 2*x_pos] = MBM_TRANSPARENT;
		  palpha_decisions[(2*y_pos + 1)*B_in_width + 2*x_pos + 1] = MBM_TRANSPARENT;
		}
	    }

	  /* decode COD, MCPC, ACpred_flag, CPBY and DQUANT */
          if (amb_type==1) for (i=0;i<4;i++) MB_transp_pattern[i]=1;
          if (!GetVopShape(rec_vop))
	    {	
	      /* no shape ("rectangular" shape) */
	      for(i=0;i<MB_SIZE;i++)
	        for(j=0;j<MB_SIZE;j++)
		  alpha[((y_pos * MB_SIZE) +i)*rec_width 
		       + (x_pos * MB_SIZE) +j] = BINARY_ALPHA;
	    }

	  if (amb_type != 1)  /* if not transparent */
	    {
              MB_non_trans_count++;
              if (amb_type==0)  for (i=0;i<4;i++) MB_transp_pattern[i]=0;
               else {
              for (i=0;i<4;i++) MB_transp_pattern[i]=1;
              for(i=0;i<B_SIZE;i++)
	        for(j=0;j<B_SIZE;j++)
		  if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   (x_pos * MB_SIZE) +j] != 0)
		    MB_transp_pattern[0]=0;
	
	      for(i=0;i<B_SIZE;i++)		
	        for(j=B_SIZE;j<2*B_SIZE;j++)
		  if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   (x_pos * MB_SIZE) +j] != 0)
		    MB_transp_pattern[1]=0;
	      
	      for(i=B_SIZE;i<2*B_SIZE;i++)
	        for(j=0;j<B_SIZE;j++)
		  if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   (x_pos * MB_SIZE) +j] != 0)
		    MB_transp_pattern[2]=0;
	      
	      for(i=B_SIZE;i<2*B_SIZE;i++)
	        for(j=B_SIZE;j<2*B_SIZE;j++)
		  if (alpha[((y_pos * MB_SIZE) +i)*rec_width + 
			   (x_pos * MB_SIZE) +j] != 0)
		    MB_transp_pattern[3]=0;
              }


               co_mbx = x_pos;
               co_mby = y_pos;

	      if ((co_mbx>=0)&&(co_mbx<GetImageSizeX(MB_decisions_P))&&
                 (co_mby>=0)&&(co_mby<GetImageSizeY(MB_decisions_P))&& 
                 (mode_P[co_mby*GetImageSizeX(MB_decisions_P)+co_mbx]==MBM_SKIPPED)&&(!spatial_scalability)

                && (GetVopScalability(rec_vop)==0 ||
		   (GetVopScalability(rec_vop)==1 && ref_sel_code==3 && GetVopEnhanceType(rec_vop)==0)))
             {

               pMB_decisions[mbnum]=4;
               COD =1;CBP =0;QP_store[mbnum]=QP;
             } else {           
              COD = BitstreamShowBits(stream,1);
              COD = COD?0:1;
              
              if (COD==1) {
                  BitstreamFlushBits(stream,1);
                  CBP =0;
                  if (spatial_scalability) 
                        pMB_decisions[mbnum]=0;
                  else  pMB_decisions[mbnum]=3;
                      
                  QP_store[mbnum]=QP;
              } else {
               receive_MODB_MTYPE(stream,&CBP,&mode,
                                  spatial_scalability, /*SpSc*/
                                  trace);
               pMB_decisions[mbnum]=mode;
               DQUANT=0;
               if (CBP) {
                 receive_CBPB(stream,MB_transp_pattern,&CBP,trace);
                 receive_B_DQUANT(stream,mode,&DQUANT,trace);    
                } 
               QP+=DQUANT;
               QP_store[mbnum]=QP;

               dct_type = 0;
               if (GetVopInterlaced(rec_vop)) {
                   if (CBP != 0)
                       dct_type = BitstreamReadBits(stream, 1, "dct_type",
						  trace, FLAG);
                   if ((mode != MBM_B_DIRECT) &&
                       BitstreamReadBits(stream, 1, "field_prediction",
						  trace, FLAG)) {
                       switch (mode) {

                       case MBM_B_FWDFRM:
                       case MBM_B_AVEFRM:
                           if (BitstreamReadBits(stream, 1,
					         "forward_top_field_reference", trace, FLAG))
                               mode |= MBM_B_FWDTOP;
                           if (BitstreamReadBits(stream, 1,
					        "forward_bottom_field_reference", trace, FLAG))
                               mode |= MBM_B_FWDBOT;
                           if ((mode & MBM_B_MODE) == MBM_B_FWDFRM) {
                               mode += MBM_B_FWDFLD - MBM_B_FWDFRM;
                               break;
                           }
                           /*FALLINTO*/

                       case MBM_B_BAKFRM:
                           if (BitstreamReadBits(stream, 1,
							   "backward_top_field_reference", trace, FLAG))
                               mode |= MBM_B_BAKTOP;
                           if (BitstreamReadBits(stream, 1,
							   "backward_bottom_field_reference", trace, FLAG))
                               mode |= MBM_B_BAKBOT;
                           mode += MBM_B_FWDFLD - MBM_B_FWDFRM;
                           break;
                       }
                       pMB_decisions[mbnum] = mode;
                   }
               }

receive_B_Motion_Vector(stream,mot_x,mot_y,MB_decisions,
                        x_pos,y_pos,f_code_for, f_code_back,
                        spatial_scalability, /*SpSc*/
                        trace,
		        GetVopErrorResDisable(rec_vop),
		        0); 
               if (CBP) 
               GetMBblockdata(MB_transp_pattern,
			     1,
			     QP,stream,mbnum,trace,
			     mblock,&skipped_flag, error_flag, 
			     MB_in_width, 
			     DC_store, QP_store, QP,
			     CBP, ACpred_flag, MODE_INTER,
			     alpha, dct_type, rec_vop);
              }
             } 
            } else pMB_decisions[mbnum]=-1; /* transparent */
            if (pMB_decisions[mbnum]!=-1)
                           	
	  /* if the MB is multilevel */
	  if ((amb_type != 0) || (amb_type != 1))
	    SetAlphaDecisions(GetVopA(rec_vop),x_pos,y_pos,alpha_decisions);  	  	  
	  FillVop (mblock, mbnum, Y_rec, U_rec, V_rec);
	}


   RemapAlphaDecisions(alpha_decisions);



B_VopMotionCompensation(
          rec_vop,GetVopPrevTemp(rec_vop),GetVopNextTemp(rec_vop),
          mot_x,mot_y,mot_x_P,mot_y_P,MB_decisions_P,
          MB_decisions,alpha_decisions,
          TRB,TRD,tmp_vop);
 
   VopTextureUpdate(tmp_vop,rec_vop,trace);

    
    if (GetVopShape(rec_vop))
      {
	/* Allocate shape ME/MC */
	/* Removed cast to (Char *), 05-FEB-1997 MW */
	FreeImage(modeA2);			  
	FreeImage(motA2_x);			  
	FreeImage(motA2_y);			  
      }

    for (i = 0; i < MB_in_width*MB_in_height; i++)
      {
	for (j = 0; j < 6; j++) 
	  free((Char *)DC_store[i][j]);
	free((Char *)DC_store[i]);
      }
    free((Char *)DC_store);


    FreeImage(alpha_decisions);
    FreeImage(MB_decisions);
    free ((Char *)mblock);
    FreeImage(mot_x);
    FreeImage(mot_y);
    FreeVop(tmp_vop);

    
    return;
}

/***********************************************************CommentBegin******
 *
 * -- B_DecodeVopCombinedMotionShapeTextureInterErrRes -- 
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	12-Dec-97
 *
 * Purpose :		
 *      Decodes combined motion / shape / texture for B-VOPs
 *      in the error resilient mode
 *
 * Arguments in : 	
 *	Bitstream *stream	combined shape / texture bitstream
 *	Trace  *trace		flag for tracing the process.
 *      Image *mot_x_P,
 *      Image *mot_y_P          motion vector of the next P-VOP or I-VOP
 *
 *
 * Arguments in/out :	
 *	Vop *rec_vop		alpha plane is supposed to be filled
 *				already / YUV components.
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *
 *
 * Note : 
 *
 * See also :
 *	
 *
 * Modified : 
 *					13-1-98: Noel Brady - added support for shape decoding.
 *
 ***********************************************************CommentEnd********/

Void B_DecodeVopCombinedMotionShapeTextureInterErrRes(Bitstream * stream,
						      Int vo_id,
						      Trace *trace,
						      Vop *rec_vop,
						      Image *mot_x_P,
						      Image *mot_y_P,
						      Image *MB_decisions_P)
{
    Int         vol_id = GetVopId(rec_vop);
    Int         ef=0, *error_flag = &ef; 
    Int         mbnum, x_pos, y_pos, i, j;
    Int         rec_height;
    Int         rec_width;
    Int         MB_in_height, MB_in_width;
    Int         B_in_width, B_in_height;
    Macroblock  *mblock;
    Image       *Y_rec, *U_rec, *V_rec;
    Short       *alpha, *alpha_prev;
    Int         vop_quant,intra_dcpred_disable;
    /*    Int         skipped_flag;*/
    Image       *alpha_decisions,*MB_decisions;
    UInt        new_vop;
    SInt        *palpha_decisions,*pMB_decisions;
    SInt        *mode_P = (SInt *)GetImageData(MB_decisions_P);
    /*   Int         MB_transp_pattern[4];*/
    Int         ***DC_store;
    Int         **slice_nb;
    Int         slice_counter;
    Int         QP;
    Int         COD,TRB,TRD;
    /*    Int         CBP;*/
    /*    Int         ACpred_flag=-1;
    Int         mode,DQUANT;*/
    Int         f_code_for=GetVopFCodeFor(rec_vop);
    Int         f_code_back=GetVopFCodeBack(rec_vop);
    Int         f_code;
    Image       *mot_x, *mot_y;
    Float       *motx_ptr, *moty_ptr;
    Vop         *tmp_vop,*ref_vop;
    SInt        *QP_store;
    Int         tmpvar;
    Int         next_MB;
    Int         MB_in_VOP;
    Int         MB_in_VOP_length;
    HeaderInfo  *header_data;
    Int         bits;
    Int         resync_marker_length;
    Int         start_of_packet;
    /*>SpSc*/
    Int         spatial_scalability=0;
    Int         scalability  = GetVopScalability(rec_vop);
    Int         ref_sel_code = GetVopRefSelCode(rec_vop);
    Int         offset_x,offset_y;
    Int         co_mbx,co_mby,edge=16;
    Int         MB_non_trans_count=0;
    Int         init_mvp=0;
 
    /*****
    *
    *   Stuff for motion compensation of alpha plane (copied by JDL 
    *   from AlphaMotionCompensate() in vm_common/src/mot_comp.c,
    *   a function written by Noel Brady
    *
    *****/
    Image *motA_x=NULL,*motA_y=NULL,*modeA=NULL;

    Int amb_type=0;
    


#ifdef _DEBUG_SPSC_
    PrintVopInfo(rec_vop,"-b-Rec--Comp");
    PrintVopInfo(GetVopNextTemp(rec_vop),"-b-Rec--Comp->N");
    PrintVopInfo(GetVopPrevTemp(rec_vop),"-b-Rec--Comp->P");
    sprintf(name,"-b-Rec--Comp%d",count);
    WriteVopDebug(rec_vop,name,name,name,0);
#endif

/* SPRITE */   
 
    /*****
     *
     *	Set some useful parameters
     *
     *****/
    rec_height = GetVopHeight (rec_vop);
    rec_width = GetVopWidth (rec_vop);
    MB_in_height = rec_height / MB_SIZE;
    MB_in_width = rec_width / MB_SIZE;
    B_in_width = 2 * MB_in_width;
    B_in_height = 2 * MB_in_height;
    QP_store = (SInt *) GetImageData(GetVopQP(rec_vop));
    MB_in_VOP = MB_in_width * MB_in_height;
    MB_in_VOP_length = (Int) ceil(log(MB_in_VOP)/log(2));
    f_code = (f_code_for > f_code_back) ? f_code_for:f_code_back;

    if (GetVopShape(rec_vop) == BINARY_SHAPE_ONLY)
      resync_marker_length = 17;
    else
      resync_marker_length = 16 + f_code;

    /*>SpSc*/
    /* B-VOP with Sp.Sc. => ref_sel_code = 0 */
    if (scalability == 1 && ref_sel_code == 0)
      spatial_scalability = 1;
    /*SpSc<*/
  
    header_data = (HeaderInfo *)calloc(MB_in_width*MB_in_height,sizeof(HeaderInfo));
    
    DC_store = (Int ***)calloc(MB_in_width*MB_in_height,
				       sizeof(Int **));
    for (i = 0; i < MB_in_width*MB_in_height; i++)
    {
	DC_store[i] = (Int **)calloc(6, sizeof(Int *));
	for (j = 0; j < 6; j++)
	    DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
    }

    /* allocate space for 2D matrix to keep track of the slice numbers */
    
    slice_nb = (Int **)calloc(MB_in_width,sizeof(Int *));
    
    for (i = 0; i < MB_in_width; i++)
      slice_nb[i] = (Int *)calloc(MB_in_height, sizeof(Int));


    mot_x = AllocImage((UInt) B_in_width,(UInt) B_in_height,FLOAT_TYPE);
    mot_y = AllocImage((UInt) B_in_width,(UInt) B_in_height,FLOAT_TYPE);
    motx_ptr = (Float *)GetImageData(mot_x);
    moty_ptr = (Float *)GetImageData(mot_y);

    SetConstantImage(mot_x,0.0);
    SetConstantImage(mot_y,0.0);

    if (GetVopShape(rec_vop))
      {
			AllocShapePacket2(rec_vop);
	/* Allocate shape ME/MC */
	modeA = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
			    GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
	motA_x = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
			     GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
	motA_y = AllocImage(GetVopWidth(rec_vop)/MB_SIZE,
			     GetVopHeight(rec_vop)/MB_SIZE,SHORT_TYPE);
      }

        
    intra_dcpred_disable = GetVopIntraACDCPredDisable(rec_vop);
    
    alpha_decisions = AllocImage(B_in_width,B_in_height,SHORT_TYPE);
    MB_decisions    = AllocImage(MB_in_width,MB_in_height,SHORT_TYPE);

    tmp_vop = AllocVop(GetVopWidth(rec_vop),GetVopHeight(rec_vop));
    CopyVopNonImageField(rec_vop,tmp_vop);

    /*****
     *
     *	Get the image fields of the VOP
     *
     *****/
    Y_rec = GetVopY (rec_vop);
    U_rec = GetVopU (rec_vop);
    V_rec = GetVopV (rec_vop);
    alpha = (Short *) GetImageData( GetVopA(rec_vop) );
    /* for inter shape */
    alpha_prev = (Short *) GetImageData( GetVopA( GetVopPrevTemp(rec_vop) ) ); 
    
    /*****
     *
     *	Get VOP quantizer and allocate MB structure
     *
     *****/
    vop_quant = GetVopQuantizer(rec_vop);

    QP = vop_quant;

  
    mblock = (Macroblock *) malloc (sizeof (Macroblock));

    if (mblock == NULL)
      {
	printf (" Error allocating macroblock\n");
	exit(1);
      }

   if(!temporal_scalability && GetVopScalability(rec_vop))
      printf("Enhancement Layer: \n");
 
	printf("Start B VOP decoding \n");

    /*****
     *
     *	Loop over all MBs, decode texture of each MB
     *
     *****/
    new_vop = 1;
    pMB_decisions = (SInt *)GetImageData(MB_decisions);
    palpha_decisions = (SInt *)GetImageData(alpha_decisions);

    /* initialise values that indicate blockwise whether */
    /* the block is transparent                          */
    for (i = 0; i < B_in_width*B_in_height; i++)
      palpha_decisions[i] = MBM_TRANSPARENT;

    /*****
    *
    * the macroblock loop
    *
    *****/

    offset_x = GetVopHorSpatRef(rec_vop)-GetVopHorSpatRef(GetVopNextTemp(rec_vop))+8-edge;
    offset_y = GetVopVerSpatRef(rec_vop)-GetVopVerSpatRef(GetVopNextTemp(rec_vop))+8-edge;




{
      if (temporal_scalability && GetVopScalability(rec_vop)==1) {
/*** 4/19 changed by SHARP */
        if(GetVopRefSelCode(rec_vop) == 1){
	  Int now ,prev, next;
	  now  = CalcFrameNumber(rec_vop);
	  next = CalcFrameNumber(GetVopNextTemp(rec_vop));
	  prev = CalcFrameNumber(GetVopPrevTemp(rec_vop));
	  TRB = abs(now - prev);
          TRD = abs(now - prev) + abs(now - next);
        }
        else{
	  Int prev, next;
	  next = CalcFrameNumber(GetVopNextTemp(rec_vop));
	  prev = CalcFrameNumber(GetVopPrevTemp(rec_vop));
          TRD = next                    - prev;
	  TRB = CalcFrameNumber(rec_vop) - prev;
	}
/* 4/19 changed by SHARP ***/
      }
      else {
        TRD = CalcVopDisplayTime(GetVopNextTemp(rec_vop))
            - CalcVopDisplayTime(GetVopPrevTemp(rec_vop));
        TRB = CalcVopDisplayTime(rec_vop)
            - CalcVopDisplayTime(GetVopPrevTemp(rec_vop));
      } 
}

if (SelectRefVop(GetVopPrevTemp(rec_vop),rec_vop,GetVopNextTemp(rec_vop),TRB,TRD))
   ref_vop = GetVopNextTemp(rec_vop);
  else ref_vop = GetVopPrevTemp(rec_vop);

    
    mbnum = 0;
    slice_counter = 0;
    start_of_packet = 1;

    while (mbnum < MB_in_width*MB_in_height)
      {
	
	x_pos = mbnum % MB_in_width;
	y_pos = mbnum / MB_in_width;

	slice_nb[x_pos][y_pos] = slice_counter;
	
	MBzero (mblock);
	
	if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY) {
	  if (MB_non_trans_count>=MB_trace_thres)
	    SetTraceLevelsZero(trace);
          else
	    SetTraceLevelsDefault(trace);
	}


	/* Store the QP value for later use in AC prediction */
	QP_store[mbnum] = (SInt) QP;
	pMB_decisions[mbnum]=-1;

	/* set all blocks to opaque */
  	for(i=0;i<4;i++) 
	  header_data[mbnum].MB_transp_pattern[i]=0;

	
	trace->trace = trace->MB_header;
	
	if (trace->trace)
	  {
	    fprintf (trace->fp_trace,"\n>>>   Decoding Macroblock %d ........- Combined Motion/Shape/Text\n",(int)mbnum);
	  }
	
	if (GetVopShape(rec_vop)) 
		{
	    trace->trace = trace->MB_shape;

		  	  GetMBInterShapeErrRes(stream,ref_vop,
						vo_id,vol_id,y_pos,x_pos,mbnum,
						MB_decisions,alpha_decisions,mot_x,mot_y,
						modeA,motA_x,motA_y,start_of_packet,&amb_type,
						header_data[mbnum].MB_transp_pattern,
						error_flag,rec_vop,trace);
			start_of_packet = 0;

	    if(trace->trace)
	      fprintf(trace->fp_trace, "----------\n");
	    trace->trace = trace->MB_header;

		}

	/* decode COD, MCPC, ACpred_flag, CPBY and DQUANT */

	if (!GetVopShape(rec_vop))
	    {	
	      /* no shape ("rectangular" shape) */
	      for(i=0;i<MB_SIZE;i++)
	        for(j=0;j<MB_SIZE;j++)
		  alpha[((y_pos * MB_SIZE) +i)*rec_width 
		       + (x_pos * MB_SIZE) +j] = BINARY_ALPHA;
	    }
	
	if (amb_type != 1)  /* if not transparent */
	  {

	    MB_non_trans_count++;

	    if (amb_type==0)  
        for (i=0;i<4;i++) header_data[mbnum].MB_transp_pattern[i]=0;

	    co_mbx = x_pos;
	    co_mby = y_pos;
	    
	    if ((co_mbx>=0)&&(co_mbx<GetImageSizeX(MB_decisions_P))&&
		(co_mby>=0)&&(co_mby<GetImageSizeY(MB_decisions_P))&& 
		(mode_P[co_mby*GetImageSizeX(MB_decisions_P)+co_mbx]==MBM_SKIPPED)&&
                (!spatial_scalability)
                && (GetVopScalability(rec_vop)==0 ||
		    (GetVopScalability(rec_vop)==1 && ref_sel_code==3 
                && GetVopEnhanceType(rec_vop)==0)))
            {
	      pMB_decisions[mbnum]=4;
	      COD =1;header_data[mbnum].CBP =0;QP_store[mbnum]=QP;
	    } else {           
              COD = BitstreamShowBits(stream,1);
              COD = COD?0:1;
              
              if (COD==1) {
		BitstreamFlushBits(stream,1);
		header_data[mbnum].CBP =0;
		if (spatial_scalability) 
		  pMB_decisions[mbnum]=0;
		else  pMB_decisions[mbnum]=3;
		
		QP_store[mbnum]=QP;
              } else {
		receive_MODB_MTYPE(stream,&header_data[mbnum].CBP,&header_data[mbnum].mode,
				   spatial_scalability, /*SpSc*/
				   trace);
		pMB_decisions[mbnum]=header_data[mbnum].mode;
		header_data[mbnum].DQUANT=0;
		if (header_data[mbnum].CBP) {
		  receive_CBPB(stream,header_data[mbnum].MB_transp_pattern,&header_data[mbnum].CBP,trace);
		  receive_B_DQUANT(stream,header_data[mbnum].mode,&header_data[mbnum].DQUANT,trace);    
                } 
		QP+=header_data[mbnum].DQUANT;
		QP_store[mbnum]=QP;
		
		receive_B_Motion_Vector(stream,mot_x,mot_y,MB_decisions,
					x_pos,y_pos,f_code_for, f_code_back,
					spatial_scalability, /*SpSc*/
					trace,
					GetVopErrorResDisable(rec_vop),
					init_mvp); 
    		init_mvp = 0;

		if (header_data[mbnum].CBP) 
		  GetMBblockdataNoDataPartErrRes(header_data[mbnum].MB_transp_pattern,
						 1,
						 QP,stream,mbnum,trace,
						 mblock, error_flag, 
						 MB_in_width, 
						 DC_store, QP_store, QP,
						 header_data[mbnum].CBP,
						 header_data[mbnum].ACpred_flag, 
						 MODE_INTER,
						 rec_vop, slice_nb);
              }
	    } 
	  } else pMB_decisions[mbnum]=-1; /* transparent */
	if (pMB_decisions[mbnum]!=-1)
	  /* if the MB is multilevel */
	  if ((amb_type != 0) || (amb_type != 1))
	    SetAlphaDecisions(GetVopA(rec_vop),x_pos,y_pos,alpha_decisions);  	  	  
	FillVop (mblock, mbnum, Y_rec, U_rec, V_rec);

	mbnum++;
	
	if (((BitstreamShowBitsByteAlign(stream,resync_marker_length)) ==
	     RESYNC_MARKER) && (CheckBitStuffing(stream))){

          init_mvp = 1;

	  BitstreamByteAlign(stream);
	  BitstreamReadBits(stream,resync_marker_length,"resync_marker",trace,NUM);
	  next_MB = BitstreamReadBits(stream,MB_in_VOP_length,"macro_block_num",trace,NUM);
	  if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY)
	    BitstreamReadBits(stream,GetVopQuantPrecision(rec_vop),"quant_scale",trace,NUM);
	  if (BitstreamReadBits(stream,1,"header_extension_code",trace,NUM)){
	    /* modulo_time_base (? bits) */
	    tmpvar = (Int) BitstreamReadBits(stream,1,"modulo_time_base",trace,FLAG);
	    
	    while(tmpvar == 1)
	      {
		tmpvar = (Int) BitstreamReadBits(stream,1,"modulo_time_base",trace,FLAG);
	      }
	    
	    /* vop_time_increment (1-15 bits) */
	    bits = ceil(log((double)GetVopTimeIncrementResolution(rec_vop))/log(2.0));
	    if (bits<1) bits=1;
	    BitstreamReadBits(stream,1,"marker_bit",trace,NUM);
	    tmpvar = (Int) BitstreamReadBits(stream,bits,"vop_time_increment",trace,NUM);
	    BitstreamReadBits(stream,1,"marker_bit",trace,NUM);
	    
	    /* vop_prediction_type (2 bits) */
	    BitstreamReadBits(stream,2,"vop_prediction_type",trace,NUM);
	    
	    /* fcodes */
	    if (GetVopShape(rec_vop) != BINARY_SHAPE_ONLY) /* Noel/E14 */
	      {

		/* Added intra_dc_vlc_thr reading due to N2171 Cl. 2.5.3 MW 27-MAR-1998 */
		BitstreamReadBits(stream,3,"intra_dc_vlc_thr",trace,NUM);

		BitstreamReadBits(stream,3,"fcode_for",trace,NUM);
		if (GetVopPredictionType(rec_vop) == B_VOP) 
		  BitstreamReadBits(stream,3,"fcode_back",trace,NUM);
	      }
	  }
	  slice_counter++;
	  start_of_packet = 1;
	}
	
	
	if ((BitstreamShowBitsByteAlign(stream,EOB_CODE_LENGTH)) == EOB_CODE
	    && CheckBitStuffing(stream)){
	  BitstreamByteAlign(stream);
	}
      }
    
    
    RemapAlphaDecisions(alpha_decisions);
    

   B_VopMotionCompensation(
          rec_vop,GetVopPrevTemp(rec_vop),GetVopNextTemp(rec_vop),
          mot_x,mot_y,mot_x_P,mot_y_P,MB_decisions_P,
          MB_decisions,alpha_decisions,
          TRB,TRD,tmp_vop);
   VopTextureUpdate(tmp_vop,rec_vop,trace);
    
    if (GetVopShape(rec_vop))
      {
  FreeShapePacket2();
	/* Allocate shape ME/MC */
	/* Removed cast to (Char *), 05-FEB-1997 MW */
	FreeImage(modeA);			  
	FreeImage(motA_x);			  
	FreeImage(motA_y);			  
      }

    for (i = 0; i < MB_in_width*MB_in_height; i++)
      {
	for (j = 0; j < 6; j++) 
	  free((Char *)DC_store[i][j]);
	free((Char *)DC_store[i]);
      }
    free((Char *)DC_store);


    FreeImage(alpha_decisions);
    FreeImage(MB_decisions);
    free ((Char *)mblock);
    FreeImage(mot_x);
    FreeImage(mot_y);
    FreeVop(tmp_vop);

    free(header_data);
    
    return;
}



Void PrintMBShapeData(Vop *vop, Int x_pos, Int y_pos, Trace *trace)
{
	Int i,j,k1,k2;

	SInt mb_shape[6][64];

	Image 	*alpha = GetVopA(vop),
					*alpha_uv = GetVopAuv(vop),
					*block = AllocImage(8,8,SHORT_TYPE);		

	SInt    *p=(SInt *)GetImageData(block);	


	for (i=0;i<4;i++)
		{
			k1 = i&1;
			k2 = (i>>1)&1;
			GetSubImage(alpha,block,x_pos*MB_SIZE+k1*8,y_pos*MB_SIZE+k2*8);
			for (j=0;j<64;j++)
				mb_shape[i][j] = p[j];
		}

	GetSubImage(alpha_uv,block,x_pos*8,y_pos*8);
			
	for (j=0;j<64;j++)
		mb_shape[4][j] = mb_shape[5][j] = p[j];
	
	PrintOutMBData("MB_shape_data",mb_shape,mb_shape,trace->fp_trace);
	FreeImage(block);
}

/***********************************************************CommentBegin******
 *
 * -- MarkerFound --
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	20-Nov-97
 *
 * Purpose : Tells if a marker is present after the byte alignment. By
 *           marker it is meant RESYNC_MARKER, VOP_START_CODE,
 *           GROUP_START_CODE or END_OF_BITSTREAM.	
 *
 *
 * Arguments in : 	
 *      Bitstream *stream                data bitstream
 *      Int resync_marker_length         length of the resync_marker
 *
 * Arguments in/out :	
 *
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	returns 1 if a marker is present
 *      returns 0 otherwise
 *
 * Side effects :	
 *	
 *
 * Description :	
 *      Checks if one marker is present after the byte alignment.
 *
 * Note : 
 *
 *
 * See also :
 *	
 *
 * Modified : 
 *
 *
 ***********************************************************CommentEnd********/
Int 
MarkerFound(Bitstream *stream, Int resync_marker_length)
{
  
  if (((BitstreamShowBitsByteAlign(stream,resync_marker_length))==RESYNC_MARKER) && (CheckBitStuffing(stream)))
    return 1;
  else if (((BitstreamShowBitsByteAlign(stream,VOP_START_CODE_LENGTH))==VOP_START_CODE) && (CheckBitStuffing(stream)))
    return 1;
  else if (((BitstreamShowBitsByteAlign(stream,GROUP_START_CODE_LENGTH))==GROUP_START_CODE) && (CheckBitStuffing(stream)))
    return 1;
  else if (((BitstreamShowBitsByteAlign(stream,EOB_CODE_LENGTH))==EOB_CODE) && (CheckBitStuffing(stream)))
    return 1;
  else
    return 0;

}


