LCOV - code coverage report
Current view: top level - bifs - memory_decoder.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 512 584 87.7 %
Date: 2021-04-29 23:48:07 Functions: 22 22 100.0 %

          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 / BIFS codec 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             : 
      27             : #include <gpac/internal/bifs_dev.h>
      28             : #include "quant.h"
      29             : 
      30             : 
      31             : #ifndef GPAC_DISABLE_BIFS
      32             : 
      33             : GF_Err ParseMFFieldList(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field);
      34             : GF_Err ParseMFFieldVec(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field);
      35             : 
      36             : 
      37             : static void BM_SetCommandNode(GF_Command *com, GF_Node *node)
      38             : {
      39         464 :         com->node = node;
      40         464 :         gf_node_register(node, NULL);
      41             : }
      42             : 
      43          12 : static GF_Err BM_ParseMultipleIndexedReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
      44             : {
      45             :         u32 ID, ind, field_ind, NumBits, lenpos, lennum, count;
      46             :         GF_Node *node;
      47             :         GF_Err e;
      48             :         GF_Command *com;
      49             :         GF_CommandField *inf;
      50             :         GF_FieldInfo field;
      51             : 
      52          12 :         ID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
      53          12 :         node = gf_sg_find_node(codec->current_graph, ID);
      54          12 :         if (!node) return GF_NON_COMPLIANT_BITSTREAM;
      55          12 :         NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
      56          12 :         ind = gf_bs_read_int(bs, NumBits);
      57          12 :         e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
      58          12 :         if (e) return e;
      59          12 :         e = gf_node_get_field(node, field_ind, &field);
      60          12 :         if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
      61             : 
      62          12 :         lenpos = gf_bs_read_int(bs, 5);
      63          12 :         lennum = gf_bs_read_int(bs, 5);
      64          12 :         count = gf_bs_read_int(bs, lennum);
      65             : 
      66          12 :         com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_INDEXED_REPLACE);
      67             :         BM_SetCommandNode(com, node);
      68          12 :         field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
      69             : 
      70          60 :         while (count) {
      71          36 :                 inf = gf_sg_command_field_new(com);
      72          36 :                 inf->pos = gf_bs_read_int(bs, lenpos);
      73          36 :                 inf->fieldIndex = field.fieldIndex;
      74          36 :                 inf->fieldType = field.fieldType;
      75             : 
      76          36 :                 if (field.fieldType==GF_SG_VRML_SFNODE) {
      77           0 :                         inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype);
      78           0 :                         if (codec->LastError) goto err;
      79           0 :                         inf->field_ptr = &inf->new_node;
      80           0 :                         gf_node_register(inf->new_node, NULL);
      81             :                 } else {
      82          36 :                         field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
      83          36 :                         e = gf_bifs_dec_sf_field(codec, bs, node, &field, GF_TRUE);
      84          36 :                         if (e) goto err;
      85             :                 }
      86          36 :                 count--;
      87             :         }
      88          12 : err:
      89          12 :         if (e) gf_sg_command_del(com);
      90          12 :         else gf_list_add(com_list, com);
      91             :         return e;
      92             : }
      93             : 
      94          16 : static GF_Err BM_ParseMultipleReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
      95             : {
      96             :         u32 i, numFields, index, flag, nbBits, field_ref, fieldind;
      97             :         GF_Err e;
      98             :         GF_FieldInfo field;
      99             :         u32 NodeID;
     100             :         GF_Node *node;
     101             :         GF_Command *com;
     102             :         GF_CommandField *inf;
     103             : 
     104          16 :         NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     105          16 :         node = gf_sg_find_node(codec->current_graph, NodeID);
     106          16 :         if (!node) return GF_NON_COMPLIANT_BITSTREAM;
     107             : 
     108             :         e = GF_OK;
     109          16 :         com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_REPLACE);
     110             :         BM_SetCommandNode(com, node);
     111          16 :         flag = gf_bs_read_int(bs, 1);
     112          16 :         if (flag) {
     113          16 :                 numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF);
     114          88 :                 for (i=0; i<numFields; i++) {
     115          72 :                         flag = gf_bs_read_int(bs, 1);
     116          72 :                         if (!flag) continue;
     117          40 :                         gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &index);
     118          40 :                         e = gf_node_get_field(node, index, &field);
     119          40 :                         if (e) goto exit;
     120          40 :                         inf = gf_sg_command_field_new(com);
     121          40 :                         inf->fieldType = field.fieldType;
     122          40 :                         inf->fieldIndex = field.fieldIndex;
     123          40 :                         if (inf->fieldType==GF_SG_VRML_SFNODE) {
     124          12 :                                 field.far_ptr = inf->field_ptr = &inf->new_node;
     125          28 :                         } else if (inf->fieldType==GF_SG_VRML_MFNODE) {
     126           4 :                                 field.far_ptr = inf->field_ptr = &inf->node_list;
     127             :                         } else {
     128          24 :                                 field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
     129             :                         }
     130          40 :                         e = gf_bifs_dec_field(codec, bs, node, &field, GF_TRUE);
     131          40 :                         if (e) goto exit;
     132             :                 }
     133             :         } else {
     134           0 :                 flag = gf_bs_read_int(bs, 1);
     135           0 :                 nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1);
     136           0 :                 while (!flag && (codec->LastError>=0)) {
     137           0 :                         field_ref = gf_bs_read_int(bs, nbBits);
     138           0 :                         e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &fieldind);
     139           0 :                         if (e) goto exit;
     140           0 :                         e = gf_node_get_field(node, fieldind, &field);
     141           0 :                         if (e) goto exit;
     142           0 :                         inf = gf_sg_command_field_new(com);
     143           0 :                         inf->fieldType = field.fieldType;
     144           0 :                         inf->fieldIndex = field.fieldIndex;
     145           0 :                         if (inf->fieldType==GF_SG_VRML_SFNODE) {
     146           0 :                                 field.far_ptr = inf->field_ptr = &inf->new_node;
     147           0 :                         } else if (inf->fieldType==GF_SG_VRML_MFNODE) {
     148           0 :                                 field.far_ptr = inf->field_ptr = &inf->node_list;
     149             :                         } else {
     150           0 :                                 field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
     151             :                         }
     152           0 :                         e = gf_bifs_dec_field(codec, bs, node, &field, GF_TRUE);
     153           0 :                         if (e) goto exit;
     154           0 :                         flag = gf_bs_read_int(bs, 1);
     155             :                 }
     156             :         }
     157             : 
     158             : 
     159           0 : exit:
     160          16 :         if (e) gf_sg_command_del(com);
     161          16 :         else gf_list_add(com_list, com);
     162             :         return e;
     163             : }
     164             : 
     165          12 : static GF_Err BM_ParseGlobalQuantizer(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     166             : {
     167             :         GF_Node *node;
     168             :         GF_Command *com;
     169             :         GF_CommandField *inf;
     170          12 :         node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode);
     171          12 :         if (!node) return GF_NON_COMPLIANT_BITSTREAM;
     172             : 
     173             :         /*reset global QP*/
     174          12 :         if (codec->scenegraph->global_qp) {
     175           0 :                 gf_node_unregister(codec->scenegraph->global_qp, NULL);
     176             :         }
     177          12 :         codec->ActiveQP = NULL;
     178          12 :         codec->scenegraph->global_qp = NULL;
     179             : 
     180          12 :         if (gf_node_get_tag(node) != TAG_MPEG4_QuantizationParameter) {
     181           0 :                 gf_node_unregister(node, NULL);
     182           0 :                 return GF_NON_COMPLIANT_BITSTREAM;
     183             :         }
     184             : 
     185             :         /*register global QP*/
     186          12 :         codec->ActiveQP = (M_QuantizationParameter *) node;
     187          12 :         codec->ActiveQP->isLocal = 0;
     188          12 :         codec->scenegraph->global_qp = node;
     189             : 
     190             :         /*register TWICE: once for the command, and for the scenegraph globalQP*/
     191          12 :         node->sgprivate->num_instances = 2;
     192             : 
     193          12 :         com = gf_sg_command_new(codec->current_graph, GF_SG_GLOBAL_QUANTIZER);
     194          12 :         inf = gf_sg_command_field_new(com);
     195          12 :         inf->new_node = node;
     196          12 :         inf->field_ptr = &inf->new_node;
     197          12 :         inf->fieldType = GF_SG_VRML_SFNODE;
     198          12 :         gf_list_add(com_list, com);
     199          12 :         return GF_OK;
     200             : }
     201             : 
     202          12 : static GF_Err BM_ParseProtoDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     203             : {
     204             :         u32 flag, count;
     205          12 :         GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_PROTO_DELETE);
     206          12 :         flag = gf_bs_read_int(bs, 1);
     207          12 :         if (flag) {
     208             :                 count = 0;
     209          12 :                 flag = gf_bs_read_int(bs, 1);
     210          24 :                 while (flag) {
     211          12 :                         com->del_proto_list = (u32*)gf_realloc(com->del_proto_list, sizeof(u32) * (com->del_proto_list_size+1));
     212          12 :                         com->del_proto_list[count] = gf_bs_read_int(bs, codec->info->config.ProtoIDBits);
     213          12 :                         com->del_proto_list_size++;
     214          12 :                         flag = gf_bs_read_int(bs, 1);
     215             :                 }
     216             :         } else {
     217           0 :                 flag = gf_bs_read_int(bs, 5);
     218           0 :                 com->del_proto_list_size = gf_bs_read_int(bs, flag);
     219           0 :                 com->del_proto_list = (u32*)gf_realloc(com->del_proto_list, sizeof(u32) * (com->del_proto_list_size));
     220             :                 flag = 0;
     221           0 :                 while (flag<com->del_proto_list_size) {
     222           0 :                         com->del_proto_list[flag] = gf_bs_read_int(bs, codec->info->config.ProtoIDBits);
     223           0 :                         flag++;
     224             :                 }
     225             :         }
     226          12 :         gf_list_add(com_list, com);
     227          12 :         return GF_OK;
     228             : }
     229             : 
     230          24 : static GF_Err BM_XReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     231             : {
     232             :         GF_FieldInfo targetField, fromField, decfield;
     233             :         GF_Node *target, *fromNode;
     234             :         s32 pos = -2;
     235             :         u32 id, nbBits, ind, aind;
     236             :         GF_Err e;
     237             :         GF_Command *com;
     238             :         GF_CommandField *inf;
     239             : 
     240          24 :         id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     241          24 :         target = gf_sg_find_node(codec->current_graph, id);
     242          24 :         if (!target) return GF_SG_UNKNOWN_NODE;
     243             : 
     244          24 :         com = gf_sg_command_new(codec->current_graph, GF_SG_XREPLACE);
     245             :         BM_SetCommandNode(com, target);
     246          24 :         gf_list_add(com_list, com);
     247             : 
     248          24 :         nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1);
     249          24 :         ind = gf_bs_read_int(bs, nbBits);
     250          24 :         e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind);
     251          24 :         if (e) return e;
     252          24 :         e = gf_node_get_field(target, aind, &targetField);
     253          24 :         if (e) return e;
     254             : 
     255          24 :         inf = gf_sg_command_field_new(com);
     256          24 :         inf->fieldIndex = aind;
     257             : 
     258          24 :         if (!gf_sg_vrml_is_sf_field(targetField.fieldType)) {
     259             :                 /*this is indexed replacement*/
     260          12 :                 if (gf_bs_read_int(bs, 1)) {
     261             :                         /*index is dynamic*/
     262          12 :                         if (gf_bs_read_int(bs, 1)) {
     263             :                                 GF_Node *n;
     264          12 :                                 id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     265          12 :                                 n = gf_sg_find_node(codec->current_graph, id);
     266          12 :                                 if (!n) return GF_SG_UNKNOWN_NODE;
     267          12 :                                 com->toNodeID = id;
     268             : 
     269          12 :                                 nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1);
     270          12 :                                 ind = gf_bs_read_int(bs, nbBits);
     271          12 :                                 e = gf_bifs_get_field_index(n, ind, GF_SG_FIELD_CODING_DEF, &aind);
     272          12 :                                 if (e) return e;
     273          12 :                                 e = gf_node_get_field(n, aind, &fromField);
     274          12 :                                 if (e) return e;
     275          12 :                                 com->toFieldIndex = aind;
     276             :                         } else {
     277           0 :                                 u32 type = gf_bs_read_int(bs, 2);
     278           0 :                                 switch (type) {
     279           0 :                                 case 0:
     280           0 :                                         pos = gf_bs_read_int(bs, 16);
     281           0 :                                         break;
     282           0 :                                 case 2:
     283             :                                         pos = 0;
     284           0 :                                         break;
     285           0 :                                 case 3:
     286             :                                         pos = -1;
     287           0 :                                         break;
     288             :                                 }
     289             :                         }
     290             :                 }
     291          12 :                 if (targetField.fieldType==GF_SG_VRML_MFNODE) {
     292          12 :                         if (gf_bs_read_int(bs, 1)) {
     293          12 :                                 target = gf_node_list_get_child(*(GF_ChildNodeItem **)targetField.far_ptr, pos);
     294          12 :                                 if (!target) return GF_SG_UNKNOWN_NODE;
     295             : 
     296          12 :                                 nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1);
     297          12 :                                 ind = gf_bs_read_int(bs, nbBits);
     298          12 :                                 e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind);
     299          12 :                                 if (e) return e;
     300          12 :                                 e = gf_node_get_field(target, aind, &targetField);
     301          12 :                                 if (e) return e;
     302             :                                 pos = -2;
     303          12 :                                 com->child_field = aind;
     304          12 :                                 com->ChildNodeTag = gf_node_get_tag(target);
     305          12 :                                 if (com->ChildNodeTag == TAG_ProtoNode) {
     306           0 :                                         s32 p_id = gf_sg_proto_get_id(gf_node_get_proto(target));
     307           0 :                                         com->ChildNodeTag = -p_id;
     308             :                                 }
     309             :                         }
     310             :                 }
     311          12 :                 inf->pos = pos;
     312             :         }
     313             : 
     314             :         fromNode = NULL;
     315          24 :         if (gf_bs_read_int(bs, 1)) {
     316          12 :                 id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     317          12 :                 fromNode = gf_sg_find_node(codec->current_graph, id);
     318          12 :                 if (!fromNode) return GF_SG_UNKNOWN_NODE;
     319          12 :                 com->fromNodeID = id;
     320             : 
     321          12 :                 nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(fromNode, GF_SG_FIELD_CODING_DEF)-1);
     322          12 :                 ind = gf_bs_read_int(bs, nbBits);
     323          12 :                 e = gf_bifs_get_field_index(fromNode, ind, GF_SG_FIELD_CODING_DEF, &aind);
     324          12 :                 if (e) return e;
     325          12 :                 e = gf_node_get_field(fromNode, aind, &fromField);
     326          12 :                 if (e) return e;
     327          12 :                 com->fromFieldIndex = aind;
     328             : 
     329          12 :                 return GF_OK;
     330             :         }
     331             : 
     332             : 
     333          12 :         if (pos>= -1) {
     334           0 :                 inf->fieldType = gf_sg_vrml_get_sf_type(targetField.fieldType);
     335             :         } else {
     336          12 :                 inf->fieldType = targetField.fieldType;
     337             :         }
     338          12 :         decfield.fieldIndex = inf->fieldIndex;
     339          12 :         decfield.fieldType = inf->fieldType;
     340             : 
     341          12 :         if (inf->fieldType==GF_SG_VRML_SFNODE) {
     342           0 :                 decfield.far_ptr = inf->field_ptr = &inf->new_node;
     343          12 :         } else if (inf->fieldType==GF_SG_VRML_MFNODE) {
     344           0 :                 decfield.far_ptr = inf->field_ptr = &inf->node_list;
     345             :         } else {
     346          12 :                 decfield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
     347             :         }
     348          12 :         e = gf_bifs_dec_sf_field(codec, bs, target, &decfield, GF_TRUE);
     349          12 :         return e;
     350             : }
     351             : 
     352         112 : static GF_Err BM_ParseExtendedUpdates(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     353             : {
     354         112 :         u32 type = gf_bs_read_int(bs, 8);
     355             :         GF_Err e;
     356             : 
     357         112 :         switch (type) {
     358          12 :         case 0:
     359             :         {
     360          12 :                 GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_PROTO_INSERT);
     361          12 :                 e = gf_bifs_dec_proto_list(codec, bs, com->new_proto_list);
     362          12 :                 if (e) gf_sg_command_del(com);
     363          12 :                 else gf_list_add(com_list, com);
     364             :         }
     365             :         return e;
     366          12 :         case 1:
     367          12 :                 return BM_ParseProtoDelete(codec, bs, com_list);
     368          12 :         case 2:
     369             :         {
     370          12 :                 GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_PROTO_DELETE_ALL);
     371          12 :                 return gf_list_add(com_list, com);
     372             :         }
     373          12 :         case 3:
     374          12 :                 return BM_ParseMultipleIndexedReplace(codec, bs, com_list);
     375          16 :         case 4:
     376          16 :                 return BM_ParseMultipleReplace(codec, bs, com_list);
     377          12 :         case 5:
     378          12 :                 return BM_ParseGlobalQuantizer(codec, bs, com_list);
     379          12 :         case 6:
     380             :         {
     381             :                 GF_Command *com;
     382          12 :                 u32 ID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     383          12 :                 GF_Node *n = gf_sg_find_node(codec->current_graph, ID);
     384          12 :                 if (!n) return GF_OK;
     385          12 :                 com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_DELETE_EX);
     386             :                 BM_SetCommandNode(com, n);
     387          12 :                 gf_list_add(com_list, com);
     388             :         }
     389          12 :         return GF_OK;
     390          24 :         case 7:
     391          24 :                 return BM_XReplace(codec, bs, com_list);
     392             : 
     393             :         default:
     394             :                 return GF_BIFS_UNKNOWN_VERSION;
     395             :         }
     396             : }
     397             : 
     398             : /*inserts a node in a container (node.children)*/
     399          60 : GF_Err BM_ParseNodeInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     400             : {
     401             :         u32 NodeID, NDT;
     402             :         GF_CommandField *inf;
     403             :         s32 type, pos;
     404             :         GF_Node *node, *def;
     405             : 
     406          60 :         NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     407          60 :         def = gf_sg_find_node(codec->current_graph, NodeID);
     408          60 :         if (!def) return GF_NON_COMPLIANT_BITSTREAM;
     409          60 :         NDT = gf_bifs_get_child_table(def);
     410          60 :         if (!NDT) return GF_NON_COMPLIANT_BITSTREAM;
     411             : 
     412          60 :         type = gf_bs_read_int(bs, 2);
     413          60 :         switch (type) {
     414           0 :         case 0:
     415           0 :                 pos = gf_bs_read_int(bs, 8);
     416           0 :                 break;
     417             :         case 2:
     418             :                 pos = 0;
     419             :                 break;
     420          36 :         case 3:
     421             :                 /*-1 means append*/
     422             :                 pos = -1;
     423          36 :                 break;
     424             :         default:
     425             :                 return GF_NON_COMPLIANT_BITSTREAM;
     426             :         }
     427          60 :         node = gf_bifs_dec_node(codec, bs, NDT);
     428          60 :         if (!codec->LastError) {
     429          60 :                 GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_INSERT);
     430             :                 BM_SetCommandNode(com, def);
     431          60 :                 inf = gf_sg_command_field_new(com);
     432          60 :                 inf->pos = pos;
     433          60 :                 inf->new_node = node;
     434          60 :                 inf->field_ptr = &inf->new_node;
     435          60 :                 inf->fieldType = GF_SG_VRML_SFNODE;
     436          60 :                 gf_list_add(com_list, com);
     437             :                 /*register*/
     438          60 :                 gf_node_register(node, NULL);
     439             :         }
     440          60 :         return codec->LastError;
     441             : }
     442             : 
     443             : /*NB This can insert a node as well (but usually not in the .children field)*/
     444          16 : GF_Err BM_ParseIndexInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     445             : {
     446             :         GF_Err e;
     447             :         u32 NodeID;
     448             :         u32 NumBits, ind, field_ind;
     449             :         u8 type;
     450             :         GF_Command *com;
     451             :         GF_CommandField *inf;
     452             :         s32 pos;
     453             :         GF_Node *def, *node;
     454             :         GF_FieldInfo field, sffield;
     455             : 
     456          16 :         NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     457          16 :         def = gf_sg_find_node(codec->current_graph, NodeID);
     458          16 :         if (!def) return GF_NON_COMPLIANT_BITSTREAM;
     459             :         /*index insertion uses IN mode for field index*/
     460          16 :         NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(def, GF_SG_FIELD_CODING_IN)-1);
     461          16 :         ind = gf_bs_read_int(bs, NumBits);
     462             : 
     463          16 :         e = gf_bifs_get_field_index(def, ind, GF_SG_FIELD_CODING_IN, &field_ind);
     464          16 :         if (e) return e;
     465             : 
     466          16 :         type = gf_bs_read_int(bs, 2);
     467          16 :         switch (type) {
     468           4 :         case 0:
     469           4 :                 pos = gf_bs_read_int(bs, 16);
     470           4 :                 break;
     471             :         case 2:
     472             :                 pos = 0;
     473             :                 break;
     474           0 :         case 3:
     475             :                 pos = -1;
     476           0 :                 break;
     477             :         default:
     478             :                 return GF_NON_COMPLIANT_BITSTREAM;
     479             :         }
     480             : 
     481          16 :         e = gf_node_get_field(def, field_ind, &field);
     482          16 :         if (e) return e;
     483          16 :         if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
     484             : 
     485             :         memcpy(&sffield, &field, sizeof(GF_FieldInfo));
     486          16 :         sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
     487             : 
     488             :         /*rescale the MFField and parse the SFField*/
     489          16 :         if (field.fieldType==GF_SG_VRML_MFNODE) {
     490           4 :                 node = gf_bifs_dec_node(codec, bs, field.NDTtype);
     491           4 :                 if (!codec->LastError) {
     492           4 :                         com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT);
     493             :                         BM_SetCommandNode(com, def);
     494           4 :                         inf = gf_sg_command_field_new(com);
     495           4 :                         inf->pos = pos;
     496           4 :                         inf->fieldIndex = field_ind;
     497           4 :                         inf->fieldType = sffield.fieldType;
     498           4 :                         inf->new_node = node;
     499           4 :                         inf->field_ptr = &inf->new_node;
     500           4 :                         gf_list_add(com_list, com);
     501             :                         /*register*/
     502           4 :                         gf_node_register(node, NULL);
     503             :                 }
     504             :         } else {
     505          12 :                 com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT);
     506             :                 BM_SetCommandNode(com, def);
     507          12 :                 inf = gf_sg_command_field_new(com);
     508          12 :                 inf->pos = pos;
     509          12 :                 inf->fieldIndex = field_ind;
     510          12 :                 inf->fieldType = sffield.fieldType;
     511          12 :                 sffield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(sffield.fieldType);
     512          12 :                 codec->LastError = gf_bifs_dec_sf_field(codec, bs, def, &sffield, GF_TRUE);
     513          12 :                 gf_list_add(com_list, com);
     514             :         }
     515          16 :         return codec->LastError;
     516             : }
     517             : 
     518             : 
     519          12 : GF_Err BM_ParseRouteInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     520             : {
     521             :         GF_Err e;
     522             :         u8 flag;
     523             :         GF_Command *com;
     524             :         GF_Node *InNode, *OutNode;
     525             :         u32 RouteID, outField, inField, numBits, ind, node_id;
     526             :         char name[1000];
     527             : 
     528             :         RouteID = 0;
     529             : 
     530          12 :         flag = gf_bs_read_int(bs, 1);
     531             :         /*def'ed route*/
     532          12 :         if (flag) {
     533           0 :                 RouteID = 1 + gf_bs_read_int(bs, codec->info->config.RouteIDBits);
     534           0 :                 if (codec->UseName) gf_bifs_dec_name(bs, name);
     535             :         }
     536             :         /*origin*/
     537          12 :         node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     538          12 :         OutNode = gf_sg_find_node(codec->current_graph, node_id);
     539          12 :         if (!OutNode) return GF_SG_UNKNOWN_NODE;
     540             : 
     541          12 :         numBits = gf_node_get_num_fields_in_mode(OutNode, GF_SG_FIELD_CODING_OUT) - 1;
     542          12 :         numBits = gf_get_bit_size(numBits);
     543          12 :         ind = gf_bs_read_int(bs, numBits);
     544          12 :         e = gf_bifs_get_field_index(OutNode, ind, GF_SG_FIELD_CODING_OUT, &outField);
     545          12 :         if (e) return e;
     546             : 
     547             :         /*target*/
     548          12 :         node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     549          12 :         InNode = gf_sg_find_node(codec->current_graph, node_id);
     550          12 :         if (!InNode) return GF_SG_UNKNOWN_NODE;
     551             : 
     552          12 :         numBits = gf_node_get_num_fields_in_mode(InNode, GF_SG_FIELD_CODING_IN) - 1;
     553          12 :         numBits = gf_get_bit_size(numBits);
     554          12 :         ind = gf_bs_read_int(bs, numBits);
     555          12 :         e = gf_bifs_get_field_index(InNode, ind, GF_SG_FIELD_CODING_IN, &inField);
     556          12 :         if (e) return e;
     557             : 
     558          12 :         com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_INSERT);
     559          12 :         com->RouteID = RouteID;
     560          12 :         if (codec->UseName) com->def_name = gf_strdup( name);
     561          12 :         com->fromNodeID = gf_node_get_id(OutNode);
     562          12 :         com->fromFieldIndex = outField;
     563          12 :         com->toNodeID = gf_node_get_id(InNode);
     564          12 :         com->toFieldIndex = inField;
     565          12 :         gf_list_add(com_list, com);
     566          12 :         return codec->LastError;
     567             : }
     568             : 
     569             : 
     570         200 : GF_Err BM_ParseInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     571             : {
     572             :         u8 type;
     573             : 
     574         200 :         type = gf_bs_read_int(bs, 2);
     575         200 :         switch (type) {
     576          60 :         case 0:
     577          60 :                 return BM_ParseNodeInsert(codec, bs, com_list);
     578         112 :         case 1:
     579         112 :                 return BM_ParseExtendedUpdates(codec, bs, com_list);
     580          16 :         case 2:
     581          16 :                 return BM_ParseIndexInsert(codec, bs, com_list);
     582          12 :         case 3:
     583          12 :                 return BM_ParseRouteInsert(codec, bs, com_list);
     584             :         default:
     585             :                 return GF_NON_COMPLIANT_BITSTREAM;
     586             :         }
     587             : }
     588             : 
     589             : 
     590          12 : GF_Err BM_ParseIndexDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     591             : {
     592             :         u32 NodeID, NumBits, ind, field_ind;
     593             :         s32 pos;
     594             :         GF_Command *com;
     595             :         u8 type;
     596             :         GF_Node *node;
     597             :         GF_Err e;
     598             :         GF_CommandField *inf;
     599             :         GF_FieldInfo field;
     600             : 
     601          12 :         NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     602          12 :         node = gf_sg_find_node(codec->current_graph, NodeID);
     603          12 :         if (!node) return GF_NON_COMPLIANT_BITSTREAM;
     604             : 
     605          12 :         NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN) - 1);
     606          12 :         ind = gf_bs_read_int(bs, NumBits);
     607             : 
     608          12 :         type = gf_bs_read_int(bs, 2);
     609          12 :         switch (type) {
     610           0 :         case 0:
     611           0 :                 pos = (u32) gf_bs_read_int(bs, 16);
     612           0 :                 break;
     613             :         case 2:
     614             :                 pos = 0;
     615             :                 break;
     616           0 :         case 3:
     617             :                 pos = -1;
     618           0 :                 break;
     619             :         default:
     620             :                 return GF_NON_COMPLIANT_BITSTREAM;
     621             :         }
     622          12 :         e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
     623          12 :         if (e) return e;
     624          12 :         e = gf_node_get_field(node, field_ind, &field);
     625          12 :         if (e) return e;
     626          12 :         if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
     627          12 :         com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_DELETE);
     628             :         BM_SetCommandNode(com, node);
     629          12 :         inf = gf_sg_command_field_new(com);
     630          12 :         inf->pos = pos;
     631          12 :         inf->fieldIndex = field.fieldIndex;
     632          12 :         inf->fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
     633          12 :         gf_list_add(com_list, com);
     634          12 :         return codec->LastError;
     635             : }
     636             : 
     637             : 
     638             : 
     639          36 : GF_Err BM_ParseDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     640             : {
     641             :         u8 type;
     642             :         u32 ID;
     643             :         GF_Command *com;
     644             :         GF_Node *n;
     645             : 
     646          36 :         type = gf_bs_read_int(bs, 2);
     647          36 :         switch (type) {
     648          12 :         case 0:
     649          12 :                 ID = 1+gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     650          12 :                 n = gf_sg_find_node(codec->current_graph, ID);
     651          12 :                 if (!n) return GF_OK;
     652          12 :                 com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_DELETE);
     653             :                 BM_SetCommandNode(com, n);
     654          12 :                 gf_list_add(com_list, com);
     655          12 :                 return GF_OK;
     656          12 :         case 2:
     657          12 :                 return BM_ParseIndexDelete(codec, bs, com_list);
     658          12 :         case 3:
     659          12 :                 com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_DELETE);
     660          12 :                 com->RouteID = 1+gf_bs_read_int(bs, codec->info->config.RouteIDBits);
     661          12 :                 gf_list_add(com_list, com);
     662          12 :                 return GF_OK;
     663             :         default:
     664             :                 return GF_NON_COMPLIANT_BITSTREAM;
     665             :         }
     666             :         return GF_OK;
     667             : }
     668             : 
     669             : 
     670          60 : GF_Err BM_ParseNodeReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     671             : {
     672             :         u32 NodeID;
     673             :         GF_Command *com;
     674             :         GF_Node *node;
     675             :         GF_CommandField *inf;
     676             : 
     677          60 :         NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     678             :         /*this is delete / new on a DEF node: replace ALL instances*/
     679          60 :         node = gf_sg_find_node(codec->current_graph, NodeID);
     680          60 :         if (!node) return GF_NON_COMPLIANT_BITSTREAM;
     681             : 
     682          60 :         com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_REPLACE);
     683             :         BM_SetCommandNode(com, node);
     684          60 :         inf = gf_sg_command_field_new(com);
     685          60 :         inf->new_node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode);
     686          60 :         inf->fieldType = GF_SG_VRML_SFNODE;
     687          60 :         inf->field_ptr = &inf->new_node;
     688          60 :         gf_list_add(com_list, com);
     689          60 :         gf_node_register(inf->new_node, NULL);
     690          60 :         return codec->LastError;
     691             : }
     692             : 
     693         208 : GF_Err BM_ParseFieldReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     694             : {
     695             :         GF_Err e;
     696             :         GF_Command *com;
     697             :         u32 NodeID, ind, field_ind, NumBits;
     698             :         GF_Node *node;
     699             :         GF_FieldInfo field;
     700             :         GF_CommandField *inf;
     701             : 
     702         208 :         NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     703         208 :         node = gf_sg_find_node(codec->current_graph, NodeID);
     704         208 :         if (!node) return GF_NON_COMPLIANT_BITSTREAM;
     705         204 :         NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
     706         204 :         ind = gf_bs_read_int(bs, NumBits);
     707         204 :         e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
     708         204 :         if (e) return e;
     709             : 
     710         204 :         e = gf_node_get_field(node, field_ind, &field);
     711         204 :         if (e) return e;
     712             : 
     713         204 :         com = gf_sg_command_new(codec->current_graph, GF_SG_FIELD_REPLACE);
     714             :         BM_SetCommandNode(com, node);
     715         204 :         inf = gf_sg_command_field_new(com);
     716         204 :         inf->fieldIndex = field_ind;
     717         204 :         inf->fieldType = field.fieldType;
     718         204 :         if (inf->fieldType == GF_SG_VRML_SFNODE) {
     719           8 :                 field.far_ptr = inf->field_ptr = &inf->new_node;
     720         196 :         } else if (inf->fieldType == GF_SG_VRML_MFNODE) {
     721           4 :                 field.far_ptr = inf->field_ptr = &inf->node_list;
     722             :         } else {
     723         192 :                 field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(field.fieldType);
     724             :         }
     725             :         /*parse the field*/
     726         204 :         codec->LastError = gf_bifs_dec_field(codec, bs, node, &field, GF_TRUE);
     727             : 
     728         204 :         gf_list_add(com_list, com);
     729         204 :         return codec->LastError;
     730             : }
     731             : 
     732          36 : GF_Err BM_ParseIndexValueReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     733             : {
     734             :         u32 NodeID, ind, field_ind, NumBits;
     735             :         s32 type, pos;
     736             :         GF_Command *com;
     737             :         GF_Node *node;
     738             :         GF_Err e;
     739             :         GF_FieldInfo field, sffield;
     740             :         GF_CommandField *inf;
     741             : 
     742             :         /*get the node*/
     743          36 :         NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     744             : 
     745          36 :         node = gf_sg_find_node(codec->current_graph, NodeID);
     746          36 :         if (!node) return GF_NON_COMPLIANT_BITSTREAM;
     747          36 :         NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
     748          36 :         ind = gf_bs_read_int(bs, NumBits);
     749          36 :         e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
     750          36 :         if (e) return e;
     751             : 
     752          36 :         e = gf_node_get_field(node, field_ind, &field);
     753          36 :         if (e) return e;
     754          36 :         if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
     755             : 
     756          36 :         type = gf_bs_read_int(bs, 2);
     757          36 :         switch (type) {
     758          12 :         case 0:
     759          12 :                 pos = gf_bs_read_int(bs, 16);
     760          12 :                 break;
     761             :         case 2:
     762             :                 pos = 0;
     763             :                 break;
     764           0 :         case 3:
     765           0 :                 pos = ((GenMFField *) field.far_ptr)->count - 1;
     766           0 :                 break;
     767             :         default:
     768             :                 return GF_NON_COMPLIANT_BITSTREAM;
     769             :         }
     770             : 
     771          36 :         com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_REPLACE);
     772             :         BM_SetCommandNode(com, node);
     773          36 :         inf = gf_sg_command_field_new(com);
     774          36 :         inf->fieldIndex = field.fieldIndex;
     775          36 :         inf->pos = pos;
     776             : 
     777          36 :         if (field.fieldType == GF_SG_VRML_MFNODE) {
     778          24 :                 inf->fieldType = GF_SG_VRML_SFNODE;
     779          24 :                 inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype);
     780          24 :                 inf->field_ptr = &inf->new_node;
     781          24 :                 if (inf->new_node) gf_node_register(inf->new_node, NULL);
     782             :         } else {
     783             :                 memcpy(&sffield, &field, sizeof(GF_FieldInfo));
     784          12 :                 sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
     785          12 :                 inf->fieldType = sffield.fieldType;
     786          12 :                 sffield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(sffield.fieldType);
     787          12 :                 codec->LastError = gf_bifs_dec_sf_field(codec, bs, node, &sffield, GF_TRUE);
     788             :         }
     789          36 :         gf_list_add(com_list, com);
     790          36 :         return codec->LastError;
     791             : }
     792             : 
     793          12 : GF_Err BM_ParseRouteReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     794             : {
     795             :         GF_Err e;
     796             :         GF_Command *com;
     797             :         u32 RouteID, numBits, ind, node_id, fromID, toID;
     798             :         GF_Node *OutNode, *InNode;
     799             : 
     800          12 :         RouteID = 1+gf_bs_read_int(bs, codec->info->config.RouteIDBits);
     801             : 
     802             :         /*origin*/
     803          12 :         node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     804          12 :         OutNode = gf_sg_find_node(codec->current_graph, node_id);
     805          12 :         if (!OutNode) return GF_NON_COMPLIANT_BITSTREAM;
     806          12 :         numBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(OutNode, GF_SG_FIELD_CODING_OUT) - 1);
     807          12 :         ind = gf_bs_read_int(bs, numBits);
     808          12 :         e = gf_bifs_get_field_index(OutNode, ind, GF_SG_FIELD_CODING_OUT, &fromID);
     809          12 :         if (e) return e;
     810             : 
     811             :         /*target*/
     812          12 :         node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
     813          12 :         InNode = gf_sg_find_node(codec->current_graph, node_id);
     814          12 :         if (!InNode) return GF_NON_COMPLIANT_BITSTREAM;
     815          12 :         numBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(InNode, GF_SG_FIELD_CODING_IN) - 1);
     816          12 :         ind = gf_bs_read_int(bs, numBits);
     817          12 :         e = gf_bifs_get_field_index(InNode, ind, GF_SG_FIELD_CODING_IN, &toID);
     818          12 :         if (e) return e;
     819             : 
     820          12 :         com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_REPLACE);
     821          12 :         com->RouteID = RouteID;
     822          12 :         com->fromNodeID = gf_node_get_id(OutNode);
     823          12 :         com->fromFieldIndex = fromID;
     824          12 :         com->toNodeID = gf_node_get_id(InNode);
     825          12 :         com->toFieldIndex = toID;
     826          12 :         gf_list_add(com_list, com);
     827          12 :         return codec->LastError;
     828             : }
     829             : 
     830             : 
     831         316 : GF_Err BM_ParseReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     832             : {
     833             :         u8 type;
     834         316 :         type = gf_bs_read_int(bs, 2);
     835         316 :         switch (type) {
     836          60 :         case 0:
     837          60 :                 return BM_ParseNodeReplace(codec, bs, com_list);
     838         208 :         case 1:
     839         208 :                 return BM_ParseFieldReplace(codec, bs, com_list);
     840          36 :         case 2:
     841          36 :                 return BM_ParseIndexValueReplace(codec, bs, com_list);
     842          12 :         case 3:
     843          12 :                 return BM_ParseRouteReplace(codec, bs, com_list);
     844             :         }
     845             :         return GF_OK;
     846             : }
     847             : 
     848          40 : GF_Err BM_SceneReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     849             : {
     850             :         GF_Command *com;
     851             :         GF_Node *backup_root;
     852             :         GF_List *backup_routes;
     853             :         GF_Err BD_DecSceneReplace(GF_BifsDecoder * codec, GF_BitStream *bs, GF_List *proto_list);
     854             : 
     855          40 :         backup_routes = codec->scenegraph->Routes;
     856          40 :         backup_root = codec->scenegraph->RootNode;
     857          40 :         com = gf_sg_command_new(codec->current_graph, GF_SG_SCENE_REPLACE);
     858          40 :         codec->scenegraph->Routes = gf_list_new();
     859          40 :         codec->current_graph = codec->scenegraph;
     860          40 :         codec->LastError = BD_DecSceneReplace(codec, bs, com->new_proto_list);
     861          40 :         com->use_names = codec->UseName;
     862             : 
     863             :         /*restore*/
     864          40 :         com->node = codec->scenegraph->RootNode;
     865          40 :         codec->scenegraph->RootNode = backup_root;
     866          40 :         gf_list_add(com_list, com);
     867             :         /*insert routes*/
     868         152 :         while (gf_list_count(codec->scenegraph->Routes)) {
     869          72 :                 GF_Route *r = (GF_Route*)gf_list_get(codec->scenegraph->Routes, 0);
     870          72 :                 GF_Command *ri = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_INSERT);
     871          72 :                 gf_list_rem(codec->scenegraph->Routes, 0);
     872          72 :                 ri->fromFieldIndex = r->FromField.fieldIndex;
     873          72 :                 ri->fromNodeID = gf_node_get_id(r->FromNode);
     874          72 :                 ri->toFieldIndex = r->ToField.fieldIndex;
     875          72 :                 ri->toNodeID = gf_node_get_id(r->ToNode);
     876          72 :                 if (r->ID) ri->RouteID = r->ID;
     877          72 :                 ri->def_name = r->name ? gf_strdup(r->name) : NULL;
     878          72 :                 gf_list_add(com_list, ri);
     879          72 :                 gf_sg_route_del(r);
     880             :         }
     881          40 :         gf_list_del(codec->scenegraph->Routes);
     882          40 :         codec->scenegraph->Routes = backup_routes;
     883          40 :         return codec->LastError;
     884             : }
     885             : 
     886             : 
     887         270 : GF_Err BM_ParseCommand(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
     888             : {
     889             :         u8 go, type;
     890             :         GF_Err e;
     891             :         go = 1;
     892             :         e = GF_OK;
     893             : 
     894         270 :         codec->LastError = GF_OK;
     895        1128 :         while (go) {
     896         592 :                 type = gf_bs_read_int(bs, 2);
     897         592 :                 switch (type) {
     898         200 :                 case 0:
     899         200 :                         e = BM_ParseInsert(codec, bs, com_list);
     900         200 :                         break;
     901          36 :                 case 1:
     902          36 :                         e = BM_ParseDelete(codec, bs, com_list);
     903          36 :                         break;
     904         316 :                 case 2:
     905         316 :                         e = BM_ParseReplace(codec, bs, com_list);
     906         316 :                         break;
     907          40 :                 case 3:
     908          40 :                         e = BM_SceneReplace(codec, bs, com_list);
     909          40 :                         break;
     910             :                 }
     911         592 :                 if (e) return e;
     912         588 :                 go = gf_bs_read_int(bs, 1);
     913             :         }
     914         266 :         while (gf_list_count(codec->QPs)) {
     915           0 :                 gf_bifs_dec_qp_remove(codec, GF_TRUE);
     916             :         }
     917             :         return GF_OK;
     918             : }
     919             : 
     920          16 : void BM_EndOfStream(void *co)
     921             : {
     922          16 :         ((GF_BifsDecoder *) co)->LastError = GF_IO_ERR;
     923          16 : }
     924             : 
     925             : void gf_bs_set_eos_callback(GF_BitStream *bs, void (*EndOfStream)(void *par), void *par);
     926             : 
     927             : 
     928         727 : GF_Err gf_bifs_flush_command_list(GF_BifsDecoder *codec)
     929             : {
     930             :         GF_BitStream *bs;
     931             :         GF_Err e;
     932             :         CommandBufferItem *cbi;
     933         727 :         u32 NbPass = gf_list_count(codec->command_buffers);
     934         727 :         GF_List *nextPass = gf_list_new();
     935        1458 :         while (NbPass) {
     936         125 :                 while (gf_list_count(codec->command_buffers)) {
     937          86 :                         cbi = (CommandBufferItem *)gf_list_get(codec->command_buffers, 0);
     938          86 :                         gf_list_rem(codec->command_buffers, 0);
     939          86 :                         codec->current_graph = gf_node_get_graph(cbi->node);
     940             :                         e = GF_OK;
     941          86 :                         if (cbi->cb->bufferSize) {
     942          86 :                                 bs = gf_bs_new((char*)cbi->cb->buffer, cbi->cb->bufferSize, GF_BITSTREAM_READ);
     943          86 :                                 gf_bs_set_eos_callback(bs, BM_EndOfStream, codec);
     944          86 :                                 e = BM_ParseCommand(codec, bs, cbi->cb->commandList);
     945          86 :                                 gf_bs_del(bs);
     946             :                         }
     947          86 :                         if (!e) {
     948          82 :                                 gf_free(cbi);
     949          82 :                                 continue;
     950             :                         }
     951             :                         /*this may be an error or a dependency pb - reset coimmand list and move to next pass*/
     952           8 :                         while (gf_list_count(cbi->cb->commandList)) {
     953             :                                 u32 i;
     954             :                                 GF_CommandField *cf;
     955           4 :                                 GF_Command *com = (GF_Command *)gf_list_get(cbi->cb->commandList, 0);
     956           4 :                                 gf_list_rem(cbi->cb->commandList, 0);
     957           4 :                                 cf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
     958           4 :                                 if (cf && cf->fieldType==GF_SG_VRML_SFCOMMANDBUFFER) {
     959           0 :                                         for (i=0; i<gf_list_count(codec->command_buffers); i++) {
     960           0 :                                                 CommandBufferItem *cbi2 = (CommandBufferItem *)gf_list_get(codec->command_buffers, i);
     961           0 :                                                 if (cbi2->cb == cf->field_ptr) {
     962           0 :                                                         gf_free(cbi2);
     963           0 :                                                         gf_list_rem(codec->command_buffers, i);
     964           0 :                                                         i--;
     965             :                                                 }
     966             :                                         }
     967             :                                 }
     968           4 :                                 gf_sg_command_del(com);
     969             :                         }
     970           4 :                         gf_list_add(nextPass, cbi);
     971             :                 }
     972          39 :                 if (!gf_list_count(nextPass)) break;
     973             :                 /*prepare next pass*/
     974           8 :                 while (gf_list_count(nextPass)) {
     975           4 :                         cbi = (CommandBufferItem *)gf_list_get(nextPass, 0);
     976           4 :                         gf_list_rem(nextPass, 0);
     977           4 :                         gf_list_add(codec->command_buffers, cbi);
     978             :                 }
     979           4 :                 NbPass --;
     980           4 :                 if (NbPass > gf_list_count(codec->command_buffers)) NbPass = gf_list_count(codec->command_buffers);
     981           4 :                 codec->LastError = GF_OK;
     982             :         }
     983         727 :         gf_list_del(nextPass);
     984         727 :         return GF_OK;
     985             : }
     986             : 
     987             : GF_EXPORT
     988         184 : GF_Err gf_bifs_decode_command_list(GF_BifsDecoder *codec, u16 ESID, u8 *data, u32 data_length, GF_List *com_list)
     989             : {
     990             :         GF_BitStream *bs;
     991             :         GF_Err e;
     992             : 
     993         184 :         if (!codec || !data || !codec->dec_memory_mode || !com_list) return GF_BAD_PARAM;
     994             : 
     995         184 :         codec->info = gf_bifs_dec_get_stream(codec, ESID);
     996         184 :         if (!codec->info) return GF_BAD_PARAM;
     997         184 :         if (codec->info->config.elementaryMasks ) return GF_NOT_SUPPORTED;
     998             : 
     999             :         /*root parse (not conditionals)*/
    1000             :         assert(codec->scenegraph);
    1001             :         /*setup current scene graph*/
    1002         184 :         codec->current_graph = codec->scenegraph;
    1003             : 
    1004         184 :         codec->ActiveQP = (M_QuantizationParameter*) codec->scenegraph->global_qp;
    1005             : 
    1006         184 :         bs = gf_bs_new(data, data_length, GF_BITSTREAM_READ);
    1007         184 :         gf_bs_set_eos_callback(bs, BM_EndOfStream, codec);
    1008             : 
    1009         184 :         e = BM_ParseCommand(codec, bs, com_list);
    1010         184 :         gf_bs_del(bs);
    1011             : 
    1012             :         /*decode conditionals / input sensors*/
    1013         184 :         if (!e) {
    1014         184 :                 gf_bifs_flush_command_list(codec);
    1015             :         }
    1016             :         /*if err or not reset conditionals*/
    1017         184 :         while (gf_list_count(codec->command_buffers)) {
    1018           0 :                 CommandBufferItem *cbi = (CommandBufferItem *)gf_list_get(codec->command_buffers, 0);
    1019           0 :                 gf_free(cbi);
    1020           0 :                 gf_list_rem(codec->command_buffers, 0);
    1021             :         }
    1022             : 
    1023             :         /*reset current config*/
    1024         184 :         codec->info = NULL;
    1025         184 :         codec->current_graph = NULL;
    1026             : 
    1027             : 
    1028             : 
    1029             : //      gf_mx_v(codec->mx);
    1030         184 :         return e;
    1031             : }
    1032             : 
    1033             : #endif /*GPAC_DISABLE_BIFS*/
    1034             : 

Generated by: LCOV version 1.13