/*****************************************************************************
 *
 * This software module was originally developed by
 *
 *   Noel O'Connor (Teltec DCU / ACTS-MoMuSyS)
 *
 * 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_vol.c
 *
 * Author:	Noel O'Connor Teltec Irl.
 * Created:	31-07-96
 *                                                                         
 * Description: 
 *	Functions related to Vol structure (except access functions)
 *
 * Notes: 	
 *
 * Modified:	
 *
 *	22.04.97 Michael Wollborn: Added syntax elements for MPEG
 *				   quantization matrices
 *      26.04.97 Luis Ducla-Soares: Added syntax elementes for data partitioning.
 *	12.05.97 Minhua Zhou      : added syntax element for   
 *				    advanced_prediction_disable
 * 
 ***********************************************************HeaderEnd*********/

/************************    INCLUDE FILES    ********************************/
#include <stdio.h>
#include <stdlib.h>
#include "momusys.h"
#include "mom_access.h"
#include "mom_image.h"
#include "mom_vop.h"
#include "mom_vol.h"

/***********************************************************CommentBegin******
 *
 * -- SallocVol -- 
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	30-07-96
 *
 * Purpose :		
 *	Allocates memory for a Vol (but not for the Vop field of the Vol)
 *
 * Arguments in : 	
 *	none
 *
 * Arguments in/out :	
 *	none
 *
 * Arguments out :	
 *	none
 *
 * Return values :	
 *	Vol *vol - allocated Vol
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	
 *
 * See also :
 *	
 *
 * Modified :		
 *
 *	
 *
 ***********************************************************CommentEnd********/

Vol *
SallocVol()
{
	Vol *vol;

	vol = (Vol *)ecalloc(1,sizeof(Vol));
	vol->tab_transmit = NULL;
	vol->tab_amb_type = NULL;
	vol->tab_mvda = NULL;
	vol->tab_QP_store = NULL;
	vol->tab_DQUANT_store = NULL;
	vol->tab_DC_store = NULL;
	vol->psprite = NULL;
	vol->ref_point_coord = NULL;
	vol->traj_point_coord = NULL;
	vol->prev_warp_param = NULL;

	return(vol);
}

/***********************************************************CommentBegin******
 *
 * -- SFreeVol -- 
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	30-07-96
 *
 * Purpose :		
 *	Deallocates memory for a Vol structure (but not for the Vop pointed to
 *	by the Vol).
 *
 * Arguments in : 	
 *
 * Arguments in/out :	
 *	none
 *
 * Arguments out :	
 *	none
 *
 * Return values :	
 *	none
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	
 *
 * See also :
 *	
 *
 * Modified :		
 *
 *	
 *
 ***********************************************************CommentEnd********/

Void
SFreeVol(Vol *vol)
{
	free((Char*)vol);
	return;
}

/***********************************************************CommentBegin******
 *
 * -- FreeVol -- 
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	30-07-96
 *
 * Purpose :		
 *	Deallocates memory for a Vol (incl. Vop pointed to by Vol)
 *
 * Arguments in : 	
 *	Vol *vol - Vol to be freed
 *
 * Arguments in/out :	
 *	none
 *
 * Arguments out :	
 *	none
 *
 * Return values :	
 *	none
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	
 *
 * See also :
 *	
 *
 * Modified :		
 *       16.06.97 Minhua Zhou: added FreeVop(GetVopNextTemp(vop));  
 *       19.06.97 Angel Pacheco: added vop!=NULL line
 *       24.07.97 Minhua Zhou: added FreeVop(GetVopPrevTemp(vop)); 
 *	
 *
 ***********************************************************CommentEnd********/

Void
FreeVol(Vol *vol)
{
	Vop	*vop;
	TrajPoint *traj;
	Int *tab;
	SInt *QP_tab;
	Int  ***DC_tab;
	Int *DQUANT_tab;
	Sprite_motion *prev_warp_param;
	Int	i,j,numblocks;

	vop = GetVolVop(vol);
   if(vop!=NULL)
     {
     if (GetVopNextTemp(vop)!=NULL)
        FreeVop(GetVopNextTemp(vop)); 
     if (GetVopPrevTemp(vop)!=NULL)
        FreeVop(GetVopPrevTemp(vop)); 

     FreeVop(vop); 
     }
     
         vop = GetVolSprite(vol);
    if (vop!=NULL)
    	FreeVop(vop); 

	prev_warp_param = GetVolPrevWarpParam(vol);
    if (prev_warp_param!=NULL)
    	free((Char*)prev_warp_param); 
	
	traj = GetVolRefPointCoord(vol);
    if (traj!=NULL)
    	free((Char*)traj); 
	
	traj = GetVolTrajPointCoord(vol);
    if (traj!=NULL)
    	free((Char*)traj); 
	
	tab = GetVolSpriteTabTransmit(vol);
    if (tab!=NULL)
    	free((Char*)tab); 

	tab = GetVolSpriteTabAmbType(vol);
    if (tab!=NULL)
    	free((Char*)tab); 

	tab = GetVolSpriteTabMvda(vol);
    if (tab!=NULL)
    	free((Char*)tab); 

	QP_tab = GetVolSpriteTabQPStore(vol);
    if (QP_tab!=NULL)
    	free((Char*)QP_tab); 

	DQUANT_tab = GetVolSpriteTabDQUANTStore(vol);
    if (DQUANT_tab!=NULL)
    	free((Char*)DQUANT_tab); 

	DC_tab = GetVolSpriteTabDCStore(vol);
    if (DC_tab!=NULL)
        {
	numblocks = (vol->sprite_hdim/16)*(vol->sprite_vdim/16);
    	for (i = 0; i < numblocks; i++)
    		{
		for (j = 0; j < 6; j++)
	    		free((Char*)DC_tab[i][j]);
		free((Char*)DC_tab[i]);
    		}
    	free((Char*)DC_tab); 
	}

	SFreeVol(vol);

	return;
}

/***********************************************************CommentBegin******
 *
 * -- AddVolToList  -- 
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	30-07-96
 *
 * Purpose :		
 *	Adds an input Vol to the end of a linked list of Vols. Assumes list
 *	is not empty.
 *
 * Arguments in : 	
 *	Vol *vol - Vol to be added to list
 *
 * Arguments in/out :	
 *	Vol *list - linked list of Vols
 *
 * Arguments out :	
 *	none
 *
 * Return values :	
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	
 *
 * See also :
 *	
 *
 * Modified :		
 *
 *	
 *
 ***********************************************************CommentEnd********/


Void
AddVolToList(Vol *vol, Vol *list)
{
	Vol	*curr,
			*prev;

	prev = list;
	curr = GetVolNext(prev);

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

	PutVolNext(vol,prev);
}

/***********************************************************CommentBegin******
 *
 * -- FreeVolList -- 
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	30-07-96
 *
 * Purpose :		
 *	Deallocates all memory associated with a linked list of Vols
 *  including the Vop structures of each Vol
 *
 * Arguments in : 	
 *
 * Arguments in/out :	
 *	none
 *
 * Arguments out :	
 *	none
 *
 * Return values :	
 *	none
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	
 *
 * See also :
 *	
 *
 * Modified :		
 *
 *	
 *
 ***********************************************************CommentEnd********/

Void
FreeVolList(Vol *list)
{
	Vol	*curr,
			*next;

	curr = list;

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

		FreeVol(curr);

		curr = next;
	}

	return;
}

/***********************************************************CommentBegin******
 *
 * -- GetVolById -- 
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	30-07-96
 *
 * Purpose :		
 *	Returns a pointer to a paricular Vol in a linked list identified by
 *	its Id
 *
 * Arguments in : 	
 *	Vol *list - linked list of Vols
 *	Int vol_id - Id of required Vol
 *
 * Arguments in/out :	
 *	none
 *
 * Arguments out :	
 *	none
 *
 * Return values :	
 *	Vol *curr - pointer to required VOl
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	
 *
 * See also :
 *	
 *
 * Modified :		
 *
 *	
 *
 ***********************************************************CommentEnd********/

Vol *
GetVolById(Vol *list,Int vol_id)
{
	Vol	*curr;

	Int	id;

	curr = list;

	while(curr != NULL)
	{
		id = GetVolId(curr);
		if(id != vol_id)
			curr = GetVolNext(curr);
		else
			break;
	}
	return(curr);
}

/***********************************************************CommentBegin******
 *
 * -- CopyVolSyntax -- 
 *
 * Author :		
 *	Noel O'Connor Teltec Irl.
 *
 * Created :		
 *	30-07-96
 *
 * Purpose :		
 *	Copies syntax fields only from one Vol to another
 *
 * Arguments in : 	
 *	Vol *in - i/p Vol (copy from)
 *
 * Arguments in/out :	
 *	none
 *
 * Arguments out :	
 *	Vol *out - o/p Vol (copy to)
 *
 * Return values :	
 *
 * Side effects :	
 *	none
 *
 * Description :	
 *	
 *
 * See also :
 *	
 *
 * Modified :		
 *
 *	22.04.97 Michael Wollborn: Added syntax elements for MPEG
 *				   quantization matrices
 *      26.04.97 Luis Ducla-Soares: Added syntax elements for data partitioning.
 *      09.07.97 Aasmund Sandvand: added VOId copying
 *
 *      15.07.97 Ulrike Pestel-Schiller: added ScalType 
 ***********************************************************CommentEnd********/

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

  PutVolVOId(GetVolVOId(in),out);
  PutVolId(GetVolId(in),out);
  PutVolShape(GetVolShape(in),out);
  PutVolShapeEffects(GetVolShapeEffects(in),out);
  PutVolWidth(GetVolWidth(in),out);
  PutVolHeight(GetVolHeight(in),out);
  PutVolQuantType(GetVolQuantType(in),out);
  PutVolLoadIntraQuantMat(GetVolLoadIntraQuantMat(in),out);
  PutVolLoadNonintraQuantMat(GetVolLoadNonintraQuantMat(in),out);
  PutVolDisableGrayQuantUpdate(GetVolDisableGrayQuantUpdate(in),out);
  PutVolLoadGrayIntraQuantMat(GetVolLoadGrayIntraQuantMat(in),out);
  PutVolLoadGrayNonintraQuantMat(GetVolLoadGrayNonintraQuantMat(in),out);
  PutVolTimeIncrementResolution(GetVolTimeIncrementResolution(in),out);
  
  if(GetVolQuantType(in))
    {
      iqmat_in  = GetVolIntraQuantMat(in);
      iqmat_out = GetVolIntraQuantMat(out);
      nqmat_in  = GetVolNonintraQuantMat(in);
      nqmat_out = GetVolNonintraQuantMat(out);

      gl_iqmat_in  = GetVolGrayIntraQuantMat(in);
      gl_iqmat_out = GetVolGrayIntraQuantMat(out);
      gl_nqmat_in  = GetVolGrayNonintraQuantMat(in);
      gl_nqmat_out = GetVolGrayNonintraQuantMat(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++);
	}
    }

  PutVolErrorResDisable(GetVolErrorResDisable(in),out);
  PutVolReverseVlc(GetVolReverseVlc(in),out);
  PutVolDataPartEnable(GetVolDataPartEnable(in),out);
  PutVolACDCPredDisable(GetVolACDCPredDisable(in),out);
  PutVolQuantPrecision(GetVolQuantPrecision(in),out);
  PutVolBitsPerPixel(GetVolBitsPerPixel(in),out);
  PutVolSADCTDisable(GetVolSADCTDisable(in),out);
  PutVolScalability(GetVolScalability(in),out);
  PutVolScalType(GetVolScalType(in),out);
  PutVolRefId(GetVolRefId(in),out);
  PutVolRefSampDir(GetVolRefSampDir(in),out);
  PutVolHorSampN(GetVolHorSampN(in),out);
  PutVolHorSampM(GetVolHorSampM(in),out);
  PutVolVerSampN(GetVolVerSampN(in),out);
  PutVolVerSampM(GetVolVerSampM(in),out);
  PutVolEnhanceType(GetVolEnhanceType(in),out);
  
  PutVolSpriteUsage(GetVolSpriteUsage(in),out);
  if (GetVolSpriteUsage(in))
  	{
	PutVolSpriteHdim(GetVolSpriteHdim(in), out);
	PutVolSpriteVdim(GetVolSpriteVdim(in), out);
	PutVolSpriteLeftEdge(GetVolSpriteLeftEdge(in), out);
	PutVolSpriteTopEdge(GetVolSpriteTopEdge(in), out);
	PutVolSpriteInitPieceWidth(GetVolSpriteInitPieceWidth(in),out);
	PutVolSpriteInitPieceHeight(GetVolSpriteInitPieceHeight(in),out);
	PutVolSpriteInitPieceHorRef(GetVolSpriteInitPieceHorRef(in),out);
	PutVolSpriteInitPieceVerRef(GetVolSpriteInitPieceVerRef(in),out);
	PutVolWarpingAccuracy(GetVolWarpingAccuracy(in),out);
	PutVolBlendFact(GetVolBlendFact(in),out);
	PutVolNoOfSpritePoints(GetVolNoOfSpritePoints(in),out);
	PutVolSpriteTransmitMode(GetVolSpriteTransmitMode(in),out);
/* This are commented for FreeVol problems, still unsolved */
/*
	PutVolSprite(GetVolSprite(in),out);
	PutVolSpriteTabTransmit(GetVolSpriteTabTransmit(in),out);
	PutVolSpriteTabMvda(GetVolSpriteTabMvda(in),out);
	PutVolSpriteTabDCStore(GetVolSpriteTabDCStore(in),out);
	PutVolSpriteTabQPStore(GetVolSpriteTabQPStore(in),out);
	PutVolPrevWarpParam(GetVolPrevWarpParam(in),out);
	if (GetVolNoOfSpritePoints(in)) 
	  {
	  PutVolRefPointCoord(GetVolRefPointCoord(in),out);
	  PutVolTrajPointCoord(GetVolTrajPointCoord(in),out);
	  }
*/
	}

  return;
}
