📄 bitbuffer.c
字号:
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);}#endifFLaC__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 */ uval = (unsigned)(((-(++val)) << 1) + 1); else uval = (unsigned)(val << 1); msbs = uval >> parameter; return 1 + parameter + msbs;}#if 0 /* UNUSED */unsigned FLAC__bitbuffer_golomb_bits_signed(int val, unsigned parameter){ unsigned bits, msbs, uval; unsigned k; FLAC__ASSERT(parameter > 0); /* fold signed to unsigned */ if(val < 0) /* equivalent to * (unsigned)(((--val) << 1) - 1); * but without the overflow problem at MININT */ uval = (unsigned)(((-(++val)) << 1) + 1); else uval = (unsigned)(val << 1); k = FLAC__bitmath_ilog2(parameter); if(parameter == 1u<<k) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -