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  */
WebRtcIsacfix_EncTerminate(Bitstr_enc * streamData)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