Пример #1
0
static void svg2bifs_text_content(void *sax_cbck, const char *text_content, Bool is_cdata)
{
    SVG2BIFS_Converter *converter = (SVG2BIFS_Converter *)sax_cbck;
    if (converter->bifs_text_node) {
        M_Text *text = (M_Text *)converter->bifs_text_node;
        gf_sg_vrml_mf_alloc(&text->string, GF_SG_VRML_MFSTRING, 1);
        text->string.vals[0] = gf_strdup(text_content);
    }
}
Пример #2
0
Bool InitCoordinateInterpolator4D(M_CoordinateInterpolator4D *node)
{
	node->on_set_fraction = CI4D_SetFraction;

	if (node->key.count && !(node->keyValue.count % node->key.count)) {
		u32 i, numElemPerKey = node->keyValue.count / node->key.count;
		gf_sg_vrml_mf_alloc(&node->value_changed, GF_SG_VRML_MFVEC4F, numElemPerKey);
		for (i=0; i<numElemPerKey; i++)
			node->value_changed.vals[i] = node->keyValue.vals[i];
	}
	return 1;
}
Пример #3
0
static void CI4D_SetFraction(GF_Node *n, GF_Route *route)
{
	Fixed frac;
	u32 numElemPerKey, i, j;
	M_CoordinateInterpolator4D *_this = (M_CoordinateInterpolator4D *) n;

	if (! _this->key.count) return;
	if (_this->keyValue.count % _this->key.count) return;

	numElemPerKey = _this->keyValue.count / _this->key.count;
	//set size
	if (_this->value_changed.count != numElemPerKey)
		gf_sg_vrml_mf_alloc(&_this->value_changed, GF_SG_VRML_MFVEC4F, numElemPerKey);


	if (_this->set_fraction < _this->key.vals[0]) {
		for (i=0; i<numElemPerKey; i++)
			_this->value_changed.vals[i] = _this->keyValue.vals[i];
	} else if (_this->set_fraction > _this->key.vals[_this->key.count - 1]) {
		for (i=0; i<numElemPerKey; i++)
			_this->value_changed.vals[i] = _this->keyValue.vals[(_this->keyValue.count) - numElemPerKey + i];
	} else {
		for (j = 1; j < _this->key.count; j++) {
			// Find the key values the fraction lies between
			if ( _this->set_fraction < _this->key.vals[j-1]) continue;
			if (_this->set_fraction >= _this->key.vals[j]) continue;

			frac = GetInterpolateFraction(_this->key.vals[j-1], _this->key.vals[j], _this->set_fraction);
			for (i=0; i<numElemPerKey; i++) {
				_this->value_changed.vals[i].x = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].x,
				                                 _this->keyValue.vals[(j)*numElemPerKey + i].x,
				                                 frac);
				_this->value_changed.vals[i].y = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].y,
				                                 _this->keyValue.vals[(j)*numElemPerKey + i].y,
				                                 frac);
				_this->value_changed.vals[i].z = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].z,
				                                 _this->keyValue.vals[(j)*numElemPerKey + i].z,
				                                 frac);
				_this->value_changed.vals[i].q = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].q,
				                                 _this->keyValue.vals[(j)*numElemPerKey + i].q,
				                                 frac);
			}
			break;
		}
	}
	//invalidate
	gf_node_event_out(n, 3);//"value_changed"
}
Пример #4
0
static void media_sensor_activate(MediaSensorStack *media_sens, GF_Segment *desc)
{
	media_sens->sensor->isActive = 1;
	gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
	/*set info*/
	gf_sg_vrml_mf_reset(& media_sens->sensor->info, GF_SG_VRML_MFSTRING);
	gf_sg_vrml_mf_alloc(& media_sens->sensor->info, GF_SG_VRML_MFSTRING, 1);
	media_sens->sensor->info.vals[0] = desc->SegmentName ? gf_strdup(desc->SegmentName) : NULL;
	gf_node_event_out((GF_Node *) media_sens->sensor, 5/*"info"*/);
	/*set duration*/
	media_sens->sensor->mediaDuration = desc->Duration;
	gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/);
	/*set seg start time*/
	media_sens->sensor->streamObjectStartTime = desc->startTime;
	gf_node_event_out((GF_Node *) media_sens->sensor, 2/*"streamObjectStartTime"*/);
}
Пример #5
0
static Bool CI_SetFraction(Fixed fraction, MFVec3f *vals, MFFloat *key, MFVec3f *keyValue)
{
	Fixed frac;
	u32 numElemPerKey, i, j;

	if (! key->count) return 0;
	if (keyValue->count % key->count) return 0;

	numElemPerKey = keyValue->count / key->count;

	if (vals->count != numElemPerKey) gf_sg_vrml_mf_alloc(vals, GF_SG_VRML_MFVEC3F, numElemPerKey);

	if (fraction < key->vals[0]) {
		for (i=0; i<numElemPerKey; i++)
			vals->vals[i] = keyValue->vals[i];
	} else if (fraction > key->vals[key->count - 1]) {
		for (i=0; i<numElemPerKey; i++)
			vals->vals[i] = keyValue->vals[(keyValue->count) - numElemPerKey + i];
	} else {
		for (j = 1; j < key->count; j++) {
			// Find the key values the fraction lies between
			if (fraction < key->vals[j-1]) continue;
			if (fraction >= key->vals[j]) continue;

			frac = GetInterpolateFraction(key->vals[j-1], key->vals[j], fraction);
			for (i=0; i<numElemPerKey; i++) {
				vals->vals[i].x = Interpolate(keyValue->vals[(j-1)*numElemPerKey + i].x,
				                              keyValue->vals[(j)*numElemPerKey + i].x,
				                              frac);
				vals->vals[i].y = Interpolate(keyValue->vals[(j-1)*numElemPerKey + i].y,
				                              keyValue->vals[(j)*numElemPerKey + i].y,
				                              frac);
				vals->vals[i].z = Interpolate(keyValue->vals[(j-1)*numElemPerKey + i].z,
				                              keyValue->vals[(j)*numElemPerKey + i].z,
				                              frac);
			}
			break;
		}
	}
	return 1;
}
Пример #6
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;
}
Пример #7
0
/*import cubic QTVR to mp4*/
GF_Err gf_sm_load_init_qt(GF_SceneLoader *load)
{
	u32 i, di, w, h, tk, nb_samp;
	Bool has_qtvr;
	GF_ISOSample *samp;
	GF_ISOFile *src;
	GF_StreamContext *st;
	GF_AUContext *au;
	GF_Command *com;
	M_Background *back;
	M_NavigationInfo *ni;
	M_Group *gr;
	GF_ODUpdate *odU;
	GF_SceneGraph *sg;
	GF_ObjectDescriptor *od;
	GF_ESD *esd;

	if (!load->ctx) return GF_NOT_SUPPORTED;

	src = gf_isom_open(load->fileName, GF_ISOM_OPEN_READ, NULL);
	if (!src) return gf_qt_report(load, GF_URL_ERROR, "Opening file %s failed", load->fileName);

	w = h = tk = 0;
	nb_samp = 0;

	has_qtvr = 0;
	for (i=0; i<gf_isom_get_track_count(src); i++) {
		switch (gf_isom_get_media_type(src, i+1)) {
		case GF_ISOM_MEDIA_VISUAL:
			if (gf_isom_get_media_subtype(src, i+1, 1) == GF_4CC('j', 'p', 'e', 'g')) {
				GF_GenericSampleDescription *udesc = gf_isom_get_generic_sample_description(src, i+1, 1);
				if ((udesc->width>w) || (udesc->height>h)) {
					w = udesc->width;
					h = udesc->height;
					tk = i+1;
					nb_samp = gf_isom_get_sample_count(src, i+1);
				}
				if (udesc->extension_buf) gf_free(udesc->extension_buf);
				gf_free(udesc);
			}
			break;
		case GF_4CC('q','t','v','r'):
			has_qtvr = 1;
			break;
		}
	}
	if (!has_qtvr) {
		gf_isom_delete(src);
		return gf_qt_report(load, GF_NOT_SUPPORTED, "QTVR not found - no conversion available for this QuickTime movie");
	}
	if (!tk) {
		gf_isom_delete(src);
		return gf_qt_report(load, GF_NON_COMPLIANT_BITSTREAM, "No associated visual track with QTVR movie");
	}
	if (nb_samp!=6) {
		gf_isom_delete(src);
		return gf_qt_report(load, GF_NOT_SUPPORTED, "Movie %s doesn't look a Cubic QTVR - sorry...", load->fileName);
	}

	GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("QT: Importing Cubic QTVR Movie"));

	/*create scene*/
	sg = load->ctx->scene_graph;
	gr = (M_Group *) gf_node_new(sg, TAG_MPEG4_Group);
	gf_node_register((GF_Node *)gr, NULL);
	st = gf_sm_stream_new(load->ctx, 1, GF_STREAM_SCENE, 1);
	au = gf_sm_stream_au_new(st, 0, 0, 1);
	com = gf_sg_command_new(load->ctx->scene_graph, GF_SG_SCENE_REPLACE);
	gf_list_add(au->commands, com);
	com->node = (GF_Node *)gr;

	back = (M_Background *) gf_node_new(sg, TAG_MPEG4_Background);
	gf_node_list_add_child( &gr->children, (GF_Node*)back);
	gf_node_register((GF_Node *)back, (GF_Node *)gr);

	gf_sg_vrml_mf_alloc(&back->leftUrl, GF_SG_VRML_MFURL, 1);
	back->leftUrl.vals[0].OD_ID = 2;
	gf_sg_vrml_mf_alloc(&back->frontUrl, GF_SG_VRML_MFURL, 1);
	back->frontUrl.vals[0].OD_ID = 3;
	gf_sg_vrml_mf_alloc(&back->rightUrl, GF_SG_VRML_MFURL, 1);
	back->rightUrl.vals[0].OD_ID = 4;
	gf_sg_vrml_mf_alloc(&back->backUrl, GF_SG_VRML_MFURL, 1);
	back->backUrl.vals[0].OD_ID = 5;
	gf_sg_vrml_mf_alloc(&back->topUrl, GF_SG_VRML_MFURL, 1);
	back->topUrl.vals[0].OD_ID = 6;
	gf_sg_vrml_mf_alloc(&back->bottomUrl, GF_SG_VRML_MFURL, 1);
	back->bottomUrl.vals[0].OD_ID = 7;

	ni = (M_NavigationInfo *) gf_node_new(sg, TAG_MPEG4_NavigationInfo);
	gf_node_list_add_child(&gr->children, (GF_Node*)ni);
	gf_node_register((GF_Node *)ni, (GF_Node *)gr);
	gf_sg_vrml_mf_reset(&ni->type, GF_SG_VRML_MFSTRING);
	gf_sg_vrml_mf_alloc(&ni->type, GF_SG_VRML_MFSTRING, 1);
	ni->type.vals[0] = gf_strdup("QTVR");

	/*create ODs*/
	st = gf_sm_stream_new(load->ctx, 2, GF_STREAM_OD, 1);
	au = gf_sm_stream_au_new(st, 0, 0, 1);
	odU = (GF_ODUpdate*) gf_odf_com_new(GF_ODF_OD_UPDATE_TAG);
	gf_list_add(au->commands, odU);
	for (i=0; i<6; i++) {
		GF_MuxInfo *mi;
		FILE *img;
		char szName[1024];
		od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
		od->objectDescriptorID = 2+i;
		esd = gf_odf_desc_esd_new(2);
		esd->decoderConfig->streamType = GF_STREAM_VISUAL;
		esd->decoderConfig->objectTypeIndication = GPAC_OTI_IMAGE_JPEG;
		esd->ESID = 3+i;
		/*extract image and remember it*/
		mi = (GF_MuxInfo *) gf_odf_desc_new(GF_ODF_MUXINFO_TAG);
		gf_list_add(esd->extensionDescriptors, mi);
		mi->delete_file = 1;
		sprintf(szName, "%s_img%d.jpg", load->fileName, esd->ESID);
		mi->file_name = gf_strdup(szName);
		
		gf_list_add(od->ESDescriptors, esd);
		gf_list_add(odU->objectDescriptors, od);

		samp = gf_isom_get_sample(src, tk, i+1, &di);
		img = gf_f64_open(mi->file_name, "wb");
		fwrite(samp->data, samp->dataLength, 1, img);
		fclose(img);
		gf_isom_sample_del(&samp);
	}
	gf_isom_delete(src);
	return GF_OK;
}
Пример #8
0
static void TraversePlanarExtrusion(GF_Node *node, void *rs, Bool is_destroy)
{
    PlanarExtrusion plane_ext;
    Drawable *stack_2d;
    u32 i, j, k;
    MFVec3f spine_vec;
    SFVec3f d;
    Fixed spine_len;
    GF_Rect bounds;
    GF_Path *geo, *spine;
    GF_TraverseState *tr_state = (GF_TraverseState *)rs;
    Drawable3D *stack = (Drawable3D *)gf_node_get_private(node);

    if (is_destroy) {
        drawable_3d_del(node);
        return;
    }

    if (!PlanarExtrusion_GetNode(node, &plane_ext)) return;
    if (!plane_ext.geometry || !plane_ext.spine) return;


    if (gf_node_dirty_get(node)) {
        u32 cur, nb_pts;
        u32 mode = tr_state->traversing_mode;
        geo = spine = NULL;

        tr_state->traversing_mode = TRAVERSE_GET_BOUNDS;
        gf_node_traverse(plane_ext.geometry, tr_state);
        gf_node_traverse(plane_ext.spine, tr_state);
        tr_state->traversing_mode = mode;

        switch (gf_node_get_tag(plane_ext.geometry) ) {
        case TAG_MPEG4_Circle:
        case TAG_MPEG4_Ellipse:
        case TAG_MPEG4_Rectangle:
        case TAG_MPEG4_Curve2D:
        case TAG_MPEG4_XCurve2D:
        case TAG_MPEG4_IndexedFaceSet2D:
        case TAG_MPEG4_IndexedLineSet2D:
            stack_2d = (Drawable*)gf_node_get_private(plane_ext.geometry);
            if (stack_2d) geo = stack_2d->path;
            break;
        default:
            return;
        }
        switch (gf_node_get_tag(plane_ext.spine) ) {
        case TAG_MPEG4_Circle:
        case TAG_MPEG4_Ellipse:
        case TAG_MPEG4_Rectangle:
        case TAG_MPEG4_Curve2D:
        case TAG_MPEG4_XCurve2D:
        case TAG_MPEG4_IndexedFaceSet2D:
        case TAG_MPEG4_IndexedLineSet2D:
            stack_2d = (Drawable*)gf_node_get_private(plane_ext.spine);
            if (stack_2d) spine = stack_2d->path;
            break;
        default:
            return;
        }
        if (!geo || !spine) return;

        mesh_reset(stack->mesh);
        gf_path_flatten(spine);
        gf_path_get_bounds(spine, &bounds);
        gf_path_flatten(geo);
        gf_path_get_bounds(geo, &bounds);

        cur = 0;
        for (i=0; i<spine->n_contours; i++) {
            nb_pts = 1 + spine->contours[i] - cur;
            spine_vec.vals = NULL;
            gf_sg_vrml_mf_alloc(&spine_vec, GF_SG_VRML_MFVEC3F, nb_pts);
            spine_len = 0;
            for (j=cur; j<nb_pts; j++) {
                spine_vec.vals[j].x = spine->points[j].x;
                spine_vec.vals[j].y = spine->points[j].y;
                spine_vec.vals[j].z = 0;
                if (j) {
                    gf_vec_diff(d, spine_vec.vals[j], spine_vec.vals[j-1]);
                    spine_len += gf_vec_len(d);
                }
            }
            cur += nb_pts;
            if (!plane_ext.orientation->count && !plane_ext.scale->count) {
                mesh_extrude_path_ext(stack->mesh, geo, &spine_vec, plane_ext.creaseAngle,
                                      bounds.x, bounds.y-bounds.height, bounds.width, bounds.height,
                                      plane_ext.beginCap, plane_ext.endCap, NULL, NULL, plane_ext.txAlongSpine);
            }
            /*interpolate orientation and scale along subpath line*/
            else {
                MFRotation ori;
                MFVec2f scale;
                Fixed cur_len, frac;

                ori.vals = NULL;
                gf_sg_vrml_mf_alloc(&ori, GF_SG_VRML_MFROTATION, nb_pts);
                scale.vals = NULL;
                gf_sg_vrml_mf_alloc(&scale, GF_SG_VRML_MFVEC2F, nb_pts);
                cur_len = 0;
                if (!plane_ext.orientation->count) ori.vals[0].y = FIX_ONE;
                if (!plane_ext.scale->count) scale.vals[0].x = scale.vals[0].y = FIX_ONE;
                for (j=0; j<nb_pts; j++) {
                    if (j) {
                        gf_vec_diff(d, spine_vec.vals[j], spine_vec.vals[j-1]);
                        cur_len += gf_vec_len(d);
                        ori.vals[j] = ori.vals[j-1];
                        scale.vals[j] = scale.vals[j-1];
                    }

                    if (plane_ext.orientation->count && (plane_ext.orientation->count == plane_ext.orientationKeys->count)) {

                        frac = gf_divfix(cur_len , spine_len);
                        if (frac < plane_ext.orientationKeys->vals[0]) ori.vals[j] = plane_ext.orientation->vals[0];
                        else if (frac >= plane_ext.orientationKeys->vals[plane_ext.orientationKeys->count-1]) ori.vals[j] = plane_ext.orientation->vals[plane_ext.orientationKeys->count-1];
                        else {
                            for (k=1; k<plane_ext.orientationKeys->count; k++) {
                                Fixed kDiff = plane_ext.orientationKeys->vals[k] - plane_ext.orientationKeys->vals[k-1];
                                if (!kDiff) continue;
                                if (frac < plane_ext.orientationKeys->vals[k-1]) continue;
                                if (frac > plane_ext.orientationKeys->vals[k]) continue;
                                frac = gf_divfix(frac - plane_ext.orientationKeys->vals[k-1], kDiff);
                                break;
                            }
                            ori.vals[j] = gf_sg_sfrotation_interpolate(plane_ext.orientation->vals[k-1], plane_ext.orientation->vals[k], frac);
                        }
                    }

                    if (plane_ext.scale->count == plane_ext.scaleKeys->count) {
                        frac = gf_divfix(cur_len , spine_len);
                        if (frac <= plane_ext.scaleKeys->vals[0]) scale.vals[j] = plane_ext.scale->vals[0];
                        else if (frac >= plane_ext.scaleKeys->vals[plane_ext.scaleKeys->count-1]) scale.vals[j] = plane_ext.scale->vals[plane_ext.scale->count-1];
                        else {
                            for (k=1; k<plane_ext.scaleKeys->count; k++) {
                                Fixed kDiff = plane_ext.scaleKeys->vals[k] - plane_ext.scaleKeys->vals[k-1];
                                if (!kDiff) continue;
                                if (frac < plane_ext.scaleKeys->vals[k-1]) continue;
                                if (frac > plane_ext.scaleKeys->vals[k]) continue;
                                frac = gf_divfix(frac - plane_ext.scaleKeys->vals[k-1], kDiff);
                                break;
                            }
                            scale.vals[j].x = gf_mulfix(plane_ext.scale->vals[k].x - plane_ext.scale->vals[k-1].x, frac) + plane_ext.scale->vals[k-1].x;
                            scale.vals[j].y = gf_mulfix(plane_ext.scale->vals[k].y - plane_ext.scale->vals[k-1].y, frac) + plane_ext.scale->vals[k-1].y;
                        }
                    }
                }

                mesh_extrude_path_ext(stack->mesh, geo, &spine_vec, plane_ext.creaseAngle,
                                      bounds.x, bounds.y-bounds.height, bounds.width, bounds.height,
                                      plane_ext.beginCap, plane_ext.endCap, &ori, &scale, plane_ext.txAlongSpine);

                gf_sg_vrml_mf_reset(&ori, GF_SG_VRML_MFROTATION);
                gf_sg_vrml_mf_reset(&scale, GF_SG_VRML_MFVEC2F);
            }

            gf_sg_vrml_mf_reset(&spine_vec, GF_SG_VRML_MFVEC3F);
        }
        mesh_update_bounds(stack->mesh);
        gf_mesh_build_aabbtree(stack->mesh);
    }

    if (tr_state->traversing_mode==TRAVERSE_DRAW_3D) {
        visual_3d_draw(tr_state, stack->mesh);
    } else if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) {
        tr_state->bbox = stack->mesh->bounds;
    }
}
Пример #9
0
GF_EXPORT
GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_offset)
{
	GF_Err e;
	GF_CommandField *inf;
	GF_FieldInfo field;
	GF_Node *def, *node;
	void *slot_ptr;

	if (!com || !graph) return GF_BAD_PARAM;

	e = GF_OK;
	switch (com->tag) {
	case GF_SG_SCENE_REPLACE:
		/*unregister root*/
		gf_node_unregister(graph->RootNode, NULL);
		/*remove all protos and routes*/
		while (gf_list_count(graph->routes_to_activate)) 
			gf_list_rem(graph->routes_to_activate, 0);
		
		/*destroy all routes*/
		while (gf_list_count(graph->Routes)) {
			GF_Route *r = (GF_Route *)gf_list_get(graph->Routes, 0);
			/*this will unregister the route from the graph, so don't delete the chain entry*/
			gf_sg_route_del(r);
		}
		/*destroy all proto*/
		while (gf_list_count(graph->protos)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0);
			/*this will unregister the proto from the graph, so don't delete the chain entry*/
			gf_sg_proto_del(p);
		}
		/*DO NOT TOUCH node registry*/
		/*DO NOT TOUCH UNREGISTERED PROTOS*/

		/*move all protos in graph*/
		while (gf_list_count(com->new_proto_list)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0);
			gf_list_rem(com->new_proto_list, 0);
			gf_list_del_item(graph->unregistered_protos, p);
			gf_list_add(graph->protos, p);
		}
		/*assign new root (no need to register/unregister)*/
		graph->RootNode = com->node;
		com->node = NULL;
		break;

	case GF_SG_NODE_REPLACE:
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		e = gf_node_replace(com->node, inf->new_node, 0);
		if (inf->new_node) gf_node_register(inf->new_node, NULL);
		break;

	case GF_SG_MULTIPLE_REPLACE:
	case GF_SG_FIELD_REPLACE:
	{
		u32 j;
		GF_ChildNodeItem *list, *cur, *prev;
		j=0;
		while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &j))) {
			e = gf_node_get_field(com->node, inf->fieldIndex, &field);
			if (e) return e;

			switch (field.fieldType) {
			case GF_SG_VRML_SFNODE:
			{
				node = *((GF_Node **) field.far_ptr);
				e = gf_node_unregister(node, com->node);
				*((GF_Node **) field.far_ptr) = inf->new_node;
				if (!e) gf_node_register(inf->new_node, com->node);
				break;
			}
			case GF_SG_VRML_MFNODE:
				gf_node_unregister_children(com->node, * ((GF_ChildNodeItem **) field.far_ptr));
				* ((GF_ChildNodeItem **) field.far_ptr) = NULL;

				list = * ((GF_ChildNodeItem **) inf->field_ptr);
				prev=NULL;
				while (list) {
					cur = malloc(sizeof(GF_ChildNodeItem));
					cur->next = NULL;
					cur->node = list->node;
					if (prev) {
						prev->next = cur;
					} else {
						* ((GF_ChildNodeItem **) field.far_ptr) = cur;
					}
					gf_node_register(list->node, com->node);
					prev = cur;
					list = list->next;
				}
				break;
			default:
				/*this is a regular field, reset it and clone - we cannot switch pointers since the
				original fields are NOT pointers*/
				if (!gf_sg_vrml_is_sf_field(field.fieldType)) {
					e = gf_sg_vrml_mf_reset(field.far_ptr, field.fieldType);
				}
				if (e) return e;
				gf_sg_vrml_field_copy(field.far_ptr, inf->field_ptr, field.fieldType);
				if (field.fieldType==GF_SG_VRML_SFTIME) *(SFTime *)field.far_ptr = *(SFTime *)field.far_ptr + time_offset;
				break;
			}
			SG_CheckFieldChange(com->node, &field);
		}
		break;
	}

	case GF_SG_MULTIPLE_INDEXED_REPLACE:
	case GF_SG_INDEXED_REPLACE:
	{
		u32 sftype, i=0;
		while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &i))) {
			e = gf_node_get_field(com->node, inf->fieldIndex, &field);
			if (e) return e;

			/*if MFNode remove the child and set new node*/
			if (field.fieldType == GF_SG_VRML_MFNODE) {
				/*we must remove the node before in case the new node uses the same ID (not forbidden) and this
				command removes the last instance of the node with the same ID*/
				gf_node_replace_child(com->node, (GF_ChildNodeItem**) field.far_ptr, inf->pos, inf->new_node);
				if (inf->new_node) gf_node_register(inf->new_node, NULL);
			}
			/*erase the field item*/
			else {
				if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) {
					inf->pos = ((GenMFField *)field.far_ptr)->count - 1;
					/*may happen with text and default value*/
					if (inf->pos < 0) {
						inf->pos = 0;
						gf_sg_vrml_mf_alloc(field.far_ptr, field.fieldType, 1);
					}
				}
				e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & slot_ptr, inf->pos);
				if (e) return e;
				sftype = gf_sg_vrml_get_sf_type(field.fieldType);
				gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype);
				/*note we don't add time offset, since there's no MFTime*/
			}
			SG_CheckFieldChange(com->node, &field);
		}
		break;
	}
	case GF_SG_ROUTE_REPLACE:
	{
		GF_Route *r;
		char *name;
		r = gf_sg_route_find(graph, com->RouteID);
		def = gf_sg_find_node(graph, com->fromNodeID);
		node = gf_sg_find_node(graph, com->toNodeID);
		if (!node || !def) return GF_SG_UNKNOWN_NODE;
		name = NULL;
		if (r) {
			name = r->name;
			r->name = NULL;
			gf_sg_route_del(r);
		}
		r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex);
		gf_sg_route_set_id(r, com->RouteID);
		if (name) {
			gf_sg_route_set_name(r, name);
			free(name);
		}
		break;
	}
	case GF_SG_NODE_DELETE_EX:
	case GF_SG_NODE_DELETE:
	{
		if (com->node) gf_node_replace(com->node, NULL, (com->tag==GF_SG_NODE_DELETE_EX) ? 1 : 0);
		break;
	}
	case GF_SG_ROUTE_DELETE:
	{
		return gf_sg_route_del_by_id(graph, com->RouteID);
	}
	case GF_SG_INDEXED_DELETE:
	{
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);

		e = gf_node_get_field(com->node, inf->fieldIndex, &field);
		if (e) return e;
		if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;

		/*then we need special handling in case of a node*/
		if (gf_sg_vrml_get_sf_type(field.fieldType) == GF_SG_VRML_SFNODE) {
			e = gf_node_replace_child(com->node, (GF_ChildNodeItem **) field.far_ptr, inf->pos, NULL);
		} else {
			if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) {
				inf->pos = ((GenMFField *)field.far_ptr)->count - 1;
			}
			/*this is a regular MFField, just remove the item (realloc)*/
			e = gf_sg_vrml_mf_remove(field.far_ptr, field.fieldType, inf->pos);
		}
		/*deletion -> node has changed*/
		if (!e) SG_CheckFieldChange(com->node, &field);
		break;
	}
	case GF_SG_NODE_INSERT:
	{
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);

		e = gf_node_insert_child(com->node, inf->new_node, inf->pos);
		if (!e) gf_node_register(inf->new_node, com->node);
		if (!e) gf_node_event_out(com->node, inf->fieldIndex);
		if (!e) gf_node_changed(com->node, NULL);
		break;
	}
	case GF_SG_ROUTE_INSERT:
	{
		GF_Route *r;
		def = gf_sg_find_node(graph, com->fromNodeID);
		node = gf_sg_find_node(graph, com->toNodeID);
		if (!node || !def) return GF_SG_UNKNOWN_NODE;
		r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex);
		if (com->RouteID) gf_sg_route_set_id(r, com->RouteID);
		if (com->def_name) {
			gf_sg_route_set_name(r, com->def_name);
			free(com->def_name);
			com->def_name = NULL;
		}
		break;
	}
	case GF_SG_INDEXED_INSERT:
	{
		u32 sftype;
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		e = gf_node_get_field(com->node, inf->fieldIndex, &field);
		if (e) return e;

		/*rescale the MFField and parse the SFField*/
		if (field.fieldType != GF_SG_VRML_MFNODE) {
			if (inf->pos == -1) {
				e = gf_sg_vrml_mf_append(field.far_ptr, field.fieldType, & slot_ptr);
			} else {
				e = gf_sg_vrml_mf_insert(field.far_ptr, field.fieldType, & slot_ptr, inf->pos);
			}
			if (e) return e;
			sftype = gf_sg_vrml_get_sf_type(field.fieldType);
			gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype);
		} else {
			if (inf->new_node) {
				if (inf->pos == -1) {
					gf_node_list_add_child( (GF_ChildNodeItem **) field.far_ptr, inf->new_node);
				} else {
					gf_node_list_insert_child((GF_ChildNodeItem **) field.far_ptr, inf->new_node, inf->pos);
				}
				gf_node_register(inf->new_node, com->node);
			}
		}
		if (!e) SG_CheckFieldChange(com->node, &field);
		break;
	}
	case GF_SG_PROTO_INSERT:
		/*destroy all proto*/
		while (gf_list_count(com->new_proto_list)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0);
			gf_list_rem(com->new_proto_list, 0);
			gf_list_del_item(graph->unregistered_protos, p);
			gf_list_add(graph->protos, p);
		}
		return GF_OK;
	case GF_SG_PROTO_DELETE:
		{
			u32 i;
			for (i=0; i<com->del_proto_list_size; i++) {
				/*note this will check for unregistered protos, but since IDs are unique we are sure we will 
				not destroy an unregistered one*/
				GF_Proto *proto = gf_sg_find_proto(graph, com->del_proto_list[i], NULL);
				if (proto) gf_sg_proto_del(proto);
			}
		}
		return GF_OK;
	case GF_SG_PROTO_DELETE_ALL:
		/*destroy all proto*/
		while (gf_list_count(graph->protos)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0);
			gf_list_rem(graph->protos, 0);
			/*this will unregister the proto from the graph, so don't delete the chain entry*/
			gf_sg_proto_del(p);
		}
		/*DO NOT TOUCH UNREGISTERED PROTOS*/
		return GF_OK;
	/*only used by BIFS*/
	case GF_SG_GLOBAL_QUANTIZER:
		return GF_OK;

#ifndef GPAC_DISABLE_SVG
	/*laser commands*/
	case GF_SG_LSR_NEW_SCENE:
		/*DO NOT TOUCH node registry*/

		/*assign new root (no need to register/unregister)*/
		graph->RootNode = com->node;
		com->node = NULL;
		break;
	case GF_SG_LSR_DELETE:
		if (!com->node) return GF_NON_COMPLIANT_BITSTREAM;
		if (!gf_list_count(com->command_fields)) {
			gf_node_replace(com->node, NULL, 0);
			gf_node_deactivate(com->node);
			return GF_OK;
		}
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		node = gf_node_list_get_child(((SVG_Element *)com->node)->children, inf->pos);
		if (node) {
			e = gf_node_replace_child(com->node, &((SVG_Element *)com->node)->children, inf->pos, NULL);
			gf_node_deactivate(node);
		}
		break;
	case GF_SG_LSR_INSERT:
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		if (!com->node || !inf) return GF_NON_COMPLIANT_BITSTREAM;
		if (inf->new_node) {
			if (inf->pos<0) 
				gf_node_list_add_child(& ((SVG_Element *)com->node)->children, inf->new_node);
			else
				gf_node_list_insert_child(& ((SVG_Element *)com->node)->children, inf->new_node, inf->pos);

			gf_node_register(inf->new_node, com->node);
			gf_node_activate(inf->new_node);
			gf_node_changed(com->node, NULL);
		} else {
			/*NOT SUPPORTED*/
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[LASeR] VALUE INSERTION NOT SUPPORTED\n"));
		}
		break;
	case GF_SG_LSR_ADD:
	case GF_SG_LSR_REPLACE:
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		if (!com->node || !inf) return GF_NON_COMPLIANT_BITSTREAM;
		if (inf->new_node) {
			if (inf->pos<0) {
				/*if fieldIndex (eg attributeName) is set, this is children replacement*/
				if (inf->fieldIndex>0) {
					gf_node_unregister_children_deactivate(com->node, ((SVG_Element *)com->node)->children);
					((SVG_Element *)com->node)->children = NULL;
					gf_node_list_add_child(& ((SVG_Element *)com->node)->children, inf->new_node);
					gf_node_register(inf->new_node, com->node);
					gf_node_activate(inf->new_node);
				} else {
					e = gf_node_replace(com->node, inf->new_node, 0);
					gf_node_activate(inf->new_node);
				}
			} else {
				node = gf_node_list_get_child( ((SVG_Element *)com->node)->children, inf->pos);
				gf_node_replace_child(com->node, & ((SVG_Element *)com->node)->children, inf->pos, inf->new_node);
				gf_node_register(inf->new_node, com->node);
				if (node) gf_node_deactivate(node);
				gf_node_activate(inf->new_node);
			}
			/*signal node modif*/
			gf_node_changed(com->node, NULL);
			return e;
		} else if (inf->node_list) {
			GF_ChildNodeItem *child, *cur, *prev;
			gf_node_unregister_children_deactivate(com->node, ((SVG_Element *)com->node)->children);
			((SVG_Element *)com->node)->children = NULL;

			prev = NULL;
			child = inf->node_list;
			while (child) {
				cur = (GF_ChildNodeItem*)malloc(sizeof(GF_ChildNodeItem));
				cur->next = NULL;
				cur->node = child->node;
				gf_node_register(child->node, com->node);
				gf_node_activate(child->node);
				if (prev) prev->next = cur;
				else ((SVG_Element *)com->node)->children = cur;
				prev = cur;
				child = child->next;
			}
			/*signal node modif*/
			gf_node_changed(com->node, NULL);
			return GF_OK;
		}
		/*attribute modif*/
		else if (inf->field_ptr) {
			GF_FieldInfo a, b;
			if (inf->fieldIndex==(u32) -2) {
				GF_Point2D scale, translate;
				Fixed rotate;
				GF_Matrix2D *dest;
				gf_node_get_field_by_name(com->node, "transform", &a);
				dest = (GF_Matrix2D*)a.far_ptr;
				
				if (com->tag==GF_SG_LSR_REPLACE) {
					if (gf_mx2d_decompose(dest, &scale, &rotate, &translate)) {
						gf_mx2d_init(*dest);
						if (inf->fieldType==SVG_TRANSFORM_SCALE) scale = *(GF_Point2D *)inf->field_ptr;
						else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) translate = *(GF_Point2D *)inf->field_ptr;
						else if (inf->fieldType==SVG_TRANSFORM_ROTATE) rotate = ((SVG_Point_Angle*)inf->field_ptr)->angle;

						gf_mx2d_add_scale(dest, scale.x, scale.y);
						gf_mx2d_add_rotation(dest, 0, 0, rotate);
						gf_mx2d_add_translation(dest, translate.x, translate.y);
					}
				} else {
					GF_Point2D *pt = (GF_Point2D *)inf->field_ptr;
					if (inf->fieldType==SVG_TRANSFORM_SCALE) gf_mx2d_add_scale(dest, pt->x, pt->y);
					else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) gf_mx2d_add_translation(dest, pt->x, pt->y);
					else if (inf->fieldType == SVG_TRANSFORM_ROTATE) gf_mx2d_add_rotation(dest, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle);
				}
			} else {
				if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==SVG_String_datatype)) {
					char *str = *(SVG_String*)inf->field_ptr;

					if (com->tag == GF_SG_LSR_REPLACE) {
						GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; 
						if (t && (t->sgprivate->tag==TAG_DOMText)) {
							if (t->textContent) free(t->textContent);
							t->textContent = NULL;
							if (str) t->textContent = strdup(str);
						}
					} else {
						if (str) gf_dom_add_text_node(com->node, strdup(str));
					}
				}
				else if ((inf->fieldIndex==TAG_LSR_ATT_scale) 
					|| (inf->fieldIndex==TAG_LSR_ATT_translation)
					|| (inf->fieldIndex==TAG_LSR_ATT_rotation)
				) {
					SVG_Transform *mx;
					gf_svg_get_attribute_by_tag(com->node, TAG_SVG_ATT_transform, 1, 0, &a);
					mx = a.far_ptr;
					if (com->tag == GF_SG_LSR_REPLACE) {
						GF_Point2D scale, translate;
						SVG_Point_Angle rotate;
						if (gf_mx2d_decompose(&mx->mat, &scale, &rotate.angle, &translate)) {
							gf_mx2d_init(mx->mat);
							if (inf->fieldIndex==TAG_LSR_ATT_scale) scale = *(GF_Point2D *)inf->field_ptr;
							else if (inf->fieldIndex==TAG_LSR_ATT_translation) translate = *(GF_Point2D *)inf->field_ptr;
							else if (inf->fieldIndex==TAG_LSR_ATT_rotation) rotate = *(SVG_Point_Angle*)inf->field_ptr;

							gf_mx2d_add_scale(&mx->mat, scale.x, scale.y);
							gf_mx2d_add_rotation(&mx->mat, 0, 0, rotate.angle);
							gf_mx2d_add_translation(&mx->mat, translate.x, translate.y);
						}
					} else {
						if (inf->fieldIndex==TAG_LSR_ATT_scale) gf_mx2d_add_scale(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y);
						if (inf->fieldIndex==TAG_LSR_ATT_translation) gf_mx2d_add_translation(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y);
						if (inf->fieldIndex==TAG_LSR_ATT_rotation) gf_mx2d_add_rotation(&mx->mat, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle);
					}
				}
				else if (gf_svg_get_attribute_by_tag(com->node, inf->fieldIndex, 1, 0, &a) == GF_OK) {
					b = a;
					b.far_ptr = inf->field_ptr;
					if (com->tag == GF_SG_LSR_REPLACE) {
						gf_svg_attributes_copy(&a, &b, 0);
					} else {
						gf_svg_attributes_add(&a, &b, &a, 0);
					}
				}
				b = a;
				b.far_ptr = inf->field_ptr;
			}
			/*signal node modif*/
			gf_node_changed(com->node, &a);
		} else if (com->fromNodeID) {
			GF_FieldInfo a, b;
			GF_Node *fromNode = gf_sg_find_node(graph, com->fromNodeID);
			if (!fromNode) return GF_NON_COMPLIANT_BITSTREAM;
			if (gf_node_get_field(fromNode, com->fromFieldIndex, &b) != GF_OK) return GF_NON_COMPLIANT_BITSTREAM;

			if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==SVG_String_datatype)) {
				char *str = *(SVG_String*)inf->field_ptr;

				if (com->tag == GF_SG_LSR_REPLACE) {
					GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; 
					if (t && (t->sgprivate->tag==TAG_DOMText)) {
						if (t->textContent) free(t->textContent);
						t->textContent = NULL;
						if (str) t->textContent = strdup(str);
					}
				} else {
					if (str) gf_dom_add_text_node(com->node, strdup(str));
				}
			} else {
				gf_node_get_field(com->node, inf->fieldIndex, &a);
				if (com->tag == GF_SG_LSR_REPLACE) {
					e = gf_svg_attributes_copy(&a, &b, 0);
				} else {
					e = gf_svg_attributes_add(&a, &b, &a, 0);
				}
			}
			gf_node_changed(com->node, &a);
			return e;
		} else {
			return GF_NON_COMPLIANT_BITSTREAM;
		}
		break;
	case GF_SG_LSR_ACTIVATE:
		gf_node_activate(com->node);
		break;
	case GF_SG_LSR_DEACTIVATE:
		gf_node_deactivate(com->node);
		gf_node_changed(com->node, NULL);
		break;
#endif

	default:
		return GF_NOT_SUPPORTED;
	}
	if (e) return e;

	if (com->scripts_to_load) {
		while (gf_list_count(com->scripts_to_load)) {
			GF_Node *script = (GF_Node *)gf_list_get(com->scripts_to_load, 0);
			gf_list_rem(com->scripts_to_load, 0);
			gf_sg_script_load(script);
		}
		gf_list_del(com->scripts_to_load);
		com->scripts_to_load = NULL;
	}
	return GF_OK;
}
Пример #10
0
GF_EXPORT
void gf_sg_vrml_field_copy(void *dest, void *orig, u32 field_type)
{
	u32 size, i, sf_type;
	void *dst_field, *orig_field;

	if (!dest || !orig) return;

	switch (field_type) {
	case GF_SG_VRML_SFBOOL:
		memcpy(dest, orig, sizeof(SFBool));
		break;
	case GF_SG_VRML_SFCOLOR:
		memcpy(dest, orig, sizeof(SFColor));
		break;
	case GF_SG_VRML_SFFLOAT:
		memcpy(dest, orig, sizeof(SFFloat));
		break;
	case GF_SG_VRML_SFINT32:
		memcpy(dest, orig, sizeof(SFInt32));
		break;
	case GF_SG_VRML_SFROTATION:
		memcpy(dest, orig, sizeof(SFRotation));
		break;
	case GF_SG_VRML_SFTIME:
		memcpy(dest, orig, sizeof(SFTime));
		break;
	case GF_SG_VRML_SFVEC2F:
		memcpy(dest, orig, sizeof(SFVec2f));
		break;
	case GF_SG_VRML_SFVEC3F:
		memcpy(dest, orig, sizeof(SFVec3f));
		break;
	case GF_SG_VRML_SFSTRING:
		if ( ((SFString*)dest)->buffer) free(((SFString*)dest)->buffer);
		if ( ((SFString*)orig)->buffer )
			((SFString*)dest)->buffer = strdup(((SFString*)orig)->buffer);
		else
			((SFString*)dest)->buffer = NULL;
		break;
	case GF_SG_VRML_SFURL:
		if ( ((SFURL *)dest)->url ) free( ((SFURL *)dest)->url );
		((SFURL *)dest)->OD_ID = ((SFURL *)orig)->OD_ID;
		if (((SFURL *)orig)->url) 
			((SFURL *)dest)->url = strdup(((SFURL *)orig)->url);
		else
			((SFURL *)dest)->url = NULL;
		break;
	case GF_SG_VRML_SFIMAGE:
		if (((SFImage *)dest)->pixels) free(((SFImage *)dest)->pixels);
		((SFImage *)dest)->width = ((SFImage *)orig)->width;
		((SFImage *)dest)->height = ((SFImage *)orig)->height;
		((SFImage *)dest)->numComponents  = ((SFImage *)orig)->numComponents;
		size = ((SFImage *)dest)->width * ((SFImage *)dest)->height * ((SFImage *)dest)->numComponents;
		((SFImage *)dest)->pixels = (u8*)malloc(sizeof(char)*size);
		memcpy(((SFImage *)dest)->pixels, ((SFImage *)orig)->pixels, sizeof(char)*size);
		break;
	case GF_SG_VRML_SFCOMMANDBUFFER:
		gf_sg_sfcommand_del( *(SFCommandBuffer *)dest);
		((SFCommandBuffer *)dest)->commandList = gf_list_new();
		((SFCommandBuffer *)dest)->bufferSize = ((SFCommandBuffer *)orig)->bufferSize;
		if (((SFCommandBuffer *)dest)->bufferSize) {
			((SFCommandBuffer *)dest)->buffer = (u8*)malloc(sizeof(char)*((SFCommandBuffer *)orig)->bufferSize);
			memcpy(((SFCommandBuffer *)dest)->buffer, 
				((SFCommandBuffer *)orig)->buffer,
				sizeof(char)*((SFCommandBuffer *)orig)->bufferSize);
		} else {
			((SFCommandBuffer *)dest)->buffer = NULL;
		}
		break;

	/*simply copy text string*/
	case GF_SG_VRML_SFSCRIPT:
		if (((SFScript*)dest)->script_text) free(((SFScript*)dest)->script_text);		
		((SFScript*)dest)->script_text = NULL;
		if ( ((SFScript*)orig)->script_text)
			((SFScript *)dest)->script_text = (u8*)strdup( (char*) ((SFScript*)orig)->script_text );
		break;


	//MFFields
	case GF_SG_VRML_MFBOOL:
	case GF_SG_VRML_MFFLOAT:
	case GF_SG_VRML_MFTIME:
	case GF_SG_VRML_MFINT32:
	case GF_SG_VRML_MFSTRING:
	case GF_SG_VRML_MFVEC3F:
	case GF_SG_VRML_MFVEC2F:
	case GF_SG_VRML_MFCOLOR:
	case GF_SG_VRML_MFROTATION:
	case GF_SG_VRML_MFIMAGE:
	case GF_SG_VRML_MFURL:
	case GF_SG_VRML_MFSCRIPT:
		size = ((GenMFField *)orig)->count;
		gf_sg_vrml_mf_reset(dest, field_type);
		gf_sg_vrml_mf_alloc(dest, field_type, size);
		sf_type = gf_sg_vrml_get_sf_type(field_type);
		//duplicate all items
		for (i=0; i<size; i++) {
			gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i);
			gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i);
			gf_sg_vrml_field_copy(dst_field, orig_field, sf_type);
		}
		break;
	}
}
Пример #11
0
static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes)
{
    u32 i;
    SVG2BIFS_Converter *converter = (SVG2BIFS_Converter *)sax_cbck;
    SVGPropertiesPointers *backup_props;
    char *id_string = NULL;
    u32	tag;
    SVG_Element *elt;
    SVG_DeferedAnimation *anim = NULL;

    tag = gf_xml_get_element_tag(name, 0);
    elt = (SVG_Element*)gf_node_new(converter->svg_sg, tag);
    if (!gf_sg_get_root_node(converter->svg_sg)) {
        gf_node_register((GF_Node *)elt, NULL);
        gf_sg_set_root_node(converter->svg_sg, (GF_Node *)elt);
    } else {
        gf_node_register((GF_Node *)elt, converter->svg_parent);
        //gf_node_list_add_child(&((GF_ParentNode*)converter->svg_parent)->children, (GF_Node *)elt);
    }

//	fprintf(stdout, "Converting %s\n", gf_node_get_class_name((GF_Node *)elt));
//	if (converter->bifs_parent) fprintf(stdout, "%s\n", gf_node_get_class_name(converter->bifs_parent));

    if (gf_svg_is_animation_tag(tag)) {
        GF_SAFEALLOC(anim, SVG_DeferedAnimation);
        /*default anim target is parent node*/
        anim->animation_elt = elt;
        if (converter->svg_parent) {
            anim->target = anim->anim_parent = (SVG_Element*) converter->svg_parent;
        }
    }

    for (i=0; i<nb_attributes; i++) {
        GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i];
        if (!att->value || !strlen(att->value)) continue;

        if (!stricmp(att->name, "style")) {
            gf_svg_parse_style((GF_Node *)elt, att->value);
        } else if (!stricmp(att->name, "id") || !stricmp(att->name, "xml:id")) {
            gf_svg_parse_element_id((GF_Node *)elt, att->value, 0);
            id_string = att->value;
        } else if (anim && !stricmp(att->name, "to")) {
            anim->to = gf_strdup(att->value);
        } else if (anim && !stricmp(att->name, "from")) {
            anim->from = gf_strdup(att->value);
        } else if (anim && !stricmp(att->name, "by")) {
            anim->by = gf_strdup(att->value);
        } else if (anim && !stricmp(att->name, "values")) {
            anim->values = gf_strdup(att->value);
        } else if (anim && (tag == TAG_SVG_animateTransform) && !stricmp(att->name, "type")) {
            anim->type = gf_strdup(att->value);
        } else {
            GF_FieldInfo info;
            if (gf_node_get_field_by_name((GF_Node *)elt, att->name, &info)==GF_OK) {
                gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0);
            } else {
                fprintf(stdout, "Skipping attribute %s\n", att->name);
            }
        }
    }

    if (anim) {
        svg_parse_animation(converter->svg_sg, anim);
    }

    memset(&converter->all_atts, 0, sizeof(SVGAllAttributes));
    gf_svg_flatten_attributes(elt, &converter->all_atts);

    backup_props = gf_malloc(sizeof(SVGPropertiesPointers));
    memcpy(backup_props, &converter->svg_props, sizeof(SVGPropertiesPointers));
    gf_node_set_private((GF_Node *)elt, backup_props);

    gf_svg_apply_inheritance(&converter->all_atts, &converter->svg_props);

    fprintf(stdout, "START\t%s\t%s\t%s", converter->svg_parent ? gf_node_get_class_name(converter->svg_parent) : "none", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none", name);
    converter->svg_parent = (GF_Node *)elt;
    if (!gf_sg_get_root_node(converter->bifs_sg)) {
        if (tag == TAG_SVG_svg) {
            GF_Node *node, *child;

            converter->bifs_sg->usePixelMetrics = 1;
            if (converter->all_atts.width && converter->all_atts.width->type == SVG_NUMBER_VALUE) {
                converter->bifs_sg->width = FIX2INT(converter->all_atts.width->value);
            } else {
                converter->bifs_sg->width = 320;
            }
            if (converter->all_atts.height && converter->all_atts.height->type == SVG_NUMBER_VALUE) {
                converter->bifs_sg->height = FIX2INT(converter->all_atts.height->value);
            } else {
                converter->bifs_sg->height = 200;
            }

            node = gf_node_new(converter->bifs_sg, TAG_MPEG4_OrderedGroup);
            gf_node_register(node, NULL);
            gf_sg_set_root_node(converter->bifs_sg, node);

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_QuantizationParameter);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_QuantizationParameter *qp = (M_QuantizationParameter *)child;
                qp->useEfficientCoding = 1;
            }

            /* SVG to BIFS coordinate transformation */
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Viewport);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_Viewport *vp = (M_Viewport*)child;
                if (converter->all_atts.viewBox) {
                    vp->size.x = converter->all_atts.viewBox->width;
                    vp->size.y = converter->all_atts.viewBox->height;
                    vp->position.x = converter->all_atts.viewBox->x+converter->all_atts.viewBox->width/2;
                    vp->position.y = -(converter->all_atts.viewBox->y+converter->all_atts.viewBox->height/2);
                } else {
                    vp->size.x = INT2FIX(converter->bifs_sg->width);
                    vp->size.y = INT2FIX(converter->bifs_sg->height);
                    vp->position.x = INT2FIX(converter->bifs_sg->width)/2;
                    vp->position.y = -INT2FIX(converter->bifs_sg->height)/2;
                }
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Background2D);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_Background2D *b = (M_Background2D *)child;
                b->backColor.red = FIX_ONE;
                b->backColor.green = FIX_ONE;
                b->backColor.blue = FIX_ONE;
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            {
                M_Transform2D *tr = (M_Transform2D *)node;
                tr->scale.y = -FIX_ONE;
            }
            converter->bifs_parent = node;
        }
    } else {
        GF_Node *node, *child;

        node = converter->bifs_parent;

        switch(tag) {
        case TAG_SVG_g:
        {
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
            } else {
                M_Group *g = (M_Group*)gf_node_new(converter->bifs_sg, TAG_MPEG4_Group);
                gf_node_register((GF_Node *)g, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, (GF_Node *)g);
                node = (GF_Node *)g;
                converter->bifs_parent = node;
            }
        }
        break;
        case TAG_SVG_rect:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            if (converter->all_atts.x || converter->all_atts.y) {
                child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
                gf_node_register(child, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
                node = child;
                child = NULL;
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
                {
                    M_Transform2D *tr = (M_Transform2D *)node;
                    if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value + (converter->all_atts.width?converter->all_atts.width->value/2:0);
                    if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value + (converter->all_atts.height?converter->all_atts.height->value/2:0);
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_Rectangle);
                gf_node_register(shape->geometry, (GF_Node *)shape);
                {
                    M_Rectangle *rect = (M_Rectangle *)shape->geometry;
                    if (converter->all_atts.width) rect->size.x = converter->all_atts.width->value;
                    if (converter->all_atts.height) rect->size.y = converter->all_atts.height->value;
                }

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_path:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            if (converter->all_atts.x || converter->all_atts.y) {
                child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
                gf_node_register(child, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
                node = child;
                child = NULL;
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
                {
                    M_Transform2D *tr = (M_Transform2D *)node;
                    if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value;
                    if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value;
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_XCurve2D);
                gf_node_register(shape->geometry, (GF_Node *)shape);
                if (converter->all_atts.d) {
                    M_Coordinate2D *c2d;
                    M_XCurve2D *xc = (M_XCurve2D *)shape->geometry;
                    u32 i, j, c, k;

                    xc->point = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
                    c2d = (M_Coordinate2D *)xc->point;
                    gf_node_register(xc->point, (GF_Node *)xc);

                    gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, converter->all_atts.d->n_points);
                    gf_sg_vrml_mf_alloc(&xc->type, GF_SG_VRML_MFINT32, converter->all_atts.d->n_points);

                    c = 0;
                    k = 0;
                    j = 0;
                    c2d->point.vals[k] = converter->all_atts.d->points[0];
                    k++;
                    xc->type.vals[0] = 0;
                    for (i = 1; i < converter->all_atts.d->n_points; ) {
                        switch(converter->all_atts.d->tags[i]) {
                        case GF_PATH_CURVE_ON:
                            c2d->point.vals[k] = converter->all_atts.d->points[i];
                            k++;

                            if (i-1 == converter->all_atts.d->contours[c]) {
                                xc->type.vals[j] = 0;
                                c++;
                            } else {
                                xc->type.vals[j] = 1;
                            }
                            i++;
                            break;
                        case GF_PATH_CURVE_CUBIC:
                            c2d->point.vals[k] = converter->all_atts.d->points[i];
                            c2d->point.vals[k+1] = converter->all_atts.d->points[i+1];
                            c2d->point.vals[k+2] = converter->all_atts.d->points[i+2];
                            k+=3;

                            xc->type.vals[j] = 2;
                            if (converter->all_atts.d->tags[i+2]==GF_PATH_CLOSE)  {
                                j++;
                                xc->type.vals[j] = 6;
                            }
                            i+=3;
                            break;
                        case GF_PATH_CLOSE:
                            xc->type.vals[j] = 6;
                            i++;
                            break;
                        case GF_PATH_CURVE_CONIC:
                            c2d->point.vals[k] = converter->all_atts.d->points[i];
                            c2d->point.vals[k+1] = converter->all_atts.d->points[i+1];
                            k+=2;

                            xc->type.vals[j] = 7;
                            if (converter->all_atts.d->tags[i+1]==GF_PATH_CLOSE)  {
                                j++;
                                xc->type.vals[j] = 6;
                            }
                            i+=2;
                            break;
                        }
                        j++;
                    }
                    xc->type.count = j;
                    c2d->point.count = k;
                }

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_polyline:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_IndexedFaceSet2D);
                gf_node_register(shape->geometry, (GF_Node *)shape);
                if (converter->all_atts.points) {
                    M_Coordinate2D *c2d;
                    M_IndexedFaceSet2D *ifs = (M_IndexedFaceSet2D *)shape->geometry;
                    u32 i;

                    ifs->coord = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
                    c2d = (M_Coordinate2D *)ifs->coord;
                    gf_node_register(ifs->coord, (GF_Node *)ifs);

                    gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, gf_list_count(*converter->all_atts.points));
                    for (i = 0; i < gf_list_count(*converter->all_atts.points); i++) {
                        SVG_Point *p = (SVG_Point *)gf_list_get(*converter->all_atts.points, i);
                        c2d->point.vals[i].x = p->x;
                        c2d->point.vals[i].y = p->y;
                    }
                }

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_text:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_Transform2D *tr = (M_Transform2D *)child;
                if (converter->all_atts.text_x) tr->translation.x = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_x, 0))->value;
                if (converter->all_atts.text_y) tr->translation.y = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_y, 0))->value;
                tr->scale.y = -FIX_ONE;
            }
            node = child;
            child = NULL;
            if (!is_parent_set) {
                converter->bifs_parent = node;
                is_parent_set = 1;
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_FontStyle *fs;
                M_Text *text;
                M_Shape *shape = (M_Shape *)node;
                text = (M_Text *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Text);
                shape->geometry = (GF_Node *)text;
                converter->bifs_text_node = shape->geometry;
                gf_node_register(shape->geometry, (GF_Node *)shape);

                fs = (M_FontStyle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_XFontStyle);
                gf_node_register((GF_Node *)fs, (GF_Node*)text);
                text->fontStyle = (GF_Node *)fs;

                gf_sg_vrml_mf_alloc(&fs->family, GF_SG_VRML_MFSTRING, 1);
                fs->family.vals[0] = gf_strdup(converter->svg_props.font_family->value);
                fs->size = converter->svg_props.font_size->value;

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_ellipse:
        case TAG_SVG_circle:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            if (converter->all_atts.cx || converter->all_atts.cy) {
                child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
                gf_node_register(child, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
                {
                    M_Transform2D *tr = (M_Transform2D *)child;
                    if (converter->all_atts.cx) tr->translation.x = converter->all_atts.cx->value;
                    if (converter->all_atts.cy) tr->translation.y = converter->all_atts.cy->value;
                }
                node = child;
                child = NULL;
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                if (tag == TAG_SVG_ellipse) {
                    M_Ellipse *e = (M_Ellipse *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Ellipse);
                    shape->geometry = (GF_Node *)e;
                    e->radius.x = converter->all_atts.rx->value;
                    e->radius.y = converter->all_atts.ry->value;
                } else {
                    M_Circle *c = (M_Circle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Circle);
                    shape->geometry = (GF_Node *)c;
                    c->radius = converter->all_atts.r->value;
                }
                gf_node_register(shape->geometry, (GF_Node *)shape);

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;

        case TAG_SVG_defs:
        {
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Switch);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            {
                M_Switch *sw = (M_Switch *)node;
                sw->whichChoice = -1;
            }
            converter->bifs_parent = node;
        }
        break;
        case TAG_SVG_solidColor:
        {
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            converter->bifs_parent = node;
        }
        break;
        case TAG_SVG_animateTransform:
        {
            GF_Node *child_ts;
            if (!gf_node_get_id(node)) {
                gf_node_set_id(node, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
            }

            child_ts = gf_node_new(converter->bifs_sg, TAG_MPEG4_TimeSensor);
            if (!gf_node_get_id(child_ts)) {
                gf_node_set_id(child_ts, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
            }
            gf_node_register(child_ts, node);
            gf_node_list_add_child(&((GF_ParentNode *)node)->children, child_ts);
            {
                M_TimeSensor *ts = (M_TimeSensor *)child_ts;
                if (converter->all_atts.dur) {
                    ts->cycleInterval = converter->all_atts.dur->clock_value;
                }
                if (converter->all_atts.repeatCount && converter->all_atts.repeatCount->type == SMIL_REPEATCOUNT_INDEFINITE) {
                    ts->loop = 1;
                }
            }

            if (converter->all_atts.transform_type) {
                GF_FieldInfo fromField, toField;

                switch (*converter->all_atts.transform_type) {
                case SVG_TRANSFORM_ROTATE:
                    child = gf_node_new(converter->bifs_sg, TAG_MPEG4_PositionInterpolator2D);
                    if (!gf_node_get_id(child)) {
                        gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
                    }
                    gf_node_register(child, node);
                    gf_node_list_add_child(&((GF_ParentNode *)node)->children, child);

                    gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField);
                    gf_node_get_field_by_name(child, "set_fraction", &toField);
                    gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex);

                    gf_node_get_field_by_name(child, "value_changed", &fromField);
                    gf_node_get_field_by_name(node, "rotationAngle", &toField);
                    gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex);
                    {
                        M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child;
                        if (converter->all_atts.keyTimes) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(*converter->all_atts.keyTimes);
                            for (i = 0; i < count; i++) {
                                Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i);
                                gf_sg_vrml_mf_append(&pi2d->key, GF_SG_VRML_MFFLOAT, &g);
                                *g = *f;
                            }
                        }
                        if (converter->all_atts.values) {
                            SFVec2f *g;
                            u32 count, i;
                            count = gf_list_count(converter->all_atts.values->values);
                            for (i = 0; i < count; i++) {
                                SVG_Point_Angle *p;
                                p = gf_list_get(converter->all_atts.values->values, i);
                                gf_sg_vrml_mf_append(&pi2d->keyValue, GF_SG_VRML_MFVEC2F, &g);
                                g->x = p->x;
                                g->y = p->y;
                            }
                        }
                    }


                    child = gf_node_new(converter->bifs_sg, TAG_MPEG4_ScalarInterpolator);
                    if (!gf_node_get_id(child)) {
                        gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
                    }
                    gf_node_register(child, node);
                    gf_node_list_add_child(&((GF_ParentNode *)node)->children, child);

                    gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField);
                    gf_node_get_field_by_name(child, "set_fraction", &toField);
                    gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex);

                    gf_node_get_field_by_name(child, "value_changed", &fromField);
                    gf_node_get_field_by_name(node, "center", &toField);
                    gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex);

                    {
                        M_ScalarInterpolator *si = (M_ScalarInterpolator *)child;
                        if (converter->all_atts.keyTimes) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(*converter->all_atts.keyTimes);
                            for (i = 0; i < count; i++) {
                                Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i);
                                gf_sg_vrml_mf_append(&si->key, GF_SG_VRML_MFFLOAT, &g);
                                *g = *f;
                            }
                        }
                        if (converter->all_atts.values) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(converter->all_atts.values->values);
                            for (i = 0; i < count; i++) {
                                SVG_Point_Angle *p;
                                p = gf_list_get(converter->all_atts.values->values, i);
                                gf_sg_vrml_mf_append(&si->keyValue, GF_SG_VRML_MFFLOAT, &g);
                                *g = p->angle;
                            }
                        }
                    }

                    break;

                case SVG_TRANSFORM_SCALE:
                case SVG_TRANSFORM_TRANSLATE:
                    child = gf_node_new(converter->bifs_sg, TAG_MPEG4_PositionInterpolator2D);
                    if (!gf_node_get_id(child)) {
                        gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
                    }
                    gf_node_register(child, node);
                    gf_node_list_add_child(&((GF_ParentNode *)node)->children, child);

                    gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField);
                    gf_node_get_field_by_name(child, "set_fraction", &toField);
                    gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex);

                    gf_node_get_field_by_name(child, "value_changed", &fromField);
                    if (*converter->all_atts.transform_type == SVG_TRANSFORM_SCALE)
                        gf_node_get_field_by_name(node, "scale", &toField);
                    else
                        gf_node_get_field_by_name(node, "translation", &toField);

                    gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex);
                    {
                        M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child;
                        if (converter->all_atts.keyTimes) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(*converter->all_atts.keyTimes);
                            for (i = 0; i < count; i++) {
                                Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i);
                                gf_sg_vrml_mf_append(&pi2d->key, GF_SG_VRML_MFFLOAT, &g);
                                *g = *f;
                            }
                        }
                        if (converter->all_atts.values) {
                            SFVec2f *g;
                            u32 count, i;
                            count = gf_list_count(converter->all_atts.values->values);
                            for (i = 0; i < count; i++) {
                                SVG_Point *p;
                                p = gf_list_get(converter->all_atts.values->values, i);
                                gf_sg_vrml_mf_append(&pi2d->keyValue, GF_SG_VRML_MFVEC2F, &g);
                                g->x = p->x;
                                g->y = p->y;
                            }
                        }
                    }
                    break;
                default:
                    fprintf(stdout, "Warning: transformation type not supported \n");
                }
            }
            //converter->bifs_parent = node;
        }
        break;
        default:
        {
            fprintf(stdout, "Warning: element %s not supported \n", gf_node_get_class_name((GF_Node *)elt));
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
            gf_node_register(child, node);
            //gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            converter->bifs_parent = node;
        }
        break;
        }

        if (id_string)
            gf_node_set_id(converter->bifs_parent, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);//gf_node_get_name((GF_Node *)elt));

    }
    fprintf(stdout, "\t%s\n", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none");
}
Пример #12
0
static void SetValuatorOutput(M_Valuator *p, SFVec4f *inSFField, GenMFField *inMFField, u32 inType)
{
	char str[500];
	u32 i, j;
	GF_Route *r;
	SFVec4f output, sf_out;
	MFVec4f *mf_output = (MFVec4f *)gf_node_get_private((GF_Node*)p);
	u32 count, num_out;
	Bool do_sum;
	output.x = output.y = output.z = output.q = 0;
	sf_out.x = sf_out.y = sf_out.z = sf_out.q = 0;
	if (!p->sgprivate->interact || !mf_output) return;

	do_sum = p->Sum;
	num_out = 1;

	if (!inMFField) {
		count = 1;
		output.x = gf_mulfix(p->Factor1, inSFField->x) + p->Offset1;
		output.y = gf_mulfix(p->Factor2, inSFField->y) + p->Offset2;
		output.z = gf_mulfix(p->Factor3, inSFField->z) + p->Offset3;
		output.q = gf_mulfix(p->Factor4, inSFField->q) + p->Offset4;

		if (do_sum) {
			output.x = output.x + output.y + output.z + output.q;
			output.y = output.z = output.q = output.x;
			do_sum = 0;
		}

		switch (inType) {
		case GF_SG_VRML_SFVEC2F:
			num_out = 2;
			break;
		case GF_SG_VRML_SFVEC3F:
		case GF_SG_VRML_SFCOLOR:
			num_out = 3;
			break;
		case GF_SG_VRML_SFVEC4F:
		case GF_SG_VRML_SFROTATION:
			num_out = 4;
			break;
		}
	} else {
		count = inMFField->count;
	}

	/*allocate temp buffer and compute values*/
	gf_sg_vrml_mf_alloc(mf_output, GF_SG_VRML_MFVEC4F, count);
	for (i=0; i<count; i++) {
		if (inType) {
			valuator_get_output(p, inMFField, inType, do_sum, i, &output, &num_out);
			mf_output->vals[i] = output;
		} else if (!i) {
			mf_output->vals[0] = output;
		}
		if (!i) sf_out = output;
	}

	gf_sg_vrml_mf_alloc(&p->outMFColor, GF_SG_VRML_MFCOLOR, count);
	gf_sg_vrml_mf_alloc(&p->outMFFloat, GF_SG_VRML_MFFLOAT, count);
	gf_sg_vrml_mf_alloc(&p->outMFInt32, GF_SG_VRML_MFINT32, count);
	gf_sg_vrml_mf_alloc(&p->outMFRotation, GF_SG_VRML_MFROTATION, count);
	gf_sg_vrml_mf_alloc(&p->outMFString, GF_SG_VRML_MFSTRING, count);	gf_sg_vrml_mf_alloc(&p->outMFVec2f, GF_SG_VRML_MFVEC2F, count);
	gf_sg_vrml_mf_alloc(&p->outMFVec3f, GF_SG_VRML_MFVEC3F, count);

	/*valuator is a special case, all routes are triggered*/
	j=0;
	while ((r = (GF_Route*)gf_list_enum(p->sgprivate->interact->routes, &j))) {
		if (r->FromNode != (GF_Node *)p) continue;
		if (!r->is_setup) gf_sg_route_setup(r);
		if (r->FromField.eventType != GF_SG_EVENT_OUT) continue;

		/*TODO we could optimize more and check if the field has been set or not ...*/
		switch (r->FromField.fieldType) {
		case GF_SG_VRML_SFBOOL:
			p->outSFBool = (Bool) (sf_out.x ? 1 : 0);
			break;
		case GF_SG_VRML_SFFLOAT:
			p->outSFFloat = sf_out.x;
			break;
		case GF_SG_VRML_SFINT32:
			p->outSFInt32 = FIX2INT(sf_out.x);
			break;
		case GF_SG_VRML_SFTIME:
			p->outSFTime = (SFTime) FIX2FLT(sf_out.x);
			break;
		case GF_SG_VRML_SFROTATION:
			p->outSFRotation.x = sf_out.x;
			p->outSFRotation.y = sf_out.y;
			p->outSFRotation.z = sf_out.z;
			p->outSFRotation.q = sf_out.q;
			break;
		case GF_SG_VRML_SFCOLOR:
			p->outSFColor.red = sf_out.x;
			p->outSFColor.green = sf_out.y;
			p->outSFColor.blue = sf_out.z;
			break;
		case GF_SG_VRML_SFVEC2F:
			p->outSFVec2f.x = sf_out.x;
			p->outSFVec2f.y = sf_out.y;
			break;
		case GF_SG_VRML_SFVEC3F:
			p->outSFVec3f.x = sf_out.x;
			p->outSFVec3f.y = sf_out.y;
			p->outSFVec3f.z = sf_out.z;
			break;
		case GF_SG_VRML_SFSTRING:
			if (num_out==1) {
				if (inType==GF_SG_VRML_SFTIME) {
					format_sftime_string(output.x, str);
				} else {
					sprintf(str, "%.6f", FIX2FLT(sf_out.x));
				}
			} else if (num_out==2) {
				sprintf(str, "%.4f %.4f", FIX2FLT(sf_out.x), FIX2FLT(sf_out.y));
			} else if (num_out==3) {
				sprintf(str, "%.3f %.3f %.3f", FIX2FLT(sf_out.x), FIX2FLT(sf_out.y), FIX2FLT(sf_out.z));
			} else if (num_out==4) {
				sprintf(str, "%.2f %.2f %.2f %.2f", FIX2FLT(sf_out.x), FIX2FLT(sf_out.y), FIX2FLT(sf_out.z), FIX2FLT(sf_out.q));
			}
			if (p->outSFString.buffer ) gf_free(p->outSFString.buffer);
			p->outSFString.buffer = gf_strdup(str);
			break;


		case GF_SG_VRML_MFFLOAT:
			gf_sg_vrml_mf_alloc(&p->outMFFloat, GF_SG_VRML_MFFLOAT, count);
			for (i=0; i<count; i++)
				p->outMFFloat.vals[i] = mf_output->vals[i].x;
			break;
		case GF_SG_VRML_MFINT32:
			gf_sg_vrml_mf_alloc(&p->outMFInt32, GF_SG_VRML_MFINT32, count);
			for (i=0; i<count; i++)
				p->outMFInt32.vals[i] = FIX2INT(mf_output->vals[i].x);
			break;
		case GF_SG_VRML_MFCOLOR:
			gf_sg_vrml_mf_alloc(&p->outMFColor, GF_SG_VRML_MFCOLOR, count);
			for (i=0; i<count; i++) {
				p->outMFColor.vals[i].red = mf_output->vals[i].x;
				p->outMFColor.vals[i].green = mf_output->vals[i].y;
				p->outMFColor.vals[i].blue = mf_output->vals[i].z;
			}
			break;
		case GF_SG_VRML_MFVEC2F:
			gf_sg_vrml_mf_alloc(&p->outMFVec2f, GF_SG_VRML_MFVEC2F, count);
			for (i=0; i<count; i++) {
				p->outMFVec2f.vals[i].x = mf_output->vals[i].x;
				p->outMFVec2f.vals[i].y = mf_output->vals[i].y;
			}
			break;
		case GF_SG_VRML_MFVEC3F:
			gf_sg_vrml_mf_alloc(&p->outMFVec3f, GF_SG_VRML_MFVEC3F, count);
			for (i=0; i<count; i++) {
				p->outMFVec3f.vals[i].x = mf_output->vals[i].x;
				p->outMFVec3f.vals[i].y = mf_output->vals[i].y;
				p->outMFVec3f.vals[i].z = mf_output->vals[i].z;
			}
			break;
		case GF_SG_VRML_MFROTATION:
			gf_sg_vrml_mf_alloc(&p->outMFRotation, GF_SG_VRML_MFROTATION, count);
			for (i=0; i<count; i++) {
				p->outMFRotation.vals[i].x = mf_output->vals[i].x;
				p->outMFRotation.vals[i].y = mf_output->vals[i].y;
				p->outMFRotation.vals[i].z = mf_output->vals[i].z;
				p->outMFRotation.vals[i].q = mf_output->vals[i].q;
			}
			break;
		case GF_SG_VRML_MFSTRING:
			gf_sg_vrml_mf_alloc(&p->outMFString, GF_SG_VRML_MFSTRING, count);	gf_sg_vrml_mf_alloc(&p->outMFVec2f, GF_SG_VRML_MFVEC2F, count);
			for (i=0; i<count; i++) {
				if (num_out==1) {
					if (inType==GF_SG_VRML_SFTIME) {
						format_sftime_string(mf_output->vals[i].x, str);
					} else {
						sprintf(str, "%g", FIX2FLT(mf_output->vals[i].x));
					}
				} else if (num_out==2) {
					sprintf(str, "%g %g", FIX2FLT(mf_output->vals[i].x), FIX2FLT(mf_output->vals[i].y));
				} else if (num_out==3) {
					sprintf(str, "%g %g %g", FIX2FLT(mf_output->vals[i].x), FIX2FLT(mf_output->vals[i].y), FIX2FLT(mf_output->vals[i].z));
				} else if (num_out==4) {
					sprintf(str, "%g %g %g %g", FIX2FLT(mf_output->vals[i].x), FIX2FLT(mf_output->vals[i].y), FIX2FLT(mf_output->vals[i].z), FIX2FLT(mf_output->vals[i].q));
				}
				if (p->outMFString.vals[i]) gf_free(p->outMFString.vals[i]);
				p->outMFString.vals[i] = gf_strdup(str);
			}
			break;
		}
		if (r->IS_route) {
			gf_sg_route_activate(r);
		} else {
			gf_sg_route_queue(p->sgprivate->scenegraph, r);
		}
	}
}
Пример #13
0
void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos)
{
	GF_Segment *desc;
	u32 i, count, j, ms_count;
	Double time;
	ms_count = gf_list_count(odm->ms_stack);
	if (!ms_count) return;
	
	time = odm->current_time / 1000.0;

	for (j=0; j<ms_count; j++) {
		MediaSensorStack *media_sens = (MediaSensorStack *)gf_list_get(odm->ms_stack, j);
		if (!media_sens->is_init) continue;
		count = gf_list_count(media_sens->seg);
		
		/*full object controled*/
		if (!media_sens->active_seg && !count) {
			/*check for end of scene (MediaSensor on inline)*/
			if (odm->subscene && odm->subscene->duration) {
				GF_Clock *ck = gf_odm_get_media_clock(odm);
				if (ck->has_seen_eos && (1000*time>=(Double) (s64)odm->subscene->duration)) {
					if (media_sens->sensor->isActive) {
						/*force notification of time (ntify the scene duration rather than the current clock*/
						media_sens->sensor->mediaCurrentTime = (Double) odm->subscene->duration;
						media_sens->sensor->mediaCurrentTime /= 1000;
						gf_node_event_out((GF_Node *) media_sens->sensor, 1/*"mediaCurrentTime"*/);
						media_sens->sensor->isActive = 0;
						gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);

						GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor\n", odm->OD->objectDescriptorID));
					}
					continue;
				}
			}

			if (!is_eos && !media_sens->sensor->isActive) {
				media_sens->sensor->isActive = 1;
				gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
				if (odm->subscene) {
					media_sens->sensor->mediaDuration = (Double) (s64)odm->subscene->duration;
				} else {
					media_sens->sensor->mediaDuration = (Double) (s64)odm->duration;
				}
				if (media_sens->sensor->mediaDuration)
					media_sens->sensor->mediaDuration /= 1000;
				else
					media_sens->sensor->mediaDuration = -FIX_ONE;

				gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/);
			}

			if (is_eos && media_sens->sensor->isActive) {
				if (media_sens->sensor->mediaDuration>=0) {
					media_sens->sensor->mediaCurrentTime = media_sens->sensor->mediaDuration;
				} else {
					media_sens->sensor->mediaCurrentTime = time;
				}
				gf_node_event_out((GF_Node *) media_sens->sensor, 1/*"mediaCurrentTime"*/);
				media_sens->sensor->isActive = 0;
				gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
			} else {
				if (media_sens->sensor->isActive && (media_sens->sensor->mediaCurrentTime != time)) {
					media_sens->sensor->mediaCurrentTime = time;
					gf_node_event_out((GF_Node *) media_sens->sensor, 1/*"mediaCurrentTime"*/);
				}
			}
			continue;
		}

		/*locate segment*/
		for (i=media_sens->active_seg; i<count; i++) {
			desc = (GF_Segment*)gf_list_get(media_sens->seg, i);
			/*not controled*/
			if (desc->startTime > time) {
				if (media_sens->sensor->isActive) {
					media_sens->sensor->isActive = 0;
					gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);

					GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor at time %g - segment %s\n", odm->OD->objectDescriptorID, time, desc->SegmentName));
				}
				break;
			}
			if (desc->startTime + desc->Duration < time) continue;
			if (desc->startTime + desc->Duration == time) {
				continue;
			}
			/*segment switch, force activation (isActive TRUE send at each seg)*/
			if (media_sens->active_seg != i) {
				media_sens->active_seg = i;
				media_sens->sensor->isActive = 0;
			}

			if (!media_sens->sensor->isActive) {
				media_sens->sensor->isActive = 1;
				gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
				/*set info*/
				gf_sg_vrml_mf_reset(& media_sens->sensor->info, GF_SG_VRML_MFSTRING);
				gf_sg_vrml_mf_alloc(& media_sens->sensor->info, GF_SG_VRML_MFSTRING, 1);
				media_sens->sensor->info.vals[0] = desc->SegmentName ? gf_strdup(desc->SegmentName) : NULL;
				gf_node_event_out((GF_Node *) media_sens->sensor, 5/*"info"*/);
				/*set duration*/
				media_sens->sensor->mediaDuration = desc->Duration;
				gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/);
				/*set seg start time*/
				media_sens->sensor->streamObjectStartTime = desc->startTime;
				gf_node_event_out((GF_Node *) media_sens->sensor, 2/*"streamObjectStartTime"*/);

				GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Activating media sensor time %g - segment %s\n", odm->OD->objectDescriptorID, time, desc->SegmentName));
			}
			/*set media time - relative to segment start time*/
			time -= desc->startTime;
			if (media_sens->sensor->mediaCurrentTime != time) {
				media_sens->sensor->mediaCurrentTime = time;
				gf_node_event_out((GF_Node *) media_sens->sensor, 1/*"mediaCurrentTime"*/);
			}
			break;
		}
		if (i==count) {
			/*we're after last segment, deactivate*/
			if (media_sens->sensor->isActive) {
				media_sens->sensor->isActive = 0;
				gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/);
				media_sens->active_seg = count;
				GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor at time %g: no more segments\n", odm->OD->objectDescriptorID, time));
			}
		}
	}
}
Пример #14
0
static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes)
{
	u32 i;
	SVG_SANI_BIFS_Converter *converter = (SVG_SANI_BIFS_Converter *)sax_cbck;
	SVGPropertiesPointers *backup_props;
	char *id_string = NULL;

	u32	tag = gf_svg_get_element_tag(name);
	SVG_Element *elt = (SVG_Element*)gf_node_new(converter->svg_sg, tag);
	if (!gf_sg_get_root_node(converter->svg_sg)) {
		gf_node_register((GF_Node *)elt, NULL);
		gf_sg_set_root_node(converter->svg_sg, (GF_Node *)elt);
	} else {
		gf_node_register((GF_Node *)elt, converter->svg_parent);	
		//gf_node_list_add_child(&((GF_ParentNode*)converter->svg_parent)->children, (GF_Node *)elt);
	}
	converter->svg_parent = (GF_Node *)elt;
	
//	fprintf(stdout, "Converting %s\n", gf_node_get_class_name((GF_Node *)elt));
//	if (converter->bifs_parent) fprintf(stdout, "%s\n", gf_node_get_class_name(converter->bifs_parent));

	for (i=0; i<nb_attributes; i++) {
		GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i];
		if (!att->value || !strlen(att->value)) continue;

		if (!stricmp(att->name, "style")) {
			gf_svg_parse_style((GF_Node *)elt, att->value);
		} else if (!stricmp(att->name, "id") || !stricmp(att->name, "xml:id")) {
			gf_svg_parse_element_id((GF_Node *)elt, att->value, 0);
			id_string = att->value;
		} else {
			GF_FieldInfo info;
			if (gf_node_get_field_by_name((GF_Node *)elt, att->name, &info)==GF_OK) {
				gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0);
			} else {
				fprintf(stdout, "Skipping attribute %s\n", att->name);
			}
		}
	}

	memset(&converter->all_atts, 0, sizeof(SVGAllAttributes));
	gf_svg_flatten_attributes(elt, &converter->all_atts);
	
	backup_props = gf_malloc(sizeof(SVGPropertiesPointers));
	memcpy(backup_props, &converter->svg_props, sizeof(SVGPropertiesPointers));
	gf_node_set_private((GF_Node *)elt, backup_props);

	gf_svg_apply_inheritance(&converter->all_atts, &converter->svg_props);

	if (!gf_sg_get_root_node(converter->bifs_sg)) {
		if (tag == TAG_SVG_svg) {
			GF_Node *node, *child;

			converter->bifs_sg->usePixelMetrics = 1;
			if (converter->all_atts.width && converter->all_atts.width->type == SVG_NUMBER_VALUE) {
				converter->bifs_sg->width = FIX2INT(converter->all_atts.width->value);
			} else {
				converter->bifs_sg->width = 320;
			}
			if (converter->all_atts.height && converter->all_atts.height->type == SVG_NUMBER_VALUE) {
				converter->bifs_sg->height = FIX2INT(converter->all_atts.height->value);
			} else {
				converter->bifs_sg->height = 200;
			}

			node = gf_node_new(converter->bifs_sg, TAG_MPEG4_OrderedGroup);
			gf_node_register(node, NULL);
			gf_sg_set_root_node(converter->bifs_sg, node);

			/* SVG to BIFS coordinate transformation */
			child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Viewport);
			gf_node_register(child, node);
			gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
			if (converter->all_atts.viewBox) {
				M_Viewport *vp = (M_Viewport*)child;
				vp->size.x = converter->all_atts.viewBox->width;
				vp->size.y = converter->all_atts.viewBox->height;
				vp->position.x = converter->all_atts.viewBox->x+converter->all_atts.viewBox->width/2;
				vp->position.y = -(converter->all_atts.viewBox->y+converter->all_atts.viewBox->height/2);
			} else {
				M_Viewport *vp = (M_Viewport*)child;
				vp->size.x = INT2FIX(converter->bifs_sg->width);
				vp->size.y = INT2FIX(converter->bifs_sg->height);
				vp->position.x = INT2FIX(converter->bifs_sg->width)/2;
				vp->position.y = -INT2FIX(converter->bifs_sg->height)/2;
			}

			child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Background2D);
			gf_node_register(child, node);
			gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
			{
				M_Background2D *b = (M_Background2D *)child;
				b->backColor.red = FIX_ONE;
				b->backColor.green = FIX_ONE;				
				b->backColor.blue = FIX_ONE;
			}

			child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
			gf_node_register(child, node);
			gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
			node = child;
			child = NULL;
			{
				M_Transform2D *tr = (M_Transform2D *)node;
				tr->scale.y = -FIX_ONE;
			}
			converter->bifs_parent = node;
		}
	} else {
		GF_Node *node, *child;
		
		node = converter->bifs_parent;

		switch(tag) {
		case TAG_SVG_g:
			{
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
				} else {
					M_Group *g = (M_Group*)gf_node_new(converter->bifs_sg, TAG_MPEG4_Group);
					gf_node_register((GF_Node *)g, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, (GF_Node *)g);
					node = (GF_Node *)g;
					converter->bifs_parent = node;
				}
			}
			break;
		case TAG_SVG_rect:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				} 
				if (converter->all_atts.x || converter->all_atts.y) {
					child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
					gf_node_register(child, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
					node = child;
					child = NULL;
					if (!is_parent_set) {
						converter->bifs_parent = node;
						is_parent_set = 1;
					}
					{
						M_Transform2D *tr = (M_Transform2D *)node;
						if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value + (converter->all_atts.width?converter->all_atts.width->value/2:0);
						if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value + (converter->all_atts.height?converter->all_atts.height->value/2:0);
					}
				} 
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_Rectangle);
					gf_node_register(shape->geometry, (GF_Node *)shape);
					{
						M_Rectangle *rect = (M_Rectangle *)shape->geometry;
						if (converter->all_atts.width) rect->size.x = converter->all_atts.width->value;
						if (converter->all_atts.height) rect->size.y = converter->all_atts.height->value;					
					}			
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_path:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				} 
				if (converter->all_atts.x || converter->all_atts.y) {
					child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
					gf_node_register(child, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
					node = child;
					child = NULL;
					if (!is_parent_set) {
						converter->bifs_parent = node;
						is_parent_set = 1;
					}
					{
						M_Transform2D *tr = (M_Transform2D *)node;
						if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value;
						if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value;
					}
				} 
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_XCurve2D);
					gf_node_register(shape->geometry, (GF_Node *)shape);
					if (converter->all_atts.d) {
						M_Coordinate2D *c2d;
						M_XCurve2D *xc = (M_XCurve2D *)shape->geometry;
						u32 i, j, c;

						xc->point = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
						c2d = (M_Coordinate2D *)xc->point;
						gf_node_register(xc->point, (GF_Node *)xc);
						
						gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, converter->all_atts.d->n_points);
						j= 0;
						for (i = 0; i < converter->all_atts.d->n_points; i++) {
							if (converter->all_atts.d->tags[i] != GF_PATH_CLOSE || i == converter->all_atts.d->n_points-1) {
								c2d->point.vals[j] = converter->all_atts.d->points[i];
								j++;
							}
						}
						c2d->point.count = j;

						gf_sg_vrml_mf_alloc(&xc->type, GF_SG_VRML_MFINT32, converter->all_atts.d->n_points);
						c = 0;
						j = 0;
						xc->type.vals[0] = 0;
						for (i = 1; i < converter->all_atts.d->n_points; i++) {
							switch(converter->all_atts.d->tags[i]) {
							case GF_PATH_CURVE_ON:
								if (c < converter->all_atts.d->n_contours &&
									i-1 == converter->all_atts.d->contours[c]) {
									xc->type.vals[j] = 0;
									c++;
								} else {
									xc->type.vals[j] = 1;
								}
								break;
							case GF_PATH_CURVE_CUBIC:
								xc->type.vals[j] = 2;
								i+=2;
								break;
							case GF_PATH_CLOSE:
								xc->type.vals[j] = 6;
								break;
							case GF_PATH_CURVE_CONIC:
								xc->type.vals[j] = 7;
								i++;
								break;
							}
							j++;
						}
						xc->type.count = j;
					}			
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_polyline:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				} 

				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_IndexedFaceSet2D);
					gf_node_register(shape->geometry, (GF_Node *)shape);
					if (converter->all_atts.points) {
						M_Coordinate2D *c2d;
						M_IndexedFaceSet2D *ifs = (M_IndexedFaceSet2D *)shape->geometry;
						u32 i;

						ifs->coord = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
						c2d = (M_Coordinate2D *)ifs->coord;
						gf_node_register(ifs->coord, (GF_Node *)ifs);
						
						gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, gf_list_count(*converter->all_atts.points));
						for (i = 0; i < gf_list_count(*converter->all_atts.points); i++) {
							SVG_Point *p = (SVG_Point *)gf_list_get(*converter->all_atts.points, i);
							c2d->point.vals[i].x = p->x;
							c2d->point.vals[i].y = p->y;
						}						
					}			
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_text:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				}

				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				{
					M_Transform2D *tr = (M_Transform2D *)child;
					if (converter->all_atts.text_x) tr->translation.x = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_x, 0))->value;
					if (converter->all_atts.text_y) tr->translation.y = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_y, 0))->value;
					tr->scale.y = -FIX_ONE;
				}
				node = child;
				child = NULL;
				if (!is_parent_set) {
					converter->bifs_parent = node;
					is_parent_set = 1;
				}

				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_FontStyle *fs;
					M_Text *text; 
					M_Shape *shape = (M_Shape *)node;
					text = (M_Text *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Text);
					shape->geometry = (GF_Node *)text;
					converter->bifs_text_node = shape->geometry;
					gf_node_register(shape->geometry, (GF_Node *)shape);
					
					fs = (M_FontStyle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_XFontStyle);
					gf_node_register((GF_Node *)fs, (GF_Node*)text);
					text->fontStyle = (GF_Node *)fs;

					gf_sg_vrml_mf_alloc(&fs->family, GF_SG_VRML_MFSTRING, 1);				
					fs->family.vals[0] = strdup(converter->svg_props.font_family->value);				
					fs->size = converter->svg_props.font_size->value;

					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_ellipse:
		case TAG_SVG_circle:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				}
				if (converter->all_atts.cx || converter->all_atts.cy) {
					child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
					gf_node_register(child, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
					{
						M_Transform2D *tr = (M_Transform2D *)child;
						if (converter->all_atts.cx) tr->translation.x = converter->all_atts.cx->value;
						if (converter->all_atts.cy) tr->translation.y = converter->all_atts.cy->value;
					}
					node = child;
					child = NULL;
					if (!is_parent_set) {
						converter->bifs_parent = node;
						is_parent_set = 1;
					}
				} 
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					if (tag == TAG_SVG_ellipse) {
						M_Ellipse *e = (M_Ellipse *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Ellipse);
						shape->geometry = (GF_Node *)e;
						e->radius.x = converter->all_atts.rx->value;
						e->radius.y = converter->all_atts.ry->value;
					} else {
						M_Circle *c = (M_Circle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Circle);
						shape->geometry = (GF_Node *)c;
						c->radius = converter->all_atts.r->value;
					}
					gf_node_register(shape->geometry, (GF_Node *)shape);
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;

		case TAG_SVG_defs:
			{
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Switch);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				{
					M_Switch *sw = (M_Switch *)node;
					sw->whichChoice = -1;
				}
				converter->bifs_parent = node;
			}
			break;
		case TAG_SVG_solidColor:
			{
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				converter->bifs_parent = node;
			}
			break;
		default:
			{
				fprintf(stdout, "Warning: element %s not supported \n", gf_node_get_class_name((GF_Node *)elt));
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				converter->bifs_parent = node;
			}
			break;
		}

		if (id_string) 
			gf_node_set_id(converter->bifs_parent, gf_node_get_id((GF_Node *)elt), gf_node_get_name((GF_Node *)elt));
	}
}
Пример #15
0
/*special cloning with type-casting from SF/MF strings to URL conversion since proto URL doesn't exist
as a field type (it's just a stupid encoding trick) */
void VRML_FieldCopyCast(void *dest, u32 dst_field_type, void *orig, u32 ori_field_type)
{
	SFURL *url;
	char tmp[50];
	u32 size, i, sf_type_ori, sf_type_dst;
	void *dst_field, *orig_field;
	if (!dest || !orig) return;

	switch (dst_field_type) {
	case GF_SG_VRML_SFSTRING:
		if (ori_field_type == GF_SG_VRML_SFURL) {
			url = ((SFURL *)orig);
			if (url->OD_ID>0) {
				sprintf(tmp, "%d", url->OD_ID);
				if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
				((SFString*)dest)->buffer = gf_strdup(tmp);
			} else {
				if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
				((SFString*)dest)->buffer = url->url ? gf_strdup(url->url) : NULL;
			}
		}
		/*for SFString to MFString cast*/
		else if (ori_field_type == GF_SG_VRML_SFSTRING) {
			if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
			((SFString*)dest)->buffer = ((SFString*)orig)->buffer ? gf_strdup(((SFString*)orig)->buffer) : NULL;
		}
		return;
	case GF_SG_VRML_SFURL:
		if (ori_field_type != GF_SG_VRML_SFSTRING) return;
		url = ((SFURL *)dest);
		url->OD_ID = 0;
		if (url->url) gf_free(url->url);
		if ( ((SFString*)orig)->buffer)
			url->url = gf_strdup(((SFString*)orig)->buffer);
		else
			url->url = NULL;
		return;
	case GF_SG_VRML_MFSTRING:
	case GF_SG_VRML_MFURL:
		break;
	default:
		return;
	}

	sf_type_dst = gf_sg_vrml_get_sf_type(dst_field_type);

	if (gf_sg_vrml_is_sf_field(ori_field_type)) {
		size = 1;
		gf_sg_vrml_mf_alloc(dest, dst_field_type, size);
		gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, 0);
		VRML_FieldCopyCast(dst_field, sf_type_dst, orig, ori_field_type);
		return;
	}

	size = ((GenMFField *)orig)->count;
	if (size != ((GenMFField *)dest)->count) gf_sg_vrml_mf_alloc(dest, dst_field_type, size);

	sf_type_ori = gf_sg_vrml_get_sf_type(ori_field_type);
	//duplicate all items
	for (i=0; i<size; i++) {
		gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, i);
		gf_sg_vrml_mf_get_item(orig, ori_field_type, &orig_field, i);
		VRML_FieldCopyCast(dst_field, sf_type_dst, orig_field, sf_type_ori);
	}
	return;
}
Пример #16
0
static GF_Node *create_appearance(SVGPropertiesPointers *svg_props, GF_SceneGraph *sg)
{
    M_Appearance *app;
    M_Material2D *mat;
    M_XLineProperties *xlp;
    M_RadialGradient *rg;
    M_LinearGradient *lg;

    app = (M_Appearance *)gf_node_new(sg, TAG_MPEG4_Appearance);

    app->material = gf_node_new(sg, TAG_MPEG4_Material2D);
    mat = (M_Material2D *)app->material;
    gf_node_register((GF_Node*)mat, (GF_Node*)app);

    if (svg_props->fill->type == SVG_PAINT_NONE) {
        mat->filled = 0;
    } else {
        mat->filled = 1;
        if (svg_props->fill->type == SVG_PAINT_COLOR) {
            if (svg_props->fill->color.type == SVG_COLOR_RGBCOLOR) {
                mat->emissiveColor.red = svg_props->fill->color.red;
                mat->emissiveColor.green = svg_props->fill->color.green;
                mat->emissiveColor.blue = svg_props->fill->color.blue;
            } else if (svg_props->fill->color.type == SVG_COLOR_CURRENTCOLOR) {
                mat->emissiveColor.red = svg_props->color->color.red;
                mat->emissiveColor.green = svg_props->color->color.green;
                mat->emissiveColor.blue = svg_props->color->color.blue;
            } else {
                /* WARNING */
                mat->emissiveColor.red = 0;
                mat->emissiveColor.green = 0;
                mat->emissiveColor.blue = 0;
            }
        } else { // SVG_PAINT_URI
            /* TODO: gradient or solidcolor */
        }
    }

    mat->transparency = FIX_ONE - svg_props->fill_opacity->value;

    if (svg_props->stroke->type != SVG_PAINT_NONE &&
            svg_props->stroke_width->value != 0) {
        mat->lineProps = gf_node_new(sg, TAG_MPEG4_XLineProperties);
        xlp = (M_XLineProperties *)mat->lineProps;
        gf_node_register((GF_Node*)xlp, (GF_Node*)mat);

        xlp->width = svg_props->stroke_width->value;

        if (svg_props->stroke->type == SVG_PAINT_COLOR) {
            if (svg_props->stroke->color.type == SVG_COLOR_RGBCOLOR) {
                xlp->lineColor.red = svg_props->stroke->color.red;
                xlp->lineColor.green = svg_props->stroke->color.green;
                xlp->lineColor.blue = svg_props->stroke->color.blue;
            } else if (svg_props->stroke->color.type == SVG_COLOR_CURRENTCOLOR) {
                xlp->lineColor.red = svg_props->color->color.red;
                xlp->lineColor.green = svg_props->color->color.green;
                xlp->lineColor.blue = svg_props->color->color.blue;
            } else {
                /* WARNING */
                xlp->lineColor.red = 0;
                xlp->lineColor.green = 0;
                xlp->lineColor.blue = 0;
            }
        } else { // SVG_PAINT_URI
            /* TODO: xlp->texture =  ... */
        }
        xlp->transparency = FIX_ONE - svg_props->stroke_opacity->value;
        xlp->lineCap = *svg_props->stroke_linecap;
        xlp->lineJoin = *svg_props->stroke_linejoin;
        if (svg_props->stroke_dasharray->type == SVG_STROKEDASHARRAY_ARRAY) {
            u32 i;
            xlp->lineStyle = 6;
            gf_sg_vrml_mf_alloc(&xlp->dashes, GF_SG_VRML_MFFLOAT, svg_props->stroke_dasharray->array.count);
            for (i = 0; i < svg_props->stroke_dasharray->array.count; i++) {
                xlp->dashes.vals[i] = svg_props->stroke_dasharray->array.vals[i] / svg_props->stroke_width->value;
            }
        }
        xlp->miterLimit = svg_props->stroke_miterlimit->value;
    }

    return (GF_Node*)app;
}
Пример #17
0
GF_EXPORT
void gf_sg_vrml_field_clone(void *dest, void *orig, u32 field_type, GF_SceneGraph *inScene)
{
	u32 size, i, sf_type;
	void *dst_field, *orig_field;

	if (!dest || !orig) return;

	switch (field_type) {
	case GF_SG_VRML_SFBOOL:
		memcpy(dest, orig, sizeof(SFBool));
		break;
	case GF_SG_VRML_SFCOLOR:
		memcpy(dest, orig, sizeof(SFColor));
		break;
	case GF_SG_VRML_SFFLOAT:
		memcpy(dest, orig, sizeof(SFFloat));
		break;
	case GF_SG_VRML_SFINT32:
		memcpy(dest, orig, sizeof(SFInt32));
		break;
	case GF_SG_VRML_SFROTATION:
		memcpy(dest, orig, sizeof(SFRotation));
		break;
	case GF_SG_VRML_SFTIME:
		memcpy(dest, orig, sizeof(SFTime));
		break;
	case GF_SG_VRML_SFVEC2F:
		memcpy(dest, orig, sizeof(SFVec2f));
		break;
	case GF_SG_VRML_SFVEC3F:
		memcpy(dest, orig, sizeof(SFVec3f));
		break;
	case GF_SG_VRML_SFATTRREF:
		memcpy(dest, orig, sizeof(SFAttrRef));
		break;
	case GF_SG_VRML_SFSTRING:
		if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
		if ( ((SFString*)orig)->buffer )
			((SFString*)dest)->buffer = gf_strdup(((SFString*)orig)->buffer);
		else
			((SFString*)dest)->buffer = NULL;
		break;
	case GF_SG_VRML_SFURL:
		if ( ((SFURL *)dest)->url ) gf_free( ((SFURL *)dest)->url );
		((SFURL *)dest)->OD_ID = ((SFURL *)orig)->OD_ID;
		if (((SFURL *)orig)->url)
			((SFURL *)dest)->url = gf_strdup(((SFURL *)orig)->url);
		else
			((SFURL *)dest)->url = NULL;
		break;
	case GF_SG_VRML_SFIMAGE:
		if (((SFImage *)dest)->pixels) gf_free(((SFImage *)dest)->pixels);
		((SFImage *)dest)->width = ((SFImage *)orig)->width;
		((SFImage *)dest)->height = ((SFImage *)orig)->height;
		((SFImage *)dest)->numComponents  = ((SFImage *)orig)->numComponents;
		size = ((SFImage *)dest)->width * ((SFImage *)dest)->height * ((SFImage *)dest)->numComponents;
		((SFImage *)dest)->pixels = (u8*)gf_malloc(sizeof(char)*size);
		memcpy(((SFImage *)dest)->pixels, ((SFImage *)orig)->pixels, sizeof(char)*size);
		break;
	case GF_SG_VRML_SFCOMMANDBUFFER:
	{
		SFCommandBuffer *cb_dst = (SFCommandBuffer *)dest;
		SFCommandBuffer *cb_src = (SFCommandBuffer *)orig;

		cb_dst->bufferSize = cb_src->bufferSize;
		if (cb_dst->bufferSize && !gf_list_count(cb_src->commandList) ) {
			cb_dst->buffer = (u8*)gf_realloc(cb_dst->buffer, sizeof(char)*cb_dst->bufferSize);
			memcpy(cb_dst->buffer, cb_src->buffer, sizeof(char)*cb_src->bufferSize);
		} else {
			u32 j, c2;
			if (cb_dst->buffer) gf_free(cb_dst->buffer);
			cb_dst->buffer = NULL;
			/*clone command list*/
			c2 = gf_list_count(cb_src->commandList);
			for (j=0; j<c2;j++) {
				GF_Command *sub_com = (GF_Command *)gf_list_get(cb_src->commandList, j);
				GF_Command *new_com = gf_sg_vrml_command_clone(sub_com, inScene, 0);
				gf_list_add(cb_dst->commandList, new_com);
			}
		}
	}
		break;

	/*simply copy text string*/
	case GF_SG_VRML_SFSCRIPT:
		if (((SFScript*)dest)->script_text) gf_free(((SFScript*)dest)->script_text);
		((SFScript*)dest)->script_text = NULL;
		if ( ((SFScript*)orig)->script_text)
			((SFScript *)dest)->script_text = (char *)gf_strdup( (char*) ((SFScript*)orig)->script_text );
		break;


	//simple MFFields, do a memcpy
	case GF_SG_VRML_MFBOOL:
	case GF_SG_VRML_MFFLOAT:
	case GF_SG_VRML_MFTIME:
	case GF_SG_VRML_MFINT32:
	case GF_SG_VRML_MFVEC3F:
	case GF_SG_VRML_MFVEC2F:
	case GF_SG_VRML_MFCOLOR:
	case GF_SG_VRML_MFROTATION:
	case GF_SG_VRML_MFATTRREF:
		size = gf_sg_vrml_get_sf_size(field_type) * ((GenMFField *)orig)->count;
		if (((GenMFField *)orig)->count != ((GenMFField *)dest)->count) {
			((GenMFField *)dest)->array = gf_realloc(((GenMFField *)dest)->array, size);
			((GenMFField *)dest)->count = ((GenMFField *)orig)->count;
		}
		memcpy(((GenMFField *)dest)->array, ((GenMFField *)orig)->array, size);
		break;
	//complex MFFields
	case GF_SG_VRML_MFSTRING:
	case GF_SG_VRML_MFIMAGE:
	case GF_SG_VRML_MFURL:
	case GF_SG_VRML_MFSCRIPT:
		size = ((GenMFField *)orig)->count;
		gf_sg_vrml_mf_reset(dest, field_type);
		gf_sg_vrml_mf_alloc(dest, field_type, size);
		sf_type = gf_sg_vrml_get_sf_type(field_type);
		//duplicate all items
		for (i=0; i<size; i++) {
			gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i);
			gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i);
			gf_sg_vrml_field_copy(dst_field, orig_field, sf_type);
		}
		break;
	}
}
Пример #18
0
GF_Err gf_bifs_dec_pred_mf_field(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
{
	GF_Err e;
	Bool HasQ;
	u8 AType;
	Fixed b_min, b_max;
	u32 i, flag;
	PredMF pmf;
	
	memset(&pmf, 0, sizeof(PredMF));
	
	HasQ = gf_bifs_get_aq_info(node, field->fieldIndex, &pmf.QType, &AType, &b_min, &b_max, &pmf.QNbBits);
	if (!HasQ || !pmf.QType) return GF_EOS;

	/*get NbBits for QP14 (QC_COORD_INDEX)*/
	if (pmf.QType == QC_COORD_INDEX) 
		pmf.QNbBits = gf_bifs_dec_qp14_get_bits(codec);

	pmf.BMin.x = pmf.BMin.y = pmf.BMin.z = b_min;
	pmf.BMax.x = pmf.BMax.y = pmf.BMax.z = b_max;

	/*check is the QP is on and retrieves the bounds*/
	if (!Q_IsTypeOn(codec->ActiveQP, pmf.QType, &pmf.QNbBits, &pmf.BMin, &pmf.BMax)) return GF_EOS;
	
	switch (field->fieldType) {
	case GF_SG_VRML_MFCOLOR:
	case GF_SG_VRML_MFVEC3F:
		if (pmf.QType==QC_NORMALS) {
			pmf.num_comp = 2;
			break;
		}
	case GF_SG_VRML_MFROTATION:
		pmf.num_comp = 3;
		break;
	case GF_SG_VRML_MFVEC2F:
		pmf.num_comp = 2;
		break;
	case GF_SG_VRML_MFFLOAT:
	case GF_SG_VRML_MFINT32:
		pmf.num_comp = 1;
		break;
	default:
		return GF_NON_COMPLIANT_BITSTREAM;
	}


	/*parse array header*/
	flag = gf_bs_read_int(bs, 5);
	pmf.num_fields = gf_bs_read_int(bs, flag);
	pmf.intra_mode = gf_bs_read_int(bs, 2);
	switch (pmf.intra_mode) {
	case 1:
		flag = gf_bs_read_int(bs, 5);
		pmf.intra_inter = gf_bs_read_int(bs, flag);
		/*no break*/
	case 2:
	case 0:
		pmf.compNbBits = gf_bs_read_int(bs, 5);
		if (pmf.QType==1) pmf.num_bounds = 3;
		else if (pmf.QType==2) pmf.num_bounds = 2;
		else pmf.num_bounds = 1;
		for (i=0; i<pmf.num_bounds; i++) {
			flag = gf_bs_read_int(bs, pmf.QNbBits + 1);
			pmf.comp_min[i] = flag - (1<<pmf.QNbBits);
		}
		break;
	case 3:
		break;
	}


	pmf.dec = gp_bifs_aa_dec_new(bs);
	pmf.models[0] = gp_bifs_aa_model_new();
	pmf.models[1] = gp_bifs_aa_model_new();
	pmf.models[2] = gp_bifs_aa_model_new();
	pmf.dir_model = gp_bifs_aa_model_new();

	PMF_ResetModels(&pmf);

	gf_sg_vrml_mf_alloc(field->far_ptr, field->fieldType, pmf.num_fields);
	pmf.cur_field = 0;
	/*parse initial I*/
	e = PMF_ParseIValue(&pmf, bs, field);
	if (e) return e;

	for (pmf.cur_field=1; pmf.cur_field<pmf.num_fields; pmf.cur_field++) {
		switch (pmf.intra_mode) {
		case 0:
			e = PMF_ParsePValue(&pmf, bs, field);
			break;

		/*NOT TESTED*/
		case 1:
			if (!(pmf.cur_field % pmf.intra_inter)) {
				/*resync bitstream*/
				gp_bifs_aa_dec_resync(pmf.dec);
				flag = gf_bs_read_int(bs, 1);
				/*update settings ?*/
				if (flag) {
					e = PMF_UpdateArrayQP(&pmf, bs);
					if (e) goto err_exit;
				}
				e = PMF_ParseIValue(&pmf, bs, field);
			} else {
				e = PMF_ParsePValue(&pmf, bs, field);
			}
			break;

		/*NOT TESTED*/
		case 2:
			/*is intra ? - WARNING: this is from the arithmetic context !!*/
			flag = gp_bifs_aa_dec_get_bit(pmf.dec);
			if (flag) {
				/*resync bitstream*/
				gp_bifs_aa_dec_resync_bit(pmf.dec);
				flag = gf_bs_read_int(bs, 1);
				/*update settings ?*/
				if (flag) {
					e = PMF_UpdateArrayQP(&pmf, bs);
					if (e) goto err_exit;
				}
				e = PMF_ParseIValue(&pmf, bs, field);
			} else {
				e = PMF_ParsePValue(&pmf, bs, field);
				gp_bifs_aa_dec_flush(pmf.dec);
			}
			break;
		}
		if (e) goto err_exit;
	}


	if (pmf.intra_mode==2) {
		gp_bifs_aa_dec_resync_bit(pmf.dec);
	} else {
		gp_bifs_aa_dec_resync(pmf.dec);
	}

err_exit:
	gp_bifs_aa_model_del(pmf.models[0]);
	gp_bifs_aa_model_del(pmf.models[1]);
	gp_bifs_aa_model_del(pmf.models[2]);
	gp_bifs_aa_model_del(pmf.dir_model);
	gp_bifs_aa_dec_del(pmf.dec);
	return e;
}