/*
 *  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_routins.c
 *
 * This C file contains a function for finalizing the bitstream
 * after arithmetic coding.
 *
 */

#include "arith_routins.h"


/****************************************************************************
 * WebRtcIsacfix_EncTerminate(...)
 *
 * Final call to the arithmetic coder for an encoder call. This function
 * terminates and return byte stream.
 *
 * Input:
 *      - streamData        : in-/output struct containing bitstream
 *
 * Return value             : number of bytes in the stream
 */
int16_t WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData)
{
  uint16_t *streamPtr;
  uint16_t negCarry;

  /* point to the right place in the stream buffer */
  streamPtr = streamData->stream + streamData->stream_index;

  /* find minimum length (determined by current interval width) */
  if ( streamData->W_upper > 0x01FFFFFF )
  {
    streamData->streamval += 0x01000000;

    /* if result is less than the added value we must take care of the carry */
    if (streamData->streamval < 0x01000000)
    {
      /* propagate carry */
      if (streamData->full == 0) {
        /* Add value to current value */
        negCarry = *streamPtr;
        negCarry += 0x0100;
        *streamPtr = negCarry;

        /* if value is too big, propagate carry to next byte, and so on */
        while (!(negCarry))
        {
          negCarry = *--streamPtr;
          negCarry++;
          *streamPtr = negCarry;
        }
      } else {
        /* propagate carry by adding one to the previous byte in the
         * stream if that byte is 0xFFFF we need to propagate the carry
         * furhter back in the stream */
        while ( !(++(*--streamPtr)) );
      }

      /* put pointer back to the old value */
      streamPtr = streamData->stream + streamData->stream_index;
    }
    /* write remaining data to bitstream, if "full == 0" first byte has data */
    if (streamData->full == 0) {
      *streamPtr++ += (uint16_t)(streamData->streamval >> 24);
      streamData->full = 1;
    } else {
      *streamPtr = (uint16_t)((streamData->streamval >> 24) << 8);
      streamData->full = 0;
    }
  }
  else
  {
    streamData->streamval += 0x00010000;

    /* if result is less than the added value we must take care of the carry */
    if (streamData->streamval < 0x00010000)
    {
      /* propagate carry */
      if (streamData->full == 0) {
        /* Add value to current value */
        negCarry = *streamPtr;
        negCarry += 0x0100;
        *streamPtr = negCarry;

        /* if value to big, propagate carry to next byte, and so on */
        while (!(negCarry))
        {
          negCarry = *--streamPtr;
          negCarry++;
          *streamPtr = negCarry;
        }
      } else {
        /* Add carry to previous byte */
        while ( !(++(*--streamPtr)) );
      }

      /* put pointer back to the old value */
      streamPtr = streamData->stream + streamData->stream_index;
    }
    /* write remaining data (2 bytes) to bitstream */
    if (streamData->full) {
      *streamPtr++ = (uint16_t)(streamData->streamval >> 16);
    } else {
      *streamPtr++ |= (uint16_t)(streamData->streamval >> 24);
      *streamPtr = (uint16_t)(streamData->streamval >> 8) & 0xFF00;
    }
  }

  /* calculate stream length in bytes */
  return (((streamPtr - streamData->stream)<<1) + !(streamData->full));
}
