Files
squeezelite-esp32/components/spotify/cspot/bell/libhelix-aac/bitstream.c
Philippe G 898998efb0 big merge
2021-12-18 21:04:23 -08:00

262 lines
9.2 KiB
C

/* ***** BEGIN LICENSE BLOCK *****
* Source last modified: $Id: bitstream.c,v 1.2 2005/09/27 20:31:11 jrecker Exp $
*
* Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file,
* are subject to the current version of the RealNetworks Public
* Source License (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the current version of the RealNetworks Community
* Source License (the "RCSL") available at
* http://www.helixcommunity.org/content/rcsl, in which case the RCSL
* will apply. You may also obtain the license terms directly from
* RealNetworks. You may not use this file except in compliance with
* the RPSL or, if you have a valid RCSL with RealNetworks applicable
* to this file, the RCSL. Please see the applicable RPSL or RCSL for
* the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the
* portions it created.
*
* This file, and the files included with this file, is distributed
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
/**************************************************************************************
* Fixed-point HE-AAC decoder
* Jon Recker (jrecker@real.com)
* February 2005
*
* bitstream.c - bitstream parsing functions
**************************************************************************************/
#include "bitstream.h"
/**************************************************************************************
* Function: SetBitstreamPointer
*
* Description: initialize bitstream reader
*
* Inputs: pointer to BitStreamInfo struct
* number of bytes in bitstream
* pointer to byte-aligned buffer of data to read from
*
* Outputs: initialized bitstream info struct
*
* Return: none
**************************************************************************************/
void SetBitstreamPointer(BitStreamInfo *bsi, int nBytes, unsigned char *buf)
{
/* init bitstream */
bsi->bytePtr = buf;
bsi->iCache = 0; /* 4-byte unsigned int */
bsi->cachedBits = 0; /* i.e. zero bits in cache */
bsi->nBytes = nBytes;
}
/**************************************************************************************
* Function: RefillBitstreamCache
*
* Description: read new data from bitstream buffer into 32-bit cache
*
* Inputs: pointer to initialized BitStreamInfo struct
*
* Outputs: updated bitstream info struct
*
* Return: none
*
* Notes: only call when iCache is completely drained (resets bitOffset to 0)
* always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer)
* stores data as big-endian in cache, regardless of machine endian-ness
**************************************************************************************/
//Optimized for REV16, REV32 (FB)
static __inline void RefillBitstreamCache(BitStreamInfo *bsi)
{
int nBytes = bsi->nBytes;
if (nBytes >= 4) {
/* optimize for common case, independent of machine endian-ness */
bsi->iCache = (*bsi->bytePtr++) << 24;
bsi->iCache |= (*bsi->bytePtr++) << 16;
bsi->iCache |= (*bsi->bytePtr++) << 8;
bsi->iCache |= (*bsi->bytePtr++);
bsi->cachedBits = 32;
bsi->nBytes -= 4;
} else {
bsi->iCache = 0;
while (nBytes--) {
bsi->iCache |= (*bsi->bytePtr++);
bsi->iCache <<= 8;
}
bsi->iCache <<= ((3 - bsi->nBytes)*8);
bsi->cachedBits = 8*bsi->nBytes;
bsi->nBytes = 0;
}
}
/**************************************************************************************
* Function: GetBits
*
* Description: get bits from bitstream, advance bitstream pointer
*
* Inputs: pointer to initialized BitStreamInfo struct
* number of bits to get from bitstream
*
* Outputs: updated bitstream info struct
*
* Return: the next nBits bits of data from bitstream buffer
*
* Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f
* for speed, does not indicate error if you overrun bit buffer
* if nBits == 0, returns 0
**************************************************************************************/
unsigned int GetBits(BitStreamInfo *bsi, int nBits)
{
unsigned int data, lowBits;
nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */
data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */
data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */
bsi->iCache <<= nBits; /* left-justify cache */
bsi->cachedBits -= nBits; /* how many bits have we drawn from the cache so far */
/* if we cross an int boundary, refill the cache */
if (bsi->cachedBits < 0) {
lowBits = -bsi->cachedBits;
RefillBitstreamCache(bsi);
data |= bsi->iCache >> (32 - lowBits); /* get the low-order bits */
bsi->cachedBits -= lowBits; /* how many bits have we drawn from the cache so far */
bsi->iCache <<= lowBits; /* left-justify cache */
}
return data;
}
/**************************************************************************************
* Function: GetBitsNoAdvance
*
* Description: get bits from bitstream, do not advance bitstream pointer
*
* Inputs: pointer to initialized BitStreamInfo struct
* number of bits to get from bitstream
*
* Outputs: none (state of BitStreamInfo struct left unchanged)
*
* Return: the next nBits bits of data from bitstream buffer
*
* Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f
* for speed, does not indicate error if you overrun bit buffer
* if nBits == 0, returns 0
**************************************************************************************/
unsigned int GetBitsNoAdvance(BitStreamInfo *bsi, int nBits)
{
unsigned char *buf;
unsigned int data, iCache;
signed int lowBits;
nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */
data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */
data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */
lowBits = nBits - bsi->cachedBits; /* how many bits do we have left to read */
/* if we cross an int boundary, read next bytes in buffer */
if (lowBits > 0) {
iCache = 0;
buf = bsi->bytePtr;
while (lowBits > 0) {
iCache <<= 8;
if (buf < bsi->bytePtr + bsi->nBytes)
iCache |= (unsigned int)*buf++;
lowBits -= 8;
}
lowBits = -lowBits;
data |= iCache >> lowBits;
}
return data;
}
/**************************************************************************************
* Function: AdvanceBitstream
*
* Description: move bitstream pointer ahead
*
* Inputs: pointer to initialized BitStreamInfo struct
* number of bits to advance bitstream
*
* Outputs: updated bitstream info struct
*
* Return: none
*
* Notes: generally used following GetBitsNoAdvance(bsi, maxBits)
**************************************************************************************/
void AdvanceBitstream(BitStreamInfo *bsi, int nBits)
{
nBits &= 0x1f;
if (nBits > bsi->cachedBits) {
nBits -= bsi->cachedBits;
RefillBitstreamCache(bsi);
}
bsi->iCache <<= nBits;
bsi->cachedBits -= nBits;
}
/**************************************************************************************
* Function: CalcBitsUsed
*
* Description: calculate how many bits have been read from bitstream
*
* Inputs: pointer to initialized BitStreamInfo struct
* pointer to start of bitstream buffer
* bit offset into first byte of startBuf (0-7)
*
* Outputs: none
*
* Return: number of bits read from bitstream, as offset from startBuf:startOffset
**************************************************************************************/
int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset)
{
int bitsUsed;
bitsUsed = (bsi->bytePtr - startBuf) * 8;
bitsUsed -= bsi->cachedBits;
bitsUsed -= startOffset;
return bitsUsed;
}
/**************************************************************************************
* Function: ByteAlignBitstream
*
* Description: bump bitstream pointer to start of next byte
*
* Inputs: pointer to initialized BitStreamInfo struct
*
* Outputs: byte-aligned bitstream BitStreamInfo struct
*
* Return: none
*
* Notes: if bitstream is already byte-aligned, do nothing
**************************************************************************************/
void ByteAlignBitstream(BitStreamInfo *bsi)
{
int offset;
offset = bsi->cachedBits & 0x07;
AdvanceBitstream(bsi, offset);
}