GF_Err BM_ParseRouteInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { GF_Err e; u8 flag; GF_Command *com; GF_Node *InNode, *OutNode; u32 RouteID, outField, inField, numBits, ind, node_id; char name[1000]; RouteID = 0; flag = gf_bs_read_int(bs, 1); /*def'ed route*/ if (flag) { RouteID = 1 + gf_bs_read_int(bs, codec->info->config.RouteIDBits); if (codec->UseName) gf_bifs_dec_name(bs, name); } /*origin*/ 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); /*target*/ 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; com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_INSERT); com->RouteID = RouteID; if (codec->UseName) com->def_name = gf_strdup( name); com->fromNodeID = gf_node_get_id(OutNode); com->fromFieldIndex = outField; com->toNodeID = gf_node_get_id(InNode); com->toFieldIndex = inField; gf_list_add(com_list, com); return codec->LastError; }
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; }
GF_Err BM_ParseRouteReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { GF_Err e; GF_Command *com; u32 RouteID, numBits, ind, node_id, fromID, toID; 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); /*origin*/ 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; /*target*/ 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; com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_REPLACE); com->RouteID = RouteID; com->fromNodeID = gf_node_get_id(OutNode); com->fromFieldIndex = fromID; com->toNodeID = gf_node_get_id(InNode); com->toFieldIndex = toID; gf_list_add(com_list, com); return codec->LastError; }
GF_Err gf_bifs_dec_node_mask(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, Bool is_proto) { u32 i, numFields, numProtoFields, index, flag, nbBits; GF_Err e; GF_FieldInfo field; //proto coding if (codec->pCurrentProto) { numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL); numProtoFields = gf_sg_proto_get_field_count(codec->pCurrentProto); nbBits = gf_get_bit_size(numProtoFields-1); for (i=0; i<numFields; i++) { flag = gf_bs_read_int(bs, 1); if (!flag) continue; flag = gf_bs_read_int(bs, 1); //IS'ed field, create route for binding to Proto declaration if (flag) { //reference index of our IS'ed proto field flag = gf_bs_read_int(bs, nbBits); e = gf_node_get_field(node, i, &field); if (e) return e; e = BD_SetProtoISed(codec, flag, node, i); } //regular field, parse it (nb: no contextual coding for protos in maskNode, //all node fields are coded else { e = gf_node_get_field(node, i, &field); if (e) return e; e = gf_bifs_dec_field(codec, bs, node, &field, 0); } if (e) return e; } } //regular coding else { numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF); for (i=0; i<numFields; i++) { flag = gf_bs_read_int(bs, 1); if (!flag) continue; gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &index); e = gf_node_get_field(node, index, &field); if (e) return e; e = gf_bifs_dec_field(codec, bs, node, &field, 0); if (e) return e; if (is_proto) gf_sg_proto_mark_field_loaded(node, &field); } } 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_dec_node_list(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, Bool is_proto) { u8 flag; GF_Err e; u32 numBitsALL, numBitsDEF, field_all, field_ref, numProtoBits; GF_FieldInfo field; e = GF_OK; numProtoBits = numBitsALL = 0; if (codec->pCurrentProto) { numProtoBits = gf_get_bit_size(gf_sg_proto_get_field_count(codec->pCurrentProto) - 1); numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL)-1); } numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1); flag = gf_bs_read_int(bs, 1); while (!flag && (codec->LastError>=0)) { if (codec->pCurrentProto) { //IS'ed flag flag = gf_bs_read_int(bs, 1); if (flag) { //get field index in ALL mode for node field_ref = gf_bs_read_int(bs, numBitsALL); //get field index in ALL mode for proto field_all = gf_bs_read_int(bs, numProtoBits); e = gf_node_get_field(node, field_ref, &field); if (e) return e; e = BD_SetProtoISed(codec, field_all, node, field_ref); if (e) return e; flag = gf_bs_read_int(bs, 1); continue; } } //fields are coded in DEF mode field_ref = gf_bs_read_int(bs, numBitsDEF); e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &field_all); if (e) return e; e = gf_node_get_field(node, field_all, &field); if (e) return e; e = gf_bifs_dec_field(codec, bs, node, &field, 0); if (e) return e; flag = gf_bs_read_int(bs, 1); if (is_proto) gf_sg_proto_mark_field_loaded(node, &field); } return codec->LastError; }
GF_Err gf_bifs_field_index_by_mode(GF_Node *node, u32 all_ind, u8 indexMode, u32 *outField) { GF_Err e; u32 i, count, temp; count = gf_node_get_num_fields_in_mode(node, indexMode); for (i=0; i<count; i++) { e = gf_bifs_get_field_index(node, i, indexMode, &temp); if (e) return e; if (temp==all_ind) { *outField = i; return GF_OK; } } return GF_BAD_PARAM; }
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; }
static GF_Err BE_MultipleReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { u32 i, j, nbBits, count, numFields, allField; Bool use_list; GF_FieldInfo field; GF_Err e; gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); count = gf_list_count(com->command_fields); use_list = 1; numFields = gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_DEF); nbBits = gf_get_bit_size(numFields - 1); if (count < 1+count*(1+nbBits)) use_list = 0; GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL); for (i=0; i<numFields; i++) { GF_CommandField *inf = NULL; gf_bifs_get_field_index(com->node, i, GF_SG_FIELD_CODING_DEF, &allField); for (j=0; j<count; j++) { inf = (GF_CommandField *)gf_list_get(com->command_fields, j); if (inf->fieldIndex==allField) break; inf = NULL; } if (!inf) { if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL); continue; } /*common case*/ gf_node_get_field(com->node, inf->fieldIndex, &field); if (use_list) { /*not end flag*/ GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { /*mask flag*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } if (use_list) GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", (char*)field.name); field.far_ptr = inf->field_ptr; e = gf_bifs_enc_field(codec, bs, com->node, &field); if (e) return e; } /*end flag*/ if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); return GF_OK; }
GF_Err BM_ParseFieldReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { GF_Err e; GF_Command *com; u32 NodeID, ind, field_ind, NumBits; GF_Node *node; GF_FieldInfo field; GF_CommandField *inf; 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); com = gf_sg_command_new(codec->current_graph, GF_SG_FIELD_REPLACE); BM_SetCommandNode(com, node); inf = gf_sg_command_field_new(com); inf->fieldIndex = field_ind; inf->fieldType = field.fieldType; if (inf->fieldType == GF_SG_VRML_SFNODE) { field.far_ptr = inf->field_ptr = &inf->new_node; } else if (inf->fieldType == GF_SG_VRML_MFNODE) { field.far_ptr = inf->field_ptr = &inf->node_list; } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(field.fieldType); } /*parse the field*/ codec->LastError = gf_bifs_dec_field(codec, bs, node, &field, 1); gf_list_add(com_list, com); return codec->LastError; }
GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com) { GF_Err e; GF_Node *new_node; u32 size, length, w, h, i; char *buffer; //blindly call unquantize. return is OK, error or GF_EOS if (codec->ActiveQP && node) { e = gf_bifs_dec_unquant_field(codec, bs, node, field); if (e != GF_EOS) return e; } //not quantized, use normal scheme switch (field->fieldType) { case GF_SG_VRML_SFBOOL: * ((SFBool *) field->far_ptr) = (SFBool) gf_bs_read_int(bs, 1); break; case GF_SG_VRML_SFCOLOR: ((SFColor *)field->far_ptr)->red = BD_ReadSFFloat(codec, bs);; ((SFColor *)field->far_ptr)->green = BD_ReadSFFloat(codec, bs); ((SFColor *)field->far_ptr)->blue = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFFLOAT: *((SFFloat *)field->far_ptr) = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFINT32: *((SFInt32 *)field->far_ptr) = (s32) gf_bs_read_int(bs, 32); break; case GF_SG_VRML_SFTIME: *((SFTime *)field->far_ptr) = gf_bs_read_double(bs); if (node) BD_CheckSFTimeOffset(codec, node, field); break; case GF_SG_VRML_SFVEC2F: ((SFVec2f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs); ((SFVec2f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFVEC3F: ((SFVec3f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs); ((SFVec3f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs); ((SFVec3f *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFROTATION: ((SFRotation *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs); ((SFRotation *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs); ((SFRotation *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs); ((SFRotation *)field->far_ptr)->q = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFSTRING: size = gf_bs_read_int(bs, 5); length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) { M_CacheTexture *ct = (M_CacheTexture *) node; ct->data_len = length; if (ct->data) gf_free(ct->data); ct->data = gf_malloc(sizeof(char)*length); gf_bs_read_data(bs, (char*)ct->data, length); } else if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) { M_BitWrapper *bw = (M_BitWrapper*) node; if (bw->buffer.buffer) gf_free(bw->buffer.buffer); bw->buffer_len = length; bw->buffer.buffer = gf_malloc(sizeof(char)*length); gf_bs_read_data(bs, (char*)bw->buffer.buffer, length); } else { if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer); ((SFString *)field->far_ptr)->buffer = (char *)gf_malloc(sizeof(char)*(length+1)); memset(((SFString *)field->far_ptr)->buffer , 0, length+1); for (i=0; i<length; i++) { ((SFString *)field->far_ptr)->buffer[i] = gf_bs_read_int(bs, 8); } } break; case GF_SG_VRML_SFURL: { SFURL *url = (SFURL *) field->far_ptr; size = gf_bs_read_int(bs, 1); if (size) { if (url->url) gf_free(url->url ); url->url = NULL; length = gf_bs_read_int(bs, 10); url->OD_ID = length; } else { if ( url->OD_ID ) url->OD_ID = (u32) -1; size = gf_bs_read_int(bs, 5); length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; buffer = NULL; if (length) { buffer = (char *)gf_malloc(sizeof(char)*(length+1)); memset(buffer, 0, length+1); for (i=0; i<length; i++) buffer[i] = gf_bs_read_int(bs, 8); } if (url->url) gf_free( url->url); /*if URL is empty set it to NULL*/ if (buffer && strlen(buffer)) { url->url = buffer; } else { gf_free(buffer); url->url = NULL; } } } break; case GF_SG_VRML_SFIMAGE: if (((SFImage *)field->far_ptr)->pixels) gf_free(((SFImage *)field->far_ptr)->pixels); w = gf_bs_read_int(bs, 12); h = gf_bs_read_int(bs, 12); length = gf_bs_read_int(bs, 2); if (length > 3) length = 3; length += 1; size = w * h * length; if (gf_bs_available(bs) < size) return GF_NON_COMPLIANT_BITSTREAM; ((SFImage *)field->far_ptr)->width = w; ((SFImage *)field->far_ptr)->height = h; ((SFImage *)field->far_ptr)->numComponents = length; ((SFImage *)field->far_ptr)->pixels = (unsigned char *)gf_malloc(sizeof(char)*size); //WARNING: Buffers are NOT ALIGNED IN THE BITSTREAM for (i=0; i<size; i++) { ((SFImage *)field->far_ptr)->pixels[i] = gf_bs_read_int(bs, 8); } break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *sfcb = (SFCommandBuffer *)field->far_ptr; if (sfcb->buffer) { gf_free(sfcb->buffer); sfcb->buffer = NULL; } while (gf_list_count(sfcb->commandList)) { GF_Command *com = (GF_Command*)gf_list_get(sfcb->commandList, 0); gf_list_rem(sfcb->commandList, 0); gf_sg_command_del(com); } size = gf_bs_read_int(bs, 5); length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; sfcb->bufferSize = length; if (length) { sfcb->buffer = (unsigned char *)gf_malloc(sizeof(char)*(length)); //WARNING Buffers are NOT ALIGNED IN THE BITSTREAM for (i=0; i<length; i++) { sfcb->buffer[i] = gf_bs_read_int(bs, 8); } } //notify the node - this is needed in case an enhencement layer replaces the buffer, in which case //the # ID Bits may change SFCommandBufferChanged(codec, node); /* 1 - memory mode, register command buffer for later parsing 2 - InputSensor only works on decompressed commands */ if (codec->dec_memory_mode || (node->sgprivate->tag==TAG_MPEG4_InputSensor)) { CommandBufferItem *cbi = (CommandBufferItem *)gf_malloc(sizeof(CommandBufferItem)); cbi->node = node; cbi->cb = sfcb; gf_list_add(codec->command_buffers, cbi); } } break; case GF_SG_VRML_SFNODE: //for nodes the field ptr is a ptr to the field, which is a node ptr ;) new_node = gf_bifs_dec_node(codec, bs, field->NDTtype); if (new_node) { e = gf_node_register(new_node, is_mem_com ? NULL : node); if (e) return e; } //it may happen that new_node is NULL (this is valid for a proto declaration) *((GF_Node **) field->far_ptr) = new_node; break; case GF_SG_VRML_SFSCRIPT: #ifdef GPAC_HAS_SPIDERMONKEY codec->LastError = SFScript_Parse(codec, (SFScript*)field->far_ptr, bs, node); #else return GF_NOT_SUPPORTED; #endif break; case GF_SG_VRML_SFATTRREF: { SFAttrRef *ar = (SFAttrRef *)field->far_ptr; u32 nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); ar->node = gf_sg_find_node(codec->current_graph, nodeID); if (!ar->node) { } else { u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1); u32 field_ref = gf_bs_read_int(bs, nbBitsDEF); codec->LastError = gf_bifs_get_field_index(ar->node, field_ref, GF_SG_FIELD_CODING_DEF, &ar->fieldIndex); } } break; default: return GF_NON_COMPLIANT_BITSTREAM; } return codec->LastError; }
GF_Err EncNodeFields(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node) { u8 mode; GF_Route *isedField; GF_Node *clone; GF_Err e; s32 *enc_fields; u32 numBitsALL, numBitsDEF, allInd, count, i, nbBitsProto, nbFinal; Bool use_list, nodeIsFDP = GF_FALSE; GF_FieldInfo field, clone_field; e = GF_OK; if (codec->encoding_proto) { mode = GF_SG_FIELD_CODING_ALL; nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(codec->encoding_proto) - 1); numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL) - 1); } else { mode = GF_SG_FIELD_CODING_DEF; nbBitsProto = 0; numBitsALL = 0; } count = gf_node_get_num_fields_in_mode(node, mode); if (node->sgprivate->tag==TAG_MPEG4_Script) count = 3; if (!count) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isMask", NULL); GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); return GF_OK; } if (node->sgprivate->tag == TAG_ProtoNode) { clone = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);; } else { clone = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag); } if (clone) gf_node_register(clone, NULL); numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF) - 1); enc_fields = (s32*)gf_malloc(sizeof(s32) * count); nbFinal = 0; for (i=0; i<count; i++) { enc_fields[i] = -1; /*get field in ALL mode*/ if (mode == GF_SG_FIELD_CODING_ALL) { allInd = i; } else { gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &allInd); } /*encode proto code*/ if (codec->encoding_proto) { isedField = gf_bifs_enc_is_field_ised(codec, node, allInd); if (isedField) { enc_fields[i] = allInd; nbFinal ++; continue; } } /*common case*/ gf_node_get_field(node, allInd, &field); /*if event don't encode (happens when encoding protos)*/ if ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) continue; /*if field is default skip*/ switch (field.fieldType) { case GF_SG_VRML_SFNODE: if (* (GF_Node **) field.far_ptr) { enc_fields[i] = allInd; nbFinal++; } break; case GF_SG_VRML_MFNODE: if (* (GF_ChildNodeItem **) field.far_ptr) { enc_fields[i] = allInd; nbFinal++; } break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr; if (gf_list_count(cb->commandList)) { enc_fields[i] = allInd; nbFinal++; } } break; case GF_SG_VRML_MFSCRIPT: enc_fields[i] = allInd; nbFinal++; break; default: gf_node_get_field(clone, allInd, &clone_field); if (!gf_sg_vrml_field_equal(clone_field.far_ptr, field.far_ptr, field.fieldType)) { enc_fields[i] = allInd; nbFinal++; } break; } } if (clone) gf_node_unregister(clone, NULL); use_list = GF_TRUE; /* patch for FDP node : */ /* cannot use default field sorting due to spec "mistake", so use list to imply inversion between field 2 and field 3 of FDP*/ if (node->sgprivate->tag == TAG_MPEG4_FDP) { s32 s4SwapValue = enc_fields[2]; enc_fields[2] = enc_fields[3]; enc_fields[3] = s4SwapValue; nodeIsFDP = GF_TRUE; use_list = GF_TRUE; } /*number of bits in mask node is count*1, in list node is 1+nbFinal*(1+numBitsDEF) */ else if (count < 1+nbFinal*(1+numBitsDEF)) use_list = GF_FALSE; GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL); for (i=0; i<count; i++) { if (enc_fields[i] == -1) { if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL); continue; } allInd = (u32) enc_fields[i]; /*encode proto code*/ if (codec->encoding_proto) { isedField = gf_bifs_enc_is_field_ised(codec, node, allInd); if (isedField) { if (use_list) { GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isedField", NULL); if (use_list) GF_BIFS_WRITE_INT(codec, bs, allInd, numBitsALL, "nodeField", NULL); if (isedField->ToNode == node) { GF_BIFS_WRITE_INT(codec, bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL); } else { GF_BIFS_WRITE_INT(codec, bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL); } continue; } } /*common case*/ gf_node_get_field(node, allInd, &field); if (use_list) { /*not end flag*/ GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL); } else { /*mask flag*/ GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL); } /*not ISed field*/ if (codec->encoding_proto) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isedField", NULL); if (use_list) { if (codec->encoding_proto || nodeIsFDP) { u32 ind=0; /*for proto, we're in ALL mode and we need DEF mode*/ /*for FDP, encoding requires to get def id from all id as fields 2 and 3 are reversed*/ gf_bifs_field_index_by_mode(node, allInd, GF_SG_FIELD_CODING_DEF, &ind); GF_BIFS_WRITE_INT(codec, bs, ind, numBitsDEF, "field", (char*)field.name); } else { GF_BIFS_WRITE_INT(codec, bs, i, numBitsDEF, "field", (char*)field.name); } } e = gf_bifs_enc_field(codec, bs, node, &field); if (e) goto exit; } /*end flag*/ if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); exit: gf_free(enc_fields); return e; }
static GF_Err BM_ParseMultipleReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { u32 i, numFields, index, flag, nbBits, field_ref, fieldind; GF_Err e; GF_FieldInfo field; u32 NodeID; GF_Node *node; GF_Command *com; GF_CommandField *inf; 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; e = GF_OK; com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_REPLACE); BM_SetCommandNode(com, node); flag = gf_bs_read_int(bs, 1); if (flag) { numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF); for (i=0; i<numFields; i++) { flag = gf_bs_read_int(bs, 1); if (!flag) continue; gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &index); e = gf_node_get_field(node, index, &field); if (e) goto exit; inf = gf_sg_command_field_new(com); inf->fieldType = field.fieldType; inf->fieldIndex = field.fieldIndex; if (inf->fieldType==GF_SG_VRML_SFNODE) { field.far_ptr = inf->field_ptr = &inf->new_node; } else if (inf->fieldType==GF_SG_VRML_MFNODE) { field.far_ptr = inf->field_ptr = &inf->node_list; } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); } e = gf_bifs_dec_field(codec, bs, node, &field, 1); if (e) goto exit; } } else { flag = gf_bs_read_int(bs, 1); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1); while (!flag && (codec->LastError>=0)) { field_ref = gf_bs_read_int(bs, nbBits); e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &fieldind); if (e) goto exit; e = gf_node_get_field(node, fieldind, &field); if (e) goto exit; inf = gf_sg_command_field_new(com); inf->fieldType = field.fieldType; inf->fieldIndex = field.fieldIndex; if (inf->fieldType==GF_SG_VRML_SFNODE) { field.far_ptr = inf->field_ptr = &inf->new_node; } else if (inf->fieldType==GF_SG_VRML_MFNODE) { field.far_ptr = inf->field_ptr = &inf->node_list; } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); } e = gf_bifs_dec_field(codec, bs, node, &field, 1); if (e) goto exit; flag = gf_bs_read_int(bs, 1); } } exit: if (e) gf_sg_command_del(com); else gf_list_add(com_list, com); return e; }
/*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; }
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; }
GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field) { GF_Err e; GF_Node *new_node; u32 size, length, w, h, i; char *buffer; //blindly call unquantize. return is OK, error or GF_EOS if (codec->ActiveQP && node) { e = gf_bifs_dec_unquant_field(codec, bs, node, field); if (e != GF_EOS) return e; } //not quantized, use normal scheme switch (field->fieldType) { case GF_SG_VRML_SFBOOL: * ((SFBool *) field->far_ptr) = (SFBool) gf_bs_read_int(bs, 1); break; case GF_SG_VRML_SFCOLOR: ((SFColor *)field->far_ptr)->red = BD_ReadSFFloat(codec, bs);; ((SFColor *)field->far_ptr)->green = BD_ReadSFFloat(codec, bs); ((SFColor *)field->far_ptr)->blue = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFFLOAT: *((SFFloat *)field->far_ptr) = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFINT32: *((SFInt32 *)field->far_ptr) = (s32) gf_bs_read_int(bs, 32); break; case GF_SG_VRML_SFTIME: *((SFTime *)field->far_ptr) = gf_bs_read_double(bs); if (node) BD_CheckSFTimeOffset(codec, node, field); break; case GF_SG_VRML_SFVEC2F: ((SFVec2f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs); ((SFVec2f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFVEC3F: ((SFVec3f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs); ((SFVec3f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs); ((SFVec3f *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFROTATION: ((SFRotation *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs); ((SFRotation *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs); ((SFRotation *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs); ((SFRotation *)field->far_ptr)->q = BD_ReadSFFloat(codec, bs); break; case GF_SG_VRML_SFSTRING: size = gf_bs_read_int(bs, 5); length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) { Bool skip_file_url_proto=0; char *name; FILE *f; M_CacheTexture *ct = (M_CacheTexture *) node; char *buf = gf_malloc(sizeof(char)*length); gf_bs_read_data(bs, buf, length); if (ct->cacheURL.buffer) { name = gf_strdup(ct->cacheURL.buffer); } else { char szImg[100], *ext; switch (ct->objectTypeIndication) { case GPAC_OTI_IMAGE_JPEG: ext = "jpg"; break; case GPAC_OTI_IMAGE_PNG: ext = "png"; break; case GPAC_OTI_IMAGE_JPEG_2000: ext = "jp2"; break; default: ext = "img"; } sprintf(szImg, "%p%p.%s", codec, ct, ext); name = gf_strdup(szImg); } if (codec->extraction_path) { char *path; u32 len = strlen(name)+strlen(codec->extraction_path)+2; if (strnicmp(codec->extraction_path, "file://", 7)) len+=7; /*SHA1 of service in hexa*/ if (codec->service_url) len += 41; path = gf_malloc(sizeof(char)*len); path[0] = 0; /*force using file:// URL prototype to avoid confusion with resources adressed from the root of the source server*/ if (strnicmp(codec->extraction_path, "file://", 7)) strcpy(path, "file://"); strcat(path, codec->extraction_path); strcat(path, "/"); if (codec->service_url) { u8 hash[20]; u32 i; gf_sha1_csum(codec->service_url, strlen(codec->service_url), hash); for (i=0; i<20; i++) { char t[3]; t[2] = 0; sprintf(t, "%02X", hash[i]); strcat(path, t); } strcat(path, "_"); } strcat(path, name); gf_free(name); name = path; skip_file_url_proto = 1; } ((SFString *)field->far_ptr)->buffer = name; /*skip the initial file://*/ f = gf_f64_open(name + (skip_file_url_proto ? 7 : 0), "wb"); fwrite(buf, 1, length, f); fclose(f); gf_free(buf); } else { if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer); ((SFString *)field->far_ptr)->buffer = (char *)gf_malloc(sizeof(char)*(length+1)); memset(((SFString *)field->far_ptr)->buffer , 0, length+1); for (i=0; i<length; i++) { ((SFString *)field->far_ptr)->buffer[i] = gf_bs_read_int(bs, 8); } } break; case GF_SG_VRML_SFURL: { SFURL *url = (SFURL *) field->far_ptr; size = gf_bs_read_int(bs, 1); if (size) { if (url->url) gf_free(url->url ); url->url = NULL; length = gf_bs_read_int(bs, 10); url->OD_ID = length; } else { if ( url->OD_ID ) url->OD_ID = (u32) -1; size = gf_bs_read_int(bs, 5); length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; buffer = NULL; if (length) { buffer = (char *)gf_malloc(sizeof(char)*(length+1)); memset(buffer, 0, length+1); for (i=0; i<length; i++) buffer[i] = gf_bs_read_int(bs, 8); } if (url->url) gf_free( url->url); /*if URL is empty set it to NULL*/ if (buffer && strlen(buffer)) { url->url = buffer; } else { gf_free(buffer); url->url = NULL; } } } break; case GF_SG_VRML_SFIMAGE: if (((SFImage *)field->far_ptr)->pixels) gf_free(((SFImage *)field->far_ptr)->pixels); w = gf_bs_read_int(bs, 12); h = gf_bs_read_int(bs, 12); length = gf_bs_read_int(bs, 2); if (length > 3) length = 3; length += 1; size = w * h * length; if (gf_bs_available(bs) < size) return GF_NON_COMPLIANT_BITSTREAM; ((SFImage *)field->far_ptr)->width = w; ((SFImage *)field->far_ptr)->height = h; ((SFImage *)field->far_ptr)->numComponents = length; ((SFImage *)field->far_ptr)->pixels = (unsigned char *)gf_malloc(sizeof(char)*size); //WARNING: Buffers are NOT ALIGNED IN THE BITSTREAM for (i=0; i<size; i++) { ((SFImage *)field->far_ptr)->pixels[i] = gf_bs_read_int(bs, 8); } break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *sfcb = (SFCommandBuffer *)field->far_ptr; if (sfcb->buffer) { gf_free(sfcb->buffer); sfcb->buffer = NULL; } while (gf_list_count(sfcb->commandList)) { GF_Command *com = (GF_Command*)gf_list_get(sfcb->commandList, 0); gf_list_rem(sfcb->commandList, 0); gf_sg_command_del(com); } size = gf_bs_read_int(bs, 5); length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; sfcb->bufferSize = length; if (length) { sfcb->buffer = (unsigned char *)gf_malloc(sizeof(char)*(length)); //WARNING Buffers are NOT ALIGNED IN THE BITSTREAM for (i=0; i<length; i++) { sfcb->buffer[i] = gf_bs_read_int(bs, 8); } } //notify the node - this is needed in case an enhencement layer replaces the buffer, in which case //the # ID Bits may change SFCommandBufferChanged(codec, node); /* 1 - memory mode, register command buffer for later parsing 2 - InputSensor only works on decompressed commands */ if (codec->dec_memory_mode || (node->sgprivate->tag==TAG_MPEG4_InputSensor)) { CommandBufferItem *cbi = (CommandBufferItem *)gf_malloc(sizeof(CommandBufferItem)); cbi->node = node; cbi->cb = sfcb; gf_list_add(codec->command_buffers, cbi); } } break; case GF_SG_VRML_SFNODE: //for nodes the field ptr is a ptr to the field, which is a node ptr ;) new_node = gf_bifs_dec_node(codec, bs, field->NDTtype); if (new_node) { e = gf_node_register(new_node, node); if (e) return e; } //it may happen that new_node is NULL (this is valid for a proto declaration) *((GF_Node **) field->far_ptr) = new_node; break; case GF_SG_VRML_SFSCRIPT: #ifdef GPAC_HAS_SPIDERMONKEY codec->LastError = SFScript_Parse(codec, (SFScript*)field->far_ptr, bs, node); #else return GF_NOT_SUPPORTED; #endif break; case GF_SG_VRML_SFATTRREF: { SFAttrRef *ar = (SFAttrRef *)field->far_ptr; u32 nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); ar->node = gf_sg_find_node(codec->current_graph, nodeID); if (!ar->node) { } else { u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1); u32 field_ref = gf_bs_read_int(bs, nbBitsDEF); codec->LastError = gf_bifs_get_field_index(ar->node, field_ref, GF_SG_FIELD_CODING_DEF, &ar->fieldIndex); } } break; default: return GF_NON_COMPLIANT_BITSTREAM; } return codec->LastError; }