Example #1
0
static GF_Err BM_ParseGlobalQuantizer(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
{
	GF_Node *node;
	GF_Command *com;
	GF_CommandField *inf;
	node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode);

	/*reset global QP*/
	if (codec->scenegraph->global_qp) {
		gf_node_unregister(codec->scenegraph->global_qp, NULL);
	}
	codec->ActiveQP = NULL;
	codec->scenegraph->global_qp = NULL;

	if (node && (gf_node_get_tag(node) != TAG_MPEG4_QuantizationParameter)) {
		gf_node_unregister(node, NULL);
		return GF_NON_COMPLIANT_BITSTREAM;
	}

	/*register global QP*/
	codec->ActiveQP = (M_QuantizationParameter *) node;
	codec->ActiveQP->isLocal = 0;
	codec->scenegraph->global_qp = node;
	if (node) {
		/*register TWICE: once for the command, and for the scenegraph globalQP*/
		node->sgprivate->num_instances = 2;
	}
	com = gf_sg_command_new(codec->current_graph, GF_SG_GLOBAL_QUANTIZER);
	inf = gf_sg_command_field_new(com);
	inf->new_node = node;
	inf->field_ptr = &inf->new_node;
	inf->fieldType = GF_SG_VRML_SFNODE;
	gf_list_add(com_list, com);
	return GF_OK;
}
Example #2
0
GF_Err BM_ParseIndexValueReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
{
	u32 NodeID, ind, field_ind, NumBits;
	s32 type, pos;
	GF_Command *com;
	GF_Node *node;
	GF_Err e;
	GF_FieldInfo field, sffield;
	GF_CommandField *inf;

	/*get the node*/
	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);

	node = gf_sg_find_node(codec->current_graph, NodeID);
	if (!node) return GF_NON_COMPLIANT_BITSTREAM;
	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
	ind = gf_bs_read_int(bs, NumBits);
	e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
	if (e) return e;

	e = gf_node_get_field(node, field_ind, &field);
	if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;

	type = gf_bs_read_int(bs, 2);
	switch (type) {
	case 0:
		pos = gf_bs_read_int(bs, 16);
		break;
	case 2:
		pos = 0;
		break;
	case 3:
		pos = ((GenMFField *) field.far_ptr)->count - 1;
		break;
	default:
		return GF_NON_COMPLIANT_BITSTREAM;
	}

	com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_REPLACE);
	BM_SetCommandNode(com, node);
	inf = gf_sg_command_field_new(com);
	inf->fieldIndex = field.fieldIndex;
	inf->pos = pos;

	if (field.fieldType == GF_SG_VRML_MFNODE) {
		inf->fieldType = GF_SG_VRML_SFNODE;
		inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype);
		inf->field_ptr = &inf->new_node;
		if (inf->new_node) gf_node_register(inf->new_node, NULL);
	} else {
		memcpy(&sffield, &field, sizeof(GF_FieldInfo));
		sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
		inf->fieldType = sffield.fieldType;
		sffield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(sffield.fieldType);
		codec->LastError = gf_bifs_dec_sf_field(codec, bs, node, &sffield, 1);
	}
	gf_list_add(com_list, com);
	return codec->LastError;
}
Example #3
0
static GF_Err BM_ParseMultipleIndexedReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
{
	u32 ID, ind, field_ind, NumBits, lenpos, lennum, count;
	GF_Node *node;
	GF_Err e;
	GF_Command *com;
	GF_CommandField *inf;
	GF_FieldInfo field;

	ID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
	node = gf_sg_find_node(codec->current_graph, ID);
	if (!node) return GF_NON_COMPLIANT_BITSTREAM;
	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
	ind = gf_bs_read_int(bs, NumBits);
	e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
	if (e) return e;
	e = gf_node_get_field(node, field_ind, &field);
	if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;

	lenpos = gf_bs_read_int(bs, 5);
	lennum = gf_bs_read_int(bs, 5);
	count = gf_bs_read_int(bs, lennum);

	com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_INDEXED_REPLACE);
	BM_SetCommandNode(com, node);
	field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);

	while (count) {
		inf = gf_sg_command_field_new(com);
		inf->pos = gf_bs_read_int(bs, lenpos);
		inf->fieldIndex = field.fieldIndex;
		inf->fieldType = field.fieldType;

		if (field.fieldType==GF_SG_VRML_SFNODE) {
			inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype);
			if (codec->LastError) goto err;
			inf->field_ptr = &inf->new_node;
			gf_node_register(inf->new_node, NULL);
		} else {
			field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
			e = gf_bifs_dec_sf_field(codec, bs, node, &field, 1);
			if (e) goto err;
		}
		count--;
	}
err:
	if (e) gf_sg_command_del(com);
	else gf_list_add(com_list, com);
	return e;
}
Example #4
0
/*inserts a node in a container (node.children)*/
GF_Err BM_ParseNodeInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
{
	u32 NodeID, NDT;
	GF_Command *com;
	GF_CommandField *inf;
	s32 type, pos;
	GF_Node *node, *def;

	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
	def = gf_sg_find_node(codec->current_graph, NodeID);
	if (!def) return GF_NON_COMPLIANT_BITSTREAM;
	NDT = gf_bifs_get_child_table(def);
	if (!NDT) return GF_NON_COMPLIANT_BITSTREAM;

	type = gf_bs_read_int(bs, 2);
	switch (type) {
	case 0:
		pos = gf_bs_read_int(bs, 8);
		break;
	case 2:
		pos = 0;
		break;
	case 3:
		/*-1 means append*/
		pos = -1;
		break;
	default:
		return GF_NON_COMPLIANT_BITSTREAM;
	}
	node = gf_bifs_dec_node(codec, bs, NDT);
	if (!codec->LastError) {
		com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_INSERT);
		BM_SetCommandNode(com, def);
		inf = gf_sg_command_field_new(com);
		inf->pos = pos;
		inf->new_node = node;
		inf->field_ptr = &inf->new_node;
		inf->fieldType = GF_SG_VRML_SFNODE;
		gf_list_add(com_list, com);
		/*register*/
		gf_node_register(node, NULL);
	}
	return codec->LastError;
}
Example #5
0
GF_Err BM_ParseNodeReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
{
	u32 NodeID;
	GF_Command *com;
	GF_Node *node;
	GF_CommandField *inf;

	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
	/*this is delete / new on a DEF node: replace ALL instances*/
	node = gf_sg_find_node(codec->current_graph, NodeID);
	if (!node) return GF_NON_COMPLIANT_BITSTREAM;

	com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_REPLACE);
	BM_SetCommandNode(com, node);
	inf = gf_sg_command_field_new(com);
	inf->new_node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode);
	inf->fieldType = GF_SG_VRML_SFNODE;
	inf->field_ptr = &inf->new_node;
	gf_list_add(com_list, com);
	gf_node_register(inf->new_node, NULL);
	return codec->LastError;
}
Example #6
0
GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com)
{
	GF_Err e;
	GF_Node *new_node;
	u32 size, length, w, h, i;
	char *buffer;

	//blindly call unquantize. return is OK, error or GF_EOS
	if (codec->ActiveQP && node) {
		e = gf_bifs_dec_unquant_field(codec, bs, node, field);
		if (e != GF_EOS) return e;
	}
	//not quantized, use normal scheme
	switch (field->fieldType) {
	case GF_SG_VRML_SFBOOL:
		* ((SFBool *) field->far_ptr) = (SFBool) gf_bs_read_int(bs, 1);
		break;
	case GF_SG_VRML_SFCOLOR:
		((SFColor *)field->far_ptr)->red = BD_ReadSFFloat(codec, bs);;
		((SFColor *)field->far_ptr)->green = BD_ReadSFFloat(codec, bs);
		((SFColor *)field->far_ptr)->blue = BD_ReadSFFloat(codec, bs);
		break;
	case GF_SG_VRML_SFFLOAT:
		*((SFFloat *)field->far_ptr) = BD_ReadSFFloat(codec, bs);
		break;
	case GF_SG_VRML_SFINT32:
		*((SFInt32 *)field->far_ptr) = (s32) gf_bs_read_int(bs, 32);
		break;
	case GF_SG_VRML_SFTIME:
		*((SFTime *)field->far_ptr) = gf_bs_read_double(bs);
		if (node) BD_CheckSFTimeOffset(codec, node, field);
		break;
	case GF_SG_VRML_SFVEC2F:
		((SFVec2f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
		((SFVec2f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
		break;
	case GF_SG_VRML_SFVEC3F:
		((SFVec3f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
		((SFVec3f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
		((SFVec3f *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs);
		break;
	case GF_SG_VRML_SFROTATION:
		((SFRotation *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
		((SFRotation *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
		((SFRotation *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs);
		((SFRotation *)field->far_ptr)->q = BD_ReadSFFloat(codec, bs);
		break;
	case GF_SG_VRML_SFSTRING:
		size = gf_bs_read_int(bs, 5);
		length = gf_bs_read_int(bs, size);
		if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;

		if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) {
			M_CacheTexture *ct = (M_CacheTexture *) node;
			ct->data_len = length;
			if (ct->data) gf_free(ct->data);
			ct->data = gf_malloc(sizeof(char)*length);
			gf_bs_read_data(bs, (char*)ct->data, length);
		} else if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) {
			M_BitWrapper *bw = (M_BitWrapper*) node;
			if (bw->buffer.buffer) gf_free(bw->buffer.buffer);
			bw->buffer_len = length;
			bw->buffer.buffer = gf_malloc(sizeof(char)*length);
			gf_bs_read_data(bs, (char*)bw->buffer.buffer, length);
		} else {
			if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer);
			((SFString *)field->far_ptr)->buffer = (char *)gf_malloc(sizeof(char)*(length+1));
			memset(((SFString *)field->far_ptr)->buffer , 0, length+1);
			for (i=0; i<length; i++) {
				((SFString *)field->far_ptr)->buffer[i] = gf_bs_read_int(bs, 8);
			}
		}
		break;
	case GF_SG_VRML_SFURL:
	{
		SFURL *url = (SFURL *) field->far_ptr;
		size = gf_bs_read_int(bs, 1);
		if (size) {
			if (url->url) gf_free(url->url );
			url->url = NULL;
			length = gf_bs_read_int(bs, 10);
			url->OD_ID = length;
		} else {
			if ( url->OD_ID ) url->OD_ID = (u32) -1;
			size = gf_bs_read_int(bs, 5);
			length = gf_bs_read_int(bs, size);
			if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;
			buffer = NULL;
			if (length) {
				buffer = (char *)gf_malloc(sizeof(char)*(length+1));
				memset(buffer, 0, length+1);
				for (i=0; i<length; i++) buffer[i] = gf_bs_read_int(bs, 8);
			}
			if (url->url) gf_free( url->url);
			/*if URL is empty set it to NULL*/
			if (buffer && strlen(buffer)) {
				url->url = buffer;
			} else {
				gf_free(buffer);
				url->url = NULL;
			}
		}
	}
	break;
	case GF_SG_VRML_SFIMAGE:
		if (((SFImage *)field->far_ptr)->pixels) gf_free(((SFImage *)field->far_ptr)->pixels);
		w = gf_bs_read_int(bs, 12);
		h = gf_bs_read_int(bs, 12);
		length = gf_bs_read_int(bs, 2);

		if (length > 3) length = 3;
		length += 1;
		size = w * h * length;
		if (gf_bs_available(bs) < size) return GF_NON_COMPLIANT_BITSTREAM;
		((SFImage *)field->far_ptr)->width = w;
		((SFImage *)field->far_ptr)->height = h;
		((SFImage *)field->far_ptr)->numComponents = length;
		((SFImage *)field->far_ptr)->pixels = (unsigned char *)gf_malloc(sizeof(char)*size);
		//WARNING: Buffers are NOT ALIGNED IN THE BITSTREAM
		for (i=0; i<size; i++) {
			((SFImage *)field->far_ptr)->pixels[i] = gf_bs_read_int(bs, 8);
		}
		break;
	case GF_SG_VRML_SFCOMMANDBUFFER:
	{
		SFCommandBuffer *sfcb = (SFCommandBuffer *)field->far_ptr;
		if (sfcb->buffer) {
			gf_free(sfcb->buffer);
			sfcb->buffer = NULL;
		}
		while (gf_list_count(sfcb->commandList)) {
			GF_Command *com = (GF_Command*)gf_list_get(sfcb->commandList, 0);
			gf_list_rem(sfcb->commandList, 0);
			gf_sg_command_del(com);
		}

		size = gf_bs_read_int(bs, 5);
		length = gf_bs_read_int(bs, size);
		if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;

		sfcb->bufferSize = length;
		if (length) {
			sfcb->buffer = (unsigned char *)gf_malloc(sizeof(char)*(length));
			//WARNING Buffers are NOT ALIGNED IN THE BITSTREAM
			for (i=0; i<length; i++) {
				sfcb->buffer[i] = gf_bs_read_int(bs, 8);
			}
		}
		//notify the node - this is needed in case an enhencement layer replaces the buffer, in which case
		//the # ID Bits may change
		SFCommandBufferChanged(codec, node);

		/*
		 1 - memory mode, register command buffer for later parsing
		 2 - InputSensor only works on decompressed commands
		*/
		if (codec->dec_memory_mode || (node->sgprivate->tag==TAG_MPEG4_InputSensor)) {
			CommandBufferItem *cbi = (CommandBufferItem *)gf_malloc(sizeof(CommandBufferItem));
			cbi->node = node;
			cbi->cb = sfcb;
			gf_list_add(codec->command_buffers, cbi);
		}
	}
	break;
	case GF_SG_VRML_SFNODE:
		//for nodes the field ptr is a ptr to the field, which is a node ptr ;)
		new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
		if (new_node) {
			e = gf_node_register(new_node, is_mem_com ? NULL : node);
			if (e) return e;
		}
		//it may happen that new_node is NULL (this is valid for a proto declaration)
		*((GF_Node **) field->far_ptr) = new_node;
		break;
	case GF_SG_VRML_SFSCRIPT:
#ifdef GPAC_HAS_SPIDERMONKEY
		codec->LastError = SFScript_Parse(codec, (SFScript*)field->far_ptr, bs, node);
#else
		return GF_NOT_SUPPORTED;
#endif
		break;
	case GF_SG_VRML_SFATTRREF:
	{
		SFAttrRef *ar = (SFAttrRef *)field->far_ptr;
		u32 nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
		ar->node = gf_sg_find_node(codec->current_graph, nodeID);
		if (!ar->node) {

		} else {
			u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1);
			u32 field_ref = gf_bs_read_int(bs, nbBitsDEF);
			codec->LastError = gf_bifs_get_field_index(ar->node, field_ref, GF_SG_FIELD_CODING_DEF, &ar->fieldIndex);
		}
	}
	break;
	default:
		return GF_NON_COMPLIANT_BITSTREAM;
	}
	return codec->LastError;
}
Example #7
0
GF_Err BD_DecMFFieldVec(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com)
{
	GF_Err e;
	u32 NbBits, nbFields;
	u32 i;
	GF_ChildNodeItem *last;
	u8 qp_local, qp_on, initial_qp;
	GF_Node *new_node;
	GF_FieldInfo sffield;

	memset(&sffield, 0, sizeof(GF_FieldInfo));
	sffield.fieldIndex = field->fieldIndex;
	sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);
	sffield.NDTtype = field->NDTtype;

	initial_qp = qp_local = qp_on = 0;

	//vector description - alloc the MF size before
	NbBits = gf_bs_read_int(bs, 5);
	nbFields = gf_bs_read_int(bs, NbBits);

	if (codec->ActiveQP) {
		initial_qp = 1;
		/*this is for QP 14*/
		gf_bifs_dec_qp14_set_length(codec, nbFields);
	}

	if (field->fieldType != GF_SG_VRML_MFNODE) {
		e = gf_sg_vrml_mf_alloc(field->far_ptr, field->fieldType, nbFields);
		if (e) return e;

		for (i=0; i<nbFields; i++) {
			e = gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, & sffield.far_ptr, i);
			if (e) return e;
			e = gf_bifs_dec_sf_field(codec, bs, node, &sffield, 0);
		}
	} else {
		last = NULL;
		for (i=0; i<nbFields; i++) {
			new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
			if (new_node) {
				e = gf_node_register(new_node, is_mem_com ? NULL : node);
				if (e) return e;

				if (node) {
					/*special case for QP, register as the current QP*/
					if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {
						qp_local = ((M_QuantizationParameter *)new_node)->isLocal;
						/*we have a QP in the same scope, remove previous
						NB: we assume this is the right behaviour, the spec doesn't say
						whether QP is cumulative or not*/
						if (qp_on) gf_bifs_dec_qp_remove(codec, 0);

						e = gf_bifs_dec_qp_set(codec, new_node);
						if (e) return e;
						qp_on = 1;
						if (qp_local) qp_local = 2;
						if (codec->force_keep_qp) {
							e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
						} else {
							gf_node_register(new_node, NULL);
							gf_node_unregister(new_node, node);
						}
					} else {
						e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
					}
				}
				/*proto coding*/
				else if (codec->pCurrentProto) {
					/*TO DO: what happens if this is a QP node on the interface ?*/
					e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);
				}
			} else {
				return codec->LastError ? codec->LastError : GF_NON_COMPLIANT_BITSTREAM;
			}
		}
		/*according to the spec, the QP applies to the current node itself, not just children.
		If IsLocal is TRUE remove the node*/
		if (qp_on && qp_local) {
			if (qp_local == 2) {
				qp_local = 1;
			} else {
				//ask to get rid of QP and reactivate if we had a QP when entering the node
				gf_bifs_dec_qp_remove(codec, initial_qp);
				qp_local = 0;
			}
		}
	}
	/*finally delete the QP if any (local or not) as we get out of this node*/
	if (qp_on) gf_bifs_dec_qp_remove(codec, 1);
	return GF_OK;
}
Example #8
0
GF_Err BD_DecMFFieldList(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com)
{
	GF_Node *new_node;
	GF_Err e;
	u8 endFlag, qp_local, qp_on, initial_qp;
	GF_ChildNodeItem *last = NULL;
	u32 nbF;

	GF_FieldInfo sffield;

	memset(&sffield, 0, sizeof(GF_FieldInfo));
	sffield.fieldIndex = field->fieldIndex;
	sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);
	sffield.NDTtype = field->NDTtype;

	nbF = 0;
	qp_on = qp_local = 0;
	initial_qp = codec->ActiveQP ? 1 : 0;

	endFlag = gf_bs_read_int(bs, 1);
	while (!endFlag  && (codec->LastError>=0)) {
		e = GF_OK;;
		if (field->fieldType != GF_SG_VRML_MFNODE) {
			e = gf_sg_vrml_mf_append(field->far_ptr, field->fieldType, & sffield.far_ptr);
			e = gf_bifs_dec_sf_field(codec, bs, node, &sffield, 0);
		} else {
			new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
			//append
			if (new_node) {
				e = gf_node_register(new_node, is_mem_com ? NULL : node);
				if (e) return e;

				//regular coding
				if (node) {
					//special case for QP, register as the current QP
					if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {
						qp_local = ((M_QuantizationParameter *)new_node)->isLocal;
						//we have a QP in the same scope, remove previous
						if (qp_on) gf_bifs_dec_qp_remove(codec, 0);
						e = gf_bifs_dec_qp_set(codec, new_node);
						if (e) return e;
						qp_on = 1;
						if (qp_local) qp_local = 2;
						if (codec->force_keep_qp) {
							e = gf_node_list_add_child_last( field->far_ptr, new_node, &last);
						} else {
							gf_node_register(new_node, NULL);
							gf_node_unregister(new_node, node);
						}
					} else
						//this is generic MFNode container
						e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);

				}
				//proto coding: directly add the child
				else if (codec->pCurrentProto) {
					//TO DO: what happens if this is a QP node on the interface ?
					e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);
				}
			} else {
				return codec->LastError;
			}
		}
		if (e) return e;

		endFlag = gf_bs_read_int(bs, 1);

		//according to the spec, the QP applies to the current node itself,
		//not just children. If IsLocal is TRUE remove the node
		if (qp_on && qp_local) {
			if (qp_local == 2) {
				qp_local = 1;
			} else {
				//ask to get rid of QP and reactivate if we had a QP when entering
				gf_bifs_dec_qp_remove(codec, initial_qp);
				qp_local = 0;
				qp_on = 0;
			}
		}
		nbF += 1;
	}
	/*finally delete the QP if any (local or not) as we get out of this node
	and reactivate previous one*/
	if (qp_on) gf_bifs_dec_qp_remove(codec, initial_qp);
	/*this is for QP 14*/
	gf_bifs_dec_qp14_set_length(codec, nbF);
	return GF_OK;
}
Example #9
0
/*NB This can insert a node as well (but usually not in the .children field)*/
GF_Err BM_ParseIndexInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
{
	GF_Err e;
	u32 NodeID;
	u32 NumBits, ind, field_ind;
	u8 type;
	GF_Command *com;
	GF_CommandField *inf;
	s32 pos;
	GF_Node *def, *node;
	GF_FieldInfo field, sffield;

	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
	def = gf_sg_find_node(codec->current_graph, NodeID);
	if (!def) return GF_NON_COMPLIANT_BITSTREAM;
	/*index insertion uses IN mode for field index*/
	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(def, GF_SG_FIELD_CODING_IN)-1);
	ind = gf_bs_read_int(bs, NumBits);

	e = gf_bifs_get_field_index(def, ind, GF_SG_FIELD_CODING_IN, &field_ind);
	if (e) return e;

	type = gf_bs_read_int(bs, 2);
	switch (type) {
	case 0:
		pos = gf_bs_read_int(bs, 16);
		break;
	case 2:
		pos = 0;
		break;
	case 3:
		pos = -1;
		break;
	default:
		return GF_NON_COMPLIANT_BITSTREAM;
	}

	e = gf_node_get_field(def, field_ind, &field);
	if (e) return e;
	if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;

	memcpy(&sffield, &field, sizeof(GF_FieldInfo));
	sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);

	/*rescale the MFField and parse the SFField*/
	if (field.fieldType==GF_SG_VRML_MFNODE) {
		node = gf_bifs_dec_node(codec, bs, field.NDTtype);
		if (!codec->LastError) {
			com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT);
			BM_SetCommandNode(com, def);
			inf = gf_sg_command_field_new(com);
			inf->pos = pos;
			inf->fieldIndex = field_ind;
			inf->fieldType = sffield.fieldType;
			inf->new_node = node;
			inf->field_ptr = &inf->new_node;
			gf_list_add(com_list, com);
			/*register*/
			gf_node_register(node, NULL);
		}
	} else {
		com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT);
		BM_SetCommandNode(com, def);
		inf = gf_sg_command_field_new(com);
		inf->pos = pos;
		inf->fieldIndex = field_ind;
		inf->fieldType = sffield.fieldType;
		sffield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(sffield.fieldType);
		codec->LastError = gf_bifs_dec_sf_field(codec, bs, def, &sffield, 1);
		gf_list_add(com_list, com);
	}
	return codec->LastError;
}
Example #10
0
GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
{
	GF_Err e;
	GF_Node *new_node;
	u32 size, length, w, h, i;
	char *buffer;

	//blindly call unquantize. return is OK, error or GF_EOS
	if (codec->ActiveQP && node) {
		e = gf_bifs_dec_unquant_field(codec, bs, node, field);
		if (e != GF_EOS) return e;
	}
	//not quantized, use normal scheme
	switch (field->fieldType) {
	case GF_SG_VRML_SFBOOL:
		* ((SFBool *) field->far_ptr) = (SFBool) gf_bs_read_int(bs, 1);
		break;
	case GF_SG_VRML_SFCOLOR:
		((SFColor *)field->far_ptr)->red = BD_ReadSFFloat(codec, bs);;
		((SFColor *)field->far_ptr)->green = BD_ReadSFFloat(codec, bs);
		((SFColor *)field->far_ptr)->blue = BD_ReadSFFloat(codec, bs);
		break;
	case GF_SG_VRML_SFFLOAT:
		*((SFFloat *)field->far_ptr) = BD_ReadSFFloat(codec, bs);
		break;
	case GF_SG_VRML_SFINT32:
		*((SFInt32 *)field->far_ptr) = (s32) gf_bs_read_int(bs, 32);
		break;
	case GF_SG_VRML_SFTIME:
		*((SFTime *)field->far_ptr) = gf_bs_read_double(bs);
		if (node) BD_CheckSFTimeOffset(codec, node, field);
		break;
	case GF_SG_VRML_SFVEC2F:
		((SFVec2f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
		((SFVec2f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
		break;
	case GF_SG_VRML_SFVEC3F:
		((SFVec3f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
		((SFVec3f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
		((SFVec3f *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs);
		break;
	case GF_SG_VRML_SFROTATION:
		((SFRotation *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
		((SFRotation *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
		((SFRotation *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs);
		((SFRotation *)field->far_ptr)->q = BD_ReadSFFloat(codec, bs);
		break;
	case GF_SG_VRML_SFSTRING:
		size = gf_bs_read_int(bs, 5);
		length = gf_bs_read_int(bs, size);
		if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;

		if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) {
			Bool skip_file_url_proto=0;
			char *name;
			FILE *f;
			M_CacheTexture *ct = (M_CacheTexture *) node;
			char *buf = gf_malloc(sizeof(char)*length);
			gf_bs_read_data(bs, buf, length);
			if (ct->cacheURL.buffer) {
				name = gf_strdup(ct->cacheURL.buffer);
			} else {
				char szImg[100], *ext;
				switch (ct->objectTypeIndication) {
				case GPAC_OTI_IMAGE_JPEG: ext = "jpg"; break;
				case GPAC_OTI_IMAGE_PNG: ext = "png"; break;
				case GPAC_OTI_IMAGE_JPEG_2000: ext = "jp2"; break;
				default: ext = "img";
				}
				sprintf(szImg, "%p%p.%s", codec, ct, ext);
				name = gf_strdup(szImg);
			}

			if (codec->extraction_path) {
				char *path;
				u32 len = strlen(name)+strlen(codec->extraction_path)+2;
				if (strnicmp(codec->extraction_path, "file://", 7)) len+=7;
				/*SHA1 of service in hexa*/
				if (codec->service_url) len += 41;
				path = gf_malloc(sizeof(char)*len);

				path[0] = 0;
				/*force using file:// URL prototype to avoid confusion with resources adressed from the root of the source server*/
				if (strnicmp(codec->extraction_path, "file://", 7)) strcpy(path, "file://");
				strcat(path, codec->extraction_path);
				strcat(path, "/");

				if (codec->service_url) {
					u8 hash[20];
					u32 i;
					gf_sha1_csum(codec->service_url, strlen(codec->service_url), hash);
					for (i=0; i<20; i++) {
						char t[3];
						t[2] = 0;
						sprintf(t, "%02X", hash[i]);
						strcat(path, t);
					}
					strcat(path, "_");
				} 
				strcat(path, name);

				gf_free(name);
				name = path;
				skip_file_url_proto = 1;
			}

			((SFString *)field->far_ptr)->buffer = name;
			/*skip the initial file://*/
			f = gf_f64_open(name + (skip_file_url_proto ? 7 : 0), "wb");
			fwrite(buf, 1, length, f);
			fclose(f);
			gf_free(buf);
		} else {
			if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer);
			((SFString *)field->far_ptr)->buffer = (char *)gf_malloc(sizeof(char)*(length+1));
			memset(((SFString *)field->far_ptr)->buffer , 0, length+1);
			for (i=0; i<length; i++) {
				 ((SFString *)field->far_ptr)->buffer[i] = gf_bs_read_int(bs, 8);
			}
		}
		break;
	case GF_SG_VRML_SFURL:
	{
		SFURL *url = (SFURL *) field->far_ptr;
		size = gf_bs_read_int(bs, 1);
		if (size) {
			if (url->url) gf_free(url->url );
			url->url = NULL;
			length = gf_bs_read_int(bs, 10);
			url->OD_ID = length;
		} else {
			if ( url->OD_ID ) url->OD_ID = (u32) -1;
			size = gf_bs_read_int(bs, 5);
			length = gf_bs_read_int(bs, size);
			if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;
			buffer = NULL;
			if (length) {
				buffer = (char *)gf_malloc(sizeof(char)*(length+1));
				memset(buffer, 0, length+1);
				for (i=0; i<length; i++) buffer[i] = gf_bs_read_int(bs, 8);
			}
			if (url->url) gf_free( url->url);
			/*if URL is empty set it to NULL*/
			if (buffer && strlen(buffer)) {
				url->url = buffer;
			} else {
				gf_free(buffer);
				url->url = NULL;
			}
		}
	}
		break;
	case GF_SG_VRML_SFIMAGE:
		if (((SFImage *)field->far_ptr)->pixels) gf_free(((SFImage *)field->far_ptr)->pixels);
		w = gf_bs_read_int(bs, 12);
		h = gf_bs_read_int(bs, 12);
		length = gf_bs_read_int(bs, 2);

		if (length > 3) length = 3;
		length += 1;
		size = w * h * length;
		if (gf_bs_available(bs) < size) return GF_NON_COMPLIANT_BITSTREAM;
		((SFImage *)field->far_ptr)->width = w;
		((SFImage *)field->far_ptr)->height = h;
		((SFImage *)field->far_ptr)->numComponents = length;
		((SFImage *)field->far_ptr)->pixels = (unsigned char *)gf_malloc(sizeof(char)*size);
		//WARNING: Buffers are NOT ALIGNED IN THE BITSTREAM
		for (i=0; i<size; i++) {
			((SFImage *)field->far_ptr)->pixels[i] = gf_bs_read_int(bs, 8);
		}
		break;
	case GF_SG_VRML_SFCOMMANDBUFFER:
	{
		SFCommandBuffer *sfcb = (SFCommandBuffer *)field->far_ptr;
		if (sfcb->buffer) {
			gf_free(sfcb->buffer);		
			sfcb->buffer = NULL;
		}
		while (gf_list_count(sfcb->commandList)) {
			GF_Command *com = (GF_Command*)gf_list_get(sfcb->commandList, 0);
			gf_list_rem(sfcb->commandList, 0);
			gf_sg_command_del(com);
		}

		size = gf_bs_read_int(bs, 5);
		length = gf_bs_read_int(bs, size);
		if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;

		sfcb->bufferSize = length;
		if (length) {
			sfcb->buffer = (unsigned char *)gf_malloc(sizeof(char)*(length));
			//WARNING Buffers are NOT ALIGNED IN THE BITSTREAM
			for (i=0; i<length; i++) {
				sfcb->buffer[i] = gf_bs_read_int(bs, 8);
			}
		}
		//notify the node - this is needed in case an enhencement layer replaces the buffer, in which case 
		//the # ID Bits may change
		SFCommandBufferChanged(codec, node);

		/*
		 1 - memory mode, register command buffer for later parsing
		 2 - InputSensor only works on decompressed commands
		*/
		if (codec->dec_memory_mode || (node->sgprivate->tag==TAG_MPEG4_InputSensor)) {
			CommandBufferItem *cbi = (CommandBufferItem *)gf_malloc(sizeof(CommandBufferItem));
			cbi->node = node;
			cbi->cb = sfcb;
			gf_list_add(codec->command_buffers, cbi);
		}
	} 
		break;
	case GF_SG_VRML_SFNODE:
		//for nodes the field ptr is a ptr to the field, which is a node ptr ;)
		new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
		if (new_node) {
			e = gf_node_register(new_node, node);
			if (e) return e;
		}
		//it may happen that new_node is NULL (this is valid for a proto declaration)
		*((GF_Node **) field->far_ptr) = new_node;
		break;
	case GF_SG_VRML_SFSCRIPT:
#ifdef GPAC_HAS_SPIDERMONKEY
		codec->LastError = SFScript_Parse(codec, (SFScript*)field->far_ptr, bs, node);
#else
		return GF_NOT_SUPPORTED;
#endif
		break;
	case GF_SG_VRML_SFATTRREF:
	{
		SFAttrRef *ar = (SFAttrRef *)field->far_ptr;
		u32 nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
		ar->node = gf_sg_find_node(codec->current_graph, nodeID);
		if (!ar->node) {

		} else {
			u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1);
			u32 field_ref = gf_bs_read_int(bs, nbBitsDEF);
			codec->LastError = gf_bifs_get_field_index(ar->node, field_ref, GF_SG_FIELD_CODING_DEF, &ar->fieldIndex);
		}
	}
		break;
	default:
		return GF_NON_COMPLIANT_BITSTREAM;
	}
	return codec->LastError;
}