📄 bitbuffer.c
字号:
free(bb->buffer);
bb->buffer = 0;
bb->capacity = 0;
bb->blurbs = bb->bits = bb->total_bits = 0;
bb->consumed_blurbs = bb->consumed_bits = bb->total_consumed_bits = 0;
}
FLAC__bool FLAC__bitbuffer_clear(FLAC__BitBuffer *bb)
{
if(bb->buffer == 0) {
bb->capacity = FLAC__BITBUFFER_DEFAULT_CAPACITY;
bb->buffer = (FLAC__blurb*)calloc(bb->capacity, sizeof(FLAC__blurb));
if(bb->buffer == 0)
return false;
}
else {
memset(bb->buffer, 0, bb->blurbs + (bb->bits?1:0));
}
bb->blurbs = bb->bits = bb->total_bits = 0;
bb->consumed_blurbs = bb->consumed_bits = bb->total_consumed_bits = 0;
return true;
}
FLAC__bool FLAC__bitbuffer_clone(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src)
{
FLAC__ASSERT(0 != dest);
FLAC__ASSERT(0 != dest->buffer);
FLAC__ASSERT(0 != src);
FLAC__ASSERT(0 != src->buffer);
if(dest->capacity < src->capacity)
if(!bitbuffer_resize_(dest, src->capacity))
return false;
memcpy(dest->buffer, src->buffer, sizeof(FLAC__blurb)*min(src->capacity, src->blurbs+1));
dest->blurbs = src->blurbs;
dest->bits = src->bits;
dest->total_bits = src->total_bits;
dest->consumed_blurbs = src->consumed_blurbs;
dest->consumed_bits = src->consumed_bits;
dest->total_consumed_bits = src->total_consumed_bits;
dest->read_crc16 = src->read_crc16;
return true;
}
void FLAC__bitbuffer_reset_read_crc16(FLAC__BitBuffer *bb, FLAC__uint16 seed)
{
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
FLAC__ASSERT((bb->consumed_bits & 7) == 0);
bb->read_crc16 = seed;
#if FLAC__BITS_PER_BLURB == 8
/* no need to do anything */
#elif FLAC__BITS_PER_BLURB == 32
bb->crc16_align = bb->consumed_bits;
#else
FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
}
FLAC__uint16 FLAC__bitbuffer_get_read_crc16(FLAC__BitBuffer *bb)
{
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
FLAC__ASSERT((bb->bits & 7) == 0);
FLAC__ASSERT((bb->consumed_bits & 7) == 0);
#if FLAC__BITS_PER_BLURB == 8
/* no need to do anything */
#elif FLAC__BITS_PER_BLURB == 32
/*@@@ BUG: even though this probably can't happen with FLAC, need to fix the case where we are called here for the very first blurb and crc16_align is > 0 */
if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) {
if(bb->consumed_bits == 8) {
const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
FLAC__CRC16_UPDATE(blurb >> 24, bb->read_crc16);
}
else if(bb->consumed_bits == 16) {
const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
FLAC__CRC16_UPDATE(blurb >> 24, bb->read_crc16);
FLAC__CRC16_UPDATE((blurb >> 16) & 0xff, bb->read_crc16);
}
else if(bb->consumed_bits == 24) {
const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
FLAC__CRC16_UPDATE(blurb >> 24, bb->read_crc16);
FLAC__CRC16_UPDATE((blurb >> 16) & 0xff, bb->read_crc16);
FLAC__CRC16_UPDATE((blurb >> 8) & 0xff, bb->read_crc16);
}
}
else {
if(bb->consumed_bits == 8) {
const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
FLAC__CRC16_UPDATE(blurb >> (bb->bits-8), bb->read_crc16);
}
else if(bb->consumed_bits == 16) {
const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
FLAC__CRC16_UPDATE(blurb >> (bb->bits-8), bb->read_crc16);
FLAC__CRC16_UPDATE((blurb >> (bb->bits-16)) & 0xff, bb->read_crc16);
}
else if(bb->consumed_bits == 24) {
const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
FLAC__CRC16_UPDATE(blurb >> (bb->bits-8), bb->read_crc16);
FLAC__CRC16_UPDATE((blurb >> (bb->bits-16)) & 0xff, bb->read_crc16);
FLAC__CRC16_UPDATE((blurb >> (bb->bits-24)) & 0xff, bb->read_crc16);
}
}
bb->crc16_align = bb->consumed_bits;
#else
FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
return bb->read_crc16;
}
FLAC__uint16 FLAC__bitbuffer_get_write_crc16(const FLAC__BitBuffer *bb)
{
FLAC__ASSERT((bb->bits & 7) == 0); /* assert that we're byte-aligned */
#if FLAC__BITS_PER_BLURB == 8
return FLAC__crc16(bb->buffer, bb->blurbs);
#elif FLAC__BITS_PER_BLURB == 32
/* @@@ WATCHOUT: code currently only works for big-endian: */
return FLAC__crc16((FLAC__byte*)(bb->buffer), (bb->blurbs * FLAC__BYTES_PER_BLURB) + (bb->bits >> 3));
#else
FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
}
FLAC__byte FLAC__bitbuffer_get_write_crc8(const FLAC__BitBuffer *bb)
{
FLAC__ASSERT(0 != bb);
FLAC__ASSERT((bb->bits & 7) == 0); /* assert that we're byte-aligned */
FLAC__ASSERT(bb->buffer[0] == 0xff); /* MAGIC NUMBER for the first byte of the sync code */
#if FLAC__BITS_PER_BLURB == 8
return FLAC__crc8(bb->buffer, bb->blurbs);
#elif FLAC__BITS_PER_BLURB == 32
/* @@@ WATCHOUT: code currently only works for big-endian: */
return FLAC__crc8((FLAC__byte*)(bb->buffer), (bb->blurbs * FLAC__BYTES_PER_BLURB) + (bb->bits >> 3));
#else
FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
}
FLAC__bool FLAC__bitbuffer_is_byte_aligned(const FLAC__BitBuffer *bb)
{
return ((bb->bits & 7) == 0);
}
FLAC__bool FLAC__bitbuffer_is_consumed_byte_aligned(const FLAC__BitBuffer *bb)
{
return ((bb->consumed_bits & 7) == 0);
}
unsigned FLAC__bitbuffer_bits_left_for_byte_alignment(const FLAC__BitBuffer *bb)
{
return 8 - (bb->consumed_bits & 7);
}
unsigned FLAC__bitbuffer_get_input_bytes_unconsumed(const FLAC__BitBuffer *bb)
{
FLAC__ASSERT((bb->consumed_bits & 7) == 0 && (bb->bits & 7) == 0);
return (bb->total_bits - bb->total_consumed_bits) >> 3;
}
void FLAC__bitbuffer_get_buffer(FLAC__BitBuffer *bb, const FLAC__byte **buffer, unsigned *bytes)
{
FLAC__ASSERT((bb->consumed_bits & 7) == 0 && (bb->bits & 7) == 0);
#if FLAC__BITS_PER_BLURB == 8
*buffer = bb->buffer + bb->consumed_blurbs;
*bytes = bb->blurbs - bb->consumed_blurbs;
#elif FLAC__BITS_PER_BLURB == 32
/* @@@ WATCHOUT: code currently only works for big-endian: */
*buffer = (FLAC__byte*)(bb->buffer + bb->consumed_blurbs) + (bb->consumed_bits >> 3);
*bytes = (bb->total_bits - bb->total_consumed_bits) >> 3;
#else
FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
}
void FLAC__bitbuffer_release_buffer(FLAC__BitBuffer *bb)
{
#if FLAC__BITS_PER_BLURB == 8
(void)bb;
#elif FLAC__BITS_PER_BLURB == 32
/* @@@ WATCHOUT: code currently only works for big-endian: */
(void)bb;
#else
FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
}
FLAC__bool FLAC__bitbuffer_write_zeroes(FLAC__BitBuffer *bb, unsigned bits)
{
unsigned n;
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
if(bits == 0)
return true;
if(!bitbuffer_ensure_size_(bb, bits))
return false;
bb->total_bits += bits;
while(bits > 0) {
n = min(FLAC__BITS_PER_BLURB - bb->bits, bits);
bb->buffer[bb->blurbs] <<= n;
bits -= n;
bb->bits += n;
if(bb->bits == FLAC__BITS_PER_BLURB) {
bb->blurbs++;
bb->bits = 0;
}
}
return true;
}
FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, FLAC__uint32 val, unsigned bits)
{
unsigned n, k;
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
FLAC__ASSERT(bits <= 32);
if(bits == 0)
return true;
/* inline the size check so we don't incure a function call unnecessarily */
if(FLAC__BLURBS_TO_BITS(bb->capacity) < bb->total_bits + bits) {
if(!bitbuffer_ensure_size_(bb, bits))
return false;
}
/* zero-out unused bits; WATCHOUT: other code relies on this, so this needs to stay */
if(bits < 32) /* @@@ gcc seems to require this because the following line causes incorrect results when bits==32; investigate */
val &= (~(0xffffffff << bits)); /* zero-out unused bits */
bb->total_bits += bits;
while(bits > 0) {
n = FLAC__BITS_PER_BLURB - bb->bits;
if(n == FLAC__BITS_PER_BLURB) { /* i.e. bb->bits == 0 */
if(bits < FLAC__BITS_PER_BLURB) {
bb->buffer[bb->blurbs] = (FLAC__blurb)val;
bb->bits = bits;
break;
}
else if(bits == FLAC__BITS_PER_BLURB) {
bb->buffer[bb->blurbs++] = (FLAC__blurb)val;
break;
}
else {
k = bits - FLAC__BITS_PER_BLURB;
bb->buffer[bb->blurbs++] = (FLAC__blurb)(val >> k);
/* we know k < 32 so no need to protect against the gcc bug mentioned above */
val &= (~(0xffffffff << k));
bits -= FLAC__BITS_PER_BLURB;
}
}
else if(bits <= n) {
bb->buffer[bb->blurbs] <<= bits;
bb->buffer[bb->blurbs] |= val;
if(bits == n) {
bb->blurbs++;
bb->bits = 0;
}
else
bb->bits += bits;
break;
}
else {
k = bits - n;
bb->buffer[bb->blurbs] <<= n;
bb->buffer[bb->blurbs] |= (val >> k);
/* we know n > 0 so k < 32 so no need to protect against the gcc bug mentioned above */
val &= (~(0xffffffff << k));
bits -= n;
bb->blurbs++;
bb->bits = 0;
}
}
return true;
}
FLAC__bool FLAC__bitbuffer_write_raw_int32(FLAC__BitBuffer *bb, FLAC__int32 val, unsigned bits)
{
return FLAC__bitbuffer_write_raw_uint32(bb, (FLAC__uint32)val, bits);
}
FLAC__bool FLAC__bitbuffer_write_raw_uint64(FLAC__BitBuffer *bb, FLAC__uint64 val, unsigned bits)
{
static const FLAC__uint64 mask[] = {
0,
FLAC__U64L(0x0000000000000001), FLAC__U64L(0x0000000000000003), FLAC__U64L(0x0000000000000007), FLAC__U64L(0x000000000000000F),
FLAC__U64L(0x000000000000001F), FLAC__U64L(0x000000000000003F), FLAC__U64L(0x000000000000007F), FLAC__U64L(0x00000000000000FF),
FLAC__U64L(0x00000000000001FF), FLAC__U64L(0x00000000000003FF), FLAC__U64L(0x00000000000007FF), FLAC__U64L(0x0000000000000FFF),
FLAC__U64L(0x0000000000001FFF), FLAC__U64L(0x0000000000003FFF), FLAC__U64L(0x0000000000007FFF), FLAC__U64L(0x000000000000FFFF),
FLAC__U64L(0x000000000001FFFF), FLAC__U64L(0x000000000003FFFF), FLAC__U64L(0x000000000007FFFF), FLAC__U64L(0x00000000000FFFFF),
FLAC__U64L(0x00000000001FFFFF), FLAC__U64L(0x00000000003FFFFF), FLAC__U64L(0x00000000007FFFFF), FLAC__U64L(0x0000000000FFFFFF),
FLAC__U64L(0x0000000001FFFFFF), FLAC__U64L(0x0000000003FFFFFF), FLAC__U64L(0x0000000007FFFFFF), FLAC__U64L(0x000000000FFFFFFF),
FLAC__U64L(0x000000001FFFFFFF), FLAC__U64L(0x000000003FFFFFFF), FLAC__U64L(0x000000007FFFFFFF), FLAC__U64L(0x00000000FFFFFFFF),
FLAC__U64L(0x00000001FFFFFFFF), FLAC__U64L(0x00000003FFFFFFFF), FLAC__U64L(0x00000007FFFFFFFF), FLAC__U64L(0x0000000FFFFFFFFF),
FLAC__U64L(0x0000001FFFFFFFFF), FLAC__U64L(0x0000003FFFFFFFFF), FLAC__U64L(0x0000007FFFFFFFFF), FLAC__U64L(0x000000FFFFFFFFFF),
FLAC__U64L(0x000001FFFFFFFFFF), FLAC__U64L(0x000003FFFFFFFFFF), FLAC__U64L(0x000007FFFFFFFFFF), FLAC__U64L(0x00000FFFFFFFFFFF),
FLAC__U64L(0x00001FFFFFFFFFFF), FLAC__U64L(0x00003FFFFFFFFFFF), FLAC__U64L(0x00007FFFFFFFFFFF), FLAC__U64L(0x0000FFFFFFFFFFFF),
FLAC__U64L(0x0001FFFFFFFFFFFF), FLAC__U64L(0x0003FFFFFFFFFFFF), FLAC__U64L(0x0007FFFFFFFFFFFF), FLAC__U64L(0x000FFFFFFFFFFFFF),
FLAC__U64L(0x001FFFFFFFFFFFFF), FLAC__U64L(0x003FFFFFFFFFFFFF), FLAC__U64L(0x007FFFFFFFFFFFFF), FLAC__U64L(0x00FFFFFFFFFFFFFF),
FLAC__U64L(0x01FFFFFFFFFFFFFF), FLAC__U64L(0x03FFFFFFFFFFFFFF), FLAC__U64L(0x07FFFFFFFFFFFFFF), FLAC__U64L(0x0FFFFFFFFFFFFFFF),
FLAC__U64L(0x1FFFFFFFFFFFFFFF), FLAC__U64L(0x3FFFFFFFFFFFFFFF), FLAC__U64L(0x7FFFFFFFFFFFFFFF), FLAC__U64L(0xFFFFFFFFFFFFFFFF)
};
unsigned n, k;
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
FLAC__ASSERT(bits <= 64);
if(bits == 0)
return true;
if(!bitbuffer_ensure_size_(bb, bits))
return false;
val &= mask[bits];
bb->total_bits += bits;
while(bits > 0) {
if(bb->bits == 0) {
if(bits < FLAC__BITS_PER_BLURB) {
bb->buffer[bb->blurbs] = (FLAC__blurb)val;
bb->bits = bits;
break;
}
else if(bits == FLAC__BITS_PER_BLURB) {
bb->buffer[bb->blurbs++] = (FLAC__blurb)val;
break;
}
else {
k = bits - FLAC__BITS_PER_BLURB;
bb->buffer[bb->blurbs++] = (FLAC__blurb)(val >> k);
/* we know k < 64 so no need to protect against the gcc bug mentioned above */
val &= (~(FLAC__U64L(0xffffffffffffffff) << k));
bits -= FLAC__BITS_PER_BLURB;
}
}
else {
n = min(FLAC__BITS_PER_BLURB - bb->bits, bits);
k = bits - n;
bb->buffer[bb->blurbs] <<= n;
bb->buffer[bb->blurbs] |= (val >> k);
/* we know n > 0 so k < 64 so no need to protect against the gcc bug mentioned above */
val &= (~(FLAC__U64L(0xffffffffffffffff) << k));
bits -= n;
bb->bits += n;
if(bb->bits == FLAC__BITS_PER_BLURB) {
bb->blurbs++;
bb->bits = 0;
}
}
}
return true;
}
#if 0 /* UNUSED */
FLAC__bool FLAC__bitbuffer_write_raw_int64(FLAC__BitBuffer *bb, FLAC__int64 val, unsigned bits)
{
return FLAC__bitbuffer_write_raw_uint64(bb, (FLAC__uint64)val, bits);
}
#endif
FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_raw_uint32_little_endian(FLAC__BitBuffer *bb, FLAC__uint32 val)
{
/* this doesn't need to be that fast as currently it is only used for vorbis comments */
/* NOTE: we rely on the fact that FLAC__bitbuffer_write_raw_uint32() masks out the unused bits */
if(!FLAC__bitbuffer_write_raw_uint32(bb, val, 8))
return false;
if(!FLAC__bitbuffer_write_raw_uint32(bb, val>>8, 8))
return false;
if(!FLAC__bitbuffer_write_raw_uint32(bb, val>>16, 8))
return false;
if(!FLAC__bitbuffer_write_raw_uint32(bb, val>>24, 8))
return false;
return true;
}
FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_byte_block(FLAC__BitBuffer *bb, const FLAC__byte vals[], unsigned nvals)
{
unsigned i;
/* this could be faster but currently we don't need it to be */
for(i = 0; i < nvals; i++) {
if(!FLAC__bitbuffer_write_raw_uint32(bb, (FLAC__uint32)(vals[i]), 8))
return false;
}
return true;
}
FLAC__bool FLAC__bitbuffer_write_unary_unsigned(FLAC__BitBuffer *bb, unsigned val)
{
if(val < 32)
return FLAC__bitbuffer_write_raw_uint32(bb, 1, ++val);
else if(val < 64)
return FLAC__bitbuffer_write_raw_uint64(bb, 1, ++val);
else {
if(!FLAC__bitbuffer_write_zeroes(bb, val))
return false;
return FLAC__bitbuffer_write_raw_uint32(bb, 1, 1);
}
}
unsigned FLAC__bitbuffer_rice_bits(int val, unsigned parameter)
{
unsigned msbs, uval;
/* fold signed to unsigned */
if(val < 0)
/* equivalent to
* (unsigned)(((--val) << 1) - 1);
* but without the overflow problem at MININT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -