/* Copyright (C) 2002 Jean-Marc Valin 
   File: speex_bits.c

   Handles bit packing/unpacking

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:
   
   - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
   
   - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
   
   - Neither the name of the Xiph.org Foundation nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.
   
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <speex/speex_bits.h>
#include "arch.h"
#include "os_support.h"

/* Maximum size of the bit-stream (for fixed-size allocation) */
#ifndef MAX_CHARS_PER_FRAME
#define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR)
#endif

EXPORT void speex_bits_init(SpeexBits *bits)
{
   bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);
   if (!bits->chars)
      return;

   bits->buf_size = MAX_CHARS_PER_FRAME;

   bits->owner=1;

   speex_bits_reset(bits);
}

EXPORT void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
{
   bits->chars = (char*)buff;
   bits->buf_size = buf_size;

   bits->owner=0;

   speex_bits_reset(bits);
}

EXPORT void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size)
{
   bits->chars = (char*)buff;
   bits->buf_size = buf_size;

   bits->owner=0;

   bits->nbBits=buf_size<<LOG2_BITS_PER_CHAR;
   bits->charPtr=0;
   bits->bitPtr=0;
   bits->overflow=0;
   
}

EXPORT void speex_bits_destroy(SpeexBits *bits)
{
   if (bits->owner)
      speex_free(bits->chars);
   /* Will do something once the allocation is dynamic */
}

EXPORT void speex_bits_reset(SpeexBits *bits)
{
   /* We only need to clear the first byte now */
   bits->chars[0]=0;
   bits->nbBits=0;
   bits->charPtr=0;
   bits->bitPtr=0;
   bits->overflow=0;
}

EXPORT void speex_bits_rewind(SpeexBits *bits)
{
   bits->charPtr=0;
   bits->bitPtr=0;
   bits->overflow=0;
}

EXPORT void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
{
   int i;
   int nchars = len / BYTES_PER_CHAR;
   if (nchars > bits->buf_size)
   {
      speex_notify("Packet is larger than allocated buffer");
      if (bits->owner)
      {
         char *tmp = (char*)speex_realloc(bits->chars, nchars);
         if (tmp)
         {
            bits->buf_size=nchars;
            bits->chars=tmp;
         } else {
            nchars=bits->buf_size;
            speex_warning("Could not resize input buffer: truncating input");
         }
      } else {
         speex_warning("Do not own input buffer: truncating oversize input");
         nchars=bits->buf_size;
      }
   }
#if (BYTES_PER_CHAR==2)
/* Swap bytes to proper endian order (could be done externally) */
#define HTOLS(A) ((((A) >> 8)&0xff)|(((A) & 0xff)<<8))
#else
#define HTOLS(A) (A)
#endif
   for (i=0;i<nchars;i++)
      bits->chars[i]=HTOLS(chars[i]);

   bits->nbBits=nchars<<LOG2_BITS_PER_CHAR;
   bits->charPtr=0;
   bits->bitPtr=0;
   bits->overflow=0;
}

static void speex_bits_flush(SpeexBits *bits)
{
   int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
   if (bits->charPtr>0)
      SPEEX_MOVE(bits->chars, &bits->chars[bits->charPtr], nchars-bits->charPtr);
   bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;
   bits->charPtr=0;
}

EXPORT void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
{
   int i,pos;
   int nchars = nbytes/BYTES_PER_CHAR;

   if (((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)+nchars > bits->buf_size)
   {
      /* Packet is larger than allocated buffer */
      if (bits->owner)
      {
         char *tmp = (char*)speex_realloc(bits->chars, (bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1);
         if (tmp)
         {
            bits->buf_size=(bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1;
            bits->chars=tmp;
         } else {
            nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;
            speex_warning("Could not resize input buffer: truncating oversize input");
         }
      } else {
         speex_warning("Do not own input buffer: truncating oversize input");
         nchars=bits->buf_size;
      }
   }

   speex_bits_flush(bits);
   pos=bits->nbBits>>LOG2_BITS_PER_CHAR;
   for (i=0;i<nchars;i++)
      bits->chars[pos+i]=HTOLS(chars[i]);
   bits->nbBits+=nchars<<LOG2_BITS_PER_CHAR;
}

EXPORT int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
{
   int i;
   int max_nchars = max_nbytes/BYTES_PER_CHAR;
   int charPtr, bitPtr, nbBits;

   /* Insert terminator, but save the data so we can put it back after */
   bitPtr=bits->bitPtr;
   charPtr=bits->charPtr;
   nbBits=bits->nbBits;
   speex_bits_insert_terminator(bits);
   bits->bitPtr=bitPtr;
   bits->charPtr=charPtr;
   bits->nbBits=nbBits;

   if (max_nchars > ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR))
      max_nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);

   for (i=0;i<max_nchars;i++)
      chars[i]=HTOLS(bits->chars[i]);
   return max_nchars*BYTES_PER_CHAR;
}

EXPORT int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)
{
   int max_nchars = max_nbytes/BYTES_PER_CHAR;
   int i;
   if (max_nchars > ((bits->nbBits)>>LOG2_BITS_PER_CHAR))
      max_nchars = ((bits->nbBits)>>LOG2_BITS_PER_CHAR);
   for (i=0;i<max_nchars;i++)
      chars[i]=HTOLS(bits->chars[i]);

   if (bits->bitPtr>0)
      bits->chars[0]=bits->chars[max_nchars];
   else
      bits->chars[0]=0;
   bits->charPtr=0;
   bits->nbBits &= (BITS_PER_CHAR-1);
   return max_nchars*BYTES_PER_CHAR;
}

EXPORT void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
{
   unsigned int d=data;

   if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
   {
      speex_notify("Buffer too small to pack bits");
      if (bits->owner)
      {
         int new_nchars = ((bits->buf_size+5)*3)>>1;
         char *tmp = (char*)speex_realloc(bits->chars, new_nchars);
         if (tmp)
         {
            bits->buf_size=new_nchars;
            bits->chars=tmp;
         } else {
            speex_warning("Could not resize input buffer: not packing");
            return;
         }
      } else {
         speex_warning("Do not own input buffer: not packing");
         return;
      }
   }

   while(nbBits)
   {
      int bit;
      bit = (d>>(nbBits-1))&1;
      bits->chars[bits->charPtr] |= bit<<(BITS_PER_CHAR-1-bits->bitPtr);
      bits->bitPtr++;

      if (bits->bitPtr==BITS_PER_CHAR)
      {
         bits->bitPtr=0;
         bits->charPtr++;
         bits->chars[bits->charPtr] = 0;
      }
      bits->nbBits++;
      nbBits--;
   }
}

EXPORT int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
{
   unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
   /* If number is negative */
   if (d>>(nbBits-1))
   {
      d |= (-1)<<nbBits;
   }
   return d;
}

EXPORT unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
{
   unsigned int d=0;
   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
      bits->overflow=1;
   if (bits->overflow)
      return 0;
   while(nbBits)
   {
      d<<=1;
      d |= (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
      bits->bitPtr++;
      if (bits->bitPtr==BITS_PER_CHAR)
      {
         bits->bitPtr=0;
         bits->charPtr++;
      }
      nbBits--;
   }
   return d;
}

EXPORT unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
{
   unsigned int d=0;
   int bitPtr, charPtr;
   char *chars;

   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
     bits->overflow=1;
   if (bits->overflow)
      return 0;

   bitPtr=bits->bitPtr;
   charPtr=bits->charPtr;
   chars = bits->chars;
   while(nbBits)
   {
      d<<=1;
      d |= (chars[charPtr]>>(BITS_PER_CHAR-1 - bitPtr))&1;
      bitPtr++;
      if (bitPtr==BITS_PER_CHAR)
      {
         bitPtr=0;
         charPtr++;
      }
      nbBits--;
   }
   return d;
}

EXPORT int speex_bits_peek(SpeexBits *bits)
{
   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)
      bits->overflow=1;
   if (bits->overflow)
      return 0;
   return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
}

EXPORT void speex_bits_advance(SpeexBits *bits, int n)
{
    if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
      bits->overflow=1;
      return;
    }
   bits->charPtr += (bits->bitPtr+n) >> LOG2_BITS_PER_CHAR; /* divide by BITS_PER_CHAR */
   bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1);       /* modulo by BITS_PER_CHAR */
}

EXPORT int speex_bits_remaining(SpeexBits *bits)
{
   if (bits->overflow)
      return -1;
   else
      return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);
}

EXPORT int speex_bits_nbytes(SpeexBits *bits)
{
   return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
}

EXPORT void speex_bits_insert_terminator(SpeexBits *bits)
{
   if (bits->bitPtr)
      speex_bits_pack(bits, 0, 1);
   while (bits->bitPtr)
      speex_bits_pack(bits, 1, 1);
}
