| /* |
| * 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 |
| */ |
| WebRtc_Word16 WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData) |
| { |
| WebRtc_UWord16 *streamPtr; |
| WebRtc_UWord16 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++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24); |
| streamData->full = 1; |
| } else { |
| *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_W32( |
| WEBRTC_SPL_RSHIFT_W32(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++ = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 16); |
| } else { |
| *streamPtr++ |= (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24); |
| *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 8) |
| & 0xFF00; |
| } |
| } |
| |
| /* calculate stream length in bytes */ |
| return (((streamPtr - streamData->stream)<<1) + !(streamData->full)); |
| } |