📄 loader_bt.c
字号:
} if ((parser->line_buffer[parser->line_pos] != '\\') || (parser->line_buffer[parser->line_pos+1] != '"')) { /*handle UTF-8 - WARNING: if parser is in unicode string is already utf8 multibyte chars*/ if (!parser->unicode_type && parser->line_buffer[parser->line_pos] & 0x80) { char c = parser->line_buffer[parser->line_pos]; /*non UTF8 (likely some win-CP)*/ if ( (parser->line_buffer[parser->line_pos+1] & 0xc0) != 0x80) { res[i] = 0xc0 | ( (parser->line_buffer[parser->line_pos] >> 6) & 0x3 ); i++; BT_STR_CHECK_ALLOC parser->line_buffer[parser->line_pos] &= 0xbf; } /*UTF8 2 bytes char*/ else if ( (c & 0xe0) == 0xc0) { res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++; BT_STR_CHECK_ALLOC } /*UTF8 3 bytes char*/ else if ( (c & 0xf0) == 0xe0) { res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++; BT_STR_CHECK_ALLOC res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++; BT_STR_CHECK_ALLOC } /*UTF8 4 bytes char*/ else if ( (c & 0xf8) == 0xf0) { res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++; BT_STR_CHECK_ALLOC res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++; BT_STR_CHECK_ALLOC res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++; BT_STR_CHECK_ALLOC } } res[i] = parser->line_buffer[parser->line_pos]; i++; } parser->line_pos++; if (parser->line_pos==parser->line_size) { gf_bt_check_line(parser); } }#undef BT_STR_CHECK_ALLOC res[i] = 0; parser->line_pos += 1; return res;}Bool gf_bt_check_externproto_field(GF_BTParser *parser, char *str){ if (!parser->is_extern_proto_field) return 0; if (!strcmp(str, "") || !strcmp(str, "field") || !strcmp(str, "eventIn") || !strcmp(str, "eventOut") || !strcmp(str, "exposedField")) { parser->last_error = GF_EOS; return 1; } return 0;}static Bool check_keyword(GF_BTParser *parser, char *str, s32 *val){ s32 res; char *sep; sep = strchr(str, '$'); if (!sep) return 0; sep++; if (!strcmp(sep, "F1")) res = GF_KEY_F1; else if (!strcmp(sep, "F2")) res = GF_KEY_F2; else if (!strcmp(sep, "F3")) res = GF_KEY_F3; else if (!strcmp(sep, "F4")) res = GF_KEY_F4; else if (!strcmp(sep, "F5")) res = GF_KEY_F5; else if (!strcmp(sep, "F6")) res = GF_KEY_F6; else if (!strcmp(sep, "F7")) res = GF_KEY_F7; else if (!strcmp(sep, "F8")) res = GF_KEY_F8; else if (!strcmp(sep, "F9")) res = GF_KEY_F9; else if (!strcmp(sep, "F10")) res = GF_KEY_F10; else if (!strcmp(sep, "F11")) res = GF_KEY_F11; else if (!strcmp(sep, "F12")) res = GF_KEY_F12; else if (!strcmp(sep, "HOME")) res = GF_KEY_HOME; else if (!strcmp(sep, "END")) res = GF_KEY_END; else if (!strcmp(sep, "PREV")) res = GF_KEY_PAGEUP; else if (!strcmp(sep, "NEXT")) res = GF_KEY_PAGEDOWN; else if (!strcmp(sep, "UP")) res = GF_KEY_UP; else if (!strcmp(sep, "DOWN")) res = GF_KEY_DOWN; else if (!strcmp(sep, "LEFT")) res = GF_KEY_LEFT; else if (!strcmp(sep, "RIGHT")) res = GF_KEY_RIGHT; else if (!strcmp(sep, "RETURN")) res = GF_KEY_ENTER; else if (!strcmp(sep, "BACK")) res = GF_KEY_BACKSPACE; else if (!strcmp(sep, "TAB")) res = GF_KEY_TAB; else if (strlen(sep)==1) { char c; sscanf(sep, "%c", &c); res = c; } else { gf_bt_report(parser, GF_OK, "unrecognized keyword %s - skipping", str); res = 0; } if (strchr(str, '-')) *val = -res; else *val = res; return 1;}GF_Err gf_bt_parse_float(GF_BTParser *parser, const char *name, Fixed *val){ s32 var; Float f; char *str = gf_bt_get_next(parser, 0); if (!str) return parser->last_error = GF_IO_ERR; if (gf_bt_check_externproto_field(parser, str)) return GF_OK; if (check_keyword(parser, str, &var)) { *val = INT2FIX(var); return GF_OK; } if (sscanf(str, "%g", &f) != 1) { return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name); } *val = FLT2FIX(f); return GF_OK;}GF_Err gf_bt_parse_double(GF_BTParser *parser, const char *name, SFDouble *val){ char *str = gf_bt_get_next(parser, 0); if (!str) return parser->last_error = GF_IO_ERR; if (gf_bt_check_externproto_field(parser, str)) return GF_OK; if (sscanf(str, "%lf", val) != 1) { return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name); } return GF_OK;}GF_Err gf_bt_parse_int(GF_BTParser *parser, const char *name, SFInt32 *val){ char *str = gf_bt_get_next(parser, 0); if (!str) return parser->last_error = GF_IO_ERR; if (gf_bt_check_externproto_field(parser, str)) return GF_OK; if (check_keyword(parser, str, val)) return GF_OK; /*URL ODID*/ if (!strnicmp(str, "od:", 3)) str += 3; if (sscanf(str, "%d", val) != 1) { return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name); } return GF_OK;}GF_Err gf_bt_parse_bool(GF_BTParser *parser, const char *name, SFBool *val){ char *str = gf_bt_get_next(parser, 0); if (!str) return parser->last_error = GF_IO_ERR; if (gf_bt_check_externproto_field(parser, str)) return GF_OK; if (!stricmp(str, "true") || !strcmp(str, "1") ) { *val = 1; } else if (!stricmp(str, "false") || !strcmp(str, "0") ) { *val = 0; } else { return gf_bt_report(parser, GF_BAD_PARAM, "%s: Boolean expected", name); } return GF_OK;}GF_Err gf_bt_parse_color(GF_BTParser *parser, const char *name, SFColor *col){ Float f; char *str = gf_bt_get_next(parser, 0); if (!str) return parser->last_error = GF_IO_ERR; if (gf_bt_check_externproto_field(parser, str)) return GF_OK; /*HTML code*/ if (str[0]=='$') { u32 val; sscanf(str+1, "%x", &val); col->red = INT2FIX((val>>16) & 0xFF) / 255; col->green = INT2FIX((val>>8) & 0xFF) / 255; col->blue = INT2FIX(val & 0xFF) / 255; return parser->last_error; } if (sscanf(str, "%f", &f) != 1) { return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name); } col->red = FLT2FIX(f); /*many VRML files use ',' separator*/ gf_bt_check_code(parser, ','); gf_bt_parse_float(parser, name, & col->green); gf_bt_check_code(parser, ','); gf_bt_parse_float(parser, name, & col->blue); return parser->last_error;}GF_Err gf_bt_parse_colorRGBA(GF_BTParser *parser, const char *name, SFColorRGBA *col){ Float f; char *str = gf_bt_get_next(parser, 0); if (!str) return parser->last_error = GF_IO_ERR; if (gf_bt_check_externproto_field(parser, str)) return GF_OK; /*HTML code*/ if (str[0]=='$') { u32 val; sscanf(str, "%x", &val); col->red = INT2FIX((val>>24) & 0xFF) / 255; col->green = INT2FIX((val>>16) & 0xFF) / 255; col->blue = INT2FIX((val>>8) & 0xFF) / 255; col->alpha = INT2FIX(val & 0xFF) / 255; return parser->last_error; } if (sscanf(str, "%f", &f) != 1) { return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name); } col->red = FLT2FIX(f); gf_bt_check_code(parser, ','); gf_bt_parse_float(parser, name, & col->green); gf_bt_check_code(parser, ','); gf_bt_parse_float(parser, name, & col->blue); gf_bt_check_code(parser, ','); gf_bt_parse_float(parser, name, & col->alpha); return parser->last_error;}static void gf_bt_offset_time(GF_BTParser *parser, Double *time){ if (!parser->is_wrl) { Double res; res = parser->au_time; res /= parser->bifs_es->timeScale; *time += res; }}static void gf_bt_check_time_offset(GF_BTParser *parser, GF_Node *n, GF_FieldInfo *info){ if (!n || !(parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK)) return; if (gf_node_get_tag(n) != TAG_ProtoNode) { if (!stricmp(info->name, "startTime") || !stricmp(info->name, "stopTime")) gf_bt_offset_time(parser, (Double *)info->far_ptr); } else if (gf_sg_proto_field_is_sftime_offset(n, info)) { gf_bt_offset_time(parser, (Double *)info->far_ptr); }}static void gf_bt_update_timenode(GF_BTParser *parser, GF_Node *node){ if (!node || !(parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK)) return; switch (gf_node_get_tag(node)) { case TAG_MPEG4_AnimationStream: gf_bt_offset_time(parser, & ((M_AnimationStream*)node)->startTime); gf_bt_offset_time(parser, & ((M_AnimationStream*)node)->stopTime); break; case TAG_MPEG4_AudioBuffer: gf_bt_offset_time(parser, & ((M_AudioBuffer*)node)->startTime); gf_bt_offset_time(parser, & ((M_AudioBuffer*)node)->stopTime); break; case TAG_MPEG4_AudioClip: gf_bt_offset_time(parser, & ((M_AudioClip*)node)->startTime); gf_bt_offset_time(parser, & ((M_AudioClip*)node)->stopTime); break; case TAG_MPEG4_AudioSource: gf_bt_offset_time(parser, & ((M_AudioSource*)node)->startTime); gf_bt_offset_time(parser, & ((M_AudioSource*)node)->stopTime); break; case TAG_MPEG4_MovieTexture: gf_bt_offset_time(parser, & ((M_MovieTexture*)node)->startTime); gf_bt_offset_time(parser, & ((M_MovieTexture*)node)->stopTime); break; case TAG_MPEG4_TimeSensor: gf_bt_offset_time(parser, & ((M_TimeSensor*)node)->startTime); gf_bt_offset_time(parser, & ((M_TimeSensor*)node)->stopTime); break; case TAG_ProtoNode: { u32 i, nbFields; GF_FieldInfo inf; nbFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL); for (i=0; i<nbFields; i++) { gf_node_get_field(node, i, &inf); if (inf.fieldType != GF_SG_VRML_SFTIME) continue; gf_bt_check_time_offset(parser, node, &inf); } } break; }}void gf_bt_sffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n){ switch (info->fieldType) { case GF_SG_VRML_SFINT32: gf_bt_parse_int(parser, info->name, (SFInt32 *)info->far_ptr); if (parser->last_error) return; break; case GF_SG_VRML_SFBOOL: gf_bt_parse_bool(parser, info->name, (SFBool *)info->far_ptr); if (parser->last_error) return; break; case GF_SG_VRML_SFFLOAT: gf_bt_parse_float(parser, info->name, (SFFloat *)info->far_ptr); if (parser->last_error) return; break; case GF_SG_VRML_SFDOUBLE: gf_bt_parse_double(parser, info->name, (SFDouble *)info->far_ptr); if (parser->last_error) return; break; case GF_SG_VRML_SFTIME: gf_bt_parse_double(parser, info->name, (SFDouble *)info->far_ptr); if (parser->last_error) return; gf_bt_check_time_offset(parser, n, info); break; case GF_SG_VRML_SFCOLOR: gf_bt_parse_color(parser, info->name, (SFColor *)info->far_ptr); break; case GF_SG_VRML_SFCOLORRGBA: gf_bt_parse_colorRGBA(parser, info->name, (SFColorRGBA *)info->far_ptr); break; case GF_SG_VRML_SFVEC2F: gf_bt_parse_float(parser, info->name, & ((SFVec2f *)info->far_ptr)->x); if (parser->last_error) return; /*many VRML files use ',' separator*/ gf_bt_check_code(parser, ','); gf_bt_parse_float(parser, info->name, & ((SFVec2f *)info->far_ptr)->y); if (parser->last_error) return; break; case GF_SG_VRML_SFVEC2D: gf_bt_parse_double(parser, info->name, & ((SFVec2d *)info->far_ptr)->x); if (parser->last_error) return; /*many VRML files use ',' separator*/ gf_bt_check_code(parser, ','); gf_bt_parse_double(parser, info->name, & ((SFVec2d *)info->far_ptr)->y); if (parser->last_error) return; break; case GF_SG_VRML_SFVEC3F: gf_bt_parse_float(parser, info->name, & ((SFVec3f *)info->far_ptr)->x); if (parser->last_error) return; /*many VRML files use ',' separator*/ gf_bt_check_code(parser, ','); gf_bt_parse_float(parser, info->name, & ((SFVec3f *)info->far_ptr)->y); if (parser->last_error) return; /*many VRML files use ',' separator*/ gf_bt_check_code(parser, ','); gf_bt_parse_float(parser, info->name, & ((SFVec3f *)info->far_ptr)->z); if (parser->last_error) return; break; case GF_SG_VRML_SFVEC3D: gf_bt_parse_double(parser, info->name, & ((SFVec3d *)info->far_ptr)->x); if (parser->last_error) return; /*many VRML files use ',' separator*/ gf_bt_check_code(parser, ','); gf_bt_parse_double(parser, info->name, & ((SFVec3d *)info->far_ptr)->y); if (parser->last_error) return; /*many VRML files use ',' separator*/ gf_bt_check_code(parser, ','); gf_bt_parse_double(parser, info->name, & ((SFVec3d *)info->far_ptr)->z); if (parser->last_error) return; break; case GF_SG_VRML_SFROTATION: gf_bt_parse_float(parser, info->name, & ((SFRotation *)info->far_ptr)->x); if (parser->last_error) return; gf_bt_parse_float(parser, info->name, & ((SFRotation *)info->far_ptr)->y); if (parser->last_error) return; gf_bt_parse_float(parser, info->name, & ((SFRotation *)info->far_ptr)->z); if (parser->last_error) return; gf_bt_parse_float(parser, info->name, & ((SFRotation *)info->far_ptr)->q); if (parser->last_error) return; break; case GF_SG_VRML_SFSTRING: if (gf_bt_check_code(parser, '\"') || gf_bt_check_code(parser, '\'')) { char *str = gf_bt_get_string(parser); if (!str) goto err; if (((SFString *)info->far_ptr)->buffer) free(((SFString *)info->far_ptr)->buffer); ((SFString *)info->far_ptr)->buffer = NULL; if (strlen(str)) ((SFString *)info->far_ptr)->buffer = str; else free(str); } else { goto err; } break; case GF_SG_VRML_SFURL: if (gf_bt_check_code(parser, '\"') || gf_bt_check_code(parser, '\'')) { SFURL *url = (SFURL *)info->far_ptr; char *str = gf_bt_get_string(parser); if (!str) goto err; if (url->url) free(url->url); url->url = NULL; url->OD_ID = 0; if (strchr(str, '#')) { url->url = str; } else { u32 id = 0; char *odstr = str; if (!strnicmp(str, "od:", 3)) odstr += 3; /*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/ if (sscanf(odstr, "%d", &id) == 1) { char szURL[20]; sprintf(szURL, "%d", id); if (strcmp(szURL, odstr)) id=0; } if (id) { url->OD_ID = id; free(str); } else { url->url = str; } } } else { s32 val; gf_bt_parse_int(parser, info->name, & val ); if (parser->last_error) return; ((SFURL *)info->far_ptr)->OD_ID = val; } break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *cb = (SFCommandBuffer *)info->far_ptr; if (gf_bt_check_code(parser, '{')) { GF_Command *prev_com = parser->cur_com; while (!parser->last_error) { if (gf_bt_check_code(parser, '}')) break; parser->last_error = gf_bt_parse_bifs_command(parser, NULL, cb->commandList); } parser->cur_com = prev_com; } } break; case GF_SG_VRML_SFIMAGE: { u32 i, size, v; char *str; SFImage *img = (SFImage *)info->far_ptr; gf_bt_parse_int(parser, "width", (SFInt32 *)&img->width);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -