/******************************************************************************
 *                                                                          
 * This software module was originally developed by 
 *
 * Noel O'Connor (TELTEC IRELAND / ACTS-MoMuSys).                   	
 *
 * and edited by 
 *
 * Aasmund Sandvand (Telenor / ACTS-MoMuSys). 	    	              	
 * J. Ignacio Ronda (UPM / ACTS-MoMuSys).   	  	              	
 * Cecile Dufour (LEP / ACTS-MoMuSys).     		              	
 * Minhua Zhou (HHI / ACTS-MoMuSys).   	  	 	              	
 * Fernando Jaureguizar (UPM / ACTS-MoMuSys).   	              	
 * Luis Ducla-Soares (IST / ACTS-MoMuSys).     	           	   	
 * Martina Eckert (UPM / ACTS-MoMuSys).   	  	              	
 * Noel Brady (TELTEC IRELAND / ACTS-MoMuSys).                   	
 * Angel Pacheco (UPM / ACTS-MoMuSys).     		              	
 * Michael Wollborn (TUH / 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) 1997
 *
 *****************************************************************************/

/***********************************************************HeaderBegin*******
 *                                                                         
 * File: vm_vop_code.c
 *
 * Author: Noel O'Connor Teltec Irl.
 * Created: 11-03-96
 *                                                                         
 * Description: 
 *
 * Notes:  
 *
 * Modified:
 * 21.04.96 Robert Danielsen: Reformatted. New headers.
 * 08.05.96 Noel O'Connor: New data structure for vop 
 *          configuration information.
 * 31.07.96 Noel O'Connor: Modified VopProcess to comply with
 *          high level changes for VM 3.0 syntax
 * 30-Aug-96 Jan De Lameillieure (HHI): MMR Coding
 * 23.09.96 Noel O'Connor: Some changes to allow coding of multiple VOs
 * 23.10.96 Robert Danielsen: Some changes to implement DC/AC prediction
 * 23.10.96 Aasmund.Sandvand@fou.telenor.no: Modified to support
 *          deblock filtering
 * 27.11.96 Noel O'Connor: Changed all instances of time variables to be
 * floating point (except in "BitstreamPutVopHeader()").
 * 2-Dec-96 Jan De Lameillieure (HHI): calculate SNR only in pels that belong
 *          to original AND reconstructed segment mask
 * 14.01.97 Luis Ducla-Soares: enabled byte alignment in function VopProcess()
 *          by removing comment around NextStartCode() function call.
 * 31.01.97 Aasmund Sandvand: Moved deblock filter out of the loop
 * 04.02.97 Noel O'Connor: removed all assert() calls
 * 07.02.97 J. Ignacio Ronda: VopCode() and VopProcess() modifications
 * 20.02.97 Cecile Dufour : including STATIC SPRITE
 * 20-MAR-97 Jan De Lameillieure (HHI) : added shape argument to SubsampleAlphaMap()
 * 11.03.97 Minhua Zhou   : added B-VOPs
 * 21.03.97 Cecile Dufour : including ONLINE SPRITE
 * 23.04.97 Michael Wollborn: changed "...GLQuantUpdate" 
 *			      -> "...DisableGrayQuantUpdate"
 * 26.04.97 Luis Ducla-Soares: added the error resilient mode with data partitioning.
 * 06.05.97 Noel Brady: added calls for VM7(CAE) binary shape coding.
 * 09.05.97 Minhua Zhou: added Group_of_GOPs 
 * 15.05.97 Luis Ducla-Soares: corrected the remultiplexing of the DCT data
 *                             in the combined error resilient mode with 
 *                             data partitioning.
 *
 * 15.05.97 Minhua Zhou      : modification for encoding empty VOP 
 * 16.06.97 Angel Pacheco: unified the TRANSPARENT modes.
 * 07.07.97 Martina Eckert: Introduction of global rate control 
 *          functions and parameters
 * 18.07.97 Ulrike Pestel-Schiller: Added spatial scalability
 * 01.08.97 Fernando Jaureguizar: Added enable_8x8_mv => Motion Vectors for
 *          8x8 blocks are allowed. This is allways set to 1 except for
 *          spatial scalability.
 *          WARNING!! Advanced prediction only means overlapped motion
 *          compensation.
 * 04.08.97 Minhua Zhou: rename obmc_disable   
 * 28.08.97 Osamu Sunohara(Sony): modified to calclate modulo_time_base in
 *                                spatial scalability exactly. 
 * 08.09.97 Cecile Dufour :modified vop_header and VOP_prediction for STATIC SP.
 * 27.11.97 M. Eckert: Changes for independent frame rate type control
 * 04.01.98 Michael Frater: Support for non-8-bit video
 * 16.01.98 M. Eckert: Changes concerning parameter-ctl-string for RC
 * 27.01.98 M. Eckert and F. Jaureguizar: VopCode() modifications for RC
 *
 ***********************************************************HeaderEnd*********/

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

#include "vm_config.h"
#include "vm_vop_code.h"
#include "vm_enc_defs.h"
#include "io_generic.h"
#include "mom_bitstream_i.h"
#include "vm_vop_bound.h"
#include "vm_compos.h"
#include "mot_comp.h"
#include "mot_padding.h"
#include "mom_putbits.h"
#include "alp_code_grey.h"
#include "mot_util.h"
#include "mot_est.h"
#include "sprite_util.h"
#include "sprite_enc_util.h"
#include "sprite_enc_piece.h"
#ifndef _WD_MODE_	  
#include "dynsprite_util.h"
#include "globalme.h"
#include "dec_svd.h"
#include "dynsprite_enc_util.h"
#endif
#include "alp_code_mom.h"
#include "alp_code_header.h"
#include "alp_common_util.h"

/* Due to N2171 Cl. 2.5.3 MW 28-MAR-1998 */
#include "vm_enc_main.h"

/* for TPS */
#include "enhance_vop.h"
#include "interlaced_bvop.h"
#include "tm5rc.h"


#include "meitca_wrapper.h"
#include "sait_rc.h"


/* inserted by SAMSUNG AIT */
#include "rc_mvo.h"	
extern Int TextureBits;
extern Int FirstInterFrame;
extern RC_MVO rc_mvo;
/* inserted by SAMSUNG AIT */


Int 	total_first_bits[3]={0,0,0},
			total_second_bits[3]={0,0,0},
			total_amv_bits[3]={0,0,0},
			total_cae_bits[3]={0,0,0},
			total_cae_intra_bits[3]={0,0,0},
			total_cae_inter_bits[3]={0,0,0},
			total_coded_mbs[3]={0,0,0},
			total_coded_intra_mbs[3]={0,0,0},
			total_coded_inter_mbs[3]={0,0,0},
			curr_first_bits,
			curr_second_bits,
			curr_amv_bits,
						curr_cae_bits,
						curr_cae_intra_bits,
						curr_cae_inter_bits,
						curr_coded_mbs,
						curr_coded_intra_mbs,
						curr_coded_inter_mbs;

Int ce_coded_frames[3],
		ce_bits_for_shape[3],
		ce_bits_for_vop;
/* for TPS */
Int	back_base_exist;

Int	for_shape_width ,          for_shape_height ,
	for_shape_hor_spat_ref ,   for_shape_ver_spat_ref;
Int	back_shape_width ,         back_shape_height ,
	back_shape_hor_spat_ref ,  back_shape_ver_spat_ref;
 
Image *for_first_shape_code_bitstream,   
      *for_shape_bitstream,          
      *back_first_shape_code_bitstream,   
      *back_shape_bitstream;
/**/

Int total_shape_bits = 0;


/***********************************************************CommentBegin******
 *
 * -- VopProcess -- Sets up and codes a vop, updates vop store
 *
 * Author :  
 * Noel O'Connor Teltec Irl.
 *
 * Created :  
 * 11-03-96
 *
 * Purpose :  
 * This function sets up a vop to be coded  (fills
 * vop syntax fields, etc.), and codes the vop. This is the main 
 *  "coding engine" of the implementation.
 * 
 * Arguments in :  
 * Vop *curr_vop_in - pointer to current vop to be coded
 *        (ASSUMED BOUNDED)
 * Vop *prev_vop - previous original Vop
 * Vop *prev_rec_vop - previous coded Vop
 * Float time - Time of coding
 * Int prev_time - Previous time of coding
 * VolConfig *vol_cfg - data structure containing extra configuration
 *        information for the VOL, specifically the file 
 *        names of the coded vop on disk.
 * Int vop_has_content - flag indicating whether Vop actually has
 *        content and needs to be coded or whether it is enough to send Vop
 *        header.
 * Int vo_id - current VO Id
 *
 * Arguments in/out : 
 * BitCount num_bits[][] - array of BitCount structures 
 *
 * Arguments out : 
 * -
 *
 * Return values : 
 * Vop *rec_curr - reconstructed current Vop
 *
 * Side effects : 
 * -
 *
 * Description : 
 *
 * See also :
 * file "README_ENCODER"
 *
 * Modified :  
 * 04.09.96 Cor Quist: added intra_dcpred_disable
 * 23.09.96 Noel O'Connor: some changes to allow coding of multiple VOs.
 * 09.10.96 Noel O'Connor: added call to NextStartCode()
 * 14.01.97 Luis Ducla-Soares: enabled byte alignment by removing
 *          comment around NextStartCode() function call.
 * 21.01.97 Removed bytealignment here. Done elsewhere. Fix by Luis.
 * 04.02.97 Noel O'Connor: added SADCT disable to VOP.
 * 04.02.97 Noel O'Connor: mods for non unique VOL Ids
 * 07.02.97 J. Ignacio Ronda: now BitstreamPutVopHeader() is called inside
 *          VopCode() => VopCode() with new parameters.
 *          New variable rc_type
 * 20.02.97 Cecile Dufour : to include STATIC SPRITE 
 * 11.03.97 Minhua Zhou   : added B-VOPs
 * 26.04.97 Luis Ducla-Soares: added data_partitioning enable to VOP.
 * 09.05.97 Minhua Zhou      : added call of BitstreamPutGOV
 * 15.05.97 Minhua Zhou      : modification for encoding empty VOP
 * 07.07.97 Martina Eckert: Introduction of global rate control 
 *              functions and parameters
 * 31.07.97 Fernando Jaureguizar: added GetVopScalability() (SpSc)
 * 01.08.97 Fernando Jaureguizar: Added enable_8x8_mv => Motion Vectors for
 *          8x8 blocks are allowed. This is allways set to 1 except for
 *          spatial scalability.
 * 27.11.97 M. Eckert: Changes for independent frame rate type control
 * 11.12.97 Bob Eifrig: Modification for interlaced video coding
 *
 ***********************************************************CommentEnd********/
/*TPS*/
Vop *
VopProcess(Vop *curr_vop_bb,
	   Vop *prev_vop,
	   Vop *prev_rec_vop,
	   Vop *next_vop,
	   Vop *next_rec_vop,
	   Float time,
	   VolConfig *vol_config,
	   Int vop_has_content,
	   Int vo_id, Int TRB, Int TRD,
	   VOConfig *vo_config_list, /* UPM Global RC */
	   Int rc_type,              /* UPM Global RC */
	   Int rc_algorithm,         /* hjlee */
	   BitCount num_bits[MAX_NUM_VOS][MAX_NUM_VOLS],
	   Vop *no_padding_vop,
	   Int temporal_scalability)
/**/
{
  Vop *rec_curr = NULL;			/* Reconstructed vop */

  Int vol_id,
    QP,
    Intra_QP,
    shape_effects,
    obmc_disable,
    unrestricted_motion_mode,
    acdc_pred_disable,
    quant_precision,
    bits_per_pixel,
    error_res_disable,
    data_partitioning,
    
    reversible_vlc,
    sadct_disable,
    sr_for,	   
    sr_back,
    num_vop_code_inc=0,
    alpha_th,
    change_CR_disable,
    gl_quantizer,
    disable_gray_quant_update,
    *qmat_vop, *qmat_vol,
    
    vop_spat_scal=0;
  
/*** 10/27 TPS */
  Int  vop_temp_scal = 0;	
  Int  modulo_tps    = 0;
/* 10/27 TPS ***/
  
  Int		i;
  TrajPoint	*tmp_refpoint;



  Int enable_8x8_mv = 1; /*SpSc*/
  
  vol_id = GetVolConfigId(vol_config);
    
  /* Getting the VOP ScalType, for spat scal (UPS)*/
/*** 10/27 TPS */
  if(GetVopScalability(curr_vop_bb) ==1){ 
    /*SpSc*/
    if (( GetVopPredictionType(curr_vop_bb)==P_VOP 
       && GetVopRefSelCode(curr_vop_bb) ==3)
     || ( GetVopPredictionType(curr_vop_bb)==B_VOP 
       && GetVopRefSelCode(curr_vop_bb) ==0))
      vop_spat_scal=1;
    /* TPS */
    else if(GetVopPredictionType(curr_vop_bb)==P_VOP &&
	    (GetVopRefSelCode(curr_vop_bb) == 0 ||
	     GetVopRefSelCode(curr_vop_bb) == 1 ||
	     GetVopRefSelCode(curr_vop_bb) == 2)        )
        vop_temp_scal = 3;       /* P_VOP        : TPS */    
    else if(GetVopPredictionType(curr_vop_bb) == B_VOP){
        if(GetVopRefSelCode(curr_vop_bb) == 3)
            vop_temp_scal = 1;   /* B_VOP_TYPE_1 : TPS */    
        else if(GetVopRefSelCode(curr_vop_bb) == 1)
            vop_temp_scal = 2;   /* B_VOP_TYPE_2 : TPS */    
    }
  }
/* 10/27 TPS ***/

      
  /* Set up the vop coding parameters */
  /* Vop type */
/*** 10/27 TPS */
  if(!vop_spat_scal                                 /* not spatial scalability         */
     && (vop_temp_scal == 0 || vop_temp_scal == 3 ))  /* not temporal_scalability(B_VOP) */
/* 10/27 TPS ***/
     {
       if ( (prev_vop != NULL) && (GetVolConfigSpriteUsage(vol_config) == ONLINE_SPRITE||
				  GetVolConfigSpriteUsage(vol_config) == GMC_SPRITE ) )
	{
	  PutVopPredictionType(SPRITE_VOP,curr_vop_bb);
	  fprintf(stdout, "==> prediction type set to SPRITE_VOP \n");
	}
      else
	if ( (GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE)&&
	     ( GetVolConfigWarpParamCounter(vol_config)!= -1 ))
	  {
	  if (GetVolConfigCheckStaticSpritePrediction(vol_config))
		{
		PutVopPredictionType(SPRITE_VOP,curr_vop_bb);
		fprintf(stdout, "==> prediction type set to SPRITE_VOP \n");
		}
	else
		{
/* Vop_prediction Type set before the Vop_process call in sprite_enc_piece.c */
		}
	  }
	else 
	  if ((TRD>1)&&(TRB!=0))
	    PutVopPredictionType(B_VOP,curr_vop_bb);
      /* for TPS */
      /*else 
	if (  (prev_vop != NULL) &&
	((vol_config->frame - vol_config->start_frame - vol_config->frame_skip)%(vol_config->frame_skip * vol_config->intra_period)!=0) )*/
	  else 
	    if (  (prev_vop != NULL) &&
		  (((vol_config->frame - vol_config->start_frame - GetVolConfigM(vol_config)*vol_config->frame_skip)%(vol_config->frame_skip * vol_config->intra_period)!=0) || ( GetVopScalability(curr_vop_bb))))
	      {
		PutVopPredictionType(DEFAULT_PRED_TYPE,curr_vop_bb);
		num_vop_code_inc = 0;
		if (GetVopWidth(prev_vop)==0) 
                  PutVopPredictionType(I_VOP,curr_vop_bb);
		/* added by Minhua Zhou 15-05-97 */
	      }
	    else
	      {
         if (rc_type >= TM5_RATE_CONTROL) {
            Int nppic, npic = (vol_config->end_frame - curr_vop_bb->frame + 1) / vol_config->frame_skip;
            if (prev_vop == NULL) {
                if (npic > (vol_config->intra_period - GetVolConfigM(vol_config) + 1))
                    npic = vol_config->intra_period - GetVolConfigM(vol_config) + 1;
            } else {
                npic += GetVolConfigM(vol_config) - 1;
                if (npic > vol_config->intra_period)
                    npic = vol_config->intra_period;
            }
            nppic = (npic + GetVolConfigM(vol_config) - 1) / GetVolConfigM(vol_config) - 1;
            tm5rc_init_GOP(nppic, npic - nppic - 1, vol_config->rcdata);
        }
		PutVopPredictionType(I_VOP,curr_vop_bb);
		num_vop_code_inc = 1;
	      }
    }
   if (rc_type >= TM5_RATE_CONTROL) { 
          Int quant;

          tm5rc_init_pict(curr_vop_bb, vol_config->rcdata);
          quant = tm5rc_start_mb(vol_config->rcdata);
          switch (GetVopPredictionType(curr_vop_bb)) {
              case I_VOP: PutVopIntraQuantizer(quant, curr_vop_bb); break;
              case P_VOP: PutVopQuantizer     (quant, curr_vop_bb); break;
              case B_VOP: PutVopBQuantizer    (quant, curr_vop_bb); break;
          }
      }

   /* Set vop_rounding_type */
      if ( GetVopPredictionType(curr_vop_bb)==P_VOP ||
           ( GetVolConfigSpriteUsage(vol_config) != STATIC_SPRITE &&
             GetVopPredictionType(curr_vop_bb)==SPRITE_VOP)) 
        {
          if (GetVopPredictionType(prev_vop)== I_VOP )
            PutVopRoundingType(0,curr_vop_bb);
          else
            if (!GetVopRoundingType(prev_vop))
              PutVopRoundingType(1,curr_vop_bb);
            else
              PutVopRoundingType(0,curr_vop_bb);
        }
      else
        PutVopRoundingType(0,curr_vop_bb);
  
  /* Vop quantizer - INTER */
  QP = GetVolConfigQuantizer(vol_config); 
  PutVopQuantizer(QP,curr_vop_bb);

  /* Vop quantizer - INTER B */
  QP = GetVolConfigBQuantizer(vol_config); 
  PutVopBQuantizer(QP,curr_vop_bb);


	/* Vop quantizer - INTRA */
	Intra_QP = GetVolConfigIntraQuantizer(vol_config);


	if (RCQ2_MVO_CHECK() >= RCQ2_MVO_HVS)  
	  Intra_QP = GetMBQuant(vo_id, 0);



	PutVopIntraQuantizer(Intra_QP,curr_vop_bb);
	
	/* Vop quantizer type (H.263 or MPEG) */
	PutVopQuantType(GetVolConfigQuantType(vol_config),curr_vop_bb);
        PutVopTimeIncrementResolution(GetVolConfigTimeIncrementResolution(vol_config),curr_vop_bb); 

	/* Added MPEG-like quantization parameters to VOP, 24-APR-1997 MW */
	if(GetVopQuantType(curr_vop_bb))
	  {
	    /* intra quant. matrix */
	    PutVopLoadIntraQuantMat(GetVolConfigLoadIntraQuantMat(vol_config),
				    curr_vop_bb);

	    qmat_vol = GetVolConfigIntraQuantMat(vol_config);
	    qmat_vop = GetVopIntraQuantMat(curr_vop_bb);

	    for(i=0; i<64; i++)
	      qmat_vop[i] = qmat_vol[i];

	    /* nonintra quant. matrix */
	    PutVopLoadNonintraQuantMat(GetVolConfigLoadNonintraQuantMat(vol_config),curr_vop_bb);

	    qmat_vol = GetVolConfigNonintraQuantMat(vol_config);
	    qmat_vop = GetVopNonintraQuantMat(curr_vop_bb);

	    for(i=0; i<64; i++)
	      qmat_vop[i] = qmat_vol[i];

	    /* disable gray quantizer update flag */
	    disable_gray_quant_update = 
	      GetVolConfigDisableGrayQuantUpdate(vol_config);
	    PutVopDisableGrayQuantUpdate(disable_gray_quant_update,
					 curr_vop_bb);

	    /* gray intra quant. matrix */
	    PutVopLoadGrayIntraQuantMat(GetVolConfigLoadGrayIntraQuantMat(vol_config),curr_vop_bb);

	    qmat_vol = GetVolConfigGrayIntraQuantMat(vol_config);
	    qmat_vop = GetVopGrayIntraQuantMat(curr_vop_bb);

	    for(i=0; i<64; i++)
	      qmat_vop[i] = qmat_vol[i];

	    /* gray nonintra quant. matrix */
	    PutVopLoadGrayNonintraQuantMat(GetVolConfigLoadGrayNonintraQuantMat(vol_config),curr_vop_bb);

	    qmat_vol = GetVolConfigGrayNonintraQuantMat(vol_config);
	    qmat_vop = GetVopGrayNonintraQuantMat(curr_vop_bb);

	    for(i=0; i<64; i++)
	      qmat_vop[i] = qmat_vol[i];

	  } /* if(GetVopQuantType(curr_vop_bb)) */

#ifndef NLSSTATS
        /* Put some text for user */
        if (GetVolConfigSpriteUsage(vol_config) == SPRITE_NOT_USED) {

     if (GetVopPredictionType(curr_vop_bb)==I_VOP) 
       fprintf(stdout,"\t\tIntra Quantizer : %d\n",GetVopIntraQuantizer(curr_vop_bb));
     else if (GetVopPredictionType(curr_vop_bb)==P_VOP)
             fprintf(stdout,"\t\tP-VOP Quantizer : %d\n",GetVopQuantizer(curr_vop_bb));
       else if (GetVopPredictionType(curr_vop_bb)==B_VOP)
             fprintf(stdout,"\t\tB-VOP Quantizer : %d\n",GetVopBQuantizer(curr_vop_bb));
 }
#endif




	/* Set remaining vop fields */
	/* GL quantizer */
	gl_quantizer = GetVolConfigGLQuant(vol_config);
	PutVopGLQuantizer(gl_quantizer,curr_vop_bb);

	/* Shape effects */
	shape_effects = GetVolConfigShapeEffects(vol_config);
	PutVopShapeEffects(shape_effects,curr_vop_bb);

        /* advanced prediction dsiable */
        obmc_disable = GetVolConfigOBMCDisable(vol_config);
        PutVopOBMCDisable(obmc_disable,curr_vop_bb);


   /*>SpSc*/
   if(vop_spat_scal)
      enable_8x8_mv = 0;
   /*SpSc<*/

	change_CR_disable = GetVolConfigChangeCRDisable(vol_config);
	PutVopChangeCRDisable(change_CR_disable,curr_vop_bb);


	/* AC/DC prediction disable */
	acdc_pred_disable = GetVolConfigACDCPredDisable(vol_config);
	PutVopIntraACDCPredDisable(acdc_pred_disable,curr_vop_bb);

	/* variable quantizer precision */
	quant_precision = GetVolConfigQuantPrecision(vol_config);
	PutVopQuantPrecision(quant_precision,curr_vop_bb);

	/* variable quantizer precision */
	bits_per_pixel = GetVolConfigBitsPerPixel(vol_config);
	PutVopBitsPerPixel(bits_per_pixel,curr_vop_bb);
      
      
	/* Error resilence disable */
	error_res_disable = GetVolConfigErrorResDisable(vol_config);
	PutVopErrorResDisable(error_res_disable,curr_vop_bb);

	/* Data Partitioning enable */
	data_partitioning = GetVolConfigDataPartEnable(vol_config);
	PutVopDataPartEnable(data_partitioning,curr_vop_bb);

	/* Reversible VLC flag */
	reversible_vlc = GetVolConfigReverseVlc(vol_config);
	PutVopReverseVlc(reversible_vlc,curr_vop_bb);

	/* SADCT disable */
	sadct_disable = GetVolConfigSADCTDisable(vol_config);
	PutVopSADCTDisable(sadct_disable,curr_vop_bb);

	/* sr_for */
	sr_for = GetVolConfigSearchRange(vol_config)*((TRB)?TRB:TRD); 
	PutVopSearchRangeFor(sr_for,curr_vop_bb);
        PutVopFCodeFor(cal_fcode(sr_for),curr_vop_bb);


	/* sr_back */
	sr_back = GetVolConfigSearchRange(vol_config)*(TRD-TRB); 
	PutVopSearchRangeBack(sr_back,curr_vop_bb);
        PutVopFCodeBack(cal_fcode(sr_back),curr_vop_bb);

    PutVopInterlaced(vol_config->interlaced, curr_vop_bb);
    PutVopTopFieldFirst(vol_config->top_field_first, curr_vop_bb);
    PutVopAlternateScan(vol_config->alternate_scan, curr_vop_bb);
    curr_vop_bb->mvfileusage = vol_config->mvfileusage;
    curr_vop_bb->mvfile = vol_config->mvfile;
    curr_vop_bb->mvlinenop = &vol_config->mvlineno;
    curr_vop_bb->mvfilename = vol_config->mvfilename;
    curr_vop_bb->sr_direct = vol_config->sr_direct;
    curr_vop_bb->vo_id = vo_id;

	/* set default value for shape_coding_type */

	if (GetVopPredictionType(curr_vop_bb) == I_VOP) 		
		PutVopShapeCodingType(0,curr_vop_bb);
	else 
		PutVopShapeCodingType(1,curr_vop_bb);

	/* under certain conditions this default is not used i.e. */

	if (  (GetVopShape(curr_vop_bb) != BINARY_SHAPE_ONLY) &&
				(!GetVopScalability(curr_vop_bb)) &&
				(!GetVopErrorResDisable(curr_vop_bb)) &&
				(GetVopShape(curr_vop_bb)) &&
				(GetVopPredictionType(curr_vop_bb) != I_VOP)
		)
		{
			if ( ((vol_config->frame-1)%GetVolConfigIntraShapePeriod(vol_config)) != 0)
				{
					PutVopShapeCodingType(1,curr_vop_bb);
				}
			else 
				PutVopShapeCodingType(0,curr_vop_bb);
		}	
  
	/* Sprite utilities */
	PutVopSpriteUsage(GetVolConfigSpriteUsage(vol_config), curr_vop_bb);
	if (GetVopSpriteUsage(curr_vop_bb) == STATIC_SPRITE)
		PutVopShapeCodingType(0,curr_vop_bb);
	PutVopBrightnessChangeFactor(1.0, curr_vop_bb);
	if (GetVolConfigSpriteUsage(vol_config) != SPRITE_NOT_USED)
		{
		PutVopSpriteHdim(GetVolConfigSpriteHdim(vol_config), curr_vop_bb);
		PutVopSpriteVdim(GetVolConfigSpriteVdim(vol_config), curr_vop_bb);
		PutVopSpriteLeftEdge(
			GetVolConfigSpriteLeftEdge(vol_config), curr_vop_bb);
		PutVopSpriteTopEdge(
			GetVolConfigSpriteTopEdge(vol_config), curr_vop_bb);
		PutVopSprite(GetVolConfigSprite(vol_config), curr_vop_bb);
		PutVopBlendFact(GetVolConfigBlendFact(vol_config), curr_vop_bb);
		PutVopNoOfSpritePoints(
			GetVolConfigNoOfSpritePoints(vol_config), curr_vop_bb);
		PutVopWarpingAccuracy(
			GetVolConfigWarpingAccuracy(vol_config), curr_vop_bb);
		PutVopBrightnessChangeInSprite(
			GetVolConfigBrightnessChangeInSprite(vol_config),curr_vop_bb);
		PutVopLowLatencySpriteEnable(
			GetVolConfigLowLatencySpriteEnable(vol_config),curr_vop_bb);

		if (GetVolConfigNoOfSpritePoints(vol_config)
			&&GetVopPredictionType(curr_vop_bb)==SPRITE_VOP) {
		  tmp_refpoint = GetVolConfigRefPointCoord(vol_config);
		  for (i=0 ; i<GetVolConfigNoOfSpritePoints(vol_config); i++)
		    {
		      tmp_refpoint[i].x = 
			GetVopHorSpatRef(curr_vop_bb)+(i%2)*GetVopWidth(curr_vop_bb);
		      tmp_refpoint[i].y = 
			GetVopVerSpatRef(curr_vop_bb)+(i>>1)*GetVopHeight(curr_vop_bb);
		    }
		  PutVopRefPointCoord(tmp_refpoint, curr_vop_bb);
		  PutVopRefPointCoord(tmp_refpoint, GetVolConfigSprite(vol_config));
		}
           }

/* SONY 070498 - start */  
  if ((GetVolConfigGOVPeriod(vol_config))
      &&((vol_config->scalability==0)
         &&((vol_config->frame - vol_config->start_frame - vol_config->frame_skip*GetVolConfigM(vol_config))%
            (vol_config->frame_skip*GetVolConfigGOVPeriod(vol_config))==0))
      &&((GetVopPredictionType(curr_vop_bb)==I_VOP)||(GetVopPredictionType(curr_vop_bb)==SPRITE_VOP)))
    {
      num_bits[vo_id][vol_id].syntax +=
        BitstreamPutGOV(curr_vop_bb,vo_id,time,TRD,vol_config);
    }
/* SONY 070498 - end */
  
	/* Don't attempt to code empty VOPs */
	if(vop_has_content)
		{
	  	/* Set up reconstructed vop */
	  	rec_curr = SetUpRecVop(curr_vop_bb);
	
	  	/*unrestricted_motion_mode = GetVopConfigUnrestrictedMotionMode(vop_cfg);*/

	  	/* Set to DEFAULT for time being */
	  	  unrestricted_motion_mode = 1;	

		/* Set alpha coding threshold */
		if (RCQ2_MVO_CHECK() >= RCQ2_MVO_ENABLED) {
		  if(vo_id==0) {
		    RCQ2_MVO_ShapeControl(vol_config);
		    alpha_th = GetVolConfigAlphaTh(vol_config);
		    rc_mvo.alphath = alpha_th;		    
		  }
		  else 
		    alpha_th = rc_mvo.alphath;
		}
		else
		  alpha_th = GetVolConfigAlphaTh(vol_config); 


		/* Set RateControl type -> now passed as parameter! */
		/* rc_type = GetVolConfigRateControl(vol_config);*/

		/* Code the image data (YUVa) of the vop */
/* TPS */



  	       VopCode(curr_vop_bb,
		       prev_vop,
		       prev_rec_vop,
		       next_vop,
		       next_rec_vop,
		       vo_id,
		       vol_id,
		       vo_config_list, /* UPM Global RC */
		       alpha_th,
		       obmc_disable,
		       unrestricted_motion_mode,
		       enable_8x8_mv,
		       rc_type,
		       rc_algorithm,  /* hjlee */
		       time,
		       vol_config, TRB, TRD,
		       rec_curr,
		       num_bits,
		       no_padding_vop,
		       temporal_scalability);

      		}
/*** 10/27 TPS */
	else{
            if(temporal_scalability == 2 &&
               !GetVopScalability(curr_vop_bb) &&
               vop_has_content == 0){
                static Int prev_type = -1;
                if(prev_type == -1 || prev_type == B_VOP)
                    PutVopPredictionType(P_VOP,curr_vop_bb);
                else if (prev_type == P_VOP)
                    PutVopPredictionType(B_VOP,curr_vop_bb);
      
                prev_type = GetVopPredictionType(curr_vop_bb);
                fprintf(stderr,"PredictionType = %d\n",prev_type);

                if(!(prev_type == -1 || prev_type == B_VOP || prev_type == P_VOP)){
                    fprintf(stderr,"-Error- PredictionType = %d\n",prev_type);
                    exit(-1);
                }
            }
	    
	    if((temporal_scalability == 2 || temporal_scalability == 5) &&
               GetVolConfigScalability(vol_config)==1 &&
	       GetVopPredictionType(prev_rec_vop)!=B_VOP)
		 modulo_tps = 1;
	    
	    num_bits[vo_id][vol_id].syntax +=
		BitstreamPutVopHeader(curr_vop_bb,vo_id,time,TRB,vol_config,
				      num_bits,vo_config_list, rc_type,
                                      modulo_tps);
        }
/* 10/27 TPS ***/

return(rec_curr);
}

/***********************************************************CommentBegin******
 *
 * -- VopCode -- Shape, texture and motion coding of the vop
 *
 * Author :
 * Noel O'Connor Teltec Irl.
 *
 * Created :
 * 11-03-96
 *
 * Purpose :
 * This function performs shape, texture and motion coding of the
 * vop passed to it. The input vop is assumed to be BOUNDED.
 * 
 * Arguments in : 
 * Vop *curr - pointer to vop to be coded
 * Vop *prev - pointer the last occurence of this vop
 * Vop *rec_prev - pointer to last coded occurence of this vop
 * Int vol_id - id of VOL to which this VOP belongs
 * Int alpha_th - shape coding threshold
 * Int obmc_disable - advanced motion mode flag
 * Int unrestricted_motion - unrestricted motion mode flag
 * Int enable_8x8_mv - 8x8 motion vectors flag (SpSc)
 * Int intra_dcpred_disable - disable intradc prediction
 * Int vo_id - current VO_ID
 * Int rc_type - rate control type
 * Float time -
 * VolConfig *vol_config -
 *
 * Arguments in/out :
 * Vop *rec_curr - coded vop
 * Bitcount num_bits[] - array of BitCount structures (one for
 *  each VOL).
 *
 * Arguments out :
 * -
 *
 * Return values :
 * none
 *
 * Side effects :
 * -
 *
 * Description :
 * -
 *
 * See also :
 * file "README_ALPHA"
 *
 * Modified :
 * 28.08.96 Noel O'Connor: added vol_id argument
 * 04.09.96 Cor Quist: added intra_dcpred_disable
 * 05.09.96 Jan De Lameillieure (HHI): inter shape coding
 * 23.09.96 Noel O'Connor: Some changes to allow coding of multiple VOs
 * 23.10.96 Robert Danielsen: Removed intra_dcpred_disable, get it from
 *          Vop-structure directly instead.
 * 23.10.96 Aasmund.Sandvand@fou.telenor.no: Modified to support deblock
 *          filtering
 * 06.11.96 Jan De Lameillieure: removed clamping after motion
 *          compensated prediction of alpha plane (obsolete since VM4.0)
 * 28.01.97 Robert Danielsen: Added freeing of comp. Bugfix from
 *          Noel O'Connor.
 * 04.02.97 Noel O'Connor: mods for non unique VOL Ids
 * 07.02.97 J. Ignacio Ronda: rc_type, time and vol_config input parameters
 *          added. Modification to allow VM5 rate control.
 *          BitstreamPutVopHeader() with updated quantizer in case of VM5
 *          rate control.
 * 11.03.97 Minhua Zhou: added B-VOPs
 * 21.04.97 Jan De Lameillieure : called grey level alpha coding with the 
 *          grey level (GL) quantiser
 * 26.04.97 Luis Ducla-Soares: added the error resilient combined mode with
 *          data partitioning.
 * 06.05.97 Noel Brady: Modified calls to VopShapeCode() for CAE.
 * 15.05.97 Luis Ducla-Soares: corrected the remultiplexing of DCT data in
 *          the combined error resilient mode with data partitioning.
 * 07.07.97 Martina Eckert: Introduction of global rate control 
 *          functions and parameters
 * 31.07.97 Fernando Jaureguizar: added GetVopScalability() (SpSc)
 * 01.08.97 Fernando Jaureguizar: added enable_8x8_mv parameter (SpSc)
 *          Changed in MotionEstimation() call its obmc_disable
 *          input parameter by enable_8x8_mv.
 * 06.08.97 Noel Brady: added mods for BINARY_SHAPE_ONLY
 * 08.09.97 Cecile Dufour: added arguments in VOPHeader for STATIC Sprite
 * 14.10.97 Noel Brady: ChangeMBType is not called when the decoded VOP is 
 *											a B-VOP
 * 14.10.97 Noel Brady: shape MC for B-VOPs uses the most recently decoded 
 *											I/P VOP i.e. the backward reference.
 * 19.11.97 Noel Brady: Several changes to do with error resilient shape
 * 27.11.97 M. Eckert: Changes for independent frame rate type control
 * 11.12.97 Bob Eifrig: Modifications for interlaced video coding
 * 13.01.97 Noel Brady: support for error resileint shape coding in B-VOPs
 * 27.01.98 M. Eckert and F. Jaureguizar: Updated the VopCodeTextInter()
 *          and RC_QuantAdjust() calls.
 *          Deleted PutVolConfig*Quantizer() and PutVop*Quantizer() calls
 *          because now they are called inside RC_QuantAdjust().
 * 27.03.98 M.Wollborn: Modified due to N2171 Cl. 2.5.3 intra_dc_vlc_thr
 *
 ***********************************************************CommentEnd********/
/* TPS */
Void VopCode(Vop *curr, 
	     Vop *prev, 
	     Vop *rec_prev,
             Vop *next_vop,
             Vop *next_rec_vop, 
	     Int vo_id, 
	     Int vol_id,
             VOConfig *vo_config_list, /* UPM Global RC */
	     Int alpha_th,
	     Int obmc_disable,
	     Int unrestricted_motion,
	     Int enable_8x8_mv, /*SpSc*/
	     Int rc_type,
	     Int rc_algorithm, /* hjlee */
	     Float time,
	     VolConfig *vol_config, Int TRB, Int TRD,
	     Vop *rec_curr,
	     BitCount num_bits[MAX_NUM_VOS][MAX_NUM_VOLS],
	     Vop *no_padding_vop,
	     Int temporal_scalability)
/**/
{
  Vop *ref_vop;
  
  Image		*first_shape_code_bitstream,
		*shape_bitstream, 		/* Intermediate integer level  	 */
		*gray_shape_bitstream,
		*texture_bitstream,	 	/* bitstream data structures  	 */
		*motion_bitstream,		/* for shape, motion and texture  */
		*mottext_bitstream,
		*motion_comb_bitstream,
		*text_header_comb_bitstream,
		*text_data_comb_bitstream,
		*comb_bitstream,
		*aux_bitstream;

  ImageF	*mot_x, *mot_y;

  static ImageF *mot_x_P[MAX_NUM_VOS][MAX_NUM_VOLS], 
		*mot_y_P[MAX_NUM_VOS][MAX_NUM_VOLS];

  Image		**Shape_stream, **First_stream;

  static Image	*MB_decisions_P[MAX_NUM_VOS][MAX_NUM_VOLS];

  Image		*MB_decisions=NULL, *alpha_decisions=NULL,
		*alpha_sub_pad=NULL;
	
  Image		*GreyLevelAlpha=NULL;
  Image		*MotionCompensatedGreyLevelAlpha=NULL;
  Image		*ReconstructedGreyLevelAlpha=NULL;

  Int		edge,f_code_for=1,f_code_back=1;

  Int		shape_bits=0;

  Vop		*comp = NULL, 
		*error_vop=NULL, 
		*rec_error;	/* will store motion compensated alpha plane */

  Int		num_pixels = GetVopWidth(curr);
  Int		num_lines = GetVopHeight(curr);
  Int		MB_width = num_pixels / 16;
  Int		MB_height = num_lines /16;
  Int		i,j,k,i_next,j_next;
  Int		vop_quantizer;

  /*  for error resilience */
  Int           num_bits_MB, num_bits_packet;
  
  /* Modified due to N2171 Cl. 2.5.3 MW 28-MAR-1998 */
  /* Int           index,time_modulo; */
  /* Int           bits; */
  /* Float         time_inc; */

  Int           first_marker, after_marker;
  Int           ***DC_store = NULL;
  Int           **slice_nb = NULL;
  Int           slice_counter;
  Int           resync_marker_length;
  Int           f_code_max;

  /* for sprite */
  Vop           *rec_sprite=NULL;
  Sprite_motion	*warp_param=NULL, *prev_warp_param=NULL;
  TrajPoint	*traj=NULL, *qtraj=NULL, *difftraj=NULL;
  Int		warp_param_counter;
  Int		flag_static_sprite_piece=0;

  Float mad =0;

  Int MB_in_VOP = MB_width * MB_height;    /* number of MBs in one vop;
					      only used in error resilient mode */
  Int vop_spat_scal=0;
	
/*** 10/27 TPS */
  Int  modulo_tps     = 0;
  Int vop_temp_scal   = 0;
  Int ref_vol_id      = GetVolConfigRefId( vol_config );
/* 10/27 TPS ***/

  /*necessary bits needed to code the MB number */
  Int MB_in_VOP_length = (Int) ceil(log(MB_in_VOP)/log(2)); 

  UInt  num_pels_vop; /* UPM Global RC - Number of pixels of current VOP */        
	Int start_of_packet;
	Int first_bits;

  UChar first_stream[7], shape_stream[4096];
  Image *pi=0,*modeA=0,*motA_x=0,*motA_y=0;
  Int RESYNC_MARKER_SPACING = GetVolConfigPacketSize(vol_config);

  /*
   * Sorry for diverging, but the code is too much of a mess to
   * to modify on the short amount of time available.
   *
   *                                 Bob Eifrig (11-nov-97)
   */
  if (GetVopInterlaced(curr) &&
      (GetVopPredictionType(curr)==B_VOP)) 
    {
      EncodeInterlacedBVOP(vol_config,
			   curr, rec_curr,
			   prev, rec_prev,
			   next_vop, next_rec_vop,
			   mot_x_P[vo_id][vol_id],
			   mot_y_P[vo_id][vol_id],
			   MB_decisions_P[vo_id][vol_id],
			   &num_bits[vo_id][vol_id],
			   rc_type,
			   time);
      return;
    }

  /* set the flag_static_sprite */
  if (GetVopPredictionType(curr)==SPRITE_PIECE || 
      GetVopPredictionType(curr)==SPRITE_UPDATE) 
    {
      flag_static_sprite_piece = 1;
      if (GetVopPredictionType(curr)==SPRITE_PIECE)
	{
	  PutVopPredictionType(I_VOP, curr);
	  PutVopPredictionType(I_VOP, rec_curr);
	}
      else
	{
	  PutVopPredictionType(P_VOP, curr);
	  PutVopPredictionType(P_VOP, rec_curr);
	}
    }
   
  /* Getting the VOP ScalType, for spat scal (UPS)*/
  /*** 10/27 TPS */
  if((temporal_scalability == 2 || temporal_scalability == 5) &&
     GetVolConfigScalability(vol_config)==1 &&
     GetVopPredictionType(rec_prev)!=B_VOP)
    {
      modulo_tps = 1;
    }

  if(GetVopScalability(curr) ==1){ 
    /*SpSc*/
    if (( GetVopPredictionType(curr)==P_VOP 
	  && GetVopRefSelCode(curr) ==3)
	|| ( GetVopPredictionType(curr)==B_VOP 
	     && GetVopRefSelCode(curr) ==0))
      {
	vop_spat_scal=1;
      }
    /* TPS */
    else if(GetVopPredictionType(curr)==P_VOP &&
	    (GetVopRefSelCode(curr) == 0 ||
	     GetVopRefSelCode(curr) == 1 ||
	     GetVopRefSelCode(curr) == 2)        )
      {
	vop_temp_scal = 3;       /* P_VOP        : TPS */    
      }
    else if(GetVopPredictionType(curr) == B_VOP)
      {
	if(GetVopRefSelCode(curr) == 3)
	  vop_temp_scal = 1;   /* B_VOP_TYPE_1 : TPS */    
        else if(GetVopRefSelCode(curr) == 1)
	  vop_temp_scal = 2;   /* B_VOP_TYPE_2 : TPS */    
      }
    
    if(!vop_spat_scal && GetVopPredictionType(curr) != I_VOP &&
       temporal_scalability != vop_temp_scal)
    if(!((temporal_scalability == 4 || temporal_scalability == 5) &&
	 vop_temp_scal == 3))
      {
        fprintf(stderr,"\n-ERROR- tps_mode is right[%d] : wrong[%d]\n",
		temporal_scalability,
		vop_temp_scal);
	exit(-1);
      }
  }
  /* 10/27 TPS ***/

  
  /* Initialise the integer level intermediate bitstreams */
  first_shape_code_bitstream = BitstreamInit();
  shape_bitstream = BitstreamInit();
  gray_shape_bitstream = BitstreamInit();
  texture_bitstream = BitstreamInit();
  motion_bitstream = BitstreamInit();
  mottext_bitstream = BitstreamInit();

  /* Allocate shape stream */
  First_stream = (Image **)calloc((GetVopWidth(curr)/MB_SIZE)*
				  (GetVopHeight(curr)/MB_SIZE), sizeof(Image *));
  Shape_stream = (Image **)calloc((GetVopWidth(curr)/MB_SIZE)*
				  (GetVopHeight(curr)/MB_SIZE), sizeof(Image *));

  for(i=0; i<(GetVopWidth(curr)/MB_SIZE)*(GetVopHeight(curr)/MB_SIZE); i++) 
    {
      First_stream[i] = BitstreamInit();
      Shape_stream[i] = BitstreamInit();
    }
  
  if (GetVopShape(curr) == GREY_SCALE)
    {
      GreyLevelAlpha = AllocImage(GetImageSizeX(curr->a_chan),
				  GetImageSizeY(curr->a_chan),SHORT_TYPE);
      CopyImage(curr->a_chan,GreyLevelAlpha);
      ObtainSupport(curr->a_chan);
      ReconstructedGreyLevelAlpha = AllocImage(GetImageSizeX(curr->a_chan),
					       GetImageSizeY(curr->a_chan),SHORT_TYPE);
    }
  
  /* Left in for the software, flag is no longer in syntax however */
  /* due to N2171. MW 27-MAR-1998				   */
  if (GetVopErrorResDisable(curr) != NON_ERROR_RESILIENT)
    {
      DC_store = (Int ***)calloc(MB_width*MB_height,sizeof(Int **));
      for (i = 0; i < MB_width*MB_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));
	}
      
      slice_nb = (Int **)calloc(MB_width,sizeof(Int *));
      for (i = 0; i < MB_width; i++)
        slice_nb[i] = (Int *)calloc(MB_height, sizeof(Int));
    }

  if (GetVopPredictionType(curr) == SPRITE_VOP)
    {
      /* GET THE WARPING PARAMETERS */
      if (GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE)
	{
	  warp_param_counter =
	    GetVolConfigWarpParamCounter(vol_config);
	  warp_param = ReadWarpingParameters(
	    GetVolConfigNoOfSpritePoints(vol_config),
	    warp_param_counter,
	    GetVolConfigWarpParamFile(vol_config));
	  warp_param_counter++;
	  PutVolConfigWarpParamCounter(warp_param_counter,vol_config);
	}/* CASE STATIC SPRITE */
#ifndef _WD_MODE_
      else
	{
	  prev_warp_param = GetVolConfigPrevWarpParam(vol_config);
	  warp_param = GlobalMotionEstimation(prev, curr,
					      prev_warp_param,
					      GetVolConfigNoOfSpritePoints(vol_config));
	}
#endif
      
      /* produce trajectories and quant the motion param.*/
      /* compute trajectories from global motion */
      if (GetVolConfigNoOfSpritePoints(vol_config))
	{
	  traj = MakeTrajectories(warp_param,
				  GetVolConfigNoOfSpritePoints(vol_config),
				  GetVolConfigRefPointCoord(vol_config));
	  PutVopTrajPointCoord(traj,GetVolConfigSprite(vol_config));
	  difftraj = MakeDiffTraj(GetVolConfigNoOfSpritePoints(vol_config), traj);
	  PutVopDiffTrajPointCoord(difftraj,curr);
	  
	  /* recompute global motion from trajectories */
	  qtraj = AddTraj( GetVolConfigNoOfSpritePoints(vol_config),difftraj);
	  PutVopTrajPointCoord(qtraj,curr);
	  PutVopTrajPointCoord(qtraj,rec_curr);
	}
      
      printf("\t\t param = %.4f   %.4f   %.4f \n \t\t\t %.4f   %.4f   %.4f\n \t\t\t %.8f   %.8f\n",
	     warp_param->a1,
	     warp_param->a2,
	     warp_param->a3,
	     warp_param->a4,
	     warp_param->a5,
	     warp_param->a6,
	     warp_param->a7,
	     warp_param->a8);
      
      PutVopWarpParam(warp_param, curr);
      PutVopWarpParam(warp_param, rec_curr);
      
    } /* CASE SPRITE_VOP */
  
  /* Decide what coding (INTRA/INTER) to perform on vop */
  if (GetVopPredictionType(curr) == I_VOP)  /* I-VOP, SPRITE PIECES */					/* I-VOP */
    {
      if (GetVopPredictionType(curr) == I_VOP && flag_static_sprite_piece!=1)
	{
	  /* RC-BIP: Independent rate control also for I-frames: */
	  if (RCQ2_MVO_CHECK() == RCQ2_MVO_HVS) 
	    SetFirstIntraQP(curr, vol_config, vo_id, vol_id);

	  if (rc_type == VM5_RATE_CONTROL)
	    {
	      if (prev != NULL) /* 1. frame */
	        mad = DSRC_compute_MAD(curr, &num_pels_vop); 
	      else
		{
		  mad = 1; /* dummy, not used for first call of RC_QuantAdjust */
		  num_pels_vop = GetVopWidth(curr) * GetVopHeight(curr);
		}

	      if (RCQ2_MVO_CHECK() >= RCQ2_MVO_ENABLED)  
	        ;
	      else 
		{
		  vop_quantizer = RC_QuantAdjust(vo_id, 
						 vol_id, 
						 vo_config_list, 
						 vol_config, 
						 (Double)mad, 
						 curr, 
						 error_vop, 
						 num_pels_vop,
						 GetVopPredictionType(curr));
		  
		  fprintf(stdout,"\t\tIntra Quantizer : %d\n", 
			  (int)vop_quantizer);
		}
	    }
	  
	  /* Write Vop Header bitstream to disk */
	  if (GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE) 
	    /* case of the first Sprite piece in VOL header */
	    num_bits[vo_id][vol_id].sprite_piece +=
	      BitstreamPutVopHeader(curr,vo_id,time,TRB,vol_config,
				    num_bits,vo_config_list, rc_type, 
				    modulo_tps);
	  else
	    num_bits[vo_id][vol_id].syntax +=
	      BitstreamPutVopHeader(curr,vo_id,time,TRB,vol_config,
				    num_bits,vo_config_list, rc_type, 
				    modulo_tps);
	}

      /* Put some text for user */
      if (GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE)
        if (GetVolConfigLowLatencySpriteEnable(vol_config))
          fprintf(stdout,"\tI_VOP encoding of object-piece (low latency static sprite syntax)\n");
	else
          fprintf(stdout,"\tI_VOP encoding of the basic sprite \n");

      /* for TPS and ssp */
      if ( GetVopScalability( curr ) ) 
        WriteBGCAlphaBitstream( curr , vo_id , vol_id , num_bits , back_base_exist );
      /**/
      
      /* only code shape if it is necessary */
      if ((GetVopShape(curr) == BINARY) || (GetVopShape(curr) == GREY_SCALE)
	  || (GetVopShape(curr) == BINARY_SHAPE_ONLY) )  /* BSO_NOEL */
	{
	  if (GetVopErrorResDisable(curr) == NON_ERROR_RESILIENT)
	    {
	      /* Put some text for user */
	      fprintf(stdout,"\t\tPerforming shape coding\n");
	      
	      ce_bits_for_shape[vol_id] = ce_bits_for_vop = 
		ce_coded_frames[vol_id] = 0;
	      

	      /* Code shape */
	      shape_bits = VopShapeCode(curr,
					rec_curr,
					(Vop *)NULL,
					vo_id,
					alpha_th,
					(Image *)NULL,
					(Image *)NULL,
					(Image *)NULL,
					(Image *)NULL,
					First_stream,
					Shape_stream
					);
	    }
	  else 
	    {
	      CopyImage(GetVopA(curr), GetVopA(rec_curr));
	    }
	  
	  SubsampleAlphaMap(GetVopA(rec_curr),GetVopAuv(rec_curr),
			    GetVopShape(rec_curr));
	  SubsampleAlphaMap(GetVopA(curr),GetVopAuv(curr),GetVopShape(curr));
	}
      else				/* RECTANGULAR SHAPE */
	{
	  /* Put some text for user */
	  fprintf(stdout,"\t\tNo shape coding required\n");

	  /* Must fill rec_curr alpha field */
	  CopyImage(GetVopA(curr),GetVopA(rec_curr)); 
          SetConstantImage(GetVopAuv(curr),255);
          SetConstantImage(GetVopAuv(rec_curr),255);
	}
		
      /* Put some text for user */
      fprintf(stdout,"\t\tCoding INTRA texture \n\n");
	
      /* The error-resilience-disable flag is no longer present in  */
      /* the syntax due to N2171 Cl. 2.5.14. However, the flag is   */
      /* still used in the encoder software to disable all error-   */
      /* resilience tools with one parameter and to use the part of */
      /* the software which is especially implemented for not using */
      /* error resilience tools.                                    */
      /*							    */
      /* The part of the software for the error-resilient encoding  */
      /* has not been used here, since there each time a video-     */
      /* packet header incl. header extension is sent, what is not  */
      /* necessarily required in non-error-resilient mode.          */
      /*							    */
      /* MW, 27-MAR-1998					    */

      if (GetVopErrorResDisable(curr) == NON_ERROR_RESILIENT)       /* non error resilient mode */
	{
	  /* Code Texture in Intra mode */
	  /* combined motion/texture mode */
	  VopCodeShapeTextIntraCom(curr,
				   First_stream,
				   Shape_stream,
				   GreyLevelAlpha,
				   MotionCompensatedGreyLevelAlpha,
				   ReconstructedGreyLevelAlpha,
				   rec_curr,
				   texture_bitstream,
				   &num_bits[vo_id][vol_id].text_bits,
				   rc_type,
				   vo_id,
				   vol_config);
	  
#ifndef _WD_MODE_
	  if (GetVolConfigSpriteUsage(vol_config) == ONLINE_SPRITE) 
	    {
	      InitOnLineSprite(GetVolConfigSprite(vol_config),rec_curr);
	      InitOnLineSpriteChroma(GetVolConfigSprite(vol_config),rec_curr); 
	      if (GetVolConfigWriteSprite(vol_config))
	        WriteVopGeneric(GetVolConfigSprite(vol_config),
				GetVolConfigSpriteY(vol_config),
				GetVolConfigSpriteU(vol_config),
				GetVolConfigSpriteV(vol_config),
				GetVolConfigSpriteA(vol_config),
				0,IO_FORMAT,IO_OVERWRITE,1);
	    }
#endif
				
	  if (GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE)
	    {
	      num_bits[vo_id][vol_id].sprite_piece += 
		BitstreamPut(first_shape_code_bitstream,vo_id,vol_id);
	      num_bits[vo_id][vol_id].sprite_piece += 
		BitstreamPut(shape_bitstream,vo_id,vol_id);
	      num_bits[vo_id][vol_id].sprite_piece += 
		BitstreamPut(gray_shape_bitstream,vo_id,vol_id);
	      num_bits[vo_id][vol_id].sprite_piece += 
		BitstreamPut(texture_bitstream,vo_id,vol_id);
	    }
	  else
	    {	  
	      /* Write shape bitstream to disk */
	      num_bits[vo_id][vol_id].shape +=
		BitstreamPut(first_shape_code_bitstream,vo_id,vol_id); 
	      num_bits[vo_id][vol_id].shape +=
		BitstreamPut(shape_bitstream,vo_id,vol_id); 
	      num_bits[vo_id][vol_id].shape +=
		BitstreamPut(gray_shape_bitstream,vo_id,vol_id);
	      
	      /* Write texture bitstream to disk */
	      num_bits[vo_id][vol_id].texture +=
		BitstreamPut(texture_bitstream,vo_id,vol_id);
	    } 
	  
	}   /* End non error resilient mode */
      else
	{      /* error resilient mode  */
	  resync_marker_length = 17;
	  
	  if (GetVopShape(curr)) AllocShapePacket(curr);
	  
	  /* Code Texture in Intra mode */
	  
	  /* Data partitioning */
	  if (GetVopDataPartEnable(curr) 
	      && (GetVopShape(curr) != BINARY_SHAPE_ONLY))
	    {
	      slice_counter = 0;
	      num_bits_packet = 0;
	      first_marker = 1;
	      motion_comb_bitstream = BitstreamInit();
	      text_header_comb_bitstream = BitstreamInit();
	      text_data_comb_bitstream = BitstreamInit();
	      k=0;
	      start_of_packet = 1;
	      
	      for (j = 0; j < num_lines/MB_SIZE; j++)
		{
		  for (i = 0; i < num_pixels/MB_SIZE; i++)
		    {
		      slice_nb[i][j] = slice_counter;
		      
		      if ((GetVopShape(curr) == BINARY) || (GetVopShape(curr) == GREY_SCALE)
			  || (GetVopShape(curr) == BINARY_SHAPE_ONLY) ) 			  
			{
			  shape_bits = ShapeCodeMB(curr,
						   rec_curr,
						   NULL,
						   vo_id,
						   j,
						   i,
						   alpha_th,
						   NULL,
						   NULL,
						   NULL,
						   NULL,
						   NULL,
						   NULL,
						   NULL,
						   &first_bits,
						   first_stream,
						   shape_stream,
						   start_of_packet
						   );
			  start_of_packet = 0;
			  BitstreamAppendTtoM(First_stream[k], first_stream, 
					      first_bits);
			  BitstreamAppendTtoM(Shape_stream[k], shape_stream, 
					      shape_bits);
			  k++;
			  total_shape_bits += shape_bits + first_bits;
			}
		      
		      /* combined motion/texture mode */
		      MBCodeShapeTextIntraComErrRes(curr,
						    First_stream,
						    Shape_stream,
						    GreyLevelAlpha,
						    MotionCompensatedGreyLevelAlpha,
						    ReconstructedGreyLevelAlpha,
						    rec_curr,
						    motion_comb_bitstream,
						    text_header_comb_bitstream,
						    text_data_comb_bitstream,
						    i, j, &num_bits_MB,
						    DC_store, slice_nb,
						    &num_bits[vo_id][vol_id].text_bits);
		      
		      num_bits_packet += num_bits_MB;
		      if ((num_bits_packet >= RESYNC_MARKER_SPACING)
			  && ((j*MB_width+i) < (MB_height*MB_width-1)))
			{
			  start_of_packet = 1;
			  
			  num_bits[vo_id][vol_id].mot_shape_text += 
			    BitstreamPut(motion_comb_bitstream,vo_id,vol_id);
			  BitstreamFree(motion_comb_bitstream);
			      
			  aux_bitstream = BitstreamInit();
			  BitstreamPutBits(aux_bitstream,DC_MARKER,DC_MARKER_LENGTH);

			  num_bits[vo_id][vol_id].syntax += 
			    BitstreamPut(aux_bitstream,vo_id,vol_id);
			  BitstreamFree(aux_bitstream);
			      
			  num_bits[vo_id][vol_id].mot_shape_text += 
			    BitstreamPut(text_header_comb_bitstream,vo_id,vol_id);
			  BitstreamFree(text_header_comb_bitstream);
			  
			  num_bits[vo_id][vol_id].mot_shape_text += 
			    BitstreamPut(text_data_comb_bitstream,vo_id,vol_id);
			  BitstreamFree(text_data_comb_bitstream);
			      
			  aux_bitstream = BitstreamInit();
			  BitstreamPutBits(aux_bitstream,RESYNC_MARKER,resync_marker_length);
			  BitstreamPutBits(aux_bitstream,j*MB_width+i+1,MB_in_VOP_length);
			  
			  if (GetVopShape(curr) != BINARY_SHAPE_ONLY)
			    BitstreamPutBits(aux_bitstream,GetVopIntraQuantizer(curr),
					     GetVopQuantPrecision(curr));
			      
			  if (first_marker)
			    {
			      first_marker = 0;
			      /* Write the HEC-flag and then the HEC itself */
			      BitstreamPutBits(aux_bitstream,1,1);
			      BitstreamPutHEC(vol_config, curr, time, aux_bitstream);

#if 0 /* Replaced by subroutine, MW 27-MAR-1998 */
			      index = GetVolConfigModTimeBase(vol_config,0);
			      time_modulo = time - index*1000;
			      while(time_modulo >= 1000)
				{
				  BitstreamPutBits(aux_bitstream,1,1);
				  time_modulo = time_modulo - 1000;
				  index++;
				}
			      BitstreamPutBits(aux_bitstream,0,1);

			      time_inc = (time - index*1000);
			      bits = ceil(log((double)GetVopTimeIncrementResolution(curr))/log(2.0));
			      if (bits<1) 
			        bits=1;
			      time_inc=time_inc*(double)GetVopTimeIncrementResolution(curr)/1000.0;
			      BitstreamPutBits(aux_bitstream,1,1); /* marker bit */
			      BitstreamPutBits(aux_bitstream,(Int)(time_inc+0.001),bits);
			      BitstreamPutBits(aux_bitstream,1,1); /* marker bit */
			      BitstreamPutBits(aux_bitstream,GetVopPredictionType(curr),2);
#endif

			    }
			  else
			    {  
			      BitstreamPutBits(aux_bitstream,0,1);
			    }

			  NextResyncMarker(vo_id,vol_id);
			  num_bits[vo_id][vol_id].syntax += 
			    BitstreamPut(aux_bitstream,vo_id,vol_id);
			  BitstreamFree(aux_bitstream);
			  
			  motion_comb_bitstream = BitstreamInit();
			  text_header_comb_bitstream = BitstreamInit();
			  text_data_comb_bitstream = BitstreamInit();
			  
			  num_bits_packet = 0;
			  slice_counter++;
			}
		    }
		}
	      
	      num_bits[vo_id][vol_id].mot_shape_text += 
		BitstreamPut(motion_comb_bitstream,vo_id,vol_id);
	      BitstreamFree(motion_comb_bitstream);
		  
	      aux_bitstream = BitstreamInit();
	      BitstreamPutBits(aux_bitstream,DC_MARKER,DC_MARKER_LENGTH);
	      num_bits[vo_id][vol_id].syntax += 
		BitstreamPut(aux_bitstream,vo_id,vol_id);
	      BitstreamFree(aux_bitstream);
		  
	      num_bits[vo_id][vol_id].mot_shape_text += 
		BitstreamPut(text_header_comb_bitstream,vo_id,vol_id);
	      BitstreamFree(text_header_comb_bitstream);
		
	      num_bits[vo_id][vol_id].mot_shape_text += 
		BitstreamPut(text_data_comb_bitstream,vo_id,vol_id);
	      BitstreamFree(text_data_comb_bitstream);
	    }
	  else /* No Data Partitioning */
	    {
	      slice_counter = 0;
	      num_bits_packet = 0;
	      start_of_packet = 1;
	      first_marker = 1;
	      comb_bitstream = BitstreamInit();
	      k=0;
		  
	      for (j = 0; j < num_lines/MB_SIZE; j++)
		{
		  for (i = 0; i < num_pixels/MB_SIZE; i++)
		    {
		      slice_nb[i][j] = slice_counter;
		      
		      if ((GetVopShape(curr) == BINARY) || (GetVopShape(curr) == GREY_SCALE)
			  || (GetVopShape(curr) == BINARY_SHAPE_ONLY) ) 			  
			{
			  shape_bits = ShapeCodeMB(curr,
						   rec_curr,
						   NULL,
						   vo_id,
						   j, 
						   i,
						   alpha_th,
						   NULL,
						   NULL,
						   NULL,
						   NULL,
						   NULL,
						   NULL,
						   NULL,
						   &first_bits,
						   first_stream,
						   shape_stream,
						   start_of_packet
						   );
			  start_of_packet = 0;
			  BitstreamAppendTtoM(First_stream[k], first_stream, 
					      first_bits);
			  BitstreamAppendTtoM(Shape_stream[k], shape_stream, 
					      shape_bits);
			  k++;
			  total_shape_bits += shape_bits + first_bits;
			}
		      
		      /* combined motion/texture mode */
		      MBCodeShapeTextIntraComErrRes(curr,
						    First_stream,
						    Shape_stream,
						    GreyLevelAlpha,
						    MotionCompensatedGreyLevelAlpha,
						    ReconstructedGreyLevelAlpha,
						    rec_curr,
						    comb_bitstream,
						    comb_bitstream,
						    comb_bitstream,
						    i, j, &num_bits_MB,
						    DC_store,slice_nb,
						    &num_bits[vo_id][vol_id].text_bits);
		      
		      num_bits_packet += num_bits_MB;
		      if ((num_bits_packet >= RESYNC_MARKER_SPACING)
			  && ((j*MB_width+i) < (MB_height*MB_width-1)))
			{
			  start_of_packet = 1;
			  num_bits[vo_id][vol_id].mot_shape_text 
			    += BitstreamPut(comb_bitstream,vo_id,vol_id);
			  BitstreamFree(comb_bitstream);
			  
			  aux_bitstream = BitstreamInit();
			  BitstreamPutBits(aux_bitstream,RESYNC_MARKER,resync_marker_length);
			  BitstreamPutBits(aux_bitstream,j*MB_width+i+1,MB_in_VOP_length);
			  
			  if (GetVopShape(curr) != BINARY_SHAPE_ONLY)
			    BitstreamPutBits(aux_bitstream,GetVopIntraQuantizer(curr),
					     GetVopQuantPrecision(curr));
			  
			  if (first_marker)
			    {
			      first_marker = 0;
			      /* Write the HEC-flag and then the HEC itself */
			      BitstreamPutBits(aux_bitstream,1,1);
			      BitstreamPutHEC(vol_config, curr, time, aux_bitstream);

#if 0 /* Replaced by subroutine, MW 27-MAR-1998 */
			      index = GetVolConfigModTimeBase(vol_config,0);
			      time_modulo = time - index*1000;
			      while(time_modulo >= 1000)
				{
				  BitstreamPutBits(aux_bitstream,1,1);
				  time_modulo = time_modulo - 1000;
				  index++;
				}
			      BitstreamPutBits(aux_bitstream,0,1);
			      
			      time_inc = (time - index*1000);
			      bits = ceil(log((double)GetVopTimeIncrementResolution(curr))/log(2.0));
			      if (bits<1) 
			        bits=1;
			      time_inc=time_inc*(double)GetVopTimeIncrementResolution(curr)/1000.0;
			      BitstreamPutBits(aux_bitstream,1,1); /* marker bit */
			      BitstreamPutBits(aux_bitstream,(Int)(time_inc+0.001),bits);
			      BitstreamPutBits(aux_bitstream,1,1); /* marker bit */
			      BitstreamPutBits(aux_bitstream,GetVopPredictionType(curr),2);
#endif

			    }
			  else
			    {  
			      BitstreamPutBits(aux_bitstream,0,1);
			    }
			  
			  NextResyncMarker(vo_id,vol_id);
			  num_bits[vo_id][vol_id].syntax += 
			    BitstreamPut(aux_bitstream,vo_id,vol_id);
			  BitstreamFree(aux_bitstream);
			  
			  comb_bitstream = BitstreamInit();
			  
			  num_bits_packet = 0;
			  slice_counter++;
			}
		    }
		}
	      
	      num_bits[vo_id][vol_id].mot_shape_text 
		+= BitstreamPut(comb_bitstream,vo_id,vol_id);
	      BitstreamFree(comb_bitstream);
	    }
	  FreeShapePacket();
	  
	  printf("Shape-bits = %d\n",total_shape_bits);
	  
#ifndef _WD_MODE_
	  if (GetVolConfigSpriteUsage(vol_config) == ONLINE_SPRITE) 
	    {
	      InitOnLineSprite(GetVolConfigSprite(vol_config),rec_curr);
	      InitOnLineSpriteChroma(GetVolConfigSprite(vol_config),rec_curr); 

	      if (GetVolConfigWriteSprite(vol_config))
	        WriteVopGeneric(GetVolConfigSprite(vol_config),
				GetVolConfigSpriteY(vol_config),
				GetVolConfigSpriteU(vol_config),
				GetVolConfigSpriteV(vol_config),
				GetVolConfigSpriteA(vol_config),
				0,IO_FORMAT,IO_OVERWRITE,1);
	    }
#endif

	  if (GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE)
	    {
	      num_bits[vo_id][vol_id].sprite_piece += 
		BitstreamPut(first_shape_code_bitstream,vo_id,vol_id);
	      num_bits[vo_id][vol_id].sprite_piece += 
		BitstreamPut(shape_bitstream,vo_id,vol_id);
	      num_bits[vo_id][vol_id].sprite_piece += 
		BitstreamPut(gray_shape_bitstream,vo_id,vol_id);
	      num_bits[vo_id][vol_id].sprite_piece += 
		BitstreamPut(texture_bitstream,vo_id,vol_id);
	    }
	  else
	    {
	      /* Write shape bitstream to disk */
	      num_bits[vo_id][vol_id].shape +=
		BitstreamPut(first_shape_code_bitstream,vo_id,vol_id); 
	      num_bits[vo_id][vol_id].shape +=
		BitstreamPut(shape_bitstream,vo_id,vol_id); 
	      num_bits[vo_id][vol_id].shape +=
		BitstreamPut(gray_shape_bitstream,vo_id,vol_id);

	      /* Write texture bitstream to disk */
	      num_bits[vo_id][vol_id].texture +=
		BitstreamPut(texture_bitstream,vo_id,vol_id); 
	    }
	} /* End error resilient mode */
    }/*end of I-VOP*/
  else
    if ( (GetVopPredictionType(curr) == SPRITE_VOP)&&
	 (GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE))	
    /* STATIC SPRITE-VOP */
      {
	/* Write Vop Header bitstream to disk */
	num_bits[vo_id][vol_id].syntax += 
	  BitstreamPutVopHeader(curr,vo_id,time,TRB,vol_config, 
				num_bits,vo_config_list, rc_type, 
				modulo_tps);

	PutVopBrightnessChangeFactor(GetVopBrightnessChangeFactor(curr), rec_curr);
	Compute_SpriteVop (rec_curr);
        SubsampleAlphaMap(GetVopA(curr),GetVopAuv(curr),GetVopShape(curr));
      }
    else
    /* P-VOP  or  B_VOP or ONLINE SPRITE_VOP or UPDATE_PIECES */  
      {
	if (GetVopErrorResDisable(curr) == NON_ERROR_RESILIENT)     /* non error resilient mode */
	  {
	    /* Must fill rec_curr alpha field */
	    CopyImage(GetVopA(curr),GetVopA(rec_curr));
	    
	    if (GetVopShape(curr) != BINARY_SHAPE_ONLY)  /* BSO_NOEL */
	      {
		if (unrestricted_motion)
		  edge = UNRESTRICTED_MV_RANGE;
		else
		  edge = 0;

		f_code_for = GetVopFCodeFor(curr);
		f_code_back = GetVopFCodeBack(curr);
		
		/* Put some text for user */
		if (GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE)
		  fprintf(stdout,"\tP_VOP encoding of update-piece (low latency static sprite syntax)\n");
	
		fprintf(stdout,"\t\tPerforming motion estimation\n");
		if(obmc_disable==0)
		  fprintf(stdout,"\t\t\t- OBMC mode ON\n");
		else
		  fprintf(stdout,"\t\t\t- OBMC mode OFF\n");
		if(enable_8x8_mv==1)
		  fprintf(stdout,"\t\t\t- 4 MV per MB mode ON\n");
		else
		  fprintf(stdout,"\t\t\t- 4 MV per MB mode OFF\n");
		if(unrestricted_motion)
		  fprintf(stdout,"\t\t\t- unrestricted mode ON\n");
		else
		  fprintf(stdout,"\t\t\t- unrestricted mode OFF\n");
		
		/* Carry out motion estimation */
		if (GetVopPredictionType(curr)!=B_VOP) 	
		  MotionEstimation(curr,rec_curr,rec_prev,prev,
				   /*obmc_disable*//*1*/ enable_8x8_mv, /*SpSc*/
				   edge ,f_code_for,
				   &mot_x,&mot_y,&MB_decisions,&alpha_decisions);

		/*** 10/27 TPS */
		else  /* Motion Estimation for B-VOPs */
		  {
		    /* B_VOP for TPS */ 
		    if(!vop_spat_scal                        &&    /* not spatial scalability               */
		       GetVolConfigScalability( vol_config ) &&    /* ENHANCE VOP mode is B_VOP             */
		       (vop_temp_scal == 1 || vop_temp_scal == 2 ) /* temporal scalability B_VOP_TYPE1 or 2 */
		       )
		      {
			if (mot_x_P[vo_id][vol_id]!=NULL) FreeImage(mot_x_P[vo_id][vol_id]);
			if (mot_y_P[vo_id][vol_id]!=NULL) FreeImage(mot_y_P[vo_id][vol_id]);
			mot_x_P[vo_id][vol_id]=AllocImage(MB_width*2, MB_height*2, FLOAT_TYPE);
			mot_y_P[vo_id][vol_id]=AllocImage(MB_width*2, MB_height*2, FLOAT_TYPE);
			SetConstantImage (mot_x_P[vo_id][vol_id], +0.0);
			SetConstantImage (mot_y_P[vo_id][vol_id], +0.0);
		      }
	       
		    /* direct mode is used in B_VOP of temporal scalability Case1 */
		    if(GetVolConfigScalability( vol_config ) && vop_temp_scal == 1)
		      {
			B_MotionEstimation(curr,rec_curr,rec_prev,next_rec_vop, 
					   f_code_for,f_code_back,TRB,TRD,
					   mot_x_P[vo_id][ref_vol_id],mot_y_P[vo_id][ref_vol_id],
					   MB_decisions_P[vo_id][ref_vol_id],
					   &mot_x,&mot_y,&MB_decisions,&alpha_decisions);
		      }
		    
		    /* direct mode is not used in B_VOP of temporal scalability Case2 */
		    else if(GetVolConfigScalability( vol_config ) && vop_temp_scal == 2)
		      {
			B_MotionEstimation(curr,rec_curr,rec_prev,next_rec_vop, 
					   f_code_for,f_code_back,TRB,TRD,
					   mot_x_P[vo_id][vol_id],mot_y_P[vo_id][vol_id],
					   MB_decisions_P[vo_id][vol_id],
					   &mot_x,&mot_y,&MB_decisions,&alpha_decisions);
		      }
		    else
		      {
			B_MotionEstimation(curr,rec_curr,rec_prev,next_rec_vop, 
					   f_code_for,f_code_back,TRB,TRD,
					   mot_x_P[vo_id][vol_id],mot_y_P[vo_id][vol_id],
					   MB_decisions_P[vo_id][vol_id],
					   &mot_x,&mot_y,&MB_decisions,&alpha_decisions);
		      }
		  }
		/* 10/27 TPS ***/
	      }  /* BSO_NOEL */

	    if (RCQ2_MVO_CHECK() >= RCQ2_MVO_ENABLED) /* hjlee */
	      {
		RCQ2_MVO_ComputeMMV(mot_x, mot_y, rec_curr->height/MB_SIZE, 
				    rec_curr->height/MB_SIZE, vo_id);
		
		if (RCQ2_MVO_CHECK() >= RCQ2_MVO_HVS)
		if (FirstInterFrame==1) {
		  SetFirstInterQP(curr, vol_config, vo_id, vol_id);
		}
	      }
	    
	    if ((GetVopShape(curr) == BINARY) || (GetVopShape(curr) == GREY_SCALE)
		|| (GetVopShape(curr) == BINARY_SHAPE_ONLY)) /* BSO_NOEL */
	      {
		if (GetVopShape(curr) == GREY_SCALE)
		MotionCompensatedGreyLevelAlpha =
		  AllocImage(GetImageSizeX(curr->a_chan),
			     GetImageSizeY(curr->a_chan),SHORT_TYPE);
		
		/* Put some text for user */
		fprintf(stdout,"\t\tPerforming INTER Shape Coding\n");
		
		/* Code shape */

		/* Minhua Zhou - for B-VOPs shape prediction is from the 
		   closest decoded P/I-VOP */

/*** 4/19 changed by SHARP */
	/* << case2 of temporal scalability >> */
	/* next_rec_vop is --> Base Vop        */
	/* rec_prev     is --> enhance Vop     */
        if (temporal_scalability == 2 && GetVopScalability(rec_curr)){
          Int now, next, prev;
	  
	  now  = (vol_config->frame -   vol_config->frame_skip)/(Int)vol_config->frame_skip;
	  next = next_rec_vop->frame                           /(Int)vol_config->frame_skip;
	  if(now - 1 == next) prev = next - 1;
	  else                prev = now  - 1;
	  
	  TRD = abs(now - prev) +abs(now - next);
	  TRB = abs(now - prev);
	}
/*** 4/19 changed by SHARP */
		
		if (SelectRefVop(rec_prev,rec_curr,next_rec_vop,TRB,TRD))
                  ref_vop = next_rec_vop;
                else
                  ref_vop = rec_prev;


		
		
		shape_bits = VopShapeCode(curr,
					  rec_curr,
					  ref_vop, 
					  vo_id,
					  alpha_th,
					  mot_x,
					  mot_y,
					  MB_decisions,  /* to be changed for B-VOPs*/
					  alpha_decisions,
					  First_stream,
					  Shape_stream);
		
		SubsampleAlphaMap(GetVopA(rec_curr),GetVopAuv(rec_curr),
				  GetVopShape(rec_curr));
		SubsampleAlphaMap(GetVopA(curr),GetVopAuv(curr),GetVopShape(curr));
		/*apa alpha_decisions-> alpha with modes in blocks units */
		/*apa alpha_sub_pad  -> alpha with (trans-opaque-border) 
		  values in blocks units */ 
		
		if (1==0)
		  {
		    /* will be done in the next loop ...C.Dufour 18/09/97 */
		    if (GetVopShape(curr) != BINARY_SHAPE_ONLY)  /* BSO_NOEL */
		      {
			subsamp_alpha_with_modes((SInt*)GetImageData(GetVopA(rec_curr)),
						 (SInt*)GetImageData(MB_decisions),
						 GetVopWidth(rec_curr),
						 GetVopHeight(rec_curr),
						 (SInt*)GetImageData(alpha_decisions));
			alpha_sub_pad=AllocImage(GetImageSizeX(alpha_decisions),
						 GetImageSizeY(alpha_decisions),SHORT_TYPE);
			subsamp_alpha((SInt*)GetImageData(GetVopA(rec_curr)),
				      GetVopWidth(rec_curr),
				      GetVopHeight(rec_curr),
				      1,
				      (SInt*)GetImageData(alpha_sub_pad));
		      }
		  } /* 1==0 */
	      } 
	    else  
	      {  
		SetConstantImage(GetVopAuv(curr),255);
		SetConstantImage(GetVopAuv(rec_curr),255);
	      }

	    if (GetVopShape(curr) == GREY_SCALE)
	      {
		ImageMotionCompensate(rec_prev->a_chan, mot_x, mot_y,
				      MB_decisions,alpha_decisions,
				      MotionCompensatedGreyLevelAlpha);
		/* to be changed for B_VOPs */
	      }

	    if (GetVopShape(curr) != BINARY_SHAPE_ONLY)  /* BSO_NOEL */
	      {
		subsamp_alpha_with_modes((SInt*)GetImageData(GetVopA(rec_curr)),
					 (SInt*)GetImageData(MB_decisions),
					 GetVopWidth(rec_curr),
					 GetVopHeight(rec_curr),
					 (SInt*)GetImageData(alpha_decisions));
		alpha_sub_pad=AllocImage(GetImageSizeX(alpha_decisions),
					 GetImageSizeY(alpha_decisions),SHORT_TYPE);
		subsamp_alpha((SInt*)GetImageData(GetVopA(rec_curr)),
			      GetVopWidth(rec_curr),
			      GetVopHeight(rec_curr),
			      1,
			      (SInt*)GetImageData(alpha_sub_pad));
	      }

	    /* Put some text for user */
	    fprintf(stdout,"\t\tCoding INTER texture \n\n");
	    /* Code motion and texture combined as in H.263 */

	     /*** 10/27 TPS */     
	     if(vop_temp_scal == 1)
	      VopCodeShapeMotTextInter(curr,
				       First_stream,
				       Shape_stream,
				       GreyLevelAlpha,
				       MotionCompensatedGreyLevelAlpha,
				       ReconstructedGreyLevelAlpha,
				       rec_prev, next_rec_vop,
				       mot_x,mot_y,
				       mot_x_P[vo_id][ref_vol_id],
				       mot_y_P[vo_id][ref_vol_id],
				       MB_decisions_P[vo_id][ref_vol_id],
				       TRB,TRD,
				       alpha_sub_pad,alpha_decisions, MB_decisions, 
				       f_code_for,f_code_back,
				       /* RC2 */ vo_id, vol_id, rc_type,
				       vo_config_list, /* UPM Global RC */
				       rec_curr,
				       /* RC2 */ &vop_quantizer,
				       mottext_bitstream,
				       &num_bits[vo_id][vol_id].text_bits,
				       vol_config);
	    else
	      /* 10/27 TPS ***/
	      VopCodeShapeMotTextInter(curr,
				       First_stream,
				       Shape_stream,
				       GreyLevelAlpha,
				       MotionCompensatedGreyLevelAlpha,
				       ReconstructedGreyLevelAlpha,
				       rec_prev, next_rec_vop,
				       mot_x,mot_y,mot_x_P[vo_id][vol_id],mot_y_P[vo_id][vol_id],
				       MB_decisions_P[vo_id][vol_id],
				       TRB,TRD,
				       alpha_sub_pad,alpha_decisions, MB_decisions, 
				       f_code_for,f_code_back,
				       /* RC2 */ vo_id, vol_id, rc_type,
				       vo_config_list, /* UPM Global RC */
				       rec_curr,
				       /* RC2 */ &vop_quantizer,
				       mottext_bitstream,
				       &num_bits[vo_id][vol_id].text_bits,
				       vol_config);

	    /* Put some text for user */
	    /* Replaced 16.9. by M.E. */
	    if (GetVolConfigSpriteUsage(vol_config) != STATIC_SPRITE)
	      num_bits[vo_id][vol_id].syntax +=
		BitstreamPutVopHeader(curr,vo_id,time,TRB,vol_config,
				      num_bits,vo_config_list, rc_type,
                                      modulo_tps);

	    /* for TPS and ssp*/ 
	    if (GetVopScalability(curr))/* && !vop_spat_scal)*/ /*UPS*/
	      WriteBGCAlphaBitstream(curr, vo_id, vol_id, num_bits
				     , back_base_exist );
	    
	    /* Write combined bitstream to disk */
	    if (GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE)
	      num_bits[vo_id][vol_id].sprite_piece += 
		BitstreamPut(mottext_bitstream,vo_id,vol_id);
	    else
	      num_bits[vo_id][vol_id].mot_shape_text +=
		BitstreamPut(mottext_bitstream,vo_id,vol_id); 
	   
            FreeImage(alpha_decisions);
	    if(alpha_sub_pad!=NULL) FreeImage(alpha_sub_pad);
	    if (GetVopShape(curr) == GREY_SCALE)
	      FreeImage(MotionCompensatedGreyLevelAlpha);

#ifndef _WD_MODE_
	    if (GetVolConfigSpriteUsage(vol_config) == ONLINE_SPRITE)
	      {
		UpdateOnLineSprite(GetVolConfigSprite(vol_config),rec_curr);

		if (GetVolConfigWriteSprite(vol_config))
		  WriteVopGeneric(GetVolConfigSprite(vol_config),
				  GetVolConfigSpriteY(vol_config),
				  GetVolConfigSpriteU(vol_config),
				  GetVolConfigSpriteV(vol_config),
				  GetVolConfigSpriteA(vol_config),
				  0,IO_FORMAT,IO_APPEND,1);
	      }
#endif
	    
	  }    /* End of non error resilient mode */
	else
	  {    /* error resilient mode */

            /* Must fill rec_curr alpha field */
	    CopyImage(GetVopA(curr),GetVopA(rec_curr));
	    
	    if (unrestricted_motion)
	      edge = UNRESTRICTED_MV_RANGE;
	    else
	      edge = 0;

	    f_code_for = GetVopFCodeFor(curr);
	    f_code_back = GetVopFCodeBack(curr);
	    f_code_max = (f_code_for > f_code_back) ? f_code_for:f_code_back;

	    if (GetVopShape(curr) == BINARY_SHAPE_ONLY)
	      resync_marker_length = 17;
	    else if (GetVopPredictionType(curr) == B_VOP)
	      resync_marker_length = 16 + f_code_max;
	    else
	      resync_marker_length = 16 + f_code_for;
	    
	    /* Put some text for user */
	    fprintf(stdout,"\t\tPerforming motion estimation\n");
	    if(obmc_disable==0)
	      fprintf(stdout,"\t\t\t- advanced mode ON\n");
	    else
	      fprintf(stdout,"\t\t\t- advanced mode OFF\n");
	    if(enable_8x8_mv)
	      fprintf(stdout,"\t\t\t- 4 MV per MB mode ON\n");
	    else
	      fprintf(stdout,"\t\t\t- 4 MV per MB mode OFF\n");
	    if(unrestricted_motion)
	      fprintf(stdout,"\t\t\t- unrestricted mode ON\n");
	    else
	      fprintf(stdout,"\t\t\t- unrestricted mode OFF\n");
		
	    /* Carry out motion estimation */
	    if (GetVopPredictionType(curr)!=B_VOP) 	
	      MotionEstimation(curr,rec_curr,rec_prev,prev,
			       /*obmc_disable*//*1*/ enable_8x8_mv, /*SpSc*/
			       edge ,f_code_for,
			       &mot_x,&mot_y,&MB_decisions,&alpha_decisions);
	    else  /* Motion Estimation for B-VOPs */ 
	      B_MotionEstimation(curr,rec_curr,rec_prev,next_rec_vop, 
				 f_code_for,f_code_back,TRB,TRD,
				 mot_x_P[vo_id][vol_id],mot_y_P[vo_id][vol_id],
				 MB_decisions_P[vo_id][vol_id],
				 &mot_x,&mot_y,&MB_decisions,&alpha_decisions);

	    /*apa alpha_decisions-> alpha with modes in blocks units                        */
	    /*apa alpha_sub_pad  -> alpha with (trans-opaque-border) values in blocks units */
	    subsamp_alpha_with_modes((SInt*)GetImageData(GetVopA(rec_curr)),
				     (SInt*)GetImageData(MB_decisions),
				     GetVopWidth(rec_curr),
				     GetVopHeight(rec_curr),
				     (SInt*)GetImageData(alpha_decisions));

	    alpha_sub_pad=AllocImage(GetImageSizeX(alpha_decisions),
				     GetImageSizeY(alpha_decisions),SHORT_TYPE);

	    subsamp_alpha((SInt*)GetImageData(GetVopA(rec_curr)),
			  GetVopWidth(rec_curr),
			  GetVopHeight(rec_curr),
			  1,
			  (SInt*)GetImageData(alpha_sub_pad));
	    
	    if ((GetVopShape(curr) == BINARY) || (GetVopShape(curr) == GREY_SCALE)) 
	      {
		if (GetVopShape(curr) == GREY_SCALE)
		  MotionCompensatedGreyLevelAlpha =
		    AllocImage(GetImageSizeX(curr->a_chan),
			       GetImageSizeY(curr->a_chan),SHORT_TYPE);
		
		SubsampleAlphaMap(GetVopA(rec_curr),GetVopAuv(rec_curr),GetVopShape(rec_curr));
		SubsampleAlphaMap(GetVopA(curr),GetVopAuv(curr),GetVopShape(curr));
	      }
	    else
	      {
		SetConstantImage(GetVopAuv(curr),255);
		SetConstantImage(GetVopAuv(rec_curr),255);
	      }
	    
	    if (GetVopShape(curr) == GREY_SCALE)
	      {
		ImageMotionCompensate(rec_prev->a_chan, mot_x, mot_y, MB_decisions,alpha_decisions,
				      MotionCompensatedGreyLevelAlpha);
	      }
	    
	    /* Code motion and texture combined as in H.263 */
	    error_vop = AllocVop(num_pixels, num_lines);
	    
	    /* Need some fields of current vop when coding error vop
	       (specifically the quantizer) */
	    CopyVopNonImageField(curr,error_vop);
	    comp = CloneVop(rec_curr);
	    rec_error = AllocVop(num_pixels, num_lines);
	    
	    if (GetVopPredictionType(curr)!=B_VOP && !GetVopShape(curr)) 		
	      VopMotionCompensate(rec_prev, mot_x, mot_y, MB_decisions, 
				  alpha_decisions, comp,GetVopOBMCDisable(curr),
				  rec_sprite); 
	    else if (GetVopPredictionType(curr) == B_VOP && !GetVopShape(curr))
	      B_VopMotionCompensation(curr,rec_prev,next_rec_vop,
				      mot_x, mot_y,
				      mot_x_P[vo_id][vol_id],
				      mot_y_P[vo_id][vol_id],
				      MB_decisions_P[vo_id][vol_id],
				      MB_decisions,
				      alpha_decisions, TRB,TRD, comp);

	    if (!GetVopShape(curr))
	      {
		SubImage(curr->y_chan, comp->y_chan, error_vop->y_chan);
		SubImage(curr->u_chan, comp->u_chan, error_vop->u_chan);
		SubImage(curr->v_chan, comp->v_chan, error_vop->v_chan);
	      }
	    else
	      {
		AllocShapePacket(curr);
		
		if (GetVopShape(curr) != BINARY_SHAPE_ONLY 
		    && GetVopPredictionType(curr) != B_VOP)
		  {
		    pi  = AllocImage(GetVopWidth(rec_prev)*2, 
				     GetVopHeight(rec_prev)*2, 	
				     SHORT_TYPE);
		    InterpolateImage(GetVopY(rec_prev), 
				     pi, 
				     GetVopRoundingType(rec_curr));
		    
		    Equalise1MVMBs(MB_decisions, mot_x, mot_y);
		  }
		
		/* Allocate shape ME/MC */
		modeA = AllocImage(GetVopWidth(curr)/MB_SIZE,
				   GetVopHeight(curr)/MB_SIZE,SHORT_TYPE);
		motA_x = AllocImage(GetVopWidth(curr)/MB_SIZE,
				    GetVopHeight(curr)/MB_SIZE,SHORT_TYPE);
		motA_y = AllocImage(GetVopWidth(curr)/MB_SIZE,
				    GetVopHeight(curr)/MB_SIZE,SHORT_TYPE);
	      }

	    CopyImage(rec_curr->a_chan, error_vop->a_chan);
	    CopyImage(rec_curr->a_chan, rec_error->a_chan);
	    CopyImage(rec_curr->a_uv_chan, error_vop->a_uv_chan);
	    CopyImage(rec_curr->a_uv_chan, rec_error->a_uv_chan);

	    if ((GetVopDataPartEnable(curr)) && (GetVopPredictionType(curr)!=B_VOP))
	      {
		/* Put some text for user */
		fprintf(stdout,"\t\tCoding combined shape, motion and INTER texture\n\n");					    
		/* RC2: adding combined mode VM5.0 Rate Control */
		if (rc_type == VM5_RATE_CONTROL)
		  {
		    if (RCQ2_MVO_CHECK() >= RCQ2_MVO_ENABLED)
		      ;
		    else
		      mad = DSRC_compute_MAD(error_vop, &num_pels_vop);

		    if (RCQ2_MVO_CHECK() >= RCQ2_MVO_ENABLED)
		      ;
		    else
		      vop_quantizer = RC_QuantAdjust(vo_id, 
						     vol_id, 
						     vo_config_list, 
						     vol_config, 
						     (Double)mad, 
						     curr, 
						     error_vop, 
						     num_pels_vop,
						     GetVopPredictionType(curr));

		    /* RC2 */
		    fprintf(stdout,"\t\tInter Quantizer : %d\n", (int)vop_quantizer);
		  }
		    
		num_bits[vo_id][vol_id].syntax +=
		  BitstreamPutVopHeader(curr,vo_id,time,TRB,vol_config,
					num_bits,vo_config_list, rc_type,
					modulo_tps);
		    
		if (GetVopPredictionType(curr)!=B_VOP) 
		  {
		    slice_counter = 0;
		    num_bits_packet = 0;
		    first_marker = 1;
		    after_marker = 0;
		    start_of_packet = 1;
		    k = 0;
		    
		    motion_comb_bitstream = BitstreamInit();
		    text_header_comb_bitstream = BitstreamInit();
		    text_data_comb_bitstream = BitstreamInit();
		    
		    /* 	encode the 1st MB shape of the frame */  
		    /* 	In the following MB encoding loop, the shape coding is one MB
			ahead of the texture coding */
		    
		    if (GetVopShape(curr))
		      {
			shape_bits = ShapeCodeMB(curr,
						 rec_curr,
						 rec_prev,
						 vo_id,
						 0,
						 0,
						 alpha_th,
						 modeA,
						 mot_x,
						 mot_y,
						 motA_x,
						 motA_y,
						 MB_decisions,
						 alpha_decisions,
						 &first_bits,
						 first_stream,
						 shape_stream,
						 start_of_packet
						 );
			BitstreamAppendTtoM(First_stream[k], first_stream, first_bits);
			BitstreamAppendTtoM(Shape_stream[k], shape_stream, shape_bits);
		      }
			
		    for (j = 0; j < num_lines/MB_SIZE; j++) 
		      {
			for (i = 0; i < num_pixels/MB_SIZE; i++) 
			  {
			    slice_nb[i][j] = slice_counter;
			    
			    if (GetVopShape(curr))
			      {
				if ((num_bits_packet+GetImageSizeX(First_stream[k])
				     +GetImageSizeX(Shape_stream[k])) > 		
				    RESYNC_MARKER_SPACING)
				  start_of_packet = 1;
				else 
				  start_of_packet = 0;

				/* encode the shape of the next MB */   
				
				if (i==(num_pixels/MB_SIZE-1)) 
							{
							  i_next = 0;
							  j_next = j+1;
							}
				else 
				  {
				    i_next = i+1;
				    j_next = j;
				  }
				
				if (j_next < num_lines/MB_SIZE)  /* check that the next MB exists */
				  {						
				    shape_bits = ShapeCodeMB(curr,
							     rec_curr,
							     rec_prev,
							     vo_id,
							     j_next,
							     i_next,
							     alpha_th,
							     modeA,
							     mot_x,
							     mot_y,
							     motA_x,
							     motA_y,
							     MB_decisions,
							     alpha_decisions,
							     &first_bits,
							     first_stream,
							     shape_stream,
							     start_of_packet
							     );
				    BitstreamAppendTtoM(First_stream[k+1], 
							first_stream, 
							first_bits);
				    BitstreamAppendTtoM(Shape_stream[k+1], 
							shape_stream, 
							shape_bits);
				    k++;
				  }
				
				if (GetVopShape(rec_curr)!=BINARY_SHAPE_ONLY)
				  {
				    CopyVopABlock(rec_curr, error_vop, i*MB_SIZE, j*MB_SIZE); 
				    CopyVopAuvBlock(rec_curr, error_vop , i*B_SIZE, j*B_SIZE);
				    
				    MotionCompensateMB(rec_prev,pi,mot_x,mot_y,i,j,
						       GetVopOBMCDisable(curr),
						       alpha_decisions, MB_decisions, comp);
				    
				    
				    FillErrorMB(curr,rec_curr,comp,error_vop,i,j);
				    
				    PadMB(rec_curr,MB_decisions,error_vop,i,j);
				  }
			      }
			    
			    MBShapeMotTextErrRes(error_vop, alpha_decisions, MB_decisions, 
						 mot_x, mot_y, f_code_for, First_stream, 
						 Shape_stream, GreyLevelAlpha,
						 MotionCompensatedGreyLevelAlpha,
						 ReconstructedGreyLevelAlpha,
						 GetVopIntraACDCPredDisable(curr),
						 GetVopDataPartEnable(curr),rec_error, 
						 motion_comb_bitstream,
						 text_header_comb_bitstream,
						 text_data_comb_bitstream,
						 i, j, &num_bits_MB,
						 after_marker,
						 DC_store, slice_nb,
						 &num_bits[vo_id][vol_id].text_bits);
			    
			    after_marker = 0;
			    num_bits_packet += num_bits_MB;
			    if ((num_bits_packet >= RESYNC_MARKER_SPACING) && start_of_packet
				&& ((j*MB_width+i) < (MB_height*MB_width-1)))
			      {
				if (GetVopShape(curr))
				  start_of_packet = 0;

				num_bits[vo_id][vol_id].mot_shape_text += 
				  BitstreamPut(motion_comb_bitstream,vo_id,vol_id);
				BitstreamFree(motion_comb_bitstream);
				    
				aux_bitstream = BitstreamInit();
				BitstreamPutBits(aux_bitstream,MOTION_MARKER_COMB,MOTION_MARKER_COMB_LENGTH);
				num_bits[vo_id][vol_id].syntax += 
				  BitstreamPut(aux_bitstream,vo_id,vol_id);
				BitstreamFree(aux_bitstream);
				    
				num_bits[vo_id][vol_id].mot_shape_text += 
				  BitstreamPut(text_header_comb_bitstream,vo_id,vol_id);
				BitstreamFree(text_header_comb_bitstream);
				
				num_bits[vo_id][vol_id].mot_shape_text += 
				  BitstreamPut(text_data_comb_bitstream,vo_id,vol_id);
				BitstreamFree(text_data_comb_bitstream);
				
				aux_bitstream = BitstreamInit();
				BitstreamPutBits(aux_bitstream,RESYNC_MARKER,resync_marker_length);
				BitstreamPutBits(aux_bitstream,j*MB_width+i+1,MB_in_VOP_length);
				
				if (GetVopShape(curr) != BINARY_SHAPE_ONLY) 	    	
				  BitstreamPutBits(aux_bitstream,GetVopQuantizer(curr),
						   GetVopQuantPrecision(curr));
				
				if (first_marker)
				  {
				    first_marker = 0;
				    /* Write the HEC-flag and then the HEC itself */
				    BitstreamPutBits(aux_bitstream,1,1);
				    BitstreamPutHEC(vol_config, curr, time, aux_bitstream);

#if 0 /* Replaced by subroutine, MW 27-MAR-1998 */
				    index = GetVolConfigModTimeBase(vol_config,0);
				    time_modulo = time - index*1000;
				    while(time_modulo >= 1000)
				      {
					BitstreamPutBits(aux_bitstream,1,1);
					time_modulo = time_modulo - 1000;
					index++;
				      }
				    BitstreamPutBits(aux_bitstream,0,1);
				    
				    time_inc = (time - index*1000);
				    bits = ceil(log((double)GetVopTimeIncrementResolution(curr))/log(2.0));
				    if (bits<1) 
				      bits=1;
				    time_inc=time_inc*(double)GetVopTimeIncrementResolution(curr)/1000.0;
				    BitstreamPutBits(aux_bitstream,1,1); /* marker bit */
				    BitstreamPutBits(aux_bitstream,(Int)(time_inc+0.001),bits);
				    BitstreamPutBits(aux_bitstream,1,1); /* marker */
				    BitstreamPutBits(aux_bitstream,GetVopPredictionType(curr),2);
				    
				    if (GetVopShape(curr) != BINARY_SHAPE_ONLY)		
				      {
					if (GetVopPredictionType(curr) != I_VOP)
					  BitstreamPutBits(aux_bitstream,GetVopFCodeFor(curr),3);
					if (GetVopPredictionType(curr) == B_VOP)
					  BitstreamPutBits(aux_bitstream,GetVopFCodeBack(curr),3);
				      }
#endif
				  }
				else
				  {  
				    BitstreamPutBits(aux_bitstream,0,1);
				  }

				NextResyncMarker(vo_id,vol_id);
				
				num_bits[vo_id][vol_id].syntax += 
				  BitstreamPut(aux_bitstream,vo_id,vol_id);
				BitstreamFree(aux_bitstream);
				    
				motion_comb_bitstream = BitstreamInit();
				text_header_comb_bitstream = BitstreamInit();
				text_data_comb_bitstream = BitstreamInit();
				    
				num_bits_packet = 0;
				after_marker = 1;
				slice_counter++;
			      }
			  }
		      }
		    
		    num_bits[vo_id][vol_id].mot_shape_text += 
		      BitstreamPut(motion_comb_bitstream,vo_id,vol_id);
		    BitstreamFree(motion_comb_bitstream);
			
		    aux_bitstream = BitstreamInit();
		    BitstreamPutBits(aux_bitstream,MOTION_MARKER_COMB,MOTION_MARKER_COMB_LENGTH);
		    
		    num_bits[vo_id][vol_id].syntax += 
		      BitstreamPut(aux_bitstream,vo_id,vol_id);
		    BitstreamFree(aux_bitstream);
			
		    num_bits[vo_id][vol_id].mot_shape_text += 
		      BitstreamPut(text_header_comb_bitstream,vo_id,vol_id);
		    BitstreamFree(text_header_comb_bitstream);
			
		    num_bits[vo_id][vol_id].mot_shape_text += 
		      BitstreamPut(text_data_comb_bitstream,vo_id,vol_id);
		    BitstreamFree(text_data_comb_bitstream);
		  }
		
		AddImage(comp->y_chan, rec_error->y_chan, rec_curr->y_chan);
		AddImage(comp->u_chan, rec_error->u_chan, rec_curr->u_chan);
		AddImage(comp->v_chan, rec_error->v_chan, rec_curr->v_chan);
		
		CopyImage(GetVopQP(rec_error), GetVopQP(rec_curr));
		    
		ClipImage (rec_curr->y_chan,GetVopBrightWhite(rec_curr));
		ClipImage (rec_curr->u_chan,GetVopBrightWhite(rec_curr));
		ClipImage (rec_curr->v_chan,GetVopBrightWhite(rec_curr));
		    
		FreeVop(error_vop);
		FreeVop(comp);
		FreeVop(rec_error);
	      }
	    else /* No Data Partitioning */
	      {
		fprintf(stdout,"\t\tCoding combined shape, motion and INTER texture\n\n");
		
		/* RC2: adding combined mode VM5.0 Rate Control */
		if (rc_type == VM5_RATE_CONTROL)
		  {
		    if (RCQ2_MVO_CHECK() >= RCQ2_MVO_ENABLED)
		      ;
		    else
		      mad = DSRC_compute_MAD(error_vop, &num_pels_vop);

		    if (RCQ2_MVO_CHECK() >= RCQ2_MVO_ENABLED)
		      ;
		    else
		      vop_quantizer = RC_QuantAdjust(vo_id, 
						     vol_id, 
						     vo_config_list, 
						     vol_config, 
						     (Double)mad, 
						     curr, 
						     error_vop, 
						     num_pels_vop,
						     GetVopPredictionType(curr));
		    
		    /* RC2 */
		    fprintf(stdout,"\t\tInter Quantizer : %d\n", (int)vop_quantizer);
		  }
		
		num_bits[vo_id][vol_id].syntax +=
		  BitstreamPutVopHeader(curr,vo_id,time,TRB,vol_config,
					num_bits,vo_config_list,
					rc_type, modulo_tps);
		
		if (GetVopPredictionType(curr)!=B_VOP) 
		  {
		    slice_counter = 0;
		    num_bits_packet = 0;
		    first_marker = 1;
		    after_marker = 0;
		    start_of_packet = 1;
		    k = 0;
		    comb_bitstream = BitstreamInit();
		    
		    /* 	encode the 1st MB shape of the frame */  
		    /* 	In the following MB encoding loop, the shape coding is one MB
			ahead of the texture coding */
		    
		    if (GetVopShape(curr))
		      {
			shape_bits = ShapeCodeMB(curr,
						 rec_curr,
						 rec_prev,
						 vo_id,
						 0,
						 0,
						 alpha_th,
						 modeA,
						 mot_x,
						 mot_y,
						 motA_x,
						 motA_y,
						 MB_decisions,
						 alpha_decisions,
						 &first_bits,
						 first_stream,
						 shape_stream,
						 start_of_packet
						 );
			BitstreamAppendTtoM(First_stream[k], first_stream, 
					    first_bits);
			BitstreamAppendTtoM(Shape_stream[k], shape_stream, 
					    shape_bits);
		      }
			
		    for (j = 0; j < num_lines/MB_SIZE; j++) 
		      {
			for (i = 0; i < num_pixels/MB_SIZE; i++) 
			  {
			    slice_nb[i][j] = slice_counter;

			    if (GetVopShape(curr))
			      {
				if ((num_bits_packet+GetImageSizeX(First_stream[k])
				     +GetImageSizeX(Shape_stream[k])) > 
				    RESYNC_MARKER_SPACING)
				  start_of_packet = 1;
				else 
				start_of_packet = 0;

				/* encode the shape of the next MB */   
				
				if (i==(num_pixels/MB_SIZE-1)) 
				  {
				    i_next = 0;
				    j_next = j+1;
				  }
				else 
				  {
				    i_next = i+1;
				    j_next = j;
				  }
				
				if (j_next < num_lines/MB_SIZE)  /* check that the next MB exists */
				  {						
				    shape_bits = ShapeCodeMB(curr,
							     rec_curr,
							     rec_prev,
							     vo_id,
							     j_next,
							     i_next,
							     alpha_th,
							     modeA,
							     mot_x,
							     mot_y,
							     motA_x,
							     motA_y,
							     MB_decisions,
							     alpha_decisions,
							     &first_bits,
							     first_stream,
							     shape_stream,
							     start_of_packet
							     );
				    BitstreamAppendTtoM(First_stream[k+1], 
							first_stream, 
							first_bits);
				    BitstreamAppendTtoM(Shape_stream[k+1], 
							shape_stream, 
							shape_bits);
				    k++;
				  }
				if (GetVopShape(rec_curr)!=BINARY_SHAPE_ONLY)
				  {
				    
				    CopyVopABlock(rec_curr, error_vop, i*MB_SIZE, j*MB_SIZE); 
				    CopyVopAuvBlock(rec_curr, error_vop , i*B_SIZE, j*B_SIZE);

				    MotionCompensateMB(rec_prev,pi,mot_x,mot_y,i,j,
						       GetVopOBMCDisable(curr),
						       alpha_decisions, MB_decisions, comp);
				    
				    FillErrorMB(curr,rec_curr,comp,error_vop,i,j);
				    
				    PadMB(rec_curr,MB_decisions,error_vop,i,j);
				  }
			      }
			    
			    MBShapeMotTextErrRes(error_vop, alpha_decisions, MB_decisions, 
						 mot_x, mot_y, f_code_for, First_stream, 
						 Shape_stream, GreyLevelAlpha,
						 MotionCompensatedGreyLevelAlpha,
						 ReconstructedGreyLevelAlpha,
						 GetVopIntraACDCPredDisable(curr),
						 GetVopDataPartEnable(curr),rec_error, 
						 comb_bitstream,
						 comb_bitstream,
						 comb_bitstream,
						 i, j, &num_bits_MB,
						 after_marker,
						 DC_store, slice_nb,
						 &num_bits[vo_id][vol_id].text_bits);
				
			    after_marker = 0;
			    num_bits_packet += num_bits_MB;
			    if ((num_bits_packet >= RESYNC_MARKER_SPACING) && start_of_packet
				&& ((j*MB_width+i) < (MB_height*MB_width-1)))
			      {
				if (GetVopShape(curr))
				start_of_packet = 0;
				
				num_bits[vo_id][vol_id].mot_shape_text += 	
				  BitstreamPut(comb_bitstream,vo_id,vol_id);
				BitstreamFree(comb_bitstream);
				    
				aux_bitstream = BitstreamInit();
				BitstreamPutBits(aux_bitstream,RESYNC_MARKER,resync_marker_length);
				BitstreamPutBits(aux_bitstream,j*MB_width+i+1,MB_in_VOP_length);
				
				if (GetVopShape(curr) != BINARY_SHAPE_ONLY) 	
				  BitstreamPutBits(aux_bitstream,GetVopQuantizer(curr),
						   GetVopQuantPrecision(curr));
				    
				if (first_marker)
				  {
				    first_marker = 0;
				    /* Write the HEC-flag and then the HEC itself */
				    BitstreamPutBits(aux_bitstream,1,1);
				    BitstreamPutHEC(vol_config, curr, time, aux_bitstream);

#if 0 /* Replaced by subroutine, MW 27-MAR-1998 */
				    BitstreamPutBits(aux_bitstream,1,1);
				    index = GetVolConfigModTimeBase(vol_config,0);
				    time_modulo = time - index*1000;
				    while(time_modulo >= 1000)
				      {
					BitstreamPutBits(aux_bitstream,1,1);
					time_modulo = time_modulo - 1000;
					index++;
				      }
				    BitstreamPutBits(aux_bitstream,0,1);
				    
				    time_inc = (time - index*1000);
				    bits = ceil(log((double)GetVopTimeIncrementResolution(curr))/log(2.0));
				    if (bits<1) 
				      bits=1;
				    time_inc=time_inc*(double)GetVopTimeIncrementResolution(curr)/1000.0;
				    BitstreamPutBits(aux_bitstream,1,1); /* marker bit */
				    BitstreamPutBits(aux_bitstream,(Int)(time_inc+0.001),bits);
				    BitstreamPutBits(aux_bitstream,1,1); /* marker bit */
				    BitstreamPutBits(aux_bitstream,GetVopPredictionType(curr),2);
				    
				    if (GetVopShape(curr) != BINARY_SHAPE_ONLY)		
				      {
					if (GetVopPredictionType(curr) != I_VOP)
					  BitstreamPutBits(aux_bitstream,
							   GetVopFCodeFor(curr),3);
					if (GetVopPredictionType(curr) == B_VOP)		
					  BitstreamPutBits(aux_bitstream,
							   GetVopFCodeBack(curr),3);
				      }
#endif

				  }
				else
				  {
				    BitstreamPutBits(aux_bitstream,0,1);
				  }
				    
				NextResyncMarker(vo_id,vol_id);
				num_bits[vo_id][vol_id].syntax += 
				  BitstreamPut(aux_bitstream,vo_id,vol_id);
				BitstreamFree(aux_bitstream);
				    
				comb_bitstream = BitstreamInit();
				
				num_bits_packet = 0;
				after_marker = 1;
				slice_counter++;
			      }
			  }
		      }
		    
		    num_bits[vo_id][vol_id].mot_shape_text += 
		      BitstreamPut(comb_bitstream,vo_id,vol_id);
		    BitstreamFree(comb_bitstream);
		  }
		else /* B_VOP */
		  {
		    /* encode B-VOPs */
		    slice_counter = 0;
		    num_bits_packet = 0;
		    first_marker = 1;
		    after_marker = 0;
		    start_of_packet = 1;
		    k = 0;
		    comb_bitstream = BitstreamInit();

		    /* MW 05-MAY-1998 bug fix by Luis D. Soares */
		    if (SelectRefVop(rec_prev,rec_curr,next_rec_vop,TRB,TRD))
		      ref_vop = next_rec_vop;
		    else
		      ref_vop = rec_prev;

		    /* 	encode the 1st MB shape of the frame */  
		    /* 	In the following MB encoding loop, the shape coding is one MB
			ahead of the texture coding */
		    if (GetVopShape(curr))
		      {
			shape_bits = ShapeCodeMB(curr,
						 rec_curr,
						 ref_vop,
						 /* rec_prev, */ /* MW 05-MAY-1998 */
						 vo_id,
						 0,
						 0,
						 alpha_th,
						 modeA,
						 mot_x,
						 mot_y,
						 motA_x,
						 motA_y,
						 MB_decisions,
						 alpha_decisions,
						 &first_bits,
						 first_stream,
						 shape_stream,
						 start_of_packet
						 );
			BitstreamAppendTtoM(First_stream[k], first_stream, 
					    first_bits);
			BitstreamAppendTtoM(Shape_stream[k], shape_stream, 
					    shape_bits);
		      }
		    
		    for (j = 0; j < num_lines/MB_SIZE; j++) 
		      {
			for (i = 0; i < num_pixels/MB_SIZE; i++) 
			  {
			    slice_nb[i][j] = slice_counter;
			    
			    if (GetVopShape(curr))
					{
					  if ((num_bits_packet+GetImageSizeX(First_stream[k])
					       +GetImageSizeX(Shape_stream[k])) > 	
					      RESYNC_MARKER_SPACING)
					    start_of_packet = 1;
					  else 
					    start_of_packet = 0;

					  /* encode the shape of the next MB */   
					  
					  if (i==(num_pixels/MB_SIZE-1)) 
					    {
					      i_next = 0;
					      j_next = j+1;
					    }
					  else 
					    {
					      i_next = i+1;
					      j_next = j;
					    }
					  
					  if (j_next < num_lines/MB_SIZE)  /* check that the next MB exists */
					    {						
					      shape_bits = ShapeCodeMB(curr,
								       rec_curr,
								       ref_vop,
								       /* rec_prev, */ /* MW 05-MAY-1998 */
								       vo_id,
								       j_next,
								       i_next,
								       alpha_th,
								       modeA,
								       mot_x,
								       mot_y,
								       motA_x,
								       motA_y,
								       MB_decisions,
								       alpha_decisions,
								       &first_bits,
								       first_stream,
								       shape_stream,
								       start_of_packet
								       );
					      BitstreamAppendTtoM(First_stream[k+1], 
								  first_stream, 
								  first_bits);
					      BitstreamAppendTtoM(Shape_stream[k+1], 
								  shape_stream, 
								  shape_bits);
					      k++;
					    }
					  
					  if (GetVopShape(rec_curr)!=BINARY_SHAPE_ONLY)
					    {
					      CopyVopABlock(rec_curr, rec_error, i*MB_SIZE, j*MB_SIZE); 
					      CopyVopAuvBlock(rec_curr, rec_error, i*B_SIZE, j*B_SIZE);
					      
					      B_MotionCompensateMB(i,j,curr,rec_prev,next_rec_vop,
								   mot_x, mot_y,
								   mot_x_P[vo_id][vol_id],
								   mot_y_P[vo_id][vol_id],
								   MB_decisions_P[vo_id][vol_id],
								   MB_decisions,
								   alpha_decisions, TRB,TRD, comp);
									
					      FillErrorMB(curr,rec_curr,comp,error_vop,i,j);

					      PadMB(rec_curr,MB_decisions,error_vop,i,j);
					    }
					}
			    
			    B_MBShapeMotTextErrRes(error_vop, alpha_decisions, MB_decisions, 
						   mot_x, mot_y,
						   f_code_for, f_code_back, First_stream, 
						   Shape_stream, GreyLevelAlpha,
						   MotionCompensatedGreyLevelAlpha,
						   ReconstructedGreyLevelAlpha,
						   rec_error, 
						   comb_bitstream,
						   i, j, &num_bits_MB,
						   slice_nb,
						   &num_bits[vo_id][vol_id].text_bits);
			    
			    after_marker = 0;
			    num_bits_packet += num_bits_MB;
			    if ((num_bits_packet >= RESYNC_MARKER_SPACING) && start_of_packet
				&& ((j*MB_width+i) < (MB_height*MB_width-1)))
			      {
				if (GetVopShape(curr))
				  start_of_packet = 0;
				    
				num_bits[vo_id][vol_id].mot_shape_text += 
				  BitstreamPut(comb_bitstream,vo_id,vol_id);
				BitstreamFree(comb_bitstream);
				    
				aux_bitstream = BitstreamInit();
				BitstreamPutBits(aux_bitstream,RESYNC_MARKER,resync_marker_length);
				BitstreamPutBits(aux_bitstream,j*MB_width+i+1,MB_in_VOP_length);
				
				if (GetVopShape(curr) != BINARY_SHAPE_ONLY) 
				  BitstreamPutBits(aux_bitstream,GetVopBQuantizer(curr),
						   GetVopQuantPrecision(curr));
				
				if (first_marker)
				  {
				    first_marker = 0;
				    /* Write the HEC-flag and then the HEC itself */
				    BitstreamPutBits(aux_bitstream,1,1);
				    BitstreamPutHEC(vol_config, curr, time, aux_bitstream);

#if 0 /* Replaced by subroutine, MW 27-MAR-1998 */
				    BitstreamPutBits(aux_bitstream,1,1);
				    index = GetVolConfigModTimeBase(vol_config,0);
				    time_modulo = time - index*1000;
				    while(time_modulo >= 1000)
				      {
					BitstreamPutBits(aux_bitstream,1,1);
					time_modulo = time_modulo - 1000;
					index++;
				      }
				    BitstreamPutBits(aux_bitstream,0,1);
				      
				    time_inc = (time - index*1000);
				    bits = ceil(log((double)GetVopTimeIncrementResolution(curr))/log(2.0));
				    if (bits<1) 
				      bits=1;
				    time_inc=time_inc*(double)GetVopTimeIncrementResolution(curr)/1000.0;
				    BitstreamPutBits(aux_bitstream,1,1); /* marker bit */
				    BitstreamPutBits(aux_bitstream,(Int)(time_inc+0.001),bits);
				    BitstreamPutBits(aux_bitstream,1,1); /* marker bit */
				    BitstreamPutBits(aux_bitstream,GetVopPredictionType(curr),2);
				    
				    if (GetVopShape(curr) != BINARY_SHAPE_ONLY)		
				      {
					if (GetVopPredictionType(curr) != I_VOP)
					  BitstreamPutBits(aux_bitstream,GetVopFCodeFor(curr),3);
					if (GetVopPredictionType(curr) == B_VOP)
					  BitstreamPutBits(aux_bitstream,GetVopFCodeBack(curr),3);
				      }
#endif

				  }
				else
				  {  
				    BitstreamPutBits(aux_bitstream,0,1);
				  }
				    
				NextResyncMarker(vo_id,vol_id);
				num_bits[vo_id][vol_id].syntax += 
				  BitstreamPut(aux_bitstream,vo_id,vol_id);
				BitstreamFree(aux_bitstream);
				    
				comb_bitstream = BitstreamInit();
				    
				num_bits_packet = 0;
				after_marker = 1;
				slice_counter++;
			      }
			  }
		      }
			
		    num_bits[vo_id][vol_id].mot_shape_text += 
		      BitstreamPut(comb_bitstream,vo_id,vol_id);
		    BitstreamFree(comb_bitstream);
		  }
			
		AddImage(comp->y_chan, rec_error->y_chan, rec_curr->y_chan);
		AddImage(comp->u_chan, rec_error->u_chan, rec_curr->u_chan);
		AddImage(comp->v_chan, rec_error->v_chan, rec_curr->v_chan);
		    
		CopyImage(GetVopQP(rec_error), GetVopQP(rec_curr));
		    
		ClipImage (rec_curr->y_chan,GetVopBrightWhite(rec_curr));
		ClipImage (rec_curr->u_chan,GetVopBrightWhite(rec_curr));
		ClipImage (rec_curr->v_chan,GetVopBrightWhite(rec_curr));
		    		    
		FreeVop(error_vop);
		FreeVop(comp);
		FreeVop(rec_error);
	      }
	    
	    FreeShapePacket();
	    
	    if (GetVopShape(curr) && (GetVopShape(curr) != BINARY_SHAPE_ONLY))
	      {		    
		if (GetVopPredictionType(curr) != B_VOP) 
		  FreeImage(pi);
		FreeImage(modeA);
		FreeImage(motA_x);
		FreeImage(motA_y);
	      }
	    
	    FreeImage(alpha_decisions);
	    
	    if(alpha_sub_pad!=NULL) 
	      FreeImage(alpha_sub_pad);
	    
	    if (GetVopShape(curr) == GREY_SCALE)
	      FreeImage(MotionCompensatedGreyLevelAlpha);

#ifndef _WD_MODE_
	    if (GetVolConfigSpriteUsage(vol_config) == ONLINE_SPRITE)
	      {
		UpdateOnLineSprite(GetVolConfigSprite(vol_config),rec_curr);

		if (GetVolConfigWriteSprite(vol_config))
		  WriteVopGeneric(GetVolConfigSprite(vol_config),
				  GetVolConfigSpriteY(vol_config),
				  GetVolConfigSpriteU(vol_config),
				  GetVolConfigSpriteV(vol_config),
				  GetVolConfigSpriteA(vol_config),
				  0,IO_FORMAT,IO_APPEND,1);
	      }
#endif

	  }  /* End of error resilient mode */
      }  /* End of P-VOP, B_VOP, ONLINE SPRITE_VOP */
 
  /* Deallocate memory for shape coding decisions */
  /* and grey level shape coding */
  if ((GetVopShape(curr) == BINARY) || (GetVopShape(curr) == GREY_SCALE))
    {
      if (GetVopShape(curr) == GREY_SCALE)
	{
	  FreeImage(GreyLevelAlpha);
	  CopyReconstructedGreyLevelAlphaToVop(ReconstructedGreyLevelAlpha,
					       rec_curr->a_chan);
          SubsampleAlphaMap(GetVopA(rec_curr),GetVopAuv(rec_curr),GetVopShape(rec_curr));

	  FreeImage(ReconstructedGreyLevelAlpha);
	}
    }

  /* Deallocate memory for intermediate bitstreams */
  BitstreamFree(first_shape_code_bitstream);
  BitstreamFree(shape_bitstream);
  BitstreamFree(gray_shape_bitstream);
  BitstreamFree(texture_bitstream);
  BitstreamFree(motion_bitstream);
  BitstreamFree(mottext_bitstream);

  if (flag_static_sprite_piece==0) /* no next start code in the syntax for sprite pieces */
    {
      if (GetVopSpriteUsage(curr)!=STATIC_SPRITE||
	  GetVopPredictionType(curr)==SPRITE_VOP)
        num_bits[vo_id][vol_id].texture+=
	  NextStartCode(vo_id,vol_id); /* added by Minhua Zhou 16-05-97 */
      else
        num_bits[vo_id][vol_id].sprite_piece+=
	  NextStartCode(vo_id,vol_id);
    }
 
  /* Free shape stream */
  for(i=0; i<(GetVopWidth(curr)/MB_SIZE)*(GetVopHeight(curr)/MB_SIZE); i++)
    {
      BitstreamFree(First_stream[i]);
      BitstreamFree(Shape_stream[i]);
    }
  free(First_stream);
  free(Shape_stream);
  
  if (GetVopErrorResDisable(curr) != NON_ERROR_RESILIENT)
    {
      /* Free allocated memory for 3D matrix */
      for (i = 0; i < MB_width*MB_height; i++)
	{
	  for (j = 0; j < 6; j++)
	    free(DC_store[i][j]);
	  free(DC_store[i]);
	}
      free(DC_store);
      
      /* Free allocated memory for 2D matrix */
      for (i = 0; i < MB_width; i++)
	free(slice_nb[i]);
      free(slice_nb);
    }
      
  if  (GetVopPredictionType(curr) == SPRITE_VOP) 
    {
      if (GetVolConfigSpriteUsage(vol_config) != STATIC_SPRITE)
      	{
	  free(prev_warp_param);
	  PutVolConfigPrevWarpParam(warp_param, vol_config);
	}
      else
      	free(warp_param);
      
      if (GetVolConfigNoOfSpritePoints(vol_config)) 
	{
	  free(traj); 
	  free(difftraj); 
	  free(qtraj);   
	}
    } 
	
  /* Compute the Vop PSNR's */
  num_bits[vo_id][vol_id].psnr_y = VopPSNR_Y(curr,rec_curr);
  num_bits[vo_id][vol_id].psnr_u = VopPSNR_U(curr,rec_curr);
  num_bits[vo_id][vol_id].psnr_v = VopPSNR_V(curr,rec_curr);

  if(!vop_spat_scal && temporal_scalability != 0)
    {
      FreeVopChannels(no_padding_vop);
      AllocVopChannels(no_padding_vop,GetImageSizeX(rec_curr->a_chan),
		       GetImageSizeY(rec_curr->a_chan));
      CopyVop(rec_curr,no_padding_vop);
    }

  if (GetVopSpriteUsage(curr) != STATIC_SPRITE)
    if ((GetVopPredictionType(curr)!=B_VOP) ||
	(vop_spat_scal) ||
	(temporal_scalability == 2 && GetVopPredictionType(curr)==B_VOP)) 
      {
	VopPadding(curr);
	VopPadding(rec_curr); 
      }

  if (GetVopPredictionType(curr) != SPRITE_VOP || GetVopSpriteUsage(curr) != STATIC_SPRITE )
    if (GetVopShape(curr) != BINARY_SHAPE_ONLY)  /* BSO_NOEL */
      {
	/* Deallocate memory for motion vectors and MB modes */
	if (GetVopPredictionType(curr)!=B_VOP ||
	    (GetVopScalability( curr ) && temporal_scalability == 2)) 
	  {
	    if (mot_x_P[vo_id][vol_id]!=NULL) 
	      FreeImage(mot_x_P[vo_id][vol_id]);
	    if (mot_y_P[vo_id][vol_id]!=NULL) 
	      FreeImage(mot_y_P[vo_id][vol_id]);
	    if (MB_decisions_P[vo_id][vol_id]!=NULL) 
	      FreeImage(MB_decisions_P[vo_id][vol_id]);
              
	    if (GetVopPredictionType(curr)==I_VOP) 
	      {
		mot_x_P[vo_id][vol_id]=AllocImage(MB_width*2,MB_height*2,FLOAT_TYPE);
                mot_y_P[vo_id][vol_id]=AllocImage(MB_width*2,MB_height*2,FLOAT_TYPE);
                SetConstantImage (mot_x_P[vo_id][vol_id],+0.0);
                SetConstantImage (mot_y_P[vo_id][vol_id],+0.0);
                if (MB_decisions!=NULL) FreeImage(MB_decisions);
                MB_decisions_P[vo_id][vol_id]=AllocImage(MB_width,MB_height,SHORT_TYPE);
                SetConstantImage (MB_decisions_P[vo_id][vol_id],+0.0);
	      } 
	    else 
	      {
		mot_x_P[vo_id][vol_id] = mot_x;
		mot_y_P[vo_id][vol_id] = mot_y;
		MB_decisions_P[vo_id][vol_id]=MB_decisions;
	      }
	  } 
	else 
	  {
	    FreeImage(mot_x);
	    FreeImage(mot_y);
	    FreeImage(MB_decisions);
	  }
      }
  
  /* Compute total bits for this Vop */
  if (GetVolConfigSpriteUsage(vol_config) != STATIC_SPRITE || 
      GetVopPredictionType(curr) == SPRITE_VOP)
    {
      num_bits[vo_id][vol_id].vop =
	num_bits[vo_id][vol_id].syntax + num_bits[vo_id][vol_id].shape 
	+ num_bits[vo_id][vol_id].motion + num_bits[vo_id][vol_id].texture 
	+ num_bits[vo_id][vol_id].mot_shape_text;
  
      /* Increment bit count for VOL */
      num_bits[vo_id][vol_id].vol += num_bits[vo_id][vol_id].vop; 

      /* Increment average counters */
      num_bits[vo_id][vol_id].psnr_y_ave += num_bits[vo_id][vol_id].psnr_y;
      num_bits[vo_id][vol_id].psnr_u_ave += num_bits[vo_id][vol_id].psnr_u;
      num_bits[vo_id][vol_id].psnr_v_ave += num_bits[vo_id][vol_id].psnr_v;
      num_bits[vo_id][vol_id].average += num_bits[vo_id][vol_id].vop;
      num_bits[vo_id][vol_id].average_shape += shape_bits;
      num_bits[vo_id][vol_id].shape = shape_bits;
    }
 
 
  return;
} /* CodeVop() */






/***********************************************************CommentBegin******
 *
 * -- VopPSNR_xxxx -- Functions computing the Vop PSNRs.
 *
 *		VopPSNR_Y(Vop *original, Vop *reconstructed)
 *		VopPSNR_U(Vop *original, Vop *reconstructed)
 * 	VopPSNR_V(Vop *original, Vop *reconstructed)
 *
 * Author :		
 *	Noel Brady Teltec Irl.
 *
 * Created :		
 *	6-6-96
 *
 * Purpose :		
 *	Computes PSNRs for the various components of the VOP
 *	
 * 
 * Arguments in : 	
 *	Vop *original - the source Vop
 *	Vop *reconstructed - the coded or noisy vop
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	-
 *
 * Return values :	
 *	The PSNR value.
 *
 * Side effects :	
 *	-
 *
 * Description :	
 *	In the computation, only pixels within the Vop shape are considered.
 *	The alpha plane from the reconstructed Vop is used to mask the
 *	error signal.
 *
 * See also :
 *	MaskedPSNRImage()
 *
 * Modified :		
 *	2-Dec-96 Jan De Lameillieure (HHI): calculate SNR only in pels
 *			that belong to original AND reconstructed segment
 *			mask
 *  	20-MAR-97 Jan De Lameillieure (HHI) : added shape argument to
 *			SubsampleAlphaMap()
 *      25.06.97  Minhua Zhou: Removed  "SubsampleAlphaMap" in VopPSNR_U,VopPSNR_V
 *
 ***********************************************************CommentEnd********/

Float 
VopPSNR_Y(Vop *original, Vop *reconstructed)
{
  Image	*im_ori = GetVopY(original),
    *im_rec = GetVopY(reconstructed),
    *alpha_ori = GetVopA(original),
    *alpha_rec = GetVopA(reconstructed);

  return MaskedPSNRImage(im_ori,im_rec,alpha_ori,alpha_rec);
}

Float
VopPSNR_U(Vop *original, Vop *reconstructed)
{
	Image *im_ori = GetVopU(original),
			*im_rec = GetVopU(reconstructed),
  			*alpha_ori_sub = GetVopAuv(original),
			*alpha_rec_sub = GetVopAuv(reconstructed);
	Float psnr;

      

	psnr = MaskedPSNRImage(im_ori,im_rec,alpha_ori_sub,alpha_rec_sub);
	return psnr;
}

Float
VopPSNR_V(Vop *original, Vop *reconstructed)
{
	Image *im_ori = GetVopV(original),
			*im_rec = GetVopV(reconstructed),
  			*alpha_ori_sub = GetVopAuv(original),
			*alpha_rec_sub = GetVopAuv(reconstructed);
	Float psnr;

      

	psnr = MaskedPSNRImage(im_ori,im_rec,alpha_ori_sub,alpha_rec_sub);
	return psnr;
}

/***********************************************************CommentBegin******
 *
 * -- BitstreamPutGOV -- Writes all fields of the Group of VOPs syntax
 *
 * Author :		
 *	Minhua Zhou
 *
 * Created :		
 *	05-05-97
 *
 * Purpose :		
 * 
 * Arguments in : 	
 *	Vop *vop - pointer to vop containing header information
 * Int vo_id - current VO Id
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	-
 *
 * Return values :	
 *	UInt num_bits - number of bits written
 *
 * Side effects :	
 *	-
 *
 * Description :	
 *
 * See also :
 *
 * Modified :	23.03.98 M. Wollborn: included user data in GOV 
 *                                    due to N2171, Cl. 2.1.9	
  ***********************************************************CommentEnd********/
 
UInt BitstreamPutGOV(Vop *vop, Int vo_id,
                     Float time,
                     Int TRD, 
		     VolConfig *vol_config)
  {
    Image *buffer;
    Int time_s,vol_id,num_bits;
    Int closed_gov;
    
    vol_id = GetVolConfigId(vol_config);
    fprintf(stdout,"Transmission of GOV\n");
    
    /* Set up intermediate integer level data structure */
    buffer = BitstreamInit();
    BitstreamPutBits(buffer,GROUP_START_CODE,32);
    
    /* modified to encode GOV header by SONY 980212 */
    time_s = (Int)( (vol_config->frame - vol_config->frame_skip * (2*TRD-1) - vol_config->start_frame) / vol_config->disk_seq_frame_rate );
    if(time_s<0) time_s=0;
    /* 980212 */
    
    /* Sending time_code */
    BitstreamPutBits(buffer,(time_s/3600)%24,5); /* Hours */
    BitstreamPutBits(buffer,(time_s/60)%60,6); /* Minutes */
    BitstreamPutBits(buffer,1,1);   /* Marker bit */
    BitstreamPutBits(buffer,time_s%60,6); /* Seconds */
    PutVolConfigModTimeBase(time_s,vol_config);
    PutVolConfigModTimeBase(time_s,vol_config);
    
/* SONY 070498 - start */       
    BitstreamPutBits(buffer,1,1);
/* SONY 070498 - end */
    
    BitstreamPutBits(buffer,0,1); /* broken_link=0 */
    
    num_bits = BitstreamPut(buffer,vo_id,vol_id);
    num_bits +=NextStartCode(vo_id,vol_id);
    BitstreamFree(buffer);
    
    /* Included for user data due to N2171, Cl. 2.1.9 MW 23-MAR-1998 */
    if(GetVolConfigIsUserDataInGov(vol_config))
      num_bits += PutUserDataToBitstream(GetVolConfigUserDataInGovFile(vol_config),
					 vo_id,vol_id);
    return(num_bits);
  }  






/***********************************************************CommentBegin******
 *
 * -- BitstreamPutVopHeader -- Writes all fields of the vop header syntax
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	11-03-96
 *
 * Purpose :		
 *	This function writes all fields of the vop header syntax to the
 * bitstream disk file.
 * 
 * Arguments in : 	
 *	Vop *vop - pointer to vop containing header information
 * Int vo_id - current VO Id
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	-
 *
 * Return values :	
 *	UInt num_bits - number of bits written
 *
 * Side effects :	
 *	-
 *
 * Description :	
 *	The vop header (start_code, vop_ID, etc.) is first
 *	written to an intermediate integer level bitstream data structure.
 *	This intermediate bitstream data structure is then written to disk.
 *
 * See also :
 *	mom_bitstream.c
 *
 * Modified :		
 * 21.05.96 - Noel O'Connor : modified to comply with VM2.1
 * 17.09.96 - M.Wollborn: time writing modified with respect to VM3.1	
 *	21.01.97 Added bitstuffing by Luis.
 * 04.02.97 Noel O'Connor: mods for non unique VOl Ids 
 * 10.02.97 Fernando Jaureguizar: error corrected: GetVopIntraQuantizer()
 *          instead of GetVopQuantizer() in case of intra frame
 * 13.03.97 Minhua Zhou: Added B_VOPs
 * 15.04.97 Jan De Lameillieure : added writing of the flag disable_sadct
 *          to bit-stream
 * 21.04.97 Jan De Lameillieure : added writing of VOP_gray_quant to bit-stream
 * 07.05.97 Noel Brady: added writing of VOP_CR and change_CR_disable
 * 09.05.97 Minhua Zhou:  modified "modulo_time_base" and "VOP_time_increment"
 *          according to VM7.x 
 * 04.08.97 Minhua Zhou: added f_code in the VOP Layer 
 * 04.08.97 Minhua Zhou: added intra_dc_vlc_thr
 * 05.08.97 Minhua Zhou: added vop_coded, removed sadct_disable
 * 06.08.97 Noel Brady: In BINARY_SHAPE_ONLY mode, several fields in 
 *				the VOP header are not sent.
 * 28.08.97 Osamu Sunohara: modified to calclate modulo_time_base in
 *          spatial scalability exactly. 
 * 08.09.97 Cecile Dufour: added the 3 last arguments for Static sprites
 * 27.03.98 M.Wollborn: Modifications due to N2171 Cl. 2.5.14
 *
 ***********************************************************CommentEnd********/
 
UInt
BitstreamPutVopHeader(Vop *vop,
		      Int vo_id,
		      Float time, Int TRB, /* TRB!=0<--> B_VOP*/
		      VolConfig *vol_config,
		      BitCount num_bits[MAX_NUM_VOS][MAX_NUM_VOLS],
		      VOConfig *vo_config_list, 
		      Int rc_type,
/*** 10/27 TPS */
                      Int modulo_tps)
/* 10/27 TPS ***/
{
  Image	*buffer;
  Int bits;
  Int	time_modulo,
        vol_id;
  Float time_inc;

  Int	index;
  
  UInt	num_bits_header=0;
  Float	brightness_factor;
  Int	tmp_blendfact;
  Int	piece_width, piece_height, piece_xoffset, piece_yoffset, tmp_val;
  
  /* Set up intermediate integer level data structure */
  buffer = BitstreamInit();
  
  /* 
   *
   * Write all syntax fields in vop header to data structure
   *
   */
  
   vol_id = GetVolConfigId(vol_config);
  
   BitstreamPutBits(buffer,VOP_START_CODE,VOP_START_CODE_LENGTH); 
   
   BitstreamPutBits(buffer,GetVopPredictionType(vop),2);

  /* Get last encoded modulo time base */
  
/* SONY 070498 - start */  
  index = GetVolConfigModTimeBase(vol_config,
        ((GetVopPredictionType(vop)==B_VOP&&GetVopRefSelCode(vop)==0)||(GetVopPredictionType(vop)!=B_VOP))?1:0);
/* SONY 070498 - end */

/* 280897 */

  time_modulo = time - index*1000;
  while(time_modulo >= 1000)
    {
      BitstreamPutBits(buffer,1,1);
      time_modulo = time_modulo - 1000;
      index++;
      printf("time modulo : 1\n");
    }
  BitstreamPutBits(buffer,0,1);
  
  /* Store this modulo time base */
  if(modulo_tps ==1) 
    PutVolConfigModTimeBase(index,vol_config);
  
  if (GetVopPredictionType(vop)!=B_VOP)
    PutVolConfigModTimeBase(index,vol_config);	

  time_inc = (time - index*1000);
  
  bits = ceil(log((double)GetVopTimeIncrementResolution(vop))/log(2.0));
  if (bits<1) bits=1;
  time_inc=time_inc*(double)GetVopTimeIncrementResolution(vop)/1000.0;
  
  /* marker bit */
  BitstreamPutBits(buffer,1,1);
  
  BitstreamPutBits(buffer,(Int)(time_inc+0.001),bits);
  
  /* marker bit */
  BitstreamPutBits(buffer,1,1);
  
  if (GetVopWidth(vop)==0) 
    {
      BitstreamPutBits(buffer,0L,1L);
      num_bits_header = BitstreamPut(buffer,vo_id,vol_id);
      num_bits_header +=NextStartCode(vo_id,vol_id); 
      BitstreamFree(buffer);
      return(num_bits_header);
    } 
  else 
    BitstreamPutBits(buffer,1L,1L);

  if ( GetVolConfigShape(vol_config) != BINARY_SHAPE_ONLY)		/* BSO_NOEL */
    {  
      
      if( GetVopPredictionType(vop) == P_VOP ||
	  ( GetVolConfigSpriteUsage(vol_config) != STATIC_SPRITE &&
	    GetVopPredictionType(vop) == SPRITE_VOP))
        BitstreamPutBits(buffer,GetVopRoundingType(vop),1);
    }		/* BSO_NOEL */

  if(GetVolConfigShape(vol_config) != RECTANGULAR)
    {
  if (!(GetVopSpriteUsage(vop)==STATIC_SPRITE&&
  			GetVopPredictionType(vop)==I_VOP))
     {
      BitstreamPutBits(buffer,GetVopWidth(vop),13);
        
      /* marker bit */
      BitstreamPutBits(buffer,1,1);
      
      BitstreamPutBits(buffer,GetVopHeight(vop),13);		
      
#ifdef _WD_MODE_
      /* marker bit */
      BitstreamPutBits(buffer,1,1);
#endif
      /* C. Dufour revised on 12/12/97 for low-latency sprite */      
      if ( GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE &&
	   GetVopPredictionType(vop) == I_VOP)
        {
	  tmp_val = GetVopHorSpatRef(vop) + 
	    GetVolConfigSpriteLeftEdge(vol_config);
	  if (tmp_val<0) tmp_val +=8192; 
	    BitstreamPutBits(buffer,tmp_val,13);
        }
      else
      /* end revision */
	{
	  BitstreamPutBits(buffer,GetVopHorSpatRef(vop),13);
	}

      /* marker bit */
      BitstreamPutBits(buffer,1,1);
      
      /* C. Dufour revised on 12/12/97 for low-latency sprite */      
      if ( GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE &&
	   GetVopPredictionType(vop) == I_VOP)
        {
	  tmp_val = GetVopVerSpatRef(vop) + 
	    GetVolConfigSpriteTopEdge(vol_config);
	  if (tmp_val<0) tmp_val +=8192; 
	    BitstreamPutBits(buffer,tmp_val,13);
        }
      else
      /* end revision */
	{      
	  BitstreamPutBits(buffer,GetVopVerSpatRef(vop),13);
	}
      } /* Not (STATIC_SPRITE and I_VOP) */

      if(GetVolConfigScalability(vol_config) && 
	 GetVolConfigEnhanceType(vol_config))
        /* for TPS */
        BitstreamPutBits(buffer, GetVopBackComp(vop), 1);
        /**/
#ifndef _WD_MODE_
        /* VOP_CR - temporary measure*/
      BitstreamPutBits(buffer,0,1);
#endif
      
      /* change_CR_disable */
      BitstreamPutBits(buffer,GetVopChangeCRDisable(vop),1);

      PutVopConstantAlpha(0,vop);
      BitstreamPutBits(buffer,GetVopConstantAlpha(vop),1);
      if (GetVopConstantAlpha(vop)) 
        BitstreamPutBits(buffer,GetVopConstantAlphaValue(vop),8);
    }
  
  if (GetVolConfigShape(vol_config) != BINARY_SHAPE_ONLY) /* BSO_NOEL */
    {  
      PutVopIntraDCVlcThr(0,vop);
      BitstreamPutBits(buffer,GetVopIntraDCVlcThr(vop),3);
      BitstreamPutBits(buffer, GetVopInterlaced(vop) , 1);
      if (GetVopInterlaced(vop)) 
	{
	  BitstreamPutBits(buffer, GetVopTopFieldFirst(vop),1);
	  BitstreamPutBits(buffer, GetVopAlternateScan(vop),1);
        }
    }

 
  /* SPRITE SPRITE SPRITE */
  if ((GetVolConfigSpriteUsage(vol_config)!= SPRITE_NOT_USED )
      &&(GetVopPredictionType(vop)==SPRITE_VOP) )
    {
      if (GetVolConfigNoOfSpritePoints(vol_config)) 
      	{
	  EncodeSpriteTraj(GetVopDiffTrajPointCoord(vop),buffer,
			   GetVolConfigNoOfSpritePoints(vol_config),
			   GetVolConfigSpriteUsage(vol_config));
      	}
      if (GetVolConfigBrightnessChangeInSprite(vol_config))
        brightness_factor = encode_brightness_change_factor (GetVopBrightnessChangeFactor(vop) ,buffer);
      else
        brightness_factor = 1;
      
      PutVopBrightnessChangeFactor(brightness_factor, vop);
      if (GetVolConfigSpriteUsage(vol_config) == STATIC_SPRITE)
	{
	  if (GetVolConfigSpriteTransmitMode(vol_config)!=STOP)
	    {
	      do
		{ 
		  FindNextSpritePieceCoord(vop,vol_config,
					   &piece_width, &piece_height,
					   &piece_xoffset, &piece_yoffset);

		  BitstreamPutBits(buffer,GetVolConfigSpriteTransmitMode(vol_config),2);
		  num_bits_header += BitstreamPut(buffer,vo_id,vol_id);
		  BitstreamFree(buffer);
		  buffer = BitstreamInit();
		
		  if (GetVolConfigSpriteTransmitMode(vol_config)==PIECE ||
		      GetVolConfigSpriteTransmitMode(vol_config)==UPDATE)
		    {
		      EncodeSpritePiece(vol_config,
					vo_id, vol_id,
					piece_width,
					piece_height,
					piece_xoffset,
					piece_yoffset,
					num_bits,
					vo_config_list,
					rc_type);
		      num_bits_header += num_bits[vo_id][vol_id].sprite_piece;
		    }
		} while (GetVolConfigSpriteTransmitMode(vol_config)!=STOP &&
			 GetVolConfigSpriteTransmitMode(vol_config)!=PAUSE);
	    }

	  num_bits_header += BitstreamPut(buffer,vo_id,vol_id);
	  /* No longer require the intermediate data structure */
	  BitstreamFree(buffer);
	  return(num_bits_header);
	}
      
      if (GetVolConfigSpriteUsage(vol_config)==ONLINE_SPRITE)
	{
	  /* Transmit alpha value multiplied by 254 since 8 bits used */
	  /* 254 is better than 255 because one can get 0.5 exactly */
	  tmp_blendfact = (Int)(GetVolConfigBlendFact(vol_config));
	  fprintf(stdout, "\n*** Blending factor has been quantized to %f \n", GetVolConfigBlendFact(vol_config) / 254.0 );
	  BitstreamPutBits(buffer, tmp_blendfact, 8);
	}
    }
  
  if (GetVolConfigShape(vol_config) != BINARY_SHAPE_ONLY) /* BSO_NOEL */
    {
      if (GetVopPredictionType(vop) == I_VOP) 	/* I_VOP */
        BitstreamPutBits(buffer,GetVopIntraQuantizer(vop),GetVopQuantPrecision(vop));
      else  if (GetVopPredictionType(vop) == B_VOP)
        BitstreamPutBits(buffer,GetVopBQuantizer(vop),GetVopQuantPrecision(vop));
      else
        BitstreamPutBits(buffer,GetVopQuantizer(vop),GetVopQuantPrecision(vop));

#ifndef _WD_MODE_    
      if(GetVolConfigShape(vol_config) == GREY_SCALE)		/* added by JDL 21-APR-97 */
        BitstreamPutBits(buffer,GetVopGLQuantizer(vop),6);
#endif
 
      /* added by Minhua Zhou 04.08.97 */
      if (GetVopPredictionType(vop)!=I_VOP)
        BitstreamPutBits(buffer,GetVopFCodeFor(vop),3);
      if (GetVopPredictionType(vop)==B_VOP) 
        BitstreamPutBits(buffer,GetVopFCodeBack(vop),3);
   
      if (!GetVopScalability(vop))
	{
	  /* Modified due to N2171 Cl. 2.5.14 MW 27-MAR-1998 */
	  /* if (!GetVopErrorResDisable(vop)) */
	  /*   { */
	  if (GetVopShape(vop) && (GetVopPredictionType(vop)!=I_VOP))
	    BitstreamPutBits(buffer,GetVopShapeCodingType(vop),1);
	  /*   } */
	}
   
      /* Background composition not implemented yet here (UPS)*/

      /*  WriteBGCAlphaBitstream in Enhance_vop used
	  if(( GetVopPredictionType(vop)== P_VOP  && GetVopRefSelCode(vop) ==3)
	       || ( GetVopPredictionType(vop)==B_VOP && GetVopRefSelCode(vop) ==0)) 
	    {
	    BitstreamPutBits(buffer,GetVopRefSelCode(vop),2);
	    if(GetVopPredictionType(vop)==P_VOP ||GetVopPredictionType(vop)==B_VOP)
	      {
	        BitstreamPutBits(buffer,GetVopForTempRef(vop),10);
		if(GetVopPredictionType(vop)==B_VOP)
		  {
		    BitstreamPutBits(buffer, 1, 1);
		    BitstreamPutBits(buffer,GetVopBackTempRef(vop),10);
		  }
	      }
	    }*//*end of ssp (UPS)*/
		  
    } /* BSO_NOEL */	      
  
  /*
   *
   * Write intermediate bitstream data structure to disk
   *
   */
  num_bits_header += BitstreamPut(buffer,vo_id,vol_id);
  
  /* No longer require the intermediate data structure */
  BitstreamFree(buffer);
  
  return(num_bits_header);
}

/***********************************************************CommentBegin******
 *
 * -- SetUpRecVop -- Sets up the reconstructed vop structure
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	23-04-96
 *
 * Purpose :	
 * This function sets up a reconstructed vop structure in which the
 * result of coding a particular vop will be stored. The reconstructed
 * vop will have the same dimensions as the vop to be coded. The function
 * CloneVop() is called which returns an exact copy of the vop to
 * be coded (incl. image fields). The image fields of the reconstructed vop
 * are then initialised.	
 * 
 * Arguments in : 	
 *  Vop *vop - pointer to the vop to be coded which is the basis for
 *				setting up the reconstructed vop
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	-
 *
 * Return values :	
 *	Vop *rec_vop - pointer to the newly allocated and initialised 
 *					reconstructed vop
 *
 * Side effects :	
 *	Memory is allocated in this function for rec_vop
 *
 * Description :	
 *	-
 *
 * See also :
 *	-
 *
 * Modified :		
 *	21.01.97 Robert Danielsen: Set to 0 for chroma instead of 128.
 *          Fix by Noel/Paulo.
 *
 ***********************************************************CommentEnd********/

Vop *
SetUpRecVop(Vop *vop)
{
	Vop	*rec_vop;

	Image *y,
			*u,
			*v,
			*alpha;

	/* Reconstructed current will be the same size as the
	bounded vop with the same vop information */
	rec_vop = CloneVop(vop);

	y = GetVopY(rec_vop);
	u = GetVopU(rec_vop);
	v = GetVopV(rec_vop);
	alpha = GetVopA(rec_vop);

	/* CloneVop() also copies image fields of input vop. For 
	reconstructed vop these should be initialised to zero for Y
	and 128 for U and V. */
	SetConstantImage(y,0);
	SetConstantImage(u,0);
	SetConstantImage(v,0);
	SetConstantImage(alpha,0);

	return(rec_vop);
}


/***********************************************************CommentBegin******
 *
 * -- WriteCodedVopToDisk -- Writes a coded vop to disk
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	19-04-96
 *
 * Purpose :	
 *	This function takes as input a coded vop and writes it to disk.
 *	The coded vop is bounded. It is possible (indeed very likely) that the 
 * size of the bounding box will change during the course of coding an
 * entire sequence. Thus the vop to be written to disk is first "pasted"
 * into a newly allocated vop which has dimensions of disk_vop_width
 *	& disk_vop_height.The coded vop is pasted in at location 
 *	(hor_spat_ref,ver_spat_ref). In this way each frame in the disk
 *	sequence of coded vops is garaunteed to
 * be the same size. The coded vop is also masked by the coded
 *	alpha channel before it is written to disk. This is just so that
 *	the image on disk contains no padding data, just the active
 *	vop.
 * 
 * Arguments in : 	
 * Vop *vop - pointer to the bounded vop whcih is to be written to disk
 * Char *y_file - name of file containing coded Y image on disk
 * Char *u_file - name of file containing coded U image on disk
 * Char *v_file - name of file containing coded V image on disk
 *	Char *a_file - name of file containing coded Alpha image on disk
 *	Int time - time instant
 *	Int	disk_vop_width - X dimension of file to be written to disk
 *	Int disk_vop_height - Y dimension of file to be written to disk
 * Int write_alpha - Flag indication whether or not to write the alpha
 *		channel to disk
 * Int vop_has_content - Flag for empty VOPs.
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	-
 *
 * Return values :	
 *  -
 *
 * Side effects :	
 *  -
 *
 * Description :	
 *	-
 *
 * See also :
 *	-
 *
 * Modified :		
 *
 *	Put the two "pel_in++" out of the if-loop; bug reported
 *			by Kevin O'Connel on 26-JUN-1996 (M.Wollborn)
 *  	20-MAR-97 Jan De Lameillieure (HHI) : added shape argument
 *			to SubsampleAlphaMap()
 *      26.05.97 Minhua Zhou: removed SubsampleAlphaMap()
 *
 ***********************************************************CommentEnd********/
 
Void
WriteCodedVopToDisk(Vop *vop,
	Char *y_file,
	Char *u_file,
	Char *v_file,
	Char *a_file,
	Int time,
	Int	disk_vop_width,
	Int disk_vop_height,
	Int shape,
		Int vop_has_content)
{
	Vop	*disk_vop;
	
	Image *y_in,
			*u_in,
			*v_in,
			*a_in,
			*y_out,
			*u_out,
			*v_out,
			*a_out,
			*a_sub;
			
	Int	x,y,
			hor_ref, ver_ref,
			dim_x, dim_y,
			pel_in,
			pel_out,
			alpha_active=0;
	
	SInt	*ptr_in_1,
			*ptr_out_1,
			*ptr_in_2,
			*ptr_out_2,
			*ptr_alp;
	
	
	/* Allocate memory for vop to be written to disk */ 
	disk_vop = AllocVop(disk_vop_width,disk_vop_height);
	PutVopBitsPerPixel(GetVopBitsPerPixel(vop),disk_vop);

	if(vop_has_content)
		{
		/* Set up pointer to image structures */
		y_in = GetVopY(vop);
		u_in = GetVopU(vop);
		v_in = GetVopV(vop);
		a_in = GetVopA(vop);
		y_out = GetVopY(disk_vop);
		u_out = GetVopU(disk_vop);
		v_out = GetVopV(disk_vop);
		a_out = GetVopA(disk_vop);
	
		/* Get location at which to copy coded vop into disk_vop */
		hor_ref = GetVopHorSpatRef(vop);
		ver_ref = GetVopVerSpatRef(vop);
	
		/* Initialise U and V fields of disk vop to 128 */
		SetConstantImage(u_out,128);
		SetConstantImage(v_out,128);
	
		/* Get size of coded vop */
		dim_x = GetImageSizeX(y_in);
		dim_y = GetImageSizeY(y_in);
	
		/* Paste coded vop into vop to be written to disk at
		horizontal and vertical spatial reference.
		Mask the coded vop with the alpha map. */
	
		/* Y and Alpha first */
		ptr_in_1 = (SInt *)GetImageData(y_in);
		ptr_out_1 = (SInt *)GetImageData(y_out);
		ptr_in_2 = (SInt *)GetImageData(a_in);
		ptr_out_2 = (SInt *)GetImageData(a_out);
	
		pel_in = 0;
		for(y=ver_ref;y<ver_ref + dim_y; y++)
			for(x=hor_ref;x<hor_ref + dim_x; x++)
				{
				if(ValidCoordinate(x,y,disk_vop_width,disk_vop_height))
					{
					/* Mask the coded output with the coded alpha channel */
					if(ptr_in_2[pel_in])
						{
						pel_out = y * disk_vop_width + x;
						ptr_out_1[pel_out] = ptr_in_1[pel_in];
						ptr_out_2[pel_out] = ptr_in_2[pel_in];
						}
					}
				pel_in++; /* Put out of loop, MW 26-JUN-1996 */
				}

		/* Subsample the alpha map so that it can be used to mask the
		coded U and V channels */
		a_sub = GetVopAuv(vop);
			
		/* U and Y next */
		ptr_in_1 = (SInt *)GetImageData(u_in);
		ptr_out_1 = (SInt *)GetImageData(u_out);
		ptr_in_2 = (SInt *)GetImageData(v_in);
		ptr_out_2 = (SInt *)GetImageData(v_out);
		ptr_alp = (SInt *)GetImageData(a_sub);

		pel_in = 0;
		for(y=(ver_ref/2);y<(ver_ref + dim_y)/2; y++)
			for(x=(hor_ref/2);x<(hor_ref + dim_x)/2; x++)
				{
				if(ValidCoordinate(x,y,disk_vop_width/2,disk_vop_height/2))
					{
					/* Mask the coded output with the (subsampled) coded
					alpha channel */
					if(ptr_alp[pel_in])
						{
						pel_out = y * (disk_vop_width/2) + x;
						ptr_out_1[pel_out] = ptr_in_1[pel_in];
						ptr_out_2[pel_out] = ptr_in_2[pel_in];
						}
					}
				pel_in++; /* Put out of loop, MW 26-JUN-1996 */
				}

		/* Write disk_vop to disk */
		if(shape == RECTANGULAR)
			alpha_active = FALSE;
		else
			alpha_active = TRUE;	
		
		}

	if(time == 0)
		WriteVopGeneric(disk_vop,
							y_file,
							u_file,
							v_file,
							a_file,
							time,
							IO_FORMAT,
							IO_OVERWRITE,
							alpha_active);
	else
		WriteVopGeneric(disk_vop,
							y_file,
							u_file,
							v_file,
							a_file,
							time,
							IO_FORMAT,
							IO_APPEND,
							alpha_active);


	/* Deallocate vop memory */
	FreeVop(disk_vop);
	
	/* Deallocate subampled alpha map */
	/* Only if VOP has content, MW 13-SEP-1996 */
	/* FreeImage(a_sub); */
	
	return;
}


/***********************************************************CommentBegin******
 *
 * -- cal_fcode -- 
 *
 * Author :		
 *	Minhua Zhou
 *
 * Created :		
 *	04.08.97
 *
 * Purpose : calculate f_code according to the given search range	
  * 
 * Arguments in : 	
 *      Int  sr    : search range
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	-
 *
 * Return values :	
 *   f_code
 *
 * Side effects :	
 *  -
 *
 * Description :	
 *	-
 *
 * See also :
 *	-
 *
 * Modified :		
 *
 *
 ***********************************************************CommentEnd********/

Int cal_fcode (Int sr) {
 if (sr<=16) return 1; 
  else if (sr<=32) return 2;
    else if (sr<=64) return 3;
     else if (sr<=128) return 4;
      else if (sr<=256) return 5;
        else if (sr<=512) return 6;
         else if (sr<=1024) return 7;
           else {
     fprintf(stdout, "ERROR in cal_search_range\n");
     return (-1);
   } 
}





/***********************************************************CommentBegin******
 *
 * -- BitstreamPutHEC -- Writes Header Extension Code (HEC) syntax
 *
 * Author :		
 *	Michael Wollborn
 *
 * Created :		
 *	27-MAR-1998
 *
 * Purpose :		
 * 
 * Arguments in : 	
 *      VolConfig * vol_config - pointer to the VOL configuration data
 *	Vop *curr              - pointer to the current VOP
 *      Float time             - current encoding time
 *
 * Arguments in/out :	
 *	Image *aux_bitstream   - intermediate bitstream for syntax
 *
 * Arguments out :	
 *	-
 *
 * Return values :	
 *	-
 *
 * Side effects :	
 *	-
 *
 * Description :	
 *
 * See also :
 *
 * Modified :	27.03.98 M. Wollborn: included intra_dc_vlc_thr 
 *			              due to N2171, Cl. 2.5.3
 *	
 ***********************************************************CommentEnd********/

Void BitstreamPutHEC(VolConfig *vol_config, Vop *curr, Float time, Image *aux_bitstream)
{
  Int           index,time_modulo;
  Int           bits;
  Float         time_inc;

  /*****
   *
   *    Write the header extension code to the bitstream
   *
   *****/
  index = GetVolConfigModTimeBase(vol_config,0);
  time_modulo = time - index*1000;
  while(time_modulo >= 1000)
    {
      BitstreamPutBits(aux_bitstream,1,1);
      time_modulo = time_modulo - 1000;
      index++;
    }
  BitstreamPutBits(aux_bitstream,0,1);
  
  time_inc = (time - index*1000);
  bits = ceil(log((double)GetVopTimeIncrementResolution(curr))/log(2.0));
  if (bits<1) 
    bits=1;
  time_inc=time_inc*(double)GetVopTimeIncrementResolution(curr)/1000.0;
  BitstreamPutBits(aux_bitstream,1,1); /* marker bit */
  BitstreamPutBits(aux_bitstream,(Int)(time_inc+0.001),bits);
  BitstreamPutBits(aux_bitstream,1,1); /* marker */
  BitstreamPutBits(aux_bitstream,GetVopPredictionType(curr),2);
  
  if (GetVopShape(curr) != BINARY_SHAPE_ONLY)		
    {
      /* Added "intra_dc_vlc_thr" due to N2171 Cl. 2.5.3 MW 27-MAR-1998 */
      PutVopIntraDCVlcThr(0,curr);
      BitstreamPutBits(aux_bitstream,GetVopIntraDCVlcThr(curr),3);

      if (GetVopPredictionType(curr) != I_VOP)
        BitstreamPutBits(aux_bitstream,GetVopFCodeFor(curr),3);
      if (GetVopPredictionType(curr) == B_VOP)
        BitstreamPutBits(aux_bitstream,GetVopFCodeBack(curr),3);
    }

  return;
}
