/*****************************************************************************
 *
 * This software module was originally developed by
 *
 *   Noel O'Connor (Teltec DCU / ACTS-MoMuSyS)
 *   Michael Wollborn (TUH / ACTS-MoMuSyS)
 *
 * and edited by
 * 
 *   Robert Danielsen (Telenor / ACTS-MoMuSyS)
 *   Aasmund Sandvand (Telenor / ACTS-MoMuSyS)
 *   Bob Eifrig (NextLevel Systems)
 *   Michael Frater (UNSW)
 *
 * in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard.
 * This software module is an implementation of a part of one or more MPEG-4
 * Video (ISO/IEC 14496-2) tools as specified by the MPEG-4 Video (ISO/IEC
 * 14496-2) standard.
 *
 * ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard free
 * license to this software module or modifications thereof for use in hardware
 * or software products claiming conformance to the MPEG-4 Video (ISO/IEC
 * 14496-2) standard.
 *
 * Those intending to use this software module in hardware or software products
 * are advised that its use may infringe existing patents. The original
 * developer of this software module and his/her company, the subsequent
 * editors and their companies, and ISO/IEC have no liability for use of this
 * software module or modifications thereof in an implementation. Copyright is
 * not released for non MPEG-4 Video (ISO/IEC 14496-2) Standard conforming
 * products.
 *
 * ACTS-MoMuSys partners retain full right to use the code for his/her own
 * purpose, assign or donate the code to a third party and to inhibit third
 * parties from using the code for non MPEG-4 Video (ISO/IEC 14496-2) Standard
 * conforming products. This copyright notice must be included in all copies or
 * derivative works.
 *
 * Copyright (c) 1996
 *
 *****************************************************************************/


/***********************************************************HeaderBegin*******
 *                                                                         
 * File:	mom_vop.c
 *
 * Author:	Noel O'Connor
 * Created:	20-Feb-96
 *                                                                         
 * Description: 
 *
 * Notes: 	
 *
 * Modified:	21.04.96 Robert Danielsen: Reformatted. New headers.
 *              01.02.97 Aasmund Sandvand: Added QP_chan to vop structure
 *              26.04.97 Luis Ducla-Soares: Added syntax elements for data
 *                                          partitioning in CopyVopNonImageField().
 *              04.01.98 Michael Frater: support for non-8-bit video
 * 
 ***********************************************************HeaderEnd*********/

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

#include <stdio.h>
#include <stdlib.h>
#include "momusys.h"
#include "mom_access.h"
#include "mom_image.h"
#include "mom_vop.h"


/***********************************************************CommentBegin******
 *
 * -- SallocVop -- Allocate memory for a vop data structure
 *
 * Author :		
 *	Noel O'Connor
 *
 * Created :		
 *	20-Feb-96
 *
 * Purpose :		
 *	Allocate memory for a vop data structure
 * 
 * Arguments in : 	
 *	none
 *
 * Arguments in/out :	
 *	none
 *
 * Arguments out :	
 *	none
 *
 * Return values :	
 *	pointer to the new vop
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	Allocate memory for a Vop structure without allocating
 *   	memory for the various image fields
 *
 * See also :
 *	
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Vop *
SallocVop()
{
  Vop	*vop;

  vop = (Vop *)ecalloc(1,sizeof(Vop));

  return(vop);
}

/***********************************************************CommentBegin******
 *
 * -- AllocVop -- Allocate memory for a vop and it's image fields.
 *
 * Author :		
 *	Noel O'Connor
 *
 * Created :		
 *	20-Feb-96 
 *
 * Purpose :		
 *	Allocate memory for a vop and it's image fields.
 * 
 * Arguments in : 	
 *	UInt x :
 *   	UInt y :	dimensions of the data field
 *
 * Arguments in/out :	
 *	none
 *
 * Arguments out :	
 *	none
 *
 * Return values :	
 *	pointer to the new vop
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	Allocate memory for a Vop structure, and for the YUV and Alpha
 *  	fields.  It is assumed that the alpha map has the same 
 *   	width and height as Y, whilst U and V have dimensions
 *   	width/2 and height/2.
 *
 * See also :
 *	
 *
 * Modified :
 *         26.05.97: Minhua Zhou: added a_chan_uv
 *         24.07.97: Minhua Zhou: added PutVopPrevTemp(NULL,vop)
 *         26.08.97: Minhua Zhou: changed the size of Qp_chan	
 *         17.04.98: Minhua Zhou: added shape mode to VOP definition	
 *	
 *
 ***********************************************************CommentEnd********/

Vop *
AllocVop(UInt x, UInt y)
{
  Vop		*vop;

  Image	*a_chan,*a_chan_uv,
    *y_chan,
    *u_chan,
    *v_chan,
    *QP_chan,
    *shape_mode; 

  /* first allocate memory for the data structure */
  vop = SallocVop();

  PutVopWidth(x,vop);
  PutVopHeight(y,vop);

  /* Allocate image fields */
  a_chan = AllocImage(x,y,SHORT_TYPE);
  a_chan_uv = AllocImage(x/2,y/2,SHORT_TYPE);
   
  
  y_chan = AllocImage(x,y,SHORT_TYPE);
  u_chan = AllocImage(x/2,y/2,SHORT_TYPE);
  v_chan = AllocImage(x/2,y/2,SHORT_TYPE);
  QP_chan = AllocImage(x/16+((x/16)?0:1),y/16+((y/16)?0:1),SHORT_TYPE);
  shape_mode = AllocImage(x/16+((x/16)?0:1),y/16+((y/16)?0:1),SHORT_TYPE);

  /* Include image fields in structure */
  PutVopA(a_chan,vop);
  PutVopAuv(a_chan_uv,vop);
  PutVopY(y_chan,vop);
  PutVopU(u_chan,vop);
  PutVopV(v_chan,vop);

  PutVopQP(QP_chan, vop);
  PutVopShapeMode(shape_mode, vop);

  /* Set vop extensions to NULL pointers */
  PutVopExtend(NULL,vop);
  PutVopNextSpat(NULL,vop);
  PutVopNextTemp(NULL,vop);
  PutVopPrevTemp(NULL,vop);

  PutVopSprite(NULL,vop);
/*** 10/30 TEST */
/*  printf("alloc %10d\n",vop); */
/* 10/30 TEST ***/
	
  return(vop);
}

/*************************************************CommentBegin****************
 *
 * -- Func -- xxxxxxxxxxxxxx
 *
 *       Vop *AllocVopChannels(Vop *vop, UInt x, UInt y)
 *
 * Purpose :
 * 
 *     	Allocate memory for the vop channels
 * 
 * 
 * 
 * Arguments in:      
 *	UInt x :
 *   	UInt y :	dimensions of the data field
 *	vop:		pointer on given vop
 *
 *
 * Arguments in/out:  	none
 *
 *
 *
 * Arguments out:     	none
 *
 *
 *
 * Description:
 *
 *   Allocate memory for the Vop channels: YUV and Alpha
 *   fields.  It is assumed that the alpha map has the same 
 *   width and height as Y, whilst U and V have dimensions
 *   width/2 and height/2, and the other vops fields areç
 *   already allocated.
 *
 *
 * Return values:     	none
 *
 *
 * Side effects:     	 none
 *
 *
 * See also:          	---
 * Modified :
 *         26.05.97: Minhua Zhou: added a_chan_uv	
 *         26.08.97: Minhua Zhou: changed the size of Qp_chan
 *         17.04.98: Minhua Zhou: added the shape mode to VOP
 *
 *************************************************CommentEnd******************/

Void AllocVopChannels(Vop *vop, UInt x, UInt y)
{
  Image	*a_chan,
	  *y_chan,
	  *u_chan,
	  *v_chan,
	  *QP_chan,
          *a_chan_uv,
          *shape_mode; 

	/* Allocate image fields */
	a_chan = AllocImage(x,y,SHORT_TYPE);
        a_chan_uv = AllocImage(x/2,y/2,SHORT_TYPE);
	y_chan = AllocImage(x,y,SHORT_TYPE);
	u_chan = AllocImage(x/2,y/2,SHORT_TYPE);
	v_chan = AllocImage(x/2,y/2,SHORT_TYPE);

	QP_chan = AllocImage(x/16+((x/16)?0:1),y/16+((y/16)?0:1),SHORT_TYPE);
        shape_mode = AllocImage(x/16+((x/16)?0:1),y/16+((y/16)?0:1),SHORT_TYPE);

	/* Include image fields in structure */
	PutVopA(a_chan,vop);
        PutVopAuv(a_chan_uv,vop);
	PutVopY(y_chan,vop);
	PutVopU(u_chan,vop);
	PutVopV(v_chan,vop);
	PutVopQP(QP_chan,vop);
        PutVopShapeMode(shape_mode,vop);


}
/***********************************************************CommentBegin******
 *
 * -- SfreeVop -- Frees a vop without data areas
 *
 * Author :		
 *	Robert Danielsen <Robert.Danielsen@nta.no>
 *
 * Created :		
 *	12.04.96
 *
 * Purpose :		
 *	Frees a vop without data areas
 * 
 * Arguments in : 	
 *	Vop to be freed
 *
 * Arguments in/out :	
 *	none
 *
 * Arguments out :	
 *	none
 *
 * Return values :	
 *	none
 *
 * Side effects :	
 *	Does not free the data areas of the vop
 *
 * Description :	
 *	
 *
 * See also :
 *	
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Void
SfreeVop (Vop *vop)
{
  free ((Char*)vop);
  /* vop = NULL; */ /*SpSc: initially put for SpSc */
  return;
}

/***********************************************************CommentBegin******
 *
 * -- FreeVop -- deallocate memory for a vop
 *
 * Author :		
 *	
 *
 * Created :		
 *	
 *
 * Purpose :		
 *	These functions deallocate memory for a vop (incl. image data fields), 
 *	and a VopExtend structure
 *
 * 
 * Arguments in : 	
 *	pointer to structure to be freed
 *
 * Arguments in/out :	
 *	none
 *
 * Arguments out :	
 *	none
 *
 * Return values :	
 *	none
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	The function FreeVop() can be considered a "top level" function
 *	which also calls FreevopExtend().
 *	Since VopExtend is a user definable field
 *	only dummy deallocation routines are supplied for these.
 *
 * See also :
 *	
 *
 * Modified :	
 * 		  26.05.97: Minhua Zhou: added a_chan_uv
 *                17.04.98: Minhua Zhou: added shape mode 	
 *	
 *
 ***********************************************************CommentEnd********/

Void
FreeVop(Vop *vop)
{
  Image		*data=NULL; /*SpSc: added the initialization */

  VopExtend	*extend;

/*** 10/30 TEST */
/*  printf("free %10d\n",vop); */
/* 10/30 TEST ***/
  if(vop != NULL) {

    /* Deallocate memory for image fields */

    data = GetVopA(vop);
    FreeImage(data);
     
    data = GetVopAuv(vop);
    FreeImage(data); 

    data = GetVopY(vop);
    FreeImage(data);

    data = GetVopU(vop);
    FreeImage(data);

    data = GetVopV(vop);
    FreeImage(data);

    data = GetVopQP(vop);
    FreeImage(data);
    
    data = GetVopShapeMode(vop);
    FreeImage(data);

   
    /* Deallocate memory for VopExtend if it exists */
    extend = GetVopExtend(vop);
    if(extend != NULL)
      FreeVopExtend(extend);

    SfreeVop(vop);
  }

  return;
}


/***********************************************************CommentBegin******
 *
 * -- FreeVopExtend -- 
 *
 * Author :		
 *	
 *
 * Created :		
 *	
 *
 * Purpose :		
 *	Deallocates a VopExtend structure. This function should
 * 	be written by the user and tailored to their own VopExtend
 *	structure.
 * 
 * Arguments in : 	
 *	
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	
 *
 * See also :
 *	
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Void
FreeVopExtend(VopExtend *extend)
{
  /*****
   *
   *   DUMMY FUNCTION - USER DEFINED
   *
   ******/
  return;
}

/***********************************************************CommentBegin******
 *
 * -- {xxx}SpatList -- Manipulations of a linked list of Vops
 *
 *	Void AddVopToSpatList(Vop *vop, Vop *list)
 *	Void ReplaceVopInSpatList(Vop *vop, Vop *list)
 *	Void RemoveVopFromSpatList( Vop *vop, Vop *list)
 *
 * Author :		
 *	Noel O'Connor
 *
 * Created :		
 *	20-Feb-96
 *
 * Purpose :		
 *	These functions allow the manipulation of a linked list 	
 * 	of Vops, linked through the "pnext_spat" field of the
 * 	Vop structure.
 * 
 * Arguments in : 	
 *	Vop *vop (pointer to vop to be added/replaced)
 *
 * Arguments in/out :	
 *	Vop *list (pointer to list of vops)
 *
 * Arguments out :	
 *	-
 *
 * Return values :	
 *	none
 *
 * Side effects :	
 *	These funcions assume that the vop to be replaced/added
 *	is NOT the first vop in the list. This should be
 *	checked before these functions are called.
 *
 * Description :	
 *	Assumes list is not empty i.e. list != NULL
 *
 * See also :
 *	-
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Void
AddVopToSpatList(Vop *vop, Vop *list)
{
  Vop		*curr,
    *prev;

  prev = list;
  curr = GetVopNextSpat(prev);

  while(curr != NULL)
    {
      prev = curr;
      curr = GetVopNextSpat(prev);
    }

  PutVopNextSpat(vop,prev);

}

Void
RemoveVopFromSpatList(Vop *vop, Vop *list)
{
  int		id,
    		remove_id;

  Vop		*remove,
    		*prev;

  id = GetVopId(vop);

  prev = list;
  remove = GetVopNextSpat(prev);
  remove_id = GetVopId(remove);

  while ( (remove_id != id) && (remove != NULL) )
    {
      prev = remove;
      remove = GetVopNextSpat(prev);
      remove_id = GetVopId(remove);
    }

  if (remove_id == id) 
		{
			PutVopNextSpat(GetVopNextSpat(remove),prev);
			FreeVop(remove);
		}

  return;
}


Void
ReplaceVopInSpatList(Vop *vop, Vop *list)
{
  int		id,
    replace_id;

  Vop		*replace,
    *prev;

  id = GetVopId(vop);

  prev = list;
  replace = GetVopNextSpat(prev);
  replace_id = GetVopId(replace);

  while(replace_id != id)
    {
      prev = replace;
      replace = GetVopNextSpat(prev);
      replace_id = GetVopId(replace);
    }

  PutVopNextSpat(GetVopNextSpat(replace),vop);
	
  FreeVop(replace);
	
  PutVopNextSpat(vop,prev);

  return;
}

/***********************************************************CommentBegin******
 *
 * -- FreeVopSpatList -- 
 *
 * Author :		
 *	Noel O'Connor
 *
 * Created :		
 *	20-Feb-96  
 *
 * Purpose :		
 *	This function scans through a linked list of vops (linked through
 * 	the "pnext_spat" field of the Vop stucture), freeing all memory
 * 	allocated to each vop in the list.
 * 
 * Arguments in : 	
 *	Vop *list (pointer to list of vops)
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	-
 *
 * Return values :	
 *	none
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	-
 *
 * See also :
 *	-
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Void
FreeVopSpatList(Vop *list)
{
  Vop		*curr,
    *next;

  curr = list;

  while(curr != NULL)
    {
      next = GetVopNextSpat(curr);

      FreeVop(curr);

      curr = next;
    }
  return;
}

/*****
*
*	Add the given Vop * at the end of the given (Vop *)->pnext_temp list
*
*	Assumes list is not empty i.e. lis != NULL
*
******/
Void AddVopToTempList(Vop *vop, Vop *list)
{
	Vop		*curr,
			*prev;

	prev = list;
	curr = GetVopNextTemp(prev);

	while(curr != NULL)
	{
		prev = curr;
		curr = GetVopNextTemp(prev);
	}

	prev->pnext_temp = vop;

}


/* 
 *  Free the pnext_temp field vop list of a given vop
 */
Void FreeVopTempList(Vop *list)
{
	Vop		*curr,
			*next;

	curr = list;

	while(curr != NULL)
	{
		next = GetVopNextTemp(curr);

		FreeVop(curr);

		curr = next;
	}
	return;
}

/***********************************************************CommentBegin******
 *
 * -- CopyVopNonImageField -- 
 *
 * Author :		
 *	Noel O'Connor
 *
 * Created :		
 *	20-Feb-96
 *
 * Purpose :		
 *	This function copies all vop fields of the input vop to the 
 * 	output vop EXCEPT for any vop image fields (i.e. a_chan,
 * 	y_chan, u_chan, v_chan). It is useful for copying the
 * 	composition information from one vop to another without 
 *	overwriting the image data
 * 
 * Arguments in : 	
 *	Vop *in (pointer to input vop)
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	Vop *out (pointer to output vop)
 *
 * Return values :	
 *	none
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	-
 *
 * See also :
 *	
 *
 * Modified : 31.01.97 Aa. Sandvand Removed deblock_filter_disable
 *	22.04.97 Michael Wollborn: Added syntax elements for MPEG
 *				   quantization matrices
 *      28.04.97 Luis Ducla-Soares: Added syntax elements for data partitioning.
 *      26.05.97 Minhua Zhou: added advanced_prediction_disable
 *      09.07.97 Aasmund Sandvand: added VOId copying	
 *      04.08.97 Minhua Zhou: renamed advanced_prediction_disable
 *      12.08.97 Minhua Zhou: added time_increment_resolution
 *      04.11.97 Minhua Zhou: added flags according to CD
 *      12.12.97 Bob Eifrig: added code to copy interlaced fields
 *
 ***********************************************************CommentEnd********/

Void
CopyVopNonImageField(Vop *in,Vop *out)
{
  Int i;
  Int *iqmat_in,*iqmat_out,*nqmat_in,*nqmat_out,
      *gl_iqmat_in,*gl_iqmat_out,*gl_nqmat_in,*gl_nqmat_out;


PutVopIsObjectLayerIdentifier(GetVopIsObjectLayerIdentifier(in),out);
PutVopVisualObjectLayerVerid(GetVopVisualObjectLayerVerid(in),out); 
PutVopVisualObjectLayerPriority(GetVopVisualObjectLayerPriority(in),out);
PutVopVolControlParameters(GetVopVolControlParameters(in),out); 
PutVopFixedVopRate(GetVopFixedVopRate(in),out); 
PutVopQuantPrecision(GetVopQuantPrecision(in),out);
PutVopBitsPerPixel(GetVopBitsPerPixel(in),out);
PutVopComplexityEstimationDisable(GetVopComplexityEstimationDisable(in),out);
PutVopRandomAccessibleVol(GetVopRandomAccessibleVol(in),out);
PutVopConstantAlpha(GetVopConstantAlpha(in),out);
PutVopConstantAlphaValue(GetVopConstantAlphaValue(in),out);
PutVopInterlaced(GetVopInterlaced(in),out);
PutVopTopFieldFirst(GetVopTopFieldFirst(in),out);
PutVopAlternateScan(GetVopAlternateScan(in),out);
PutVopBQuantizer(GetVopBQuantizer(in),out);


  PutVopModTimeBase(GetVopModTimeBase(in),out);
  PutVopTimeInc(GetVopTimeInc(in),out);
  PutVopPredictionType(GetVopPredictionType(in),out);
  PutVopRoundingType(GetVopRoundingType(in),out);
  PutVopWidth(GetVopWidth(in),out);
  PutVopCoded(GetVopCoded(in),out);
  PutVopHeight(GetVopHeight(in),out);
  PutVopHorSpatRef(GetVopHorSpatRef(in),out);
  PutVopVerSpatRef(GetVopVerSpatRef(in),out);
  PutVopBackComp(GetVopBackComp(in),out);
  PutVopQuantizer(GetVopQuantizer(in),out);
  PutVopIntraQuantizer(GetVopIntraQuantizer(in),out);
  PutVopGLQuantizer(GetVopGLQuantizer(in),out);
  PutVopTimeIncrementResolution(GetVopTimeIncrementResolution(in),out);
  PutVopLoadBackShape(GetVopLoadBackShape(in),out);
  PutVopLoadForShape(GetVopLoadForShape(in),out);
  PutVopRefSelCode(GetVopRefSelCode(in),out);
  PutVopForTempRef(GetVopForTempRef(in),out);
  PutVopBackTempRef(GetVopBackTempRef(in),out);

  PutVopVOId(GetVopVOId(in),out);
  PutVopId(GetVopId(in),out);
  PutVopArbitraryShape(GetVopArbitraryShape(in),out);
  PutVopShapeEffects(GetVopShapeEffects(in),out);
  PutVopQuantType(GetVopQuantType(in),out);

  PutVopLoadIntraQuantMat(GetVopLoadIntraQuantMat(in),out);
  PutVopLoadNonintraQuantMat(GetVopLoadNonintraQuantMat(in),out);
  PutVopDisableGrayQuantUpdate(GetVopDisableGrayQuantUpdate(in),out);
  PutVopLoadGrayIntraQuantMat(GetVopLoadGrayIntraQuantMat(in),out);
  PutVopLoadGrayNonintraQuantMat(GetVopLoadGrayNonintraQuantMat(in),out);

  out->sr_direct   = in->sr_direct;
  out->mvfileusage = in->mvfileusage;
  out->mvfilename  = in->mvfilename;
  out->mvfile      = in->mvfile;
  out->mvlinenop   = in->mvlinenop;
  out->frame       = in->frame;
  
  if(GetVopQuantType(in))
    {
      iqmat_in  = GetVopIntraQuantMat(in);
      iqmat_out = GetVopIntraQuantMat(out);
      nqmat_in  = GetVopNonintraQuantMat(in);
      nqmat_out = GetVopNonintraQuantMat(out);

      gl_iqmat_in  = GetVopGrayIntraQuantMat(in);
      gl_iqmat_out = GetVopGrayIntraQuantMat(out);
      gl_nqmat_in  = GetVopGrayNonintraQuantMat(in);
      gl_nqmat_out = GetVopGrayNonintraQuantMat(out);

      for(i=0; i<64; i++)
        {
	  *(iqmat_out++) = *(iqmat_in++);
	  *(nqmat_out++) = *(nqmat_in++);
	  *(gl_iqmat_out++) = *(gl_iqmat_in++);
	  *(gl_nqmat_out++) = *(gl_nqmat_in++);
	}
    }

  PutVopIntraACDCPredDisable(GetVopIntraACDCPredDisable(in),out);
  PutVopErrorResDisable(GetVopErrorResDisable(in),out);
  PutVopDataPartEnable(GetVopDataPartEnable(in),out);
  PutVopReverseVlc(GetVopReverseVlc(in),out);
  PutVopFCodeFor(GetVopFCodeFor(in),out);
  PutVopFCodeBack(GetVopFCodeBack(in),out);
  PutVopSearchRangeFor(GetVopSearchRangeFor(in),out);
  PutVopSearchRangeBack(GetVopSearchRangeBack(in),out);

  PutVopScalability(GetVopScalability(in),out);
  PutVopSADCTDisable(GetVopSADCTDisable(in),out);
  PutVopOBMCDisable(GetVopOBMCDisable(in), out);
  PutVopIntraDCVlcThr(GetVopIntraDCVlcThr(in),out);

  PutVopRefId(GetVopRefId(in),out);
  PutVopRefSampDir(GetVopRefSampDir(in),out);
  PutVopHorSampN(GetVopHorSampN(in),out);
  PutVopHorSampM(GetVopHorSampM(in),out);
  PutVopVerSampN(GetVopVerSampN(in),out);
  PutVopVerSampM(GetVopVerSampM(in),out);
  PutVopEnhanceType(GetVopEnhanceType(in),out);

  PutVopScaling(GetVopScaling(in),out);
  PutVopVisibility(GetVopVisibility(in),out);
  PutVopBinaryShape(GetVopBinaryShape(in),out);
  PutVopCompOrder(GetVopCompOrder(in),out);	

  PutVopSpriteUsage(GetVopSpriteUsage(in),out);
  if (GetVopSpriteUsage(in))
  	{
	PutVopSpriteHdim(GetVopSpriteHdim(in), out);
	PutVopSpriteVdim(GetVopSpriteVdim(in), out);
	PutVopSpriteLeftEdge(GetVopSpriteLeftEdge(in), out);
	PutVopSpriteTopEdge(GetVopSpriteTopEdge(in), out);
	PutVopSprite(GetVopSprite(in),out);
	PutVopWarpParam(GetVopWarpParam(in),out);
	PutVopWarpingAccuracy(GetVopWarpingAccuracy(in),out);
	PutVopBlendFact(GetVopBlendFact(in),out);
	PutVopNoOfSpritePoints(GetVopNoOfSpritePoints(in),out);
	if (GetVopNoOfSpritePoints(in)) {
	  PutVopRefPointCoord(GetVopRefPointCoord(in),out);
	  PutVopTrajPointCoord(GetVopTrajPointCoord(in),out);
	}
	PutVopBrightnessChangeFactor(GetVopBrightnessChangeFactor(in),out);
	PutVopLowLatencySpriteEnable(GetVopLowLatencySpriteEnable(in),out);
	PutVopSpriteTabTransmit(GetVopSpriteTabTransmit(in),out);
	PutVopSpriteTabMvda(GetVopSpriteTabMvda(in),out);
	PutVopSpriteTabAmbType(GetVopSpriteTabAmbType(in),out);
	PutVopSpriteTabDCStore(GetVopSpriteTabDCStore(in),out);
	PutVopSpriteTabQPStore(GetVopSpriteTabQPStore(in),out);		
	PutVopSpriteTabDQUANTStore(GetVopSpriteTabDQUANTStore(in),out);		
	}
  PutVopChangeCRDisable(GetVopChangeCRDisable(in),out);
  PutVopErrorResDisable(GetVopErrorResDisable(in),out);
  PutVopShapeCodingType(GetVopShapeCodingType(in),out);

}

/***********************************************************CommentBegin******
 *
 * -- CloneVop -- 
 *
 * Author :		
 *	Noel O'Connor
 *
 * Created :		
 *	20-Feb-96
 *
 * Purpose :		
 *	This function allocates an output vop of the same size as the
 *	input vop and copies ALL fields of the input into the
 *	output vop. 
 * 
 * Arguments in : 	
 *	Vop *vop_in (pointer to input vop)
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	-
 *
 * Return values :	
 *	Pointer newly allocated and copied vop
 *
 * Side effects :	
 *	Memory for the new vop is allocated within this function.
 *
 * Description :	
 *	-
 *
 * See also :
 *	
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Vop *
CloneVop(Vop *vop_in)
{
  Int		x,y;
	
  Image	*image_data;
  Image *QP_chan;
	
  Vop		*vop_out;
	
  image_data = GetVopA(vop_in);
  x = GetImageSizeX(image_data);
  y = GetImageSizeY(image_data);

  vop_out = AllocVop(x,y);
  image_data = GetVopQP(vop_in); 
  x = GetImageSizeX(image_data);
  y = GetImageSizeY(image_data);
  QP_chan = AllocImage(x,y,SHORT_TYPE);
  PutVopQP(QP_chan, vop_out);

   

	
  CopyVop(vop_in,vop_out);
	
  return(vop_out);
}

/***********************************************************CommentBegin******
 *
 * -- CopyVop -- Copies all vop fields of the input vop to the output vop. 
 *
 * Author :		
 *	Noel O'Connor
 *
 * Created :		
 *	20-Feb-96
 *
 * Purpose :		
 *	This function copies all vop fields of the input vop to the 
 * 		output vop. 
 * 
 * Arguments in : 	
 *	Vop *in (pointer to input vop)
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	Vop *out (pointer to output vop)
 *
 * Return values :	
 *	none
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	-
 *
 * See also :
 *	-
 *
 * Modified :		
 *	
 *          17.04.1998: Minhua Zhou: added shape mode 
 *
 ***********************************************************CommentEnd********/

Void
CopyVop(Vop *in, Vop *out)
{
  Image	*img_in,
    *img_out;
						
  /* First copy the non-image fields of the vop */
  CopyVopNonImageField(in,out);

  /* Now copy the image fields of the vop */
	
  /* Alpha channel */
  img_in = GetVopA(in);
  img_out = GetVopA(out);
  CopyImage(img_in,img_out);

  img_in = GetVopAuv(in);
  img_out = GetVopAuv(out);
  CopyImage(img_in,img_out);
	
  /* Y channel */
  img_in = GetVopY(in);
  img_out = GetVopY(out);
  CopyImage(img_in,img_out);
	
  /* U channel */
  img_in = GetVopU(in);
  img_out = GetVopU(out);
  CopyImage(img_in,img_out);
	
  /* V channel */
  img_in = GetVopV(in);
  img_out = GetVopV(out);
  CopyImage(img_in,img_out);
	
  /* QP channel */
  img_in = GetVopQP(in);
  img_out = GetVopQP(out);
  CopyImage(img_in,img_out);

  /* Shape Mode */
  img_in = GetVopShapeMode(in);
  img_out = GetVopShapeMode(out);
  CopyImage(img_in,img_out);

	
}

/***********************************************************CommentBegin******
 *
 * -- UpdateVopStore -- Update a particular vop in a store of vops 
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	11-03-96
 *
 * Purpose :		
 *	This function updates a particular vop in a store of vops. This might 
 *	mean adding a new vop to the store or replacing an existing vop. The
 *	vop store is assumed to consist of a linked list of vops, linked
 *	through the "pnext_spat" field in the vop structure.
 * 
 * Arguments in : 	
 *	Vop *update_vop - pointer to vop with which to update the store
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	Vop **vop_store - pointer to the vop store which is to be updated
 *
 * Return values :	
 *	-
 *
 * Side effects :	
 *	-
 *
 * Description :	
 *	-
 *
 * See also :
 *	-
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Void
UpdateVopStore(Vop *update_vop,Vop **vop_store)
{
  Vop *replace_vop;
	
  Int id;
	
  /* Get Id of vop to be updated */
  id = GetVopId(update_vop);
	
  replace_vop = GetVopById((*vop_store),id);
	
  /* Check if a vop to be replaced exists */
  if(replace_vop == NULL) 
    {
      /* If there are no vops in store, add update vop
	 as first vop in list */
      if((*vop_store) == NULL)
	(*vop_store) = update_vop;
		
      /* Else add this vop on to end of existing list */
      else
	AddVopToSpatList(update_vop,(*vop_store));
    }
  else
    {
      /* Check if vop to be replaced is first in list */
      if((*vop_store)->ident == id)
	{
	  update_vop->pnext_spat = (*vop_store)->pnext_spat;
	  FreeVop(*vop_store);
	  (*vop_store) = update_vop;
	}
      else
	/* Replace existing vop with updated vop */
	ReplaceVopInSpatList(update_vop,(*vop_store));
    }	
  return;
}

/***********************************************************CommentBegin******
 *
 * -- RemoveFromVopStore -- Remove a particular vop from the store of vops 
 *
 * Author :		
 *	Noel Brady Teltec Irl.
 *
 * Created :		
 *	11-06-96
 *
 * Purpose :		
 *	This function removes a particular vop from the store of vops.
 * 
 * Arguments in : 	
 *	Vop *remove_vop - pointer to vop which is to be removed from the store
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *	Vop **vop_store - pointer to the vop store
 *
 * Return values :	
 *	-
 *
 * Side effects :	
 *	-
 *
 * Description :	
 *	-
 *
 * See also :
 *	-
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Void
RemoveFromVopStore(Vop *remove_vop,Vop **vop_store)
{
	Int	remove_id;
	
	Vop	*loc_vop;

	/* Check if vop to be removed exists - if not do nothing */
	remove_id = GetVopId(remove_vop);
	loc_vop = GetVopById(*vop_store,remove_id);
	
	if(loc_vop == NULL)
			return;

	else
	{
		/* Check if vop to be removed is first in vop store */
		if(remove_id == GetVopId(*vop_store))
		{
			loc_vop = GetVopNextSpat(*vop_store);
			FreeVop(*vop_store);
			*vop_store = loc_vop;
		}

		/* otherwise remove vop from vop store */
		else
			RemoveVopFromSpatList(remove_vop, *vop_store);
	}
}





/***********************************************************CommentBegin******
 *
 * -- CalcVopDisplayTime -- calculate absolute time when VOP is to be displayed
 *
 * Author :		
 *      Michael Wollborn (TUH, Germany)
 *
 * Created :		
 *	12-AUG-1996
 *
 * Purpose :	
 *	This function calculates the absolute time (of local time base) when
 *	the VOP is to be displayed the next time
 *
 * 
 * Arguments in : 	
 *	Vop *curr_vop - pointer to vop
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *	Int display_time	time in milliseconds when the VOP is to 
 *				be displayed
 *
 *
 * Side effects :	
 *	-
 *
 * Description :	
 *	-
 *
 * See also :
 *	-
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Int CalcVopDisplayTime(Vop *curr_vop)
{
  Int modulo_time_base;
  Int time_increment;
  Int  display_time;

  /*****
   *
   *	Calculate the time when the VOP is to be displayed next
   *
   *****/
  modulo_time_base = GetVopModTimeBase(curr_vop);
  time_increment   = GetVopTimeInc(curr_vop);
  if (modulo_time_base<0) return -1000;
  
  display_time = modulo_time_base*GetVopTimeIncrementResolution(curr_vop) +  time_increment;
 
  return(display_time);
}





/***********************************************************CommentBegin******
 *
 * -- FreeVopChannels -- free the VOP channels from a VOP
 *
 * Author :		
 *      Michael Wollborn (TUH, Germany)
 *
 * Created :		
 *	15-AUG-1996
 *
 * Purpose :
 *	All channels (YUVA) from a VOP are freed	
 *
 * 
 * Arguments in : 	
 *	Vop *vop 	pointer to vop
 *
 * Arguments in/out :	
 *	-
 *
 * Arguments out :	
 *
 *
 * Return values :	
 *
 *
 * Side effects :	
 *	-
 *
 * Description :	
 *	-
 *
 * See also :
 *	-
 *
 * Modified :	13-NOV-1996, M.Wollborn, since PutVopY/U/V frees the image
 *		in the VOP anyway, it is sufficient to call just that function.
 *		9-DEC-1996, F. Marques to fix a cut_and_paste mistake detected
 *		by I. Corset in the call of GetVopU
 *              26.05.97 Minhua Zhou: added free uv_alpha_channel
 *
 *               17.04.1998: Minhua Zhou: added shape mode 	
 *
 ***********************************************************CommentEnd********/

Void FreeVopChannels(Vop *vop)
{
  Image *Y_image, *U_image, *V_image, *A_image, *A_uv_image, 
        *QP_image,*ShapeMode_image;

  /*****
   *
   *	Free the VOP image fields, if allocated
   *
   *****/
  Y_image = GetVopY(vop);
  if(Y_image != NULL)
    PutVopY(NULL,vop);
  
  U_image = GetVopU(vop);
  if(U_image != NULL)
    PutVopU(NULL,vop);

  V_image = GetVopV(vop);
  if(V_image != NULL)
    PutVopV(NULL,vop);

  A_image = GetVopA(vop);
  if(A_image != NULL)
    PutVopA(NULL,vop);

  A_uv_image = GetVopAuv(vop);
  if(A_uv_image != NULL)
    PutVopAuv(NULL,vop);


 
 QP_image = GetVopQP(vop);
  if(QP_image != NULL)
    PutVopQP(NULL,vop);

  ShapeMode_image = GetVopShapeMode(vop);
  if(ShapeMode_image != NULL)
    PutVopShapeMode(NULL,vop);

  return;
}





  
