blob: 79ec9671a57c6abf364ee084cad36359fabc882e [file] [log] [blame]
/*
* 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.
*/
#include "bitstream_parser.h"
namespace webrtc {
BitstreamParser::BitstreamParser(const WebRtc_UWord8* data, const WebRtc_UWord32 dataLength) :
_data(data),
_dataLength(dataLength),
_byteOffset(0),
_bitOffset(0)
{
}
// todo should we have any error codes from this?
WebRtc_UWord8
BitstreamParser::Get1Bit()
{
WebRtc_UWord8 retVal = 0x1 & (_data[_byteOffset] >> (7-_bitOffset++));
// prepare next byte
if(_bitOffset == 8)
{
_bitOffset = 0;
_byteOffset++;
}
return retVal;
}
WebRtc_UWord8
BitstreamParser::Get2Bits()
{
WebRtc_UWord8 retVal = (Get1Bit() << 1);
retVal += Get1Bit();
return retVal;
}
WebRtc_UWord8
BitstreamParser::Get3Bits()
{
WebRtc_UWord8 retVal = (Get1Bit() << 2);
retVal += (Get1Bit() << 1);
retVal += Get1Bit();
return retVal;
}
WebRtc_UWord8
BitstreamParser::Get4Bits()
{
WebRtc_UWord8 retVal = (Get1Bit() << 3);
retVal += (Get1Bit() << 2);
retVal += (Get1Bit() << 1);
retVal += Get1Bit();
return retVal;
}
WebRtc_UWord8
BitstreamParser::Get5Bits()
{
WebRtc_UWord8 retVal = (Get1Bit() << 4);
retVal += (Get1Bit() << 3);
retVal += (Get1Bit() << 2);
retVal += (Get1Bit() << 1);
retVal += Get1Bit();
return retVal;
}
WebRtc_UWord8
BitstreamParser::Get6Bits()
{
WebRtc_UWord8 retVal = (Get1Bit() << 5);
retVal += (Get1Bit() << 4);
retVal += (Get1Bit() << 3);
retVal += (Get1Bit() << 2);
retVal += (Get1Bit() << 1);
retVal += Get1Bit();
return retVal;
}
WebRtc_UWord8
BitstreamParser::Get7Bits()
{
WebRtc_UWord8 retVal = (Get1Bit() << 6);
retVal += (Get1Bit() << 5);
retVal += (Get1Bit() << 4);
retVal += (Get1Bit() << 3);
retVal += (Get1Bit() << 2);
retVal += (Get1Bit() << 1);
retVal += Get1Bit();
return retVal;
}
WebRtc_UWord8
BitstreamParser::Get8Bits()
{
WebRtc_UWord16 retVal;
if(_bitOffset != 0)
{
// read 16 bits
retVal = (_data[_byteOffset] << 8)+ (_data[_byteOffset+1]) ;
retVal = retVal >> (8-_bitOffset);
} else
{
retVal = _data[_byteOffset];
}
_byteOffset++;
return (WebRtc_UWord8)retVal;
}
WebRtc_UWord16
BitstreamParser::Get16Bits()
{
WebRtc_UWord32 retVal;
if(_bitOffset != 0)
{
// read 24 bits
retVal = (_data[_byteOffset] << 16) + (_data[_byteOffset+1] << 8) + (_data[_byteOffset+2]);
retVal = retVal >> (8-_bitOffset);
}else
{
// read 16 bits
retVal = (_data[_byteOffset] << 8) + (_data[_byteOffset+1]) ;
}
_byteOffset += 2;
return (WebRtc_UWord16)retVal;
}
WebRtc_UWord32
BitstreamParser::Get24Bits()
{
WebRtc_UWord32 retVal;
if(_bitOffset != 0)
{
// read 32 bits
retVal = (_data[_byteOffset] << 24) + (_data[_byteOffset+1] << 16) + (_data[_byteOffset+2] << 8) + (_data[_byteOffset+3]);
retVal = retVal >> (8-_bitOffset);
}else
{
// read 24 bits
retVal = (_data[_byteOffset] << 16) + (_data[_byteOffset+1] << 8) + (_data[_byteOffset+2]) ;
}
_byteOffset += 3;
return retVal & 0x00ffffff; // we need to clean up the high 8 bits
}
WebRtc_UWord32
BitstreamParser::Get32Bits()
{
WebRtc_UWord32 retVal;
if(_bitOffset != 0)
{
// read 40 bits
WebRtc_UWord64 tempVal = _data[_byteOffset];
tempVal <<= 8;
tempVal += _data[_byteOffset+1];
tempVal <<= 8;
tempVal += _data[_byteOffset+2];
tempVal <<= 8;
tempVal += _data[_byteOffset+3];
tempVal <<= 8;
tempVal += _data[_byteOffset+4];
tempVal >>= (8-_bitOffset);
retVal = WebRtc_UWord32(tempVal);
}else
{
// read 32 bits
retVal = (_data[_byteOffset]<< 24) + (_data[_byteOffset+1] << 16) + (_data[_byteOffset+2] << 8) + (_data[_byteOffset+3]) ;
}
_byteOffset += 4;
return retVal;
}
// Exp-Golomb codes
/*
with "prefix" and "suffix" bits and assignment to codeNum ranges (informative)
Bit string form Range of codeNum
1 0
0 1 x0 1..2
0 0 1 x1 x0 3..6
0 0 0 1 x2 x1 x0 7..14
0 0 0 0 1 x3 x2 x1 x0 15..30
0 0 0 0 0 1 x4 x3 x2 x1 x0 31..62
*/
WebRtc_UWord32
BitstreamParser::GetUE()
{
WebRtc_UWord32 retVal = 0;
WebRtc_UWord8 numLeadingZeros = 0;
while (Get1Bit() != 1)
{
numLeadingZeros++;
}
// prefix
retVal = (1 << numLeadingZeros) - 1;
// suffix
while (numLeadingZeros)
{
retVal += (Get1Bit() << --numLeadingZeros);
}
return retVal;
}
} // namespace webrtc