Created
October 15, 2011 08:40
-
-
Save code-walkers/1289284 to your computer and use it in GitHub Desktop.
getbits routine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*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