GF_EXPORT GF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType) { GenMFField *mffield = (GenMFField *)mf; if (!mffield->array) return GF_OK; //field we can't copy if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; if (!gf_sg_vrml_get_sf_size(FieldType)) return GF_BAD_PARAM; switch (FieldType) { case GF_SG_VRML_MFSTRING: gf_sg_mfstring_del( * ((MFString *) mf)); break; case GF_SG_VRML_MFURL: gf_sg_mfurl_del( * ((MFURL *) mf)); break; case GF_SG_VRML_MFSCRIPT: gf_sg_mfscript_del( * ((MFScript *) mf)); break; default: if (mffield->array) gf_free(mffield->array); break; } mffield->array = NULL; mffield->count = 0; return GF_OK; }
GF_Err BM_ParseIndexValueReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { u32 NodeID, ind, field_ind, NumBits; s32 type, pos; GF_Command *com; GF_Node *node; GF_Err e; GF_FieldInfo field, sffield; GF_CommandField *inf; /*get the 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; 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; 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; } com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_REPLACE); BM_SetCommandNode(com, node); inf = gf_sg_command_field_new(com); inf->fieldIndex = field.fieldIndex; inf->pos = pos; if (field.fieldType == GF_SG_VRML_MFNODE) { inf->fieldType = GF_SG_VRML_SFNODE; inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype); inf->field_ptr = &inf->new_node; if (inf->new_node) gf_node_register(inf->new_node, NULL); } else { memcpy(&sffield, &field, sizeof(GF_FieldInfo)); sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); inf->fieldType = sffield.fieldType; sffield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(sffield.fieldType); codec->LastError = gf_bifs_dec_sf_field(codec, bs, node, &sffield, 1); } gf_list_add(com_list, com); return codec->LastError; }
void gf_storage_save(M_Storage *storage) { char szID[20]; u32 i; GF_Config *cfg = storage_get_cfg(storage); char *section = storage_get_section(storage); if (!cfg || !section) return; gf_cfg_del_section(cfg, section); if (storage->expireAfter) { u32 sec, frac; char szNTP[100]; gf_net_get_ntp(&sec, &frac); sec += storage->expireAfter; sprintf(szNTP, "%u", sec); gf_cfg_set_key(cfg, section, "expireAfterNTP", szNTP); } else { gf_cfg_set_key(cfg, section, "expireAfterNTP", "0"); } for (i=0; i<storage->storageList.count; i++) { char *val; GF_FieldInfo info; sprintf(szID, "%d", i); if (!storage->storageList.vals[i].node) break; if (gf_node_get_field(storage->storageList.vals[i].node, storage->storageList.vals[i].fieldIndex, &info) != GF_OK) break; if (gf_sg_vrml_is_sf_field(info.fieldType)) { val = storage_serialize_sf(info.far_ptr, info.fieldType); } else { //u32 sftype = gf_sg_vrml_get_sf_type(info.fieldType); char *slotval; void *slot; val = NULL; for (i=0; i<((GenMFField *)info.far_ptr)->count; i++) { if (gf_sg_vrml_mf_get_item(info.far_ptr, info.fieldType, &slot, i) != GF_OK) break; slotval = storage_serialize_sf(info.far_ptr, info.fieldType); if (!slotval) break; if (val) { val = gf_realloc(val, strlen(val) + 3 + strlen(slot)); } else { val = gf_malloc(3 + strlen(slot)); val[0] = 0; } strcat(val, "'"); strcat(val, slotval); strcat(val, "'"); gf_free(slot); } } if (val) { gf_cfg_set_key(cfg, section, szID, val); gf_free(val); } } gf_free(section); }
GF_Err gf_bifs_dec_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com) { GF_Err e; u8 flag; // if (codec->LastError) return codec->LastError; assert(node); // if (field->fieldType == GF_SG_VRML_UNKNOWN) return GF_NON_COMPLIANT_BITSTREAM; if (gf_sg_vrml_is_sf_field(field->fieldType)) { e = gf_bifs_dec_sf_field(codec, bs, node, field, is_mem_com); if (e) return e; } else { /*clean up the eventIn field if not done*/ if (field->eventType == GF_SG_EVENT_IN) { if (field->fieldType == GF_SG_VRML_MFNODE) { gf_node_unregister_children(node, * (GF_ChildNodeItem **)field->far_ptr); * (GF_ChildNodeItem **)field->far_ptr = NULL; } else { //remove all items of the MFField gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType); } } /*predictiveMFField*/ if (codec->info->config.UsePredictiveMFField) { flag = gf_bs_read_int(bs, 1); if (flag) { GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] Stream uses Predictive Field Coding!\n")); #ifdef GPAC_ENABLE_BIFS_PMF return gf_bifs_dec_pred_mf_field(codec, bs, node, field); #else return GF_NOT_SUPPORTED; #endif } } /*reserved*/ flag = gf_bs_read_int(bs, 1); if (!flag) { /*destroy the field content...*/ if (field->fieldType != GF_SG_VRML_MFNODE) { e = gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType); if (e) return e; } /*List description - alloc is dynamic*/ flag = gf_bs_read_int(bs, 1); if (flag) { e = BD_DecMFFieldList(codec, bs, node, field, is_mem_com); } else { e = BD_DecMFFieldVec(codec, bs, node, field, is_mem_com); } if (e) return e; } } return GF_OK; }
// // Insert (+alloc) an MFField with a specified position for insertion and sets the ptr to the // newly created slot // !! Doesnt work for MFNodes // InsertAt is the 0-based index for the new slot GF_Err gf_sg_vrml_mf_insert(void *mf, u32 FieldType, void **new_ptr, u32 InsertAt) { char *buffer; u32 FieldSize, i, k; GenMFField *mffield = (GenMFField *)mf; if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM; FieldSize = gf_sg_vrml_get_sf_size(FieldType); //field we can't copy if (!FieldSize) return GF_BAD_PARAM; //first item ever if (!mffield->count || !mffield->array) { if (mffield->array) gf_free(mffield->array); mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize); memset(mffield->array, 0, sizeof(char)*FieldSize); mffield->count = 1; if (new_ptr) *new_ptr = mffield->array; return GF_OK; } //append at the end if (InsertAt >= mffield->count) { mffield->array = (char*)gf_realloc(mffield->array, sizeof(char)*(1+mffield->count)*FieldSize); memset(mffield->array + mffield->count * FieldSize, 0, FieldSize); if (new_ptr) *new_ptr = mffield->array + mffield->count * FieldSize; mffield->count += 1; return GF_OK; } //alloc 1+itemCount buffer = (char*)gf_malloc(sizeof(char)*(1+mffield->count)*FieldSize); //insert in the array k=0; for (i=0; i < mffield->count; i++) { if (InsertAt == i) { if (new_ptr) { *new_ptr = buffer + i*FieldSize; memset(*new_ptr, 0, sizeof(char)*FieldSize); } k = 1; } memcpy(buffer + (k+i) * FieldSize , mffield->array + i*FieldSize, FieldSize); } gf_free(mffield->array); mffield->array = buffer; mffield->count += 1; return GF_OK; }
static GF_Err BM_ParseMultipleIndexedReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { u32 ID, ind, field_ind, NumBits, lenpos, lennum, count; GF_Node *node; GF_Err e; GF_Command *com; GF_CommandField *inf; GF_FieldInfo field; 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); com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_INDEXED_REPLACE); BM_SetCommandNode(com, node); field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); while (count) { inf = gf_sg_command_field_new(com); inf->pos = gf_bs_read_int(bs, lenpos); inf->fieldIndex = field.fieldIndex; inf->fieldType = field.fieldType; if (field.fieldType==GF_SG_VRML_SFNODE) { inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype); if (codec->LastError) goto err; inf->field_ptr = &inf->new_node; gf_node_register(inf->new_node, NULL); } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); e = gf_bifs_dec_sf_field(codec, bs, node, &field, 1); if (e) goto err; } count--; } err: if (e) gf_sg_command_del(com); else gf_list_add(com_list, com); return e; }
GF_Err gf_bifs_enc_field(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field) { assert(node); if (field->fieldType == GF_SG_VRML_UNKNOWN) return GF_NON_COMPLIANT_BITSTREAM; if (gf_sg_vrml_is_sf_field(field->fieldType)) { return gf_bifs_enc_sf_field(codec, bs, node, field); } /*TO DO : PMF support*/ if (codec->info->config.UsePredictiveMFField) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL); } return gf_bifs_enc_mf_field(codec, bs, node, field); }
GF_Err gf_sg_vrml_mf_get_item(void *mf, u32 FieldType, void **new_ptr, u32 ItemPos) { u32 FieldSize; GenMFField *mffield = (GenMFField *)mf; *new_ptr = NULL; if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM; FieldSize = gf_sg_vrml_get_sf_size(FieldType); //field we can't copy if (!FieldSize) return GF_BAD_PARAM; if (ItemPos >= mffield->count) return GF_BAD_PARAM; *new_ptr = mffield->array + ItemPos * FieldSize; return GF_OK; }
GF_Err BM_ParseIndexDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { u32 NodeID, NumBits, ind, field_ind; s32 pos; GF_Command *com; u8 type; GF_Node *node; GF_Err e; GF_CommandField *inf; 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; com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_DELETE); BM_SetCommandNode(com, node); inf = gf_sg_command_field_new(com); inf->pos = pos; inf->fieldIndex = field.fieldIndex; inf->fieldType = gf_sg_vrml_get_sf_type(field.fieldType); gf_list_add(com_list, com); return codec->LastError; }
GF_Err BE_IndexInsert(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs) { GF_Err e; u32 NumBits, ind; GF_FieldInfo field, sffield; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); /*index insertion uses IN mode for field index*/ NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL); switch (inf->pos) { case 0: GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idx"); break; case -1: GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx"); break; default: GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx"); GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL); break; } e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; memcpy(&sffield, &field, sizeof(GF_FieldInfo)); sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); sffield.far_ptr = inf->field_ptr; /*rescale the MFField and parse the SFField*/ if (field.fieldType==GF_SG_VRML_MFNODE) { return gf_bifs_enc_node(codec, inf->new_node, field.NDTtype, bs); } else { return gf_bifs_enc_sf_field(codec, bs, com->node, &sffield); } }
GF_EXPORT GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems) { u32 FieldSize; GenMFField *mffield = (GenMFField *)mf; if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM; FieldSize = gf_sg_vrml_get_sf_size(FieldType); //field we can't copy if (!FieldSize) return GF_BAD_PARAM; if (NbItems>MAX_MFFIELD_ALLOC) return GF_IO_ERR; if (mffield->count==NbItems) return GF_OK; gf_sg_vrml_mf_reset(mf, FieldType); if (NbItems) { mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize*NbItems); memset(mffield->array, 0, sizeof(char)*FieldSize*NbItems); } mffield->count = NbItems; return GF_OK; }
/*NB This can insert a node as well (but usually not in the .children field)*/ GF_Err BM_ParseIndexInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { GF_Err e; u32 NodeID; u32 NumBits, ind, field_ind; u8 type; GF_Command *com; GF_CommandField *inf; 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; /*index insertion uses IN mode for field index*/ 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); /*rescale the MFField and parse the SFField*/ if (field.fieldType==GF_SG_VRML_MFNODE) { node = gf_bifs_dec_node(codec, bs, field.NDTtype); if (!codec->LastError) { com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT); BM_SetCommandNode(com, def); inf = gf_sg_command_field_new(com); inf->pos = pos; inf->fieldIndex = field_ind; inf->fieldType = sffield.fieldType; inf->new_node = node; inf->field_ptr = &inf->new_node; gf_list_add(com_list, com); /*register*/ gf_node_register(node, NULL); } } else { com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT); BM_SetCommandNode(com, def); inf = gf_sg_command_field_new(com); inf->pos = pos; inf->fieldIndex = field_ind; inf->fieldType = sffield.fieldType; sffield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(sffield.fieldType); codec->LastError = gf_bifs_dec_sf_field(codec, bs, def, &sffield, 1); gf_list_add(com_list, com); } return codec->LastError; }
GF_Err BE_EncProtoList(GF_BifsEncoder *codec, GF_List *protoList, GF_BitStream *bs) { u8 useQuant, useAnim; u32 i, j, nbRoutes, nbBits, numProtos, numFields, count; GF_Node *node; GF_ProtoFieldInterface *proto_field; GF_Proto *proto, *prev_proto; GF_Route *r; GF_Err e; GF_SceneGraph *rootSG; GF_FieldInfo field; e = GF_OK; if (!protoList || !gf_list_count(protoList)) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL); return GF_OK; } if (!codec->info->config.ProtoIDBits) return GF_NON_COMPLIANT_BITSTREAM; /*store state*/ rootSG = codec->current_proto_graph; prev_proto = codec->encoding_proto; numProtos = gf_list_count(protoList); for (i=0; i<numProtos; i++) { proto = (GF_Proto*)gf_list_get(protoList, i); useQuant = useAnim = 0; /*set current proto state*/ codec->encoding_proto = proto; codec->current_proto_graph = proto->sub_graph; GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreProto", NULL); /*1- proto interface declaration*/ GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL); if (codec->UseName) gf_bifs_enc_name(codec, bs, proto->Name); numFields = gf_list_count(proto->proto_fields); for (j=0; j<numFields; j++) { proto_field = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, j); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreField", NULL); GF_BIFS_WRITE_INT(codec, bs, proto_field->EventType, 2, "eventType", NULL); GF_BIFS_WRITE_INT(codec, bs, proto_field->FieldType, 6, "fieldType", NULL); if (codec->UseName) gf_bifs_enc_name(codec, bs, proto_field->FieldName); switch (proto_field->EventType) { case GF_SG_EVENT_EXPOSED_FIELD: case GF_SG_EVENT_FIELD: gf_sg_proto_field_get_field(proto_field, &field); if (gf_sg_vrml_is_sf_field(field.fieldType)) { e = gf_bifs_enc_sf_field(codec, bs, NULL, &field); } else { if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL); e = gf_bifs_enc_mf_field(codec, bs, NULL, &field); } if (e) goto exit; break; } if (proto_field->QP_Type) useQuant = 1; if (proto_field->Anim_Type) useAnim = 1; } GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreField", NULL); GF_BIFS_WRITE_INT(codec, bs, proto->ExternProto.count ? 1 : 0, 1, "externProto", NULL); /*externProto*/ if (proto->ExternProto.count) { memset(&field, 0, sizeof(GF_FieldInfo)); field.far_ptr = &proto->ExternProto; field.fieldType = GF_SG_VRML_MFURL; field.name = "ExternProto"; if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL); e = gf_bifs_enc_mf_field(codec, bs, NULL, &field); if (e) goto exit; } else { /*encode sub-proto list*/ e = BE_EncProtoList(codec, proto->sub_graph->protos, bs); if (e) goto exit; count = gf_list_count(proto->node_code); /*BIFS cannot encode empty protos ! We therefore encode a NULL node instead*/ if (!count) { gf_bifs_enc_node(codec, NULL, NDT_SFWorldNode, bs); GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreNodes", NULL); } else { for (j=0; j<count; j++) { /*parse all nodes in SFWorldNode table*/ node = (GF_Node*)gf_list_get(proto->node_code, j); e = gf_bifs_enc_node(codec, node, NDT_SFWorldNode, bs); if (e) goto exit; GF_BIFS_WRITE_INT(codec, bs, (j+1==count) ? 0 : 1, 1, "moreNodes", NULL); } } /*encode routes routes*/ nbRoutes = count = gf_list_count(proto->sub_graph->Routes); for (j=0; j<count; j++) { r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j); if (r->IS_route) nbRoutes--; } GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "hasRoute", NULL); if (nbRoutes) { nbBits = gf_get_bit_size(nbRoutes); if (nbBits + 5 > nbRoutes) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL); /*list*/ for (j=0; j<count; j++) { r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j); if (r->IS_route) continue; e = gf_bifs_enc_route(codec, r, bs); if (e) goto exit; nbRoutes--; GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "moreRoute", NULL); } } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL); GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, nbRoutes, nbBits, "length", NULL); for (j=0; j<count; j++) { r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j); if (r->IS_route) continue; e = gf_bifs_enc_route(codec, r, bs); if (e) goto exit; } } } } /*anim and Quantization stuff*/ GF_BIFS_WRITE_INT(codec, bs, useQuant, 1, "useQuant", NULL); GF_BIFS_WRITE_INT(codec, bs, useAnim, 1, "useAnim", NULL); if (!useAnim && !useQuant) continue; count = gf_sg_proto_get_field_count(proto); for (j=0; j<count; j++) { proto_field = gf_sg_proto_field_find(proto, j); gf_sg_proto_field_get_field(proto_field, &field); /*quant*/ if (useQuant && ( (field.eventType == GF_SG_EVENT_FIELD) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) { GF_BIFS_WRITE_INT(codec, bs, proto_field->QP_Type, 4, "QPType", NULL); if (proto_field->QP_Type==QC_LINEAR_SCALAR) GF_BIFS_WRITE_INT(codec, bs, proto_field->NumBits, 5, "nbBits", NULL); GF_BIFS_WRITE_INT(codec, bs, proto_field->hasMinMax, 1, "hasMinMax", NULL); if (proto_field->hasMinMax) { field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); switch (field.fieldType) { case GF_SG_VRML_SFINT32: case GF_SG_VRML_SFTIME: break; default: field.fieldType = GF_SG_VRML_SFFLOAT; break; } field.name = "QPMinValue"; field.far_ptr = proto_field->qp_min_value; gf_bifs_enc_sf_field(codec, bs, NULL, &field); field.name = "QPMaxValue"; field.far_ptr = proto_field->qp_max_value; gf_bifs_enc_sf_field(codec, bs, NULL, &field); } } /*anim - not supported yet*/ if (useAnim && ( (field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) { e = GF_NOT_SUPPORTED; goto exit; } } } GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL); exit: /*restore scene graph state*/ codec->encoding_proto = prev_proto; codec->current_proto_graph = rootSG; return e; }
/*special cloning with type-casting from SF/MF strings to URL conversion since proto URL doesn't exist as a field type (it's just a stupid encoding trick) */ void VRML_FieldCopyCast(void *dest, u32 dst_field_type, void *orig, u32 ori_field_type) { SFURL *url; char tmp[50]; u32 size, i, sf_type_ori, sf_type_dst; void *dst_field, *orig_field; if (!dest || !orig) return; switch (dst_field_type) { case GF_SG_VRML_SFSTRING: if (ori_field_type == GF_SG_VRML_SFURL) { url = ((SFURL *)orig); if (url->OD_ID>0) { sprintf(tmp, "%d", url->OD_ID); if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); ((SFString*)dest)->buffer = gf_strdup(tmp); } else { if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); ((SFString*)dest)->buffer = url->url ? gf_strdup(url->url) : NULL; } } /*for SFString to MFString cast*/ else if (ori_field_type == GF_SG_VRML_SFSTRING) { if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); ((SFString*)dest)->buffer = ((SFString*)orig)->buffer ? gf_strdup(((SFString*)orig)->buffer) : NULL; } return; case GF_SG_VRML_SFURL: if (ori_field_type != GF_SG_VRML_SFSTRING) return; url = ((SFURL *)dest); url->OD_ID = 0; if (url->url) gf_free(url->url); if ( ((SFString*)orig)->buffer) url->url = gf_strdup(((SFString*)orig)->buffer); else url->url = NULL; return; case GF_SG_VRML_MFSTRING: case GF_SG_VRML_MFURL: break; default: return; } sf_type_dst = gf_sg_vrml_get_sf_type(dst_field_type); if (gf_sg_vrml_is_sf_field(ori_field_type)) { size = 1; gf_sg_vrml_mf_alloc(dest, dst_field_type, size); gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, 0); VRML_FieldCopyCast(dst_field, sf_type_dst, orig, ori_field_type); return; } size = ((GenMFField *)orig)->count; if (size != ((GenMFField *)dest)->count) gf_sg_vrml_mf_alloc(dest, dst_field_type, size); sf_type_ori = gf_sg_vrml_get_sf_type(ori_field_type); //duplicate all items for (i=0; i<size; i++) { gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, i); gf_sg_vrml_mf_get_item(orig, ori_field_type, &orig_field, i); VRML_FieldCopyCast(dst_field, sf_type_dst, orig_field, sf_type_ori); } return; }
GF_EXPORT GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_offset) { GF_Err e; GF_CommandField *inf; GF_FieldInfo field; GF_Node *def, *node; void *slot_ptr; if (!com || !graph) return GF_BAD_PARAM; e = GF_OK; switch (com->tag) { case GF_SG_SCENE_REPLACE: /*unregister root*/ gf_node_unregister(graph->RootNode, NULL); /*remove all protos and routes*/ while (gf_list_count(graph->routes_to_activate)) gf_list_rem(graph->routes_to_activate, 0); /*destroy all routes*/ while (gf_list_count(graph->Routes)) { GF_Route *r = (GF_Route *)gf_list_get(graph->Routes, 0); /*this will unregister the route from the graph, so don't delete the chain entry*/ gf_sg_route_del(r); } /*destroy all proto*/ while (gf_list_count(graph->protos)) { GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0); /*this will unregister the proto from the graph, so don't delete the chain entry*/ gf_sg_proto_del(p); } /*DO NOT TOUCH node registry*/ /*DO NOT TOUCH UNREGISTERED PROTOS*/ /*move all protos in graph*/ while (gf_list_count(com->new_proto_list)) { GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0); gf_list_rem(com->new_proto_list, 0); gf_list_del_item(graph->unregistered_protos, p); gf_list_add(graph->protos, p); } /*assign new root (no need to register/unregister)*/ graph->RootNode = com->node; com->node = NULL; break; case GF_SG_NODE_REPLACE: if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); e = gf_node_replace(com->node, inf->new_node, 0); if (inf->new_node) gf_node_register(inf->new_node, NULL); break; case GF_SG_MULTIPLE_REPLACE: case GF_SG_FIELD_REPLACE: { u32 j; GF_ChildNodeItem *list, *cur, *prev; j=0; while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &j))) { e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; switch (field.fieldType) { case GF_SG_VRML_SFNODE: { node = *((GF_Node **) field.far_ptr); e = gf_node_unregister(node, com->node); *((GF_Node **) field.far_ptr) = inf->new_node; if (!e) gf_node_register(inf->new_node, com->node); break; } case GF_SG_VRML_MFNODE: gf_node_unregister_children(com->node, * ((GF_ChildNodeItem **) field.far_ptr)); * ((GF_ChildNodeItem **) field.far_ptr) = NULL; list = * ((GF_ChildNodeItem **) inf->field_ptr); prev=NULL; while (list) { cur = malloc(sizeof(GF_ChildNodeItem)); cur->next = NULL; cur->node = list->node; if (prev) { prev->next = cur; } else { * ((GF_ChildNodeItem **) field.far_ptr) = cur; } gf_node_register(list->node, com->node); prev = cur; list = list->next; } break; default: /*this is a regular field, reset it and clone - we cannot switch pointers since the original fields are NOT pointers*/ if (!gf_sg_vrml_is_sf_field(field.fieldType)) { e = gf_sg_vrml_mf_reset(field.far_ptr, field.fieldType); } if (e) return e; gf_sg_vrml_field_copy(field.far_ptr, inf->field_ptr, field.fieldType); if (field.fieldType==GF_SG_VRML_SFTIME) *(SFTime *)field.far_ptr = *(SFTime *)field.far_ptr + time_offset; break; } SG_CheckFieldChange(com->node, &field); } break; } case GF_SG_MULTIPLE_INDEXED_REPLACE: case GF_SG_INDEXED_REPLACE: { u32 sftype, i=0; while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &i))) { e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; /*if MFNode remove the child and set new node*/ if (field.fieldType == GF_SG_VRML_MFNODE) { /*we must remove the node before in case the new node uses the same ID (not forbidden) and this command removes the last instance of the node with the same ID*/ gf_node_replace_child(com->node, (GF_ChildNodeItem**) field.far_ptr, inf->pos, inf->new_node); if (inf->new_node) gf_node_register(inf->new_node, NULL); } /*erase the field item*/ else { if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) { inf->pos = ((GenMFField *)field.far_ptr)->count - 1; /*may happen with text and default value*/ if (inf->pos < 0) { inf->pos = 0; gf_sg_vrml_mf_alloc(field.far_ptr, field.fieldType, 1); } } e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & slot_ptr, inf->pos); if (e) return e; sftype = gf_sg_vrml_get_sf_type(field.fieldType); gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype); /*note we don't add time offset, since there's no MFTime*/ } SG_CheckFieldChange(com->node, &field); } break; } case GF_SG_ROUTE_REPLACE: { GF_Route *r; char *name; r = gf_sg_route_find(graph, com->RouteID); def = gf_sg_find_node(graph, com->fromNodeID); node = gf_sg_find_node(graph, com->toNodeID); if (!node || !def) return GF_SG_UNKNOWN_NODE; name = NULL; if (r) { name = r->name; r->name = NULL; gf_sg_route_del(r); } r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex); gf_sg_route_set_id(r, com->RouteID); if (name) { gf_sg_route_set_name(r, name); free(name); } break; } case GF_SG_NODE_DELETE_EX: case GF_SG_NODE_DELETE: { if (com->node) gf_node_replace(com->node, NULL, (com->tag==GF_SG_NODE_DELETE_EX) ? 1 : 0); break; } case GF_SG_ROUTE_DELETE: { return gf_sg_route_del_by_id(graph, com->RouteID); } case GF_SG_INDEXED_DELETE: { if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; /*then we need special handling in case of a node*/ if (gf_sg_vrml_get_sf_type(field.fieldType) == GF_SG_VRML_SFNODE) { e = gf_node_replace_child(com->node, (GF_ChildNodeItem **) field.far_ptr, inf->pos, NULL); } else { if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) { inf->pos = ((GenMFField *)field.far_ptr)->count - 1; } /*this is a regular MFField, just remove the item (realloc)*/ e = gf_sg_vrml_mf_remove(field.far_ptr, field.fieldType, inf->pos); } /*deletion -> node has changed*/ if (!e) SG_CheckFieldChange(com->node, &field); break; } case GF_SG_NODE_INSERT: { if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); e = gf_node_insert_child(com->node, inf->new_node, inf->pos); if (!e) gf_node_register(inf->new_node, com->node); if (!e) gf_node_event_out(com->node, inf->fieldIndex); if (!e) gf_node_changed(com->node, NULL); break; } case GF_SG_ROUTE_INSERT: { GF_Route *r; def = gf_sg_find_node(graph, com->fromNodeID); node = gf_sg_find_node(graph, com->toNodeID); if (!node || !def) return GF_SG_UNKNOWN_NODE; r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex); if (com->RouteID) gf_sg_route_set_id(r, com->RouteID); if (com->def_name) { gf_sg_route_set_name(r, com->def_name); free(com->def_name); com->def_name = NULL; } break; } case GF_SG_INDEXED_INSERT: { u32 sftype; if (!gf_list_count(com->command_fields)) return GF_OK; inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); e = gf_node_get_field(com->node, inf->fieldIndex, &field); if (e) return e; /*rescale the MFField and parse the SFField*/ if (field.fieldType != GF_SG_VRML_MFNODE) { if (inf->pos == -1) { e = gf_sg_vrml_mf_append(field.far_ptr, field.fieldType, & slot_ptr); } else { e = gf_sg_vrml_mf_insert(field.far_ptr, field.fieldType, & slot_ptr, inf->pos); } if (e) return e; sftype = gf_sg_vrml_get_sf_type(field.fieldType); gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype); } else { if (inf->new_node) { if (inf->pos == -1) { gf_node_list_add_child( (GF_ChildNodeItem **) field.far_ptr, inf->new_node); } else { gf_node_list_insert_child((GF_ChildNodeItem **) field.far_ptr, inf->new_node, inf->pos); } gf_node_register(inf->new_node, com->node); } } if (!e) SG_CheckFieldChange(com->node, &field); break; } case GF_SG_PROTO_INSERT: /*destroy all proto*/ while (gf_list_count(com->new_proto_list)) { GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0); gf_list_rem(com->new_proto_list, 0); gf_list_del_item(graph->unregistered_protos, p); gf_list_add(graph->protos, p); } return GF_OK; case GF_SG_PROTO_DELETE: { u32 i; for (i=0; i<com->del_proto_list_size; i++) { /*note this will check for unregistered protos, but since IDs are unique we are sure we will not destroy an unregistered one*/ GF_Proto *proto = gf_sg_find_proto(graph, com->del_proto_list[i], NULL); if (proto) gf_sg_proto_del(proto); } } return GF_OK; case GF_SG_PROTO_DELETE_ALL: /*destroy all proto*/ while (gf_list_count(graph->protos)) { GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0); gf_list_rem(graph->protos, 0); /*this will unregister the proto from the graph, so don't delete the chain entry*/ gf_sg_proto_del(p); } /*DO NOT TOUCH UNREGISTERED PROTOS*/ return GF_OK; /*only used by BIFS*/ case GF_SG_GLOBAL_QUANTIZER: return GF_OK; #ifndef GPAC_DISABLE_SVG /*laser commands*/ case GF_SG_LSR_NEW_SCENE: /*DO NOT TOUCH node registry*/ /*assign new root (no need to register/unregister)*/ graph->RootNode = com->node; com->node = NULL; break; case GF_SG_LSR_DELETE: if (!com->node) return GF_NON_COMPLIANT_BITSTREAM; if (!gf_list_count(com->command_fields)) { gf_node_replace(com->node, NULL, 0); gf_node_deactivate(com->node); return GF_OK; } inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); node = gf_node_list_get_child(((SVG_Element *)com->node)->children, inf->pos); if (node) { e = gf_node_replace_child(com->node, &((SVG_Element *)com->node)->children, inf->pos, NULL); gf_node_deactivate(node); } break; case GF_SG_LSR_INSERT: inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); if (!com->node || !inf) return GF_NON_COMPLIANT_BITSTREAM; if (inf->new_node) { if (inf->pos<0) gf_node_list_add_child(& ((SVG_Element *)com->node)->children, inf->new_node); else gf_node_list_insert_child(& ((SVG_Element *)com->node)->children, inf->new_node, inf->pos); gf_node_register(inf->new_node, com->node); gf_node_activate(inf->new_node); gf_node_changed(com->node, NULL); } else { /*NOT SUPPORTED*/ GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[LASeR] VALUE INSERTION NOT SUPPORTED\n")); } break; case GF_SG_LSR_ADD: case GF_SG_LSR_REPLACE: inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); if (!com->node || !inf) return GF_NON_COMPLIANT_BITSTREAM; if (inf->new_node) { if (inf->pos<0) { /*if fieldIndex (eg attributeName) is set, this is children replacement*/ if (inf->fieldIndex>0) { gf_node_unregister_children_deactivate(com->node, ((SVG_Element *)com->node)->children); ((SVG_Element *)com->node)->children = NULL; gf_node_list_add_child(& ((SVG_Element *)com->node)->children, inf->new_node); gf_node_register(inf->new_node, com->node); gf_node_activate(inf->new_node); } else { e = gf_node_replace(com->node, inf->new_node, 0); gf_node_activate(inf->new_node); } } else { node = gf_node_list_get_child( ((SVG_Element *)com->node)->children, inf->pos); gf_node_replace_child(com->node, & ((SVG_Element *)com->node)->children, inf->pos, inf->new_node); gf_node_register(inf->new_node, com->node); if (node) gf_node_deactivate(node); gf_node_activate(inf->new_node); } /*signal node modif*/ gf_node_changed(com->node, NULL); return e; } else if (inf->node_list) { GF_ChildNodeItem *child, *cur, *prev; gf_node_unregister_children_deactivate(com->node, ((SVG_Element *)com->node)->children); ((SVG_Element *)com->node)->children = NULL; prev = NULL; child = inf->node_list; while (child) { cur = (GF_ChildNodeItem*)malloc(sizeof(GF_ChildNodeItem)); cur->next = NULL; cur->node = child->node; gf_node_register(child->node, com->node); gf_node_activate(child->node); if (prev) prev->next = cur; else ((SVG_Element *)com->node)->children = cur; prev = cur; child = child->next; } /*signal node modif*/ gf_node_changed(com->node, NULL); return GF_OK; } /*attribute modif*/ else if (inf->field_ptr) { GF_FieldInfo a, b; if (inf->fieldIndex==(u32) -2) { GF_Point2D scale, translate; Fixed rotate; GF_Matrix2D *dest; gf_node_get_field_by_name(com->node, "transform", &a); dest = (GF_Matrix2D*)a.far_ptr; if (com->tag==GF_SG_LSR_REPLACE) { if (gf_mx2d_decompose(dest, &scale, &rotate, &translate)) { gf_mx2d_init(*dest); if (inf->fieldType==SVG_TRANSFORM_SCALE) scale = *(GF_Point2D *)inf->field_ptr; else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) translate = *(GF_Point2D *)inf->field_ptr; else if (inf->fieldType==SVG_TRANSFORM_ROTATE) rotate = ((SVG_Point_Angle*)inf->field_ptr)->angle; gf_mx2d_add_scale(dest, scale.x, scale.y); gf_mx2d_add_rotation(dest, 0, 0, rotate); gf_mx2d_add_translation(dest, translate.x, translate.y); } } else { GF_Point2D *pt = (GF_Point2D *)inf->field_ptr; if (inf->fieldType==SVG_TRANSFORM_SCALE) gf_mx2d_add_scale(dest, pt->x, pt->y); else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) gf_mx2d_add_translation(dest, pt->x, pt->y); else if (inf->fieldType == SVG_TRANSFORM_ROTATE) gf_mx2d_add_rotation(dest, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle); } } else { if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==SVG_String_datatype)) { char *str = *(SVG_String*)inf->field_ptr; if (com->tag == GF_SG_LSR_REPLACE) { GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; if (t && (t->sgprivate->tag==TAG_DOMText)) { if (t->textContent) free(t->textContent); t->textContent = NULL; if (str) t->textContent = strdup(str); } } else { if (str) gf_dom_add_text_node(com->node, strdup(str)); } } else if ((inf->fieldIndex==TAG_LSR_ATT_scale) || (inf->fieldIndex==TAG_LSR_ATT_translation) || (inf->fieldIndex==TAG_LSR_ATT_rotation) ) { SVG_Transform *mx; gf_svg_get_attribute_by_tag(com->node, TAG_SVG_ATT_transform, 1, 0, &a); mx = a.far_ptr; if (com->tag == GF_SG_LSR_REPLACE) { GF_Point2D scale, translate; SVG_Point_Angle rotate; if (gf_mx2d_decompose(&mx->mat, &scale, &rotate.angle, &translate)) { gf_mx2d_init(mx->mat); if (inf->fieldIndex==TAG_LSR_ATT_scale) scale = *(GF_Point2D *)inf->field_ptr; else if (inf->fieldIndex==TAG_LSR_ATT_translation) translate = *(GF_Point2D *)inf->field_ptr; else if (inf->fieldIndex==TAG_LSR_ATT_rotation) rotate = *(SVG_Point_Angle*)inf->field_ptr; gf_mx2d_add_scale(&mx->mat, scale.x, scale.y); gf_mx2d_add_rotation(&mx->mat, 0, 0, rotate.angle); gf_mx2d_add_translation(&mx->mat, translate.x, translate.y); } } else { if (inf->fieldIndex==TAG_LSR_ATT_scale) gf_mx2d_add_scale(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y); if (inf->fieldIndex==TAG_LSR_ATT_translation) gf_mx2d_add_translation(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y); if (inf->fieldIndex==TAG_LSR_ATT_rotation) gf_mx2d_add_rotation(&mx->mat, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle); } } else if (gf_svg_get_attribute_by_tag(com->node, inf->fieldIndex, 1, 0, &a) == GF_OK) { b = a; b.far_ptr = inf->field_ptr; if (com->tag == GF_SG_LSR_REPLACE) { gf_svg_attributes_copy(&a, &b, 0); } else { gf_svg_attributes_add(&a, &b, &a, 0); } } b = a; b.far_ptr = inf->field_ptr; } /*signal node modif*/ gf_node_changed(com->node, &a); } else if (com->fromNodeID) { GF_FieldInfo a, b; GF_Node *fromNode = gf_sg_find_node(graph, com->fromNodeID); if (!fromNode) return GF_NON_COMPLIANT_BITSTREAM; if (gf_node_get_field(fromNode, com->fromFieldIndex, &b) != GF_OK) return GF_NON_COMPLIANT_BITSTREAM; if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==SVG_String_datatype)) { char *str = *(SVG_String*)inf->field_ptr; if (com->tag == GF_SG_LSR_REPLACE) { GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; if (t && (t->sgprivate->tag==TAG_DOMText)) { if (t->textContent) free(t->textContent); t->textContent = NULL; if (str) t->textContent = strdup(str); } } else { if (str) gf_dom_add_text_node(com->node, strdup(str)); } } else { gf_node_get_field(com->node, inf->fieldIndex, &a); if (com->tag == GF_SG_LSR_REPLACE) { e = gf_svg_attributes_copy(&a, &b, 0); } else { e = gf_svg_attributes_add(&a, &b, &a, 0); } } gf_node_changed(com->node, &a); return e; } else { return GF_NON_COMPLIANT_BITSTREAM; } break; case GF_SG_LSR_ACTIVATE: gf_node_activate(com->node); break; case GF_SG_LSR_DEACTIVATE: gf_node_deactivate(com->node); gf_node_changed(com->node, NULL); break; #endif default: return GF_NOT_SUPPORTED; } if (e) return e; if (com->scripts_to_load) { while (gf_list_count(com->scripts_to_load)) { GF_Node *script = (GF_Node *)gf_list_get(com->scripts_to_load, 0); gf_list_rem(com->scripts_to_load, 0); gf_sg_script_load(script); } gf_list_del(com->scripts_to_load); com->scripts_to_load = NULL; } return GF_OK; }
static void gf_storage_load(M_Storage *storage) { const char *opt; char szID[20]; u32 i, count; u32 sec, exp, frac; GF_Config *cfg = storage_get_cfg(storage); char *section = storage_get_section(storage); if (!cfg || !section) return; if (!gf_cfg_get_key_count(cfg, section)) { gf_free(section); return; } opt = gf_cfg_get_key(cfg, section, "expireAfterNTP"); gf_net_get_ntp(&sec, &frac); sscanf(opt, "%u", &exp); if (exp && (exp<=sec)) { gf_cfg_del_section(cfg, section); gf_free(section); return; } count = gf_cfg_get_key_count(cfg, section)-1; if (!count || (count!=storage->storageList.count)) { gf_cfg_del_section(cfg, section); gf_free(section); return; } for (i=0; i<count; i++) { GF_FieldInfo info; sprintf(szID, "%d", i); opt = gf_cfg_get_key(cfg, section, szID); if (!opt) break; if (!storage->storageList.vals[i].node) break; if (gf_node_get_field(storage->storageList.vals[i].node, storage->storageList.vals[i].fieldIndex, &info) != GF_OK) break; if (gf_sg_vrml_is_sf_field(info.fieldType)) { storage_parse_sf(info.far_ptr, info.fieldType, (char *) opt); } else { u32 sftype = gf_sg_vrml_get_sf_type(info.fieldType); char *sep, *val; void *slot; gf_sg_vrml_mf_reset(info.far_ptr, info.fieldType); while (1) { val = strchr(opt, '\''); sep = val ? strchr(val+1, '\'') : NULL; if (!val || !sep) break; sep[0] = 0; gf_sg_vrml_mf_append(info.far_ptr, info.fieldType, &slot); storage_parse_sf(slot, sftype, val+1); sep[0] = '\''; opt = sep+1; } } gf_node_changed(storage->storageList.vals[i].node, &info); } gf_free(section); }
static GF_Err BM_XReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { GF_FieldInfo targetField, fromField, decfield; GF_Node *target, *n, *fromNode; s32 pos = -2; u32 id, nbBits, ind, aind; GF_Err e; GF_Command *com; GF_CommandField *inf; 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; e = GF_OK; com = gf_sg_command_new(codec->current_graph, GF_SG_XREPLACE); BM_SetCommandNode(com, target); 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; inf = gf_sg_command_field_new(com); inf->fieldIndex = aind; if (!gf_sg_vrml_is_sf_field(targetField.fieldType)) { /*this is indexed replacement*/ if (gf_bs_read_int(bs, 1)) { /*index is dynamic*/ 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; com->toNodeID = id; 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; com->toFieldIndex = aind; } 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; com->child_field = aind; com->ChildNodeTag = gf_node_get_tag(target); if (com->ChildNodeTag == TAG_ProtoNode) { s32 p_id = gf_sg_proto_get_id(gf_node_get_proto(target)); com->ChildNodeTag = -p_id; } } } inf->pos = pos; } 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; com->fromNodeID = id; 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; com->fromFieldIndex = aind; return GF_OK; } if (pos>= -1) { inf->fieldType = gf_sg_vrml_get_sf_type(targetField.fieldType); } else { inf->fieldType = targetField.fieldType; } decfield.fieldIndex = inf->fieldIndex; decfield.fieldType = inf->fieldType; if (inf->fieldType==GF_SG_VRML_SFNODE) { decfield.far_ptr = inf->field_ptr = &inf->new_node; } else if (inf->fieldType==GF_SG_VRML_MFNODE) { decfield.far_ptr = inf->field_ptr = &inf->node_list; } else { decfield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); } e = gf_bifs_dec_sf_field(codec, bs, target, &decfield, 1); if (e) return e; gf_list_add(com_list, com); return GF_OK; }
static GF_Err BE_XReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { u32 i,nbBits; GF_FieldInfo field; GF_Err e; GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_BAD_PARAM; inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &i); GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", NULL); gf_node_get_field(com->node, inf->fieldIndex, &field); if (!gf_sg_vrml_is_sf_field(field.fieldType)) { if ((inf->pos != -2) || com->toNodeID) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "indexedReplacement", NULL); if (com->toNodeID) { GF_Node *n = gf_bifs_enc_find_node(codec, com->toNodeID); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "dynamicIndex", NULL); GF_BIFS_WRITE_INT(codec, bs, com->toNodeID-1, codec->info->config.NodeIDBits, "idxNodeID", NULL); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); gf_bifs_field_index_by_mode(n, com->toFieldIndex, GF_SG_FIELD_CODING_DEF, &i); GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "idxField", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "dynamicIndex", NULL); if (inf->pos==-1) { GF_BIFS_WRITE_INT(codec, bs, 3, 2, "replacementPosition", NULL); } else if (inf->pos==0) { GF_BIFS_WRITE_INT(codec, bs, 2, 2, "replacementPosition", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, 0, 2, "replacementPosition", NULL); GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "position", NULL); } } } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "indexedReplacement", NULL); } } if (field.fieldType==GF_SG_VRML_MFNODE) { if (com->ChildNodeTag) { GF_Node *n; if (com->ChildNodeTag>0) { n = gf_node_new(codec->scene_graph, com->ChildNodeTag); } else { GF_Proto *proto = gf_sg_find_proto(codec->scene_graph, -com->ChildNodeTag , NULL); if (!proto) return GF_SG_UNKNOWN_NODE; n = gf_sg_proto_create_instance(codec->scene_graph, proto); } if (!n) return GF_SG_UNKNOWN_NODE; gf_node_register(n, NULL); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "childField", NULL); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_IN)-1); gf_bifs_field_index_by_mode(n, com->child_field, GF_SG_FIELD_CODING_IN, &i); GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "childField", NULL); gf_node_unregister(n, NULL); } else { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "childField", NULL); } } if (com->fromNodeID) { GF_Node *n = gf_bifs_enc_find_node(codec, com->fromNodeID); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "valueFromNode", NULL); GF_BIFS_WRITE_INT(codec, bs, com->fromNodeID-1, codec->info->config.NodeIDBits, "sourceNodeID", NULL); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); gf_bifs_field_index_by_mode(n, com->fromFieldIndex, GF_SG_FIELD_CODING_DEF, &i); GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "sourceField", NULL); return GF_OK; } GF_BIFS_WRITE_INT(codec, bs, 0, 1, "valueFromNode", NULL); field.far_ptr = inf->field_ptr; field.fieldType = inf->fieldType; e = gf_bifs_enc_field(codec, bs, com->node, &field); return e; }