
   /******************************************************************

       iLBC Speech Coder ANSI-C Source Code

       packing.c

       Copyright (C) The Internet Society (2004).
       All Rights Reserved.

   ******************************************************************/

#include <math.h>
#include <stdlib.h>

#include "iLBC_define.h"
#include "constants.h"
#include "helpfun.h"
#include "string.h"

   /*----------------------------------------------------------------*
    *  splitting an integer into first most significant bits and
    *  remaining least significant bits
    *---------------------------------------------------------------*/

void packsplit(int *index,      /* (i) the value to split */
  int *firstpart,               /* (o) the value specified by most
                                   significant bits */
  int *rest,                    /* (o) the value specified by least
                                   significant bits */
  int bitno_firstpart,          /* (i) number of bits in most
                                   significant part */
  int bitno_total               /* (i) number of bits in full range
                                   of value */
  )
{
  int bitno_rest = bitno_total - bitno_firstpart;

  *firstpart = *index >> (bitno_rest);
  *rest = *index - (*firstpart << (bitno_rest));
}

   /*----------------------------------------------------------------*
    *  combining a value corresponding to msb's with a value
    *  corresponding to lsb's
    *---------------------------------------------------------------*/

void packcombine(int *index,    /* (i/o) the msb value in the
                                   combined value out */
  int rest,                     /* (i) the lsb value */
  int bitno_rest                /* (i) the number of bits in the
                                   lsb part */
  )
{
  *index = *index << bitno_rest;
  *index += rest;
}

   /*----------------------------------------------------------------*
    *  packing of bits into bitstream, i.e., vector of bytes
    *---------------------------------------------------------------*/

void dopack(unsigned char **bitstream,  /* (i/o) on entrance pointer to
                                           place in bitstream to pack
                                           new data, on exit pointer
                                           to place in bitstream to
                                           pack future data */
  int index,                    /* (i) the value to pack */
  int bitno,                    /* (i) the number of bits that the
                                   value will fit within */
  int *pos                      /* (i/o) write position in the
                                   current byte */
  )
{
  int posLeft;

  /* Clear the bits before starting in a new byte */

  if ((*pos) == 0) {





    **bitstream = 0;
  }

  while (bitno > 0) {

    /* Jump to the next byte if end of this byte is reached */

    if (*pos == 8) {
      *pos = 0;
      (*bitstream)++;
      **bitstream = 0;
    }

    posLeft = 8 - (*pos);

    /* Insert index into the bitstream */

    if (bitno <= posLeft) {
      **bitstream |= (unsigned char) (index << (posLeft - bitno));
      *pos += bitno;
      bitno = 0;
    } else {
      **bitstream |= (unsigned char) (index >> (bitno - posLeft));

      *pos = 8;
      index -= ((index >> (bitno - posLeft)) << (bitno - posLeft));

      bitno -= posLeft;
    }
  }
}

   /*----------------------------------------------------------------*
    *  unpacking of bits from bitstream, i.e., vector of bytes
    *---------------------------------------------------------------*/

void unpack(unsigned char **bitstream,  /* (i/o) on entrance pointer to
                                           place in bitstream to
                                           unpack new data from, on
                                           exit pointer to place in
                                           bitstream to unpack future
                                           data from */
  int *index,                   /* (o) resulting value */
  int bitno,                    /* (i) number of bits used to
                                   represent the value */
  int *pos                      /* (i/o) read position in the
                                   current byte */
  )
{
  int BitsLeft;

  *index = 0;

  while (bitno > 0) {

    /* move forward in bitstream when the end of the
       byte is reached */

    if (*pos == 8) {
      *pos = 0;
      (*bitstream)++;
    }

    BitsLeft = 8 - (*pos);

    /* Extract bits to index */

    if (BitsLeft >= bitno) {
      *index += ((((**bitstream) << (*pos)) & 0xFF) >> (8 - bitno));

      *pos += bitno;
      bitno = 0;
    } else {

      if ((8 - bitno) > 0) {
        *index += ((((**bitstream) << (*pos)) & 0xFF) >> (8 - bitno));
        *pos = 8;
      } else {
        *index += (((int) (((**bitstream) << (*pos)) & 0xFF)) <<
          (bitno - 8));
        *pos = 8;
      }
      bitno -= BitsLeft;
    }
  }
}
