This source file includes following definitions.
- gf_bifs_dec_name
- BD_XReplace
- BD_DecProtoDelete
- BD_DecMultipleIndexReplace
- BD_DecMultipleReplace
- BD_DecGlobalQuantizer
- BD_DecNodeDeleteEx
- BD_DecOperandReplace
- BD_DecExtendedUpdate
- BD_DecNodeInsert
- BD_DecIndexInsert
- BD_DecInsert
- BD_DecIndexDelete
- BD_DecDelete
- BD_DecNodeReplace
- BD_DecFieldReplace
- BD_DecIndexValueReplace
- BD_DecRouteReplace
- BD_DecReplace
- gf_bifs_dec_proto_list
- gf_bifs_dec_route
- BD_DecSceneReplace
- gf_bifs_dec_command
#include <gpac/maths.h>
#include <gpac/internal/bifs_dev.h>
#include "quant.h"
#ifndef GPAC_DISABLE_BIFS
GF_Err BD_DecMFFieldList(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field);
GF_Err BD_DecMFFieldVec(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field);
void gf_bifs_dec_name(GF_BitStream *bs, char *name)
{
u32 i = 0;
while (1) {
name[i] = gf_bs_read_int(bs, 8);
if (!name[i]) break;
i++;
}
}
static GF_Err BD_XReplace(GF_BifsDecoder * codec, GF_BitStream *bs)
{
GF_FieldInfo targetField, fromField;
GF_Node *target, *n, *fromNode;
s32 pos = -2;
void *slot_ptr;
u32 id, nbBits, ind, aind;
GF_Err e;
id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
target = gf_sg_find_node(codec->current_graph, id);
if (!target) return GF_SG_UNKNOWN_NODE;
nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1);
ind = gf_bs_read_int(bs, nbBits);
e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind);
if (e) return e;
e = gf_node_get_field(target, aind, &targetField);
if (e) return e;
if (!gf_sg_vrml_is_sf_field(targetField.fieldType)) {
if (gf_bs_read_int(bs, 1)) {
if (gf_bs_read_int(bs, 1)) {
id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
n = gf_sg_find_node(codec->current_graph, id);
if (!n) return GF_SG_UNKNOWN_NODE;
nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1);
ind = gf_bs_read_int(bs, nbBits);
e = gf_bifs_get_field_index(n, ind, GF_SG_FIELD_CODING_DEF, &aind);
if (e) return e;
e = gf_node_get_field(n, aind, &fromField);
if (e) return e;
pos = 0;
switch (fromField.fieldType) {
case GF_SG_VRML_SFBOOL:
if (*(SFBool*)fromField.far_ptr) pos = 1;
break;
case GF_SG_VRML_SFINT32:
if (*(SFInt32*)fromField.far_ptr >=0) pos = *(SFInt32*)fromField.far_ptr;
break;
case GF_SG_VRML_SFFLOAT:
if ( (*(SFFloat *)fromField.far_ptr) >=0) pos = (s32) floor( FIX2FLT(*(SFFloat*)fromField.far_ptr) );
break;
case GF_SG_VRML_SFTIME:
if ( (*(SFTime *)fromField.far_ptr) >=0) pos = (s32) floor( (*(SFTime *)fromField.far_ptr) );
break;
}
} else {
u32 type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
pos = gf_bs_read_int(bs, 16);
break;
case 2:
pos = 0;
break;
case 3:
pos = -1;
break;
}
}
}
if (targetField.fieldType==GF_SG_VRML_MFNODE) {
if (gf_bs_read_int(bs, 1)) {
target = gf_node_list_get_child(*(GF_ChildNodeItem **)targetField.far_ptr, pos);
if (!target) return GF_SG_UNKNOWN_NODE;
nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1);
ind = gf_bs_read_int(bs, nbBits);
e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind);
if (e) return e;
e = gf_node_get_field(target, aind, &targetField);
if (e) return e;
pos = -2;
}
}
}
fromNode = NULL;
if (gf_bs_read_int(bs, 1)) {
id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
fromNode = gf_sg_find_node(codec->current_graph, id);
if (!fromNode) return GF_SG_UNKNOWN_NODE;
nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(fromNode, GF_SG_FIELD_CODING_DEF)-1);
ind = gf_bs_read_int(bs, nbBits);
e = gf_bifs_get_field_index(fromNode, ind, GF_SG_FIELD_CODING_DEF, &aind);
if (e) return e;
e = gf_node_get_field(fromNode, aind, &fromField);
if (e) return e;
}
if (pos>=-1) {
if (targetField.fieldType == GF_SG_VRML_MFNODE) {
GF_Node *newnode;
if (fromNode) {
newnode = *(GF_Node**)fromField.far_ptr;
} else {
newnode = gf_bifs_dec_node(codec, bs, targetField.NDTtype);
}
gf_node_replace_child(target, (GF_ChildNodeItem**) targetField.far_ptr, pos, newnode);
if (newnode) gf_node_register(newnode, NULL);
}
else {
u32 sftype;
if ((pos < 0) || ((u32) pos >= ((GenMFField *) targetField.far_ptr)->count) ) {
pos = ((GenMFField *)targetField.far_ptr)->count - 1;
if (pos < 0) {
pos = 0;
gf_sg_vrml_mf_alloc(targetField.far_ptr, targetField.fieldType, 1);
}
}
e = gf_sg_vrml_mf_get_item(targetField.far_ptr, targetField.fieldType, & slot_ptr, pos);
if (e) return e;
sftype = gf_sg_vrml_get_sf_type(targetField.fieldType);
if (fromNode) {
if (sftype==fromField.fieldType)
gf_sg_vrml_field_copy(slot_ptr, fromField.far_ptr, sftype);
} else {
GF_FieldInfo sffield;
memcpy(&sffield, &targetField, sizeof(GF_FieldInfo));
sffield.fieldType = sftype;
sffield.far_ptr = slot_ptr;
gf_bifs_dec_sf_field(codec, bs, target, &sffield, GF_FALSE);
}
}
gf_bifs_check_field_change(target, &targetField);
return GF_OK;
}
switch (targetField.fieldType) {
case GF_SG_VRML_SFNODE:
{
GF_Node *newnode;
if (fromNode) {
newnode = *(GF_Node**)fromField.far_ptr;
} else {
newnode = gf_bifs_dec_node(codec, bs, targetField.NDTtype);
}
n = *((GF_Node **) targetField.far_ptr);
*((GF_Node **) targetField.far_ptr) = newnode;
if (newnode) gf_node_register(newnode, target);
if (n) gf_node_unregister(n, target);
break;
}
case GF_SG_VRML_MFNODE:
{
GF_ChildNodeItem *previous = * (GF_ChildNodeItem **) targetField.far_ptr;
* ((GF_ChildNodeItem **) targetField.far_ptr) = NULL;
if (fromNode) {
GF_ChildNodeItem *list, *prev, *cur;
list = * ((GF_ChildNodeItem **) targetField.far_ptr);
prev=NULL;
while (list) {
cur = (GF_ChildNodeItem*)gf_malloc(sizeof(GF_ChildNodeItem));
cur->next = NULL;
cur->node = list->node;
if (prev) {
prev->next = cur;
} else {
* ((GF_ChildNodeItem **) targetField.far_ptr) = cur;
}
gf_node_register(list->node, target);
prev = cur;
list = list->next;
}
} else {
e = gf_bifs_dec_field(codec, bs, target, &targetField, GF_FALSE);
if (e) return e;
}
if (previous)
gf_node_unregister_children(target, previous);
break;
}
default:
if (!gf_sg_vrml_is_sf_field(targetField.fieldType)) {
e = gf_sg_vrml_mf_reset(targetField.far_ptr, targetField.fieldType);
}
if (e) return e;
if (fromNode) {
if (fromField.fieldType == targetField.fieldType)
gf_sg_vrml_field_clone(targetField.far_ptr, fromField.far_ptr, targetField.fieldType, codec->current_graph);
} else {
e = gf_bifs_dec_field(codec, bs, target, &targetField, GF_FALSE);
}
break;
}
gf_bifs_check_field_change(target, &targetField);
return e;
}
static GF_Err BD_DecProtoDelete(GF_BifsDecoder * codec, GF_BitStream *bs)
{
u32 ID, flag, count;
GF_Proto *proto;
flag = gf_bs_read_int(bs, 1);
if (flag) {
flag = gf_bs_read_int(bs, 1);
while (flag) {
ID = gf_bs_read_int(bs, codec->info->config.ProtoIDBits);
proto = gf_sg_find_proto(codec->current_graph, ID, NULL);
if (proto) gf_sg_proto_del(proto);
flag = gf_bs_read_int(bs, 1);
}
} else {
flag = gf_bs_read_int(bs, 5);
count = gf_bs_read_int(bs, flag);
while (count) {
ID = gf_bs_read_int(bs, codec->info->config.ProtoIDBits);
proto = gf_sg_find_proto(codec->current_graph, ID, NULL);
if (proto) gf_sg_proto_del(proto);
count--;
}
}
return GF_OK;
}
static GF_Err BD_DecMultipleIndexReplace(GF_BifsDecoder * codec, GF_BitStream *bs)
{
u32 ID, ind, field_ind, NumBits, lenpos, lennum, count, pos;
GF_Node *node, *new_node;
GF_Err e;
GF_FieldInfo field, sffield;
ID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
node = gf_sg_find_node(codec->current_graph, ID);
if (!node) return GF_NON_COMPLIANT_BITSTREAM;
NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
ind = gf_bs_read_int(bs, NumBits);
e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
if (e) return e;
e = gf_node_get_field(node, field_ind, &field);
if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
lenpos = gf_bs_read_int(bs, 5);
lennum = gf_bs_read_int(bs, 5);
count = gf_bs_read_int(bs, lennum);
if (field.fieldType == GF_SG_VRML_MFNODE) {
while (count) {
pos = gf_bs_read_int(bs, lenpos);
new_node = gf_bifs_dec_node(codec, bs, field.NDTtype);
if (!new_node) return codec->LastError;
e = gf_node_register(new_node, node);
if (e) return e;
e = gf_node_replace_child(node, (GF_ChildNodeItem**) field.far_ptr, pos, new_node);
count--;
}
if (!e) gf_bifs_check_field_change(node, &field);
return e;
}
memcpy(&sffield, &field, sizeof(GF_FieldInfo));
sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
while (count) {
pos = gf_bs_read_int(bs, lenpos);
if (pos && pos >= ((GenMFField *)field.far_ptr)->count) {
pos = ((GenMFField *)field.far_ptr)->count - 1;
}
e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & sffield.far_ptr, pos);
if (e) return e;
e = gf_bifs_dec_sf_field(codec, bs, node, &sffield, GF_FALSE);
if (e) break;
count--;
}
if (!e) gf_bifs_check_field_change(node, &field);
return e;
}
static GF_Err BD_DecMultipleReplace(GF_BifsDecoder * codec, GF_BitStream *bs)
{
GF_Err e;
u32 NodeID, flag;
GF_Node *node;
NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
node = gf_sg_find_node(codec->current_graph, NodeID);
if (!node) return GF_NON_COMPLIANT_BITSTREAM;
flag = gf_bs_read_int(bs, 1);
if (flag) {
e = gf_bifs_dec_node_mask(codec, bs, node, GF_FALSE);
} else {
e = gf_bifs_dec_node_list(codec, bs, node, GF_FALSE);
}
return e;
}
static GF_Err BD_DecGlobalQuantizer(GF_BifsDecoder * codec, GF_BitStream *bs)
{
GF_Node *node;
node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode);
if (codec->scenegraph->global_qp) {
gf_node_unregister(codec->scenegraph->global_qp, NULL);
codec->scenegraph->global_qp = NULL;
}
codec->ActiveQP = NULL;
if (!node || (gf_node_get_tag(node) != TAG_MPEG4_QuantizationParameter)) {
if (node) gf_node_unregister(node, NULL);
return codec->LastError;
}
codec->scenegraph->global_qp = node;
gf_node_register(node, NULL);
codec->ActiveQP = (M_QuantizationParameter *) node;
codec->ActiveQP->isLocal = 0;
return GF_OK;
}
static GF_Err BD_DecNodeDeleteEx(GF_BifsDecoder * codec, GF_BitStream *bs)
{
u32 NodeID;
GF_Node *node;
NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
node = gf_sg_find_node(codec->current_graph, NodeID);
if (!node) return GF_NON_COMPLIANT_BITSTREAM;
return gf_node_replace(node, NULL, GF_TRUE);
}
#ifdef GPAC_UNUSED_FUNC
static GF_Err BD_DecOperandReplace(GF_BifsDecoder * codec, GF_BitStream *bs)
{
s32 pos;
GF_FieldInfo field;
GF_FieldInfo src_field;
GF_Err e;
u32 NodeID, NumBits, ind, field_ind, type, src_type, dst_type;
GF_Node *node, *src;
void *src_ptr, *dst_ptr;
NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
node = gf_sg_find_node(codec->current_graph, NodeID);
if (!node) return GF_NON_COMPLIANT_BITSTREAM;
NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
ind = gf_bs_read_int(bs, NumBits);
e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
if (e) return e;
e = gf_node_get_field(node, field_ind, &field);
if (e) return e;
dst_type = field.fieldType;
dst_ptr = field.far_ptr;
pos = -2;
if (! gf_sg_vrml_is_sf_field(field.fieldType)) {
type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
break;
case 1:
pos = gf_bs_read_int(bs, 8);
break;
case 2:
pos = 0;
break;
case 3:
pos = ((GenMFField *)field.far_ptr)->count;
if (!pos)
return GF_NON_COMPLIANT_BITSTREAM;
pos -= 1;
break;
default:
return GF_NON_COMPLIANT_BITSTREAM;
}
if (pos>-2) {
dst_type = gf_sg_vrml_get_sf_type(field.fieldType);
e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &dst_ptr, pos);
if (e) return e;
}
}
NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
src = gf_sg_find_node(codec->current_graph, NodeID);
if (!src) return GF_NON_COMPLIANT_BITSTREAM;
NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(src, GF_SG_FIELD_CODING_IN)-1);
ind = gf_bs_read_int(bs, NumBits);
e = gf_bifs_get_field_index(src, ind, GF_SG_FIELD_CODING_IN, &field_ind);
if (e) return e;
e = gf_node_get_field(src, field_ind, &src_field);
if (e) return e;
src_type = src_field.fieldType;
src_ptr = src_field.far_ptr;
pos = -2;
if (! gf_sg_vrml_is_sf_field(src_field.fieldType)) {
type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
break;
case 1:
pos = gf_bs_read_int(bs, 8);
break;
case 2:
pos = 0;
break;
case 3:
pos = ((GenMFField *)src_field.far_ptr)->count;
if (!pos)
return GF_NON_COMPLIANT_BITSTREAM;
pos -= 1;
break;
default:
return GF_NON_COMPLIANT_BITSTREAM;
}
if (pos>-2) {
src_type = gf_sg_vrml_get_sf_type(src_field.fieldType);
e = gf_sg_vrml_mf_get_item(src_field.far_ptr, src_field.fieldType, &src_ptr, pos);
if (e) return e;
}
}
if (src_type!=dst_type) return GF_NON_COMPLIANT_BITSTREAM;
gf_sg_vrml_field_copy(dst_ptr, src_ptr, src_type);
return GF_OK;
}
#endif
static GF_Err BD_DecExtendedUpdate(GF_BifsDecoder * codec, GF_BitStream *bs)
{
u32 type;
type = gf_bs_read_int(bs, 8);
switch (type) {
case 0:
return gf_bifs_dec_proto_list(codec, bs, NULL);
case 1:
return BD_DecProtoDelete(codec, bs);
case 2:
return gf_sg_delete_all_protos(codec->current_graph);
case 3:
return BD_DecMultipleIndexReplace(codec, bs);
case 4:
return BD_DecMultipleReplace(codec, bs);
case 5:
return BD_DecGlobalQuantizer(codec, bs);
case 6:
return BD_DecNodeDeleteEx(codec, bs);
case 7:
return BD_XReplace(codec, bs);
default:
return GF_BIFS_UNKNOWN_VERSION;
}
}
static GF_Err BD_DecNodeInsert(GF_BifsDecoder * codec, GF_BitStream *bs)
{
u32 NodeID, NDT;
s32 type, pos;
GF_Node *node, *def;
GF_Err e;
NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
def = gf_sg_find_node(codec->current_graph, NodeID);
if (!def) return GF_NON_COMPLIANT_BITSTREAM;
NDT = gf_bifs_get_child_table(def);
if (!NDT) return GF_NON_COMPLIANT_BITSTREAM;
type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
pos = gf_bs_read_int(bs, 8);
break;
case 2:
pos = 0;
break;
case 3:
pos = -1;
break;
default:
return GF_NON_COMPLIANT_BITSTREAM;
}
node = gf_bifs_dec_node(codec, bs, NDT);
if (!node) return codec->LastError;
e = gf_node_register(node, def);
if (e) return e;
e = gf_node_insert_child(def, node, pos);
if (!e) {
GF_FieldInfo field;
e = gf_node_get_field_by_name(def, "children", &field);
if (e) return e;
gf_bifs_check_field_change(def, &field);
}
return e;
}
static GF_Err BD_DecIndexInsert(GF_BifsDecoder * codec, GF_BitStream *bs)
{
GF_Err e;
u32 NodeID;
u32 NumBits, ind, field_ind;
u8 type;
s32 pos;
GF_Node *def, *node;
GF_FieldInfo field, sffield;
NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
def = gf_sg_find_node(codec->current_graph, NodeID);
if (!def) return GF_NON_COMPLIANT_BITSTREAM;
NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(def, GF_SG_FIELD_CODING_IN)-1);
ind = gf_bs_read_int(bs, NumBits);
e = gf_bifs_get_field_index(def, ind, GF_SG_FIELD_CODING_IN, &field_ind);
if (e) return e;
type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
pos = gf_bs_read_int(bs, 16);
break;
case 2:
pos = 0;
break;
case 3:
pos = -1;
break;
default:
return GF_NON_COMPLIANT_BITSTREAM;
}
e = gf_node_get_field(def, field_ind, &field);
if (e) return e;
if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
memcpy(&sffield, &field, sizeof(GF_FieldInfo));
sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
if (field.fieldType==GF_SG_VRML_MFNODE) {
node = gf_bifs_dec_node(codec, bs, field.NDTtype);
if (!node) return codec->LastError;
e = gf_node_register(node, def);
if (e) return e;
if (pos== -1) {
e = gf_node_list_add_child( (GF_ChildNodeItem **) field.far_ptr, node);
} else {
e = gf_node_list_insert_child((GF_ChildNodeItem **) field.far_ptr, node, pos);
}
if (!e) gf_bifs_check_field_change(def, &field);
} else {
if (pos == -1) {
e = gf_sg_vrml_mf_append(field.far_ptr, field.fieldType, & sffield.far_ptr);
} else {
e = gf_sg_vrml_mf_insert(field.far_ptr, field.fieldType, & sffield.far_ptr, pos);
}
if (e) return e;
e = gf_bifs_dec_sf_field(codec, bs, def, &sffield, GF_FALSE);
if (!e) gf_bifs_check_field_change(def, &field);
}
return e;
}
static GF_Err BD_DecInsert(GF_BifsDecoder * codec, GF_BitStream *bs)
{
u8 type;
type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
return BD_DecNodeInsert(codec, bs);
case 1:
return BD_DecExtendedUpdate(codec, bs);
case 2:
return BD_DecIndexInsert(codec, bs);
case 3:
return gf_bifs_dec_route(codec, bs, GF_TRUE);
default:
return GF_NON_COMPLIANT_BITSTREAM;
}
}
static GF_Err BD_DecIndexDelete(GF_BifsDecoder * codec, GF_BitStream *bs)
{
u32 NodeID, NumBits, SF_type, ind, field_ind;
s32 pos;
u8 type;
GF_Node *node;
GF_Err e;
GF_FieldInfo field;
NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
node = gf_sg_find_node(codec->current_graph, NodeID);
if (!node) return GF_NON_COMPLIANT_BITSTREAM;
NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN) - 1);
ind = gf_bs_read_int(bs, NumBits);
type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
pos = (u32) gf_bs_read_int(bs, 16);
break;
case 2:
pos = 0;
break;
case 3:
pos = -1;
break;
default:
return GF_NON_COMPLIANT_BITSTREAM;
}
e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
if (e) return e;
e = gf_node_get_field(node, field_ind, &field);
if (e) return e;
if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
SF_type = gf_sg_vrml_get_sf_type(field.fieldType);
if (SF_type == GF_SG_VRML_SFNODE) {
GF_ChildNodeItem** nlist_ptr = (GF_ChildNodeItem**) field.far_ptr;
if (*nlist_ptr) {
e = gf_node_replace_child(node, nlist_ptr, pos, NULL);
}
} else {
e = gf_sg_vrml_mf_remove(field.far_ptr, field.fieldType, pos);
}
if (!e) gf_bifs_check_field_change(node, &field);
return e;
}
static GF_Err BD_DecDelete(GF_BifsDecoder * codec, GF_BitStream *bs)
{
u8 type;
u32 ID;
GF_Node *n;
type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
ID = 1+gf_bs_read_int(bs, codec->info->config.NodeIDBits);
n = gf_sg_find_node(codec->current_graph, ID);
#ifdef MPEG4_STRICT
if (!n) return GF_NON_COMPLIANT_BITSTREAM;
#else
if (!n) return GF_OK;
#endif
return gf_node_replace(n, NULL, GF_FALSE);
case 2:
return BD_DecIndexDelete(codec, bs);
case 3:
ID = 1+gf_bs_read_int(bs, codec->info->config.RouteIDBits);
gf_sg_route_del_by_id(codec->current_graph, ID);
return GF_OK;
default:
return GF_NON_COMPLIANT_BITSTREAM;
}
return GF_OK;
}
static GF_Err BD_DecNodeReplace(GF_BifsDecoder * codec, GF_BitStream *bs)
{
u32 NodeID;
GF_Node *node, *new_node;
GF_Err e;
NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
node = gf_sg_find_node(codec->current_graph, NodeID);
if (!node) return GF_NON_COMPLIANT_BITSTREAM;
new_node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode);
if (!new_node && codec->LastError) return codec->LastError;
e = gf_node_replace(node, new_node, GF_FALSE);
return e;
}
static GF_Err BD_DecFieldReplace(GF_BifsDecoder * codec, GF_BitStream *bs)
{
GF_Err e;
u32 NodeID, ind, field_ind, NumBits;
GF_Node *node, *prev_node;
GF_ChildNodeItem *prev_child;
GF_FieldInfo field;
NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
node = gf_sg_find_node(codec->current_graph, NodeID);
if (!node) return GF_NON_COMPLIANT_BITSTREAM;
NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
ind = gf_bs_read_int(bs, NumBits);
e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
if (e) return e;
e = gf_node_get_field(node, field_ind, &field);
if (e) return e;
prev_node = NULL;
prev_child = NULL;
if (field.fieldType == GF_SG_VRML_SFNODE) {
prev_node = *((GF_Node **) field.far_ptr);
}
else if (field.fieldType == GF_SG_VRML_MFNODE) {
prev_child = * ((GF_ChildNodeItem **) field.far_ptr);
* ((GF_ChildNodeItem **) field.far_ptr) = NULL;
}
else if (!gf_sg_vrml_is_sf_field(field.fieldType)) {
gf_sg_vrml_mf_reset(field.far_ptr, field.fieldType);
}
codec->is_com_dec = GF_TRUE;
e = gf_bifs_dec_field(codec, bs, node, &field, GF_FALSE);
codec->is_com_dec = GF_FALSE;
if (field.fieldType == GF_SG_VRML_SFNODE) {
if (prev_node) e = gf_node_unregister(prev_node, node);
} else if (field.fieldType == GF_SG_VRML_MFNODE) {
gf_node_unregister_children(node, prev_child);
}
if (!e) gf_bifs_check_field_change(node, &field);
return e;
}
static GF_Err BD_DecIndexValueReplace(GF_BifsDecoder * codec, GF_BitStream *bs)
{
GF_Node *new_node;
u32 NodeID, ind, field_ind, NumBits, pos;
u8 type;
GF_Node *node;
GF_Err e;
GF_FieldInfo field, sffield;
NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
node = gf_sg_find_node(codec->current_graph, NodeID);
if (!node) return GF_NON_COMPLIANT_BITSTREAM;
NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
ind = gf_bs_read_int(bs, NumBits);
e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
if (e) return e;
e = gf_node_get_field(node, field_ind, &field);
if (e) return e;
if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
pos = gf_bs_read_int(bs, 16);
break;
case 2:
pos = 0;
break;
case 3:
pos = ((GenMFField *) field.far_ptr)->count - 1;
break;
default:
return GF_NON_COMPLIANT_BITSTREAM;
}
if (field.fieldType == GF_SG_VRML_MFNODE) {
new_node = gf_bifs_dec_node(codec, bs, field.NDTtype);
if (codec->LastError) {
e = codec->LastError;
goto exit;
}
if (new_node) {
e = gf_node_register(new_node, node);
if (e) return e;
}
e = gf_node_replace_child(node, (GF_ChildNodeItem**) field.far_ptr, pos, new_node);
if (!e) gf_bifs_check_field_change(node, &field);
}
else {
memcpy(&sffield, &field, sizeof(GF_FieldInfo));
sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
if (pos && pos >= ((GenMFField *)field.far_ptr)->count) {
pos = ((GenMFField *)field.far_ptr)->count - 1;
}
e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & sffield.far_ptr, pos);
if (e) return e;
e = gf_bifs_dec_sf_field(codec, bs, node, &sffield, GF_FALSE);
if (!e) gf_bifs_check_field_change(node, &field);
}
exit:
return e;
}
static GF_Err BD_DecRouteReplace(GF_BifsDecoder * codec, GF_BitStream *bs)
{
GF_Err e;
u32 RouteID, numBits, ind, node_id, fromID, toID;
char name[1000], *ptr;
GF_Route *r;
GF_Node *OutNode, *InNode;
RouteID = 1+gf_bs_read_int(bs, codec->info->config.RouteIDBits);
r = gf_sg_route_find(codec->current_graph, RouteID);
#ifdef MPEG4_STRICT
if (!r) return GF_NON_COMPLIANT_BITSTREAM;
ptr = gf_sg_route_get_name(r);
gf_sg_route_del(r);
#else
ptr = NULL;
if (r) {
ptr = gf_sg_route_get_name(r);
}
#endif
if (ptr) strcpy(name, ptr);
node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
OutNode = gf_sg_find_node(codec->current_graph, node_id);
if (!OutNode) return GF_NON_COMPLIANT_BITSTREAM;
numBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(OutNode, GF_SG_FIELD_CODING_OUT) - 1);
ind = gf_bs_read_int(bs, numBits);
e = gf_bifs_get_field_index(OutNode, ind, GF_SG_FIELD_CODING_OUT, &fromID);
if (e) return e;
node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
InNode = gf_sg_find_node(codec->current_graph, node_id);
if (!InNode) return GF_NON_COMPLIANT_BITSTREAM;
numBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(InNode, GF_SG_FIELD_CODING_IN) - 1);
ind = gf_bs_read_int(bs, numBits);
e = gf_bifs_get_field_index(InNode, ind, GF_SG_FIELD_CODING_IN, &toID);
if (e) return e;
if (r) {
if (r->FromNode->sgprivate->interact)
gf_list_del_item(r->FromNode->sgprivate->interact->routes, r);
r->is_setup = 0;
r->lastActivateTime = 0;
r->FromNode = OutNode;
r->FromField.fieldIndex = fromID;
r->ToNode = InNode;
r->ToField.fieldIndex = toID;
if (!r->FromNode->sgprivate->interact) {
GF_SAFEALLOC(r->FromNode->sgprivate->interact, struct _node_interactive_ext);
if (!r->FromNode->sgprivate->interact) return GF_OUT_OF_MEM;
}
if (!r->FromNode->sgprivate->interact->routes) {
r->FromNode->sgprivate->interact->routes = gf_list_new();
if (!r->FromNode->sgprivate->interact->routes) return GF_OUT_OF_MEM;
}
gf_list_add(r->FromNode->sgprivate->interact->routes, r);
} else {
r = gf_sg_route_new(codec->current_graph, OutNode, fromID, InNode, toID);
if (!r) return GF_OUT_OF_MEM;
gf_sg_route_set_id(r, RouteID);
if (ptr) e = gf_sg_route_set_name(r, name);
}
return e;
}
static GF_Err BD_DecReplace(GF_BifsDecoder * codec, GF_BitStream *bs)
{
u8 type;
type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
return BD_DecNodeReplace(codec, bs);
case 1:
return BD_DecFieldReplace(codec, bs);
case 2:
return BD_DecIndexValueReplace(codec, bs);
case 3:
return BD_DecRouteReplace(codec, bs);
}
return GF_OK;
}
GF_Err gf_bifs_dec_proto_list(GF_BifsDecoder * codec, GF_BitStream *bs, GF_List *proto_list)
{
u8 flag, field_type, event_type, useQuant, useAnim, f;
u32 i, NbRoutes, ID, numProtos, numFields, count, qpsftype, QP_Type, NumBits;
GF_Node *node;
char name[1000];
GF_ProtoFieldInterface *proto_field;
GF_Proto *proto, *ParentProto;
GF_Err e;
u32 hasMinMax;
void *qp_min_value, *qp_max_value;
GF_SceneGraph *rootSG;
GF_FieldInfo field;
NumBits = qpsftype = 0;
rootSG = codec->current_graph;
ParentProto = codec->pCurrentProto;
e = GF_OK;
numProtos = 0;
proto = NULL;
flag = gf_bs_read_int(bs, 1);
while (flag) {
if (!codec->info->config.ProtoIDBits) return GF_NON_COMPLIANT_BITSTREAM;
ID = gf_bs_read_int(bs, codec->info->config.ProtoIDBits);
if (codec->UseName) {
gf_bifs_dec_name(bs, name);
} else {
sprintf(name, "Proto%d", numProtos);
}
proto = gf_sg_proto_new(codec->current_graph, ID, name, proto_list ? GF_TRUE : GF_FALSE);
if (proto_list) gf_list_add(proto_list, proto);
codec->current_graph = gf_sg_proto_get_graph(proto);
codec->pCurrentProto = proto;
numFields = 0;
flag = gf_bs_read_int(bs, 1);
while (flag) {
event_type = gf_bs_read_int(bs, 2);
field_type = gf_bs_read_int(bs, 6);
if (codec->UseName) {
gf_bifs_dec_name(bs, name);
} else {
sprintf(name, "_field%d", numFields);
}
proto_field = gf_sg_proto_field_new(proto, field_type, event_type, name);
gf_sg_proto_field_get_field(proto_field, &field);
switch (event_type) {
case GF_SG_EVENT_EXPOSED_FIELD:
case GF_SG_EVENT_FIELD:
if (gf_sg_vrml_is_sf_field(field_type)) {
e = gf_bifs_dec_sf_field(codec, bs, NULL, &field, GF_FALSE);
} else {
if (codec->info->config.UsePredictiveMFField) {
f = gf_bs_read_int(bs, 1);
assert(!f);
}
f = gf_bs_read_int(bs, 1);
if (!f) {
if (gf_bs_read_int(bs, 1)) {
e = BD_DecMFFieldList(codec, bs, NULL, &field);
} else {
e = BD_DecMFFieldVec(codec, bs, NULL, &field);
}
}
}
if (e) goto exit;
break;
}
flag = gf_bs_read_int(bs, 1);
numFields++;
}
flag = gf_bs_read_int(bs, 1);
if (flag) {
memset(&field, 0, sizeof(GF_FieldInfo));
field.far_ptr = gf_sg_proto_get_extern_url(proto);
field.fieldType = GF_SG_VRML_MFURL;
field.name = "ExternProto";
if (codec->info->config.UsePredictiveMFField) {
flag = gf_bs_read_int(bs, 1);
assert(!flag);
}
gf_bs_read_int(bs, 1);
flag = gf_bs_read_int(bs, 1);
if (flag) {
e = BD_DecMFFieldList(codec, bs, NULL, &field);
} else {
e = BD_DecMFFieldVec(codec, bs, NULL, &field);
}
if (e) goto exit;
}
else {
e = gf_bifs_dec_proto_list(codec, bs, NULL);
if (e) goto exit;
flag = 1;
while (flag) {
node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode);
if (!node) {
if (codec->LastError) {
e = codec->LastError;
goto exit;
} else {
flag = gf_bs_read_int(bs, 1);
continue;
}
}
e = gf_node_register(node, NULL);
if (e) goto exit;
gf_bifs_flush_command_list(codec);
gf_sg_proto_add_node_code(proto, node);
flag = gf_bs_read_int(bs, 1);
}
flag = gf_bs_read_int(bs, 1);
if (flag) {
flag = gf_bs_read_int(bs, 1);
if (flag) {
while (flag) {
e = gf_bifs_dec_route(codec, bs, GF_FALSE);
if (e) goto exit;
flag = gf_bs_read_int(bs, 1);
}
} else {
i = gf_bs_read_int(bs, 5);
NbRoutes = gf_bs_read_int(bs, i);
for (i=0; i<NbRoutes; i++) {
e = gf_bifs_dec_route(codec, bs, GF_FALSE);
if (e) goto exit;
}
}
}
}
codec->current_graph = rootSG;
useQuant = gf_bs_read_int(bs, 1);
useAnim = gf_bs_read_int(bs, 1);
count = gf_sg_proto_get_field_count(proto);
for (i=0; i<count; i++) {
proto_field = gf_sg_proto_field_find(proto, i);
gf_sg_proto_field_get_field(proto_field, &field);
if (useQuant && ( (field.eventType == GF_SG_EVENT_FIELD) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) {
QP_Type = gf_bs_read_int(bs, 4);
if (QP_Type==QC_LINEAR_SCALAR) {
NumBits = gf_bs_read_int(bs, 5);
}
hasMinMax = gf_bs_read_int(bs, 1);
qp_min_value = qp_max_value = NULL;
if (hasMinMax) {
qpsftype = gf_sg_vrml_get_sf_type(field.fieldType);
switch (qpsftype) {
case GF_SG_VRML_SFINT32:
case GF_SG_VRML_SFTIME:
break;
default:
qpsftype = GF_SG_VRML_SFFLOAT;
break;
}
field.fieldType = qpsftype;
qp_min_value = gf_sg_vrml_field_pointer_new(qpsftype);
field.name = "QPMinValue";
field.far_ptr = qp_min_value;
gf_bifs_dec_sf_field(codec, bs, NULL, &field, GF_FALSE);
qp_max_value = gf_sg_vrml_field_pointer_new(qpsftype);
field.name = "QPMaxValue";
field.far_ptr = qp_max_value;
gf_bifs_dec_sf_field(codec, bs, NULL, &field, GF_FALSE);
}
if (QP_Type) {
e = gf_bifs_proto_field_set_aq_info(proto_field, QP_Type, hasMinMax, qpsftype, qp_min_value, qp_max_value, NumBits);
gf_sg_vrml_field_pointer_del(qp_min_value, qpsftype);
gf_sg_vrml_field_pointer_del(qp_max_value, qpsftype);
}
}
if (useAnim && ( (field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) {
flag = gf_bs_read_int(bs, 1);
if (flag) {
gf_bs_read_int(bs, 4);
}
}
}
numProtos ++;
flag = gf_bs_read_int(bs, 1);
}
exit:
if (e) {
if (proto) gf_sg_proto_del(proto);
codec->current_graph = rootSG;
}
codec->pCurrentProto = ParentProto;
return e;
}
GF_Err gf_bifs_dec_route(GF_BifsDecoder * codec, GF_BitStream *bs, Bool is_insert)
{
GF_Err e;
u8 flag;
GF_Route *r;
GF_Node *InNode, *OutNode;
u32 RouteID, outField, inField, numBits, ind, node_id;
char name[1000];
RouteID = 0;
flag = gf_bs_read_int(bs, 1);
if (flag) {
RouteID = 1 + gf_bs_read_int(bs, codec->info->config.RouteIDBits);
if (codec->UseName) gf_bifs_dec_name(bs, name);
}
node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
OutNode = gf_sg_find_node(codec->current_graph, node_id);
if (!OutNode) return GF_SG_UNKNOWN_NODE;
numBits = gf_node_get_num_fields_in_mode(OutNode, GF_SG_FIELD_CODING_OUT) - 1;
numBits = gf_get_bit_size(numBits);
ind = gf_bs_read_int(bs, numBits);
e = gf_bifs_get_field_index(OutNode, ind, GF_SG_FIELD_CODING_OUT, &outField);
if (e) return e;
node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
InNode = gf_sg_find_node(codec->current_graph, node_id);
if (!InNode) return GF_SG_UNKNOWN_NODE;
numBits = gf_node_get_num_fields_in_mode(InNode, GF_SG_FIELD_CODING_IN) - 1;
numBits = gf_get_bit_size(numBits);
ind = gf_bs_read_int(bs, numBits);
e = gf_bifs_get_field_index(InNode, ind, GF_SG_FIELD_CODING_IN, &inField);
if (e) return e;
r = gf_sg_route_new(codec->current_graph, OutNode, outField, InNode, inField);
if (!r) return GF_OUT_OF_MEM;
if (RouteID) {
e = gf_sg_route_set_id(r, RouteID);
if (!e && codec->UseName) e = gf_sg_route_set_name(r, name);
}
return e;
}
GF_Err BD_DecSceneReplace(GF_BifsDecoder * codec, GF_BitStream *bs, GF_List *proto_list)
{
u8 flag;
u32 i, nbR;
GF_Err e;
GF_Node *root;
if (!proto_list) gf_sg_reset(codec->current_graph);
gf_bs_read_int(bs, 6);
codec->UseName = (Bool)gf_bs_read_int(bs, 1);
e = gf_bifs_dec_proto_list(codec, bs, proto_list);
if (e) goto exit;
assert(codec->pCurrentProto==NULL);
root = gf_bifs_dec_node(codec, bs, NDT_SFTopNode);
if (!root && codec->LastError) {
e = codec->LastError;
goto exit;
}
if (root) {
e = gf_node_register(root, NULL);
if (e) goto exit;
}
gf_sg_set_root_node(codec->current_graph, root);
flag = gf_bs_read_int(bs, 1);
if (flag) {
flag = gf_bs_read_int(bs, 1);
if (flag) {
while (flag) {
e = gf_bifs_dec_route(codec, bs, GF_FALSE);
if (e) goto exit;
flag = gf_bs_read_int(bs, 1);
}
} else {
i = gf_bs_read_int(bs, 5);
nbR = gf_bs_read_int(bs, i);
for (i=0; i<nbR; i++) {
e = gf_bifs_dec_route(codec, bs, GF_FALSE);
if (e) goto exit;
}
}
}
exit:
return e;
}
GF_Err gf_bifs_dec_command(GF_BifsDecoder * codec, GF_BitStream *bs)
{
GF_Err e;
e = codec->LastError = GF_OK;
codec->ActiveQP = (M_QuantizationParameter*)codec->scenegraph->global_qp;
while (1) {
u8 type = gf_bs_read_int(bs, 2);
switch (type) {
case 0:
e = BD_DecInsert(codec, bs);
break;
case 1:
e = BD_DecDelete(codec, bs);
break;
case 2:
e = BD_DecReplace(codec, bs);
break;
case 3:
e = BD_DecSceneReplace(codec, bs, NULL);
break;
}
if (e) return e;
if (! gf_bs_read_int(bs, 1)) break;
}
while (gf_list_count(codec->QPs)) {
gf_bifs_dec_qp_remove(codec, GF_TRUE);
}
gf_bifs_flush_command_list(codec);
return GF_OK;
}
#endif