diff --git a/src/libFLAC/bitbuffer.c b/src/libFLAC/bitbuffer.c index b10436c4..b0849613 100644 --- a/src/libFLAC/bitbuffer.c +++ b/src/libFLAC/bitbuffer.c @@ -32,10 +32,44 @@ * */ -/* This should be at least twice as large as the largest number of bytes required to represent any 'number' (in any encoding) you are going to read. */ -static const unsigned FLAC__BITBUFFER_DEFAULT_CAPACITY = 65536; /* bytes */ +/* + * This should be at least twice as large as the largest number of blurbs + * required to represent any 'number' (in any encoding) you are going to + * read. With FLAC this is on the order of maybe a few hundred bits. + * If the buffer is smaller than that, the decoder won't be able to read + * in a whole number that is in a variable length encoding (e.g. Rice). + * + * The number we are actually using here is based on what would be the + * approximate maximum size of a verbatim frame at the default block size, + * for CD audio (4096 sample * 4 bytes per sample), plus some wiggle room. + * 32kbytes sounds reasonable. For kicks we subtract out 64 bytes for any + * alignment or malloc overhead. + * + * Increase this number to decrease the number of read callbacks, at the + * expense of using more memory. Or decrease for the reverse effect, + * keeping in mind the limit from the first paragraph. + */ +static const unsigned FLAC__BITBUFFER_DEFAULT_CAPACITY = ((65536 - 64) * 8) / FLAC__BITS_PER_BLURB; /* blurbs */ -#define BYTE_BIT_TO_MASK(b) (((FLAC__byte)'\x80') >> (b)) +#if FLAC__BITS_PER_BLURB == 8 +#define FLAC__BITS_PER_BLURB_LOG2 3 +#define FLAC__BYTES_PER_BLURB 1 +#define FLAC__BLURB_ALL_ONES ((FLAC__byte)0xff) +#define FLAC__BLURB_TOP_BIT_ONE ((FLAC__byte)0x80) +#define BLURB_BIT_TO_MASK(b) (((FLAC__blurb)'\x80') >> (b)) +#define CRC16_UPDATE_BLURB(bb, blurb, crc) FLAC__CRC16_UPDATE((blurb), (crc)); +#elif FLAC__BITS_PER_BLURB == 32 +#define FLAC__BITS_PER_BLURB_LOG2 5 +#define FLAC__BYTES_PER_BLURB 4 +#define FLAC__BLURB_ALL_ONES ((FLAC__uint32)0xffffffff) +#define FLAC__BLURB_TOP_BIT_ONE ((FLAC__uint32)0x80000000) +#define BLURB_BIT_TO_MASK(b) (((FLAC__blurb)0x80000000) >> (b)) +#define CRC16_UPDATE_BLURB(bb, blurb, crc) crc16_update_blurb((bb), (blurb)); +#else +/* ERROR, only sizes of 8 and 32 are supported */ +#endif + +#define FLAC__BLURBS_TO_BITS(blurbs) ((blurbs) << FLAC__BITS_PER_BLURB_LOG2) #ifdef min #undef min @@ -50,9 +84,58 @@ static const unsigned FLAC__BITBUFFER_DEFAULT_CAPACITY = 65536; /* bytes */ #define FLaC__INLINE #endif +struct FLAC__BitBuffer { + FLAC__blurb *buffer; + unsigned capacity; /* in blurbs */ + unsigned blurbs, bits; + unsigned total_bits; /* must always == FLAC__BITS_PER_BLURB*blurbs+bits */ + unsigned consumed_blurbs, consumed_bits; + unsigned total_consumed_bits; /* must always == FLAC__BITS_PER_BLURB*consumed_blurbs+consumed_bits */ + FLAC__uint16 read_crc16; +#if FLAC__BITS_PER_BLURB == 32 + unsigned crc16_align; +#endif + FLAC__blurb save_head, save_tail; +}; + +static void crc16_update_blurb(FLAC__BitBuffer *bb, FLAC__blurb blurb) +{ +#if FLAC__BITS_PER_BLURB == 32 + if(bb->crc16_align == 0) { + 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); + FLAC__CRC16_UPDATE(blurb & 0xff, bb->read_crc16); + } + else if(bb->crc16_align == 8) { + FLAC__CRC16_UPDATE((blurb >> 16) & 0xff, bb->read_crc16); + FLAC__CRC16_UPDATE((blurb >> 8) & 0xff, bb->read_crc16); + FLAC__CRC16_UPDATE(blurb & 0xff, bb->read_crc16); + } + else if(bb->crc16_align == 16) { + FLAC__CRC16_UPDATE((blurb >> 8) & 0xff, bb->read_crc16); + FLAC__CRC16_UPDATE(blurb & 0xff, bb->read_crc16); + } + else if(bb->crc16_align == 24) { + FLAC__CRC16_UPDATE(blurb & 0xff, bb->read_crc16); + } + bb->crc16_align = 0; +#else + (void)bb; (void)blurb; + FLAC__ASSERT(false); +#endif +} + +/* + * WATCHOUT: The current implentation is not friendly to shrinking, i.e. it + * does not shift left what is consumed, it just chops off the end, whether + * there is unconsumed data there or not. This is OK because currently we + * never shrink the buffer, but if this ever changes, we'll have to do some + * fixups here. + */ static FLAC__bool bitbuffer_resize_(FLAC__BitBuffer *bb, unsigned new_capacity) { - FLAC__byte *new_buffer; + FLAC__blurb *new_buffer; FLAC__ASSERT(bb != 0); FLAC__ASSERT(bb->buffer != 0); @@ -60,20 +143,20 @@ static FLAC__bool bitbuffer_resize_(FLAC__BitBuffer *bb, unsigned new_capacity) if(bb->capacity == new_capacity) return true; - new_buffer = (FLAC__byte*)malloc(sizeof(FLAC__byte) * new_capacity); + new_buffer = (FLAC__blurb*)malloc(sizeof(FLAC__blurb) * new_capacity); if(new_buffer == 0) return false; - memset(new_buffer, 0, new_capacity); - memcpy(new_buffer, bb->buffer, sizeof(FLAC__byte)*min(bb->bytes+(bb->bits?1:0), new_capacity)); - if(new_capacity < bb->bytes+(bb->bits?1:0)) { - bb->bytes = new_capacity; + memset(new_buffer, 0, sizeof(FLAC__blurb) * new_capacity); + memcpy(new_buffer, bb->buffer, sizeof(FLAC__blurb)*min(bb->blurbs+(bb->bits?1:0), new_capacity)); + if(new_capacity < bb->blurbs+(bb->bits?1:0)) { + bb->blurbs = new_capacity; bb->bits = 0; - bb->total_bits = (new_capacity<<3); + bb->total_bits = FLAC__BLURBS_TO_BITS(new_capacity); } - if(new_capacity < bb->consumed_bytes+(bb->consumed_bits?1:0)) { - bb->consumed_bytes = new_capacity; + if(new_capacity < bb->consumed_blurbs+(bb->consumed_bits?1:0)) { + bb->consumed_blurbs = new_capacity; bb->consumed_bits = 0; - bb->total_consumed_bits = (new_capacity<<3); + bb->total_consumed_bits = FLAC__BLURBS_TO_BITS(new_capacity); } free(bb->buffer); // we've already asserted above that (bb->buffer != 0) bb->buffer = new_buffer; @@ -81,13 +164,13 @@ static FLAC__bool bitbuffer_resize_(FLAC__BitBuffer *bb, unsigned new_capacity) return true; } -static FLAC__bool bitbuffer_grow_(FLAC__BitBuffer *bb, unsigned min_bytes_to_add) +static FLAC__bool bitbuffer_grow_(FLAC__BitBuffer *bb, unsigned min_blurbs_to_add) { unsigned new_capacity; - FLAC__ASSERT(min_bytes_to_add > 0); + FLAC__ASSERT(min_blurbs_to_add > 0); - new_capacity = max(bb->capacity * 4, bb->capacity + min_bytes_to_add); + new_capacity = max(bb->capacity * 2, bb->capacity + min_blurbs_to_add); return bitbuffer_resize_(bb, new_capacity); } @@ -96,8 +179,8 @@ static FLAC__bool bitbuffer_ensure_size_(FLAC__BitBuffer *bb, unsigned bits_to_a FLAC__ASSERT(bb != 0); FLAC__ASSERT(bb->buffer != 0); - if((bb->capacity<<3) < bb->total_bits + bits_to_add) - return bitbuffer_grow_(bb, (bits_to_add>>3)+2); + if(FLAC__BLURBS_TO_BITS(bb->capacity) < bb->total_bits + bits_to_add) + return bitbuffer_grow_(bb, (bits_to_add >> FLAC__BITS_PER_BLURB_LOG2) + 2); else return true; } @@ -105,74 +188,123 @@ static FLAC__bool bitbuffer_ensure_size_(FLAC__BitBuffer *bb, unsigned bits_to_a static FLAC__bool bitbuffer_read_from_client_(FLAC__BitBuffer *bb, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) { unsigned bytes; + FLAC__byte *target; /* first shift the unconsumed buffer data toward the front as much as possible */ - if(bb->total_consumed_bits >= 8) { - unsigned l = 0, r = bb->consumed_bytes, r_end = bb->bytes; + if(bb->total_consumed_bits >= FLAC__BITS_PER_BLURB) { + unsigned l = 0, r = bb->consumed_blurbs, r_end = bb->blurbs + (bb->bits? 1:0); for( ; r < r_end; l++, r++) bb->buffer[l] = bb->buffer[r]; for( ; l < r_end; l++) bb->buffer[l] = 0; - bb->bytes -= bb->consumed_bytes; - bb->total_bits -= (bb->consumed_bytes<<3); - bb->consumed_bytes = 0; + bb->blurbs -= bb->consumed_blurbs; + bb->total_bits -= FLAC__BLURBS_TO_BITS(bb->consumed_blurbs); + bb->consumed_blurbs = 0; bb->total_consumed_bits = bb->consumed_bits; } + /* grow if we need to */ if(bb->capacity <= 1) { if(!bitbuffer_resize_(bb, 16)) return false; } + + /* set the target for reading, taking into account blurb alignment */ +#if FLAC__BITS_PER_BLURB == 8 + /* blurb == byte, so no gyrations necessary: */ + target = bb->buffer + bb->blurbs; + bytes = bb->capacity - bb->blurbs; +#elif FLAC__BITS_PER_BLURB == 32 + /* @@@ WATCHOUT: code currently only works for big-endian: */ + FLAC__ASSERT((bb->bits & 7) == 0); + target = (FLAC__byte*)(bb->buffer + bb->blurbs) + (bb->bits >> 3); + bytes = ((bb->capacity - bb->blurbs) << 2) - (bb->bits >> 3); /* i.e. (bb->capacity - bb->blurbs) * FLAC__BYTES_PER_BLURB - (bb->bits / 8) */ +#else + FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ +#endif + /* finally, read in some data */ - bytes = bb->capacity - bb->bytes; - if(!read_callback(bb->buffer+bb->bytes, &bytes, client_data)) + if(!read_callback(target, &bytes, client_data)) return false; - bb->bytes += bytes; - bb->total_bits += (bytes<<3); + + /* now we have to handle partial blurb cases: */ +#if FLAC__BITS_PER_BLURB == 8 + /* blurb == byte, so no gyrations necessary: */ + bb->blurbs += bytes; + bb->total_bits += FLAC__BLURBS_TO_BITS(bytes); +#elif FLAC__BITS_PER_BLURB == 32 + /* @@@ WATCHOUT: code currently only works for big-endian: */ + { + const unsigned aligned_bytes = (bb->bits >> 3) + bytes; + bb->blurbs += (aligned_bytes >> 2); /* i.e. aligned_bytes / FLAC__BYTES_PER_BLURB */ + bb->bits = (aligned_bytes & 3u) << 3; /* i.e. (aligned_bytes % FLAC__BYTES_PER_BLURB) * 8 */ + bb->total_bits += (bytes << 3); + } +#else + FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ +#endif return true; } -void FLAC__bitbuffer_init(FLAC__BitBuffer *bb) +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +FLAC__BitBuffer *FLAC__bitbuffer_new() +{ + return (FLAC__BitBuffer*)malloc(sizeof(FLAC__BitBuffer)); +} + +void FLAC__bitbuffer_delete(FLAC__BitBuffer *bb) +{ + FLAC__ASSERT(bb != 0); + + FLAC__bitbuffer_free(bb); + free(bb); +} + +/*********************************************************************** + * + * Public class methods + * + ***********************************************************************/ + +FLAC__bool FLAC__bitbuffer_init(FLAC__BitBuffer *bb) { FLAC__ASSERT(bb != 0); bb->buffer = 0; bb->capacity = 0; - bb->bytes = bb->bits = bb->total_bits = 0; - bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0; + bb->blurbs = bb->bits = bb->total_bits = 0; + bb->consumed_blurbs = bb->consumed_bits = bb->total_consumed_bits = 0; + + return FLAC__bitbuffer_clear(bb); } FLAC__bool FLAC__bitbuffer_init_from(FLAC__BitBuffer *bb, const FLAC__byte buffer[], unsigned bytes) { FLAC__ASSERT(bb != 0); - FLAC__bitbuffer_init(bb); + FLAC__ASSERT(bytes > 0); - if(bytes == 0) - return true; - else { - FLAC__ASSERT(buffer != 0); - bb->buffer = (FLAC__byte*)malloc(sizeof(FLAC__byte)*bytes); - if(bb->buffer == 0) - return false; - memcpy(bb->buffer, buffer, sizeof(FLAC__byte)*bytes); - bb->capacity = bb->bytes = bytes; - bb->bits = 0; - bb->total_bits = (bytes<<3); - bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0; - return true; - } -} + if(!FLAC__bitbuffer_init(bb)) + return false; -void FLAC__bitbuffer_init_read_crc16(FLAC__BitBuffer *bb, FLAC__uint16 seed) -{ - FLAC__ASSERT(bb != 0); + if(!bitbuffer_ensure_size_(bb, bytes << 3)) + return false; - bb->read_crc16 = seed; + FLAC__ASSERT(buffer != 0); + /* @@@ WATCHOUT: code currently only works for 8-bits-per-blurb inclusive-or big-endian: */ + memcpy((FLAC__byte*)bb->buffer, buffer, sizeof(FLAC__byte)*bytes); + bb->blurbs = bytes / FLAC__BYTES_PER_BLURB; + bb->bits = (bytes % FLAC__BYTES_PER_BLURB) << 3; + bb->total_bits = bytes << 3; + return true; } FLAC__bool FLAC__bitbuffer_concatenate_aligned(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src) { - static const FLAC__byte mask_[9] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; unsigned bits_to_add = src->total_bits - src->total_consumed_bits; FLAC__ASSERT(dest != 0); @@ -185,20 +317,20 @@ FLAC__bool FLAC__bitbuffer_concatenate_aligned(FLAC__BitBuffer *dest, const FLAC if(!bitbuffer_ensure_size_(dest, bits_to_add)) return false; if(dest->bits == 0) { - memcpy(dest->buffer+dest->bytes, src->buffer+src->consumed_bytes, src->bytes-src->consumed_bytes + ((src->bits)? 1:0)); + memcpy(dest->buffer+dest->blurbs, src->buffer+src->consumed_blurbs, sizeof(FLAC__blurb)*(src->blurbs-src->consumed_blurbs + ((src->bits)? 1:0))); } - else if(dest->bits + bits_to_add > 8) { - dest->buffer[dest->bytes] <<= (8 - dest->bits); - dest->buffer[dest->bytes] |= (src->buffer[src->consumed_bytes] & mask_[8-dest->bits]); - memcpy(dest->buffer+dest->bytes+1, src->buffer+src->consumed_bytes+1, src->bytes-src->consumed_bytes-1 + ((src->bits)? 1:0)); + else if(dest->bits + bits_to_add > FLAC__BITS_PER_BLURB) { + dest->buffer[dest->blurbs] <<= (FLAC__BITS_PER_BLURB - dest->bits); + dest->buffer[dest->blurbs] |= (src->buffer[src->consumed_blurbs] & ((1u << (FLAC__BITS_PER_BLURB-dest->bits)) - 1)); + memcpy(dest->buffer+dest->blurbs+1, src->buffer+src->consumed_blurbs+1, sizeof(FLAC__blurb)*(src->blurbs-src->consumed_blurbs-1 + ((src->bits)? 1:0))); } else { - dest->buffer[dest->bytes] <<= bits_to_add; - dest->buffer[dest->bytes] |= (src->buffer[src->consumed_bytes] & mask_[bits_to_add]); + dest->buffer[dest->blurbs] <<= bits_to_add; + dest->buffer[dest->blurbs] |= (src->buffer[src->consumed_blurbs] & ((1u << bits_to_add) - 1)); } dest->bits = src->bits; dest->total_bits += bits_to_add; - dest->bytes = dest->total_bits / 8; + dest->blurbs = dest->total_bits / FLAC__BITS_PER_BLURB; return true; } @@ -211,24 +343,24 @@ void FLAC__bitbuffer_free(FLAC__BitBuffer *bb) free(bb->buffer); bb->buffer = 0; bb->capacity = 0; - bb->bytes = bb->bits = bb->total_bits = 0; - bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 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__byte*)malloc(sizeof(FLAC__byte) * bb->capacity); + bb->buffer = (FLAC__blurb*)malloc(sizeof(FLAC__blurb) * bb->capacity); if(bb->buffer == 0) return false; memset(bb->buffer, 0, bb->capacity); } else { - memset(bb->buffer, 0, bb->bytes + (bb->bits?1:0)); + memset(bb->buffer, 0, bb->blurbs + (bb->bits?1:0)); } - bb->bytes = bb->bits = bb->total_bits = 0; - bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0; + bb->blurbs = bb->bits = bb->total_bits = 0; + bb->consumed_blurbs = bb->consumed_bits = bb->total_consumed_bits = 0; return true; } @@ -242,17 +374,162 @@ FLAC__bool FLAC__bitbuffer_clone(FLAC__BitBuffer *dest, const FLAC__BitBuffer *s if(dest->capacity < src->capacity) if(!bitbuffer_resize_(dest, src->capacity)) return false; - memcpy(dest->buffer, src->buffer, sizeof(FLAC__byte)*min(src->capacity, src->bytes+1)); - dest->bytes = src->bytes; + 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_bytes = src->consumed_bytes; + 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(bb != 0); + FLAC__ASSERT(bb->buffer != 0); + 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(bb != 0); + FLAC__ASSERT(bb->buffer != 0); + 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(bb->blurbs == 0); + FLAC__ASSERT(bb->buffer[0] == 0xff); /* MAGIC NUMBER for the first byte of the sync code */ + FLAC__ASSERT((bb->bits & 7) == 0); /* assert that we're byte-aligned */ +#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; @@ -266,12 +543,12 @@ FLAC__bool FLAC__bitbuffer_write_zeroes(FLAC__BitBuffer *bb, unsigned bits) return false; bb->total_bits += bits; while(bits > 0) { - n = min(8 - bb->bits, bits); - bb->buffer[bb->bytes] <<= n; + n = min(FLAC__BITS_PER_BLURB - bb->bits, bits); + bb->buffer[bb->blurbs] <<= n; bits -= n; bb->bits += n; - if(bb->bits == 8) { - bb->bytes++; + if(bb->bits == FLAC__BITS_PER_BLURB) { + bb->blurbs++; bb->bits = 0; } } @@ -289,7 +566,7 @@ FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, FL if(bits == 0) return true; /* inline the size check so we don't incure a function call unnecessarily */ - if((bb->capacity<<3) < bb->total_bits + bits) { + if(FLAC__BLURBS_TO_BITS(bb->capacity) < bb->total_bits + bits) { if(!bitbuffer_ensure_size_(bb, bits)) return false; } @@ -297,29 +574,30 @@ FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, FL val &= (~(0xffffffff << bits)); /* zero-out unused bits */ bb->total_bits += bits; while(bits > 0) { - n = 8 - bb->bits; - if(n == 8) { /* i.e. bb->bits == 0 */ - if(bits < 8) { - bb->buffer[bb->bytes] = (FLAC__byte)val; + 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 == 8) { - bb->buffer[bb->bytes++] = (FLAC__byte)val; + else if(bits == FLAC__BITS_PER_BLURB) { + bb->buffer[bb->blurbs++] = (FLAC__blurb)val; break; } else { - k = bits - 8; - bb->buffer[bb->bytes++] = (FLAC__byte)(val >> k); + 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 -= 8; + bits -= FLAC__BITS_PER_BLURB; } } else if(bits <= n) { - bb->buffer[bb->bytes] <<= bits; - bb->buffer[bb->bytes] |= val; + bb->buffer[bb->blurbs] <<= bits; + bb->buffer[bb->blurbs] |= val; if(bits == n) { - bb->bytes++; + bb->blurbs++; bb->bits = 0; } else @@ -328,11 +606,12 @@ FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, FL } else { k = bits - n; - bb->buffer[bb->bytes] <<= n; - bb->buffer[bb->bytes] |= (val>>k); + 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->bytes++; + bb->blurbs++; bb->bits = 0; } } @@ -380,32 +659,34 @@ FLAC__bool FLAC__bitbuffer_write_raw_uint64(FLAC__BitBuffer *bb, FLAC__uint64 va bb->total_bits += bits; while(bits > 0) { if(bb->bits == 0) { - if(bits < 8) { - bb->buffer[bb->bytes] = (FLAC__byte)val; + if(bits < FLAC__BITS_PER_BLURB) { + bb->buffer[bb->blurbs] = (FLAC__blurb)val; bb->bits = bits; break; } - else if(bits == 8) { - bb->buffer[bb->bytes++] = (FLAC__byte)val; + else if(bits == FLAC__BITS_PER_BLURB) { + bb->buffer[bb->blurbs++] = (FLAC__blurb)val; break; } else { - k = bits - 8; - bb->buffer[bb->bytes++] = (FLAC__byte)(val >> k); + 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 &= (~(0xffffffffffffffff << k)); - bits -= 8; + bits -= FLAC__BITS_PER_BLURB; } } else { - n = min(8 - bb->bits, bits); + n = min(FLAC__BITS_PER_BLURB - bb->bits, bits); k = bits - n; - bb->buffer[bb->bytes] <<= n; - bb->buffer[bb->bytes] |= (val>>k); + 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 &= (~(0xffffffffffffffff << k)); bits -= n; bb->bits += n; - if(bb->bits == 8) { - bb->bytes++; + if(bb->bits == FLAC__BITS_PER_BLURB) { + bb->blurbs++; bb->bits = 0; } } @@ -451,6 +732,7 @@ unsigned FLAC__bitbuffer_rice_bits(int val, unsigned parameter) return 1 + parameter + msbs; } +#if 0 /* UNUSED */ unsigned FLAC__bitbuffer_golomb_bits_signed(int val, unsigned parameter) { unsigned bits, msbs, uval; @@ -516,7 +798,9 @@ unsigned FLAC__bitbuffer_golomb_bits_unsigned(unsigned uval, unsigned parameter) } return bits; } +#endif /* UNUSED */ +#ifdef FLAC__SYMMETRIC_RICE FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter) { unsigned total_bits, interesting_bits, msbs; @@ -555,6 +839,7 @@ FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed(FLAC__BitBuffer *bb, int return true; } +#if 0 /* UNUSED */ FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow) { unsigned total_bits, interesting_bits, msbs; @@ -598,6 +883,7 @@ FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed_guarded(FLAC__BitBuffer * } return true; } +#endif /* UNUSED */ FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed_escape(FLAC__BitBuffer *bb, int val, unsigned parameter) { @@ -633,6 +919,7 @@ FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed_escape(FLAC__BitBuffer *b } return true; } +#endif /* ifdef FLAC__SYMMETRIC_RICE */ FLAC__bool FLAC__bitbuffer_write_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter) { @@ -674,6 +961,7 @@ FLAC__bool FLAC__bitbuffer_write_rice_signed(FLAC__BitBuffer *bb, int val, unsig return true; } +#if 0 /* UNUSED */ FLAC__bool FLAC__bitbuffer_write_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow) { unsigned total_bits, interesting_bits, msbs, uval; @@ -719,7 +1007,9 @@ FLAC__bool FLAC__bitbuffer_write_rice_signed_guarded(FLAC__BitBuffer *bb, int va } return true; } +#endif /* UNUSED */ +#if 0 /* UNUSED */ FLAC__bool FLAC__bitbuffer_write_golomb_signed(FLAC__BitBuffer *bb, int val, unsigned parameter) { unsigned total_bits, msbs, uval; @@ -845,6 +1135,7 @@ FLAC__bool FLAC__bitbuffer_write_golomb_unsigned(FLAC__BitBuffer *bb, unsigned u } return true; } +#endif /* UNUSED */ FLAC__bool FLAC__bitbuffer_write_utf8_uint32(FLAC__BitBuffer *bb, FLAC__uint32 val) { @@ -950,8 +1241,8 @@ FLAC__bool FLAC__bitbuffer_write_utf8_uint64(FLAC__BitBuffer *bb, FLAC__uint64 v FLAC__bool FLAC__bitbuffer_zero_pad_to_byte_boundary(FLAC__BitBuffer *bb) { /* 0-pad to byte boundary */ - if(bb->bits != 0) - return FLAC__bitbuffer_write_zeroes(bb, 8 - bb->bits); + if(bb->bits & 7u) + return FLAC__bitbuffer_write_zeroes(bb, 8 - (bb->bits & 7u)); else return true; } @@ -966,7 +1257,7 @@ FLAC__bool FLAC__bitbuffer_peek_bit(FLAC__BitBuffer *bb, unsigned *val, FLAC__bo while(1) { if(bb->total_consumed_bits < bb->total_bits) { - *val = (bb->buffer[bb->consumed_bytes] & BYTE_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; + *val = (bb->buffer[bb->consumed_blurbs] & BLURB_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; return true; } else { @@ -986,11 +1277,11 @@ FLAC__bool FLAC__bitbuffer_read_bit(FLAC__BitBuffer *bb, unsigned *val, FLAC__bo while(1) { if(bb->total_consumed_bits < bb->total_bits) { - *val = (bb->buffer[bb->consumed_bytes] & BYTE_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; + *val = (bb->buffer[bb->consumed_blurbs] & BLURB_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; bb->consumed_bits++; - if(bb->consumed_bits == 8) { - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; + 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; } bb->total_consumed_bits++; @@ -1014,11 +1305,11 @@ FLAC__bool FLAC__bitbuffer_read_bit_to_uint32(FLAC__BitBuffer *bb, FLAC__uint32 while(1) { if(bb->total_consumed_bits < bb->total_bits) { *val <<= 1; - *val |= (bb->buffer[bb->consumed_bytes] & BYTE_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; + *val |= (bb->buffer[bb->consumed_blurbs] & BLURB_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; bb->consumed_bits++; - if(bb->consumed_bits == 8) { - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; + 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; } bb->total_consumed_bits++; @@ -1042,11 +1333,11 @@ FLAC__bool FLAC__bitbuffer_read_bit_to_uint64(FLAC__BitBuffer *bb, FLAC__uint64 while(1) { if(bb->total_consumed_bits < bb->total_bits) { *val <<= 1; - *val |= (bb->buffer[bb->consumed_bytes] & BYTE_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; + *val |= (bb->buffer[bb->consumed_blurbs] & BLURB_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; bb->consumed_bits++; - if(bb->consumed_bits == 8) { - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; + 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; } bb->total_consumed_bits++; @@ -1085,46 +1376,77 @@ FLaC__INLINE FLAC__bool FLAC__bitbuffer_read_raw_uint32(FLAC__BitBuffer *bb, FLA FLAC__ASSERT(bb->buffer != 0); FLAC__ASSERT(bits <= 32); - FLAC__ASSERT((bb->capacity*8) * 2 >= bits); + 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(bb->consumed_bits) { - i = 8 - bb->consumed_bits; - if(i <= bits_) { - v = bb->buffer[bb->consumed_bytes] & (0xff >> bb->consumed_bits); - bits_ -= i; - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - bb->consumed_bits = 0; - /* we hold off updating bb->total_consumed_bits until the end */ +#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; + } } - else { - *val = (bb->buffer[bb->consumed_bytes] & (0xff >> bb->consumed_bits)) >> (i-bits_); - bb->consumed_bits += bits_; - bb->total_consumed_bits += bits_; +#if FLAC__BITS_PER_BLURB == 32 + /* note that we know bits_ cannot be > 32 because of previous assertions */ + if(bits_ == FLAC__BITS_PER_BLURB) { + v = bb->buffer[bb->consumed_blurbs]; + CRC16_UPDATE_BLURB(bb, v, bb->read_crc16); + bb->consumed_blurbs++; + /* bb->consumed_bits is already 0 */ + bb->total_consumed_bits += bits; + *val = v; return true; } +#else + 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 */ + } +#endif + 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 } - while(bits_ >= 8) { - v <<= 8; - v |= bb->buffer[bb->consumed_bytes]; - bits_ -= 8; - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - /* bb->consumed_bits is already 0 */ - /* we hold off updating bb->total_consumed_bits until the end */ + else { + *val = 0; + for(i = 0; i < bits; i++) { + if(!FLAC__bitbuffer_read_bit_to_uint32(bb, val, read_callback, client_data)) + return false; + } } - if(bits_ > 0) { - v <<= bits_; - v |= (bb->buffer[bb->consumed_bytes] >> (8-bits_)); - bb->consumed_bits = bits_; - /* we hold off updating bb->total_consumed_bits until the end */ - } - bb->total_consumed_bits += bits; - *val = v; +#endif return true; } #endif @@ -1172,7 +1494,7 @@ FLAC__bool FLAC__bitbuffer_read_raw_int32(FLAC__BitBuffer *bb, FLAC__int32 *val, FLAC__ASSERT(bb->buffer != 0); FLAC__ASSERT(bits <= 32); - FLAC__ASSERT((bb->capacity*8) * 2 >= bits); + FLAC__ASSERT((bb->capacity*FLAC__BITS_PER_BLURB) * 2 >= bits); if(bits == 0) { *val = 0; @@ -1183,43 +1505,67 @@ FLAC__bool FLAC__bitbuffer_read_raw_int32(FLAC__BitBuffer *bb, FLAC__int32 *val, if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) return false; } - if(bb->consumed_bits) { - i = 8 - bb->consumed_bits; - if(i <= bits_) { - v = bb->buffer[bb->consumed_bytes] & (0xff >> bb->consumed_bits); - bits_ -= i; - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - bb->consumed_bits = 0; +#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 <<= (32-i); + *val = (FLAC__int32)v; + *val >>= (32-bits_); + bb->consumed_bits += bits_; + bb->total_consumed_bits += bits_; + return true; + } + } +#if FLAC__BITS_PER_BLURB == 32 + /* note that we know bits_ cannot be > 32 because of previous assertions */ + if(bits_ == FLAC__BITS_PER_BLURB) { + v = bb->buffer[bb->consumed_blurbs]; + bits_ = 0; + CRC16_UPDATE_BLURB(bb, v, bb->read_crc16); + bb->consumed_blurbs++; + /* bb->consumed_bits is already 0 */ /* we hold off updating bb->total_consumed_bits until the end */ } - else { - /* bits_ must be < 7 if we get to here */ - v = (bb->buffer[bb->consumed_bytes] & (0xff >> bb->consumed_bits)); - v <<= (32-i); - *val = (FLAC__int32)v; - *val >>= (32-bits_); - bb->consumed_bits += bits_; - bb->total_consumed_bits += bits_; - return true; +#else + 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 */ + } +#endif + 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_uint32(bb, &v, read_callback, client_data)) + return false; } } - while(bits_ >= 8) { - v <<= 8; - v |= bb->buffer[bb->consumed_bytes]; - bits_ -= 8; - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - /* 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_bytes] >> (8-bits_)); - bb->consumed_bits = bits_; - /* we hold off updating bb->total_consumed_bits until the end */ - } - bb->total_consumed_bits += bits; +#endif /* fix the sign */ i = 32 - bits; @@ -1261,46 +1607,64 @@ FLAC__bool FLAC__bitbuffer_read_raw_uint64(FLAC__BitBuffer *bb, FLAC__uint64 *va FLAC__ASSERT(bb->buffer != 0); FLAC__ASSERT(bits <= 64); - FLAC__ASSERT((bb->capacity*8) * 2 >= bits); + 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(bb->consumed_bits) { - i = 8 - bb->consumed_bits; - if(i <= bits_) { - v = bb->buffer[bb->consumed_bytes] & (0xff >> bb->consumed_bits); - bits_ -= i; - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - bb->consumed_bits = 0; +#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 */ } - else { - *val = (bb->buffer[bb->consumed_bytes] & (0xff >> bb->consumed_bits)) >> (i-bits_); - bb->consumed_bits += bits_; - bb->total_consumed_bits += bits_; - return true; + 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; } } - while(bits_ >= 8) { - v <<= 8; - v |= bb->buffer[bb->consumed_bytes]; - bits_ -= 8; - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - /* 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_bytes] >> (8-bits_)); - bb->consumed_bits = bits_; - /* we hold off updating bb->total_consumed_bits until the end */ - } - bb->total_consumed_bits += bits; - *val = v; +#endif return true; } #endif @@ -1342,49 +1706,66 @@ FLAC__bool FLAC__bitbuffer_read_raw_int64(FLAC__BitBuffer *bb, FLAC__int64 *val, FLAC__ASSERT(bb->buffer != 0); FLAC__ASSERT(bits <= 64); - FLAC__ASSERT((bb->capacity*8) * 2 >= bits); + 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(bb->consumed_bits) { - i = 8 - bb->consumed_bits; - if(i <= bits_) { - v = bb->buffer[bb->consumed_bytes] & (0xff >> bb->consumed_bits); - bits_ -= i; - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - bb->consumed_bits = 0; +#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 */ } - else { - /* bits_ must be < 7 if we get to here */ - v = (bb->buffer[bb->consumed_bytes] & (0xff >> bb->consumed_bits)); - v <<= (64-i); - *val = (FLAC__int64)v; - *val >>= (64-bits_); - bb->consumed_bits += bits_; - bb->total_consumed_bits += bits_; - return true; + 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; } } - while(bits_ >= 8) { - v <<= 8; - v |= bb->buffer[bb->consumed_bytes]; - bits_ -= 8; - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - /* 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_bytes] >> (8-bits_)); - bb->consumed_bits = bits_; - /* we hold off updating bb->total_consumed_bits until the end */ - } - bb->total_consumed_bits += bits; +#endif /* fix the sign */ i = 64 - bits; @@ -1422,70 +1803,88 @@ FLaC__INLINE FLAC__bool FLAC__bitbuffer_read_unary_unsigned(FLAC__BitBuffer *bb, #else { unsigned i, val_ = 0; - unsigned total_bytes_ = (bb->total_bits + 7) / 8; - FLAC__byte b; + unsigned total_blurbs_ = (bb->total_bits + (FLAC__BITS_PER_BLURB-1)) / FLAC__BITS_PER_BLURB; + FLAC__blurb b; FLAC__ASSERT(bb != 0); FLAC__ASSERT(bb->buffer != 0); - if(bb->consumed_bits) { - b = bb->buffer[bb->consumed_bytes] << bb->consumed_bits; - if(b) { - for(i = 0; !(b & 0x80); i++) - b <<= 1; - *val = i; - i++; - bb->consumed_bits += i; - bb->total_consumed_bits += i; - if(bb->consumed_bits == 8) { - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - bb->consumed_bits = 0; +#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_; } - return true; } - else { - val_ = 8 - bb->consumed_bits; - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - 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 } - while(1) { - if(bb->consumed_bytes >= total_bytes_) { - if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) + else { + while(1) { + if(!FLAC__bitbuffer_read_bit(bb, &i, read_callback, client_data)) return false; - total_bytes_ = (bb->total_bits + 7) / 8; - } - b = bb->buffer[bb->consumed_bytes]; - if(b) { - for(i = 0; !(b & 0x80); i++) - b <<= 1; - val_ += i; - i++; - bb->consumed_bits = i; - *val = val_; - if(i == 8) { - FLAC__CRC16_UPDATE(bb->buffer[bb->consumed_bytes], bb->read_crc16); - bb->consumed_bytes++; - bb->consumed_bits = 0; - } - bb->total_consumed_bits += i; - return true; - } - else { - val_ += 8; - FLAC__CRC16_UPDATE(0, bb->read_crc16); - bb->consumed_bytes++; - /* bb->consumed_bits is already 0 */ - /* we hold off updating bb->total_consumed_bits until the end */ - bb->total_consumed_bits += 8; + if(i) + break; + else + val_++; } + *val = val_; + return true; } +#endif } #endif +#ifdef FLAC__SYMMETRIC_RICE FLAC__bool FLAC__bitbuffer_read_symmetric_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) { FLAC__uint32 sign = 0, lsbs = 0, msbs = 0; @@ -1513,6 +1912,7 @@ FLAC__bool FLAC__bitbuffer_read_symmetric_rice_signed(FLAC__BitBuffer *bb, int * return true; } +#endif /* ifdef FLAC__SYMMETRIC_RICE */ FLAC__bool FLAC__bitbuffer_read_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) { @@ -1541,6 +1941,7 @@ FLAC__bool FLAC__bitbuffer_read_rice_signed(FLAC__BitBuffer *bb, int *val, unsig return true; } +#if 0 /* UNUSED */ FLAC__bool FLAC__bitbuffer_read_golomb_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) { FLAC__uint32 lsbs = 0, msbs = 0; @@ -1622,6 +2023,7 @@ FLAC__bool FLAC__bitbuffer_read_golomb_unsigned(FLAC__BitBuffer *bb, unsigned *v return true; } +#endif /* UNUSED */ /* on return, if *val == 0xffffffff then the utf-8 sequence was invalid, but the return value will be true */ FLAC__bool FLAC__bitbuffer_read_utf8_uint32(FLAC__BitBuffer *bb, FLAC__uint32 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data, FLAC__byte *raw, unsigned *rawlen) @@ -1744,20 +2146,20 @@ void FLAC__bitbuffer_dump(const FLAC__BitBuffer *bb, FILE *out) fprintf(out, "bitbuffer is NULL\n"); } else { - fprintf(out, "bitbuffer: capacity=%u bytes=%u bits=%u total_bits=%u consumed: bytes=%u, bits=%u, total_bits=%u\n", bb->capacity, bb->bytes, bb->bits, bb->total_bits, bb->consumed_bytes, bb->consumed_bits, bb->total_consumed_bits); - for(i = 0; i < bb->bytes; i++) { + fprintf(out, "bitbuffer: capacity=%u blurbs=%u bits=%u total_bits=%u consumed: blurbs=%u, bits=%u, total_bits=%u\n", bb->capacity, bb->blurbs, bb->bits, bb->total_bits, bb->consumed_blurbs, bb->consumed_bits, bb->total_consumed_bits); + for(i = 0; i < bb->blurbs; i++) { fprintf(out, "%08X: ", i); - for(j = 0; j < 8; j++) - if(i*8+j < bb->total_consumed_bits) + for(j = 0; j < FLAC__BITS_PER_BLURB; j++) + if(i*FLAC__BITS_PER_BLURB+j < bb->total_consumed_bits) fprintf(out, "."); else - fprintf(out, "%01u", bb->buffer[i] & (1 << (8-j-1)) ? 1:0); + fprintf(out, "%01u", bb->buffer[i] & (1 << (FLAC__BITS_PER_BLURB-j-1)) ? 1:0); fprintf(out, "\n"); } if(bb->bits > 0) { fprintf(out, "%08X: ", i); for(j = 0; j < bb->bits; j++) - if(i*8+j < bb->total_consumed_bits) + if(i*FLAC__BITS_PER_BLURB+j < bb->total_consumed_bits) fprintf(out, "."); else fprintf(out, "%01u", bb->buffer[i] & (1 << (bb->bits-j-1)) ? 1:0); diff --git a/src/libFLAC/include/private/bitbuffer.h b/src/libFLAC/include/private/bitbuffer.h index d8764f15..43ead8ee 100644 --- a/src/libFLAC/include/private/bitbuffer.h +++ b/src/libFLAC/include/private/bitbuffer.h @@ -23,23 +23,61 @@ #include /* for FILE */ #include "FLAC/ordinals.h" -typedef struct { - FLAC__byte *buffer; - unsigned capacity; /* in bytes */ - unsigned bytes, bits; - unsigned total_bits; /* must always == 8*bytes+bits */ - unsigned consumed_bytes, consumed_bits; - unsigned total_consumed_bits; /* must always == 8*consumed_bytes+consumed_bits */ - FLAC__uint16 read_crc16; -} FLAC__BitBuffer; +/* @@@ This should be configurable. Valid values are currently 8 and 32. */ +/* @@@ WATCHOUT! do not use 32 with a little endian system yet. */ +#define FLAC__BITS_PER_BLURB 8 -void FLAC__bitbuffer_init(FLAC__BitBuffer *bb); +#if FLAC__BITS_PER_BLURB == 8 +typedef FLAC__byte FLAC__blurb; +#elif FLAC__BITS_PER_BLURB == 32 +typedef FLAC__uint32 FLAC__blurb; +#else +/* ERROR, only sizes of 8 and 32 are supported */ +#endif + +/* + * opaque structure definition + */ +struct FLAC__BitBuffer; +typedef struct FLAC__BitBuffer FLAC__BitBuffer; + +/* + * construction, deletion, initialization, cloning functions + */ +FLAC__BitBuffer *FLAC__bitbuffer_new(); +void FLAC__bitbuffer_delete(FLAC__BitBuffer *bb); +FLAC__bool FLAC__bitbuffer_init(FLAC__BitBuffer *bb); FLAC__bool FLAC__bitbuffer_init_from(FLAC__BitBuffer *bb, const FLAC__byte buffer[], unsigned bytes); -void FLAC__bitbuffer_init_read_crc16(FLAC__BitBuffer *bb, FLAC__uint16 seed); FLAC__bool FLAC__bitbuffer_concatenate_aligned(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src); void FLAC__bitbuffer_free(FLAC__BitBuffer *bb); /* does not 'free(buffer)' */ FLAC__bool FLAC__bitbuffer_clear(FLAC__BitBuffer *bb); FLAC__bool FLAC__bitbuffer_clone(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src); + +/* + * CRC functions + */ +void FLAC__bitbuffer_reset_read_crc16(FLAC__BitBuffer *bb, FLAC__uint16 seed); +FLAC__uint16 FLAC__bitbuffer_get_read_crc16(FLAC__BitBuffer *bb); +FLAC__uint16 FLAC__bitbuffer_get_write_crc16(const FLAC__BitBuffer *bb); +FLAC__byte FLAC__bitbuffer_get_write_crc8(const FLAC__BitBuffer *bb); + +/* + * info functions + */ +FLAC__bool FLAC__bitbuffer_is_byte_aligned(const FLAC__BitBuffer *bb); +FLAC__bool FLAC__bitbuffer_is_consumed_byte_aligned(const FLAC__BitBuffer *bb); +unsigned FLAC__bitbuffer_bits_left_for_byte_alignment(const FLAC__BitBuffer *bb); +unsigned FLAC__bitbuffer_get_input_bytes_unconsumed(const FLAC__BitBuffer *bb); /* do not call unless byte-aligned */ + +/* + * direct buffer access + */ +void FLAC__bitbuffer_get_buffer(FLAC__BitBuffer *bb, const FLAC__byte **buffer, unsigned *bytes); +void FLAC__bitbuffer_release_buffer(FLAC__BitBuffer *bb); + +/* + * write functions + */ FLAC__bool FLAC__bitbuffer_write_zeroes(FLAC__BitBuffer *bb, unsigned bits); FLAC__bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, FLAC__uint32 val, unsigned bits); FLAC__bool FLAC__bitbuffer_write_raw_int32(FLAC__BitBuffer *bb, FLAC__int32 val, unsigned bits); @@ -47,20 +85,34 @@ FLAC__bool FLAC__bitbuffer_write_raw_uint64(FLAC__BitBuffer *bb, FLAC__uint64 va FLAC__bool FLAC__bitbuffer_write_raw_int64(FLAC__BitBuffer *bb, FLAC__int64 val, unsigned bits); FLAC__bool FLAC__bitbuffer_write_unary_unsigned(FLAC__BitBuffer *bb, unsigned val); unsigned FLAC__bitbuffer_rice_bits(int val, unsigned parameter); +#if 0 /* UNUSED */ unsigned FLAC__bitbuffer_golomb_bits_signed(int val, unsigned parameter); unsigned FLAC__bitbuffer_golomb_bits_unsigned(unsigned val, unsigned parameter); +#endif +#ifdef FLAC__SYMMETRIC_RICE FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter); +#if 0 /* UNUSED */ FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow); +#endif FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed_escape(FLAC__BitBuffer *bb, int val, unsigned parameter); +#endif FLAC__bool FLAC__bitbuffer_write_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter); +#if 0 /* UNUSED */ FLAC__bool FLAC__bitbuffer_write_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow); +#endif +#if 0 /* UNUSED */ FLAC__bool FLAC__bitbuffer_write_golomb_signed(FLAC__BitBuffer *bb, int val, unsigned parameter); FLAC__bool FLAC__bitbuffer_write_golomb_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow); FLAC__bool FLAC__bitbuffer_write_golomb_unsigned(FLAC__BitBuffer *bb, unsigned val, unsigned parameter); FLAC__bool FLAC__bitbuffer_write_golomb_unsigned_guarded(FLAC__BitBuffer *bb, unsigned val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow); +#endif FLAC__bool FLAC__bitbuffer_write_utf8_uint32(FLAC__BitBuffer *bb, FLAC__uint32 val); FLAC__bool FLAC__bitbuffer_write_utf8_uint64(FLAC__BitBuffer *bb, FLAC__uint64 val); FLAC__bool FLAC__bitbuffer_zero_pad_to_byte_boundary(FLAC__BitBuffer *bb); + +/* + * read functions + */ FLAC__bool FLAC__bitbuffer_peek_bit(FLAC__BitBuffer *bb, unsigned *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); FLAC__bool FLAC__bitbuffer_read_bit(FLAC__BitBuffer *bb, unsigned *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); FLAC__bool FLAC__bitbuffer_read_bit_to_uint32(FLAC__BitBuffer *bb, FLAC__uint32 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); @@ -70,10 +122,14 @@ FLAC__bool FLAC__bitbuffer_read_raw_int32(FLAC__BitBuffer *bb, FLAC__int32 *val, 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); 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); 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__SYMMETRIC_RICE FLAC__bool FLAC__bitbuffer_read_symmetric_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); +#endif FLAC__bool FLAC__bitbuffer_read_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); +#if 0 /* UNUSED */ FLAC__bool FLAC__bitbuffer_read_golomb_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); FLAC__bool FLAC__bitbuffer_read_golomb_unsigned(FLAC__BitBuffer *bb, unsigned *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); +#endif FLAC__bool FLAC__bitbuffer_read_utf8_uint32(FLAC__BitBuffer *bb, FLAC__uint32 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data, FLAC__byte *raw, unsigned *rawlen); FLAC__bool FLAC__bitbuffer_read_utf8_uint64(FLAC__BitBuffer *bb, FLAC__uint64 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data, FLAC__byte *raw, unsigned *rawlen); void FLAC__bitbuffer_dump(const FLAC__BitBuffer *bb, FILE *out); diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c index 2f5da20a..abe8613b 100644 --- a/src/libFLAC/stream_decoder.c +++ b/src/libFLAC/stream_decoder.c @@ -72,7 +72,7 @@ typedef struct FLAC__StreamDecoderPrivate { void (*local_lpc_restore_signal)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); void *client_data; - FLAC__BitBuffer input; + FLAC__BitBuffer *input; FLAC__int32 *output[FLAC__MAX_CHANNELS]; FLAC__int32 *residual[FLAC__MAX_CHANNELS]; unsigned output_capacity, output_channels; @@ -151,6 +151,13 @@ FLAC__StreamDecoder *FLAC__stream_decoder_new() free(decoder); return 0; } + decoder->private_->input = FLAC__bitbuffer_new(); + if(decoder->private_->input == 0) { + free(decoder->private_); + free(decoder->protected_); + free(decoder); + return 0; + } decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; @@ -168,7 +175,9 @@ void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder) FLAC__ASSERT(decoder != 0); FLAC__ASSERT(decoder->protected_ != 0); FLAC__ASSERT(decoder->private_ != 0); + FLAC__ASSERT(decoder->private_->input != 0); + FLAC__bitbuffer_delete(decoder->private_->input); free(decoder->private_); free(decoder->protected_); free(decoder); @@ -194,7 +203,8 @@ FLAC__StreamDecoderState FLAC__stream_decoder_init(FLAC__StreamDecoder *decoder) if(0 == decoder->private_->read_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback) return decoder->protected_->state = FLAC__STREAM_DECODER_INVALID_CALLBACK; - FLAC__bitbuffer_init(&decoder->private_->input); + if(!FLAC__bitbuffer_init(decoder->private_->input)) + return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; for(i = 0; i < FLAC__MAX_CHANNELS; i++) { decoder->private_->output[i] = 0; @@ -248,7 +258,7 @@ void FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) free(decoder->private_->seek_table.data.seek_table.points); decoder->private_->seek_table.data.seek_table.points = 0; } - FLAC__bitbuffer_free(&decoder->private_->input); + FLAC__bitbuffer_free(decoder->private_->input); for(i = 0; i < FLAC__MAX_CHANNELS; i++) { /* WATCHOUT: FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the output arrays have a buffer of up to 3 zeroes in front (at negative indices) for alignment purposes; we use 4 to keep the data well-aligned. */ if(decoder->private_->output[i] != 0) { @@ -339,7 +349,7 @@ FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder) { FLAC__ASSERT(decoder != 0); - if(!FLAC__bitbuffer_clear(&decoder->private_->input)) { + if(!FLAC__bitbuffer_clear(decoder->private_->input)) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -507,7 +517,7 @@ FLAC__bool FLAC__stream_decoder_process_remaining_frames(FLAC__StreamDecoder *de unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder) { FLAC__ASSERT(decoder != 0); - return decoder->private_->input.bytes - decoder->private_->input.consumed_bytes; + return FLAC__bitbuffer_get_input_bytes_unconsumed(decoder->private_->input); } /*********************************************************************** @@ -567,7 +577,7 @@ FLAC__bool stream_decoder_find_metadata_(FLAC__StreamDecoder *decoder) unsigned i, id; FLAC__bool first = true; - FLAC__ASSERT(decoder->private_->input.consumed_bits == 0); /* make sure we're byte aligned */ + FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); for(i = id = 0; i < 4; ) { if(decoder->private_->cached) { @@ -575,7 +585,7 @@ FLAC__bool stream_decoder_find_metadata_(FLAC__StreamDecoder *decoder) decoder->private_->cached = false; } else { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ } if(x == FLAC__STREAM_SYNC_STRING[i]) { @@ -595,7 +605,7 @@ FLAC__bool stream_decoder_find_metadata_(FLAC__StreamDecoder *decoder) } if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ decoder->private_->header_warmup[0] = (FLAC__byte)x; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ @@ -626,13 +636,13 @@ FLAC__bool stream_decoder_read_metadata_(FLAC__StreamDecoder *decoder) FLAC__uint32 i, x, last_block, type, length; FLAC__uint64 xx; - FLAC__ASSERT(decoder->private_->input.consumed_bits == 0); /* make sure we're byte aligned */ + FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &last_block, FLAC__STREAM_METADATA_IS_LAST_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &last_block, FLAC__STREAM_METADATA_IS_LAST_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &type, FLAC__STREAM_METADATA_TYPE_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &type, FLAC__STREAM_METADATA_TYPE_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ if(type == FLAC__METADATA_TYPE_STREAMINFO) { unsigned used_bits = 0; @@ -640,47 +650,47 @@ FLAC__bool stream_decoder_read_metadata_(FLAC__StreamDecoder *decoder) decoder->private_->stream_info.is_last = last_block; decoder->private_->stream_info.length = length; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->stream_info.data.stream_info.min_blocksize = x; used_bits += FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->stream_info.data.stream_info.max_blocksize = x; used_bits += FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->stream_info.data.stream_info.min_framesize = x; used_bits += FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->stream_info.data.stream_info.max_framesize = x; used_bits += FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->stream_info.data.stream_info.sample_rate = x; used_bits += FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->stream_info.data.stream_info.channels = x+1; used_bits += FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->stream_info.data.stream_info.bits_per_sample = x+1; used_bits += FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; - if(!FLAC__bitbuffer_read_raw_uint64(&decoder->private_->input, &decoder->private_->stream_info.data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &decoder->private_->stream_info.data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ used_bits += FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; for(i = 0; i < 16; i++) { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->stream_info.data.stream_info.md5sum[i] = (FLAC__byte)x; } @@ -690,7 +700,7 @@ FLAC__bool stream_decoder_read_metadata_(FLAC__StreamDecoder *decoder) FLAC__ASSERT(used_bits % 8 == 0); length -= (used_bits / 8); for(i = 0; i < length; i++) { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ } @@ -711,15 +721,15 @@ FLAC__bool stream_decoder_read_metadata_(FLAC__StreamDecoder *decoder) return false; } for(i = real_points = 0; i < decoder->private_->seek_table.data.seek_table.num_points; i++) { - if(!FLAC__bitbuffer_read_raw_uint64(&decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->seek_table.data.seek_table.points[real_points].sample_number = xx; - if(!FLAC__bitbuffer_read_raw_uint64(&decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->seek_table.data.seek_table.points[real_points].stream_offset = xx; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->seek_table.data.seek_table.points[real_points].frame_samples = x; @@ -734,7 +744,7 @@ FLAC__bool stream_decoder_read_metadata_(FLAC__StreamDecoder *decoder) else { /* skip other metadata blocks */ for(i = 0; i < length; i++) { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ } } @@ -751,19 +761,19 @@ FLAC__bool stream_decoder_skip_id3v2_tag_(FLAC__StreamDecoder *decoder) unsigned i, skip; /* skip the version and flags bytes */ - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 24, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 24, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ /* get the size (in bytes) to skip */ skip = 0; for(i = 0; i < 4; i++) { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ skip <<= 7; skip |= (x & 0x7f); } /* skip the rest of the tag */ for(i = 0; i < skip; i++) { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ } return true; @@ -784,8 +794,8 @@ FLAC__bool stream_decoder_frame_sync_(FLAC__StreamDecoder *decoder) } /* make sure we're byte aligned */ - if(decoder->private_->input.consumed_bits != 0) { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8-decoder->private_->input.consumed_bits, read_callback_, decoder)) + if(!FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)) { + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__bitbuffer_bits_left_for_byte_alignment(decoder->private_->input), read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ } @@ -795,12 +805,12 @@ FLAC__bool stream_decoder_frame_sync_(FLAC__StreamDecoder *decoder) decoder->private_->cached = false; } else { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ } if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ decoder->private_->header_warmup[0] = (FLAC__byte)x; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ @@ -838,7 +848,7 @@ FLAC__bool stream_decoder_read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool * frame_crc = 0; FLAC__CRC16_UPDATE(decoder->private_->header_warmup[0], frame_crc); FLAC__CRC16_UPDATE(decoder->private_->header_warmup[1], frame_crc); - FLAC__bitbuffer_init_read_crc16(&decoder->private_->input, frame_crc); + FLAC__bitbuffer_reset_read_crc16(decoder->private_->input, frame_crc); if(!stream_decoder_read_frame_header_(decoder)) return false; @@ -889,8 +899,8 @@ FLAC__bool stream_decoder_read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool * /* * Read the frame CRC-16 from the footer and check */ - frame_crc = decoder->private_->input.read_crc16; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN, read_callback_, decoder)) + frame_crc = FLAC__bitbuffer_get_read_crc16(decoder->private_->input); + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ if(frame_crc == (FLAC__uint16)x) { /* Undo any special channel coding */ @@ -967,7 +977,7 @@ FLAC__bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder) const FLAC__bool is_known_variable_blocksize_stream = (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize != decoder->private_->stream_info.data.stream_info.max_blocksize); const FLAC__bool is_known_fixed_blocksize_stream = (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize); - FLAC__ASSERT(decoder->private_->input.consumed_bits == 0); /* make sure we're byte aligned */ + FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); /* init the raw header with the saved bits from synchronization */ raw_header[0] = decoder->private_->header_warmup[0]; @@ -991,7 +1001,7 @@ FLAC__bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder) * read in the raw header as bytes so we can CRC it, and parse it on the way */ for(i = 0; i < 2; i++) { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ /* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */ @@ -1149,7 +1159,7 @@ FLAC__bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder) } if(blocksize_hint && is_known_variable_blocksize_stream) { - if(!FLAC__bitbuffer_read_utf8_uint64(&decoder->private_->input, &xx, read_callback_, decoder, raw_header, &raw_header_len)) + if(!FLAC__bitbuffer_read_utf8_uint64(decoder->private_->input, &xx, read_callback_, decoder, raw_header, &raw_header_len)) return false; /* the read_callback_ sets the state for us */ if(xx == 0xffffffffffffffff) { /* i.e. non-UTF8 code... */ decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */ @@ -1162,7 +1172,7 @@ FLAC__bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder) decoder->private_->frame.header.number.sample_number = xx; } else { - if(!FLAC__bitbuffer_read_utf8_uint32(&decoder->private_->input, &x, read_callback_, decoder, raw_header, &raw_header_len)) + if(!FLAC__bitbuffer_read_utf8_uint32(decoder->private_->input, &x, read_callback_, decoder, raw_header, &raw_header_len)) return false; /* the read_callback_ sets the state for us */ if(x == 0xffffffff) { /* i.e. non-UTF8 code... */ decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */ @@ -1182,12 +1192,12 @@ FLAC__bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder) } if(blocksize_hint) { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ raw_header[raw_header_len++] = (FLAC__byte)x; if(blocksize_hint == 7) { FLAC__uint32 _x; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &_x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &_x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ raw_header[raw_header_len++] = (FLAC__byte)_x; x = (x << 8) | _x; @@ -1196,12 +1206,12 @@ FLAC__bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder) } if(sample_rate_hint) { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ raw_header[raw_header_len++] = (FLAC__byte)x; if(sample_rate_hint != 12) { FLAC__uint32 _x; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &_x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &_x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ raw_header[raw_header_len++] = (FLAC__byte)_x; x = (x << 8) | _x; @@ -1215,7 +1225,7 @@ FLAC__bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder) } /* read the CRC-8 byte */ - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ crc8 = (FLAC__byte)x; @@ -1238,7 +1248,7 @@ FLAC__bool stream_decoder_read_subframe_(FLAC__StreamDecoder *decoder, unsigned FLAC__uint32 x; FLAC__bool wasted_bits; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &x, 8, read_callback_, decoder)) /* MAGIC NUMBER */ + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) /* MAGIC NUMBER */ return false; /* the read_callback_ sets the state for us */ wasted_bits = (x & 1); @@ -1246,7 +1256,7 @@ FLAC__bool stream_decoder_read_subframe_(FLAC__StreamDecoder *decoder, unsigned if(wasted_bits) { unsigned u; - if(!FLAC__bitbuffer_read_unary_unsigned(&decoder->private_->input, &u, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_unary_unsigned(decoder->private_->input, &u, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ decoder->private_->frame.subframes[channel].wasted_bits = u+1; bps -= decoder->private_->frame.subframes[channel].wasted_bits; @@ -1306,7 +1316,7 @@ FLAC__bool stream_decoder_read_subframe_constant_(FLAC__StreamDecoder *decoder, decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT; - if(!FLAC__bitbuffer_read_raw_int32(&decoder->private_->input, &x, bps, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &x, bps, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ subframe->value = x; @@ -1332,18 +1342,18 @@ FLAC__bool stream_decoder_read_subframe_fixed_(FLAC__StreamDecoder *decoder, uns /* read warm-up samples */ for(u = 0; u < order; u++) { - if(!FLAC__bitbuffer_read_raw_int32(&decoder->private_->input, &i32, bps, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, bps, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ subframe->warmup[u] = i32; } /* read entropy coding method info */ - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ subframe->entropy_coding_method.type = u32; switch(subframe->entropy_coding_method.type) { case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ subframe->entropy_coding_method.data.partitioned_rice.order = u32; break; @@ -1383,13 +1393,13 @@ FLAC__bool stream_decoder_read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsig /* read warm-up samples */ for(u = 0; u < order; u++) { - if(!FLAC__bitbuffer_read_raw_int32(&decoder->private_->input, &i32, bps, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, bps, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ subframe->warmup[u] = i32; } /* read qlp coeff precision */ - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &u32, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ if(u32 == (1u << FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) { decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->private_->client_data); @@ -1399,24 +1409,24 @@ FLAC__bool stream_decoder_read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsig subframe->qlp_coeff_precision = u32+1; /* read qlp shift */ - if(!FLAC__bitbuffer_read_raw_int32(&decoder->private_->input, &i32, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ subframe->quantization_level = i32; /* read quantized lp coefficiencts */ for(u = 0; u < order; u++) { - if(!FLAC__bitbuffer_read_raw_int32(&decoder->private_->input, &i32, subframe->qlp_coeff_precision, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, subframe->qlp_coeff_precision, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ subframe->qlp_coeff[u] = i32; } /* read entropy coding method info */ - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ subframe->entropy_coding_method.type = u32; switch(subframe->entropy_coding_method.type) { case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ subframe->entropy_coding_method.data.partitioned_rice.order = u32; break; @@ -1456,7 +1466,7 @@ FLAC__bool stream_decoder_read_subframe_verbatim_(FLAC__StreamDecoder *decoder, subframe->data = residual; for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { - if(!FLAC__bitbuffer_read_raw_int32(&decoder->private_->input, &x, bps, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &x, bps, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ residual[i] = x; } @@ -1478,27 +1488,27 @@ FLAC__bool stream_decoder_read_residual_partitioned_rice_(FLAC__StreamDecoder *d sample = 0; for(partition = 0; partition < partitions; partition++) { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ partitioned_rice->parameters[partition] = rice_parameter; if(rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) { #ifdef FLAC__SYMMETRIC_RICE - if(!FLAC__bitbuffer_read_symmetric_rice_signed(&decoder->private_->input, &i, rice_parameter, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_symmetric_rice_signed(decoder->private_->input, &i, rice_parameter, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ #else - if(!FLAC__bitbuffer_read_rice_signed(&decoder->private_->input, &i, rice_parameter, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_rice_signed(decoder->private_->input, &i, rice_parameter, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ #endif residual[sample] = i; } } else { - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ partitioned_rice->raw_bits[partition] = rice_parameter; for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) { - if(!FLAC__bitbuffer_read_raw_int32(&decoder->private_->input, &i, rice_parameter, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i, rice_parameter, read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ residual[sample] = i; } @@ -1510,9 +1520,9 @@ FLAC__bool stream_decoder_read_residual_partitioned_rice_(FLAC__StreamDecoder *d FLAC__bool stream_decoder_read_zero_padding_(FLAC__StreamDecoder *decoder) { - if(decoder->private_->input.consumed_bits != 0) { + if(!FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)) { FLAC__uint32 zero = 0; - if(!FLAC__bitbuffer_read_raw_uint32(&decoder->private_->input, &zero, 8-decoder->private_->input.consumed_bits, read_callback_, decoder)) + if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &zero, FLAC__bitbuffer_bits_left_for_byte_alignment(decoder->private_->input), read_callback_, decoder)) return false; /* the read_callback_ sets the state for us */ if(zero != 0) { decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->private_->client_data); @@ -1526,6 +1536,7 @@ FLAC__bool read_callback_(FLAC__byte buffer[], unsigned *bytes, void *client_dat { FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder *)client_data; FLAC__StreamDecoderReadStatus status; + status = decoder->private_->read_callback(decoder, buffer, bytes, decoder->private_->client_data); if(status == FLAC__STREAM_DECODER_READ_END_OF_STREAM) decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c index 200f67dc..c0012fde 100644 --- a/src/libFLAC/stream_encoder.c +++ b/src/libFLAC/stream_encoder.c @@ -97,7 +97,7 @@ typedef struct FLAC__StreamEncoderPrivate { FLAC__uint32 *abs_residual; /* workspace where abs(candidate residual) is stored */ FLAC__uint64 *abs_residual_partition_sums; /* workspace where the sum of abs(candidate residual) for each partition is stored */ unsigned *raw_bits_per_partition; /* workspace where the sum of silog2(candidate residual) for each partition is stored */ - FLAC__BitBuffer frame; /* the current frame being worked on */ + FLAC__BitBuffer *frame; /* the current frame being worked on */ double loose_mid_side_stereo_frames_exact; /* exact number of frames the encoder will use before trying both independent and mid/side frames again */ unsigned loose_mid_side_stereo_frames; /* rounded number of frames the encoder will use before trying both independent and mid/side frames again */ unsigned loose_mid_side_stereo_frame_count; /* number of frames using the current channel assignment */ @@ -195,6 +195,13 @@ FLAC__StreamEncoder *FLAC__stream_encoder_new() free(encoder); return 0; } + encoder->private_->frame = FLAC__bitbuffer_new(); + if(encoder->private_->frame == 0) { + free(encoder->private_); + free(encoder->protected_); + free(encoder); + return 0; + } encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; @@ -230,7 +237,9 @@ void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder) FLAC__ASSERT(encoder != 0); FLAC__ASSERT(encoder->protected_ != 0); FLAC__ASSERT(encoder->private_ != 0); + FLAC__ASSERT(encoder->private_->frame != 0); + FLAC__bitbuffer_delete(encoder->private_->frame); free(encoder->private_); free(encoder->protected_); free(encoder); @@ -421,15 +430,14 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder) /* the above function sets the state for us in case of an error */ return encoder->protected_->state; } - FLAC__bitbuffer_init(&encoder->private_->frame); + + if(!FLAC__bitbuffer_init(encoder->private_->frame)) + return encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; /* * write the stream header */ - - if(!FLAC__bitbuffer_clear(&encoder->private_->frame)) - return encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; - if(!FLAC__bitbuffer_write_raw_uint32(&encoder->private_->frame, FLAC__STREAM_SYNC, FLAC__STREAM_SYNC_LEN)) + if(!FLAC__bitbuffer_write_raw_uint32(encoder->private_->frame, FLAC__STREAM_SYNC, FLAC__STREAM_SYNC_LEN)) return encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; encoder->private_->metadata.type = FLAC__METADATA_TYPE_STREAMINFO; @@ -445,7 +453,7 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder) encoder->private_->metadata.data.stream_info.total_samples = encoder->protected_->total_samples_estimate; /* we will replace this later with the real total */ memset(encoder->private_->metadata.data.stream_info.md5sum, 0, 16); /* we don't know this yet; have to fill it in later */ MD5Init(&encoder->private_->md5context); - if(!FLAC__add_metadata_block(&encoder->private_->metadata, &encoder->private_->frame)) + if(!FLAC__add_metadata_block(&encoder->private_->metadata, encoder->private_->frame)) return encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; if(0 != encoder->protected_->seek_table) { @@ -455,7 +463,7 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder) seek_table_block.is_last = (encoder->protected_->padding == 0 && encoder->protected_->last_metadata_is_last); seek_table_block.length = encoder->protected_->seek_table->num_points * FLAC__STREAM_METADATA_SEEKPOINT_LEN; seek_table_block.data.seek_table = *encoder->protected_->seek_table; - if(!FLAC__add_metadata_block(&seek_table_block, &encoder->private_->frame)) + if(!FLAC__add_metadata_block(&seek_table_block, encoder->private_->frame)) return encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; } @@ -464,14 +472,22 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder) padding_block.type = FLAC__METADATA_TYPE_PADDING; padding_block.is_last = encoder->protected_->last_metadata_is_last; padding_block.length = encoder->protected_->padding; - if(!FLAC__add_metadata_block(&padding_block, &encoder->private_->frame)) + if(!FLAC__add_metadata_block(&padding_block, encoder->private_->frame)) return encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; } - FLAC__ASSERT(encoder->private_->frame.bits == 0); /* assert that we're byte-aligned before writing */ - FLAC__ASSERT(encoder->private_->frame.total_consumed_bits == 0); /* assert that no reading of the buffer was done */ - if(encoder->private_->write_callback(encoder, encoder->private_->frame.buffer, encoder->private_->frame.bytes, 0, encoder->private_->current_frame_number, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_OK) - return encoder->protected_->state = FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_WRITING; + FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(encoder->private_->frame)); + { + FLAC__byte *buffer; + unsigned bytes; + + FLAC__bitbuffer_get_buffer(encoder->private_->frame, &buffer, &bytes); + + if(encoder->private_->write_callback(encoder, buffer, bytes, 0, encoder->private_->current_frame_number, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_OK) + return encoder->protected_->state = FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_WRITING; + + FLAC__bitbuffer_release_buffer(encoder->private_->frame); + } /* now that the metadata block is written, we can init this to an absurdly-high value... */ encoder->private_->metadata.data.stream_info.min_framesize = (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN) - 1; @@ -542,7 +558,7 @@ void FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder) free(encoder->private_->raw_bits_per_partition_unaligned); encoder->private_->raw_bits_per_partition_unaligned = 0; } - FLAC__bitbuffer_free(&encoder->private_->frame); + FLAC__bitbuffer_free(encoder->private_->frame); encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; } @@ -973,6 +989,9 @@ FLAC__bool stream_encoder_resize_buffers_(FLAC__StreamEncoder *encoder, unsigned FLAC__bool stream_encoder_process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame) { + const FLAC__byte *buffer; + unsigned bytes; + FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); /* @@ -995,7 +1014,7 @@ FLAC__bool stream_encoder_process_frame_(FLAC__StreamEncoder *encoder, FLAC__boo /* * Zero-pad the frame to a byte_boundary */ - if(!FLAC__bitbuffer_zero_pad_to_byte_boundary(&encoder->private_->frame)) { + if(!FLAC__bitbuffer_zero_pad_to_byte_boundary(encoder->private_->frame)) { encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1003,17 +1022,18 @@ FLAC__bool stream_encoder_process_frame_(FLAC__StreamEncoder *encoder, FLAC__boo /* * CRC-16 the whole thing */ - FLAC__ASSERT(encoder->private_->frame.bits == 0); /* assert that we're byte-aligned */ - FLAC__ASSERT(encoder->private_->frame.total_consumed_bits == 0); /* assert that no reading of the buffer was done */ - FLAC__bitbuffer_write_raw_uint32(&encoder->private_->frame, FLAC__crc16(encoder->private_->frame.buffer, encoder->private_->frame.bytes), FLAC__FRAME_FOOTER_CRC_LEN); + FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(encoder->private_->frame)); + FLAC__bitbuffer_write_raw_uint32(encoder->private_->frame, FLAC__bitbuffer_get_write_crc16(encoder->private_->frame), FLAC__FRAME_FOOTER_CRC_LEN); /* * Write it */ - if(encoder->private_->write_callback(encoder, encoder->private_->frame.buffer, encoder->private_->frame.bytes, encoder->protected_->blocksize, encoder->private_->current_frame_number, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_OK) { + FLAC__bitbuffer_get_buffer(encoder->private_->frame, &buffer, &bytes); + if(encoder->private_->write_callback(encoder, buffer, bytes, encoder->protected_->blocksize, encoder->private_->current_frame_number, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_OK) { encoder->protected_->state = FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_WRITING; return false; } + FLAC__bitbuffer_release_buffer(encoder->private_->frame); /* * Get ready for the next frame @@ -1021,8 +1041,8 @@ FLAC__bool stream_encoder_process_frame_(FLAC__StreamEncoder *encoder, FLAC__boo encoder->private_->current_sample_number = 0; encoder->private_->current_frame_number++; encoder->private_->metadata.data.stream_info.total_samples += (FLAC__uint64)encoder->protected_->blocksize; - encoder->private_->metadata.data.stream_info.min_framesize = min(encoder->private_->frame.bytes, encoder->private_->metadata.data.stream_info.min_framesize); - encoder->private_->metadata.data.stream_info.max_framesize = max(encoder->private_->frame.bytes, encoder->private_->metadata.data.stream_info.max_framesize); + encoder->private_->metadata.data.stream_info.min_framesize = min(bytes, encoder->private_->metadata.data.stream_info.min_framesize); + encoder->private_->metadata.data.stream_info.max_framesize = max(bytes, encoder->private_->metadata.data.stream_info.max_framesize); return true; } @@ -1054,7 +1074,7 @@ FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC_ /* * Setup the frame */ - if(!FLAC__bitbuffer_clear(&encoder->private_->frame)) { + if(!FLAC__bitbuffer_clear(encoder->private_->frame)) { encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1171,7 +1191,7 @@ FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC_ frame_header.channel_assignment = channel_assignment; - if(!FLAC__frame_add_header(&frame_header, encoder->protected_->streamable_subset, is_last_frame, &encoder->private_->frame)) { + if(!FLAC__frame_add_header(&frame_header, encoder->protected_->streamable_subset, is_last_frame, encoder->private_->frame)) { encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; return false; } @@ -1219,19 +1239,19 @@ FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC_ } /* note that encoder_add_subframe_ sets the state for us in case of an error */ - if(!stream_encoder_add_subframe_(encoder, &frame_header, left_bps , left_subframe , &encoder->private_->frame)) + if(!stream_encoder_add_subframe_(encoder, &frame_header, left_bps , left_subframe , encoder->private_->frame)) return false; - if(!stream_encoder_add_subframe_(encoder, &frame_header, right_bps, right_subframe, &encoder->private_->frame)) + if(!stream_encoder_add_subframe_(encoder, &frame_header, right_bps, right_subframe, encoder->private_->frame)) return false; } else { - if(!FLAC__frame_add_header(&frame_header, encoder->protected_->streamable_subset, is_last_frame, &encoder->private_->frame)) { + if(!FLAC__frame_add_header(&frame_header, encoder->protected_->streamable_subset, is_last_frame, encoder->private_->frame)) { encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; return false; } for(channel = 0; channel < encoder->protected_->channels; channel++) { - if(!stream_encoder_add_subframe_(encoder, &frame_header, encoder->private_->subframe_bps[channel], &encoder->private_->subframe_workspace[channel][encoder->private_->best_subframe[channel]], &encoder->private_->frame)) { + if(!stream_encoder_add_subframe_(encoder, &frame_header, encoder->private_->subframe_bps[channel], &encoder->private_->subframe_workspace[channel][encoder->private_->best_subframe[channel]], encoder->private_->frame)) { /* the above function sets the state for us in case of an error */ return false; } diff --git a/src/libFLAC/stream_encoder_framing.c b/src/libFLAC/stream_encoder_framing.c index 243ff1f9..8e03e82b 100644 --- a/src/libFLAC/stream_encoder_framing.c +++ b/src/libFLAC/stream_encoder_framing.c @@ -114,12 +114,9 @@ FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetaData *metadata, FLAC__ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__bool streamable_subset, FLAC__bool is_last_block, FLAC__BitBuffer *bb) { - unsigned u, crc8_start, blocksize_hint, sample_rate_hint; - FLAC__byte crc8; + unsigned u, blocksize_hint, sample_rate_hint; - FLAC__ASSERT(bb->bits == 0); /* assert that we're byte-aligned before writing */ - - crc8_start = bb->bytes; + FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(bb)); if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__FRAME_HEADER_SYNC, FLAC__FRAME_HEADER_SYNC_LEN)) return false; @@ -246,10 +243,7 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__bool st } /* write the CRC */ - FLAC__ASSERT(bb->buffer[crc8_start] == 0xff); /* MAGIC NUMBER for the first byte of the sync code */ - FLAC__ASSERT(bb->bits == 0); /* assert that we're byte-aligned */ - crc8 = FLAC__crc8(bb->buffer+crc8_start, bb->bytes-crc8_start); - if(!FLAC__bitbuffer_write_raw_uint32(bb, crc8, FLAC__FRAME_HEADER_CRC_LEN)) + if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__bitbuffer_get_write_crc8(bb), FLAC__FRAME_HEADER_CRC_LEN)) return false; return true;