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

📄 field_decode.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
	u8 flag;//	if (codec->LastError) return codec->LastError;	assert(node);//	if (field->fieldType == GF_SG_VRML_UNKNOWN) return GF_NON_COMPLIANT_BITSTREAM;		if (gf_sg_vrml_is_sf_field(field->fieldType)) {		e = gf_bifs_dec_sf_field(codec, bs, node, field);		if (e) return e;	} else {		/*clean up the eventIn field if not done*/		if (field->eventType == GF_SG_EVENT_IN) {			if (field->fieldType == GF_SG_VRML_MFNODE) {				gf_node_unregister_children(node, * (GF_ChildNodeItem **)field->far_ptr);				* (GF_ChildNodeItem **)field->far_ptr = NULL;			} else {				//remove all items of the MFField				gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType);			}		}		/*predictiveMFField*/		if (codec->info->config.UsePredictiveMFField) {			flag = gf_bs_read_int(bs, 1);			if (flag)  return gf_bifs_dec_pred_mf_field(codec, bs, node, field);		}		/*reserved*/		flag = gf_bs_read_int(bs, 1);		if (!flag) {			/*destroy the field content...*/			if (field->fieldType != GF_SG_VRML_MFNODE) {				e = gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType);				if (e) return e;			}			/*List description - alloc is dynamic*/			flag = gf_bs_read_int(bs, 1);			if (flag) {				e = BD_DecMFFieldList(codec, bs, node, field);			} else {				e = BD_DecMFFieldVec(codec, bs, node, field);			}			if (e) return e;		}	}	return GF_OK;}GF_Err BD_SetProtoISed(GF_BifsDecoder * codec, u32 protofield, GF_Node *n, u32 nodefield){	/*take care of conditional execution in proto*/	if (codec->current_graph->pOwningProto) {		return gf_sg_proto_instance_set_ised((GF_Node *) codec->current_graph->pOwningProto, protofield, n, nodefield);	}	/*regular ISed fields*/	else {		return gf_sg_proto_field_set_ised(codec->pCurrentProto, protofield, n, nodefield);	}}GF_Err gf_bifs_dec_node_list(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node){	u8 flag;	GF_Err e;	u32 numBitsALL, numBitsDEF, field_all, field_ref, numProtoBits;	GF_FieldInfo field;	e = GF_OK;	numProtoBits = numBitsALL = 0;	if (codec->pCurrentProto) {		numProtoBits = gf_get_bit_size(gf_sg_proto_get_field_count(codec->pCurrentProto) - 1);		numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL)-1);	}	numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1);	flag = gf_bs_read_int(bs, 1);	while (!flag) {		if (codec->pCurrentProto) {			//IS'ed flag			flag = gf_bs_read_int(bs, 1);			if (flag) {				//get field index in ALL mode for node				field_ref = gf_bs_read_int(bs, numBitsALL);				//get field index in ALL mode for proto				field_all = gf_bs_read_int(bs, numProtoBits);				e = gf_node_get_field(node, field_ref, &field);				if (e) return e;				e = BD_SetProtoISed(codec, field_all, node, field_ref);				if (e) return e;				flag = gf_bs_read_int(bs, 1);				continue;			}		}		//fields are coded in DEF mode		field_ref = gf_bs_read_int(bs, numBitsDEF);		e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &field_all);		if (e) return e;		e = gf_node_get_field(node, field_all, &field);		if (e) return e;		e = gf_bifs_dec_field(codec, bs, node, &field);		if (e) return e;		flag = gf_bs_read_int(bs, 1);	}	return codec->LastError;}GF_Err gf_bifs_dec_node_mask(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node){	u32 i, numFields, numProtoFields, index, flag, nbBits;	GF_Err e;	GF_FieldInfo field;	//proto coding	if (codec->pCurrentProto) {		numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL);		numProtoFields = gf_sg_proto_get_field_count(codec->pCurrentProto);		nbBits = gf_get_bit_size(numProtoFields-1);		for (i=0; i<numFields; i++) {			flag = gf_bs_read_int(bs, 1);			if (!flag) continue;			flag = gf_bs_read_int(bs, 1);			//IS'ed field, create route for binding to Proto declaration			if (flag) {				//reference index of our IS'ed proto field				flag = gf_bs_read_int(bs, nbBits);				e = gf_node_get_field(node, i, &field);				if (e) return e;				e = BD_SetProtoISed(codec, flag, node, i);			}			//regular field, parse it (nb: no contextual coding for protos in maskNode, 			//all node fields are coded			else {				e = gf_node_get_field(node, i, &field);				if (e) return e;				e = gf_bifs_dec_field(codec, bs, node, &field);			}			if (e) return e;		}	}	//Anim coding	else {		numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF);		for (i=0; i<numFields; i++) {			flag = gf_bs_read_int(bs, 1);			if (!flag) continue;			gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &index);			e = gf_node_get_field(node, index, &field);			if (e) return e;			e = gf_bifs_dec_field(codec, bs, node, &field);			if (e) return e;		}	}	return GF_OK;}static void UpdateTimeNode(GF_BifsDecoder * codec, GF_Node *node){	switch (gf_node_get_tag(node)) {	case TAG_MPEG4_AnimationStream:		BD_OffsetSFTime(codec, & ((M_AnimationStream*)node)->startTime);		BD_OffsetSFTime(codec, & ((M_AnimationStream*)node)->stopTime);		break;	case TAG_MPEG4_AudioBuffer:		BD_OffsetSFTime(codec, & ((M_AudioBuffer*)node)->startTime);		BD_OffsetSFTime(codec, & ((M_AudioBuffer*)node)->stopTime);		break;	case TAG_MPEG4_AudioClip:		BD_OffsetSFTime(codec, & ((M_AudioClip*)node)->startTime);		BD_OffsetSFTime(codec, & ((M_AudioClip*)node)->stopTime);		break;	case TAG_MPEG4_AudioSource:		BD_OffsetSFTime(codec, & ((M_AudioSource*)node)->startTime);		BD_OffsetSFTime(codec, & ((M_AudioSource*)node)->stopTime);		break;	case TAG_MPEG4_MovieTexture:		BD_OffsetSFTime(codec, & ((M_MovieTexture*)node)->startTime);		BD_OffsetSFTime(codec, & ((M_MovieTexture*)node)->stopTime);		break;	case TAG_MPEG4_TimeSensor:		BD_OffsetSFTime(codec, & ((M_TimeSensor*)node)->startTime);		BD_OffsetSFTime(codec, & ((M_TimeSensor*)node)->stopTime);		break;	case TAG_ProtoNode:	{		u32 i, nbFields;		GF_FieldInfo inf;		nbFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL);		for (i=0; i<nbFields; i++) {			gf_node_get_field(node, i, &inf);			if (inf.fieldType != GF_SG_VRML_SFTIME) continue;			BD_CheckSFTimeOffset(codec, node, &inf);		}	}		break;	}}GF_Node *gf_bifs_dec_node(GF_BifsDecoder * codec, GF_BitStream *bs, u32 NDT_Tag){	u32 nodeID, NDTBits, node_type, node_tag, ProtoID, BVersion;	u8 node_flag;	Bool skip_init;	GF_Node *new_node;	GF_Err e;	GF_Proto *proto;	void SetupConditional(GF_BifsDecoder *codec, GF_Node *node);	//to store the UseName	char name[1000];#if 0	/*should only happen with inputSensor, in which case this is BAAAAD*/	if (!codec->info) {		codec->LastError = GF_BAD_PARAM;		return NULL;	}#endif	BVersion = GF_BIFS_V1;	node_flag = 0;	/*this is a USE statement*/	if (gf_bs_read_int(bs, 1)) {		nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);		/*NULL node is encoded as USE with ID = all bits to 1*/		if (nodeID == (u32) (1<<codec->info->config.NodeIDBits))			return NULL;		//find node and return it		new_node = gf_sg_find_node(codec->current_graph, nodeID);		if (!new_node) {			codec->LastError = GF_SG_UNKNOWN_NODE;		} else {			/*restore QP14 length*/			switch (gf_node_get_tag(new_node)) {			case TAG_MPEG4_Coordinate:				{					u32 nbCoord = ((M_Coordinate *)new_node)->point.count;					gf_bifs_dec_qp14_enter(codec, 1);					gf_bifs_dec_qp14_set_length(codec, nbCoord);					gf_bifs_dec_qp14_enter(codec, 0);				}				break;			case TAG_MPEG4_Coordinate2D:				{					u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count;					gf_bifs_dec_qp14_enter(codec, 1);					gf_bifs_dec_qp14_set_length(codec, nbCoord);					gf_bifs_dec_qp14_enter(codec, 0);				}				break;			}		}		return new_node;	}	//this is a new node	nodeID = 0;	name[0] = 0;	node_tag = 0;	proto = NULL;	//browse all node groups	while (1) {		NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion);		/*this happens in replacescene where no top-level node is present (externProto)*/		if ((BVersion==1) && (NDTBits > 8 * gf_bs_available(bs)) ) {			codec->LastError = GF_OK;			return NULL;		}		node_type = gf_bs_read_int(bs, NDTBits);		if (node_type) break;		//increment BIFS version		BVersion += 1;		//not supported		if (BVersion > GF_BIFS_NUM_VERSION) {			codec->LastError = GF_BIFS_UNKNOWN_VERSION;			return NULL;		}	}	if (BVersion==2 && node_type==1) {		ProtoID = gf_bs_read_int(bs, codec->info->config.ProtoIDBits);		/*look in current graph for the proto - this may be a proto graph*/		proto = gf_sg_find_proto(codec->current_graph, ProtoID, NULL);		/*this was in proto so look in main scene*/		if (!proto && codec->current_graph != codec->scenegraph)			proto = gf_sg_find_proto(codec->scenegraph, ProtoID, NULL);		if (!proto) {			codec->LastError = GF_SG_UNKNOWN_NODE;			return NULL;		}	} else {		node_tag = gf_bifs_ndt_get_node_type(NDT_Tag, node_type, BVersion);	}	/*special handling of 3D mesh*/	if ((node_tag == TAG_MPEG4_IndexedFaceSet) && codec->info->config.Use3DMeshCoding) {		if (gf_bs_read_int(bs, 1)) {			nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);			if (codec->info->UseName) gf_bifs_dec_name(bs, name);		}		/*parse the 3DMesh node*/		return NULL;	}	/*unknow node*/	if (!node_tag && !proto) {		codec->LastError = GF_SG_UNKNOWN_NODE;		return NULL;	}	/*DEF'd flag*/	if (gf_bs_read_int(bs, 1)) {		if (!codec->info->config.NodeIDBits) {			codec->LastError = GF_NON_COMPLIANT_BITSTREAM;			return NULL;		}		nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);		if (codec->info->UseName) gf_bifs_dec_name(bs, name);	}	new_node = NULL;	skip_init = 0;	/*don't check node IDs duplicate since VRML may use them...*/#if 0	/*if a node with same DEF is already in the scene, use it	we don't do that in memory mode because commands may force replacement	of a node with a new node with same ID, and we want to be able to dump it (otherwise we would	dump a USE)*/	if (nodeID && !codec->dec_memory_mode) {		new_node = gf_sg_find_node(codec->current_graph, nodeID);		if (new_node) {			if (proto) {				if ((gf_node_get_tag(new_node) != TAG_ProtoNode) || (gf_node_get_proto(new_node) != proto)) {					codec->LastError = GF_NON_COMPLIANT_BITSTREAM;					return NULL;				}				skip_init = 1;			} else {				if (gf_node_get_tag(new_node) != node_tag) {					codec->LastError = GF_NON_COMPLIANT_BITSTREAM;					return NULL;				}				skip_init = 1;			}		}	}#endif		if (!new_node) {		if (proto) {			/*create proto interface*/			new_node = gf_sg_proto_create_instance(codec->current_graph, proto);		} else {			new_node = gf_node_new(codec->current_graph, node_tag);		}	}	if (!new_node) {		codec->LastError = GF_NOT_SUPPORTED;		return NULL;	}	/*VRML: "The transformation hierarchy shall be a directed acyclic graph; results are undefined if a node 	in the transformation hierarchy is its own ancestor"	that's good, because the scene graph can't handle cyclic graphs (destroy will never be called).	We therefore only register the node once parsed*/	if (nodeID) {		if (strlen(name)) {			gf_node_set_id(new_node, nodeID, name);		} else {			gf_node_set_id(new_node, nodeID, NULL);		}	}	/*update default time fields except in proto parsing*/	if (!codec->pCurrentProto) UpdateTimeNode(codec, new_node);	/*QP 14 is a special quant mode for IndexFace/Line(2D)Set to quantize the 	coordonate(2D) child, based on the first field parsed	we must check the type of the node and notfy the QP*/	switch (node_tag) {	case TAG_MPEG4_Coordinate:	case TAG_MPEG4_Coordinate2D:		gf_bifs_dec_qp14_enter(codec, 1);	}	if (gf_bs_read_int(bs, 1)) {		e = gf_bifs_dec_node_mask(codec, bs, new_node);	} else {		e = gf_bifs_dec_node_list(codec, bs, new_node);	}	if (e) {		codec->LastError = e;		/*register*/		gf_node_register(new_node, NULL);		/*unregister (deletes)*/		gf_node_unregister(new_node, NULL);		return NULL;	}	/*nodes are only init outside protos */	if (!proto && !codec->pCurrentProto && new_node && !skip_init) gf_node_init(new_node);	switch (node_tag) {	case TAG_MPEG4_IndexedFaceSet:	case TAG_MPEG4_IndexedFaceSet2D:	case TAG_MPEG4_IndexedLineSet:	case TAG_MPEG4_IndexedLineSet2D:		gf_bifs_dec_qp14_reset(codec);		break;	case TAG_MPEG4_Coordinate:	case TAG_MPEG4_Coordinate2D:		gf_bifs_dec_qp14_enter(codec, 0);		break;	case TAG_MPEG4_Script:		/*load script if in main graph (useless to load in proto declaration)*/		if (codec->scenegraph == codec->current_graph) {			gf_sg_script_load(new_node);		}		break;	/*conditionals must be init*/	case TAG_MPEG4_Conditional:		SetupConditional(codec, new_node);		break;	}	/*if new node is a proto and we're in the top scene, load proto code*/	if (proto && new_node && (codec->scenegraph == codec->current_graph)) {		codec->LastError = gf_sg_proto_load_code(new_node);	}	return new_node;}

⌨️ 快捷键说明

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