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

📄 bitstr.c

📁 mp3解码源代码
💻 C
字号:
/****************************************************************************//* *	bitstr.c -- BitStream files handling * *	Author  :   St閜hane TAVENARD * *	(C) Copyright 1997-1998 St閜hane TAVENARD *	    All Rights Reserved * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License as published by *	the Free Software Foundation; either version 2 of the License, or *	(at your option) any later version. *	 *	This program is distributed in the hope that it will be useful, *	but WITHOUT ANY WARRANTY; without even the implied warranty of *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *	GNU General Public License for more details. *	 *	You should have received a copy of the GNU General Public License *	along with this program; if not, write to the Free Software *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//****************************************************************************/#include "defs.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "bitstr.h"/****************************************************************************//* *	Default file I/O functions. */static long def_open(char *stream_name, long buffer_size, long *stream_size){	FILE *file_ptr;	file_ptr = fopen(stream_name, "rb");	if ((file_ptr) && (buffer_size > 0))		setvbuf(file_ptr, NULL, _IOFBF, buffer_size);	*stream_size = 0;	if (file_ptr) {		if (!fseek(file_ptr, 0, SEEK_END)) {			*stream_size = ftell(file_ptr);			fseek(file_ptr, 0, SEEK_SET);		}	}	return((long) file_ptr);}/****************************************************************************/static void def_close( long handle ){	if (handle)		fclose((FILE *) handle);}/****************************************************************************/static long def_read(long handle, void *buffer, long num_bytes){	long read_size = -1;	if (handle)		read_size = fread(buffer, 1, num_bytes, (FILE *) handle);	return(read_size);}/****************************************************************************/static int def_seek(long handle, long abs_byte_seek_pos){	int err = 0;	if (handle)		err = fseek((FILE *) handle, abs_byte_seek_pos, SEEK_SET);	return(err);}/****************************************************************************//* *	End of default file I/O functions. */void BSTR_close(BITSTREAM *bitstream){	if (bitstream) {		if (bitstream->buffer)			//ffree(bitstream->buffer);			free(bitstream->buffer);		if (bitstream->file_handle) {			if (bitstream->baccess.close)				bitstream->baccess.close(bitstream->file_handle);		}		free(bitstream);	}}/****************************************************************************//* *	Open a BitStream for read *	Inputs: *		bs_access = specify how to access to the bitstream (functions) *		if NULL, use standard file i/o *		filename = name of the bitstream *		buffer_size = # of bytes read for each access */BITSTREAM *BSTR_open(BITSTREAM_ACCESS *bs_access, char *filename, long buffer_size){	BITSTREAM *bs;	bs = (BITSTREAM *) malloc(sizeof(BITSTREAM));	if (!bs)		return NULL;	memset(bs, 0, sizeof(BITSTREAM));	if (bs_access) {		bs->baccess = *bs_access;	} else {		bs->baccess.open = def_open;		bs->baccess.close = def_close;		bs->baccess.read = def_read;		bs->baccess.seek = def_seek;	}	// Buffer size must be 4-bytes aligned	buffer_size &= ~3;		bs->buffer = malloc(buffer_size);	//bs->buffer = fmalloc(buffer_size);	if (!bs->buffer) {		BSTR_close(bs);		return(NULL);	}	bs->buffer_size = buffer_size;	if (!bs->baccess.open) {		BSTR_close(bs);		return(NULL);	}	bs->file_handle = bs->baccess.open(filename, buffer_size, &bs->bitstream_size);	if (!bs->file_handle) {		BSTR_close(bs);		return(NULL);	}	bs->buffer_ptr = bs->buffer; // #10	bs->buffer_len = 0; // #10	bs->buffer_pos = 0; // #10	return(bs);}/****************************************************************************/static int fill_buffer(BITSTREAM *bitstream){#ifdef BSTR_MSBF	bitstream->buffer[0] = 0;#else	bitstream->buffer[1] = bitstream->buffer[2] = bitstream->buffer[3] = 0;#endif	if (bitstream->end_of_stream)		return 1;	if (!bitstream->baccess.read)		return 1;	bitstream->remain_bytes = bitstream->baccess.read(		bitstream->file_handle, bitstream->buffer,		bitstream->buffer_size );	bitstream->buffer_len = bitstream->remain_bytes; // #10	bitstream->buffer_pos += (long)bitstream->buffer_ptr - (long)bitstream->buffer; // #10	bitstream->buffer_ptr = bitstream->buffer;	bitstream->cache_size = 0;	if (bitstream->remain_bytes <= 0) {		bitstream->end_of_stream = 1;		return(1); /* empty */	} else if (bitstream->remain_bytes < 4) {		bitstream->remain_bytes = 4;	}	return(0);}/****************************************************************************/#ifdef BSTR_MSBF#define FILL_CACHE(b) { \	if (b->remain_bytes <= 0) \		fill_buffer(b); \	b->remain_bytes -= 4; \	b->bit_cache = *b->buffer_ptr++; \}#else#define FILL_CACHE(b) { \	if (b->remain_bytes <= 0) \		fill_buffer(b); \	b->remain_bytes -= 4; \	b->bit_cache = (((unsigned long)b->buffer_ptr[0])<<24) | \		(((unsigned long)b->buffer_ptr[1])<<16)| \		(((unsigned long)b->buffer_ptr[2])<<8) | \		((unsigned long)b->buffer_ptr[3]); b->buffer_ptr+=4; \}#endif/****************************************************************************/int BSTR_seek(BITSTREAM *bitstream, long seek_byte_pos){	int err;	// Optimize seek if inside current buffer	long offset_pos = seek_byte_pos - bitstream->buffer_pos;	if (bitstream->buffer_len > 0) {		if ((offset_pos >= 0) && (offset_pos < bitstream->buffer_len)) {			// Use current buffer			long remain = offset_pos & 3; // Remainder			offset_pos &= ~3; // align to 32 bit			bitstream->remain_bytes = bitstream->buffer_len - offset_pos;#ifdef BSTR_MSBF			bitstream->buffer_ptr = bitstream->buffer + (offset_pos>>2);#else			bitstream->buffer_ptr = bitstream->buffer + offset_pos;#endif         		bitstream->cache_size = 0;         		bitstream->bits = 0;         		FILL_CACHE(bitstream);         		bitstream->cache_size = 32;         		// Skip remainder         		while(remain--)				BSTR_read_byte(bitstream);         		return(0);		}	}	if (bitstream->baccess.seek) {		err = bitstream->baccess.seek(bitstream->file_handle, seek_byte_pos);		if (err)			return(err);	}	bitstream->remain_bytes = 0;	bitstream->buffer_ptr = bitstream->buffer;	bitstream->end_of_stream = 0;	bitstream->cache_size = 0;	bitstream->bits = 0;	bitstream->buffer_len = 0; // #10	bitstream->buffer_pos = seek_byte_pos; // #10	return(0);}/****************************************************************************/long BSTR_pos(BITSTREAM *bitstream){	return(bitstream->buffer_pos + (long)bitstream->buffer_ptr -		(long)bitstream->buffer - (bitstream->cache_size >> 3));}/****************************************************************************/unsigned long BSTR_read_byte(BITSTREAM *b){	if (b->cache_size < 8) {		FILL_CACHE(b);		b->cache_size = 32;	}	if (b->cache_size & 7) { // Not aligned		b->bit_cache <<= b->cache_size & 7;		b->cache_size &= ~7;	}	b->bits = b->bit_cache >> 24;	b->bit_cache <<= 8;	b->cache_size -= 8;	return(b->bits);}/****************************************************************************/unsigned int BSTR_read_bytes(BITSTREAM *b, unsigned int count, char *buffer){	if (count == 0)		return 0;	if (b->cache_size & 7) { // Not aligned		b->bit_cache <<= b->cache_size & 7;		b->cache_size &= ~7;	}	while ((b->cache_size > 0) && (count-- > 0 )) {		*buffer++ = b->bit_cache >> 24;		b->bit_cache <<= 8;		b->cache_size -= 8;	}	while (count > 3) {		int to_fill;		if (b->remain_bytes <= 0) {			if (fill_buffer(b))				return 0;		}		to_fill = count & ~3; // Important 4-bytes aligned		// Note: b->remain_bytes is always 4-bytes aligned		if (to_fill > b->remain_bytes)			to_fill = b->remain_bytes;				memcpy(buffer, b->buffer_ptr, to_fill);			count -= to_fill;			buffer += to_fill;			b->remain_bytes -= to_fill;#ifdef BSTR_MSBF			// This is a INT32 pointer here.			b->buffer_ptr += to_fill>>2;#else			b->buffer_ptr += to_fill;#endif		}	// Not 4 bytes aligned -> use cached read	while (count > 0) {		*buffer++ = BSTR_read_byte(b);		count--;	}	b->bits = (unsigned int)*(buffer-1);	return(1);}/****************************************************************************/unsigned long BSTR_read_bit_cache(BITSTREAM *b){	unsigned long bits;	FILL_CACHE(b);	b->cache_size = 31;	bits = (b->bit_cache & 0x80000000) ? 1 : 0;	b->bit_cache <<= 1;	return(bits);}/****************************************************************************/unsigned long BSTR_read_bits_cache(BITSTREAM *b, unsigned int count){	unsigned long bits;	bits = b->bit_cache >> (32 - count);	count -= b->cache_size;	FILL_CACHE(b);	b->cache_size = 32 - count;	bits |= b->bit_cache >> (32 - count);	b->bit_cache <<= count;	return(bits);}/****************************************************************************/

⌨️ 快捷键说明

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