Merge pull request #849 from terrelln/30

[bitstream] Allow adding 31 bits at a time
This commit is contained in:
Yann Collet 2017-09-19 14:25:10 -07:00 committed by GitHub
commit c399ab4804

View File

@ -194,11 +194,14 @@ MEM_STATIC unsigned BIT_highbit32 (register U32 val)
} }
/*===== Local Constants =====*/ /*===== Local Constants =====*/
static const unsigned BIT_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, static const unsigned BIT_mask[] = {
0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0, 1, 3, 7, 0xF, 0x1F,
0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF,
0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF }; /* up to 26 bits */ 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF,
0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,
0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF,
0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */
#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0]))
/*-************************************************************** /*-**************************************************************
* bitStream encoding * bitStream encoding
@ -220,11 +223,14 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
} }
/*! BIT_addBits() : /*! BIT_addBits() :
* can add up to 26 bits into `bitC`. * can add up to 31 bits into `bitC`.
* Note : does not check for register overflow ! */ * Note : does not check for register overflow ! */
MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
size_t value, unsigned nbBits) size_t value, unsigned nbBits)
{ {
MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32);
assert(nbBits < BIT_MASK_SIZE);
assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos; bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
bitC->bitPos += nbBits; bitC->bitPos += nbBits;
} }
@ -235,6 +241,7 @@ MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC,
size_t value, unsigned nbBits) size_t value, unsigned nbBits)
{ {
assert((value>>nbBits) == 0); assert((value>>nbBits) == 0);
assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
bitC->bitContainer |= value << bitC->bitPos; bitC->bitContainer |= value << bitC->bitPos;
bitC->bitPos += nbBits; bitC->bitPos += nbBits;
} }
@ -245,7 +252,7 @@ MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC,
MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC) MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
{ {
size_t const nbBytes = bitC->bitPos >> 3; size_t const nbBytes = bitC->bitPos >> 3;
assert( bitC->bitPos <= (sizeof(bitC->bitContainer)*8) ); assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
MEM_writeLEST(bitC->ptr, bitC->bitContainer); MEM_writeLEST(bitC->ptr, bitC->bitContainer);
bitC->ptr += nbBytes; bitC->ptr += nbBytes;
assert(bitC->ptr <= bitC->endPtr); assert(bitC->ptr <= bitC->endPtr);
@ -261,7 +268,7 @@ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC) MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
{ {
size_t const nbBytes = bitC->bitPos >> 3; size_t const nbBytes = bitC->bitPos >> 3;
assert( bitC->bitPos <= (sizeof(bitC->bitContainer)*8) ); assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
MEM_writeLEST(bitC->ptr, bitC->bitContainer); MEM_writeLEST(bitC->ptr, bitC->bitContainer);
bitC->ptr += nbBytes; bitC->ptr += nbBytes;
if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
@ -353,12 +360,14 @@ MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 co
# endif # endif
return _bextr_u32(bitContainer, start, nbBits); return _bextr_u32(bitContainer, start, nbBits);
#else #else
assert(nbBits < BIT_MASK_SIZE);
return (bitContainer >> start) & BIT_mask[nbBits]; return (bitContainer >> start) & BIT_mask[nbBits];
#endif #endif
} }
MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
{ {
assert(nbBits < BIT_MASK_SIZE);
return bitContainer & BIT_mask[nbBits]; return bitContainer & BIT_mask[nbBits];
} }