Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 /*
     12  * arith_routins.c
     13  *
     14  * This C file contains a function for finalizing the bitstream
     15  * after arithmetic coding.
     16  *
     17  */
     18 
     19 #include "arith_routins.h"
     20 
     21 
     22 /****************************************************************************
     23  * WebRtcIsacfix_EncTerminate(...)
     24  *
     25  * Final call to the arithmetic coder for an encoder call. This function
     26  * terminates and return byte stream.
     27  *
     28  * Input:
     29  *      - streamData        : in-/output struct containing bitstream
     30  *
     31  * Return value             : number of bytes in the stream
     32  */
     33 int16_t WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData)
     34 {
     35   uint16_t *streamPtr;
     36   uint16_t negCarry;
     37 
     38   /* point to the right place in the stream buffer */
     39   streamPtr = streamData->stream + streamData->stream_index;
     40 
     41   /* find minimum length (determined by current interval width) */
     42   if ( streamData->W_upper > 0x01FFFFFF )
     43   {
     44     streamData->streamval += 0x01000000;
     45 
     46     /* if result is less than the added value we must take care of the carry */
     47     if (streamData->streamval < 0x01000000)
     48     {
     49       /* propagate carry */
     50       if (streamData->full == 0) {
     51         /* Add value to current value */
     52         negCarry = *streamPtr;
     53         negCarry += 0x0100;
     54         *streamPtr = negCarry;
     55 
     56         /* if value is too big, propagate carry to next byte, and so on */
     57         while (!(negCarry))
     58         {
     59           negCarry = *--streamPtr;
     60           negCarry++;
     61           *streamPtr = negCarry;
     62         }
     63       } else {
     64         /* propagate carry by adding one to the previous byte in the
     65          * stream if that byte is 0xFFFF we need to propagate the carry
     66          * furhter back in the stream */
     67         while ( !(++(*--streamPtr)) );
     68       }
     69 
     70       /* put pointer back to the old value */
     71       streamPtr = streamData->stream + streamData->stream_index;
     72     }
     73     /* write remaining data to bitstream, if "full == 0" first byte has data */
     74     if (streamData->full == 0) {
     75       *streamPtr++ += (uint16_t)(streamData->streamval >> 24);
     76       streamData->full = 1;
     77     } else {
     78       *streamPtr = (uint16_t)((streamData->streamval >> 24) << 8);
     79       streamData->full = 0;
     80     }
     81   }
     82   else
     83   {
     84     streamData->streamval += 0x00010000;
     85 
     86     /* if result is less than the added value we must take care of the carry */
     87     if (streamData->streamval < 0x00010000)
     88     {
     89       /* propagate carry */
     90       if (streamData->full == 0) {
     91         /* Add value to current value */
     92         negCarry = *streamPtr;
     93         negCarry += 0x0100;
     94         *streamPtr = negCarry;
     95 
     96         /* if value to big, propagate carry to next byte, and so on */
     97         while (!(negCarry))
     98         {
     99           negCarry = *--streamPtr;
    100           negCarry++;
    101           *streamPtr = negCarry;
    102         }
    103       } else {
    104         /* Add carry to previous byte */
    105         while ( !(++(*--streamPtr)) );
    106       }
    107 
    108       /* put pointer back to the old value */
    109       streamPtr = streamData->stream + streamData->stream_index;
    110     }
    111     /* write remaining data (2 bytes) to bitstream */
    112     if (streamData->full) {
    113       *streamPtr++ = (uint16_t)(streamData->streamval >> 16);
    114     } else {
    115       *streamPtr++ |= (uint16_t)(streamData->streamval >> 24);
    116       *streamPtr = (uint16_t)(streamData->streamval >> 8) & 0xFF00;
    117     }
    118   }
    119 
    120   /* calculate stream length in bytes */
    121   return (((streamPtr - streamData->stream)<<1) + !(streamData->full));
    122 }
    123