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

📄 bitstream.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / common tools sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC 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 Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/bitstream.h>/*the default size for new streams allocation...*/#define BS_MEM_BLOCK_ALLOC_SIZE		250/*private types*/enum{	GF_BITSTREAM_FILE_READ = GF_BITSTREAM_WRITE + 1,	GF_BITSTREAM_FILE_WRITE,	/*private mode if we own the buffer*/	GF_BITSTREAM_WRITE_DYN};struct __tag_bitstream{	/*original stream data*/	FILE *stream;	/*original data*/	char *original;	/*the size of our buffer*/	u64 size;	/*current position in BYTES*/	u64 position;	/*the byte readen/written */	u32 current;	/*the number of bits in the current byte*/	u32 nbBits;	/*the bitstream mode*/	u32 bsmode;	void (*EndOfStream)(void *par);	void *par;};GF_EXPORTGF_BitStream *gf_bs_new(char *buffer, u64 BufferSize, u32 mode){	GF_BitStream *tmp;	if ( (buffer && ! BufferSize)) return NULL;	tmp = (GF_BitStream *)malloc(sizeof(GF_BitStream));	if (!tmp) return NULL;	memset(tmp, 0, sizeof(GF_BitStream));	tmp->original = (char*)buffer;	tmp->size = BufferSize;	tmp->position = 0;	tmp->current = 0;	tmp->bsmode = mode;	tmp->stream = NULL;	switch (tmp->bsmode) {	case GF_BITSTREAM_READ:		tmp->nbBits = 8;		tmp->current = 0;		break;	case GF_BITSTREAM_WRITE:		tmp->nbBits = 0;		if (! buffer) {			/*if BufferSize is specified, use it. This is typically used when AvgSize of			some buffers is known, but some exceed it.*/			if (BufferSize) {				tmp->size = BufferSize;			} else {				tmp->size = BS_MEM_BLOCK_ALLOC_SIZE;			}			tmp->original = (char *) malloc(sizeof(char) * ((u32) tmp->size));			if (! tmp->original) {				free(tmp);				return NULL;			}			tmp->bsmode = GF_BITSTREAM_WRITE_DYN;		} else {			tmp->original = (char*)buffer;			tmp->size = BufferSize;		}		break;	default:		/*the stream constructor is not the same...*/		free(tmp);		return NULL;	}	return tmp;}GF_EXPORTGF_BitStream *gf_bs_from_file(FILE *f, u32 mode){	GF_BitStream *tmp;	if (!f) return NULL;	tmp = (GF_BitStream *)malloc(sizeof(GF_BitStream));	if (!tmp) return NULL;	memset(tmp, 0, sizeof(GF_BitStream));	/*switch to internal mode*/	mode = (mode==GF_BITSTREAM_READ) ? GF_BITSTREAM_FILE_READ : GF_BITSTREAM_FILE_WRITE;	tmp->bsmode = mode;	tmp->current = 0;	tmp->nbBits = (mode == GF_BITSTREAM_FILE_READ) ? 8 : 0;	tmp->original = NULL;	tmp->position = 0;	tmp->stream = f;	/*get the size of this file (for read streams)*/	tmp->position = gf_f64_tell(f);	gf_f64_seek(f, 0, SEEK_END);	tmp->size = gf_f64_tell(f);	gf_f64_seek(f, tmp->position, SEEK_SET);	return tmp;}GF_EXPORTvoid gf_bs_del(GF_BitStream *bs){	if (!bs) return;	/*if we are in dynamic mode (alloc done by the bitstream), free the buffer if still present*/	if ((bs->bsmode == GF_BITSTREAM_WRITE_DYN) && bs->original) free(bs->original);	free(bs);}/*returns 1 if aligned wrt current mode, 0 otherwise*/static Bool BS_IsAlign(GF_BitStream *bs){	switch (bs->bsmode) {	case GF_BITSTREAM_READ:	case GF_BITSTREAM_FILE_READ:		return ( (8 == bs->nbBits) ? 1 : 0);	default:		return !bs->nbBits;	}}/*fetch a new byte in the bitstream switch between packets*/static u8 BS_ReadByte(GF_BitStream *bs){	if (bs->bsmode == GF_BITSTREAM_READ) {		if (bs->position == bs->size) {			if (bs->EndOfStream) bs->EndOfStream(bs->par);			return 0;		}		return (u32) bs->original[bs->position++];	}	/*we are in FILE mode, test for end of file*/	if (!feof(bs->stream)) {		bs->position++;		return (u32) fgetc(bs->stream);	}	if (bs->EndOfStream) bs->EndOfStream(bs->par);	return 0;}#define NO_OPTS#ifndef NO_OPTSstatic u32 bit_mask[] = {0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1};static u32 bits_mask[] = {0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F};#endifGF_EXPORTu8 gf_bs_read_bit(GF_BitStream *bs){	if (bs->nbBits == 8) {			bs->current = BS_ReadByte(bs);	 	bs->nbBits = 0;	}#ifdef NO_OPTS	{		s32 ret;		bs->current <<= 1;		bs->nbBits++;		ret = (bs->current & 0x100) >> 8;		return (u8) ret;	}#else	return (u8) (bs->current & bit_mask[bs->nbBits++]) ? 1 : 0;#endif}GF_EXPORTu32 gf_bs_read_int(GF_BitStream *bs, u32 nBits){	u32 ret;#ifndef NO_OPTS	if (nBits + bs->nbBits <= 8) {		bs->nbBits += nBits;        ret = (bs->current >> (8 - bs->nbBits) ) & bits_mask[nBits];		return ret;	}#endif	ret = 0;	while (nBits-- > 0) {		ret <<= 1;		ret |= gf_bs_read_bit(bs);	}	return ret;}GF_EXPORTu32 gf_bs_read_u8(GF_BitStream *bs){	assert(bs->nbBits==8);	return (u32) BS_ReadByte(bs);}GF_EXPORTu32 gf_bs_read_u16(GF_BitStream *bs){	u32 ret;	assert(bs->nbBits==8);	ret = BS_ReadByte(bs); ret<<=8;	ret |= BS_ReadByte(bs);	return ret;}GF_EXPORTu32 gf_bs_read_u24(GF_BitStream *bs){	u32 ret;	assert(bs->nbBits==8);	ret = BS_ReadByte(bs); ret<<=8;	ret |= BS_ReadByte(bs); ret<<=8;	ret |= BS_ReadByte(bs);	return ret;}GF_EXPORTu32 gf_bs_read_u32(GF_BitStream *bs){	u32 ret;	assert(bs->nbBits==8);	ret = BS_ReadByte(bs); ret<<=8;	ret |= BS_ReadByte(bs); ret<<=8;	ret |= BS_ReadByte(bs); ret<<=8;	ret |= BS_ReadByte(bs);	return ret;}GF_EXPORTu64 gf_bs_read_u64(GF_BitStream *bs){	u64 ret;	ret = gf_bs_read_u32(bs); ret<<=32;	ret |= gf_bs_read_u32(bs);	return ret;}GF_EXPORTu64 gf_bs_read_long_int(GF_BitStream *bs, u32 nBits){	u64 ret = 0;	while (nBits-- > 0) {		ret <<= 1;		ret |= gf_bs_read_bit(bs);	}	return ret;}GF_EXPORTFloat gf_bs_read_float(GF_BitStream *bs){		char buf [4] = "\0\0\0";#ifdef NO_OPTS	s32 i;	for (i = 0; i < 32; i++)		buf[3-i/8] |= gf_bs_read_bit(bs) << (7 - i%8);#else	buf[3] = gf_bs_read_int(bs, 8);	buf[2] = gf_bs_read_int(bs, 8);	buf[1] = gf_bs_read_int(bs, 8);	buf[0] = gf_bs_read_int(bs, 8);#endif	return (* (Float *) buf);}GF_EXPORTDouble gf_bs_read_double(GF_BitStream *bs){	char buf [8] = "\0\0\0\0\0\0\0";	s32 i;	for (i = 0; i < 64; i++)		buf[7-i/8] |= gf_bs_read_bit(bs) << (7 - i%8);	return (* (Double *) buf);}GF_EXPORTu32 gf_bs_read_data(GF_BitStream *bs, char *data, u32 nbBytes){	u64 orig = bs->position;	if (bs->position+nbBytes > bs->size) return 0;	if (BS_IsAlign(bs)) {		switch (bs->bsmode) {		case GF_BITSTREAM_READ:			memcpy(data, bs->original + bs->position, nbBytes);			bs->position += nbBytes;			return nbBytes;		case GF_BITSTREAM_FILE_READ:		case GF_BITSTREAM_FILE_WRITE:			fread(data, nbBytes, 1, bs->stream);			bs->position += nbBytes;			return nbBytes;		default:			return 0;		}	}	while (nbBytes-- > 0) {		*data++ = gf_bs_read_int(bs, 8);	}	return (u32) (bs->position - orig);}static void BS_WriteByte(GF_BitStream *bs, u8 val){	/*we don't allow write on READ buffers*/	if ( (bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_FILE_READ) ) return;	if (!bs->original && !bs->stream) return;	/*we are in MEM mode*/	if ( (bs->bsmode == GF_BITSTREAM_WRITE) || (bs->bsmode == GF_BITSTREAM_WRITE_DYN) ) {		if (bs->position == bs->size) {			/*no more space...*/			if (bs->bsmode != GF_BITSTREAM_WRITE_DYN) return;			/*realloc if enough space...*/			if (bs->size > 0xFFFFFFFF) return;			bs->original = (char*)realloc(bs->original, (u32) (bs->size + BS_MEM_BLOCK_ALLOC_SIZE));			if (!bs->original) return;			bs->size += BS_MEM_BLOCK_ALLOC_SIZE;		}		bs->original[bs->position] = val;		bs->position++;		return;	}	/*we are in FILE mode, no pb for any realloc...*/	fputc(val, bs->stream);	/*check we didn't rewind the stream*/	if (bs->size == bs->position) bs->size++;	bs->position += 1;}static void BS_WriteBit(GF_BitStream *bs, u32 bit){	bs->current <<= 1;	bs->current |= bit;	if (++ bs->nbBits == 8) {		bs->nbBits = 0;		BS_WriteByte(bs, (u8) bs->current);		bs->current = 0;	}}GF_EXPORTvoid gf_bs_write_int(GF_BitStream *bs, s32 value, s32 nBits){	value <<= sizeof (s32) * 8 - nBits;	while (--nBits >= 0) {		BS_WriteBit (bs, value < 0);		value <<= 1;	}}GF_EXPORTvoid gf_bs_write_long_int(GF_BitStream *bs, s64 value, s32 nBits){	value <<= sizeof (s64) * 8 - nBits;	while (--nBits >= 0) {		BS_WriteBit (bs, value < 0);		value <<= 1;	}}GF_EXPORTvoid gf_bs_write_u8(GF_BitStream *bs, u32 value){	assert(!bs->nbBits);	BS_WriteByte(bs, (u8) value);}GF_EXPORTvoid gf_bs_write_u16(GF_BitStream *bs, u32 value){

⌨️ 快捷键说明

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