/******************************************************************************
 *                                                                          
 * This software module was originally developed by 
 *
 *   Cecile Dufour (LEP / ACTS-MoMuSys)
 *   Frederic Dufaux (Digital Equipment Corp.)
 *
 * 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:	sprite_dec_util.c
 *
 * Author:	Frederic Dufaux, Cecile Dufour
 * Created:	06/20/96
 *                                                                         
 * Description: 
 * -- VlcFirstTrajPoint
 * -- DecodeSpriteTraj	
 * -- decode_brightness_change_factor
 *
 * Notes: 	
 *
 * Modified:	
 * 
 ***********************************************************HeaderEnd*********/

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

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "mom_bitstream_d.h"
#include "sprite_dec_util.h"
#include "vm_vlc_dec.h"
#include "mot_decode.h"

#include <math.h>



/***********************************************************CommentBegin******
 *
 * -- VlcFirstTrajPoint -- 
 *
 * Author :		
 *	Frederic Dufaux (Digital Equipment Corporation/ dufaux@crl.dec.com)
 *
 * Created :		
 *	02/03/97
 *
 * Purpose :		
 *
 * Arguments in : 
 * 
 * Arguments in / out : 
 *
 * Return values :	
 * 
 * Side effects :	
 *	
 * Description : 
 *
 * See also :
 *
 * Modified : 
 *		
 *
 ***********************************************************CommentEnd********/

Int
VlcFirstTrajPoint(Bitstream *stream, Trace *trace)
{	
Int code;
Int vlc_code;

  code = BitstreamShowBits(stream, 12);

  if (code <= 1023) {
    /* 00 */
    vlc_code = BitstreamReadBits(stream,2,"VlcFirstTrajPoint0",trace, NUM);
    code = 0;
    return code;
  }
  if (code <= 1535) {
    /* 010 */
    vlc_code = BitstreamReadBits(stream,3,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,1,"TrajPoint",trace, NUM);
    if (code < 1) code-=1;
    return code;
  }
  if (code <= 2047) {
    /* 011 */
    vlc_code = BitstreamReadBits(stream,3,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,2,"TrajPoint",trace, NUM);
    if (code < 2) code-=3;
    return code;
  }
  if (code <= 2559) {
    /* 100 */
    vlc_code = BitstreamReadBits(stream,3,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,3,"TrajPoint",trace, NUM);
    if (code < 4) code-=7;
    return code;
  }  
  if (code <= 3071) {
    /* 101 */
    vlc_code = BitstreamReadBits(stream,3,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,4,"TrajPoint",trace, NUM);
    if (code < 8) code-=15;
    return code;
  }
  if (code <= 3583) {
    /* 110 */
    vlc_code = BitstreamReadBits(stream,3,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,5,"TrajPoint",trace, NUM);
    if (code < 16) code-=31;
    return code;
  }
  if (code <= 3839) {
    /* 1110 */
    vlc_code = BitstreamReadBits(stream,4,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,6,"TrajPoint",trace, NUM);
    if (code < 32) code-=63;
    return code;
  }
  if (code <= 3967) {
    /* 11110 */
    vlc_code = BitstreamReadBits(stream,5,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,7,"TrajPoint",trace, NUM);
    if (code < 64) code-=127;
    return code;
  }
  if (code <= 4031) {
    /* 111110 */
    vlc_code = BitstreamReadBits(stream,6,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,8,"TrajPoint",trace, NUM);
    if (code < 128) code-=255;
    return code;
  }
  if (code <= 4063) {
    /* 1111110 */
    vlc_code = BitstreamReadBits(stream,7,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,9,"TrajPoint",trace, NUM);
    if (code < 256) code-=511;
    return code;
  }
  if (code <= 4079) {
    /* 11111110 */
    vlc_code = BitstreamReadBits(stream,8,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,10,"TrajPoint",trace, NUM);
    if (code < 512) code-=1023;
    return code;
  }
  if (code <= 4087) {
    /* 111111110 */
    vlc_code = BitstreamReadBits(stream,9,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,11,"TrajPoint",trace, NUM);
    if (code < 1024) code-=2047;
    return code;
  }
  if (code <= 4091) {
    /* 1111111110 */
    vlc_code = BitstreamReadBits(stream,10,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,12,"TrajPoint",trace, NUM);
    if (code < 2048) code-=4095;
    return code;
  }
  if (code <= 4093) {
    /* 11111111110 */
    vlc_code = BitstreamReadBits(stream,11,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,13,"TrajPoint",trace, NUM);
    if (code < 4096) code-=8191;
    return code;
  }
  if (code == 4094) {
    /* 111111111110 */
    vlc_code = BitstreamReadBits(stream,12,"VlcFirstTrajPoint",trace, NUM);
    code = BitstreamReadBits(stream,14,"TrajPoint",trace, NUM);
    if (code < 8192) code-=16383;
    return code;
  }
 return(0);
}

/***********************************************************CommentBegin******
 *
 * -- DecodeSpriteTraj -- 
 *
 * Author :		
 *	Frederic Dufaux (Digital Equipment Corporation/ dufaux@crl.dec.com)
 *
 * Created :		
 *	02/03/97
 *
 * Purpose :		
 *
 * Arguments in : 
 * 
 * Arguments in / out : 
 *
 * Return values :	
 * 
 * Side effects :	
 *	
 * Description : 
 *
 * See also :
 *
 * Modified : 
 *		
 *
 ***********************************************************CommentEnd********/

TrajPoint *
DecodeSpriteTraj(Bitstream *stream, Trace *trace, Int no_of_sprite_points, 
					Int sprite_usage)
{	
  Int i;
  TrajPoint	*difftraj;
  
  difftraj = (TrajPoint *) emalloc(no_of_sprite_points*sizeof(TrajPoint)); 

  for (i=0; i<no_of_sprite_points; i++) {
    /* all points encoded using Vlc table */
    difftraj[i].x = VlcFirstTrajPoint(stream,trace);
    difftraj[i].y = VlcFirstTrajPoint(stream,trace);
  }

 return(difftraj);

}

/***********************************************************CommentBegin******
 *
 * -- decode_brightness_change_factor -- 
 *
 * Author :		
 *	Cecile Dufour, (Philips LEP/ dufour@lep.research.philips.com)
 *
 * Created :		
 *	08/12/97
 *
 * Purpose :
 *	decoding of brightness_change factor for sprite		
 *
 * Arguments in : 
 * 
 * Arguments in / out : 
 *
 * Return values :	
 *  
 * Side effects :	
 *	
 *
 * Description : 
 *
 * See also :
 *
 * Modified : 
 *		
 ***********************************************************CommentEnd********/

Float
decode_brightness_change_factor(Bitstream *stream, Trace *trace, Int *readen_bits)
{	
Int code;
Float	rec_factor;

  code = BitstreamShowBits(stream, 4);

  if (code <= 7) {
    /* 0 */
    BitstreamFlushBits(stream,1);
    code = BitstreamReadBits(stream,5,"Brightness Change Factor",trace, NUM);
    readen_bits +=6;
    if (code < 16) code-=31;
    if (code<0) code +=15;
    else	code -=15;
    rec_factor = (Float)code/100.0 + 1;
    return(rec_factor);
  }
  if (code <= 11) {
    /* 10 */
    BitstreamFlushBits(stream,2);
    code = BitstreamReadBits(stream,6,"Brightness Change Factor",trace, NUM);
    readen_bits +=8;
    if (code < 32) code-=63;
    if (code<0) code +=15;
    else	code -=15;
    rec_factor = (Float)code/100.0 + 1;
    return(rec_factor);
  }
  if (code <= 13) {
    /* 110 */
    BitstreamFlushBits(stream,3);
    code = BitstreamReadBits(stream,7,"Brightness Change Factor",trace, NUM);
    readen_bits +=10;
    if (code < 64) code-=127;
    if (code<0) code +=15;
    else	code -=15;
    rec_factor = (Float)code/100.0 + 1;
    return(rec_factor);
  }
  if (code <= 14) {
    /* 1110 */
    BitstreamFlushBits(stream,4);
    code = BitstreamReadBits(stream,10,"Brightness Change Factor",trace, NUM);
    readen_bits +=13;
    code+=113;
    rec_factor = (Float)code/100.0 + 1;
    return(rec_factor);
  }  
  if (code <= 15) {
    /* 1111 */
    BitstreamFlushBits(stream,4);
    code = BitstreamReadBits(stream,11,"Brightness Change Factor",trace, NUM);
    readen_bits +=14;
    code += 625;
    rec_factor = (Float)code/100.0 + 1;
    return(rec_factor);
  }

 return(0);
}



