blob: 4d252efdbe77ec458ac11555ea3b4e53cb9ed421 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
/*
------------------------------------------------------------------------------
PacketVideo Corp.
MP3 Decoder Library
Filename: pvmp3_getbits.cpp
Date: 09/21/2007
------------------------------------------------------------------------------
REVISION HISTORY
Description:
------------------------------------------------------------------------------
INPUT AND OUTPUT DEFINITIONS
Inputs:
tmp3Bits *inputStream, structure holding the input stream parameters
int32 neededBits number of bits to read from the bit stream
Outputs:
word parsed from teh bitstream, with size neededBits-bits,
------------------------------------------------------------------------------
FUNCTION DESCRIPTION
------------------------------------------------------------------------------
REQUIREMENTS
------------------------------------------------------------------------------
REFERENCES
[1] ISO MPEG Audio Subgroup Software Simulation Group (1996)
ISO 13818-3 MPEG-2 Audio Decoder - Lower Sampling Frequency Extension
------------------------------------------------------------------------------
PSEUDO-CODE
------------------------------------------------------------------------------
*/
/*----------------------------------------------------------------------------
; INCLUDES
----------------------------------------------------------------------------*/
#include "pvmp3_getbits.h"
/*----------------------------------------------------------------------------
; MACROS
; Define module specific macros here
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
; DEFINES
; Include all pre-processor statements here. Include conditional
; compile variables also.
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
; LOCAL FUNCTION DEFINITIONS
; Function Prototype declaration
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
; LOCAL STORE/BUFFER/POINTER DEFINITIONS
; Variable declaration - defined here and used outside this module
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
; EXTERNAL FUNCTION REFERENCES
; Declare functions defined elsewhere and referenced in this module
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
; Declare variables used in this module but defined elsewhere
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
uint32 getNbits(tmp3Bits *ptBitStream,
int32 neededBits) /* number of bits to read from the bitstream (up to 25) */
{
uint32 offset;
uint32 bitIndex;
uint32 bytesToFetch;
uint8 Elem = 0; /* Needs to be same type as pInput->pBuffer */
uint8 Elem1 = 0;
uint8 Elem2 = 0;
uint8 Elem3 = 0;
uint32 returnValue = 0;
if (!neededBits)
{
return (returnValue);
}
offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
/* Remove extra high bits by shifting up */
bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ;
switch (bytesToFetch)
{
case 4:
Elem3 = *(ptBitStream->pBuffer + module(offset + 3, BUFSIZE));
[[fallthrough]];
case 3:
Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE));
[[fallthrough]];
case 2:
Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
[[fallthrough]];
case 1:
Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
}
returnValue = (((uint32)(Elem)) << 24) |
(((uint32)(Elem1)) << 16) |
(((uint32)(Elem2)) << 8) |
((uint32)(Elem3));
/* This line is faster than to mask off the high bits. */
returnValue <<= bitIndex;
/* Move the field down. */
returnValue >>= (32 - neededBits);
ptBitStream->usedBits += neededBits;
return (returnValue);
}
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
uint16 getUpTo9bits(tmp3Bits *ptBitStream,
int32 neededBits) /* number of bits to read from the bit stream 2 to 9 */
{
uint32 offset;
uint32 bitIndex;
uint32 bytesToFetch;
uint8 Elem = 0; /* Needs to be same type as pInput->pBuffer */
uint8 Elem1 = 0;
uint16 returnValue;
offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
/* Remove extra high bits by shifting up */
bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ;
if (bytesToFetch > 1)
{
Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
}
else if (bytesToFetch > 0)
{
Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
}
returnValue = (((uint16)(Elem)) << 8) |
((uint16)(Elem1));
ptBitStream->usedBits += neededBits;
/* This line is faster than to mask off the high bits. */
returnValue = (returnValue << (bitIndex));
/* Move the field down. */
return (uint16)(returnValue >> (16 - neededBits));
}
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
uint32 getUpTo17bits(tmp3Bits *ptBitStream,
int32 neededBits) /* number of bits to read from the bit stream 2 to 8 */
{
uint32 offset;
uint32 bitIndex;
uint32 bytesToFetch;
uint8 Elem = 0; /* Needs to be same type as pInput->pBuffer */
uint8 Elem1 = 0;
uint8 Elem2 = 0;
uint32 returnValue;
offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
/* Remove extra high bits by shifting up */
bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ;
if (bytesToFetch > 2)
{
Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE));
}
else if (bytesToFetch > 1)
{
Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
}
else if (bytesToFetch > 0)
{
Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
}
returnValue = (((uint32)(Elem)) << 16) |
(((uint32)(Elem1)) << 8) |
((uint32)(Elem2));
ptBitStream->usedBits += neededBits;
/* This line is faster than to mask off the high bits. */
returnValue = 0xFFFFFF & (returnValue << (bitIndex));
/* Move the field down. */
return (uint32)(returnValue >> (24 - neededBits));
}
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
uint8 get1bit(tmp3Bits *ptBitStream) /* number of bits to read from the bit stream */
{
uint32 offset;
uint32 bitIndex;
uint8 returnValue;
offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
returnValue = *(ptBitStream->pBuffer + module(offset , BUFSIZE));
/* Remove extra high bits by shifting up */
bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
ptBitStream->usedBits++;
/* This line is faster than to mask off the high bits. */
returnValue = (returnValue << (bitIndex));
return (uint8)(returnValue >> 7);
}