/*****************************************************************************
 *
 * This software module was originally developed by
 *
 *   Paulo Nunes (IST / 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_bitstream_d.c
 *
 * Author:	Paulo Nunes (IST) - Paulo.Nunes@lx.it.pt
 * Created:	1-Mar-1996
 *                                                                         
 * Description: File containing functions to access & handle bitstreams in
 *              the decoder.
 *
 * Notes: 	The functions contained in this file were adapted from
 *   		tmndecode
 * 		Written by Karl Olav Lillevold <kol@nta.no>,
 *					1995 Telenor R&D.
 * 		Donated to the Momusys-project as background code by
 *		Telenor. 
 *   		
 *   		based on mpeg2decode, (C) 1994, MPEG Software Simulation Group
 *   		and mpeg2play, (C) 1994 Stefan Eckart
 *   					<stefan@lis.e-technik.tu-muenchen.de>
 *
 *
 * Modified:	 7-May-96 Paulo Nunes: Reformatted. New headers.
 *		10-May-96 Paulo Nunes: Changed BitstreamShowBits.
 *              14-Jan-97 Luis Ducla-Soares: Added function BitstreamByteAlign().
 *              28-Apr-97 Luis Ducla-Soares: Added #include "vm_common_defs.h"
 *                                          and functions RVLCBitstreamXXX()
 *                                          BitstreamShowBitsByteAlign() and
 *                                          CheckBitStuffing().
 *              23-May-97 Luis Ducla-Soares: Added function BitstreamShowBitsAfterX().
 *
 ***********************************************************HeaderEnd*********//************************    INCLUDE FILES    ********************************/
#include "mom_bitstream_d.h"
#include "vm_common_defs.h"

/***********************************************************CommentBegin******
 *
 * -- BitstreamInit -- Initialises a bitstream structure
 *
 * Author :		
 *	Paulo Nunes (IST) - Paulo.Nunes@lx.it.pt
 *
 * Created :		
 *	1-Mar-1996
 *
 * Purpose :		
 *	Initialisation of a bitstream structure.
 * 
 * Arguments in : 	
 *	Char filename,	 The name of the file containing the bitstream data.
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	A poiter to a bitstream structure.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	Allocates memory for the bitstream structure, opens the bitstream
 *	file and initialises the bitstream structure.
 *
 * See also :
 *	
 *
 * Modified :
 *	
 *
 ***********************************************************CommentEnd********/

Bitstream          *
BitstreamOpen (Char * filename)

{
  Bitstream          *stream;
  File               *file;
  Int i;

  stream = (Bitstream *) emalloc (sizeof (Bitstream));

  if ((file = fopen (filename, "rb")) == 0)
    {
      fprintf (stderr, "ERROR: opening bitstream file.\n");
      exit (1);
    }

  stream->fptr = file;
  stream->incnt = 0;
  stream->rdptr = stream->rdbfr + BFR_SIZE;
  stream->bitcnt = 0;

  for (i = 0; i < 3*INBFR_BYTES; i++)
    {
      stream->inbfr[i] = 0;
    }

  return stream;

}				/* BitstreamInit */



/***********************************************************CommentBegin******
 *
 * -- BitstreamFree -- Frees a bitstream structure
 *
 * Author :		
 *	Paulo Nunes (IST) - Paulo.Nunes@lx.it.pt
 *
 * Created :		
 *	1-Mar-1996
 *
 * Purpose :		
 *	Freeing a bitstream structure.
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	Closes the file associated with the bitstream structure and frees
 *	the structure. 
 *
 * See also :
 *	
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Void
BitstreamClose (Bitstream * stream)

{
  fclose (stream->fptr);
  free ((Char *)stream);

}				/* BitstreamFree */



/***********************************************************CommentBegin******
 *
 * -- BitstreamFillBuffer -- Fills a bitstream structure
 *
 * Author :		
 *	Paulo Nunes (IST) - Paulo.Nunes@lx.it.pt
 *
 * Created :		
 *	1-Mar-1996
 *
 * Purpose :		
 *	To read a piece of the bitstream from the bitstream file to the
 *	bitstream buffer. 
 *	
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	
 *
 * See also :
 *	
 *
 * Modified :		 Noel Brady/Luis Ducla-Soares: Changed termination of bitstream
 *	
 *
 ***********************************************************CommentEnd********/

Void
BitstreamFillBuffer (Bitstream * stream)

{
  Int                 l, i;


  for (i = 0; i < INBFR_BYTES; i++)
    {
      stream->inbfr[i] = stream->inbfr[i + 2 * INBFR_BYTES];
    }

  if (stream->rdptr >= stream->rdbfr + BFR_SIZE)
    {
      l = fread ((Char *)stream->rdbfr, sizeof (UChar), BFR_SIZE, stream->fptr);
      stream->rdptr = stream->rdbfr;
      if (l < BFR_SIZE)
	{
	  if (l < 0)
	    l = 0;

	      stream->rdbfr[l++] = 0;
	      stream->rdbfr[l++] = 0;
	      stream->rdbfr[l++] = 0;
	      stream->rdbfr[l++] = 1;
	}      
    }

  for (l = 0; l < 2*INBFR_BYTES; l++)
    stream->inbfr[l + INBFR_BYTES] = stream->rdptr[l];

  stream->rdptr += 2*INBFR_BYTES;
  stream->incnt += 2*INBFR_BYTES*8;

}				/* BitstreamFillBuffer */


/***********************************************************CommentBegin******
 *
 * -- BitstreamShowBits -- Shows the next "nbits" of the bitstream
 *
 * Author :		
 *	Paulo Nunes (IST) - Paulo.Nunes@lx.it.pt
 *
 * Created :		
 *	1-Mar-1996
 *
 * Purpose :		
 *	To see the next "nbits" bitstream bits without advancing the read
 *	pointer. 
 *
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to see.

 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	The value of the "nbits" right adjusted in one UInt.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	This function allows to see the next "nbits" after the current
 *	position of the bitstream pointer without advancing the pointer. It
 *	returns "nbits" bitstream bits right aligned in one UInt (see
 *	example)  
 *  			  ______ 
 *  			  |    | 
 *  			  v    v
 *  	bitstream -> 0000001000100111101 
 *  			  ^
 *  			  |
 *  	BitstreamShowBits(bitstream, 6) = 17
 *  	(i.e. 00000000000000000000000000010001) 
 *  					^    ^ 
 *  					|    |
 *  	
 *
 * See also :
 *	
 *
 * Modified :		
 *	10-May-96 Paulo Nunes: change to allow reading words up to 32 bits.
 *
 ***********************************************************CommentEnd********/

UInt 
BitstreamShowBits (Bitstream * stream, Int nbits)

{
  UChar              *v;
  UInt                b, b1;
  Int                 c;

 /* to mask the n least significant bits of an integer */
  static UInt         msk[33] =
  {
    0x00000000, 0x00000001, 0x00000003, 0x00000007,
    0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
    0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
    0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
    0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
    0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
    0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
    0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
    0xffffffff
  };

  if (nbits > 8 * sizeof (UInt))
    {
      fprintf (stderr, "ERROR: number of bits greater than size of UInt.\n");
      exit (1);
    }
  if (stream->incnt < nbits)
    BitstreamFillBuffer (stream);

  v = stream->inbfr + ((INBFR_TOTAL_BITS - stream->incnt) >> 3);
  b = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
  c = ((stream->incnt - 1) & 7) + 25;

  if (c < nbits)
    {
      b1 = v[4];
      return ((b << (nbits - c)) | (b1 >> (8 - (nbits - c)))) & msk[nbits];
    }
  else
    {
      return (b >> (c - nbits)) & msk[nbits];
    }
}				/* BitstreamShowBits */


/***********************************************************CommentBegin******
 *
 * -- BitstreamLookAheadBit -- shows the value of the next "n"th bit in the bitstream
 *
 * Author :		
 *	Paulo Nunes (IST) - Paulo.Nunes@lx.it.pt
 *
 * Created :		
 *	1-Mar-1996
 *
 * Purpose :		
 *	To see the value of the "n"th bit in the bitstream without advancing the read
 *	pointer. 
 *
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nth_bit,			the relative bit position.
 *
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	The value of the "n"th bit in the bitstream relatively to the
 *	current position.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *		Returns the value of the n-th bit in the bitstream.
 *		The next bit in the bitstream can be obtained by 
 *		BitstreamLookAheadBit(bitstream,1); The use of nth_bit=0
 *		is not allowed. The bitstream pointer is not advanced and
 *		nth_bit can be in the range [1,64].
 *  	
 *
 * See also :
 *	
 *
 * Modified :		Noel Brady.
 *
 *
 ***********************************************************CommentEnd********/

UInt 
BitstreamLookAheadBit (Bitstream * stream, Int nth_bit)

{
  UChar              *v;
  UInt                b, offset;
  Int                 c;

  if (nth_bit > 8 * INBFR_BYTES || nth_bit < 1)
    {
      fprintf (stderr, "ERROR(BitstreamLookAheadBit): Parameter out of range.\n");
      exit (1);
    }
  if (stream->incnt < nth_bit)
    BitstreamFillBuffer (stream);

  offset = INBFR_TOTAL_BITS - stream->incnt + nth_bit - 1;

  v = stream->inbfr + (offset >> 3);
  b = v[0];
  c = 7 - (offset & 7);

  return (b >> c) & 1;

}				/* BitstreamLookAheadBit */


/***********************************************************CommentBegin******
 *
 * -- BitstreamFlushBits -- Advances the bitstream read pointer
 *
 * Author :		
 *	Paulo Nunes (IST) - Paulo.Nunes@lx.it.pt
 *
 * Created :		
 *	1-Mar-1996
 *
 * Purpose :		
 *	To advance the bitstream read pointer.
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream; 
 *	Int nbits,		number of bits positions to advance the
 *	                        pointer. 
 *
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	Advances "nbits" the bitstream read pointer and calls the function
 *	BitstreamFillBuffer to reload the bitstream buffer whenever
 *	necessary. 
 *
 *
 * See also :
 *	BitstreamFillBuffer.
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Void
BitstreamFlushBits (Bitstream * stream, Int nbits)

{
  stream->bitcnt += nbits;
  stream->incnt -= nbits;
  if (stream->incnt < 0)
    BitstreamFillBuffer (stream);

}				/* BitstreamFlushBits */


/***********************************************************CommentBegin******
 *
 * -- RVLCBitstreamFlushBitsForward -- Advances the bitstream read pointer
 *                                       in a reversible bitstream.
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	28.04.97
 *
 * Purpose :		
 *	To advance the bitstream read pointer in a reversible bitstream.
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream; 
 *	Int nbits,		number of bits positions to advance the
 *	                        pointer. 
 *
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	Advances "nbits" the bitstream read pointer
 *
 *
 *
 *
 * See also :
 *
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Void
RVLCBitstreamFlushBitsForward (Bitstream * stream, Int nbits)

{
  stream->bitcnt += nbits;
  stream->incnt -= nbits;


}				/* RVLCBitstreamFlushBitsForward */



/***********************************************************CommentBegin******
 *
 * -- RVLCBitstreamFlushBitsBackward -- Backs the bitstream read pointer in
 *                                      a reversible bitstream.
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	28.04.97
 *
 * Purpose :		
 *	To back the bitstream read pointer in a reversible bitstream.
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream; 
 *	Int nbits,		number of bits positions to back up the
 *	                        pointer. 
 *
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	Advances "nbits" the bitstream read pointer.
 *
 *
 *
 *
 * See also :
 *
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

Void
RVLCBitstreamFlushBitsBackward (Bitstream * stream, Int nbits)

{
  stream->bitcnt -= nbits;
  stream->incnt += nbits;
  if (stream->bitcnt < 0)
    fprintf(stderr,"Cannot flush that many bits!\n");

}				/* RVLCBitstreamFlushBitsBackward */

/***********************************************************CommentBegin******
 *
 * -- BitstreamReadBits -- Reads the next next "nbits" from the bitstream
 *
 * Author :		
 *	Paulo Nunes (IST) - Paulo.Nunes@lx.it.pt
 *
 * Created :		
 *	1-Mar-1996
 *
 * Purpose :		
 *	To read the next "nbits" from the bitstream.
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to read.
 *
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	Reads the next "nbits" of the bitstream and advances the bitsttream
 *	read pointer. 
 *
 * See also :
 *	BitstreamFlushBits.
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

UInt
BitstreamReadBits (Bitstream * stream, Int nbits, Char *s, Trace *trace, Int mode)

{
  UInt                l;

  l = BitstreamShowBits (stream, nbits);
  BitstreamFlushBits (stream, nbits);

  trace_routine(s, l, btos(l, nbits), trace, mode);
  
  return l;

}
/* BitstreamReadBits */


/***********************************************************CommentBegin******
 *
 * -- RVLCBitstreamReadBitsForward -- Reads the next "nbits" from the
 *                                    reversible bitstream
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	28.04.97
 *
 * Purpose :		
 *	To read the next "nbits" from the reversible bitstream.
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to read.
 *
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	Reads the next "nbits" of the bitstream and advances the bitstream
 *	read pointer. 
 *
 * See also :
 *	RVLCBitstreamFlushBitsForward.
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

UInt
RVLCBitstreamReadBitsForward (Bitstream * stream, Int nbits, Char *s, Trace *trace, Int mode)

{
  UInt                l;

  l = RVLCBitstreamShowBitsForward (stream, nbits);
  RVLCBitstreamFlushBitsForward (stream, nbits);

  trace_routine(s, l, btos(l, nbits), trace, mode);
  
  return l;

}
/* RVLCBitstreamReadBitsForward */


/***********************************************************CommentBegin******
 *
 * -- RVLCBitstreamReadBitsBackward -- Reads the previous "nbits" from the
 *                                     reversible bitstream
 *
 * Author :		
 *      Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	28.04.97
 *
 * Purpose :		
 *	To read the previous "nbits" from the reversible bitstream.
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to read.
 *
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	Reads the previous "nbits" of the bitstream and advances the bitsttream
 *	read pointer. 
 *
 * See also :
 *	RVLCBitstreamFlushBitsBackward.
 *
 * Modified :		
 *	
 *
 ***********************************************************CommentEnd********/

UInt
RVLCBitstreamReadBitsBackward (Bitstream * stream, Int nbits, Char *s, Trace *trace, Int mode)

{
  UInt                l;

  l = RVLCBitstreamShowBitsBackward (stream, nbits);
  RVLCBitstreamFlushBitsBackward (stream, nbits);

  trace_routine(s, l, btos(l, nbits), trace, mode);
  
  return l;

}
/* RVLCBitstreamReadBitsBackward */

/***********************************************************CommentBegin******
 *
 * -- BitstreamByteAlign -- Advances the bitstream read pointer until it is
 *                          byte aligned
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	14-Jan-1997
 *
 * Purpose :		
 *	To advance the bitstream read pointer until it is byte aligned.
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream; 
 *
 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	Returns n_stuffed, the number of bits stuffed that were skipped.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	Advances the bitstream read pointer until the number of bits left in
 *      the buffer is a multiple of 8. Since the function
 *      BitstreamFillBuffer always reads bytes (multiples of 8 bits), this
 *      is the same as saying that the read pointer is byte aligned.
 *     
 *
 *
 * See also :
 *
 * Modified :		
 *	27.04.97 Luis Ducla-Soares: modified function to deal with
 *                                  bitstuffing as per VM6.0
 *
 ***********************************************************CommentEnd********/


UInt
BitstreamByteAlign (Bitstream *stream)
{
  
  UInt n_stuffed;
  C_UInt byte = 8;
  
  
  n_stuffed = stream->incnt % byte;
  if (n_stuffed == 0)
    n_stuffed = byte;
  stream->bitcnt += n_stuffed;
  stream->incnt -= n_stuffed;

  return n_stuffed;
  
}

/* BitstreamByteAlign */


/***********************************************************CommentBegin******
 *
 * -- BitstreamShowBitsByteAlign -- Shows the next "nbits" of the bitstream
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	28-April-1997
 *
 * Purpose :		
 *	To see the next "nbits" bitstream bits (byte aligned) without advancing the read
 *	pointer. 
 *
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to see after the byte alignment

 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	The value of the "nbits" right adjusted in one UInt.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	This function allows to see the next "nbits" after the current
 *	position of the bitstream pointer without advancing the pointer. It
 *	returns "nbits" bitstream bits right aligned in one UInt (see
 *	example)  
 *  			  ______ 
 *  			  |    | 
 *  			  v    v
 *  	bitstream -> 0000001000100111101 
 *  			  ^
 *  			  |
 *  	BitstreamShowBits(bitstream, 6) = 17
 *  	(i.e. 00000000000000000000000000010001) 
 *  					^    ^ 
 *  					|    |
 *  	
 *
 * See also :
 *	
 *
 * Modified :		
 *      23.05.97 Luis Ducla-Soares: changed it to deal with the larger input
 *                                  buffer added by Paulo.
 *
 ***********************************************************CommentEnd********/

UInt 
BitstreamShowBitsByteAlign (Bitstream * stream, Int nbits)

{
  UChar              *v;
  UInt                b;


  UInt n_stuffed;
  C_UInt byte = 8;



 /* to mask the n least significant bits of an integer */
  static UInt         msk[33] =
  {
    0x00000000, 0x00000001, 0x00000003, 0x00000007,
    0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
    0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
    0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
    0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
    0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
    0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
    0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
    0xffffffff
  };

  
  if (nbits > 8 * sizeof (UInt))
    {
      fprintf (stderr, "ERROR: number of bits greater than size of UInt.\n");
      exit (1);
    }

  n_stuffed = stream->incnt % byte;


  if (n_stuffed == 0)    /* to enable the VM5.1 stuffing mode, remove the  comments */
    n_stuffed = byte;



  if (stream->incnt < (nbits + n_stuffed))
    BitstreamFillBuffer (stream);


  v = stream->inbfr + ((INBFR_TOTAL_BITS - stream->incnt + n_stuffed) >> 3);
  b = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];


  return ((b >> (32 - nbits)) & msk[nbits]);

}				/* BitstreamShowBitsByteAlign */



/***********************************************************CommentBegin******
 *
 * -- CheckBitStuffing -- Shows the next "nbits" of the bitstream
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	28-Apr-1997
 *
 * Purpose :		
 *	To see the next "nbits" bitstream bits (byte aligned) without advancing the read
 *	pointer. 
 *
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to see after the byte alignment

 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	The value of the "nbits" right adjusted in one UInt.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	This function allows to see the next "nbits" after the current
 *	position of the bitstream pointer without advancing the pointer. It
 *	returns "nbits" bitstream bits right aligned in one UInt (see
 *	example)  
 *  			  ______ 
 *  			  |    | 
 *  			  v    v
 *  	bitstream -> 0000001000100111101 
 *  			  ^
 *  			  |
 *  	BitstreamShowBits(bitstream, 6) = 17
 *  	(i.e. 00000000000000000000000000010001) 
 *  					^    ^ 
 *  					|    |
 *  	
 *
 * See also :
 *	
 *
 * Modified :		
 *
 ***********************************************************CommentEnd********/

Int CheckBitStuffing(Bitstream *stream)
{

  UInt n_stuffed;
  C_UInt byte = 8;
  
  static UInt     bit_stuffing[9] =
  {
    0x00, 0x00, 0x01, 0x03,
    0x07, 0x0f, 0x1f, 0x3f,
    0x7f
  };


  n_stuffed = stream->incnt % byte;


  if (n_stuffed == 0)    /* to enable the VM5.1 stuffing mode, remove the  comments */
    n_stuffed = byte;


    
  if (BitstreamShowBits(stream,n_stuffed) != bit_stuffing[n_stuffed])
    return 0;
  else
    return 1;
}

                                 /* CheckBitStuffing  */
                                    

/***********************************************************CommentBegin******
 *
 * -- RVLCBitstreamCopy -- Shows the next "nbits" of the bitstream
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	28-Apr-1997
 *
 * Purpose :		
 *	To see the next "nbits" bitstream bits (byte aligned) without advancing the read
 *	pointer. 
 *
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to see after the byte alignment

 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	The value of the "nbits" right adjusted in one UInt.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	This function allows to see the next "nbits" after the current
 *	position of the bitstream pointer without advancing the pointer. It
 *	returns "nbits" bitstream bits right aligned in one UInt (see
 *	example)  
 *  			  ______ 
 *  			  |    | 
 *  			  v    v
 *  	bitstream -> 0000001000100111101 
 *  			  ^
 *  			  |
 *  	BitstreamShowBits(bitstream, 6) = 17
 *  	(i.e. 00000000000000000000000000010001) 
 *  					^    ^ 
 *  					|    |
 *  	
 *
 * See also :
 *	
 *
 * Modified :		
 *
 ***********************************************************CommentEnd********/

Void RVLCBitstreamCopy (Bitstream *stream1, Bitstream *stream2)
{

  Int j = 0;
  UChar l;
  UChar i = 1;



  UChar msk[9] = { 0x00, 0x80, 0x40, 0x20, 0x10,
		   0x08, 0x04, 0x02, 0x01 };



  while  ((((BitstreamShowBitsByteAlign(stream1,RESYNC_MARKER_LENGTH))!=RESYNC_MARKER) || (!CheckBitStuffing(stream1))) &&
	  (((BitstreamShowBitsByteAlign(stream1,VOP_START_CODE_LENGTH))!=VOP_START_CODE) || (!CheckBitStuffing(stream1))) && 
	  (((BitstreamShowBitsByteAlign(stream1,24))!=252) || (!CheckBitStuffing(stream1))))
    {
      l = BitstreamShowBits(stream1,1);
      BitstreamFlushBits(stream1,1);
      stream2->rdptr[j] += msk[i++]*l;
      stream2->incnt++;
      if (i > 8)
	{
	  i = 1;
	  j++;
	}
    }

}                       /* BitstreamCopyRVLC   */
    





/***********************************************************CommentBegin******
 *
 * -- RVLCBitstreamShowBitsForward -- Shows the next "nbits" of the bitstream
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	28-April-1997
 *
 * Purpose :		
 *	To see the next "nbits" bitstream bits without advancing the read
 *	pointer. 
 *
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to see.

 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	The value of the "nbits" right adjusted in one UInt.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	This function allows to see the next "nbits" after the current
 *	position of the bitstream pointer without advancing the pointer. It
 *	returns "nbits" bitstream bits right aligned in one UInt (see
 *	example)  
 *  			  ______ 
 *  			  |    | 
 *  			  v    v
 *  	bitstream -> 0000001000100111101 
 *  			  ^
 *  			  |
 *  	BitstreamShowBits(bitstream, 6) = 17
 *  	(i.e. 00000000000000000000000000010001) 
 *  					^    ^ 
 *  					|    |
 *  	
 *
 * See also :
 *	
 *
 * Modified :		
 *
 ***********************************************************CommentEnd********/

UInt 
RVLCBitstreamShowBitsForward (Bitstream * stream, Int nbits)

{
  UChar              *v;
  UInt                b, b1;
  Int                 c;

 /* to mask the n least significant bits of an integer */
  static UInt         msk[33] =
  {
    0x00000000, 0x00000001, 0x00000003, 0x00000007,
    0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
    0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
    0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
    0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
    0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
    0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
    0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
    0xffffffff
  };

  if (nbits > 8 * sizeof (UInt))
    {
      fprintf (stderr, "ERROR: number of bits greater than size of UInt.\n");
      exit (1);
    }


  v = stream->rdbfr + ((stream->bitcnt) >> 3);
  b = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
  c = (((8 - (stream->bitcnt & 7)) - 1) & 7) + 25;

  if (c < nbits)
    {
      b1 = v[4];
      return ((b << (nbits - c)) | (b1 >> (8 - (nbits - c)))) & msk[nbits];
    }
  else
    {
      return (b >> (c - nbits)) & msk[nbits];
    }


}				/* RVLCBitstreamShowBitsForward */



/***********************************************************CommentBegin******
 *
 * -- RVLCBitstreamShowBitsBackward -- Shows the next "nbits" of the bitstream
 *
 * Author :		
 *	Luis Ducla-Soares(IST) - lds@lx.it.pt
 *
 * Created :		
 *	28-Apr-1997
 *
 * Purpose :		
 *	To see the next "nbits" bitstream bits without advancing the read
 *	pointer. 
 *
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to see.

 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	The value of the "nbits" right adjusted in one UInt.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	This function allows to see the next "nbits" after the current
 *	position of the bitstream pointer without advancing the pointer. It
 *	returns "nbits" bitstream bits right aligned in one UInt (see
 *	example)  
 *  			  ______ 
 *  			  |    | 
 *  			  v    v
 *  	bitstream -> 0000001000100111101 
 *  			  ^
 *  			  |
 *  	BitstreamShowBits(bitstream, 6) = 17
 *  	(i.e. 00000000000000000000000000010001) 
 *  					^    ^ 
 *  					|    |
 *  	
 *
 * See also :
 *	
 *
 * Modified :		
 *      20.05.97 Luis Ducla-Soares: initialized variables to remove warnings.
 *
 ***********************************************************CommentEnd********/

UInt 
RVLCBitstreamShowBitsBackward (Bitstream * stream, Int nbits)

{
  UChar              *v;
  UInt                b, b1;
  Int                 c;

 /* to mask the n least significant bits of an integer */
  static UInt         msk[33] =
  {
    0x00000000, 0x00000001, 0x00000003, 0x00000007,
    0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
    0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
    0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
    0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
    0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
    0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
    0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
    0xffffffff
  };

  v = NULL;
  b = 0;

  if (nbits > 8 * sizeof (UInt))
    {
      fprintf (stderr, "ERROR: number of bits greater than size of UInt.\n");
      exit (1);
    }




  if ((((stream->bitcnt) >> 3) - 3) >= 0)
    {
      v = stream->rdbfr + ((stream->bitcnt) >> 3) - 3;
      b = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
    }
  else if ((((stream->bitcnt) >> 3) - 2) >= 0)
    {
      v = stream->rdbfr + ((stream->bitcnt) >> 3) - 2;
      b = (v[0] << 16) | (v[1] << 8) | v[2];
    }
  else if ((((stream->bitcnt) >> 3) - 1) >= 0)
    {
      v = stream->rdbfr + ((stream->bitcnt) >> 3) - 1;
      b = (v[0] << 8) | v[1];
    }
  else if (((stream->bitcnt) >> 3) >= 0)
    {
      v = stream->rdbfr + ((stream->bitcnt) >> 3);
      b = v[0];
    }

  c = ((stream->bitcnt)  & 7) + 24;

  if ((c < nbits) && (stream->bitcnt >= 32))
    {
      b1 = v[-1];
      return ((b >> (8 - ((stream->bitcnt) & 7 ))) | (b1 << c))  & msk[nbits];
    }
  else
    {
      return (b >> (8 - ((stream->bitcnt) & 7))) & msk[nbits];
    }




}				/* RVLCBitstreamShowBitsBackward */



/***********************************************************CommentBegin******
 *
 * -- RVLCBitstreamGotoEnd -- Shows the next "nbits" of the bitstream
 *
 * Author :		
 *	Luis Ducla Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	28-April-1997
 *
 * Purpose :		
 *	To see the next "nbits" bitstream bits without advancing the read
 *	pointer. 
 *
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to see.

 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	The value of the "nbits" right adjusted in one UInt.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	This function allows to see the next "nbits" after the current
 *	position of the bitstream pointer without advancing the pointer. It
 *	returns "nbits" bitstream bits right aligned in one UInt (see
 *	example)  
 *  			  ______ 
 *  			  |    | 
 *  			  v    v
 *  	bitstream -> 0000001000100111101 
 *  			  ^
 *  			  |
 *  	BitstreamShowBits(bitstream, 6) = 17
 *  	(i.e. 00000000000000000000000000010001) 
 *  					^    ^ 
 *  					|    |
 *  	
 *
 * See also :
 *	
 *
 * Modified :		
 *
 ***********************************************************CommentEnd********/

Void
RVLCBitstreamGotoEnd (Bitstream * stream)

{

  stream->bitcnt += stream->incnt;
  stream->incnt = 0;



}				/* RVLCBitstreamGotoEnd */




/***********************************************************CommentBegin******
 *
 * -- BitstreamShowBitsAfterX -- Shows "nbits" of the bitstream starting after
 *                               the next xbits.
 *
 * Author :		
 *	Luis Ducla-Soares (IST) - lds@lx.it.pt
 *
 * Created :		
 *	23-May-1997
 *
 * Purpose :		
 *	To see "nbits" of the bitstream bits after the next xbits, without advancing the read
 *	pointer. 
 *
 * 
 * Arguments in : 	
 *	Bitstream * stream,	input bitstream.
 *	Int nbits,		number of bits to see.

 *
 * Arguments in/out :	
 *	
 *
 * Arguments out :	
 *	
 *
 * Return values :	
 *	The value of the "nbits" right adjusted in one UInt.
 *
 * Side effects :	
 *	
 *
 * Description :	
 *	This function allows to see "nbits" after the next xbits after current
 *	position of the bitstream pointer without advancing the pointer. It
 *	returns "nbits" bitstream bits right aligned in one UInt (see
 *	example)  
 *  			  ______ 
 *  			  |    | 
 *  			  v    v
 *   bitstream -> 0000001000100111101 
 *  	         	^
 *  			|
 *                   pointer
 *
 *
 *  	BitstreamShowBits(bitstream, 2, 6) = 9
 *  	(i.e. 00000000000000000000000000001001) 
 *  					^    ^ 
 *  					|    |
 *  	
 *
 * See also : BitstreamShowBits
 *	
 *
 * Modified :		
 *
 ***********************************************************CommentEnd********/

UInt 
BitstreamShowBitsAfterX (Bitstream * stream, Int xbits, Int nbits)

{
  UChar              *v;
  UInt                b, b1;
  Int                 c;

 /* to mask the n least significant bits of an integer */
  static UInt         msk[33] =
  {
    0x00000000, 0x00000001, 0x00000003, 0x00000007,
    0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
    0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
    0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
    0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
    0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
    0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
    0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
    0xffffffff
  };


  if (nbits > 8 * sizeof (UInt))
    {
      fprintf (stderr, "ERROR: number of bits greater than size of UInt.\n");
      exit (1);
    }

  if (xbits + nbits >= 64)
    {
      fprintf (stderr, "ERROR: tried to read ahead by more than 64 bits!\n");
      exit(1);
    }

  if (stream->incnt < nbits)
    BitstreamFillBuffer (stream);

  v = stream->inbfr + ((INBFR_TOTAL_BITS - stream->incnt + xbits) >> 3);
  b = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
  c = ((stream->incnt - xbits - 1) & 7) + 25;

  if (c < nbits)
    {
      b1 = v[4];
      return ((b << (nbits - c)) | (b1 >> (8 - (nbits - c)))) & msk[nbits];
    }
  else
    {
      return (b >> (c - nbits)) & msk[nbits];
    }
}				/* BitstreamShowBitsAfterX */




