📄 bitbuffer.c
字号:
/* we hold off updating bb->total_consumed_bits until the end */
}
bb->total_consumed_bits += bits;
#if FLAC__BITS_PER_BLURB > 8
}
else {
for(i = 0; i < bits; i++) {
if(!FLAC__bitbuffer_read_bit_to_uint32(bb, &v, read_callback, client_data))
return false;
}
}
#endif
/* fix the sign */
i = 32 - bits;
if(i) {
v <<= i;
*val = (FLAC__int32)v;
*val >>= i;
}
else
*val = (FLAC__int32)v;
return true;
}
#endif
FLAC__bool FLAC__bitbuffer_read_raw_uint64(FLAC__BitBuffer *bb, FLAC__uint64 *val, const unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data)
#ifdef FLAC__NO_MANUAL_INLINING
{
unsigned i;
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
FLAC__ASSERT(bits <= 64);
*val = 0;
for(i = 0; i < bits; i++) {
if(!FLAC__bitbuffer_read_bit_to_uint64(bb, val, read_callback, client_data))
return false;
}
return true;
}
#else
{
unsigned i, bits_ = bits;
FLAC__uint64 v = 0;
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
FLAC__ASSERT(bits <= 64);
FLAC__ASSERT((bb->capacity*FLAC__BITS_PER_BLURB) * 2 >= bits);
if(bits == 0) {
*val = 0;
return true;
}
while(bb->total_consumed_bits + bits > bb->total_bits) {
if(!bitbuffer_read_from_client_(bb, read_callback, client_data))
return false;
}
#if FLAC__BITS_PER_BLURB > 8
if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) { /*@@@ comment on why this is here*/
#endif
if(bb->consumed_bits) {
i = FLAC__BITS_PER_BLURB - bb->consumed_bits;
if(i <= bits_) {
v = bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits);
bits_ -= i;
CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16);
bb->consumed_blurbs++;
bb->consumed_bits = 0;
/* we hold off updating bb->total_consumed_bits until the end */
}
else {
*val = (bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits)) >> (i-bits_);
bb->consumed_bits += bits_;
bb->total_consumed_bits += bits_;
return true;
}
}
while(bits_ >= FLAC__BITS_PER_BLURB) {
v <<= FLAC__BITS_PER_BLURB;
v |= bb->buffer[bb->consumed_blurbs];
bits_ -= FLAC__BITS_PER_BLURB;
CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16);
bb->consumed_blurbs++;
/* bb->consumed_bits is already 0 */
/* we hold off updating bb->total_consumed_bits until the end */
}
if(bits_ > 0) {
v <<= bits_;
v |= (bb->buffer[bb->consumed_blurbs] >> (FLAC__BITS_PER_BLURB-bits_));
bb->consumed_bits = bits_;
/* we hold off updating bb->total_consumed_bits until the end */
}
bb->total_consumed_bits += bits;
*val = v;
#if FLAC__BITS_PER_BLURB > 8
}
else {
*val = 0;
for(i = 0; i < bits; i++) {
if(!FLAC__bitbuffer_read_bit_to_uint64(bb, val, read_callback, client_data))
return false;
}
}
#endif
return true;
}
#endif
#if 0 /* UNUSED */
FLAC__bool FLAC__bitbuffer_read_raw_int64(FLAC__BitBuffer *bb, FLAC__int64 *val, const unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data)
#ifdef FLAC__NO_MANUAL_INLINING
{
unsigned i;
FLAC__uint64 v;
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
FLAC__ASSERT(bits <= 64);
v = 0;
for(i = 0; i < bits; i++) {
if(!FLAC__bitbuffer_read_bit_to_uint64(bb, &v, read_callback, client_data))
return false;
}
/* fix the sign */
i = 64 - bits;
if(i) {
v <<= i;
*val = (FLAC__int64)v;
*val >>= i;
}
else
*val = (FLAC__int64)v;
return true;
}
#else
{
unsigned i, bits_ = bits;
FLAC__uint64 v = 0;
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
FLAC__ASSERT(bits <= 64);
FLAC__ASSERT((bb->capacity*FLAC__BITS_PER_BLURB) * 2 >= bits);
if(bits == 0) {
*val = 0;
return true;
}
while(bb->total_consumed_bits + bits > bb->total_bits) {
if(!bitbuffer_read_from_client_(bb, read_callback, client_data))
return false;
}
#if FLAC__BITS_PER_BLURB > 8
if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) { /*@@@ comment on why this is here*/
#endif
if(bb->consumed_bits) {
i = FLAC__BITS_PER_BLURB - bb->consumed_bits;
if(i <= bits_) {
v = bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits);
bits_ -= i;
CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16);
bb->consumed_blurbs++;
bb->consumed_bits = 0;
/* we hold off updating bb->total_consumed_bits until the end */
}
else {
/* bits_ must be < FLAC__BITS_PER_BLURB-1 if we get to here */
v = (bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits));
v <<= (64-i);
*val = (FLAC__int64)v;
*val >>= (64-bits_);
bb->consumed_bits += bits_;
bb->total_consumed_bits += bits_;
return true;
}
}
while(bits_ >= FLAC__BITS_PER_BLURB) {
v <<= FLAC__BITS_PER_BLURB;
v |= bb->buffer[bb->consumed_blurbs];
bits_ -= FLAC__BITS_PER_BLURB;
CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16);
bb->consumed_blurbs++;
/* bb->consumed_bits is already 0 */
/* we hold off updating bb->total_consumed_bits until the end */
}
if(bits_ > 0) {
v <<= bits_;
v |= (bb->buffer[bb->consumed_blurbs] >> (FLAC__BITS_PER_BLURB-bits_));
bb->consumed_bits = bits_;
/* we hold off updating bb->total_consumed_bits until the end */
}
bb->total_consumed_bits += bits;
#if FLAC__BITS_PER_BLURB > 8
}
else {
for(i = 0; i < bits; i++) {
if(!FLAC__bitbuffer_read_bit_to_uint64(bb, &v, read_callback, client_data))
return false;
}
}
#endif
/* fix the sign */
i = 64 - bits;
if(i) {
v <<= i;
*val = (FLAC__int64)v;
*val >>= i;
}
else
*val = (FLAC__int64)v;
return true;
}
#endif
#endif
FLaC__INLINE FLAC__bool FLAC__bitbuffer_read_raw_uint32_little_endian(FLAC__BitBuffer *bb, FLAC__uint32 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data)
{
FLAC__uint32 x8, x32 = 0;
/* this doesn't need to be that fast as currently it is only used for vorbis comments */
if(!FLAC__bitbuffer_read_raw_uint32(bb, &x32, 8, read_callback, client_data))
return false;
if(!FLAC__bitbuffer_read_raw_uint32(bb, &x8, 8, read_callback, client_data))
return false;
x32 |= (x8 << 8);
if(!FLAC__bitbuffer_read_raw_uint32(bb, &x8, 8, read_callback, client_data))
return false;
x32 |= (x8 << 16);
if(!FLAC__bitbuffer_read_raw_uint32(bb, &x8, 8, read_callback, client_data))
return false;
x32 |= (x8 << 24);
*val = x32;
return true;
}
FLAC__bool FLAC__bitbuffer_skip_bits_no_crc(FLAC__BitBuffer *bb, unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data)
{
/*
* @@@ a slightly faster implementation is possible but
* probably not that useful since this is only called a
* couple of times in the metadata readers.
*/
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
if(bits > 0) {
const unsigned n = bb->consumed_bits & 7;
unsigned m;
FLAC__uint32 x;
if(n != 0) {
m = min(8-n, bits);
if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, m, read_callback, client_data))
return false;
bits -= m;
}
m = bits / 8;
if(m > 0) {
if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(bb, 0, m, read_callback, client_data))
return false;
bits %= 8;
}
if(bits > 0) {
if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, bits, read_callback, client_data))
return false;
}
}
return true;
}
FLAC__bool FLAC__bitbuffer_read_byte_block_aligned_no_crc(FLAC__BitBuffer *bb, FLAC__byte *val, unsigned nvals, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data)
{
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(bb));
FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(bb));
#if FLAC__BITS_PER_BLURB == 8
while(nvals > 0) {
unsigned chunk = min(nvals, bb->blurbs - bb->consumed_blurbs);
if(chunk == 0) {
if(!bitbuffer_read_from_client_(bb, read_callback, client_data))
return false;
}
else {
if(0 != val) {
memcpy(val, bb->buffer + bb->consumed_blurbs, FLAC__BYTES_PER_BLURB * chunk);
val += FLAC__BYTES_PER_BLURB * chunk;
}
nvals -= chunk;
bb->consumed_blurbs += chunk;
bb->total_consumed_bits = (bb->consumed_blurbs << FLAC__BITS_PER_BLURB_LOG2);
}
}
#else
@@@ need to write this still
FLAC__ASSERT(0);
#endif
return true;
}
FLaC__INLINE FLAC__bool FLAC__bitbuffer_read_unary_unsigned(FLAC__BitBuffer *bb, unsigned *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data)
#ifdef FLAC__NO_MANUAL_INLINING
{
unsigned bit, val_ = 0;
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
while(1) {
if(!FLAC__bitbuffer_read_bit(bb, &bit, read_callback, client_data))
return false;
if(bit)
break;
else
val_++;
}
*val = val_;
return true;
}
#else
{
unsigned i, val_ = 0;
unsigned total_blurbs_ = (bb->total_bits + (FLAC__BITS_PER_BLURB-1)) / FLAC__BITS_PER_BLURB;
FLAC__blurb b;
FLAC__ASSERT(0 != bb);
FLAC__ASSERT(0 != bb->buffer);
#if FLAC__BITS_PER_BLURB > 8
if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) { /*@@@ comment on why this is here*/
#endif
if(bb->consumed_bits) {
b = bb->buffer[bb->consumed_blurbs] << bb->consumed_bits;
if(b) {
for(i = 0; !(b & FLAC__BLURB_TOP_BIT_ONE); i++)
b <<= 1;
*val = i;
i++;
bb->consumed_bits += i;
bb->total_consumed_bits += i;
if(bb->consumed_bits == FLAC__BITS_PER_BLURB) {
CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16);
bb->consumed_blurbs++;
bb->consumed_bits = 0;
}
return true;
}
else {
val_ = FLAC__BITS_PER_BLURB - bb->consumed_bits;
CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16);
bb->consumed_blurbs++;
bb->consumed_bits = 0;
bb->total_consumed_bits += val_;
}
}
while(1) {
if(bb->consumed_blurbs >= total_blurbs_) {
if(!bitbuffer_read_from_client_(bb, read_callback, client_data))
return false;
total_blurbs_ = (bb->total_bits + (FLAC__BITS_PER_BLURB-1)) / FLAC__BITS_PER_BLURB;
}
b = bb->buffer[bb->consumed_blurbs];
if(b) {
for(i = 0; !(b & FLAC__BLURB_TOP_BIT_ONE); i++)
b <<= 1;
val_ += i;
i++;
bb->consumed_bits = i;
*val = val_;
if(i == FLAC__BITS_PER_BLURB) {
CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16);
bb->consumed_blurbs++;
bb->consumed_bits = 0;
}
bb->total_consumed_bits += i;
return true;
}
else {
val_ += FLAC__BITS_PER_BLURB;
CRC16_UPDATE_BLURB(bb, 0, bb->read_crc16);
bb->consumed_blurbs++;
/* bb->consumed_bits is already 0 */
bb->total_consumed_bits += FLAC__BITS_PER_BLURB;
}
}
#if FLAC__BITS_PER_BLURB > 8
}
else {
while(1) {
if(!FLAC__bitbuffer_read_bit(bb, &i, read_callback, client_data))
return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -