Skip to content

Instantly share code, notes, and snippets.

@code-walkers
Created October 15, 2011 08:40
Show Gist options
  • Save code-walkers/1289284 to your computer and use it in GitHub Desktop.
Save code-walkers/1289284 to your computer and use it in GitHub Desktop.
getbits routine
/*Endian reverse function. If there is an instruction, its more efficient
*Can be used in the code below
*/
Uint32 EndianRev(unsigned int word)
{
Uint32 tmp = 0;
tmp = (((word & 0xff) << 24) & 0xff000000) ;
tmp |= (((word & 0xff00) << 8) & 0x00ff0000) ;
tmp |= (((word & 0xff0000) >> 8) & 0x0000ff00) ;
tmp |= (((word & 0xff000000) >> 24) & 0xff);
return tmp;
}
typedef struct
{
int currWord;
int bitsRemaining;
unsigned int *pBuff;
unsigned int bufferSizeInWords;
}buff_state;
/**
* Function:
* GetNextNBits
* Arguments:
* 1. pointer to an object of type buff_state.
* 2. number of bits to get
* 3. address of unsigned integer to collect output.
*
* Return Value:
* 'n' bits returned as an unsigned integer in 'output'
* 0 if success, -1 for invalid input (or) if no more bits present to get.
*
* Notes:
* Use inline commented code for reversing endian-ness.
* and your unsigned int is "Uint32". Sigh! too many limitations? :(
* Cannot ask for more than 32-bits.
* Initialize buff_state.currWord = 0;
* Initialize buff_state.bitsRemaining = 32;
* Initialize Input Buffer Size In words.
*
* Example:
* If the input buffer has 0xf0f0f0f0f0f0f0f0f0f0f0f0f....
* you pull bits from most significant just like from a fifo
* state.currWord = 0;
* state.bitsRemaining = 32;
* state.bufferSizeInWords = 500; //for example;
* state.pBuff = myBuff; //for example, Uint32 myBuff[500]
* GetNextNBits(&state,24, &output); // output = 0xf0f0f0
* GetNextNBits(&state,18, &output); // output = 0x3c3c3
* GetNextNBits(&state,30, &output); // output = 0x30f0f0f0
**/
int GetNextNBits(buff_state *pState,int n, unsigned int *output)
{
unsigned int retVal, curr,next;
/*Invalid input or not enough words*/
if( n > 32 || n <= 0 || pState->currWord >= pState->bufferSizeInWords ){
return -1;
}
/*we are on last word and you do not have enough bits*/
if( (pState->currWord == (pState->bufferSizeInWords - 1)) && pState->bitsRemaining < n){
return -1;
}
curr = pState->pBuff[pState->currWord];
//curr = EndianRev(pState->pBuff[pState->currWord]); //reverse endianness
/*Avoid segfault by accessing next word only when you have it*/
if(pState->currWord != pState->bufferSizeInWords - 1){
next = pState->pBuff[pState->currWord + 1];
//next = EndianRev(pState->pBuff[pState->currWord + 1]); //reverse endianness
}
if( pState->bitsRemaining < n ){
retVal = curr & ((0x1 << pState->bitsRemaining) - 1);
retVal <<= (n - pState->bitsRemaining);
next >>= (32 - n + pState->bitsRemaining );
retVal |= ( next & ((0x1 << (n - pState->bitsRemaining))-1) );
pState->bitsRemaining = 32 - (n - pState->bitsRemaining);
pState->currWord++;
}
else if( pState->bitsRemaining == n){
retVal = curr & ((0x1 << n) - 1);
pState->currWord++;
pState->bitsRemaining = 32;
}
else/*(pState->bitsRemaining > n)*/{
retVal = curr >> (pState->bitsRemaining - n);
retVal &= ((0x1 << n) - 1);
pState->bitsRemaining -= n;
}
*output = retVal;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment