⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitbuffer.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 5 页
字号:
		free(bb->buffer);
	bb->buffer = 0;
	bb->capacity = 0;
	bb->blurbs = bb->bits = bb->total_bits = 0;
	bb->consumed_blurbs = bb->consumed_bits = bb->total_consumed_bits = 0;
}

FLAC__bool FLAC__bitbuffer_clear(FLAC__BitBuffer *bb)
{
	if(bb->buffer == 0) {
		bb->capacity = FLAC__BITBUFFER_DEFAULT_CAPACITY;
		bb->buffer = (FLAC__blurb*)calloc(bb->capacity, sizeof(FLAC__blurb));
		if(bb->buffer == 0)
			return false;
	}
	else {
		memset(bb->buffer, 0, bb->blurbs + (bb->bits?1:0));
	}
	bb->blurbs = bb->bits = bb->total_bits = 0;
	bb->consumed_blurbs = bb->consumed_bits = bb->total_consumed_bits = 0;
	return true;
}

FLAC__bool FLAC__bitbuffer_clone(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src)
{
	FLAC__ASSERT(0 != dest);
	FLAC__ASSERT(0 != dest->buffer);
	FLAC__ASSERT(0 != src);
	FLAC__ASSERT(0 != src->buffer);

	if(dest->capacity < src->capacity)
		if(!bitbuffer_resize_(dest, src->capacity))
			return false;
	memcpy(dest->buffer, src->buffer, sizeof(FLAC__blurb)*min(src->capacity, src->blurbs+1));
	dest->blurbs = src->blurbs;
	dest->bits = src->bits;
	dest->total_bits = src->total_bits;
	dest->consumed_blurbs = src->consumed_blurbs;
	dest->consumed_bits = src->consumed_bits;
	dest->total_consumed_bits = src->total_consumed_bits;
	dest->read_crc16 = src->read_crc16;
	return true;
}

void FLAC__bitbuffer_reset_read_crc16(FLAC__BitBuffer *bb, FLAC__uint16 seed)
{
	FLAC__ASSERT(0 != bb);
	FLAC__ASSERT(0 != bb->buffer);
	FLAC__ASSERT((bb->consumed_bits & 7) == 0);

	bb->read_crc16 = seed;
#if FLAC__BITS_PER_BLURB == 8
	/* no need to do anything */
#elif FLAC__BITS_PER_BLURB == 32
	bb->crc16_align = bb->consumed_bits;
#else
	FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
}

FLAC__uint16 FLAC__bitbuffer_get_read_crc16(FLAC__BitBuffer *bb)
{
	FLAC__ASSERT(0 != bb);
	FLAC__ASSERT(0 != bb->buffer);
	FLAC__ASSERT((bb->bits & 7) == 0);
	FLAC__ASSERT((bb->consumed_bits & 7) == 0);

#if FLAC__BITS_PER_BLURB == 8
	/* no need to do anything */
#elif FLAC__BITS_PER_BLURB == 32
	/*@@@ BUG: even though this probably can't happen with FLAC, need to fix the case where we are called here for the very first blurb and crc16_align is > 0 */
	if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) {
		if(bb->consumed_bits == 8) {
			const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
			FLAC__CRC16_UPDATE(blurb >> 24, bb->read_crc16);
		}
		else if(bb->consumed_bits == 16) {
			const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
			FLAC__CRC16_UPDATE(blurb >> 24, bb->read_crc16);
			FLAC__CRC16_UPDATE((blurb >> 16) & 0xff, bb->read_crc16);
		}
		else if(bb->consumed_bits == 24) {
			const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
			FLAC__CRC16_UPDATE(blurb >> 24, bb->read_crc16);
			FLAC__CRC16_UPDATE((blurb >> 16) & 0xff, bb->read_crc16);
			FLAC__CRC16_UPDATE((blurb >> 8) & 0xff, bb->read_crc16);
		}
	}
	else {
		if(bb->consumed_bits == 8) {
			const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
			FLAC__CRC16_UPDATE(blurb >> (bb->bits-8), bb->read_crc16);
		}
		else if(bb->consumed_bits == 16) {
			const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
			FLAC__CRC16_UPDATE(blurb >> (bb->bits-8), bb->read_crc16);
			FLAC__CRC16_UPDATE((blurb >> (bb->bits-16)) & 0xff, bb->read_crc16);
		}
		else if(bb->consumed_bits == 24) {
			const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs];
			FLAC__CRC16_UPDATE(blurb >> (bb->bits-8), bb->read_crc16);
			FLAC__CRC16_UPDATE((blurb >> (bb->bits-16)) & 0xff, bb->read_crc16);
			FLAC__CRC16_UPDATE((blurb >> (bb->bits-24)) & 0xff, bb->read_crc16);
		}
	}
	bb->crc16_align = bb->consumed_bits;
#else
	FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
	return bb->read_crc16;
}

FLAC__uint16 FLAC__bitbuffer_get_write_crc16(const FLAC__BitBuffer *bb)
{
	FLAC__ASSERT((bb->bits & 7) == 0); /* assert that we're byte-aligned */

#if FLAC__BITS_PER_BLURB == 8
	return FLAC__crc16(bb->buffer, bb->blurbs);
#elif FLAC__BITS_PER_BLURB == 32
	/* @@@ WATCHOUT: code currently only works for big-endian: */
	return FLAC__crc16((FLAC__byte*)(bb->buffer), (bb->blurbs * FLAC__BYTES_PER_BLURB) + (bb->bits >> 3));
#else
	FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
}

FLAC__byte FLAC__bitbuffer_get_write_crc8(const FLAC__BitBuffer *bb)
{
	FLAC__ASSERT(0 != bb);
	FLAC__ASSERT((bb->bits & 7) == 0); /* assert that we're byte-aligned */
	FLAC__ASSERT(bb->buffer[0] == 0xff); /* MAGIC NUMBER for the first byte of the sync code */
#if FLAC__BITS_PER_BLURB == 8
	return FLAC__crc8(bb->buffer, bb->blurbs);
#elif FLAC__BITS_PER_BLURB == 32
	/* @@@ WATCHOUT: code currently only works for big-endian: */
	return FLAC__crc8((FLAC__byte*)(bb->buffer), (bb->blurbs * FLAC__BYTES_PER_BLURB) + (bb->bits >> 3));
#else
	FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
}

FLAC__bool FLAC__bitbuffer_is_byte_aligned(const FLAC__BitBuffer *bb)
{
	return ((bb->bits & 7) == 0);
}

FLAC__bool FLAC__bitbuffer_is_consumed_byte_aligned(const FLAC__BitBuffer *bb)
{
	return ((bb->consumed_bits & 7) == 0);
}

unsigned FLAC__bitbuffer_bits_left_for_byte_alignment(const FLAC__BitBuffer *bb)
{
	return 8 - (bb->consumed_bits & 7);
}

unsigned FLAC__bitbuffer_get_input_bytes_unconsumed(const FLAC__BitBuffer *bb)
{
	FLAC__ASSERT((bb->consumed_bits & 7) == 0 && (bb->bits & 7) == 0);
	return (bb->total_bits - bb->total_consumed_bits) >> 3;
}

void FLAC__bitbuffer_get_buffer(FLAC__BitBuffer *bb, const FLAC__byte **buffer, unsigned *bytes)
{
	FLAC__ASSERT((bb->consumed_bits & 7) == 0 && (bb->bits & 7) == 0);
#if FLAC__BITS_PER_BLURB == 8
	*buffer = bb->buffer + bb->consumed_blurbs;
	*bytes = bb->blurbs - bb->consumed_blurbs;
#elif FLAC__BITS_PER_BLURB == 32
	/* @@@ WATCHOUT: code currently only works for big-endian: */
	*buffer = (FLAC__byte*)(bb->buffer + bb->consumed_blurbs) + (bb->consumed_bits >> 3);
	*bytes = (bb->total_bits - bb->total_consumed_bits) >> 3;
#else
	FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
}

void FLAC__bitbuffer_release_buffer(FLAC__BitBuffer *bb)
{
#if FLAC__BITS_PER_BLURB == 8
	(void)bb;
#elif FLAC__BITS_PER_BLURB == 32
	/* @@@ WATCHOUT: code currently only works for big-endian: */
	(void)bb;
#else
	FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */
#endif
}

FLAC__bool FLAC__bitbuffer_write_zeroes(FLAC__BitBuffer *bb, unsigned bits)
{
	unsigned n;

	FLAC__ASSERT(0 != bb);
	FLAC__ASSERT(0 != bb->buffer);

	if(bits == 0)
		return true;
	if(!bitbuffer_ensure_size_(bb, bits))
		return false;
	bb->total_bits += bits;
	while(bits > 0) {
		n = min(FLAC__BITS_PER_BLURB - bb->bits, bits);
		bb->buffer[bb->blurbs] <<= n;
		bits -= n;
		bb->bits += n;
		if(bb->bits == FLAC__BITS_PER_BLURB) {
			bb->blurbs++;
			bb->bits = 0;
		}
	}
	return true;
}

FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, FLAC__uint32 val, unsigned bits)
{
	unsigned n, k;

	FLAC__ASSERT(0 != bb);
	FLAC__ASSERT(0 != bb->buffer);

	FLAC__ASSERT(bits <= 32);
	if(bits == 0)
		return true;
	/* inline the size check so we don't incure a function call unnecessarily */
	if(FLAC__BLURBS_TO_BITS(bb->capacity) < bb->total_bits + bits) {
		if(!bitbuffer_ensure_size_(bb, bits))
			return false;
	}

	/* zero-out unused bits; WATCHOUT: other code relies on this, so this needs to stay */
	if(bits < 32) /* @@@ gcc seems to require this because the following line causes incorrect results when bits==32; investigate */
		val &= (~(0xffffffff << bits)); /* zero-out unused bits */

	bb->total_bits += bits;
	while(bits > 0) {
		n = FLAC__BITS_PER_BLURB - bb->bits;
		if(n == FLAC__BITS_PER_BLURB) { /* i.e. bb->bits == 0 */
			if(bits < FLAC__BITS_PER_BLURB) {
				bb->buffer[bb->blurbs] = (FLAC__blurb)val;
				bb->bits = bits;
				break;
			}
			else if(bits == FLAC__BITS_PER_BLURB) {
				bb->buffer[bb->blurbs++] = (FLAC__blurb)val;
				break;
			}
			else {
				k = bits - FLAC__BITS_PER_BLURB;
				bb->buffer[bb->blurbs++] = (FLAC__blurb)(val >> k);
				/* we know k < 32 so no need to protect against the gcc bug mentioned above */
				val &= (~(0xffffffff << k));
				bits -= FLAC__BITS_PER_BLURB;
			}
		}
		else if(bits <= n) {
			bb->buffer[bb->blurbs] <<= bits;
			bb->buffer[bb->blurbs] |= val;
			if(bits == n) {
				bb->blurbs++;
				bb->bits = 0;
			}
			else
				bb->bits += bits;
			break;
		}
		else {
			k = bits - n;
			bb->buffer[bb->blurbs] <<= n;
			bb->buffer[bb->blurbs] |= (val >> k);
			/* we know n > 0 so k < 32 so no need to protect against the gcc bug mentioned above */
			val &= (~(0xffffffff << k));
			bits -= n;
			bb->blurbs++;
			bb->bits = 0;
		}
	}

	return true;
}

FLAC__bool FLAC__bitbuffer_write_raw_int32(FLAC__BitBuffer *bb, FLAC__int32 val, unsigned bits)
{
	return FLAC__bitbuffer_write_raw_uint32(bb, (FLAC__uint32)val, bits);
}

FLAC__bool FLAC__bitbuffer_write_raw_uint64(FLAC__BitBuffer *bb, FLAC__uint64 val, unsigned bits)
{
	static const FLAC__uint64 mask[] = {
		0,
		FLAC__U64L(0x0000000000000001), FLAC__U64L(0x0000000000000003), FLAC__U64L(0x0000000000000007), FLAC__U64L(0x000000000000000F),
		FLAC__U64L(0x000000000000001F), FLAC__U64L(0x000000000000003F), FLAC__U64L(0x000000000000007F), FLAC__U64L(0x00000000000000FF),
		FLAC__U64L(0x00000000000001FF), FLAC__U64L(0x00000000000003FF), FLAC__U64L(0x00000000000007FF), FLAC__U64L(0x0000000000000FFF),
		FLAC__U64L(0x0000000000001FFF), FLAC__U64L(0x0000000000003FFF), FLAC__U64L(0x0000000000007FFF), FLAC__U64L(0x000000000000FFFF),
		FLAC__U64L(0x000000000001FFFF), FLAC__U64L(0x000000000003FFFF), FLAC__U64L(0x000000000007FFFF), FLAC__U64L(0x00000000000FFFFF),
		FLAC__U64L(0x00000000001FFFFF), FLAC__U64L(0x00000000003FFFFF), FLAC__U64L(0x00000000007FFFFF), FLAC__U64L(0x0000000000FFFFFF),
		FLAC__U64L(0x0000000001FFFFFF), FLAC__U64L(0x0000000003FFFFFF), FLAC__U64L(0x0000000007FFFFFF), FLAC__U64L(0x000000000FFFFFFF),
		FLAC__U64L(0x000000001FFFFFFF), FLAC__U64L(0x000000003FFFFFFF), FLAC__U64L(0x000000007FFFFFFF), FLAC__U64L(0x00000000FFFFFFFF),
		FLAC__U64L(0x00000001FFFFFFFF), FLAC__U64L(0x00000003FFFFFFFF), FLAC__U64L(0x00000007FFFFFFFF), FLAC__U64L(0x0000000FFFFFFFFF),
		FLAC__U64L(0x0000001FFFFFFFFF), FLAC__U64L(0x0000003FFFFFFFFF), FLAC__U64L(0x0000007FFFFFFFFF), FLAC__U64L(0x000000FFFFFFFFFF),
		FLAC__U64L(0x000001FFFFFFFFFF), FLAC__U64L(0x000003FFFFFFFFFF), FLAC__U64L(0x000007FFFFFFFFFF), FLAC__U64L(0x00000FFFFFFFFFFF),
		FLAC__U64L(0x00001FFFFFFFFFFF), FLAC__U64L(0x00003FFFFFFFFFFF), FLAC__U64L(0x00007FFFFFFFFFFF), FLAC__U64L(0x0000FFFFFFFFFFFF),
		FLAC__U64L(0x0001FFFFFFFFFFFF), FLAC__U64L(0x0003FFFFFFFFFFFF), FLAC__U64L(0x0007FFFFFFFFFFFF), FLAC__U64L(0x000FFFFFFFFFFFFF),
		FLAC__U64L(0x001FFFFFFFFFFFFF), FLAC__U64L(0x003FFFFFFFFFFFFF), FLAC__U64L(0x007FFFFFFFFFFFFF), FLAC__U64L(0x00FFFFFFFFFFFFFF),
		FLAC__U64L(0x01FFFFFFFFFFFFFF), FLAC__U64L(0x03FFFFFFFFFFFFFF), FLAC__U64L(0x07FFFFFFFFFFFFFF), FLAC__U64L(0x0FFFFFFFFFFFFFFF),
		FLAC__U64L(0x1FFFFFFFFFFFFFFF), FLAC__U64L(0x3FFFFFFFFFFFFFFF), FLAC__U64L(0x7FFFFFFFFFFFFFFF), FLAC__U64L(0xFFFFFFFFFFFFFFFF)
	};
	unsigned n, k;

	FLAC__ASSERT(0 != bb);
	FLAC__ASSERT(0 != bb->buffer);

	FLAC__ASSERT(bits <= 64);
	if(bits == 0)
		return true;
	if(!bitbuffer_ensure_size_(bb, bits))
		return false;
	val &= mask[bits];
	bb->total_bits += bits;
	while(bits > 0) {
		if(bb->bits == 0) {
			if(bits < FLAC__BITS_PER_BLURB) {
				bb->buffer[bb->blurbs] = (FLAC__blurb)val;
				bb->bits = bits;
				break;
			}
			else if(bits == FLAC__BITS_PER_BLURB) {
				bb->buffer[bb->blurbs++] = (FLAC__blurb)val;
				break;
			}
			else {
				k = bits - FLAC__BITS_PER_BLURB;
				bb->buffer[bb->blurbs++] = (FLAC__blurb)(val >> k);
				/* we know k < 64 so no need to protect against the gcc bug mentioned above */
				val &= (~(FLAC__U64L(0xffffffffffffffff) << k));
				bits -= FLAC__BITS_PER_BLURB;
			}
		}
		else {
			n = min(FLAC__BITS_PER_BLURB - bb->bits, bits);
			k = bits - n;
			bb->buffer[bb->blurbs] <<= n;
			bb->buffer[bb->blurbs] |= (val >> k);
			/* we know n > 0 so k < 64 so no need to protect against the gcc bug mentioned above */
			val &= (~(FLAC__U64L(0xffffffffffffffff) << k));
			bits -= n;
			bb->bits += n;
			if(bb->bits == FLAC__BITS_PER_BLURB) {
				bb->blurbs++;
				bb->bits = 0;
			}
		}
	}

	return true;
}

#if 0 /* UNUSED */
FLAC__bool FLAC__bitbuffer_write_raw_int64(FLAC__BitBuffer *bb, FLAC__int64 val, unsigned bits)
{
	return FLAC__bitbuffer_write_raw_uint64(bb, (FLAC__uint64)val, bits);
}
#endif

FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_raw_uint32_little_endian(FLAC__BitBuffer *bb, FLAC__uint32 val)
{
	/* this doesn't need to be that fast as currently it is only used for vorbis comments */

	/* NOTE: we rely on the fact that FLAC__bitbuffer_write_raw_uint32() masks out the unused bits */
	if(!FLAC__bitbuffer_write_raw_uint32(bb, val, 8))
		return false;
	if(!FLAC__bitbuffer_write_raw_uint32(bb, val>>8, 8))
		return false;
	if(!FLAC__bitbuffer_write_raw_uint32(bb, val>>16, 8))
		return false;
	if(!FLAC__bitbuffer_write_raw_uint32(bb, val>>24, 8))
		return false;

	return true;
}

FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_byte_block(FLAC__BitBuffer *bb, const FLAC__byte vals[], unsigned nvals)
{
	unsigned i;

	/* this could be faster but currently we don't need it to be */
	for(i = 0; i < nvals; i++) {
		if(!FLAC__bitbuffer_write_raw_uint32(bb, (FLAC__uint32)(vals[i]), 8))
			return false;
	}

	return true;
}

FLAC__bool FLAC__bitbuffer_write_unary_unsigned(FLAC__BitBuffer *bb, unsigned val)
{
	if(val < 32)
		return FLAC__bitbuffer_write_raw_uint32(bb, 1, ++val);
	else if(val < 64)
		return FLAC__bitbuffer_write_raw_uint64(bb, 1, ++val);
	else {
		if(!FLAC__bitbuffer_write_zeroes(bb, val))
			return false;
		return FLAC__bitbuffer_write_raw_uint32(bb, 1, 1);
	}
}

unsigned FLAC__bitbuffer_rice_bits(int val, unsigned parameter)
{
	unsigned msbs, uval;

	/* fold signed to unsigned */
	if(val < 0)
		/* equivalent to
		 *     (unsigned)(((--val) << 1) - 1);
		 * but without the overflow problem at MININT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -