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 WebRtc_Word16 WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData)
34 {
35 WebRtc_UWord16 *streamPtr;
36 WebRtc_UWord16 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++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
76 streamData->full = 1;
77 } else {
78 *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_W32(
79 WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8);
80 streamData->full = 0;
81 }
82 }
83 else
84 {
85 streamData->streamval += 0x00010000;
86
87 /* if result is less than the added value we must take care of the carry */
88 if (streamData->streamval < 0x00010000)
89 {
90 /* propagate carry */
91 if (streamData->full == 0) {
92 /* Add value to current value */
93 negCarry = *streamPtr;
94 negCarry += 0x0100;
95 *streamPtr = negCarry;
96
97 /* if value to big, propagate carry to next byte, and so on */
98 while (!(negCarry))
99 {
100 negCarry = *--streamPtr;
101 negCarry++;
102 *streamPtr = negCarry;
103 }
104 } else {
105 /* Add carry to previous byte */
106 while ( !(++(*--streamPtr)) );
107 }
108
109 /* put pointer back to the old value */
110 streamPtr = streamData->stream + streamData->stream_index;
111 }
112 /* write remaining data (2 bytes) to bitstream */
113 if (streamData->full) {
114 *streamPtr++ = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 16);
115 } else {
116 *streamPtr++ |= (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
117 *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 8)
118 & 0xFF00;
119 }
120 }
121
122 /* calculate stream length in bytes */
123 return (((streamPtr - streamData->stream)<<1) + !(streamData->full));
124 }
125