1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *			Authors: Jean Le Feuvre
5  *			Copyright (c) Telecom ParisTech 2000-2012
6  *					All rights reserved
7  *
8  *  This file is part of GPAC / Scene Graph sub-project
9  *
10  *  GPAC is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU Lesser General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  GPAC is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; see the file COPYING.  If not, write to
22  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 
26 #include <gpac/internal/scenegraph_dev.h>
27 
28 /*MPEG4 & X3D tags (for node tables & script handling)*/
29 #include <gpac/nodes_mpeg4.h>
30 #include <gpac/nodes_x3d.h>
31 
32 
33 #ifndef GPAC_DISABLE_VRML
34 #include <gpac/internal/bifs_dev.h>
35 
36 
37 GF_EXPORT
gf_node_in_table_by_tag(u32 tag,u32 NDTType)38 Bool gf_node_in_table_by_tag(u32 tag, u32 NDTType)
39 {
40 	if (!tag) return 0;
41 	if (tag==TAG_ProtoNode) return 1;
42 	else if (tag<=GF_NODE_RANGE_LAST_MPEG4) {
43 #ifndef GPAC_DISABLE_BIFS
44 		u32 i;
45 		for (i=0; i<GF_BIFS_LAST_VERSION; i++) {
46 			if (gf_bifs_get_node_type(NDTType, tag, i+1)) return 1;
47 		}
48 		return 0;
49 #else
50 		/*if BIFS is disabled, we don't have the NDTs - we therefore allow any node in any table otherwise we would reject
51 		them all*/
52 		return 1;
53 #endif
54 
55 	}
56 #ifndef GPAC_DISABLE_X3D
57 	else if (tag<=GF_NODE_RANGE_LAST_X3D) {
58 		return gf_x3d_get_node_type(NDTType, tag);
59 	}
60 #endif
61 	return 0;
62 }
63 
64 
Node_on_add_children(GF_Node * node,GF_Route * route)65 static void Node_on_add_children(GF_Node *node, GF_Route *route)
66 {
67 	GF_ChildNodeItem *list;
68 	GF_FieldInfo field;
69 	GF_VRMLParent *n = (GF_VRMLParent *)node;
70 
71 	if (n->children) {
72 		list = n->children;
73 		while (list->next) list = list->next;
74 		list->next = n->addChildren;
75 	} else {
76 		n->children = n->addChildren;
77 	}
78 	n->addChildren = NULL;
79 
80 	/*signal children field is modified*/
81 	field.name = "children";
82 	field.eventType = GF_SG_EVENT_EXPOSED_FIELD;
83 	field.fieldType = GF_SG_VRML_MFNODE;
84 	field.NDTtype = -1;
85 	if ( node->sgprivate->tag == TAG_MPEG4_Transform )
86 		field.fieldIndex = 3;
87 	else
88 		field.fieldIndex = 2;
89 	field.far_ptr = & n->children;
90 	gf_node_event_out(node, field.fieldIndex);
91 	gf_node_changed(node, &field);
92 
93 	if (node->sgprivate->scenegraph->on_node_modified) {
94 		field.name = "addChildren";
95 		field.eventType = GF_SG_EVENT_IN;
96 		field.fieldType = GF_SG_VRML_MFNODE;
97 		field.NDTtype = -1;
98 		field.fieldIndex = 0;
99 		field.far_ptr = & n->addChildren;
100 		node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, &field, NULL);
101 	}
102 }
103 
Node_on_remove_children(GF_Node * node,GF_Route * route)104 static void Node_on_remove_children(GF_Node *node, GF_Route *route)
105 {
106 	GF_ChildNodeItem *list;
107 	GF_FieldInfo field;
108 	GF_VRMLParent *n = (GF_VRMLParent *)node;
109 
110 	if (!n->removeChildren) return;
111 
112 	list = n->removeChildren;
113 	while (list) {
114 		if (gf_node_list_del_child(& n->children, list->node)) {
115 			gf_node_unregister(list->node, node);
116 		}
117 		list = list->next;
118 	}
119 	gf_node_unregister_children(node, n->removeChildren);
120 	n->removeChildren = NULL;
121 
122 	/*signal children field is modified*/
123 	field.name = "children";
124 	field.eventType = GF_SG_EVENT_EXPOSED_FIELD;
125 	field.fieldType = GF_SG_VRML_MFNODE;
126 	field.NDTtype = -1;
127 	if ( node->sgprivate->tag == TAG_MPEG4_Transform )
128 		field.fieldIndex = 3;
129 	else
130 		field.fieldIndex = 2;
131 	field.far_ptr = & n->children;
132 	gf_node_event_out(node, field.fieldIndex);
133 	gf_node_changed(node, &field);
134 
135 
136 	if (node->sgprivate->scenegraph->on_node_modified) {
137 		field.name = "removeChildren";
138 		field.eventType = GF_SG_EVENT_IN;
139 		field.fieldType = GF_SG_VRML_MFNODE;
140 		field.NDTtype = -1;
141 		field.fieldIndex = 1;
142 		field.far_ptr = & n->removeChildren;
143 		node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, &field, NULL);
144 	}
145 }
146 
gf_sg_vrml_parent_setup(GF_Node * pNode)147 void gf_sg_vrml_parent_setup(GF_Node *pNode)
148 {
149 	GF_VRMLParent *par = (GF_VRMLParent *)pNode;
150 	par->children = NULL;
151 	par->addChildren = NULL;
152 	par->on_addChildren = Node_on_add_children;
153 	par->removeChildren = NULL;
154 	par->on_removeChildren = Node_on_remove_children;
155 	pNode->sgprivate->flags |= GF_SG_CHILD_DIRTY;
156 }
157 
gf_sg_vrml_parent_destroy(GF_Node * pNode)158 void gf_sg_vrml_parent_destroy(GF_Node *pNode)
159 {
160 	GF_VRMLParent *par = (GF_VRMLParent *)pNode;
161 	gf_node_unregister_children(pNode, par->children);
162 	gf_node_unregister_children(pNode, par->addChildren);
163 	gf_node_unregister_children(pNode, par->removeChildren);
164 }
165 
166 GF_EXPORT
gf_sg_delete_all_protos(GF_SceneGraph * scene)167 GF_Err gf_sg_delete_all_protos(GF_SceneGraph *scene)
168 {
169 	if (!scene) return GF_BAD_PARAM;
170 	while (gf_list_count(scene->protos)) {
171 		GF_Proto *p = (GF_Proto *)gf_list_get(scene->protos, 0);
172 		gf_sg_proto_del(p);
173 	}
174 	return GF_OK;
175 }
176 
177 GF_EXPORT
gf_sg_set_proto_loader(GF_SceneGraph * scene,GF_SceneGraph * (* GetExternProtoLib)(void * SceneCallback,MFURL * lib_url))178 void gf_sg_set_proto_loader(GF_SceneGraph *scene, GF_SceneGraph *(*GetExternProtoLib)(void *SceneCallback, MFURL *lib_url))
179 {
180 	if (!scene) return;
181 	scene->GetExternProtoLib = GetExternProtoLib;
182 }
183 
184 GF_EXPORT
gf_sg_get_next_available_route_id(GF_SceneGraph * sg)185 u32 gf_sg_get_next_available_route_id(GF_SceneGraph *sg)
186 {
187 	u32 i, count;
188 	u32 ID = 0;
189 
190 	if (!sg->max_defined_route_id) {
191 		count = gf_list_count(sg->Routes);
192 		/*routes are not sorted*/
193 		for (i=0; i<count; i++) {
194 			GF_Route *r = (GF_Route *)gf_list_get(sg->Routes, i);
195 			if (ID<=r->ID) ID = r->ID;
196 		}
197 		return ID+1;
198 	} else {
199 		sg->max_defined_route_id++;
200 		return sg->max_defined_route_id;
201 	}
202 }
203 
204 GF_EXPORT
gf_sg_set_max_defined_route_id(GF_SceneGraph * sg,u32 ID)205 void gf_sg_set_max_defined_route_id(GF_SceneGraph *sg, u32 ID)
206 {
207 	sg->max_defined_route_id = MAX(sg->max_defined_route_id, ID);
208 }
209 
210 GF_EXPORT
gf_sg_get_next_available_proto_id(GF_SceneGraph * sg)211 u32 gf_sg_get_next_available_proto_id(GF_SceneGraph *sg)
212 {
213 	u32 i, count;
214 	u32 ID = 0;
215 	count = gf_list_count(sg->protos);
216 	/*protos are not sorted*/
217 	for (i=0; i<count; i++) {
218 		GF_Proto *p = (GF_Proto *)gf_list_get(sg->protos, i);
219 		if (ID<=p->ID) ID = p->ID;
220 	}
221 	count = gf_list_count(sg->unregistered_protos);
222 	for (i=0; i<count; i++) {
223 		GF_Proto *p = (GF_Proto *)gf_list_get(sg->unregistered_protos, i);
224 		if (ID<=p->ID) ID = p->ID;
225 	}
226 	return ID+1;
227 }
228 
229 //adds a child in the children list
230 GF_EXPORT
gf_node_insert_child(GF_Node * parent,GF_Node * new_child,s32 Position)231 GF_Err gf_node_insert_child(GF_Node *parent, GF_Node *new_child, s32 Position)
232 {
233 	GF_ParentNode *node = (GF_ParentNode *) parent;
234 	if (Position == -1) {
235 		gf_node_list_add_child(& node->children, new_child);
236 	} else {
237 		gf_node_list_insert_child(& node->children, new_child, Position);
238 	}
239 	return GF_OK;
240 }
241 
242 #if 0
243 GF_Err gf_node_remove_child(GF_Node *parent, GF_Node *toremove_child)
244 {
245 	if (!gf_node_list_del_child(& ((GF_ParentNode *) parent)->children, toremove_child)) return GF_BAD_PARAM;
246 	/*V4Studio doesn't handle DEF/USE properly yet...*/
247 	/*gf_node_unregister(toremove_child, parent);*/
248 	return GF_OK;
249 }
250 #endif
251 
252 GF_EXPORT
gf_sg_script_load(GF_Node * n)253 void gf_sg_script_load(GF_Node *n)
254 {
255 	if (n && n->sgprivate->scenegraph->script_load) n->sgprivate->scenegraph->script_load(n);
256 }
257 
258 GF_EXPORT
gf_sg_find_proto(GF_SceneGraph * sg,u32 ProtoID,char * name)259 GF_Proto *gf_sg_find_proto(GF_SceneGraph *sg, u32 ProtoID, char *name)
260 {
261 	GF_Proto *proto;
262 	u32 i;
263 
264 	assert(sg);
265 
266 	/*browse all top-level */
267 	i=0;
268 	while ((proto = (GF_Proto *)gf_list_enum(sg->protos, &i))) {
269 		/*first check on name if given, since parsers use this with ID=0*/
270 		if (name) {
271 			if (proto->Name && !stricmp(name, proto->Name)) return proto;
272 		} else if (proto->ID == ProtoID) return proto;
273 	}
274 	/*browse all top-level unregistered in reverse order*/
275 	for (i=gf_list_count(sg->unregistered_protos); i>0; i--) {
276 		proto = (GF_Proto *)gf_list_get(sg->unregistered_protos, i-1);
277 		if (name) {
278 			if (proto->Name && !stricmp(name, proto->Name)) return proto;
279 		} else if (proto->ID == ProtoID) return proto;
280 	}
281 	return NULL;
282 }
283 
284 
285 
NewSFBool()286 static SFBool *NewSFBool()
287 {
288 	SFBool *tmp = (SFBool *)gf_malloc(sizeof(SFBool));
289 	memset(tmp, 0, sizeof(SFBool));
290 	return tmp;
291 }
NewSFFloat()292 static SFFloat *NewSFFloat()
293 {
294 	SFFloat *tmp = (SFFloat *)gf_malloc(sizeof(SFFloat));
295 	memset(tmp, 0, sizeof(SFFloat));
296 	return tmp;
297 }
NewSFDouble()298 static SFDouble *NewSFDouble()
299 {
300 	SFDouble *tmp = (SFDouble *)gf_malloc(sizeof(SFDouble));
301 	memset(tmp, 0, sizeof(SFDouble));
302 	return tmp;
303 }
NewSFTime()304 static SFTime *NewSFTime()
305 {
306 	SFTime *tmp = (SFTime *)gf_malloc(sizeof(SFTime));
307 	memset(tmp, 0, sizeof(SFTime));
308 	return tmp;
309 }
NewSFInt32()310 static SFInt32 *NewSFInt32()
311 {
312 	SFInt32 *tmp = (SFInt32 *)gf_malloc(sizeof(SFInt32));
313 	memset(tmp, 0, sizeof(SFInt32));
314 	return tmp;
315 }
NewSFString()316 static SFString *NewSFString()
317 {
318 	SFString *tmp = (SFString *)gf_malloc(sizeof(SFString));
319 	memset(tmp, 0, sizeof(SFString));
320 	return tmp;
321 }
NewSFVec3f()322 static SFVec3f *NewSFVec3f()
323 {
324 	SFVec3f *tmp = (SFVec3f *)gf_malloc(sizeof(SFVec3f));
325 	memset(tmp, 0, sizeof(SFVec3f));
326 	return tmp;
327 }
NewSFVec3d()328 static SFVec3d *NewSFVec3d()
329 {
330 	SFVec3d *tmp = (SFVec3d *)gf_malloc(sizeof(SFVec3d));
331 	memset(tmp, 0, sizeof(SFVec3d));
332 	return tmp;
333 }
NewSFVec2f()334 static SFVec2f *NewSFVec2f()
335 {
336 	SFVec2f *tmp = (SFVec2f *)gf_malloc(sizeof(SFVec2f));
337 	memset(tmp, 0, sizeof(SFVec2f));
338 	return tmp;
339 }
NewSFVec2d()340 static SFVec2d *NewSFVec2d()
341 {
342 	SFVec2d *tmp = (SFVec2d *)gf_malloc(sizeof(SFVec2d));
343 	memset(tmp, 0, sizeof(SFVec2d));
344 	return tmp;
345 }
NewSFColor()346 static SFColor *NewSFColor()
347 {
348 	SFColor *tmp = (SFColor *)gf_malloc(sizeof(SFColor));
349 	memset(tmp, 0, sizeof(SFColor));
350 	return tmp;
351 }
NewSFColorRGBA()352 static SFColorRGBA *NewSFColorRGBA()
353 {
354 	SFColorRGBA *tmp = (SFColorRGBA *)gf_malloc(sizeof(SFColorRGBA));
355 	memset(tmp, 0, sizeof(SFColorRGBA));
356 	return tmp;
357 }
NewSFRotation()358 static SFRotation *NewSFRotation()
359 {
360 	SFRotation *tmp = (SFRotation *)gf_malloc(sizeof(SFRotation));
361 	memset(tmp, 0, sizeof(SFRotation));
362 	return tmp;
363 }
NewSFImage()364 static SFImage *NewSFImage()
365 {
366 	SFImage *tmp = (SFImage *)gf_malloc(sizeof(SFImage));
367 	memset(tmp, 0, sizeof(SFImage));
368 	return tmp;
369 }
NewSFURL()370 static SFURL *NewSFURL()
371 {
372 	SFURL *tmp = (SFURL *)gf_malloc(sizeof(SFURL));
373 	memset(tmp, 0, sizeof(SFURL));
374 	return tmp;
375 }
NewSFCommandBuffer()376 static SFCommandBuffer *NewSFCommandBuffer()
377 {
378 	SFCommandBuffer *tmp = (SFCommandBuffer *)gf_malloc(sizeof(SFCommandBuffer));
379 	memset(tmp, 0, sizeof(SFCommandBuffer));
380 	tmp->commandList = gf_list_new();
381 	return tmp;
382 }
NewSFScript()383 static SFScript *NewSFScript()
384 {
385 	SFScript *tmp = (SFScript *)gf_malloc(sizeof(SFScript));
386 	memset(tmp, 0, sizeof(SFScript));
387 	return tmp;
388 }
NewSFAttrRef()389 static SFAttrRef *NewSFAttrRef()
390 {
391 	SFAttrRef *tmp;
392 	GF_SAFEALLOC(tmp, SFAttrRef);
393 	return tmp;
394 }
NewMFBool()395 static MFBool *NewMFBool()
396 {
397 	MFBool *tmp = (MFBool *)gf_malloc(sizeof(MFBool));
398 	memset(tmp, 0, sizeof(MFBool));
399 	return tmp;
400 }
NewMFFloat()401 static MFFloat *NewMFFloat()
402 {
403 	MFFloat *tmp = (MFFloat *)gf_malloc(sizeof(MFFloat));
404 	memset(tmp, 0, sizeof(MFFloat));
405 	return tmp;
406 }
NewMFTime()407 static MFTime *NewMFTime()
408 {
409 	MFTime *tmp = (MFTime *)gf_malloc(sizeof(MFTime));
410 	memset(tmp, 0, sizeof(MFTime));
411 	return tmp;
412 }
NewMFInt32()413 static MFInt32 *NewMFInt32()
414 {
415 	MFInt32 *tmp = (MFInt32 *)gf_malloc(sizeof(MFInt32));
416 	memset(tmp, 0, sizeof(MFInt32));
417 	return tmp;
418 }
NewMFString()419 static MFString *NewMFString()
420 {
421 	MFString *tmp = (MFString *)gf_malloc(sizeof(MFString));
422 	memset(tmp, 0, sizeof(MFString));
423 	return tmp;
424 }
NewMFVec3f()425 static MFVec3f *NewMFVec3f()
426 {
427 	MFVec3f *tmp = (MFVec3f *)gf_malloc(sizeof(MFVec3f));
428 	memset(tmp, 0, sizeof(MFVec3f));
429 	return tmp;
430 }
NewMFVec3d()431 static MFVec3d *NewMFVec3d()
432 {
433 	MFVec3d *tmp = (MFVec3d *)gf_malloc(sizeof(MFVec3d));
434 	memset(tmp, 0, sizeof(MFVec3d));
435 	return tmp;
436 }
NewMFVec2f()437 static MFVec2f *NewMFVec2f()
438 {
439 	MFVec2f *tmp = (MFVec2f *)gf_malloc(sizeof(MFVec2f));
440 	memset(tmp, 0, sizeof(MFVec2f));
441 	return tmp;
442 }
NewMFVec2d()443 static MFVec2d *NewMFVec2d()
444 {
445 	MFVec2d *tmp = (MFVec2d *)gf_malloc(sizeof(MFVec2d));
446 	memset(tmp, 0, sizeof(MFVec2d));
447 	return tmp;
448 }
NewMFColor()449 static MFColor *NewMFColor()
450 {
451 	MFColor *tmp = (MFColor *)gf_malloc(sizeof(MFColor));
452 	memset(tmp, 0, sizeof(MFColor));
453 	return tmp;
454 }
NewMFColorRGBA()455 static MFColorRGBA *NewMFColorRGBA()
456 {
457 	MFColorRGBA *tmp = (MFColorRGBA *)gf_malloc(sizeof(MFColorRGBA));
458 	memset(tmp, 0, sizeof(MFColorRGBA));
459 	return tmp;
460 }
NewMFRotation()461 static MFRotation *NewMFRotation()
462 {
463 	MFRotation *tmp = (MFRotation *)gf_malloc(sizeof(MFRotation));
464 	memset(tmp, 0, sizeof(MFRotation));
465 	return tmp;
466 }
NewMFURL()467 static MFURL *NewMFURL()
468 {
469 	MFURL *tmp = (MFURL *)gf_malloc(sizeof(MFURL));
470 	memset(tmp, 0, sizeof(MFURL));
471 	return tmp;
472 }
NewMFScript()473 static MFScript *NewMFScript()
474 {
475 	MFScript *tmp = (MFScript *)gf_malloc(sizeof(MFScript));
476 	memset(tmp, 0, sizeof(MFScript));
477 	return tmp;
478 }
NewMFAttrRef()479 static MFAttrRef *NewMFAttrRef()
480 {
481 	MFAttrRef *tmp;
482 	GF_SAFEALLOC(tmp, MFAttrRef);
483 	return tmp;
484 }
485 
486 GF_EXPORT
gf_sg_vrml_field_pointer_new(u32 FieldType)487 void *gf_sg_vrml_field_pointer_new(u32 FieldType)
488 {
489 	switch (FieldType) {
490 	case GF_SG_VRML_SFBOOL:
491 		return NewSFBool();
492 	case GF_SG_VRML_SFFLOAT:
493 		return NewSFFloat();
494 	case GF_SG_VRML_SFDOUBLE:
495 		return NewSFDouble();
496 	case GF_SG_VRML_SFTIME:
497 		return NewSFTime();
498 	case GF_SG_VRML_SFINT32:
499 		return NewSFInt32();
500 	case GF_SG_VRML_SFSTRING:
501 		return NewSFString();
502 	case GF_SG_VRML_SFVEC3F:
503 		return NewSFVec3f();
504 	case GF_SG_VRML_SFVEC2F:
505 		return NewSFVec2f();
506 	case GF_SG_VRML_SFVEC3D:
507 		return NewSFVec3d();
508 	case GF_SG_VRML_SFVEC2D:
509 		return NewSFVec2d();
510 	case GF_SG_VRML_SFCOLOR:
511 		return NewSFColor();
512 	case GF_SG_VRML_SFCOLORRGBA:
513 		return NewSFColorRGBA();
514 	case GF_SG_VRML_SFROTATION:
515 		return NewSFRotation();
516 	case GF_SG_VRML_SFIMAGE:
517 		return NewSFImage();
518 	case GF_SG_VRML_SFATTRREF:
519 		return NewSFAttrRef();
520 	case GF_SG_VRML_MFBOOL:
521 		return NewMFBool();
522 	case GF_SG_VRML_MFFLOAT:
523 		return NewMFFloat();
524 	case GF_SG_VRML_MFTIME:
525 		return NewMFTime();
526 	case GF_SG_VRML_MFINT32:
527 		return NewMFInt32();
528 	case GF_SG_VRML_MFSTRING:
529 		return NewMFString();
530 	case GF_SG_VRML_MFVEC3F:
531 		return NewMFVec3f();
532 	case GF_SG_VRML_MFVEC2F:
533 		return NewMFVec2f();
534 	case GF_SG_VRML_MFVEC3D:
535 		return NewMFVec3d();
536 	case GF_SG_VRML_MFVEC2D:
537 		return NewMFVec2d();
538 	case GF_SG_VRML_MFCOLOR:
539 		return NewMFColor();
540 	case GF_SG_VRML_MFCOLORRGBA:
541 		return NewMFColorRGBA();
542 	case GF_SG_VRML_MFROTATION:
543 	case GF_SG_VRML_MFVEC4F:
544 		return NewMFRotation();
545 	case GF_SG_VRML_MFATTRREF:
546 		return NewMFAttrRef();
547 
548 	//used in commands
549 	case GF_SG_VRML_SFCOMMANDBUFFER:
550 		return NewSFCommandBuffer();
551 
552 	case GF_SG_VRML_SFURL:
553 		return NewSFURL();
554 	case GF_SG_VRML_MFURL:
555 		return NewMFURL();
556 
557 	case GF_SG_VRML_SFSCRIPT:
558 		return NewSFScript();
559 	case GF_SG_VRML_MFSCRIPT:
560 		return NewMFScript();
561 	}
562 	return NULL;
563 }
564 
gf_sg_mfint32_del(MFInt32 par)565 void gf_sg_mfint32_del(MFInt32 par) {
566 	gf_free(par.vals);
567 }
gf_sg_mffloat_del(MFFloat par)568 void gf_sg_mffloat_del(MFFloat par) {
569 	gf_free(par.vals);
570 }
gf_sg_mfdouble_del(MFDouble par)571 void gf_sg_mfdouble_del(MFDouble par) {
572 	gf_free(par.vals);
573 }
gf_sg_mfbool_del(MFBool par)574 void gf_sg_mfbool_del(MFBool par) {
575 	gf_free(par.vals);
576 }
gf_sg_mfcolor_del(MFColor par)577 void gf_sg_mfcolor_del(MFColor par) {
578 	gf_free(par.vals);
579 }
gf_sg_mfcolorrgba_del(MFColorRGBA par)580 void gf_sg_mfcolorrgba_del(MFColorRGBA par) {
581 	gf_free(par.vals);
582 }
gf_sg_mfrotation_del(MFRotation par)583 void gf_sg_mfrotation_del(MFRotation par) {
584 	gf_free(par.vals);
585 }
gf_sg_mftime_del(MFTime par)586 void gf_sg_mftime_del(MFTime par) {
587 	gf_free(par.vals);
588 }
gf_sg_mfvec2f_del(MFVec2f par)589 void gf_sg_mfvec2f_del(MFVec2f par) {
590 	gf_free(par.vals);
591 }
gf_sg_mfvec2d_del(MFVec2d par)592 void gf_sg_mfvec2d_del(MFVec2d par) {
593 	gf_free(par.vals);
594 }
gf_sg_mfvec3f_del(MFVec3f par)595 void gf_sg_mfvec3f_del(MFVec3f par) {
596 	gf_free(par.vals);
597 }
gf_sg_mfvec3d_del(MFVec3d par)598 void gf_sg_mfvec3d_del(MFVec3d par) {
599 	gf_free(par.vals);
600 }
gf_sg_mfvec4f_del(MFVec4f par)601 void gf_sg_mfvec4f_del(MFVec4f par) {
602 	gf_free(par.vals);
603 }
gf_sg_mfattrref_del(MFAttrRef par)604 void gf_sg_mfattrref_del(MFAttrRef par) {
605 	gf_free(par.vals);
606 }
gf_sg_sfimage_del(SFImage im)607 void gf_sg_sfimage_del(SFImage im) {
608 	gf_free(im.pixels);
609 }
gf_sg_sfstring_del(SFString par)610 void gf_sg_sfstring_del(SFString par) {
611 	if (par.buffer) gf_free(par.buffer);
612 }
gf_sg_sfscript_del(SFScript par)613 void gf_sg_sfscript_del(SFScript par) {
614 	if (par.script_text) gf_free(par.script_text);
615 }
616 
617 
gf_sg_sfcommand_del(SFCommandBuffer cb)618 void gf_sg_sfcommand_del(SFCommandBuffer cb)
619 {
620 	u32 i;
621 	for (i=gf_list_count(cb.commandList); i>0; i--) {
622 		GF_Command *com = (GF_Command *)gf_list_get(cb.commandList, i-1);
623 		gf_sg_command_del(com);
624 	}
625 	gf_list_del(cb.commandList);
626 	if (cb.buffer) gf_free(cb.buffer);
627 }
628 
629 GF_EXPORT
gf_sg_vrml_field_pointer_del(void * field,u32 FieldType)630 void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType)
631 {
632 	GF_Node *node;
633 
634 	switch (FieldType) {
635 	case GF_SG_VRML_SFBOOL:
636 	case GF_SG_VRML_SFFLOAT:
637 	case GF_SG_VRML_SFDOUBLE:
638 	case GF_SG_VRML_SFTIME:
639 	case GF_SG_VRML_SFINT32:
640 	case GF_SG_VRML_SFVEC3F:
641 	case GF_SG_VRML_SFVEC3D:
642 	case GF_SG_VRML_SFVEC2F:
643 	case GF_SG_VRML_SFVEC2D:
644 	case GF_SG_VRML_SFCOLOR:
645 	case GF_SG_VRML_SFCOLORRGBA:
646 	case GF_SG_VRML_SFROTATION:
647 	case GF_SG_VRML_SFATTRREF:
648 		break;
649 	case GF_SG_VRML_SFSTRING:
650 		if ( ((SFString *)field)->buffer) gf_free(((SFString *)field)->buffer);
651 		break;
652 	case GF_SG_VRML_SFIMAGE:
653 		gf_sg_sfimage_del(* ((SFImage *)field));
654 		break;
655 
656 	case GF_SG_VRML_SFNODE:
657 		node = *(GF_Node **) field;
658 		if (node) gf_node_del(node);
659 		return;
660 	case GF_SG_VRML_SFCOMMANDBUFFER:
661 		gf_sg_sfcommand_del(*(SFCommandBuffer *)field);
662 		break;
663 
664 	case GF_SG_VRML_MFBOOL:
665 		gf_sg_mfbool_del( * ((MFBool *) field));
666 		break;
667 	case GF_SG_VRML_MFFLOAT:
668 		gf_sg_mffloat_del( * ((MFFloat *) field));
669 		break;
670 	case GF_SG_VRML_MFDOUBLE:
671 		gf_sg_mfdouble_del( * ((MFDouble *) field));
672 		break;
673 	case GF_SG_VRML_MFTIME:
674 		gf_sg_mftime_del( * ((MFTime *)field));
675 		break;
676 	case GF_SG_VRML_MFINT32:
677 		gf_sg_mfint32_del( * ((MFInt32 *)field));
678 		break;
679 	case GF_SG_VRML_MFSTRING:
680 		gf_sg_mfstring_del( *((MFString *)field));
681 		break;
682 	case GF_SG_VRML_MFVEC3F:
683 		gf_sg_mfvec3f_del( * ((MFVec3f *)field));
684 		break;
685 	case GF_SG_VRML_MFVEC2F:
686 		gf_sg_mfvec2f_del( * ((MFVec2f *)field));
687 		break;
688 	case GF_SG_VRML_MFVEC3D:
689 		gf_sg_mfvec3d_del( * ((MFVec3d *)field));
690 		break;
691 	case GF_SG_VRML_MFVEC2D:
692 		gf_sg_mfvec2d_del( * ((MFVec2d *)field));
693 		break;
694 	case GF_SG_VRML_MFCOLOR:
695 		gf_sg_mfcolor_del( * ((MFColor *)field));
696 		break;
697 	case GF_SG_VRML_MFCOLORRGBA:
698 		gf_sg_mfcolorrgba_del( * ((MFColorRGBA *)field));
699 		break;
700 	case GF_SG_VRML_MFROTATION:
701 	case GF_SG_VRML_MFVEC4F:
702 		gf_sg_mfrotation_del( * ((MFRotation *)field));
703 		break;
704 	case GF_SG_VRML_SFURL:
705 		gf_sg_sfurl_del( * ((SFURL *) field));
706 		break;
707 	case GF_SG_VRML_MFURL:
708 		gf_sg_mfurl_del( * ((MFURL *) field));
709 		break;
710 	case GF_SG_VRML_MFATTRREF:
711 		gf_sg_mfattrref_del( * ((MFAttrRef *) field));
712 		break;
713 	//used only in proto since this field is created by default for regular nodes
714 	case GF_SG_VRML_MFNODE:
715 		assert(0);
716 		return;
717 	case GF_SG_VRML_MFSCRIPT:
718 		gf_sg_mfscript_del( * ((MFScript *) field));
719 		break;
720 	case GF_SG_VRML_SFSCRIPT:
721 		return;
722 
723 	default:
724 		assert(0);
725 		return;
726 	}
727 	//free pointer
728 	gf_free(field);
729 }
730 
731 
732 /*********************************************************************
733 		MF Fields manipulation (alloc, gf_realloc, GetAt)
734 *********************************************************************/
735 GF_EXPORT
gf_sg_vrml_get_event_type_name(u32 EventType,Bool forX3D)736 const char *gf_sg_vrml_get_event_type_name(u32 EventType, Bool forX3D)
737 {
738 	switch (EventType) {
739 	case GF_SG_EVENT_IN:
740 		return forX3D ? "inputOnly" : "eventIn";
741 	case GF_SG_EVENT_FIELD:
742 		return forX3D ? "initializeOnly" : "field";
743 	case GF_SG_EVENT_EXPOSED_FIELD:
744 		return forX3D ? "inputOutput" : "exposedField";
745 	case GF_SG_EVENT_OUT:
746 		return forX3D ? "outputOnly" : "eventOut";
747 	default:
748 		return "unknownEvent";
749 	}
750 }
751 
752 GF_EXPORT
gf_sg_vrml_get_field_type_name(u32 FieldType)753 const char *gf_sg_vrml_get_field_type_name(u32 FieldType)
754 {
755 
756 	switch (FieldType) {
757 	case GF_SG_VRML_SFBOOL:
758 		return "SFBool";
759 	case GF_SG_VRML_SFFLOAT:
760 		return "SFFloat";
761 	case GF_SG_VRML_SFDOUBLE:
762 		return "SFDouble";
763 	case GF_SG_VRML_SFTIME:
764 		return "SFTime";
765 	case GF_SG_VRML_SFINT32:
766 		return "SFInt32";
767 	case GF_SG_VRML_SFSTRING:
768 		return "SFString";
769 	case GF_SG_VRML_SFVEC3F:
770 		return "SFVec3f";
771 	case GF_SG_VRML_SFVEC2F:
772 		return "SFVec2f";
773 	case GF_SG_VRML_SFVEC3D:
774 		return "SFVec3d";
775 	case GF_SG_VRML_SFVEC2D:
776 		return "SFVec2d";
777 	case GF_SG_VRML_SFCOLOR:
778 		return "SFColor";
779 	case GF_SG_VRML_SFCOLORRGBA:
780 		return "SFColorRGBA";
781 	case GF_SG_VRML_SFROTATION:
782 		return "SFRotation";
783 	case GF_SG_VRML_SFIMAGE:
784 		return "SFImage";
785 	case GF_SG_VRML_SFNODE:
786 		return "SFNode";
787 	case GF_SG_VRML_SFVEC4F:
788 		return "SFVec4f";
789 	case GF_SG_VRML_SFATTRREF:
790 		return "SFAttrRef";
791 	case GF_SG_VRML_MFBOOL:
792 		return "MFBool";
793 	case GF_SG_VRML_MFFLOAT:
794 		return "MFFloat";
795 	case GF_SG_VRML_MFDOUBLE:
796 		return "MFDouble";
797 	case GF_SG_VRML_MFTIME:
798 		return "MFTime";
799 	case GF_SG_VRML_MFINT32:
800 		return "MFInt32";
801 	case GF_SG_VRML_MFSTRING:
802 		return "MFString";
803 	case GF_SG_VRML_MFVEC3F:
804 		return "MFVec3f";
805 	case GF_SG_VRML_MFVEC2F:
806 		return "MFVec2f";
807 	case GF_SG_VRML_MFVEC3D:
808 		return "MFVec3d";
809 	case GF_SG_VRML_MFVEC2D:
810 		return "MFVec2d";
811 	case GF_SG_VRML_MFCOLOR:
812 		return "MFColor";
813 	case GF_SG_VRML_MFCOLORRGBA:
814 		return "MFColorRGBA";
815 	case GF_SG_VRML_MFROTATION:
816 		return "MFRotation";
817 	case GF_SG_VRML_MFIMAGE:
818 		return "MFImage";
819 	case GF_SG_VRML_MFNODE:
820 		return "MFNode";
821 	case GF_SG_VRML_MFVEC4F:
822 		return "MFVec4f";
823 	case GF_SG_VRML_SFURL:
824 		return "SFURL";
825 	case GF_SG_VRML_MFURL:
826 		return "MFURL";
827 	case GF_SG_VRML_MFATTRREF:
828 		return "MFAttrRef";
829 	case GF_SG_VRML_SFCOMMANDBUFFER:
830 		return "SFCommandBuffer";
831 	case GF_SG_VRML_SFSCRIPT:
832 		return "SFScript";
833 	case GF_SG_VRML_MFSCRIPT:
834 		return "MFScript";
835 	default:
836 		return "UnknownType";
837 	}
838 }
839 
gf_sg_field_type_by_name(char * fieldType)840 u32 gf_sg_field_type_by_name(char *fieldType)
841 {
842 	if (!stricmp(fieldType, "SFBool")) return GF_SG_VRML_SFBOOL;
843 	else if (!stricmp(fieldType, "SFFloat")) return GF_SG_VRML_SFFLOAT;
844 	else if (!stricmp(fieldType, "SFDouble")) return GF_SG_VRML_SFDOUBLE;
845 	else if (!stricmp(fieldType, "SFTime")) return GF_SG_VRML_SFTIME;
846 	else if (!stricmp(fieldType, "SFInt32")) return GF_SG_VRML_SFINT32;
847 	else if (!stricmp(fieldType, "SFString")) return GF_SG_VRML_SFSTRING;
848 	else if (!stricmp(fieldType, "SFVec2f")) return GF_SG_VRML_SFVEC2F;
849 	else if (!stricmp(fieldType, "SFVec3f")) return GF_SG_VRML_SFVEC3F;
850 	else if (!stricmp(fieldType, "SFVec2d")) return GF_SG_VRML_SFVEC2D;
851 	else if (!stricmp(fieldType, "SFVec3d")) return GF_SG_VRML_SFVEC3D;
852 	else if (!stricmp(fieldType, "SFColor")) return GF_SG_VRML_SFCOLOR;
853 	else if (!stricmp(fieldType, "SFColorRGBA")) return GF_SG_VRML_SFCOLORRGBA;
854 	else if (!stricmp(fieldType, "SFRotation")) return GF_SG_VRML_SFROTATION;
855 	else if (!stricmp(fieldType, "SFImage")) return GF_SG_VRML_SFIMAGE;
856 	else if (!stricmp(fieldType, "SFAttrRef")) return GF_SG_VRML_SFATTRREF;
857 	else if (!stricmp(fieldType, "SFNode")) return GF_SG_VRML_SFNODE;
858 
859 	else if (!stricmp(fieldType, "MFBool")) return GF_SG_VRML_MFBOOL;
860 	else if (!stricmp(fieldType, "MFFloat")) return GF_SG_VRML_MFFLOAT;
861 	else if (!stricmp(fieldType, "MFDouble")) return GF_SG_VRML_MFDOUBLE;
862 	else if (!stricmp(fieldType, "MFTime")) return GF_SG_VRML_MFTIME;
863 	else if (!stricmp(fieldType, "MFInt32")) return GF_SG_VRML_MFINT32;
864 	else if (!stricmp(fieldType, "MFString")) return GF_SG_VRML_MFSTRING;
865 	else if (!stricmp(fieldType, "MFVec2f")) return GF_SG_VRML_MFVEC2F;
866 	else if (!stricmp(fieldType, "MFVec3f")) return GF_SG_VRML_MFVEC3F;
867 	else if (!stricmp(fieldType, "MFVec2d")) return GF_SG_VRML_MFVEC2D;
868 	else if (!stricmp(fieldType, "MFVec3d")) return GF_SG_VRML_MFVEC3D;
869 	else if (!stricmp(fieldType, "MFColor")) return GF_SG_VRML_MFCOLOR;
870 	else if (!stricmp(fieldType, "MFColorRGBA")) return GF_SG_VRML_MFCOLORRGBA;
871 	else if (!stricmp(fieldType, "MFRotation")) return GF_SG_VRML_MFROTATION;
872 	else if (!stricmp(fieldType, "MFImage")) return GF_SG_VRML_MFIMAGE;
873 	else if (!stricmp(fieldType, "MFAttrRef")) return GF_SG_VRML_MFATTRREF;
874 	else if (!stricmp(fieldType, "MFNode")) return GF_SG_VRML_MFNODE;
875 
876 	return GF_SG_VRML_UNKNOWN;
877 }
878 
879 #endif
880 
gf_sg_sfurl_del(SFURL url)881 void gf_sg_sfurl_del(SFURL url) {
882 	if (url.url) gf_free(url.url);
883 }
884 
885 GF_EXPORT
gf_sg_vrml_is_sf_field(u32 FieldType)886 Bool gf_sg_vrml_is_sf_field(u32 FieldType)
887 {
888 	return (FieldType<GF_SG_VRML_FIRST_MF);
889 }
890 
gf_sg_mfstring_del(MFString par)891 void gf_sg_mfstring_del(MFString par)
892 {
893 	u32 i;
894 	for (i=0; i<par.count; i++) {
895 		if (par.vals[i]) gf_free(par.vals[i]);
896 	}
897 	gf_free(par.vals);
898 }
899 
900 
901 GF_EXPORT
gf_sg_mfurl_del(MFURL url)902 void gf_sg_mfurl_del(MFURL url)
903 {
904 	u32 i;
905 	for (i=0; i<url.count; i++) {
906 		gf_sg_sfurl_del(url.vals[i]);
907 	}
908 	gf_free(url.vals);
909 }
gf_sg_mfscript_del(MFScript sc)910 void gf_sg_mfscript_del(MFScript sc)
911 {
912 	u32 i;
913 	for (i=0; i<sc.count; i++) {
914 		if (sc.vals[i].script_text) gf_free(sc.vals[i].script_text);
915 	}
916 	gf_free(sc.vals);
917 }
918 
919 
gf_sg_vrml_copy_mfurl(MFURL * dst,MFURL * src)920 void gf_sg_vrml_copy_mfurl(MFURL *dst, MFURL *src)
921 {
922 	u32 i;
923 	gf_sg_vrml_mf_reset(dst, GF_SG_VRML_MFURL);
924 	dst->count = src->count;
925 	dst->vals = gf_malloc(sizeof(SFURL)*src->count);
926 	for (i=0; i<src->count; i++) {
927 		dst->vals[i].OD_ID = src->vals[i].OD_ID;
928 		dst->vals[i].url = src->vals[i].url ? gf_strdup(src->vals[i].url) : NULL;
929 	}
930 }
931 
932 
933 
934 //return the size of fixed fields (eg no buffer in the field)
gf_sg_vrml_get_sf_size(u32 FieldType)935 u32 gf_sg_vrml_get_sf_size(u32 FieldType)
936 {
937 	switch (FieldType) {
938 	case GF_SG_VRML_SFBOOL:
939 	case GF_SG_VRML_MFBOOL:
940 		return sizeof(SFBool);
941 	case GF_SG_VRML_SFFLOAT:
942 	case GF_SG_VRML_MFFLOAT:
943 		return sizeof(SFFloat);
944 	case GF_SG_VRML_SFTIME:
945 	case GF_SG_VRML_MFTIME:
946 		return sizeof(SFTime);
947 	case GF_SG_VRML_SFDOUBLE:
948 	case GF_SG_VRML_MFDOUBLE:
949 		return sizeof(SFDouble);
950 	case GF_SG_VRML_SFINT32:
951 	case GF_SG_VRML_MFINT32:
952 		return sizeof(SFInt32);
953 	case GF_SG_VRML_SFVEC3F:
954 	case GF_SG_VRML_MFVEC3F:
955 		return 3*sizeof(SFFloat);
956 	case GF_SG_VRML_SFVEC2F:
957 	case GF_SG_VRML_MFVEC2F:
958 		return 2*sizeof(SFFloat);
959 	case GF_SG_VRML_SFVEC3D:
960 	case GF_SG_VRML_MFVEC3D:
961 		return 3*sizeof(SFDouble);
962 	case GF_SG_VRML_SFCOLOR:
963 	case GF_SG_VRML_MFCOLOR:
964 		return 3*sizeof(SFFloat);
965 	case GF_SG_VRML_SFCOLORRGBA:
966 	case GF_SG_VRML_MFCOLORRGBA:
967 		return 4*sizeof(SFFloat);
968 	case GF_SG_VRML_SFROTATION:
969 	case GF_SG_VRML_MFROTATION:
970 	case GF_SG_VRML_MFVEC4F:
971 		return 4*sizeof(SFFloat);
972 
973 	case GF_SG_VRML_SFATTRREF:
974 	case GF_SG_VRML_MFATTRREF:
975 		return sizeof(SFAttrRef);
976 	//check if that works!!
977 	case GF_SG_VRML_SFSTRING:
978 	case GF_SG_VRML_MFSTRING:
979 		//ptr to char
980 		return sizeof(SFString);
981 	case GF_SG_VRML_SFSCRIPT:
982 	case GF_SG_VRML_MFSCRIPT:
983 		return sizeof(SFScript);
984 	case GF_SG_VRML_SFURL:
985 	case GF_SG_VRML_MFURL:
986 		return sizeof(SFURL);
987 	default:
988 		return 0;
989 	}
990 }
991 
992 GF_EXPORT
gf_sg_vrml_get_sf_type(u32 FieldType)993 u32 gf_sg_vrml_get_sf_type(u32 FieldType)
994 {
995 	switch (FieldType) {
996 	case GF_SG_VRML_SFBOOL:
997 	case GF_SG_VRML_MFBOOL:
998 		return GF_SG_VRML_SFBOOL;
999 	case GF_SG_VRML_SFFLOAT:
1000 	case GF_SG_VRML_MFFLOAT:
1001 		return GF_SG_VRML_SFFLOAT;
1002 	case GF_SG_VRML_SFDOUBLE:
1003 	case GF_SG_VRML_MFDOUBLE:
1004 		return GF_SG_VRML_SFDOUBLE;
1005 	case GF_SG_VRML_SFTIME:
1006 	case GF_SG_VRML_MFTIME:
1007 		return GF_SG_VRML_SFTIME;
1008 	case GF_SG_VRML_SFINT32:
1009 	case GF_SG_VRML_MFINT32:
1010 		return GF_SG_VRML_SFINT32;
1011 	case GF_SG_VRML_SFVEC3F:
1012 	case GF_SG_VRML_MFVEC3F:
1013 		return GF_SG_VRML_SFVEC3F;
1014 	case GF_SG_VRML_SFVEC4F:
1015 	case GF_SG_VRML_MFVEC4F:
1016 		return GF_SG_VRML_SFVEC4F;
1017 	case GF_SG_VRML_SFVEC2F:
1018 	case GF_SG_VRML_MFVEC2F:
1019 		return GF_SG_VRML_SFVEC2F;
1020 	case GF_SG_VRML_SFVEC3D:
1021 	case GF_SG_VRML_MFVEC3D:
1022 		return GF_SG_VRML_SFVEC3D;
1023 	case GF_SG_VRML_SFVEC2D:
1024 	case GF_SG_VRML_MFVEC2D:
1025 		return GF_SG_VRML_SFVEC2D;
1026 	case GF_SG_VRML_SFCOLOR:
1027 	case GF_SG_VRML_MFCOLOR:
1028 		return GF_SG_VRML_SFCOLOR;
1029 	case GF_SG_VRML_SFCOLORRGBA:
1030 	case GF_SG_VRML_MFCOLORRGBA:
1031 		return GF_SG_VRML_SFCOLORRGBA;
1032 	case GF_SG_VRML_SFROTATION:
1033 	case GF_SG_VRML_MFROTATION:
1034 		return GF_SG_VRML_SFROTATION;
1035 	case GF_SG_VRML_SFATTRREF:
1036 	case GF_SG_VRML_MFATTRREF:
1037 		return GF_SG_VRML_SFATTRREF;
1038 
1039 	//check if that works!!
1040 	case GF_SG_VRML_SFSTRING:
1041 	case GF_SG_VRML_MFSTRING:
1042 		//ptr to char
1043 		return GF_SG_VRML_SFSTRING;
1044 	case GF_SG_VRML_SFSCRIPT:
1045 	case GF_SG_VRML_MFSCRIPT:
1046 		return GF_SG_VRML_SFSCRIPT;
1047 	case GF_SG_VRML_SFURL:
1048 	case GF_SG_VRML_MFURL:
1049 		return GF_SG_VRML_SFURL;
1050 	case GF_SG_VRML_SFNODE:
1051 	case GF_SG_VRML_MFNODE:
1052 		return GF_SG_VRML_SFNODE;
1053 	default:
1054 		return GF_SG_VRML_UNKNOWN;
1055 	}
1056 }
1057 
1058 //
1059 //	Insert (+alloc) an MFField with a specified position for insertion and sets the ptr to the
1060 //	newly created slot
1061 //	!! Doesnt work for MFNodes
1062 //	InsertAt is the 0-based index for the new slot
1063 GF_EXPORT
gf_sg_vrml_mf_insert(void * mf,u32 FieldType,void ** new_ptr,u32 InsertAt)1064 GF_Err gf_sg_vrml_mf_insert(void *mf, u32 FieldType, void **new_ptr, u32 InsertAt)
1065 {
1066 	char *buffer;
1067 	u32 FieldSize, i, k;
1068 	GenMFField *mffield = (GenMFField *)mf;
1069 
1070 	if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM;
1071 	if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM;
1072 
1073 	FieldSize = gf_sg_vrml_get_sf_size(FieldType);
1074 
1075 	//field we can't copy
1076 	if (!FieldSize) return GF_BAD_PARAM;
1077 
1078 	//first item ever
1079 	if (!mffield->count || !mffield->array) {
1080 		if (mffield->array) gf_free(mffield->array);
1081 		mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize);
1082 		memset(mffield->array, 0, sizeof(char)*FieldSize);
1083 		mffield->count = 1;
1084 		if (new_ptr) *new_ptr = mffield->array;
1085 		return GF_OK;
1086 	}
1087 
1088 	//append at the end
1089 	if (InsertAt >= mffield->count) {
1090 		mffield->array = (char*)gf_realloc(mffield->array, sizeof(char)*(1+mffield->count)*FieldSize);
1091 		memset(mffield->array + mffield->count * FieldSize, 0, FieldSize);
1092 		if (new_ptr) *new_ptr = mffield->array + mffield->count * FieldSize;
1093 		mffield->count += 1;
1094 		return GF_OK;
1095 	}
1096 	//alloc 1+itemCount
1097 	buffer = (char*)gf_malloc(sizeof(char)*(1+mffield->count)*FieldSize);
1098 
1099 	//insert in the array
1100 	k=0;
1101 	for (i=0; i < mffield->count; i++) {
1102 		if (InsertAt == i) {
1103 			if (new_ptr) {
1104 				*new_ptr = buffer + i*FieldSize;
1105 				memset(*new_ptr, 0, sizeof(char)*FieldSize);
1106 			}
1107 			k = 1;
1108 		}
1109 		memcpy(buffer + (k+i) * FieldSize , mffield->array + i*FieldSize, FieldSize);
1110 	}
1111 	gf_free(mffield->array);
1112 	mffield->array = buffer;
1113 	mffield->count += 1;
1114 	return GF_OK;
1115 }
1116 
1117 
1118 GF_EXPORT
gf_sg_vrml_mf_reset(void * mf,u32 FieldType)1119 GF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType)
1120 {
1121 	GenMFField *mffield = (GenMFField *)mf;
1122 	if (!mffield->array) return GF_OK;
1123 
1124 	//field we can't copy
1125 	if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM;
1126 	if (!gf_sg_vrml_get_sf_size(FieldType)) return GF_BAD_PARAM;
1127 
1128 	switch (FieldType) {
1129 	case GF_SG_VRML_MFSTRING:
1130 		gf_sg_mfstring_del( * ((MFString *) mf));
1131 		break;
1132 	case GF_SG_VRML_MFURL:
1133 		gf_sg_mfurl_del( * ((MFURL *) mf));
1134 		break;
1135 	case GF_SG_VRML_MFSCRIPT:
1136 		gf_sg_mfscript_del( * ((MFScript *) mf));
1137 		break;
1138 	default:
1139 		if (mffield->array) gf_free(mffield->array);
1140 		break;
1141 	}
1142 
1143 	mffield->array = NULL;
1144 	mffield->count = 0;
1145 	return GF_OK;
1146 }
1147 
1148 #ifndef GPAC_DISABLE_VRML
1149 
1150 #define MAX_MFFIELD_ALLOC		5000000
1151 GF_EXPORT
gf_sg_vrml_mf_alloc(void * mf,u32 FieldType,u32 NbItems)1152 GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems)
1153 {
1154 	u32 FieldSize;
1155 	GenMFField *mffield = (GenMFField *)mf;
1156 
1157 	if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM;
1158 	if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM;
1159 
1160 	FieldSize = gf_sg_vrml_get_sf_size(FieldType);
1161 
1162 	//field we can't copy
1163 	if (!FieldSize) return GF_BAD_PARAM;
1164 	if (NbItems>MAX_MFFIELD_ALLOC) return GF_IO_ERR;
1165 
1166 	if (mffield->count==NbItems) return GF_OK;
1167 	gf_sg_vrml_mf_reset(mf, FieldType);
1168 	if (NbItems) {
1169 		mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize*NbItems);
1170 		memset(mffield->array, 0, sizeof(char)*FieldSize*NbItems);
1171 	}
1172 	mffield->count = NbItems;
1173 	return GF_OK;
1174 }
1175 
1176 GF_EXPORT
gf_sg_vrml_mf_get_item(void * mf,u32 FieldType,void ** new_ptr,u32 ItemPos)1177 GF_Err gf_sg_vrml_mf_get_item(void *mf, u32 FieldType, void **new_ptr, u32 ItemPos)
1178 {
1179 	u32 FieldSize;
1180 	GenMFField *mffield = (GenMFField *)mf;
1181 
1182 	*new_ptr = NULL;
1183 	if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM;
1184 	if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM;
1185 
1186 	FieldSize = gf_sg_vrml_get_sf_size(FieldType);
1187 
1188 	//field we can't copy
1189 	if (!FieldSize) return GF_BAD_PARAM;
1190 	if (ItemPos >= mffield->count) return GF_BAD_PARAM;
1191 	*new_ptr = mffield->array + ItemPos * FieldSize;
1192 	return GF_OK;
1193 }
1194 
1195 
1196 GF_EXPORT
gf_sg_vrml_mf_append(void * mf,u32 FieldType,void ** new_ptr)1197 GF_Err gf_sg_vrml_mf_append(void *mf, u32 FieldType, void **new_ptr)
1198 {
1199 	GenMFField *mffield = (GenMFField *)mf;
1200 	return gf_sg_vrml_mf_insert(mf, FieldType, new_ptr, mffield->count+2);
1201 }
1202 
1203 
1204 //remove the specified item (0-based index)
1205 GF_EXPORT
gf_sg_vrml_mf_remove(void * mf,u32 FieldType,u32 RemoveFrom)1206 GF_Err gf_sg_vrml_mf_remove(void *mf, u32 FieldType, u32 RemoveFrom)
1207 {
1208 	char *buffer;
1209 	u32 FieldSize, i, k;
1210 	GenMFField *mffield = (GenMFField *)mf;
1211 
1212 	FieldSize = gf_sg_vrml_get_sf_size(FieldType);
1213 
1214 	//field we can't copy
1215 	if (!FieldSize) return GF_BAD_PARAM;
1216 
1217 	if (!mffield->count || RemoveFrom >= mffield->count) return GF_BAD_PARAM;
1218 
1219 	if (mffield->count == 1) {
1220 		gf_free(mffield->array);
1221 		mffield->array = NULL;
1222 		mffield->count = 0;
1223 		return GF_OK;
1224 	}
1225 	k=0;
1226 	buffer = (char*)gf_malloc(sizeof(char)*(mffield->count-1)*FieldSize);
1227 	for (i=0; i<mffield->count; i++) {
1228 		if (RemoveFrom == i) {
1229 			k = 1;
1230 		} else {
1231 			memcpy(buffer + (i-k)*FieldSize, mffield->array + i*FieldSize, FieldSize);
1232 		}
1233 	}
1234 	gf_free(mffield->array);
1235 	mffield->array = buffer;
1236 	mffield->count -= 1;
1237 	return GF_OK;
1238 }
1239 
1240 /*special cloning with type-casting from SF/MF strings to URL conversion since proto URL doesn't exist
1241 as a field type (it's just a stupid encoding trick) */
VRML_FieldCopyCast(void * dest,u32 dst_field_type,void * orig,u32 ori_field_type)1242 void VRML_FieldCopyCast(void *dest, u32 dst_field_type, void *orig, u32 ori_field_type)
1243 {
1244 	SFURL *url;
1245 	u32 size, i, sf_type_ori, sf_type_dst;
1246 	void *dst_field, *orig_field;
1247 	if (!dest || !orig) return;
1248 
1249 	switch (dst_field_type) {
1250 	case GF_SG_VRML_SFSTRING:
1251 		if (ori_field_type == GF_SG_VRML_SFURL) {
1252 			url = ((SFURL *)orig);
1253 			if (url->OD_ID>0) {
1254 				char tmp[50];
1255 				sprintf(tmp, "%d", url->OD_ID);
1256 				if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
1257 				((SFString*)dest)->buffer = gf_strdup(tmp);
1258 			} else {
1259 				if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
1260 				((SFString*)dest)->buffer = url->url ? gf_strdup(url->url) : NULL;
1261 			}
1262 		}
1263 		/*for SFString to MFString cast*/
1264 		else if (ori_field_type == GF_SG_VRML_SFSTRING) {
1265 			if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
1266 			((SFString*)dest)->buffer = ((SFString*)orig)->buffer ? gf_strdup(((SFString*)orig)->buffer) : NULL;
1267 		}
1268 		return;
1269 	case GF_SG_VRML_SFURL:
1270 		if (ori_field_type != GF_SG_VRML_SFSTRING) return;
1271 		url = ((SFURL *)dest);
1272 		url->OD_ID = 0;
1273 		if (url->url) gf_free(url->url);
1274 		if ( ((SFString*)orig)->buffer)
1275 			url->url = gf_strdup(((SFString*)orig)->buffer);
1276 		else
1277 			url->url = NULL;
1278 		return;
1279 	case GF_SG_VRML_MFSTRING:
1280 	case GF_SG_VRML_MFURL:
1281 		break;
1282 	default:
1283 		return;
1284 	}
1285 
1286 	sf_type_dst = gf_sg_vrml_get_sf_type(dst_field_type);
1287 
1288 	if (gf_sg_vrml_is_sf_field(ori_field_type)) {
1289 		size = 1;
1290 		gf_sg_vrml_mf_alloc(dest, dst_field_type, size);
1291 		gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, 0);
1292 		VRML_FieldCopyCast(dst_field, sf_type_dst, orig, ori_field_type);
1293 		return;
1294 	}
1295 
1296 	size = ((GenMFField *)orig)->count;
1297 	if (size != ((GenMFField *)dest)->count) gf_sg_vrml_mf_alloc(dest, dst_field_type, size);
1298 
1299 	sf_type_ori = gf_sg_vrml_get_sf_type(ori_field_type);
1300 	//duplicate all items
1301 	for (i=0; i<size; i++) {
1302 		gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, i);
1303 		gf_sg_vrml_mf_get_item(orig, ori_field_type, &orig_field, i);
1304 		VRML_FieldCopyCast(dst_field, sf_type_dst, orig_field, sf_type_ori);
1305 	}
1306 	return;
1307 }
1308 
1309 GF_EXPORT
gf_sg_vrml_field_clone(void * dest,void * orig,u32 field_type,GF_SceneGraph * inScene)1310 void gf_sg_vrml_field_clone(void *dest, void *orig, u32 field_type, GF_SceneGraph *inScene)
1311 {
1312 	u32 size, i, sf_type;
1313 	void *dst_field, *orig_field;
1314 
1315 	if (!dest || !orig) return;
1316 
1317 	switch (field_type) {
1318 	case GF_SG_VRML_SFBOOL:
1319 		memcpy(dest, orig, sizeof(SFBool));
1320 		break;
1321 	case GF_SG_VRML_SFCOLOR:
1322 		memcpy(dest, orig, sizeof(SFColor));
1323 		break;
1324 	case GF_SG_VRML_SFFLOAT:
1325 		memcpy(dest, orig, sizeof(SFFloat));
1326 		break;
1327 	case GF_SG_VRML_SFINT32:
1328 		memcpy(dest, orig, sizeof(SFInt32));
1329 		break;
1330 	case GF_SG_VRML_SFROTATION:
1331 		memcpy(dest, orig, sizeof(SFRotation));
1332 		break;
1333 	case GF_SG_VRML_SFTIME:
1334 		memcpy(dest, orig, sizeof(SFTime));
1335 		break;
1336 	case GF_SG_VRML_SFVEC2F:
1337 		memcpy(dest, orig, sizeof(SFVec2f));
1338 		break;
1339 	case GF_SG_VRML_SFVEC3F:
1340 		memcpy(dest, orig, sizeof(SFVec3f));
1341 		break;
1342 	case GF_SG_VRML_SFATTRREF:
1343 		memcpy(dest, orig, sizeof(SFAttrRef));
1344 		break;
1345 	case GF_SG_VRML_SFSTRING:
1346 		if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
1347 		if ( ((SFString*)orig)->buffer )
1348 			((SFString*)dest)->buffer = gf_strdup(((SFString*)orig)->buffer);
1349 		else
1350 			((SFString*)dest)->buffer = NULL;
1351 		break;
1352 	case GF_SG_VRML_SFURL:
1353 		if ( ((SFURL *)dest)->url ) gf_free( ((SFURL *)dest)->url );
1354 		((SFURL *)dest)->OD_ID = ((SFURL *)orig)->OD_ID;
1355 		if (((SFURL *)orig)->url)
1356 			((SFURL *)dest)->url = gf_strdup(((SFURL *)orig)->url);
1357 		else
1358 			((SFURL *)dest)->url = NULL;
1359 		break;
1360 	case GF_SG_VRML_SFIMAGE:
1361 		if (((SFImage *)dest)->pixels) gf_free(((SFImage *)dest)->pixels);
1362 		((SFImage *)dest)->width = ((SFImage *)orig)->width;
1363 		((SFImage *)dest)->height = ((SFImage *)orig)->height;
1364 		((SFImage *)dest)->numComponents  = ((SFImage *)orig)->numComponents;
1365 		size = ((SFImage *)dest)->width * ((SFImage *)dest)->height * ((SFImage *)dest)->numComponents;
1366 		((SFImage *)dest)->pixels = (u8*)gf_malloc(sizeof(char)*size);
1367 		memcpy(((SFImage *)dest)->pixels, ((SFImage *)orig)->pixels, sizeof(char)*size);
1368 		break;
1369 	case GF_SG_VRML_SFCOMMANDBUFFER:
1370 	{
1371 		SFCommandBuffer *cb_dst = (SFCommandBuffer *)dest;
1372 		SFCommandBuffer *cb_src = (SFCommandBuffer *)orig;
1373 
1374 		cb_dst->bufferSize = cb_src->bufferSize;
1375 		if (cb_dst->bufferSize && !gf_list_count(cb_src->commandList) ) {
1376 			cb_dst->buffer = (u8*)gf_realloc(cb_dst->buffer, sizeof(char)*cb_dst->bufferSize);
1377 			memcpy(cb_dst->buffer, cb_src->buffer, sizeof(char)*cb_src->bufferSize);
1378 		} else {
1379 			u32 j, c2;
1380 			if (cb_dst->buffer) gf_free(cb_dst->buffer);
1381 			cb_dst->buffer = NULL;
1382 			/*clone command list*/
1383 			c2 = gf_list_count(cb_src->commandList);
1384 			for (j=0; j<c2; j++) {
1385 				GF_Command *sub_com = (GF_Command *)gf_list_get(cb_src->commandList, j);
1386 				GF_Command *new_com = gf_sg_vrml_command_clone(sub_com, inScene, 0);
1387 				gf_list_add(cb_dst->commandList, new_com);
1388 			}
1389 		}
1390 	}
1391 	break;
1392 
1393 	/*simply copy text string*/
1394 	case GF_SG_VRML_SFSCRIPT:
1395 		if (((SFScript*)dest)->script_text) gf_free(((SFScript*)dest)->script_text);
1396 		((SFScript*)dest)->script_text = NULL;
1397 		if ( ((SFScript*)orig)->script_text)
1398 			((SFScript *)dest)->script_text = (char *)gf_strdup( (char*) ((SFScript*)orig)->script_text );
1399 		break;
1400 
1401 
1402 	//simple MFFields, do a memcpy
1403 	case GF_SG_VRML_MFBOOL:
1404 	case GF_SG_VRML_MFFLOAT:
1405 	case GF_SG_VRML_MFTIME:
1406 	case GF_SG_VRML_MFINT32:
1407 	case GF_SG_VRML_MFVEC3F:
1408 	case GF_SG_VRML_MFVEC2F:
1409 	case GF_SG_VRML_MFCOLOR:
1410 	case GF_SG_VRML_MFROTATION:
1411 	case GF_SG_VRML_MFATTRREF:
1412 		size = gf_sg_vrml_get_sf_size(field_type) * ((GenMFField *)orig)->count;
1413 		if (((GenMFField *)orig)->count != ((GenMFField *)dest)->count) {
1414 			((GenMFField *)dest)->array = gf_realloc(((GenMFField *)dest)->array, size);
1415 			((GenMFField *)dest)->count = ((GenMFField *)orig)->count;
1416 		}
1417 		memcpy(((GenMFField *)dest)->array, ((GenMFField *)orig)->array, size);
1418 		break;
1419 	//complex MFFields
1420 	case GF_SG_VRML_MFSTRING:
1421 	case GF_SG_VRML_MFIMAGE:
1422 	case GF_SG_VRML_MFURL:
1423 	case GF_SG_VRML_MFSCRIPT:
1424 		size = ((GenMFField *)orig)->count;
1425 		gf_sg_vrml_mf_reset(dest, field_type);
1426 		gf_sg_vrml_mf_alloc(dest, field_type, size);
1427 		sf_type = gf_sg_vrml_get_sf_type(field_type);
1428 		//duplicate all items
1429 		for (i=0; i<size; i++) {
1430 			gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i);
1431 			gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i);
1432 			gf_sg_vrml_field_copy(dst_field, orig_field, sf_type);
1433 		}
1434 		break;
1435 	}
1436 }
1437 
1438 GF_EXPORT
gf_sg_vrml_field_copy(void * dest,void * orig,u32 field_type)1439 void gf_sg_vrml_field_copy(void *dest, void *orig, u32 field_type)
1440 {
1441 	gf_sg_vrml_field_clone(dest, orig, field_type, NULL);
1442 }
1443 
1444 GF_EXPORT
gf_sg_vrml_field_equal(void * dest,void * orig,u32 field_type)1445 Bool gf_sg_vrml_field_equal(void *dest, void *orig, u32 field_type)
1446 {
1447 	u32 size, i, sf_type;
1448 	void *dst_field, *orig_field;
1449 	Bool changed = 0;
1450 
1451 	if (!dest || !orig) return 0;
1452 
1453 	switch (field_type) {
1454 	case GF_SG_VRML_SFBOOL:
1455 		changed = memcmp(dest, orig, sizeof(SFBool));
1456 		break;
1457 	case GF_SG_VRML_SFCOLOR:
1458 		if (((SFColor *)dest)->red != ((SFColor *)orig)->red) changed = 1;
1459 		else if (((SFColor *)dest)->green != ((SFColor *)orig)->green) changed = 1;
1460 		else if (((SFColor *)dest)->blue != ((SFColor *)orig)->blue) changed = 1;
1461 		break;
1462 	case GF_SG_VRML_SFFLOAT:
1463 		if ( (*(SFFloat *)dest) != (*(SFFloat *)orig) ) changed = 1;
1464 		break;
1465 	case GF_SG_VRML_SFINT32:
1466 		changed = memcmp(dest, orig, sizeof(SFInt32));
1467 		break;
1468 	case GF_SG_VRML_SFROTATION:
1469 		if (((SFRotation *)dest)->x != ((SFRotation *)orig)->x) changed = 1;
1470 		else if (((SFRotation *)dest)->y != ((SFRotation *)orig)->y) changed = 1;
1471 		else if (((SFRotation *)dest)->z != ((SFRotation *)orig)->z) changed = 1;
1472 		else if (((SFRotation *)dest)->q != ((SFRotation *)orig)->q) changed = 1;
1473 		break;
1474 	case GF_SG_VRML_SFTIME:
1475 		if ( (*(SFTime *)dest) != (*(SFTime*)orig) ) changed = 1;
1476 		break;
1477 	case GF_SG_VRML_SFVEC2F:
1478 		if (((SFVec2f *)dest)->x != ((SFVec2f *)orig)->x) changed = 1;
1479 		else if (((SFVec2f *)dest)->y != ((SFVec2f *)orig)->y) changed = 1;
1480 		break;
1481 	case GF_SG_VRML_SFVEC3F:
1482 		if (((SFVec3f *)dest)->x != ((SFVec3f *)orig)->x) changed = 1;
1483 		else if (((SFVec3f *)dest)->y != ((SFVec3f *)orig)->y) changed = 1;
1484 		else if (((SFVec3f *)dest)->z != ((SFVec3f *)orig)->z) changed = 1;
1485 		break;
1486 	case GF_SG_VRML_SFSTRING:
1487 		if ( ((SFString*)dest)->buffer && ((SFString*)orig)->buffer) {
1488 			changed = strcmp(((SFString*)dest)->buffer, ((SFString*)orig)->buffer);
1489 		} else {
1490 			changed = ( !((SFString*)dest)->buffer && !((SFString*)orig)->buffer) ? 0 : 1;
1491 		}
1492 		break;
1493 	case GF_SG_VRML_SFURL:
1494 		if (((SFURL *)dest)->OD_ID > 0 || ((SFURL *)orig)->OD_ID > 0) {
1495 			if ( ((SFURL *)orig)->OD_ID != ((SFURL *)dest)->OD_ID) changed = 1;
1496 		} else {
1497 			if ( ((SFURL *)orig)->url && ! ((SFURL *)dest)->url) changed = 1;
1498 			else if ( ! ((SFURL *)orig)->url && ((SFURL *)dest)->url) changed = 1;
1499 			else if ( ((SFURL *)orig)->url && ((SFURL *)dest)->url && strcmp( ((SFURL *)orig)->url , ((SFURL *)dest)->url) ) changed = 1;
1500 		}
1501 		break;
1502 	case GF_SG_VRML_SFIMAGE:
1503 	case GF_SG_VRML_SFATTRREF:
1504 	case GF_SG_VRML_SFSCRIPT:
1505 	case GF_SG_VRML_SFCOMMANDBUFFER:
1506 		changed = 1;
1507 		break;
1508 
1509 	//MFFields
1510 	case GF_SG_VRML_MFATTRREF:
1511 		changed = 1;
1512 		break;
1513 	case GF_SG_VRML_MFBOOL:
1514 	case GF_SG_VRML_MFFLOAT:
1515 	case GF_SG_VRML_MFTIME:
1516 	case GF_SG_VRML_MFINT32:
1517 	case GF_SG_VRML_MFSTRING:
1518 	case GF_SG_VRML_MFVEC3F:
1519 	case GF_SG_VRML_MFVEC2F:
1520 	case GF_SG_VRML_MFCOLOR:
1521 	case GF_SG_VRML_MFROTATION:
1522 	case GF_SG_VRML_MFIMAGE:
1523 	case GF_SG_VRML_MFURL:
1524 	case GF_SG_VRML_MFSCRIPT:
1525 		if ( ((GenMFField *)orig)->count != ((GenMFField *)dest)->count) changed = 1;
1526 		else {
1527 			size = ((GenMFField *)orig)->count;
1528 			sf_type = gf_sg_vrml_get_sf_type(field_type);
1529 			for (i=0; i<size; i++) {
1530 				gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i);
1531 				gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i);
1532 				if (! gf_sg_vrml_field_equal(dst_field, orig_field, sf_type) ) {
1533 					changed = 1;
1534 					break;
1535 				}
1536 			}
1537 		}
1538 		break;
1539 	}
1540 	return changed ? 0 : 1;
1541 }
1542 
1543 
1544 
1545 GF_EXPORT
gf_sg_sfcolor_to_rgba(SFColor val)1546 SFColorRGBA gf_sg_sfcolor_to_rgba(SFColor val)
1547 {
1548 	SFColorRGBA res;
1549 	res.alpha = FIX_ONE;
1550 	res.red = val.red;
1551 	res.green = val.green;
1552 	res.blue = val.blue;
1553 	return res;
1554 }
1555 
1556 
1557 GF_EXPORT
gf_node_get_num_fields_in_mode(GF_Node * Node,u8 IndexMode)1558 u32 gf_node_get_num_fields_in_mode(GF_Node *Node, u8 IndexMode)
1559 {
1560 	assert(Node);
1561 	if (Node->sgprivate->tag == TAG_ProtoNode) return gf_sg_proto_get_num_fields(Node, IndexMode);
1562 	else if (Node->sgprivate->tag == TAG_MPEG4_Script)
1563 		return gf_sg_script_get_num_fields(Node, IndexMode);
1564 #ifndef GPAC_DISABLE_X3D
1565 	else if (Node->sgprivate->tag == TAG_X3D_Script)
1566 		return gf_sg_script_get_num_fields(Node, IndexMode);
1567 #endif
1568 	else if (Node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) return gf_sg_mpeg4_node_get_field_count(Node, IndexMode);
1569 #ifndef GPAC_DISABLE_X3D
1570 	else if (Node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_sg_x3d_node_get_field_count(Node);
1571 #endif
1572 	else return 0;
1573 }
1574 
1575 
1576 
1577 /*all our internally handled nodes*/
1578 Bool InitColorInterpolator(M_ColorInterpolator *node);
1579 Bool InitCoordinateInterpolator2D(M_CoordinateInterpolator2D *node);
1580 Bool InitCoordinateInterpolator(M_CoordinateInterpolator *n);
1581 Bool InitNormalInterpolator(M_NormalInterpolator *n);
1582 Bool InitPositionInterpolator2D(M_PositionInterpolator2D *node);
1583 Bool InitPositionInterpolator(M_PositionInterpolator *node);
1584 Bool InitScalarInterpolator(M_ScalarInterpolator *node);
1585 Bool InitOrientationInterpolator(M_OrientationInterpolator *node);
1586 Bool InitValuator(M_Valuator *node);
1587 Bool InitCoordinateInterpolator4D(M_CoordinateInterpolator4D *node);
1588 Bool InitPositionInterpolator4D(M_PositionInterpolator4D *node);
1589 
1590 void PA_Init(GF_Node *n);
1591 void PA_Modified(GF_Node *n, GF_FieldInfo *field);
1592 void PA2D_Init(GF_Node *n);
1593 void PA2D_Modified(GF_Node *n, GF_FieldInfo *field);
1594 void SA_Init(GF_Node *n);
1595 void SA_Modified(GF_Node *n, GF_FieldInfo *field);
1596 /*X3D tools*/
1597 void InitBooleanFilter(GF_Node *n);
1598 void InitBooleanSequencer(GF_Node *n);
1599 void InitBooleanToggle(GF_Node *n);
1600 void InitBooleanTrigger(GF_Node *n);
1601 void InitIntegerSequencer(GF_Node *n);
1602 void InitIntegerTrigger(GF_Node *n);
1603 void InitTimeTrigger(GF_Node *n);
1604 
gf_sg_vrml_node_init(GF_Node * node)1605 Bool gf_sg_vrml_node_init(GF_Node *node)
1606 {
1607 	switch (node->sgprivate->tag) {
1608 	case TAG_MPEG4_ColorInterpolator:
1609 #ifndef GPAC_DISABLE_X3D
1610 	case TAG_X3D_ColorInterpolator:
1611 #endif
1612 		return InitColorInterpolator((M_ColorInterpolator *)node);
1613 	case TAG_MPEG4_CoordinateInterpolator:
1614 #ifndef GPAC_DISABLE_X3D
1615 	case TAG_X3D_CoordinateInterpolator:
1616 #endif
1617 		return InitCoordinateInterpolator((M_CoordinateInterpolator *)node);
1618 	case TAG_MPEG4_CoordinateInterpolator2D:
1619 		return InitCoordinateInterpolator2D((M_CoordinateInterpolator2D *)node);
1620 	case TAG_MPEG4_NormalInterpolator:
1621 #ifndef GPAC_DISABLE_X3D
1622 	case TAG_X3D_NormalInterpolator:
1623 #endif
1624 		return InitNormalInterpolator((M_NormalInterpolator*)node);
1625 	case TAG_MPEG4_OrientationInterpolator:
1626 #ifndef GPAC_DISABLE_X3D
1627 	case TAG_X3D_OrientationInterpolator:
1628 #endif
1629 		return InitOrientationInterpolator((M_OrientationInterpolator*)node);
1630 	case TAG_MPEG4_PositionInterpolator:
1631 #ifndef GPAC_DISABLE_X3D
1632 	case TAG_X3D_PositionInterpolator:
1633 #endif
1634 		return InitPositionInterpolator((M_PositionInterpolator *)node);
1635 	case TAG_MPEG4_PositionInterpolator2D:
1636 #ifndef GPAC_DISABLE_X3D
1637 	case TAG_X3D_PositionInterpolator2D:
1638 #endif
1639 		return InitPositionInterpolator2D((M_PositionInterpolator2D *)node);
1640 	case TAG_MPEG4_ScalarInterpolator:
1641 #ifndef GPAC_DISABLE_X3D
1642 	case TAG_X3D_ScalarInterpolator:
1643 #endif
1644 		return InitScalarInterpolator((M_ScalarInterpolator *)node);
1645 	case TAG_MPEG4_Valuator:
1646 		return InitValuator((M_Valuator *)node);
1647 	case TAG_MPEG4_PositionAnimator:
1648 		PA_Init(node);
1649 		return 1;
1650 	case TAG_MPEG4_PositionAnimator2D:
1651 		PA2D_Init(node);
1652 		return 1;
1653 	case TAG_MPEG4_ScalarAnimator:
1654 		SA_Init(node);
1655 		return 1;
1656 	case TAG_MPEG4_PositionInterpolator4D:
1657 		return InitPositionInterpolator4D((M_PositionInterpolator4D *)node);
1658 	case TAG_MPEG4_CoordinateInterpolator4D:
1659 		return InitCoordinateInterpolator4D((M_CoordinateInterpolator4D *)node);
1660 	case TAG_MPEG4_Script:
1661 #ifndef GPAC_DISABLE_X3D
1662 	case TAG_X3D_Script:
1663 #endif
1664 		return 1;
1665 
1666 #ifndef GPAC_DISABLE_X3D
1667 	case TAG_X3D_BooleanFilter:
1668 		InitBooleanFilter(node);
1669 		return 1;
1670 	case TAG_X3D_BooleanSequencer:
1671 		InitBooleanSequencer(node);
1672 		return 1;
1673 	case TAG_X3D_BooleanToggle:
1674 		InitBooleanToggle(node);
1675 		return 1;
1676 	case TAG_X3D_BooleanTrigger:
1677 		InitBooleanTrigger(node);
1678 		return 1;
1679 	case TAG_X3D_IntegerSequencer:
1680 		InitIntegerSequencer(node);
1681 		return 1;
1682 	case TAG_X3D_IntegerTrigger:
1683 		InitIntegerTrigger(node);
1684 		return 1;
1685 	case TAG_X3D_TimeTrigger:
1686 		InitTimeTrigger(node);
1687 		return 1;
1688 #endif
1689 	}
1690 	return 0;
1691 }
1692 
gf_sg_vrml_node_changed(GF_Node * node,GF_FieldInfo * field)1693 Bool gf_sg_vrml_node_changed(GF_Node *node, GF_FieldInfo *field)
1694 {
1695 	switch (node->sgprivate->tag) {
1696 	case TAG_ProtoNode:
1697 		/*hardcoded protos need modification notifs*/
1698 		if (node->sgprivate->UserCallback) return 0;
1699 	case TAG_MPEG4_ColorInterpolator:
1700 	case TAG_MPEG4_CoordinateInterpolator:
1701 	case TAG_MPEG4_CoordinateInterpolator2D:
1702 	case TAG_MPEG4_NormalInterpolator:
1703 	case TAG_MPEG4_OrientationInterpolator:
1704 	case TAG_MPEG4_PositionInterpolator:
1705 	case TAG_MPEG4_PositionInterpolator2D:
1706 	case TAG_MPEG4_ScalarInterpolator:
1707 	case TAG_MPEG4_Valuator:
1708 	case TAG_MPEG4_PositionInterpolator4D:
1709 	case TAG_MPEG4_CoordinateInterpolator4D:
1710 	case TAG_MPEG4_Script:
1711 #ifndef GPAC_DISABLE_X3D
1712 	case TAG_X3D_ColorInterpolator:
1713 	case TAG_X3D_CoordinateInterpolator:
1714 	case TAG_X3D_NormalInterpolator:
1715 	case TAG_X3D_OrientationInterpolator:
1716 	case TAG_X3D_PositionInterpolator:
1717 	case TAG_X3D_ScalarInterpolator:
1718 	case TAG_X3D_Script:
1719 	case TAG_X3D_BooleanFilter:
1720 	case TAG_X3D_BooleanSequencer:
1721 	case TAG_X3D_BooleanToggle:
1722 	case TAG_X3D_BooleanTrigger:
1723 	case TAG_X3D_IntegerSequencer:
1724 	case TAG_X3D_IntegerTrigger:
1725 	case TAG_X3D_TimeTrigger:
1726 #endif
1727 		return 1;
1728 	case TAG_MPEG4_PositionAnimator:
1729 		PA_Modified(node, field);
1730 		return 1;
1731 	case TAG_MPEG4_PositionAnimator2D:
1732 		PA2D_Modified(node, field);
1733 		return 1;
1734 	case TAG_MPEG4_ScalarAnimator:
1735 		SA_Modified(node, field);
1736 		return 1;
1737 	}
1738 	return 0;
1739 }
1740 
1741 #if 0 //unused
1742 char *gf_node_vrml_dump_attribute(GF_Node *n, GF_FieldInfo *info)
1743 {
1744 	char szVal[1024];
1745 
1746 	switch (info->fieldType) {
1747 	case GF_SG_VRML_SFBOOL:
1748 		strcpy(szVal, *((SFBool*)info->far_ptr) ? "TRUE" : "FALSE");
1749 		return gf_strdup(szVal);
1750 	case GF_SG_VRML_SFINT32:
1751 		sprintf(szVal, "%d", *((SFInt32*)info->far_ptr) );
1752 		return gf_strdup(szVal);
1753 	case GF_SG_VRML_SFFLOAT:
1754 		sprintf(szVal, "%g", FIX2FLT( *((SFFloat*)info->far_ptr) ) );
1755 		return gf_strdup(szVal);
1756 	case GF_SG_VRML_SFDOUBLE:
1757 		sprintf(szVal, "%g", *((SFDouble *)info->far_ptr) );
1758 		return gf_strdup(szVal);
1759 	case GF_SG_VRML_SFTIME:
1760 		sprintf(szVal, "%g", *((SFTime *)info->far_ptr) );
1761 		return gf_strdup(szVal);
1762 	case GF_SG_VRML_SFVEC2F:
1763 		sprintf(szVal, "%g %g", FIX2FLT(((SFVec2f *)info->far_ptr)->x), FIX2FLT( ((SFVec2f *)info->far_ptr)->y) );
1764 		return gf_strdup(szVal);
1765 	case GF_SG_VRML_SFVEC2D:
1766 		sprintf(szVal, "%g %g", ((SFVec2d *)info->far_ptr)->x, ((SFVec2d *)info->far_ptr)->y);
1767 		return gf_strdup(szVal);
1768 	case GF_SG_VRML_SFVEC3F:
1769 		sprintf(szVal, "%g %g %g", FIX2FLT(((SFVec3f *)info->far_ptr)->x), FIX2FLT( ((SFVec3f *)info->far_ptr)->y) , FIX2FLT( ((SFVec3f *)info->far_ptr)->z) );
1770 		return gf_strdup(szVal);
1771 	case GF_SG_VRML_SFVEC3D:
1772 		sprintf(szVal, "%g %g %g", ((SFVec3d *)info->far_ptr)->x, ((SFVec3d *)info->far_ptr)->y, ((SFVec3d *)info->far_ptr)->z);
1773 		return gf_strdup(szVal);
1774 	case GF_SG_VRML_SFCOLOR:
1775 		sprintf(szVal, "%g %g %g", FIX2FLT(((SFColor *)info->far_ptr)->red), FIX2FLT( ((SFColor *)info->far_ptr)->green) , FIX2FLT( ((SFColor *)info->far_ptr)->blue) );
1776 		return gf_strdup(szVal);
1777 	case GF_SG_VRML_SFCOLORRGBA:
1778 		sprintf(szVal, "%g %g %g %g", FIX2FLT(((SFColorRGBA *)info->far_ptr)->red), FIX2FLT( ((SFColorRGBA*)info->far_ptr)->green) , FIX2FLT( ((SFColorRGBA*)info->far_ptr)->blue) , FIX2FLT( ((SFColorRGBA*)info->far_ptr)->alpha) );
1779 		return gf_strdup(szVal);
1780 	case GF_SG_VRML_SFROTATION:
1781 		sprintf(szVal, "%g %g %g %g", FIX2FLT(((SFRotation *)info->far_ptr)->x), FIX2FLT( ((SFRotation *)info->far_ptr)->y) , FIX2FLT( ((SFRotation *)info->far_ptr)->z), FIX2FLT( ((SFRotation *)info->far_ptr)->q) );
1782 		return gf_strdup(szVal);
1783 	case GF_SG_VRML_SFSTRING:
1784 		if (!((SFString*)info->far_ptr)->buffer ) return gf_strdup("");
1785 		return gf_strdup( ((SFString*)info->far_ptr)->buffer );
1786 
1787 	case GF_SG_VRML_SFURL:
1788 		if (((SFURL *)info->far_ptr)->url) {
1789 			return gf_strdup( ((SFURL *)info->far_ptr)->url );
1790 		} else {
1791 			sprintf(szVal, "od://%d", ((SFURL *)info->far_ptr)->OD_ID);
1792 			return gf_strdup(szVal);
1793 		}
1794 
1795 	case GF_SG_VRML_SFIMAGE:
1796 	{
1797 		u32 i, count;
1798 		char *buf;
1799 		SFImage *img = (SFImage *)info->far_ptr;
1800 
1801 		count = img->width * img->height * img->numComponents;
1802 		i = (3/*' 0x'*/ + 2/*%02X*/*img->numComponents)*count + 20;
1803 		buf = gf_malloc(sizeof(char) * i);
1804 
1805 		sprintf(buf , "%d %d %d", img->width, img->height, img->numComponents);
1806 
1807 		for (i=0; i<count; ) {
1808 			switch (img->numComponents) {
1809 			case 1:
1810 				sprintf(szVal, " 0x%02X", img->pixels[i]);
1811 				i++;
1812 				break;
1813 			case 2:
1814 				sprintf(szVal, " 0x%02X%02X", img->pixels[i], img->pixels[i+1]);
1815 				i+=2;
1816 				break;
1817 			case 3:
1818 				sprintf(szVal, " 0x%02X%02X%02X", img->pixels[i], img->pixels[i+1], img->pixels[i+2]);
1819 				i+=3;
1820 				break;
1821 			case 4:
1822 				sprintf(szVal, " 0x%02X%02X%02X%02X", img->pixels[i], img->pixels[i+1], img->pixels[i+2], img->pixels[i+3]);
1823 				i+=4;
1824 				break;
1825 			}
1826 			strcat(buf, szVal);
1827 		}
1828 		return buf;
1829 	}
1830 	default:
1831 		break;
1832 	}
1833 	/*todo - dump MFFields*/
1834 	return NULL;
1835 }
1836 #endif
1837 
1838 
1839 #endif /*GPAC_DISABLE_VRML*/
1840 
gf_node_in_table(GF_Node * node,u32 NDTType)1841 Bool gf_node_in_table(GF_Node *node, u32 NDTType)
1842 {
1843 #ifndef GPAC_DISABLE_VRML
1844 	u32 tag = node ? node->sgprivate->tag : 0;
1845 	if (tag==TAG_ProtoNode) {
1846 		tag = gf_sg_proto_get_root_tag(((GF_ProtoInstance *)node)->proto_interface);
1847 		if (tag==TAG_UndefinedNode) return 1;
1848 	}
1849 	return gf_node_in_table_by_tag(tag, NDTType);
1850 #else
1851 	return 1;
1852 #endif
1853 }
1854