/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

/*
 * arith_routinshist.c
 *
 * This C file contains arithmetic encoding and decoding.
 *
 */

#include "arith_routins.h"


/****************************************************************************
 * WebRtcIsacfix_EncHistMulti(...)
 *
 * Encode the histogram interval
 *
 * Input:
 *      - streamData        : in-/output struct containing bitstream
 *      - data              : data vector
 *      - cdf               : array of cdf arrays
 *      - lenData           : data vector length
 *
 * Return value             : 0 if ok
 *                            <0 if error detected
 */
int WebRtcIsacfix_EncHistMulti(Bitstr_enc *streamData,
                               const int16_t *data,
                               const uint16_t *const *cdf,
                               const int16_t lenData)
{
  uint32_t W_lower;
  uint32_t W_upper;
  uint32_t W_upper_LSB;
  uint32_t W_upper_MSB;
  uint16_t *streamPtr;
  uint16_t negCarry;
  uint16_t *maxStreamPtr;
  uint16_t *streamPtrCarry;
  uint32_t cdfLo;
  uint32_t cdfHi;
  int k;


  /* point to beginning of stream buffer
   * and set maximum streamPtr value */
  streamPtr = streamData->stream + streamData->stream_index;
  maxStreamPtr = streamData->stream + STREAM_MAXW16_60MS - 1;

  W_upper = streamData->W_upper;

  for (k = lenData; k > 0; k--)
  {
    /* fetch cdf_lower and cdf_upper from cdf tables */
    cdfLo = (uint32_t) *(*cdf + (uint32_t)*data);
    cdfHi = (uint32_t) *(*cdf++ + (uint32_t)*data++ + 1);

    /* update interval */
    W_upper_LSB = W_upper & 0x0000FFFF;
    W_upper_MSB = W_upper >> 16;
    W_lower = WEBRTC_SPL_UMUL(W_upper_MSB, cdfLo);
    W_lower += ((W_upper_LSB * cdfLo) >> 16);
    W_upper = WEBRTC_SPL_UMUL(W_upper_MSB, cdfHi);
    W_upper += ((W_upper_LSB * cdfHi) >> 16);

    /* shift interval such that it begins at zero */
    W_upper -= ++W_lower;

    /* add integer to bitstream */
    streamData->streamval += W_lower;

    /* handle carry */
    if (streamData->streamval < W_lower)
    {
      /* propagate carry */
      streamPtrCarry = streamPtr;
      if (streamData->full == 0) {
        negCarry = *streamPtrCarry;
        negCarry += 0x0100;
        *streamPtrCarry = negCarry;
        while (!(negCarry))
        {
          negCarry = *--streamPtrCarry;
          negCarry++;
          *streamPtrCarry = negCarry;
        }
      } else {
        while ( !(++(*--streamPtrCarry)) );
      }
    }

    /* renormalize interval, store most significant byte of streamval and update streamval
     * W_upper < 2^24 */
    while ( !(W_upper & 0xFF000000) )
    {
      W_upper <<= 8;
      if (streamData->full == 0) {
        *streamPtr++ += (uint16_t)(streamData->streamval >> 24);
        streamData->full = 1;
      } else {
        *streamPtr = (uint16_t)((streamData->streamval >> 24) << 8);
        streamData->full = 0;
      }

      if( streamPtr > maxStreamPtr ) {
        return -ISAC_DISALLOWED_BITSTREAM_LENGTH;
      }
      streamData->streamval <<= 8;
    }
  }

  /* calculate new stream_index */
  streamData->stream_index = streamPtr - streamData->stream;
  streamData->W_upper = W_upper;

  return 0;
}


/****************************************************************************
 * WebRtcIsacfix_DecHistBisectMulti(...)
 *
 * Function to decode more symbols from the arithmetic bytestream, using
 * method of bisection cdf tables should be of size 2^k-1 (which corresponds
 * to an alphabet size of 2^k-2)
 *
 * Input:
 *      - streamData        : in-/output struct containing bitstream
 *      - cdf               : array of cdf arrays
 *      - cdfSize           : array of cdf table sizes+1 (power of two: 2^k)
 *      - lenData           : data vector length
 *
 * Output:
 *      - data              : data vector
 *
 * Return value             : number of bytes in the stream
 *                            <0 if error detected
 */
int16_t WebRtcIsacfix_DecHistBisectMulti(int16_t *data,
                                         Bitstr_dec *streamData,
                                         const uint16_t *const *cdf,
                                         const uint16_t *cdfSize,
                                         const int16_t lenData)
{
  uint32_t    W_lower = 0;
  uint32_t    W_upper;
  uint32_t    W_tmp;
  uint32_t    W_upper_LSB;
  uint32_t    W_upper_MSB;
  uint32_t    streamval;
  const uint16_t *streamPtr;
  const uint16_t *cdfPtr;
  int16_t     sizeTmp;
  int             k;


  streamPtr = streamData->stream + streamData->stream_index;
  W_upper = streamData->W_upper;

  /* Error check: should not be possible in normal operation */
  if (W_upper == 0) {
    return -2;
  }

  /* first time decoder is called for this stream */
  if (streamData->stream_index == 0)
  {
    /* read first word from bytestream */
    streamval = (uint32_t)*streamPtr++ << 16;
    streamval |= *streamPtr++;
  } else {
    streamval = streamData->streamval;
  }

  for (k = lenData; k > 0; k--)
  {
    /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
    W_upper_LSB = W_upper & 0x0000FFFF;
    W_upper_MSB = W_upper >> 16;

    /* start halfway the cdf range */
    sizeTmp = *cdfSize++ / 2;
    cdfPtr = *cdf + (sizeTmp - 1);

    /* method of bisection */
    for ( ;; )
    {
      W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
      W_tmp += (W_upper_LSB * (*cdfPtr)) >> 16;
      sizeTmp /= 2;
      if (sizeTmp == 0) {
        break;
      }

      if (streamval > W_tmp)
      {
        W_lower = W_tmp;
        cdfPtr += sizeTmp;
      } else {
        W_upper = W_tmp;
        cdfPtr -= sizeTmp;
      }
    }
    if (streamval > W_tmp)
    {
      W_lower = W_tmp;
      *data++ = cdfPtr - *cdf++;
    } else {
      W_upper = W_tmp;
      *data++ = cdfPtr - *cdf++ - 1;
    }

    /* shift interval to start at zero */
    W_upper -= ++W_lower;

    /* add integer to bitstream */
    streamval -= W_lower;

    /* renormalize interval and update streamval */
    /* W_upper < 2^24 */
    while ( !(W_upper & 0xFF000000) )
    {
      /* read next byte from stream */
      if (streamData->full == 0) {
        streamval = (streamval << 8) | (*streamPtr++ & 0x00FF);
        streamData->full = 1;
      } else {
        streamval = (streamval << 8) | (*streamPtr >> 8);
        streamData->full = 0;
      }
      W_upper <<= 8;
    }


    /* Error check: should not be possible in normal operation */
    if (W_upper == 0) {
      return -2;
    }

  }

  streamData->stream_index = streamPtr - streamData->stream;
  streamData->W_upper = W_upper;
  streamData->streamval = streamval;

  if ( W_upper > 0x01FFFFFF ) {
    return (streamData->stream_index*2 - 3 + !streamData->full);
  } else {
    return (streamData->stream_index*2 - 2 + !streamData->full);
  }
}


/****************************************************************************
 * WebRtcIsacfix_DecHistOneStepMulti(...)
 *
 * Function to decode more symbols from the arithmetic bytestream, taking
 * single step up or down at a time.
 * cdf tables can be of arbitrary size, but large tables may take a lot of
 * iterations.
 *
 * Input:
 *      - streamData        : in-/output struct containing bitstream
 *      - cdf               : array of cdf arrays
 *      - initIndex         : vector of initial cdf table search entries
 *      - lenData           : data vector length
 *
 * Output:
 *      - data              : data vector
 *
 * Return value             : number of bytes in original stream
 *                            <0 if error detected
 */
int16_t WebRtcIsacfix_DecHistOneStepMulti(int16_t *data,
                                          Bitstr_dec *streamData,
                                          const uint16_t *const *cdf,
                                          const uint16_t *initIndex,
                                          const int16_t lenData)
{
  uint32_t    W_lower;
  uint32_t    W_upper;
  uint32_t    W_tmp;
  uint32_t    W_upper_LSB;
  uint32_t    W_upper_MSB;
  uint32_t    streamval;
  const uint16_t *streamPtr;
  const uint16_t *cdfPtr;
  int             k;


  streamPtr = streamData->stream + streamData->stream_index;
  W_upper = streamData->W_upper;
  /* Error check: Should not be possible in normal operation */
  if (W_upper == 0) {
    return -2;
  }

  /* Check if it is the first time decoder is called for this stream */
  if (streamData->stream_index == 0)
  {
    /* read first word from bytestream */
    streamval = (uint32_t)(*streamPtr++) << 16;
    streamval |= *streamPtr++;
  } else {
    streamval = streamData->streamval;
  }

  for (k = lenData; k > 0; k--)
  {
    /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
    W_upper_LSB = W_upper & 0x0000FFFF;
    W_upper_MSB = WEBRTC_SPL_RSHIFT_U32(W_upper, 16);

    /* start at the specified table entry */
    cdfPtr = *cdf + (*initIndex++);
    W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
    W_tmp += (W_upper_LSB * (*cdfPtr)) >> 16;

    if (streamval > W_tmp)
    {
      for ( ;; )
      {
        W_lower = W_tmp;

        /* range check */
        if (cdfPtr[0] == 65535) {
          return -3;
        }

        W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *++cdfPtr);
        W_tmp += (W_upper_LSB * (*cdfPtr)) >> 16;

        if (streamval <= W_tmp) {
          break;
        }
      }
      W_upper = W_tmp;
      *data++ = cdfPtr - *cdf++ - 1;
    } else {
      for ( ;; )
      {
        W_upper = W_tmp;
        --cdfPtr;

        /* range check */
        if (cdfPtr < *cdf) {
          return -3;
        }

        W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
        W_tmp += (W_upper_LSB * (*cdfPtr)) >> 16;

        if (streamval > W_tmp) {
          break;
        }
      }
      W_lower = W_tmp;
      *data++ = cdfPtr - *cdf++;
    }

    /* shift interval to start at zero */
    W_upper -= ++W_lower;

    /* add integer to bitstream */
    streamval -= W_lower;

    /* renormalize interval and update streamval */
    /* W_upper < 2^24 */
    while ( !(W_upper & 0xFF000000) )
    {
      /* read next byte from stream */
      if (streamData->full == 0) {
        streamval = (streamval << 8) | (*streamPtr++ & 0x00FF);
        streamData->full = 1;
      } else {
        streamval = (streamval << 8) | (*streamPtr >> 8);
        streamData->full = 0;
      }
      W_upper <<= 8;
    }
  }

  streamData->stream_index = streamPtr - streamData->stream;
  streamData->W_upper = W_upper;
  streamData->streamval = streamval;

  /* find number of bytes in original stream (determined by current interval width) */
  if ( W_upper > 0x01FFFFFF ) {
    return (streamData->stream_index*2 - 3 + !streamData->full);
  } else {
    return (streamData->stream_index*2 - 2 + !streamData->full);
  }
}
