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)33int16_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