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

📄 bitstream.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
	assert(!bs->nbBits);	BS_WriteByte(bs, (u8) ((value>>8)&0xff));	BS_WriteByte(bs, (u8) ((value)&0xff));}GF_EXPORTvoid gf_bs_write_u24(GF_BitStream *bs, u32 value){	assert(!bs->nbBits);	BS_WriteByte(bs, (u8) ((value>>16)&0xff));	BS_WriteByte(bs, (u8) ((value>>8)&0xff));	BS_WriteByte(bs, (u8) ((value)&0xff));}GF_EXPORTvoid gf_bs_write_u32(GF_BitStream *bs, u32 value){	assert(!bs->nbBits);	BS_WriteByte(bs, (u8) ((value>>24)&0xff));	BS_WriteByte(bs, (u8) ((value>>16)&0xff));	BS_WriteByte(bs, (u8) ((value>>8)&0xff));	BS_WriteByte(bs, (u8) ((value)&0xff));}GF_EXPORTvoid gf_bs_write_u64(GF_BitStream *bs, u64 value){	assert(!bs->nbBits);	gf_bs_write_u32(bs, (u32) ((value>>32)&0xffffffff));	gf_bs_write_u32(bs, (u32) (value&0xffffffff));}GF_EXPORTvoid gf_bs_write_float(GF_BitStream *bs, Float value){	u32 i;	union	{	float f;		char sz [4];	} float_value;	float_value.f = value;	for (i = 0; i < 32; i++)		BS_WriteBit(bs, (float_value.sz [3 - i / 8] & 1 << (7 - i % 8)) != 0);}GF_EXPORTvoid gf_bs_write_double (GF_BitStream *bs, Double value){	u32 i;	union	{	Double d;		char sz [8];	} double_value;	double_value.d = value;	for (i = 0; i < 64; i++) {		BS_WriteBit(bs, (double_value.sz [7 - i / 8] & 1 << (7 - i % 8)) != 0);	}}GF_EXPORTu32 gf_bs_write_data(GF_BitStream *bs, char *data, u32 nbBytes){	/*we need some feedback for this guy...*/	u64 begin = bs->position;	if (!nbBytes) return 0;	if (BS_IsAlign(bs)) {		switch (bs->bsmode) {		case GF_BITSTREAM_WRITE:			if (bs->position+nbBytes > bs->size) 				return 0;			memcpy(bs->original + bs->position, data, nbBytes);			bs->position += nbBytes;			return nbBytes;		case GF_BITSTREAM_WRITE_DYN:			/*need to realloc ...*/			if (bs->position+nbBytes > bs->size) {				if (bs->size + nbBytes > 0xFFFFFFFF) 					return 0;				bs->original = (char*)realloc(bs->original, sizeof(u32)*((u32) bs->size + nbBytes));				if (!bs->original) 					return 0;				bs->size += nbBytes;			}			memcpy(bs->original + bs->position, data, nbBytes);			bs->position += nbBytes;			return nbBytes;		case GF_BITSTREAM_FILE_READ:		case GF_BITSTREAM_FILE_WRITE:			if (fwrite(data, nbBytes, 1, bs->stream) != 1) return 0;			if (bs->size == bs->position) bs->size += nbBytes;			bs->position += nbBytes;			return nbBytes;		default:			return 0;		}	}	while (nbBytes) {		gf_bs_write_int(bs, (s32) *data, 8);		data++;		nbBytes--;	}	return (u32) (bs->position - begin);}/*align return the num of bits read in READ mode, 0 in WRITE*/GF_EXPORTu8 gf_bs_align(GF_BitStream *bs){	u8 res = 8 - bs->nbBits;	if ( (bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_FILE_READ)) {		if (res > 0) {			gf_bs_read_int(bs, res);		}		return res;	}	if (bs->nbBits > 0) {		gf_bs_write_int (bs, 0, res);		return res;	}	return 0;}/*size available in the bitstream*/GF_EXPORTu64 gf_bs_available(GF_BitStream *bs){	s64 cur, end;	/*in WRITE mode only, this should not be called, but return something big in case ...*/	if ( (bs->bsmode == GF_BITSTREAM_WRITE) 		|| (bs->bsmode == GF_BITSTREAM_WRITE_DYN) 		)		return (u64) -1;	/*we are in MEM mode*/	if (bs->bsmode == GF_BITSTREAM_READ) {		return (bs->size - bs->position);	}	/*FILE READ: assume size hasn't changed, otherwise the user shall call gf_bs_get_refreshed_size*/	if (bs->bsmode==GF_BITSTREAM_FILE_READ) return (bs->size - bs->position);	cur = gf_f64_tell(bs->stream);	gf_f64_seek(bs->stream, 0, SEEK_END);	end = gf_f64_tell(bs->stream);	gf_f64_seek(bs->stream, cur, SEEK_SET);		return (u64) (end - cur);}/*call this funct to set the buffer size to the nb of bytes written Used only in WRITE mode, as we don't know the real size during allocation...return -1 for bad param or malloc failedreturn nbBytes cut*/static u32 BS_CutBuffer(GF_BitStream *bs){		u32 nbBytes;	if ( (bs->bsmode != GF_BITSTREAM_WRITE_DYN) && (bs->bsmode != GF_BITSTREAM_WRITE)) return (u32) -1;	/*Align our buffer or we're dead!*/	gf_bs_align(bs);	nbBytes = (u32) (bs->size - bs->position);	if (!nbBytes || (nbBytes == 0xFFFFFFFF) || (bs->position >= 0xFFFFFFFF)) return 0;	bs->original = (char*)realloc(bs->original, (u32) bs->position);	if (! bs->original) return (u32) -1;	/*just in case, re-adjust..*/	bs->size = bs->position;	return nbBytes;}/*For DYN mode, this gets the content out*/GF_EXPORTvoid gf_bs_get_content(GF_BitStream *bs, char **output, u32 *outSize){	/*only in WRITE MEM mode*/	if (bs->bsmode != GF_BITSTREAM_WRITE_DYN) return;	if (!bs->position && !bs->nbBits) {		*output = NULL;		*outSize = 0;		free(bs->original);	} else {		BS_CutBuffer(bs);		*output = bs->original;		*outSize = (u32) bs->size;	}	bs->original = NULL;	bs->size = 0;	bs->position = 0;}/*	Skip nbytes. 	Align	If READ (MEM or FILE) mode, just read n times 8 bit	If WRITE (MEM or FILE) mode, write n times 0 on 8 bit*/GF_EXPORTvoid gf_bs_skip_bytes(GF_BitStream *bs, u64 nbBytes){	if (!bs || !nbBytes) return;	gf_bs_align(bs);		/*special case for file skipping...*/	if ((bs->bsmode == GF_BITSTREAM_FILE_WRITE) || (bs->bsmode == GF_BITSTREAM_FILE_READ)) {		gf_f64_seek(bs->stream, nbBytes, SEEK_CUR);		bs->position += nbBytes;		return;	}	/*special case for reading*/	if (bs->bsmode == GF_BITSTREAM_READ) {		bs->position += nbBytes;		return;	}	/*for writing we must do it this way, otherwise pb in dynamic buffers*/	while (nbBytes) {		gf_bs_write_int(bs, 0, 8);		nbBytes--;	}}/*Only valid for READ MEMORY*/GF_EXPORTvoid gf_bs_rewind_bits(GF_BitStream *bs, u64 nbBits){	u64 nbBytes;	if (bs->bsmode != GF_BITSTREAM_READ) return;	nbBits -= (bs->nbBits);	nbBytes = (nbBits+8)>>3;	nbBits = nbBytes*8 - nbBits;	gf_bs_align(bs);	assert(bs->position >= nbBytes);	bs->position -= nbBytes + 1;	gf_bs_read_int(bs, (u32)nbBits);	return;}/*seek from begining of stream: use internally even when non aligned!*/static GF_Err BS_SeekIntern(GF_BitStream *bs, u64 offset){	u32 i;	/*if mem, do it */	if ((bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_WRITE) || (bs->bsmode == GF_BITSTREAM_WRITE_DYN)) {		if (offset > 0xFFFFFFFF) return GF_IO_ERR;		/*0 for write, read will be done automatically*/		if (offset >= bs->size) {			if ( (bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_WRITE) ) return GF_BAD_PARAM;			/*in DYN, realloc ...*/			bs->original = (char*)realloc(bs->original, (u32) (offset + 1));			for (i = 0; i < (u32) (offset + 1 - bs->size); i++) {				bs->original[bs->size + i] = 0;			}			bs->size = offset + 1;		}		bs->current = bs->original[offset];		bs->position = offset;		bs->nbBits = (bs->bsmode == GF_BITSTREAM_READ) ? 8 : 0;		return GF_OK;	}	gf_f64_seek(bs->stream, offset, SEEK_SET);	bs->position = offset;	bs->current = 0;	/*setup NbBits so that next acccess to the buffer will trigger read/write*/	bs->nbBits = (bs->bsmode == GF_BITSTREAM_FILE_READ) ? 8 : 0;	return GF_OK;}/*seek from begining of stream: align before anything else*/GF_EXPORTGF_Err gf_bs_seek(GF_BitStream *bs, u64 offset){	/*warning: we allow offset = bs->size for WRITE buffers*/	if (offset > bs->size) return GF_BAD_PARAM;	gf_bs_align(bs);	return BS_SeekIntern(bs, offset);}/*peek bits (as int!!) from orig position (ON BYTE BOUNDARIES, from 0) - only for read ...*/GF_EXPORTu32 gf_bs_peek_bits(GF_BitStream *bs, u32 numBits, u32 byte_offset){	u64 curPos;	u32 curBits, ret, current;	if ( (bs->bsmode != GF_BITSTREAM_READ) && (bs->bsmode != GF_BITSTREAM_FILE_READ)) return 0;	if (!numBits || (bs->size < bs->position + byte_offset)) return 0;	/*store our state*/	curPos = bs->position;	curBits = bs->nbBits;	current = bs->current;	if (byte_offset) gf_bs_seek(bs, bs->position + byte_offset);	ret = gf_bs_read_int(bs, numBits);	/*restore our cache - position*/	gf_bs_seek(bs, curPos);	/*to avoid re-reading our bits ...*/	bs->nbBits = curBits;	bs->current = current;	return ret;}GF_EXPORTu64 gf_bs_get_refreshed_size(GF_BitStream *bs){	s64 offset;	switch (bs->bsmode) {	case GF_BITSTREAM_READ:	case GF_BITSTREAM_WRITE:		return bs->size;	default:		offset = gf_f64_tell(bs->stream);		gf_f64_seek(bs->stream, 0, SEEK_END);		bs->size = gf_f64_tell(bs->stream);		gf_f64_seek(bs->stream, offset, SEEK_SET);		return bs->size;	}}GF_EXPORTu64 gf_bs_get_size(GF_BitStream *bs){	return bs->size;}GF_EXPORTu64 gf_bs_get_position(GF_BitStream *bs){	return bs->position;}GF_EXPORTu8 gf_bs_bits_available(GF_BitStream *bs){	if (bs->size > bs->position) return 8;	if (bs->nbBits < 8) return (8-bs->nbBits);	return 0;}GF_EXPORTvoid gf_bs_set_eos_callback(GF_BitStream *bs, void (*EndOfStream)(void *par), void *par){	bs->EndOfStream = EndOfStream;	bs->par = par;}GF_EXPORTu32 gf_bs_read_u32_le(GF_BitStream *bs){	u32 ret, v;	ret = gf_bs_read_int(bs, 8);	v = gf_bs_read_int(bs, 8); v<<=8; ret |= v;	v = gf_bs_read_int(bs, 8); v<<=16; ret |= v;	v = gf_bs_read_int(bs, 8); v<<=24; ret |= v;	return ret;}GF_EXPORTu16 gf_bs_read_u16_le(GF_BitStream *bs){	u32 ret, v;	ret = gf_bs_read_int(bs, 8);	v = gf_bs_read_int(bs, 8); v<<=8; ret |= v;	return ret;}GF_EXPORTvoid gf_bs_write_u32_le(GF_BitStream *bs, u32 val){	gf_bs_write_int(bs, val & 0xFF, 8);	gf_bs_write_int(bs, val>>8, 8);	gf_bs_write_int(bs, val>>16, 8);	gf_bs_write_int(bs, val>>24, 8);}GF_EXPORTvoid gf_bs_write_u16_le(GF_BitStream *bs, u32 val){	gf_bs_write_int(bs, val & 0xFF, 8);	gf_bs_write_int(bs, val>>8, 8);}GF_EXPORTu32 gf_bs_get_bit_offset(GF_BitStream *bs){	if (bs->stream) return 0;	if (bs->bsmode==GF_BITSTREAM_READ) return (u32) ( (bs->position - 1) * 8 + bs->nbBits);	return (u32) ( (bs->position ) * 8 + bs->nbBits);}GF_EXPORTu32 gf_bs_get_bit_position(GF_BitStream *bs){	if (bs->stream) return 0;	return bs->nbBits;}u32 gf_bs_read_vluimsbf5(GF_BitStream *bs){	u32 nb_words = 0;	while (gf_bs_read_int(bs, 1)) nb_words++;	nb_words++;	return gf_bs_read_int(bs, 4*nb_words);}

⌨️ 快捷键说明

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