LCOV - code coverage report
Current view: top level - scenegraph - vrml_tools.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 786 846 92.9 %
Date: 2021-04-29 23:48:07 Functions: 89 92 96.7 %

          Line data    Source code
       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
      38       36697 : Bool gf_node_in_table_by_tag(u32 tag, u32 NDTType)
      39             : {
      40       36697 :         if (!tag) return 0;
      41       36697 :         if (tag==TAG_ProtoNode) return 1;
      42       36697 :         else if (tag<=GF_NODE_RANGE_LAST_MPEG4) {
      43             : #ifndef GPAC_DISABLE_BIFS
      44             :                 u32 i;
      45      134001 :                 for (i=0; i<GF_BIFS_LAST_VERSION; i++) {
      46      123957 :                         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        7129 :         else if (tag<=GF_NODE_RANGE_LAST_X3D) {
      58        7129 :                 return gf_x3d_get_node_type(NDTType, tag);
      59             :         }
      60             : #endif
      61             :         return 0;
      62             : }
      63             : 
      64             : 
      65           9 : 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           9 :         if (n->children) {
      72             :                 list = n->children;
      73           3 :                 while (list->next) list = list->next;
      74           3 :                 list->next = n->addChildren;
      75             :         } else {
      76           6 :                 n->children = n->addChildren;
      77             :         }
      78           9 :         n->addChildren = NULL;
      79             : 
      80             :         /*signal children field is modified*/
      81           9 :         field.name = "children";
      82           9 :         field.eventType = GF_SG_EVENT_EXPOSED_FIELD;
      83           9 :         field.fieldType = GF_SG_VRML_MFNODE;
      84           9 :         field.NDTtype = -1;
      85           9 :         if ( node->sgprivate->tag == TAG_MPEG4_Transform )
      86           0 :                 field.fieldIndex = 3;
      87             :         else
      88           9 :                 field.fieldIndex = 2;
      89           9 :         field.far_ptr = & n->children;
      90           9 :         gf_node_event_out(node, field.fieldIndex);
      91           9 :         gf_node_changed(node, &field);
      92             : 
      93           9 :         if (node->sgprivate->scenegraph->on_node_modified) {
      94           9 :                 field.name = "addChildren";
      95           9 :                 field.eventType = GF_SG_EVENT_IN;
      96           9 :                 field.fieldType = GF_SG_VRML_MFNODE;
      97           9 :                 field.NDTtype = -1;
      98           9 :                 field.fieldIndex = 0;
      99           9 :                 field.far_ptr = & n->addChildren;
     100           9 :                 node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, &field, NULL);
     101             :         }
     102           9 : }
     103             : 
     104           3 : 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           3 :         if (!n->removeChildren) return;
     111             : 
     112             :         list = n->removeChildren;
     113           6 :         while (list) {
     114           3 :                 if (gf_node_list_del_child(& n->children, list->node)) {
     115           3 :                         gf_node_unregister(list->node, node);
     116             :                 }
     117           3 :                 list = list->next;
     118             :         }
     119           3 :         gf_node_unregister_children(node, n->removeChildren);
     120           3 :         n->removeChildren = NULL;
     121             : 
     122             :         /*signal children field is modified*/
     123           3 :         field.name = "children";
     124           3 :         field.eventType = GF_SG_EVENT_EXPOSED_FIELD;
     125           3 :         field.fieldType = GF_SG_VRML_MFNODE;
     126           3 :         field.NDTtype = -1;
     127           3 :         if ( node->sgprivate->tag == TAG_MPEG4_Transform )
     128           0 :                 field.fieldIndex = 3;
     129             :         else
     130           3 :                 field.fieldIndex = 2;
     131           3 :         field.far_ptr = & n->children;
     132           3 :         gf_node_event_out(node, field.fieldIndex);
     133           3 :         gf_node_changed(node, &field);
     134             : 
     135             : 
     136           3 :         if (node->sgprivate->scenegraph->on_node_modified) {
     137           3 :                 field.name = "removeChildren";
     138           3 :                 field.eventType = GF_SG_EVENT_IN;
     139           3 :                 field.fieldType = GF_SG_VRML_MFNODE;
     140           3 :                 field.NDTtype = -1;
     141           3 :                 field.fieldIndex = 1;
     142           3 :                 field.far_ptr = & n->removeChildren;
     143           3 :                 node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, &field, NULL);
     144             :         }
     145             : }
     146             : 
     147       18909 : void gf_sg_vrml_parent_setup(GF_Node *pNode)
     148             : {
     149             :         GF_VRMLParent *par = (GF_VRMLParent *)pNode;
     150       18909 :         par->children = NULL;
     151       18909 :         par->addChildren = NULL;
     152       18909 :         par->on_addChildren = Node_on_add_children;
     153       18909 :         par->removeChildren = NULL;
     154       18909 :         par->on_removeChildren = Node_on_remove_children;
     155       18909 :         pNode->sgprivate->flags |= GF_SG_CHILD_DIRTY;
     156       18909 : }
     157             : 
     158       18909 : void gf_sg_vrml_parent_destroy(GF_Node *pNode)
     159             : {
     160             :         GF_VRMLParent *par = (GF_VRMLParent *)pNode;
     161       18909 :         gf_node_unregister_children(pNode, par->children);
     162       18909 :         gf_node_unregister_children(pNode, par->addChildren);
     163       18909 :         gf_node_unregister_children(pNode, par->removeChildren);
     164       18909 : }
     165             : 
     166             : GF_EXPORT
     167           3 : GF_Err gf_sg_delete_all_protos(GF_SceneGraph *scene)
     168             : {
     169           3 :         if (!scene) return GF_BAD_PARAM;
     170           9 :         while (gf_list_count(scene->protos)) {
     171           6 :                 GF_Proto *p = (GF_Proto *)gf_list_get(scene->protos, 0);
     172           6 :                 gf_sg_proto_del(p);
     173             :         }
     174             :         return GF_OK;
     175             : }
     176             : 
     177             : GF_EXPORT
     178         681 : void gf_sg_set_proto_loader(GF_SceneGraph *scene, GF_SceneGraph *(*GetExternProtoLib)(void *SceneCallback, MFURL *lib_url))
     179             : {
     180         681 :         if (!scene) return;
     181         681 :         scene->GetExternProtoLib = GetExternProtoLib;
     182             : }
     183             : 
     184             : GF_EXPORT
     185          25 : u32 gf_sg_get_next_available_route_id(GF_SceneGraph *sg)
     186             : {
     187             :         u32 i, count;
     188             :         u32 ID = 0;
     189             : 
     190          25 :         if (!sg->max_defined_route_id) {
     191          23 :                 count = gf_list_count(sg->Routes);
     192             :                 /*routes are not sorted*/
     193          58 :                 for (i=0; i<count; i++) {
     194          35 :                         GF_Route *r = (GF_Route *)gf_list_get(sg->Routes, i);
     195          35 :                         if (ID<=r->ID) ID = r->ID;
     196             :                 }
     197          23 :                 return ID+1;
     198             :         } else {
     199           2 :                 sg->max_defined_route_id++;
     200           2 :                 return sg->max_defined_route_id;
     201             :         }
     202             : }
     203             : 
     204             : GF_EXPORT
     205          51 : void gf_sg_set_max_defined_route_id(GF_SceneGraph *sg, u32 ID)
     206             : {
     207          51 :         sg->max_defined_route_id = MAX(sg->max_defined_route_id, ID);
     208          51 : }
     209             : 
     210             : GF_EXPORT
     211         107 : u32 gf_sg_get_next_available_proto_id(GF_SceneGraph *sg)
     212             : {
     213             :         u32 i, count;
     214             :         u32 ID = 0;
     215         107 :         count = gf_list_count(sg->protos);
     216             :         /*protos are not sorted*/
     217         111 :         for (i=0; i<count; i++) {
     218           4 :                 GF_Proto *p = (GF_Proto *)gf_list_get(sg->protos, i);
     219           4 :                 if (ID<=p->ID) ID = p->ID;
     220             :         }
     221         107 :         count = gf_list_count(sg->unregistered_protos);
     222         169 :         for (i=0; i<count; i++) {
     223          62 :                 GF_Proto *p = (GF_Proto *)gf_list_get(sg->unregistered_protos, i);
     224          62 :                 if (ID<=p->ID) ID = p->ID;
     225             :         }
     226         107 :         return ID+1;
     227             : }
     228             : 
     229             : //adds a child in the children list
     230             : GF_EXPORT
     231        6360 : GF_Err gf_node_insert_child(GF_Node *parent, GF_Node *new_child, s32 Position)
     232             : {
     233             :         GF_ParentNode *node = (GF_ParentNode *) parent;
     234        6360 :         if (Position == -1) {
     235        6290 :                 gf_node_list_add_child(& node->children, new_child);
     236             :         } else {
     237          70 :                 gf_node_list_insert_child(& node->children, new_child, Position);
     238             :         }
     239        6360 :         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
     253         416 : void gf_sg_script_load(GF_Node *n)
     254             : {
     255         416 :         if (n && n->sgprivate->scenegraph->script_load) n->sgprivate->scenegraph->script_load(n);
     256         416 : }
     257             : 
     258             : GF_EXPORT
     259        1277 : 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        1277 :         i=0;
     268        2759 :         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        1221 :                 if (name) {
     271         508 :                         if (proto->Name && !stricmp(name, proto->Name)) return proto;
     272         713 :                 } else if (proto->ID == ProtoID) return proto;
     273             :         }
     274             :         /*browse all top-level unregistered in reverse order*/
     275         333 :         for (i=gf_list_count(sg->unregistered_protos); i>0; i--) {
     276         281 :                 proto = (GF_Proto *)gf_list_get(sg->unregistered_protos, i-1);
     277         281 :                 if (name) {
     278         216 :                         if (proto->Name && !stricmp(name, proto->Name)) return proto;
     279          65 :                 } else if (proto->ID == ProtoID) return proto;
     280             :         }
     281             :         return NULL;
     282             : }
     283             : 
     284             : 
     285             : 
     286        2546 : static SFBool *NewSFBool()
     287             : {
     288        2546 :         SFBool *tmp = (SFBool *)gf_malloc(sizeof(SFBool));
     289             :         memset(tmp, 0, sizeof(SFBool));
     290        2546 :         return tmp;
     291             : }
     292        4903 : static SFFloat *NewSFFloat()
     293             : {
     294        4903 :         SFFloat *tmp = (SFFloat *)gf_malloc(sizeof(SFFloat));
     295             :         memset(tmp, 0, sizeof(SFFloat));
     296        4903 :         return tmp;
     297             : }
     298           2 : static SFDouble *NewSFDouble()
     299             : {
     300           2 :         SFDouble *tmp = (SFDouble *)gf_malloc(sizeof(SFDouble));
     301             :         memset(tmp, 0, sizeof(SFDouble));
     302           2 :         return tmp;
     303             : }
     304         139 : static SFTime *NewSFTime()
     305             : {
     306         139 :         SFTime *tmp = (SFTime *)gf_malloc(sizeof(SFTime));
     307             :         memset(tmp, 0, sizeof(SFTime));
     308         139 :         return tmp;
     309             : }
     310        2290 : static SFInt32 *NewSFInt32()
     311             : {
     312        2290 :         SFInt32 *tmp = (SFInt32 *)gf_malloc(sizeof(SFInt32));
     313             :         memset(tmp, 0, sizeof(SFInt32));
     314        2290 :         return tmp;
     315             : }
     316          32 : static SFString *NewSFString()
     317             : {
     318          32 :         SFString *tmp = (SFString *)gf_malloc(sizeof(SFString));
     319             :         memset(tmp, 0, sizeof(SFString));
     320          32 :         return tmp;
     321             : }
     322          18 : static SFVec3f *NewSFVec3f()
     323             : {
     324          18 :         SFVec3f *tmp = (SFVec3f *)gf_malloc(sizeof(SFVec3f));
     325             :         memset(tmp, 0, sizeof(SFVec3f));
     326          18 :         return tmp;
     327             : }
     328           2 : static SFVec3d *NewSFVec3d()
     329             : {
     330           2 :         SFVec3d *tmp = (SFVec3d *)gf_malloc(sizeof(SFVec3d));
     331             :         memset(tmp, 0, sizeof(SFVec3d));
     332           2 :         return tmp;
     333             : }
     334        4867 : static SFVec2f *NewSFVec2f()
     335             : {
     336        4867 :         SFVec2f *tmp = (SFVec2f *)gf_malloc(sizeof(SFVec2f));
     337             :         memset(tmp, 0, sizeof(SFVec2f));
     338        4867 :         return tmp;
     339             : }
     340           2 : static SFVec2d *NewSFVec2d()
     341             : {
     342           2 :         SFVec2d *tmp = (SFVec2d *)gf_malloc(sizeof(SFVec2d));
     343             :         memset(tmp, 0, sizeof(SFVec2d));
     344           2 :         return tmp;
     345             : }
     346        1701 : static SFColor *NewSFColor()
     347             : {
     348        1701 :         SFColor *tmp = (SFColor *)gf_malloc(sizeof(SFColor));
     349             :         memset(tmp, 0, sizeof(SFColor));
     350        1701 :         return tmp;
     351             : }
     352           2 : static SFColorRGBA *NewSFColorRGBA()
     353             : {
     354           2 :         SFColorRGBA *tmp = (SFColorRGBA *)gf_malloc(sizeof(SFColorRGBA));
     355             :         memset(tmp, 0, sizeof(SFColorRGBA));
     356           2 :         return tmp;
     357             : }
     358           2 : static SFRotation *NewSFRotation()
     359             : {
     360           2 :         SFRotation *tmp = (SFRotation *)gf_malloc(sizeof(SFRotation));
     361             :         memset(tmp, 0, sizeof(SFRotation));
     362           2 :         return tmp;
     363             : }
     364           2 : static SFImage *NewSFImage()
     365             : {
     366           2 :         SFImage *tmp = (SFImage *)gf_malloc(sizeof(SFImage));
     367             :         memset(tmp, 0, sizeof(SFImage));
     368           2 :         return tmp;
     369             : }
     370           2 : static SFURL *NewSFURL()
     371             : {
     372           2 :         SFURL *tmp = (SFURL *)gf_malloc(sizeof(SFURL));
     373             :         memset(tmp, 0, sizeof(SFURL));
     374           2 :         return tmp;
     375             : }
     376           2 : static SFCommandBuffer *NewSFCommandBuffer()
     377             : {
     378           2 :         SFCommandBuffer *tmp = (SFCommandBuffer *)gf_malloc(sizeof(SFCommandBuffer));
     379             :         memset(tmp, 0, sizeof(SFCommandBuffer));
     380           2 :         tmp->commandList = gf_list_new();
     381           2 :         return tmp;
     382             : }
     383           2 : static SFScript *NewSFScript()
     384             : {
     385           2 :         SFScript *tmp = (SFScript *)gf_malloc(sizeof(SFScript));
     386             :         memset(tmp, 0, sizeof(SFScript));
     387           2 :         return tmp;
     388             : }
     389           2 : static SFAttrRef *NewSFAttrRef()
     390             : {
     391             :         SFAttrRef *tmp;
     392           2 :         GF_SAFEALLOC(tmp, SFAttrRef);
     393           2 :         return tmp;
     394             : }
     395           2 : static MFBool *NewMFBool()
     396             : {
     397           2 :         MFBool *tmp = (MFBool *)gf_malloc(sizeof(MFBool));
     398             :         memset(tmp, 0, sizeof(MFBool));
     399           2 :         return tmp;
     400             : }
     401           8 : static MFFloat *NewMFFloat()
     402             : {
     403           8 :         MFFloat *tmp = (MFFloat *)gf_malloc(sizeof(MFFloat));
     404             :         memset(tmp, 0, sizeof(MFFloat));
     405           8 :         return tmp;
     406             : }
     407           2 : static MFTime *NewMFTime()
     408             : {
     409           2 :         MFTime *tmp = (MFTime *)gf_malloc(sizeof(MFTime));
     410             :         memset(tmp, 0, sizeof(MFTime));
     411           2 :         return tmp;
     412             : }
     413        1586 : static MFInt32 *NewMFInt32()
     414             : {
     415        1586 :         MFInt32 *tmp = (MFInt32 *)gf_malloc(sizeof(MFInt32));
     416             :         memset(tmp, 0, sizeof(MFInt32));
     417        1586 :         return tmp;
     418             : }
     419          81 : static MFString *NewMFString()
     420             : {
     421          81 :         MFString *tmp = (MFString *)gf_malloc(sizeof(MFString));
     422             :         memset(tmp, 0, sizeof(MFString));
     423          81 :         return tmp;
     424             : }
     425           4 : static MFVec3f *NewMFVec3f()
     426             : {
     427           4 :         MFVec3f *tmp = (MFVec3f *)gf_malloc(sizeof(MFVec3f));
     428             :         memset(tmp, 0, sizeof(MFVec3f));
     429           4 :         return tmp;
     430             : }
     431           2 : static MFVec3d *NewMFVec3d()
     432             : {
     433           2 :         MFVec3d *tmp = (MFVec3d *)gf_malloc(sizeof(MFVec3d));
     434             :         memset(tmp, 0, sizeof(MFVec3d));
     435           2 :         return tmp;
     436             : }
     437           8 : static MFVec2f *NewMFVec2f()
     438             : {
     439           8 :         MFVec2f *tmp = (MFVec2f *)gf_malloc(sizeof(MFVec2f));
     440             :         memset(tmp, 0, sizeof(MFVec2f));
     441           8 :         return tmp;
     442             : }
     443           2 : static MFVec2d *NewMFVec2d()
     444             : {
     445           2 :         MFVec2d *tmp = (MFVec2d *)gf_malloc(sizeof(MFVec2d));
     446             :         memset(tmp, 0, sizeof(MFVec2d));
     447           2 :         return tmp;
     448             : }
     449           3 : static MFColor *NewMFColor()
     450             : {
     451           3 :         MFColor *tmp = (MFColor *)gf_malloc(sizeof(MFColor));
     452             :         memset(tmp, 0, sizeof(MFColor));
     453           3 :         return tmp;
     454             : }
     455           2 : static MFColorRGBA *NewMFColorRGBA()
     456             : {
     457           2 :         MFColorRGBA *tmp = (MFColorRGBA *)gf_malloc(sizeof(MFColorRGBA));
     458             :         memset(tmp, 0, sizeof(MFColorRGBA));
     459           2 :         return tmp;
     460             : }
     461        1559 : static MFRotation *NewMFRotation()
     462             : {
     463        1559 :         MFRotation *tmp = (MFRotation *)gf_malloc(sizeof(MFRotation));
     464             :         memset(tmp, 0, sizeof(MFRotation));
     465        1559 :         return tmp;
     466             : }
     467          25 : static MFURL *NewMFURL()
     468             : {
     469          25 :         MFURL *tmp = (MFURL *)gf_malloc(sizeof(MFURL));
     470             :         memset(tmp, 0, sizeof(MFURL));
     471          25 :         return tmp;
     472             : }
     473           2 : static MFScript *NewMFScript()
     474             : {
     475           2 :         MFScript *tmp = (MFScript *)gf_malloc(sizeof(MFScript));
     476             :         memset(tmp, 0, sizeof(MFScript));
     477           2 :         return tmp;
     478             : }
     479           2 : static MFAttrRef *NewMFAttrRef()
     480             : {
     481             :         MFAttrRef *tmp;
     482           2 :         GF_SAFEALLOC(tmp, MFAttrRef);
     483           2 :         return tmp;
     484             : }
     485             : 
     486             : GF_EXPORT
     487       20998 : void *gf_sg_vrml_field_pointer_new(u32 FieldType)
     488             : {
     489       20998 :         switch (FieldType) {
     490        2546 :         case GF_SG_VRML_SFBOOL:
     491        2546 :                 return NewSFBool();
     492        4903 :         case GF_SG_VRML_SFFLOAT:
     493        4903 :                 return NewSFFloat();
     494           2 :         case GF_SG_VRML_SFDOUBLE:
     495           2 :                 return NewSFDouble();
     496         139 :         case GF_SG_VRML_SFTIME:
     497         139 :                 return NewSFTime();
     498        2290 :         case GF_SG_VRML_SFINT32:
     499        2290 :                 return NewSFInt32();
     500          32 :         case GF_SG_VRML_SFSTRING:
     501          32 :                 return NewSFString();
     502          18 :         case GF_SG_VRML_SFVEC3F:
     503          18 :                 return NewSFVec3f();
     504        4867 :         case GF_SG_VRML_SFVEC2F:
     505        4867 :                 return NewSFVec2f();
     506           2 :         case GF_SG_VRML_SFVEC3D:
     507           2 :                 return NewSFVec3d();
     508           2 :         case GF_SG_VRML_SFVEC2D:
     509           2 :                 return NewSFVec2d();
     510        1701 :         case GF_SG_VRML_SFCOLOR:
     511        1701 :                 return NewSFColor();
     512           2 :         case GF_SG_VRML_SFCOLORRGBA:
     513           2 :                 return NewSFColorRGBA();
     514           2 :         case GF_SG_VRML_SFROTATION:
     515           2 :                 return NewSFRotation();
     516           2 :         case GF_SG_VRML_SFIMAGE:
     517           2 :                 return NewSFImage();
     518           2 :         case GF_SG_VRML_SFATTRREF:
     519           2 :                 return NewSFAttrRef();
     520           2 :         case GF_SG_VRML_MFBOOL:
     521           2 :                 return NewMFBool();
     522           8 :         case GF_SG_VRML_MFFLOAT:
     523           8 :                 return NewMFFloat();
     524           2 :         case GF_SG_VRML_MFTIME:
     525           2 :                 return NewMFTime();
     526        1586 :         case GF_SG_VRML_MFINT32:
     527        1586 :                 return NewMFInt32();
     528          81 :         case GF_SG_VRML_MFSTRING:
     529          81 :                 return NewMFString();
     530           4 :         case GF_SG_VRML_MFVEC3F:
     531           4 :                 return NewMFVec3f();
     532           8 :         case GF_SG_VRML_MFVEC2F:
     533           8 :                 return NewMFVec2f();
     534           2 :         case GF_SG_VRML_MFVEC3D:
     535           2 :                 return NewMFVec3d();
     536           2 :         case GF_SG_VRML_MFVEC2D:
     537           2 :                 return NewMFVec2d();
     538           3 :         case GF_SG_VRML_MFCOLOR:
     539           3 :                 return NewMFColor();
     540           2 :         case GF_SG_VRML_MFCOLORRGBA:
     541           2 :                 return NewMFColorRGBA();
     542        1559 :         case GF_SG_VRML_MFROTATION:
     543             :         case GF_SG_VRML_MFVEC4F:
     544        1559 :                 return NewMFRotation();
     545           2 :         case GF_SG_VRML_MFATTRREF:
     546           2 :                 return NewMFAttrRef();
     547             : 
     548             :         //used in commands
     549           2 :         case GF_SG_VRML_SFCOMMANDBUFFER:
     550           2 :                 return NewSFCommandBuffer();
     551             : 
     552           2 :         case GF_SG_VRML_SFURL:
     553           2 :                 return NewSFURL();
     554          25 :         case GF_SG_VRML_MFURL:
     555          25 :                 return NewMFURL();
     556             : 
     557           2 :         case GF_SG_VRML_SFSCRIPT:
     558           2 :                 return NewSFScript();
     559           2 :         case GF_SG_VRML_MFSCRIPT:
     560           2 :                 return NewMFScript();
     561             :         }
     562             :         return NULL;
     563             : }
     564             : 
     565       12673 : void gf_sg_mfint32_del(MFInt32 par) {
     566       14259 :         gf_free(par.vals);
     567       12673 : }
     568       10052 : void gf_sg_mffloat_del(MFFloat par) {
     569       10060 :         gf_free(par.vals);
     570       10052 : }
     571          19 : void gf_sg_mfdouble_del(MFDouble par) {
     572          19 :         gf_free(par.vals);
     573          19 : }
     574           2 : void gf_sg_mfbool_del(MFBool par) {
     575           4 :         gf_free(par.vals);
     576           2 : }
     577        5221 : void gf_sg_mfcolor_del(MFColor par) {
     578        5224 :         gf_free(par.vals);
     579        5221 : }
     580           2 : void gf_sg_mfcolorrgba_del(MFColorRGBA par) {
     581           4 :         gf_free(par.vals);
     582           2 : }
     583        4229 : void gf_sg_mfrotation_del(MFRotation par) {
     584        5788 :         gf_free(par.vals);
     585        4229 : }
     586           1 : void gf_sg_mftime_del(MFTime par) {
     587           3 :         gf_free(par.vals);
     588           1 : }
     589        9222 : void gf_sg_mfvec2f_del(MFVec2f par) {
     590        9230 :         gf_free(par.vals);
     591        9222 : }
     592           0 : void gf_sg_mfvec2d_del(MFVec2d par) {
     593           2 :         gf_free(par.vals);
     594           0 : }
     595        4531 : void gf_sg_mfvec3f_del(MFVec3f par) {
     596        4535 :         gf_free(par.vals);
     597        4531 : }
     598           3 : void gf_sg_mfvec3d_del(MFVec3d par) {
     599           5 :         gf_free(par.vals);
     600           3 : }
     601           9 : void gf_sg_mfvec4f_del(MFVec4f par) {
     602           9 :         gf_free(par.vals);
     603           9 : }
     604           2 : void gf_sg_mfattrref_del(MFAttrRef par) {
     605           4 :         gf_free(par.vals);
     606           2 : }
     607          72 : void gf_sg_sfimage_del(SFImage im) {
     608          74 :         gf_free(im.pixels);
     609          72 : }
     610        6804 : void gf_sg_sfstring_del(SFString par) {
     611        6804 :         if (par.buffer) gf_free(par.buffer);
     612        6804 : }
     613           0 : void gf_sg_sfscript_del(SFScript par) {
     614           0 :         if (par.script_text) gf_free(par.script_text);
     615           0 : }
     616             : 
     617             : 
     618        1089 : void gf_sg_sfcommand_del(SFCommandBuffer cb)
     619             : {
     620             :         u32 i;
     621        3299 :         for (i=gf_list_count(cb.commandList); i>0; i--) {
     622        1121 :                 GF_Command *com = (GF_Command *)gf_list_get(cb.commandList, i-1);
     623        1121 :                 gf_sg_command_del(com);
     624             :         }
     625        1089 :         gf_list_del(cb.commandList);
     626        1089 :         if (cb.buffer) gf_free(cb.buffer);
     627        1089 : }
     628             : 
     629             : GF_EXPORT
     630       19794 : void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType)
     631             : {
     632             :         GF_Node *node;
     633             : 
     634       19794 :         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          32 :         case GF_SG_VRML_SFSTRING:
     650          32 :                 if ( ((SFString *)field)->buffer) gf_free(((SFString *)field)->buffer);
     651             :                 break;
     652           2 :         case GF_SG_VRML_SFIMAGE:
     653             :                 gf_sg_sfimage_del(* ((SFImage *)field));
     654             :                 break;
     655             : 
     656           0 :         case GF_SG_VRML_SFNODE:
     657           0 :                 node = *(GF_Node **) field;
     658           0 :                 if (node) gf_node_del(node);
     659             :                 return;
     660           2 :         case GF_SG_VRML_SFCOMMANDBUFFER:
     661           2 :                 gf_sg_sfcommand_del(*(SFCommandBuffer *)field);
     662           2 :                 break;
     663             : 
     664           2 :         case GF_SG_VRML_MFBOOL:
     665             :                 gf_sg_mfbool_del( * ((MFBool *) field));
     666             :                 break;
     667           8 :         case GF_SG_VRML_MFFLOAT:
     668             :                 gf_sg_mffloat_del( * ((MFFloat *) field));
     669             :                 break;
     670           0 :         case GF_SG_VRML_MFDOUBLE:
     671             :                 gf_sg_mfdouble_del( * ((MFDouble *) field));
     672             :                 break;
     673           2 :         case GF_SG_VRML_MFTIME:
     674             :                 gf_sg_mftime_del( * ((MFTime *)field));
     675             :                 break;
     676        1586 :         case GF_SG_VRML_MFINT32:
     677             :                 gf_sg_mfint32_del( * ((MFInt32 *)field));
     678             :                 break;
     679          81 :         case GF_SG_VRML_MFSTRING:
     680          81 :                 gf_sg_mfstring_del( *((MFString *)field));
     681          81 :                 break;
     682           4 :         case GF_SG_VRML_MFVEC3F:
     683             :                 gf_sg_mfvec3f_del( * ((MFVec3f *)field));
     684             :                 break;
     685           8 :         case GF_SG_VRML_MFVEC2F:
     686             :                 gf_sg_mfvec2f_del( * ((MFVec2f *)field));
     687             :                 break;
     688           2 :         case GF_SG_VRML_MFVEC3D:
     689             :                 gf_sg_mfvec3d_del( * ((MFVec3d *)field));
     690             :                 break;
     691           2 :         case GF_SG_VRML_MFVEC2D:
     692             :                 gf_sg_mfvec2d_del( * ((MFVec2d *)field));
     693             :                 break;
     694           3 :         case GF_SG_VRML_MFCOLOR:
     695             :                 gf_sg_mfcolor_del( * ((MFColor *)field));
     696             :                 break;
     697           2 :         case GF_SG_VRML_MFCOLORRGBA:
     698             :                 gf_sg_mfcolorrgba_del( * ((MFColorRGBA *)field));
     699             :                 break;
     700        1559 :         case GF_SG_VRML_MFROTATION:
     701             :         case GF_SG_VRML_MFVEC4F:
     702             :                 gf_sg_mfrotation_del( * ((MFRotation *)field));
     703             :                 break;
     704           2 :         case GF_SG_VRML_SFURL:
     705             :                 gf_sg_sfurl_del( * ((SFURL *) field));
     706             :                 break;
     707          25 :         case GF_SG_VRML_MFURL:
     708          25 :                 gf_sg_mfurl_del( * ((MFURL *) field));
     709          25 :                 break;
     710           2 :         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           2 :         case GF_SG_VRML_MFSCRIPT:
     718           2 :                 gf_sg_mfscript_del( * ((MFScript *) field));
     719           2 :                 break;
     720             :         case GF_SG_VRML_SFSCRIPT:
     721             :                 return;
     722             : 
     723             :         default:
     724             :                 assert(0);
     725             :                 return;
     726             :         }
     727             :         //free pointer
     728       19794 :         gf_free(field);
     729             : }
     730             : 
     731             : 
     732             : /*********************************************************************
     733             :                 MF Fields manipulation (alloc, gf_realloc, GetAt)
     734             : *********************************************************************/
     735             : GF_EXPORT
     736        3069 : const char *gf_sg_vrml_get_event_type_name(u32 EventType, Bool forX3D)
     737             : {
     738        3069 :         switch (EventType) {
     739         260 :         case GF_SG_EVENT_IN:
     740         260 :                 return forX3D ? "inputOnly" : "eventIn";
     741         457 :         case GF_SG_EVENT_FIELD:
     742         457 :                 return forX3D ? "initializeOnly" : "field";
     743        2086 :         case GF_SG_EVENT_EXPOSED_FIELD:
     744        2086 :                 return forX3D ? "inputOutput" : "exposedField";
     745         266 :         case GF_SG_EVENT_OUT:
     746         266 :                 return forX3D ? "outputOnly" : "eventOut";
     747             :         default:
     748             :                 return "unknownEvent";
     749             :         }
     750             : }
     751             : 
     752             : GF_EXPORT
     753        2959 : const char *gf_sg_vrml_get_field_type_name(u32 FieldType)
     754             : {
     755             : 
     756        2959 :         switch (FieldType) {
     757             :         case GF_SG_VRML_SFBOOL:
     758             :                 return "SFBool";
     759         371 :         case GF_SG_VRML_SFFLOAT:
     760         371 :                 return "SFFloat";
     761           2 :         case GF_SG_VRML_SFDOUBLE:
     762           2 :                 return "SFDouble";
     763         122 :         case GF_SG_VRML_SFTIME:
     764         122 :                 return "SFTime";
     765         625 :         case GF_SG_VRML_SFINT32:
     766         625 :                 return "SFInt32";
     767          86 :         case GF_SG_VRML_SFSTRING:
     768          86 :                 return "SFString";
     769         134 :         case GF_SG_VRML_SFVEC3F:
     770         134 :                 return "SFVec3f";
     771          75 :         case GF_SG_VRML_SFVEC2F:
     772          75 :                 return "SFVec2f";
     773           6 :         case GF_SG_VRML_SFVEC3D:
     774           6 :                 return "SFVec3d";
     775           0 :         case GF_SG_VRML_SFVEC2D:
     776           0 :                 return "SFVec2d";
     777          48 :         case GF_SG_VRML_SFCOLOR:
     778          48 :                 return "SFColor";
     779           0 :         case GF_SG_VRML_SFCOLORRGBA:
     780           0 :                 return "SFColorRGBA";
     781          42 :         case GF_SG_VRML_SFROTATION:
     782          42 :                 return "SFRotation";
     783           3 :         case GF_SG_VRML_SFIMAGE:
     784           3 :                 return "SFImage";
     785         344 :         case GF_SG_VRML_SFNODE:
     786         344 :                 return "SFNode";
     787           7 :         case GF_SG_VRML_SFVEC4F:
     788           7 :                 return "SFVec4f";
     789           0 :         case GF_SG_VRML_SFATTRREF:
     790           0 :                 return "SFAttrRef";
     791           1 :         case GF_SG_VRML_MFBOOL:
     792           1 :                 return "MFBool";
     793         115 :         case GF_SG_VRML_MFFLOAT:
     794         115 :                 return "MFFloat";
     795          19 :         case GF_SG_VRML_MFDOUBLE:
     796          19 :                 return "MFDouble";
     797           1 :         case GF_SG_VRML_MFTIME:
     798           1 :                 return "MFTime";
     799         149 :         case GF_SG_VRML_MFINT32:
     800         149 :                 return "MFInt32";
     801          44 :         case GF_SG_VRML_MFSTRING:
     802          44 :                 return "MFString";
     803          33 :         case GF_SG_VRML_MFVEC3F:
     804          33 :                 return "MFVec3f";
     805          34 :         case GF_SG_VRML_MFVEC2F:
     806          34 :                 return "MFVec2f";
     807           3 :         case GF_SG_VRML_MFVEC3D:
     808           3 :                 return "MFVec3d";
     809           0 :         case GF_SG_VRML_MFVEC2D:
     810           0 :                 return "MFVec2d";
     811          17 :         case GF_SG_VRML_MFCOLOR:
     812          17 :                 return "MFColor";
     813           1 :         case GF_SG_VRML_MFCOLORRGBA:
     814           1 :                 return "MFColorRGBA";
     815          10 :         case GF_SG_VRML_MFROTATION:
     816          10 :                 return "MFRotation";
     817           0 :         case GF_SG_VRML_MFIMAGE:
     818           0 :                 return "MFImage";
     819         188 :         case GF_SG_VRML_MFNODE:
     820         188 :                 return "MFNode";
     821           6 :         case GF_SG_VRML_MFVEC4F:
     822           6 :                 return "MFVec4f";
     823           3 :         case GF_SG_VRML_SFURL:
     824           3 :                 return "SFURL";
     825          47 :         case GF_SG_VRML_MFURL:
     826          47 :                 return "MFURL";
     827           1 :         case GF_SG_VRML_MFATTRREF:
     828           1 :                 return "MFAttrRef";
     829           2 :         case GF_SG_VRML_SFCOMMANDBUFFER:
     830           2 :                 return "SFCommandBuffer";
     831           0 :         case GF_SG_VRML_SFSCRIPT:
     832           0 :                 return "SFScript";
     833           2 :         case GF_SG_VRML_MFSCRIPT:
     834           2 :                 return "MFScript";
     835           0 :         default:
     836           0 :                 return "UnknownType";
     837             :         }
     838             : }
     839             : 
     840         836 : u32 gf_sg_field_type_by_name(char *fieldType)
     841             : {
     842         836 :         if (!stricmp(fieldType, "SFBool")) return GF_SG_VRML_SFBOOL;
     843         682 :         else if (!stricmp(fieldType, "SFFloat")) return GF_SG_VRML_SFFLOAT;
     844         519 :         else if (!stricmp(fieldType, "SFDouble")) return GF_SG_VRML_SFDOUBLE;
     845         519 :         else if (!stricmp(fieldType, "SFTime")) return GF_SG_VRML_SFTIME;
     846         470 :         else if (!stricmp(fieldType, "SFInt32")) return GF_SG_VRML_SFINT32;
     847         429 :         else if (!stricmp(fieldType, "SFString")) return GF_SG_VRML_SFSTRING;
     848         427 :         else if (!stricmp(fieldType, "SFVec2f")) return GF_SG_VRML_SFVEC2F;
     849         318 :         else if (!stricmp(fieldType, "SFVec3f")) return GF_SG_VRML_SFVEC3F;
     850         308 :         else if (!stricmp(fieldType, "SFVec2d")) return GF_SG_VRML_SFVEC2D;
     851         308 :         else if (!stricmp(fieldType, "SFVec3d")) return GF_SG_VRML_SFVEC3D;
     852         308 :         else if (!stricmp(fieldType, "SFColor")) return GF_SG_VRML_SFCOLOR;
     853         219 :         else if (!stricmp(fieldType, "SFColorRGBA")) return GF_SG_VRML_SFCOLORRGBA;
     854         219 :         else if (!stricmp(fieldType, "SFRotation")) return GF_SG_VRML_SFROTATION;
     855         219 :         else if (!stricmp(fieldType, "SFImage")) return GF_SG_VRML_SFIMAGE;
     856         219 :         else if (!stricmp(fieldType, "SFAttrRef")) return GF_SG_VRML_SFATTRREF;
     857         219 :         else if (!stricmp(fieldType, "SFNode")) return GF_SG_VRML_SFNODE;
     858             : 
     859          38 :         else if (!stricmp(fieldType, "MFBool")) return GF_SG_VRML_MFBOOL;
     860          38 :         else if (!stricmp(fieldType, "MFFloat")) return GF_SG_VRML_MFFLOAT;
     861          36 :         else if (!stricmp(fieldType, "MFDouble")) return GF_SG_VRML_MFDOUBLE;
     862          36 :         else if (!stricmp(fieldType, "MFTime")) return GF_SG_VRML_MFTIME;
     863          36 :         else if (!stricmp(fieldType, "MFInt32")) return GF_SG_VRML_MFINT32;
     864          34 :         else if (!stricmp(fieldType, "MFString")) return GF_SG_VRML_MFSTRING;
     865          24 :         else if (!stricmp(fieldType, "MFVec2f")) return GF_SG_VRML_MFVEC2F;
     866          22 :         else if (!stricmp(fieldType, "MFVec3f")) return GF_SG_VRML_MFVEC3F;
     867          21 :         else if (!stricmp(fieldType, "MFVec2d")) return GF_SG_VRML_MFVEC2D;
     868          21 :         else if (!stricmp(fieldType, "MFVec3d")) return GF_SG_VRML_MFVEC3D;
     869          21 :         else if (!stricmp(fieldType, "MFColor")) return GF_SG_VRML_MFCOLOR;
     870          20 :         else if (!stricmp(fieldType, "MFColorRGBA")) return GF_SG_VRML_MFCOLORRGBA;
     871          20 :         else if (!stricmp(fieldType, "MFRotation")) return GF_SG_VRML_MFROTATION;
     872          18 :         else if (!stricmp(fieldType, "MFImage")) return GF_SG_VRML_MFIMAGE;
     873          18 :         else if (!stricmp(fieldType, "MFAttrRef")) return GF_SG_VRML_MFATTRREF;
     874          18 :         else if (!stricmp(fieldType, "MFNode")) return GF_SG_VRML_MFNODE;
     875             : 
     876           0 :         return GF_SG_VRML_UNKNOWN;
     877             : }
     878             : 
     879             : #endif
     880             : 
     881           3 : void gf_sg_sfurl_del(SFURL url) {
     882        1066 :         if (url.url) gf_free(url.url);
     883           3 : }
     884             : 
     885             : GF_EXPORT
     886      498292 : Bool gf_sg_vrml_is_sf_field(u32 FieldType)
     887             : {
     888      498292 :         return (FieldType<GF_SG_VRML_FIRST_MF);
     889             : }
     890             : 
     891        8499 : void gf_sg_mfstring_del(MFString par)
     892             : {
     893             :         u32 i;
     894       16709 :         for (i=0; i<par.count; i++) {
     895        8210 :                 if (par.vals[i]) gf_free(par.vals[i]);
     896             :         }
     897        8499 :         gf_free(par.vals);
     898        8499 : }
     899             : 
     900             : 
     901             : GF_EXPORT
     902        4528 : void gf_sg_mfurl_del(MFURL url)
     903             : {
     904             :         u32 i;
     905        5589 :         for (i=0; i<url.count; i++) {
     906        1061 :                 gf_sg_sfurl_del(url.vals[i]);
     907             :         }
     908        4528 :         gf_free(url.vals);
     909        4528 : }
     910         460 : void gf_sg_mfscript_del(MFScript sc)
     911             : {
     912             :         u32 i;
     913         890 :         for (i=0; i<sc.count; i++) {
     914         430 :                 if (sc.vals[i].script_text) gf_free(sc.vals[i].script_text);
     915             :         }
     916         460 :         gf_free(sc.vals);
     917         460 : }
     918             : 
     919             : 
     920         130 : void gf_sg_vrml_copy_mfurl(MFURL *dst, MFURL *src)
     921             : {
     922             :         u32 i;
     923         130 :         gf_sg_vrml_mf_reset(dst, GF_SG_VRML_MFURL);
     924         130 :         dst->count = src->count;
     925         130 :         dst->vals = gf_malloc(sizeof(SFURL)*src->count);
     926         260 :         for (i=0; i<src->count; i++) {
     927         130 :                 dst->vals[i].OD_ID = src->vals[i].OD_ID;
     928         130 :                 dst->vals[i].url = src->vals[i].url ? gf_strdup(src->vals[i].url) : NULL;
     929             :         }
     930         130 : }
     931             : 
     932             : 
     933             : 
     934             : //return the size of fixed fields (eg no buffer in the field)
     935           0 : 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
     993       83883 : 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
    1064      192804 : 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      192804 :         if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM;
    1071      192804 :         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      192804 :         if (!FieldSize) return GF_BAD_PARAM;
    1077             : 
    1078             :         //first item ever
    1079      192804 :         if (!mffield->count || !mffield->array) {
    1080        8840 :                 if (mffield->array) gf_free(mffield->array);
    1081        8840 :                 mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize);
    1082             :                 memset(mffield->array, 0, sizeof(char)*FieldSize);
    1083        8840 :                 mffield->count = 1;
    1084        8840 :                 if (new_ptr) *new_ptr = mffield->array;
    1085             :                 return GF_OK;
    1086             :         }
    1087             : 
    1088             :         //append at the end
    1089      183964 :         if (InsertAt >= mffield->count) {
    1090      183952 :                 mffield->array = (char*)gf_realloc(mffield->array, sizeof(char)*(1+mffield->count)*FieldSize);
    1091      183952 :                 memset(mffield->array + mffield->count * FieldSize, 0, FieldSize);
    1092      183952 :                 if (new_ptr) *new_ptr = mffield->array + mffield->count * FieldSize;
    1093      183952 :                 mffield->count += 1;
    1094      183952 :                 return GF_OK;
    1095             :         }
    1096             :         //alloc 1+itemCount
    1097          12 :         buffer = (char*)gf_malloc(sizeof(char)*(1+mffield->count)*FieldSize);
    1098             : 
    1099             :         //insert in the array
    1100             :         k=0;
    1101          72 :         for (i=0; i < mffield->count; i++) {
    1102          60 :                 if (InsertAt == i) {
    1103          12 :                         if (new_ptr) {
    1104          12 :                                 *new_ptr = buffer + i*FieldSize;
    1105             :                                 memset(*new_ptr, 0, sizeof(char)*FieldSize);
    1106             :                         }
    1107             :                         k = 1;
    1108             :                 }
    1109          60 :                 memcpy(buffer + (k+i) * FieldSize , mffield->array + i*FieldSize, FieldSize);
    1110             :         }
    1111          12 :         gf_free(mffield->array);
    1112          12 :         mffield->array = buffer;
    1113          12 :         mffield->count += 1;
    1114          12 :         return GF_OK;
    1115             : }
    1116             : 
    1117             : 
    1118             : GF_EXPORT
    1119       16860 : GF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType)
    1120             : {
    1121             :         GenMFField *mffield = (GenMFField *)mf;
    1122       16860 :         if (!mffield->array) return GF_OK;
    1123             : 
    1124             :         //field we can't copy
    1125        1616 :         if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM;
    1126        1616 :         if (!gf_sg_vrml_get_sf_size(FieldType)) return GF_BAD_PARAM;
    1127             : 
    1128        1616 :         switch (FieldType) {
    1129        1056 :         case GF_SG_VRML_MFSTRING:
    1130        1056 :                 gf_sg_mfstring_del( * ((MFString *) mf));
    1131        1056 :                 break;
    1132         188 :         case GF_SG_VRML_MFURL:
    1133         188 :                 gf_sg_mfurl_del( * ((MFURL *) mf));
    1134         188 :                 break;
    1135           0 :         case GF_SG_VRML_MFSCRIPT:
    1136           0 :                 gf_sg_mfscript_del( * ((MFScript *) mf));
    1137           0 :                 break;
    1138         372 :         default:
    1139         372 :                 if (mffield->array) gf_free(mffield->array);
    1140             :                 break;
    1141             :         }
    1142             : 
    1143        1616 :         mffield->array = NULL;
    1144        1616 :         mffield->count = 0;
    1145        1616 :         return GF_OK;
    1146             : }
    1147             : 
    1148             : #ifndef GPAC_DISABLE_VRML
    1149             : 
    1150             : #define MAX_MFFIELD_ALLOC               5000000
    1151             : GF_EXPORT
    1152       29585 : GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems)
    1153             : {
    1154             :         u32 FieldSize;
    1155             :         GenMFField *mffield = (GenMFField *)mf;
    1156             : 
    1157       29585 :         if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM;
    1158       29585 :         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       29585 :         if (!FieldSize) return GF_BAD_PARAM;
    1164       29585 :         if (NbItems>MAX_MFFIELD_ALLOC) return GF_IO_ERR;
    1165             : 
    1166       29585 :         if (mffield->count==NbItems) return GF_OK;
    1167        6001 :         gf_sg_vrml_mf_reset(mf, FieldType);
    1168        6001 :         if (NbItems) {
    1169        6001 :                 mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize*NbItems);
    1170             :                 memset(mffield->array, 0, sizeof(char)*FieldSize*NbItems);
    1171             :         }
    1172        6001 :         mffield->count = NbItems;
    1173        6001 :         return GF_OK;
    1174             : }
    1175             : 
    1176             : GF_EXPORT
    1177      162699 : 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      162699 :         *new_ptr = NULL;
    1183      162699 :         if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM;
    1184      162699 :         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      162699 :         if (!FieldSize) return GF_BAD_PARAM;
    1190      162699 :         if (ItemPos >= mffield->count) return GF_BAD_PARAM;
    1191      162699 :         *new_ptr = mffield->array + ItemPos * FieldSize;
    1192      162699 :         return GF_OK;
    1193             : }
    1194             : 
    1195             : 
    1196             : GF_EXPORT
    1197      191450 : GF_Err gf_sg_vrml_mf_append(void *mf, u32 FieldType, void **new_ptr)
    1198             : {
    1199             :         GenMFField *mffield = (GenMFField *)mf;
    1200      191450 :         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
    1206          24 : 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          24 :         if (!FieldSize) return GF_BAD_PARAM;
    1216             : 
    1217          24 :         if (!mffield->count || RemoveFrom >= mffield->count) return GF_BAD_PARAM;
    1218             : 
    1219          12 :         if (mffield->count == 1) {
    1220           0 :                 gf_free(mffield->array);
    1221           0 :                 mffield->array = NULL;
    1222           0 :                 mffield->count = 0;
    1223           0 :                 return GF_OK;
    1224             :         }
    1225             :         k=0;
    1226          12 :         buffer = (char*)gf_malloc(sizeof(char)*(mffield->count-1)*FieldSize);
    1227          84 :         for (i=0; i<mffield->count; i++) {
    1228          72 :                 if (RemoveFrom == i) {
    1229             :                         k = 1;
    1230             :                 } else {
    1231          60 :                         memcpy(buffer + (i-k)*FieldSize, mffield->array + i*FieldSize, FieldSize);
    1232             :                 }
    1233             :         }
    1234          12 :         gf_free(mffield->array);
    1235          12 :         mffield->array = buffer;
    1236          12 :         mffield->count -= 1;
    1237          12 :         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) */
    1242         302 : 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         302 :         if (!dest || !orig) return;
    1248             : 
    1249          60 :         switch (dst_field_type) {
    1250          10 :         case GF_SG_VRML_SFSTRING:
    1251          10 :                 if (ori_field_type == GF_SG_VRML_SFURL) {
    1252             :                         url = ((SFURL *)orig);
    1253          10 :                         if (url->OD_ID>0) {
    1254             :                                 char tmp[50];
    1255             :                                 sprintf(tmp, "%d", url->OD_ID);
    1256           0 :                                 if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
    1257           0 :                                 ((SFString*)dest)->buffer = gf_strdup(tmp);
    1258             :                         } else {
    1259          10 :                                 if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
    1260          10 :                                 ((SFString*)dest)->buffer = url->url ? gf_strdup(url->url) : NULL;
    1261             :                         }
    1262             :                 }
    1263             :                 /*for SFString to MFString cast*/
    1264           0 :                 else if (ori_field_type == GF_SG_VRML_SFSTRING) {
    1265           0 :                         if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
    1266           0 :                         ((SFString*)dest)->buffer = ((SFString*)orig)->buffer ? gf_strdup(((SFString*)orig)->buffer) : NULL;
    1267             :                 }
    1268             :                 return;
    1269          20 :         case GF_SG_VRML_SFURL:
    1270          20 :                 if (ori_field_type != GF_SG_VRML_SFSTRING) return;
    1271             :                 url = ((SFURL *)dest);
    1272          20 :                 url->OD_ID = 0;
    1273          20 :                 if (url->url) gf_free(url->url);
    1274          20 :                 if ( ((SFString*)orig)->buffer)
    1275          20 :                         url->url = gf_strdup(((SFString*)orig)->buffer);
    1276             :                 else
    1277           0 :                         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          30 :         sf_type_dst = gf_sg_vrml_get_sf_type(dst_field_type);
    1287             : 
    1288          30 :         if (gf_sg_vrml_is_sf_field(ori_field_type)) {
    1289             :                 size = 1;
    1290           0 :                 gf_sg_vrml_mf_alloc(dest, dst_field_type, size);
    1291           0 :                 gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, 0);
    1292           0 :                 VRML_FieldCopyCast(dst_field, sf_type_dst, orig, ori_field_type);
    1293           0 :                 return;
    1294             :         }
    1295             : 
    1296          30 :         size = ((GenMFField *)orig)->count;
    1297          30 :         if (size != ((GenMFField *)dest)->count) gf_sg_vrml_mf_alloc(dest, dst_field_type, size);
    1298             : 
    1299          30 :         sf_type_ori = gf_sg_vrml_get_sf_type(ori_field_type);
    1300             :         //duplicate all items
    1301          60 :         for (i=0; i<size; i++) {
    1302          30 :                 gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, i);
    1303          30 :                 gf_sg_vrml_mf_get_item(orig, ori_field_type, &orig_field, i);
    1304          30 :                 VRML_FieldCopyCast(dst_field, sf_type_dst, orig_field, sf_type_ori);
    1305             :         }
    1306             :         return;
    1307             : }
    1308             : 
    1309             : GF_EXPORT
    1310      170783 : 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      170932 :         if (!dest || !orig) return;
    1316             : 
    1317      170634 :         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        2915 :         case GF_SG_VRML_SFSTRING:
    1346        2915 :                 if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer);
    1347        2915 :                 if ( ((SFString*)orig)->buffer )
    1348         495 :                         ((SFString*)dest)->buffer = gf_strdup(((SFString*)orig)->buffer);
    1349             :                 else
    1350        2420 :                         ((SFString*)dest)->buffer = NULL;
    1351             :                 break;
    1352          53 :         case GF_SG_VRML_SFURL:
    1353          53 :                 if ( ((SFURL *)dest)->url ) gf_free( ((SFURL *)dest)->url );
    1354          53 :                 ((SFURL *)dest)->OD_ID = ((SFURL *)orig)->OD_ID;
    1355          53 :                 if (((SFURL *)orig)->url)
    1356          19 :                         ((SFURL *)dest)->url = gf_strdup(((SFURL *)orig)->url);
    1357             :                 else
    1358          34 :                         ((SFURL *)dest)->url = NULL;
    1359             :                 break;
    1360           0 :         case GF_SG_VRML_SFIMAGE:
    1361           0 :                 if (((SFImage *)dest)->pixels) gf_free(((SFImage *)dest)->pixels);
    1362           0 :                 ((SFImage *)dest)->width = ((SFImage *)orig)->width;
    1363           0 :                 ((SFImage *)dest)->height = ((SFImage *)orig)->height;
    1364           0 :                 ((SFImage *)dest)->numComponents  = ((SFImage *)orig)->numComponents;
    1365           0 :                 size = ((SFImage *)dest)->width * ((SFImage *)dest)->height * ((SFImage *)dest)->numComponents;
    1366           0 :                 ((SFImage *)dest)->pixels = (u8*)gf_malloc(sizeof(char)*size);
    1367           0 :                 memcpy(((SFImage *)dest)->pixels, ((SFImage *)orig)->pixels, sizeof(char)*size);
    1368             :                 break;
    1369          39 :         case GF_SG_VRML_SFCOMMANDBUFFER:
    1370             :         {
    1371             :                 SFCommandBuffer *cb_dst = (SFCommandBuffer *)dest;
    1372             :                 SFCommandBuffer *cb_src = (SFCommandBuffer *)orig;
    1373             : 
    1374          39 :                 cb_dst->bufferSize = cb_src->bufferSize;
    1375          39 :                 if (cb_dst->bufferSize && !gf_list_count(cb_src->commandList) ) {
    1376          12 :                         cb_dst->buffer = (u8*)gf_realloc(cb_dst->buffer, sizeof(char)*cb_dst->bufferSize);
    1377          12 :                         memcpy(cb_dst->buffer, cb_src->buffer, sizeof(char)*cb_src->bufferSize);
    1378             :                 } else {
    1379             :                         u32 j, c2;
    1380          27 :                         if (cb_dst->buffer) gf_free(cb_dst->buffer);
    1381          27 :                         cb_dst->buffer = NULL;
    1382             :                         /*clone command list*/
    1383          27 :                         c2 = gf_list_count(cb_src->commandList);
    1384          56 :                         for (j=0; j<c2; j++) {
    1385          29 :                                 GF_Command *sub_com = (GF_Command *)gf_list_get(cb_src->commandList, j);
    1386          29 :                                 GF_Command *new_com = gf_sg_vrml_command_clone(sub_com, inScene, 0);
    1387          29 :                                 gf_list_add(cb_dst->commandList, new_com);
    1388             :                         }
    1389             :                 }
    1390             :         }
    1391             :         break;
    1392             : 
    1393             :         /*simply copy text string*/
    1394         365 :         case GF_SG_VRML_SFSCRIPT:
    1395         365 :                 if (((SFScript*)dest)->script_text) gf_free(((SFScript*)dest)->script_text);
    1396         365 :                 ((SFScript*)dest)->script_text = NULL;
    1397         365 :                 if ( ((SFScript*)orig)->script_text)
    1398         365 :                         ((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       19153 :                 size = gf_sg_vrml_get_sf_size(field_type) * ((GenMFField *)orig)->count;
    1413       19153 :                 if (((GenMFField *)orig)->count != ((GenMFField *)dest)->count) {
    1414        2042 :                         ((GenMFField *)dest)->array = gf_realloc(((GenMFField *)dest)->array, size);
    1415        2042 :                         ((GenMFField *)dest)->count = ((GenMFField *)orig)->count;
    1416             :                 }
    1417       19153 :                 if (size)
    1418        2876 :                         memcpy(((GenMFField *)dest)->array, ((GenMFField *)orig)->array, size);
    1419             :                 break;
    1420             :         //complex MFFields
    1421        3421 :         case GF_SG_VRML_MFSTRING:
    1422             :         case GF_SG_VRML_MFIMAGE:
    1423             :         case GF_SG_VRML_MFURL:
    1424             :         case GF_SG_VRML_MFSCRIPT:
    1425        3421 :                 size = ((GenMFField *)orig)->count;
    1426        3421 :                 gf_sg_vrml_mf_reset(dest, field_type);
    1427        3421 :                 gf_sg_vrml_mf_alloc(dest, field_type, size);
    1428        3421 :                 sf_type = gf_sg_vrml_get_sf_type(field_type);
    1429             :                 //duplicate all items
    1430        4237 :                 for (i=0; i<size; i++) {
    1431         816 :                         gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i);
    1432         816 :                         gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i);
    1433         816 :                         gf_sg_vrml_field_copy(dst_field, orig_field, sf_type);
    1434             :                 }
    1435             :                 break;
    1436             :         }
    1437             : }
    1438             : 
    1439             : GF_EXPORT
    1440       84620 : void gf_sg_vrml_field_copy(void *dest, void *orig, u32 field_type)
    1441             : {
    1442       84620 :         gf_sg_vrml_field_clone(dest, orig, field_type, NULL);
    1443       84620 : }
    1444             : 
    1445             : GF_EXPORT
    1446      132542 : Bool gf_sg_vrml_field_equal(void *dest, void *orig, u32 field_type)
    1447             : {
    1448             :         u32 size, i, sf_type;
    1449             :         void *dst_field, *orig_field;
    1450             :         Bool changed = 0;
    1451             : 
    1452      132542 :         if (!dest || !orig) return 0;
    1453             : 
    1454      132542 :         switch (field_type) {
    1455       12484 :         case GF_SG_VRML_SFBOOL:
    1456       12484 :                 changed = memcmp(dest, orig, sizeof(SFBool));
    1457       12484 :                 break;
    1458        3269 :         case GF_SG_VRML_SFCOLOR:
    1459        3269 :                 if (((SFColor *)dest)->red != ((SFColor *)orig)->red) changed = 1;
    1460        1053 :                 else if (((SFColor *)dest)->green != ((SFColor *)orig)->green) changed = 1;
    1461         952 :                 else if (((SFColor *)dest)->blue != ((SFColor *)orig)->blue) changed = 1;
    1462             :                 break;
    1463       77622 :         case GF_SG_VRML_SFFLOAT:
    1464       77622 :                 if ( (*(SFFloat *)dest) != (*(SFFloat *)orig) ) changed = 1;
    1465             :                 break;
    1466        5240 :         case GF_SG_VRML_SFINT32:
    1467        5240 :                 changed = memcmp(dest, orig, sizeof(SFInt32));
    1468        5240 :                 break;
    1469        2835 :         case GF_SG_VRML_SFROTATION:
    1470        2835 :                 if (((SFRotation *)dest)->x != ((SFRotation *)orig)->x) changed = 1;
    1471        2691 :                 else if (((SFRotation *)dest)->y != ((SFRotation *)orig)->y) changed = 1;
    1472        2688 :                 else if (((SFRotation *)dest)->z != ((SFRotation *)orig)->z) changed = 1;
    1473        2688 :                 else if (((SFRotation *)dest)->q != ((SFRotation *)orig)->q) changed = 1;
    1474             :                 break;
    1475        1951 :         case GF_SG_VRML_SFTIME:
    1476        1951 :                 if ( (*(SFTime *)dest) != (*(SFTime*)orig) ) changed = 1;
    1477             :                 break;
    1478       15548 :         case GF_SG_VRML_SFVEC2F:
    1479       15548 :                 if (((SFVec2f *)dest)->x != ((SFVec2f *)orig)->x) changed = 1;
    1480        7212 :                 else if (((SFVec2f *)dest)->y != ((SFVec2f *)orig)->y) changed = 1;
    1481             :                 break;
    1482        2808 :         case GF_SG_VRML_SFVEC3F:
    1483        2808 :                 if (((SFVec3f *)dest)->x != ((SFVec3f *)orig)->x) changed = 1;
    1484        1140 :                 else if (((SFVec3f *)dest)->y != ((SFVec3f *)orig)->y) changed = 1;
    1485         640 :                 else if (((SFVec3f *)dest)->z != ((SFVec3f *)orig)->z) changed = 1;
    1486             :                 break;
    1487        1634 :         case GF_SG_VRML_SFSTRING:
    1488        1634 :                 if ( ((SFString*)dest)->buffer && ((SFString*)orig)->buffer) {
    1489        1200 :                         changed = strcmp(((SFString*)dest)->buffer, ((SFString*)orig)->buffer);
    1490             :                 } else {
    1491         434 :                         changed = ( !((SFString*)dest)->buffer && !((SFString*)orig)->buffer) ? 0 : 1;
    1492             :                 }
    1493             :                 break;
    1494           0 :         case GF_SG_VRML_SFURL:
    1495           0 :                 if (((SFURL *)dest)->OD_ID > 0 || ((SFURL *)orig)->OD_ID > 0) {
    1496           0 :                         if ( ((SFURL *)orig)->OD_ID != ((SFURL *)dest)->OD_ID) changed = 1;
    1497             :                 } else {
    1498           0 :                         if ( ((SFURL *)orig)->url && ! ((SFURL *)dest)->url) changed = 1;
    1499           0 :                         else if ( ! ((SFURL *)orig)->url && ((SFURL *)dest)->url) changed = 1;
    1500           0 :                         else if ( ((SFURL *)orig)->url && ((SFURL *)dest)->url && strcmp( ((SFURL *)orig)->url , ((SFURL *)dest)->url) ) changed = 1;
    1501             :                 }
    1502             :                 break;
    1503          71 :         case GF_SG_VRML_SFIMAGE:
    1504             :         case GF_SG_VRML_SFATTRREF:
    1505             :         case GF_SG_VRML_SFSCRIPT:
    1506             :         case GF_SG_VRML_SFCOMMANDBUFFER:
    1507             :                 changed = 1;
    1508          71 :                 break;
    1509             : 
    1510             :         //MFFields
    1511           0 :         case GF_SG_VRML_MFATTRREF:
    1512             :                 changed = 1;
    1513           0 :                 break;
    1514        9080 :         case GF_SG_VRML_MFBOOL:
    1515             :         case GF_SG_VRML_MFFLOAT:
    1516             :         case GF_SG_VRML_MFTIME:
    1517             :         case GF_SG_VRML_MFINT32:
    1518             :         case GF_SG_VRML_MFSTRING:
    1519             :         case GF_SG_VRML_MFVEC3F:
    1520             :         case GF_SG_VRML_MFVEC2F:
    1521             :         case GF_SG_VRML_MFCOLOR:
    1522             :         case GF_SG_VRML_MFROTATION:
    1523             :         case GF_SG_VRML_MFIMAGE:
    1524             :         case GF_SG_VRML_MFURL:
    1525             :         case GF_SG_VRML_MFSCRIPT:
    1526        9080 :                 if ( ((GenMFField *)orig)->count != ((GenMFField *)dest)->count) changed = 1;
    1527             :                 else {
    1528             :                         size = ((GenMFField *)orig)->count;
    1529        3871 :                         sf_type = gf_sg_vrml_get_sf_type(field_type);
    1530        5151 :                         for (i=0; i<size; i++) {
    1531        2041 :                                 gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i);
    1532        2041 :                                 gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i);
    1533        2041 :                                 if (! gf_sg_vrml_field_equal(dst_field, orig_field, sf_type) ) {
    1534             :                                         changed = 1;
    1535             :                                         break;
    1536             :                                 }
    1537             :                         }
    1538             :                 }
    1539             :                 break;
    1540             :         }
    1541      132542 :         return changed ? 0 : 1;
    1542             : }
    1543             : 
    1544             : 
    1545             : 
    1546             : GF_EXPORT
    1547          54 : SFColorRGBA gf_sg_sfcolor_to_rgba(SFColor val)
    1548             : {
    1549             :         SFColorRGBA res;
    1550             :         res.alpha = FIX_ONE;
    1551          54 :         res.red = val.red;
    1552          54 :         res.green = val.green;
    1553          54 :         res.blue = val.blue;
    1554          54 :         return res;
    1555             : }
    1556             : 
    1557             : 
    1558             : GF_EXPORT
    1559       82371 : u32 gf_node_get_num_fields_in_mode(GF_Node *Node, u8 IndexMode)
    1560             : {
    1561             :         assert(Node);
    1562       82371 :         if (Node->sgprivate->tag == TAG_ProtoNode) return gf_sg_proto_get_num_fields(Node, IndexMode);
    1563       80107 :         else if (Node->sgprivate->tag == TAG_MPEG4_Script)
    1564        1509 :                 return gf_sg_script_get_num_fields(Node, IndexMode);
    1565             : #ifndef GPAC_DISABLE_X3D
    1566       78598 :         else if (Node->sgprivate->tag == TAG_X3D_Script)
    1567          29 :                 return gf_sg_script_get_num_fields(Node, IndexMode);
    1568             : #endif
    1569       78569 :         else if (Node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) return gf_sg_mpeg4_node_get_field_count(Node, IndexMode);
    1570             : #ifndef GPAC_DISABLE_X3D
    1571         129 :         else if (Node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_sg_x3d_node_get_field_count(Node);
    1572             : #endif
    1573             :         else return 0;
    1574             : }
    1575             : 
    1576             : 
    1577             : 
    1578             : /*all our internally handled nodes*/
    1579             : Bool InitColorInterpolator(M_ColorInterpolator *node);
    1580             : Bool InitCoordinateInterpolator2D(M_CoordinateInterpolator2D *node);
    1581             : Bool InitCoordinateInterpolator(M_CoordinateInterpolator *n);
    1582             : Bool InitNormalInterpolator(M_NormalInterpolator *n);
    1583             : Bool InitPositionInterpolator2D(M_PositionInterpolator2D *node);
    1584             : Bool InitPositionInterpolator(M_PositionInterpolator *node);
    1585             : Bool InitScalarInterpolator(M_ScalarInterpolator *node);
    1586             : Bool InitOrientationInterpolator(M_OrientationInterpolator *node);
    1587             : Bool InitValuator(M_Valuator *node);
    1588             : Bool InitCoordinateInterpolator4D(M_CoordinateInterpolator4D *node);
    1589             : Bool InitPositionInterpolator4D(M_PositionInterpolator4D *node);
    1590             : 
    1591             : void PA_Init(GF_Node *n);
    1592             : void PA_Modified(GF_Node *n, GF_FieldInfo *field);
    1593             : void PA2D_Init(GF_Node *n);
    1594             : void PA2D_Modified(GF_Node *n, GF_FieldInfo *field);
    1595             : void SA_Init(GF_Node *n);
    1596             : void SA_Modified(GF_Node *n, GF_FieldInfo *field);
    1597             : /*X3D tools*/
    1598             : void InitBooleanFilter(GF_Node *n);
    1599             : void InitBooleanSequencer(GF_Node *n);
    1600             : void InitBooleanToggle(GF_Node *n);
    1601             : void InitBooleanTrigger(GF_Node *n);
    1602             : void InitIntegerSequencer(GF_Node *n);
    1603             : void InitIntegerTrigger(GF_Node *n);
    1604             : void InitTimeTrigger(GF_Node *n);
    1605             : 
    1606       35411 : Bool gf_sg_vrml_node_init(GF_Node *node)
    1607             : {
    1608       35411 :         switch (node->sgprivate->tag) {
    1609           6 :         case TAG_MPEG4_ColorInterpolator:
    1610             : #ifndef GPAC_DISABLE_X3D
    1611             :         case TAG_X3D_ColorInterpolator:
    1612             : #endif
    1613           6 :                 return InitColorInterpolator((M_ColorInterpolator *)node);
    1614           1 :         case TAG_MPEG4_CoordinateInterpolator:
    1615             : #ifndef GPAC_DISABLE_X3D
    1616             :         case TAG_X3D_CoordinateInterpolator:
    1617             : #endif
    1618           1 :                 return InitCoordinateInterpolator((M_CoordinateInterpolator *)node);
    1619           2 :         case TAG_MPEG4_CoordinateInterpolator2D:
    1620           2 :                 return InitCoordinateInterpolator2D((M_CoordinateInterpolator2D *)node);
    1621           1 :         case TAG_MPEG4_NormalInterpolator:
    1622             : #ifndef GPAC_DISABLE_X3D
    1623             :         case TAG_X3D_NormalInterpolator:
    1624             : #endif
    1625           1 :                 return InitNormalInterpolator((M_NormalInterpolator*)node);
    1626          18 :         case TAG_MPEG4_OrientationInterpolator:
    1627             : #ifndef GPAC_DISABLE_X3D
    1628             :         case TAG_X3D_OrientationInterpolator:
    1629             : #endif
    1630          18 :                 return InitOrientationInterpolator((M_OrientationInterpolator*)node);
    1631          11 :         case TAG_MPEG4_PositionInterpolator:
    1632             : #ifndef GPAC_DISABLE_X3D
    1633             :         case TAG_X3D_PositionInterpolator:
    1634             : #endif
    1635          11 :                 return InitPositionInterpolator((M_PositionInterpolator *)node);
    1636         408 :         case TAG_MPEG4_PositionInterpolator2D:
    1637             : #ifndef GPAC_DISABLE_X3D
    1638             :         case TAG_X3D_PositionInterpolator2D:
    1639             : #endif
    1640         408 :                 return InitPositionInterpolator2D((M_PositionInterpolator2D *)node);
    1641          68 :         case TAG_MPEG4_ScalarInterpolator:
    1642             : #ifndef GPAC_DISABLE_X3D
    1643             :         case TAG_X3D_ScalarInterpolator:
    1644             : #endif
    1645          68 :                 return InitScalarInterpolator((M_ScalarInterpolator *)node);
    1646        1551 :         case TAG_MPEG4_Valuator:
    1647        1551 :                 return InitValuator((M_Valuator *)node);
    1648           1 :         case TAG_MPEG4_PositionAnimator:
    1649           1 :                 PA_Init(node);
    1650           1 :                 return 1;
    1651           2 :         case TAG_MPEG4_PositionAnimator2D:
    1652           2 :                 PA2D_Init(node);
    1653           2 :                 return 1;
    1654           1 :         case TAG_MPEG4_ScalarAnimator:
    1655           1 :                 SA_Init(node);
    1656           1 :                 return 1;
    1657           1 :         case TAG_MPEG4_PositionInterpolator4D:
    1658           1 :                 return InitPositionInterpolator4D((M_PositionInterpolator4D *)node);
    1659           1 :         case TAG_MPEG4_CoordinateInterpolator4D:
    1660           1 :                 return InitCoordinateInterpolator4D((M_CoordinateInterpolator4D *)node);
    1661             :         case TAG_MPEG4_Script:
    1662             : #ifndef GPAC_DISABLE_X3D
    1663             :         case TAG_X3D_Script:
    1664             : #endif
    1665             :                 return 1;
    1666             : 
    1667             : #ifndef GPAC_DISABLE_X3D
    1668           1 :         case TAG_X3D_BooleanFilter:
    1669           1 :                 InitBooleanFilter(node);
    1670           1 :                 return 1;
    1671           1 :         case TAG_X3D_BooleanSequencer:
    1672           1 :                 InitBooleanSequencer(node);
    1673           1 :                 return 1;
    1674           1 :         case TAG_X3D_BooleanToggle:
    1675           1 :                 InitBooleanToggle(node);
    1676           1 :                 return 1;
    1677           1 :         case TAG_X3D_BooleanTrigger:
    1678           1 :                 InitBooleanTrigger(node);
    1679           1 :                 return 1;
    1680           1 :         case TAG_X3D_IntegerSequencer:
    1681           1 :                 InitIntegerSequencer(node);
    1682           1 :                 return 1;
    1683           1 :         case TAG_X3D_IntegerTrigger:
    1684           1 :                 InitIntegerTrigger(node);
    1685           1 :                 return 1;
    1686           1 :         case TAG_X3D_TimeTrigger:
    1687           1 :                 InitTimeTrigger(node);
    1688           1 :                 return 1;
    1689             : #endif
    1690             :         }
    1691       32928 :         return 0;
    1692             : }
    1693             : 
    1694       86880 : Bool gf_sg_vrml_node_changed(GF_Node *node, GF_FieldInfo *field)
    1695             : {
    1696       86880 :         switch (node->sgprivate->tag) {
    1697        1798 :         case TAG_ProtoNode:
    1698             :                 /*hardcoded protos need modification notifs*/
    1699        1798 :                 if (node->sgprivate->UserCallback) return 0;
    1700             :         case TAG_MPEG4_ColorInterpolator:
    1701             :         case TAG_MPEG4_CoordinateInterpolator:
    1702             :         case TAG_MPEG4_CoordinateInterpolator2D:
    1703             :         case TAG_MPEG4_NormalInterpolator:
    1704             :         case TAG_MPEG4_OrientationInterpolator:
    1705             :         case TAG_MPEG4_PositionInterpolator:
    1706             :         case TAG_MPEG4_PositionInterpolator2D:
    1707             :         case TAG_MPEG4_ScalarInterpolator:
    1708             :         case TAG_MPEG4_Valuator:
    1709             :         case TAG_MPEG4_PositionInterpolator4D:
    1710             :         case TAG_MPEG4_CoordinateInterpolator4D:
    1711             :         case TAG_MPEG4_Script:
    1712             : #ifndef GPAC_DISABLE_X3D
    1713             :         case TAG_X3D_ColorInterpolator:
    1714             :         case TAG_X3D_CoordinateInterpolator:
    1715             :         case TAG_X3D_NormalInterpolator:
    1716             :         case TAG_X3D_OrientationInterpolator:
    1717             :         case TAG_X3D_PositionInterpolator:
    1718             :         case TAG_X3D_ScalarInterpolator:
    1719             :         case TAG_X3D_Script:
    1720             :         case TAG_X3D_BooleanFilter:
    1721             :         case TAG_X3D_BooleanSequencer:
    1722             :         case TAG_X3D_BooleanToggle:
    1723             :         case TAG_X3D_BooleanTrigger:
    1724             :         case TAG_X3D_IntegerSequencer:
    1725             :         case TAG_X3D_IntegerTrigger:
    1726             :         case TAG_X3D_TimeTrigger:
    1727             : #endif
    1728       25049 :                 return 1;
    1729         149 :         case TAG_MPEG4_PositionAnimator:
    1730         149 :                 PA_Modified(node, field);
    1731         149 :                 return 1;
    1732         298 :         case TAG_MPEG4_PositionAnimator2D:
    1733         298 :                 PA2D_Modified(node, field);
    1734         298 :                 return 1;
    1735         149 :         case TAG_MPEG4_ScalarAnimator:
    1736         149 :                 SA_Modified(node, field);
    1737         149 :                 return 1;
    1738             :         }
    1739             :         return 0;
    1740             : }
    1741             : 
    1742             : #if 0 //unused
    1743             : char *gf_node_vrml_dump_attribute(GF_Node *n, GF_FieldInfo *info)
    1744             : {
    1745             :         char szVal[1024];
    1746             : 
    1747             :         switch (info->fieldType) {
    1748             :         case GF_SG_VRML_SFBOOL:
    1749             :                 strcpy(szVal, *((SFBool*)info->far_ptr) ? "TRUE" : "FALSE");
    1750             :                 return gf_strdup(szVal);
    1751             :         case GF_SG_VRML_SFINT32:
    1752             :                 sprintf(szVal, "%d", *((SFInt32*)info->far_ptr) );
    1753             :                 return gf_strdup(szVal);
    1754             :         case GF_SG_VRML_SFFLOAT:
    1755             :                 sprintf(szVal, "%g", FIX2FLT( *((SFFloat*)info->far_ptr) ) );
    1756             :                 return gf_strdup(szVal);
    1757             :         case GF_SG_VRML_SFDOUBLE:
    1758             :                 sprintf(szVal, "%g", *((SFDouble *)info->far_ptr) );
    1759             :                 return gf_strdup(szVal);
    1760             :         case GF_SG_VRML_SFTIME:
    1761             :                 sprintf(szVal, "%g", *((SFTime *)info->far_ptr) );
    1762             :                 return gf_strdup(szVal);
    1763             :         case GF_SG_VRML_SFVEC2F:
    1764             :                 sprintf(szVal, "%g %g", FIX2FLT(((SFVec2f *)info->far_ptr)->x), FIX2FLT( ((SFVec2f *)info->far_ptr)->y) );
    1765             :                 return gf_strdup(szVal);
    1766             :         case GF_SG_VRML_SFVEC2D:
    1767             :                 sprintf(szVal, "%g %g", ((SFVec2d *)info->far_ptr)->x, ((SFVec2d *)info->far_ptr)->y);
    1768             :                 return gf_strdup(szVal);
    1769             :         case GF_SG_VRML_SFVEC3F:
    1770             :                 sprintf(szVal, "%g %g %g", FIX2FLT(((SFVec3f *)info->far_ptr)->x), FIX2FLT( ((SFVec3f *)info->far_ptr)->y) , FIX2FLT( ((SFVec3f *)info->far_ptr)->z) );
    1771             :                 return gf_strdup(szVal);
    1772             :         case GF_SG_VRML_SFVEC3D:
    1773             :                 sprintf(szVal, "%g %g %g", ((SFVec3d *)info->far_ptr)->x, ((SFVec3d *)info->far_ptr)->y, ((SFVec3d *)info->far_ptr)->z);
    1774             :                 return gf_strdup(szVal);
    1775             :         case GF_SG_VRML_SFCOLOR:
    1776             :                 sprintf(szVal, "%g %g %g", FIX2FLT(((SFColor *)info->far_ptr)->red), FIX2FLT( ((SFColor *)info->far_ptr)->green) , FIX2FLT( ((SFColor *)info->far_ptr)->blue) );
    1777             :                 return gf_strdup(szVal);
    1778             :         case GF_SG_VRML_SFCOLORRGBA:
    1779             :                 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) );
    1780             :                 return gf_strdup(szVal);
    1781             :         case GF_SG_VRML_SFROTATION:
    1782             :                 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) );
    1783             :                 return gf_strdup(szVal);
    1784             :         case GF_SG_VRML_SFSTRING:
    1785             :                 if (!((SFString*)info->far_ptr)->buffer ) return gf_strdup("");
    1786             :                 return gf_strdup( ((SFString*)info->far_ptr)->buffer );
    1787             : 
    1788             :         case GF_SG_VRML_SFURL:
    1789             :                 if (((SFURL *)info->far_ptr)->url) {
    1790             :                         return gf_strdup( ((SFURL *)info->far_ptr)->url );
    1791             :                 } else {
    1792             :                         sprintf(szVal, "od://%d", ((SFURL *)info->far_ptr)->OD_ID);
    1793             :                         return gf_strdup(szVal);
    1794             :                 }
    1795             : 
    1796             :         case GF_SG_VRML_SFIMAGE:
    1797             :         {
    1798             :                 u32 i, count;
    1799             :                 char *buf;
    1800             :                 SFImage *img = (SFImage *)info->far_ptr;
    1801             : 
    1802             :                 count = img->width * img->height * img->numComponents;
    1803             :                 i = (3/*' 0x'*/ + 2/*%02X*/*img->numComponents)*count + 20;
    1804             :                 buf = gf_malloc(sizeof(char) * i);
    1805             : 
    1806             :                 sprintf(buf , "%d %d %d", img->width, img->height, img->numComponents);
    1807             : 
    1808             :                 for (i=0; i<count; ) {
    1809             :                         switch (img->numComponents) {
    1810             :                         case 1:
    1811             :                                 sprintf(szVal, " 0x%02X", img->pixels[i]);
    1812             :                                 i++;
    1813             :                                 break;
    1814             :                         case 2:
    1815             :                                 sprintf(szVal, " 0x%02X%02X", img->pixels[i], img->pixels[i+1]);
    1816             :                                 i+=2;
    1817             :                                 break;
    1818             :                         case 3:
    1819             :                                 sprintf(szVal, " 0x%02X%02X%02X", img->pixels[i], img->pixels[i+1], img->pixels[i+2]);
    1820             :                                 i+=3;
    1821             :                                 break;
    1822             :                         case 4:
    1823             :                                 sprintf(szVal, " 0x%02X%02X%02X%02X", img->pixels[i], img->pixels[i+1], img->pixels[i+2], img->pixels[i+3]);
    1824             :                                 i+=4;
    1825             :                                 break;
    1826             :                         }
    1827             :                         strcat(buf, szVal);
    1828             :                 }
    1829             :                 return buf;
    1830             :         }
    1831             :         default:
    1832             :                 break;
    1833             :         }
    1834             :         /*todo - dump MFFields*/
    1835             :         return NULL;
    1836             : }
    1837             : #endif
    1838             : 
    1839             : 
    1840             : #endif /*GPAC_DISABLE_VRML*/
    1841             : 
    1842       19288 : Bool gf_node_in_table(GF_Node *node, u32 NDTType)
    1843             : {
    1844             : #ifndef GPAC_DISABLE_VRML
    1845       19288 :         u32 tag = node ? node->sgprivate->tag : 0;
    1846       19288 :         if (tag==TAG_ProtoNode) {
    1847         131 :                 tag = gf_sg_proto_get_root_tag(((GF_ProtoInstance *)node)->proto_interface);
    1848         131 :                 if (tag==TAG_UndefinedNode) return 1;
    1849             :         }
    1850       19255 :         return gf_node_in_table_by_tag(tag, NDTType);
    1851             : #else
    1852             :         return 1;
    1853             : #endif
    1854             : }

Generated by: LCOV version 1.13