PageRenderTime 73ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/ext/gpac/src/scene_manager/loader_bt.c

https://github.com/paulcbetts/yikes
C | 3354 lines | 3266 code | 47 blank | 41 comment | 108 complexity | 28cd8dfc0a20318e11e15877ce58beaa MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, BSD-3-Clause, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. /*
  2. * GPAC - Multimedia Framework C SDK
  3. *
  4. * Copyright (c) Jean Le Feuvre 2000-2005
  5. * All rights reserved
  6. *
  7. * This file is part of GPAC / Scene Management sub-project
  8. *
  9. * GPAC is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation; either version 2, or (at your option)
  12. * any later version.
  13. *
  14. * GPAC is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; see the file COPYING. If not, write to
  21. * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22. *
  23. */
  24. #include <gpac/scene_manager.h>
  25. #include <gpac/utf.h>
  26. #include <gpac/constants.h>
  27. #include <gpac/internal/bifs_dev.h>
  28. #include <gpac/internal/scenegraph_dev.h>
  29. #include <gpac/nodes_x3d.h>
  30. /*for key codes...*/
  31. #include <gpac/user.h>
  32. /*since 0.2.2, we use zlib for bt reading to handle wrl.gz files*/
  33. #include <zlib.h>
  34. void gf_sm_load_done_BT(GF_SceneLoader *load);
  35. #define BT_LINE_SIZE 4000
  36. typedef struct
  37. {
  38. char *name;
  39. char *value;
  40. } BTDefSymbol;
  41. typedef struct
  42. {
  43. GF_SceneLoader *load;
  44. gzFile gz_in;
  45. u32 file_size, file_pos;
  46. /*create from string only*/
  47. GF_List *top_nodes;
  48. GF_Err last_error;
  49. u32 line;
  50. Bool done;
  51. u32 is_wrl;
  52. /*0: no unicode, 1: UTF-16BE, 2: UTF-16LE*/
  53. u32 unicode_type;
  54. GF_List *def_symbols;
  55. /*routes are not created in the graph when parsing, so we need to track insert and delete/replace*/
  56. GF_List *unresolved_routes, *inserted_routes, *peeked_nodes;
  57. GF_List *undef_nodes, *def_nodes;
  58. char *line_buffer;
  59. char cur_buffer[500];
  60. s32 line_size, line_pos, line_start_pos;
  61. /*set when parsing proto*/
  62. GF_Proto *parsing_proto;
  63. Bool is_extern_proto_field;
  64. /*current stream ID, AU time and RAP flag*/
  65. u32 stream_id;
  66. u32 au_time;
  67. Bool au_is_rap;
  68. /*current BIFS stream & AU*/
  69. GF_StreamContext *bifs_es;
  70. GF_AUContext *bifs_au;
  71. u32 base_bifs_id;
  72. GF_Command *cur_com;
  73. /*current OD stream & AU*/
  74. GF_StreamContext *od_es;
  75. GF_AUContext *od_au;
  76. u32 base_od_id;
  77. GF_List *scripts;
  78. } GF_BTParser;
  79. GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdList);
  80. GF_Route *gf_bt_parse_route(GF_BTParser *parser, Bool skip_def, Bool is_insert, GF_Command *com);
  81. void gf_bt_resolve_routes(GF_BTParser *parser, Bool clean);
  82. static GF_Err gf_bt_report(GF_BTParser *parser, GF_Err e, char *format, ...)
  83. {
  84. #ifndef GPAC_DISABLE_LOG
  85. if (gf_log_get_level() && (gf_log_get_tools() & GF_LOG_PARSER)) {
  86. char szMsg[2048];
  87. va_list args;
  88. va_start(args, format);
  89. vsprintf(szMsg, format, args);
  90. va_end(args);
  91. GF_LOG((u32) (e ? GF_LOG_ERROR : GF_LOG_WARNING), GF_LOG_PARSER, ("[BT/WRL Parsing] %s (line %d)\n", szMsg, parser->line));
  92. }
  93. #endif
  94. if (e) parser->last_error = e;
  95. return e;
  96. }
  97. GF_Node *gf_bt_new_node(GF_BTParser *parser, u32 tag)
  98. {
  99. GF_Node *n = gf_node_new(parser->load->scene_graph, tag);
  100. return n;
  101. }
  102. void gf_bt_check_line(GF_BTParser *parser)
  103. {
  104. while (1) {
  105. switch (parser->line_buffer[parser->line_pos]) {
  106. case ' ':
  107. case '\t':
  108. case '\n':
  109. case '\r':
  110. parser->line_pos++;
  111. continue;
  112. default:
  113. break;
  114. }
  115. break;
  116. }
  117. if (parser->line_buffer[parser->line_pos]=='#') {
  118. parser->line_size = parser->line_pos;
  119. }
  120. else if ((parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/') ) parser->line_size = parser->line_pos;
  121. if (parser->line_size == parser->line_pos) {
  122. /*string based input - done*/
  123. if (!parser->gz_in) {
  124. parser->done = 1;
  125. return;
  126. }
  127. next_line:
  128. parser->line_start_pos = gztell(parser->gz_in);
  129. parser->line_buffer[0] = 0;
  130. if (parser->unicode_type) {
  131. u8 c1, c2;
  132. unsigned short wchar;
  133. unsigned short l[BT_LINE_SIZE];
  134. unsigned short *dst = l;
  135. Bool is_ret = 0;
  136. u32 last_space_pos, last_space_pos_stream;
  137. u32 go = BT_LINE_SIZE - 1;
  138. last_space_pos = last_space_pos_stream = 0;
  139. while (go && !gzeof(parser->gz_in) ) {
  140. c1 = gzgetc(parser->gz_in);
  141. c2 = gzgetc(parser->gz_in);
  142. /*Little-endian order*/
  143. if (parser->unicode_type==2) {
  144. if (c2) { wchar = c2; wchar <<=8; wchar |= c1; }
  145. else wchar = c1;
  146. } else {
  147. wchar = c1;
  148. if (c2) { wchar <<= 8; wchar |= c2;}
  149. }
  150. *dst = wchar;
  151. if (wchar=='\r') is_ret = 1;
  152. else if (wchar=='\n') {
  153. dst++;
  154. break;
  155. }
  156. else if (is_ret && wchar!='\n') {
  157. u32 fpos = gztell(parser->gz_in);
  158. gzseek(parser->gz_in, fpos-2, SEEK_SET);
  159. is_ret = 1;
  160. break;
  161. }
  162. if (wchar==' ') {
  163. last_space_pos_stream = gztell(parser->gz_in);
  164. last_space_pos = dst - l;
  165. }
  166. dst++;
  167. go--;
  168. }
  169. *dst = 0;
  170. /*long line, rewind stream to last space*/
  171. if (!go) {
  172. u32 rew_pos = gztell(parser->gz_in) - 2*(dst - &l[last_space_pos]);
  173. gzseek(parser->gz_in, rew_pos, SEEK_SET);
  174. l[last_space_pos+1] = 0;
  175. }
  176. /*check eof*/
  177. if (l[0]==0xFFFF) {
  178. parser->done = 1;
  179. return;
  180. }
  181. /*convert to mbc string*/
  182. dst = l;
  183. gf_utf8_wcstombs(parser->line_buffer, BT_LINE_SIZE, (const unsigned short **) &dst);
  184. if (!strlen(parser->line_buffer) && gzeof(parser->gz_in)) {
  185. parser->done = 1;
  186. return;
  187. }
  188. } else {
  189. if ((gzgets(parser->gz_in, parser->line_buffer, BT_LINE_SIZE) == NULL)
  190. || (!strlen(parser->line_buffer) && gzeof(parser->gz_in))) {
  191. parser->done = 1;
  192. return;
  193. }
  194. /*watchout for long lines*/
  195. if (1 + strlen(parser->line_buffer) == BT_LINE_SIZE) {
  196. u32 rew, pos, go;
  197. rew = 0;
  198. go = 1;
  199. while (go) {
  200. switch (parser->line_buffer[strlen(parser->line_buffer)-1]) {
  201. case ' ':
  202. case ',':
  203. case '[':
  204. case ']':
  205. go = 0;
  206. break;
  207. default:
  208. parser->line_buffer[strlen(parser->line_buffer)-1] = 0;
  209. rew++;
  210. break;
  211. }
  212. }
  213. pos = gztell(parser->gz_in);
  214. gzseek(parser->gz_in, pos-rew, SEEK_SET);
  215. }
  216. }
  217. while (1) {
  218. char c;
  219. u32 len = strlen(parser->line_buffer);
  220. if (!len) break;
  221. c = parser->line_buffer[len-1];
  222. if (!strchr("\n\r\t", c)) break;
  223. parser->line_buffer[len-1] = 0;
  224. }
  225. parser->line_size = strlen(parser->line_buffer);
  226. parser->line_pos = 0;
  227. parser->line++;
  228. {
  229. u32 pos = gztell(parser->gz_in);
  230. if (pos>=parser->file_pos) {
  231. parser->file_pos = pos;
  232. if (parser->line>1) gf_set_progress("BT Parsing", pos, parser->file_size);
  233. }
  234. }
  235. while ((parser->line_buffer[parser->line_pos]==' ') || (parser->line_buffer[parser->line_pos]=='\t'))
  236. parser->line_pos++;
  237. if ( (parser->line_buffer[parser->line_pos]=='#')
  238. || ( (parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/')) ) {
  239. if (parser->line==1) {
  240. if (strstr(parser->line_buffer, "VRML")) {
  241. if (strstr(parser->line_buffer, "VRML V2.0")) parser->is_wrl = 1;
  242. /*although not std, many files use this*/
  243. else if (strstr(parser->line_buffer, "VRML2.0")) parser->is_wrl = 1;
  244. else {
  245. gf_bt_report(parser, GF_NOT_SUPPORTED, "%s: VRML Version Not Supported", parser->line_buffer);
  246. return;
  247. }
  248. }
  249. else if (strstr(parser->line_buffer, "X3D")) {
  250. if (strstr(parser->line_buffer, "X3D V3.0")) parser->is_wrl = 2;
  251. else {
  252. gf_bt_report(parser, GF_NOT_SUPPORTED, "%s: X3D Version Not Supported", parser->line_buffer);
  253. return;
  254. }
  255. }
  256. }
  257. if (!strnicmp(parser->line_buffer+parser->line_pos, "#define ", 8)) {
  258. char *buf, *sep;
  259. parser->line_pos+=8;
  260. buf = parser->line_buffer+parser->line_pos;
  261. sep = strchr(buf, ' ');
  262. if (sep && (sep[1]!='\n') ) {
  263. BTDefSymbol *def;
  264. GF_SAFEALLOC(def, BTDefSymbol);
  265. sep[0] = 0;
  266. def->name = strdup(buf);
  267. sep[0] = ' ';
  268. buf = sep+1;
  269. while (strchr(" \t", buf[0])) buf++;
  270. def->value = strdup(buf);
  271. gf_list_add(parser->def_symbols, def);
  272. }
  273. }
  274. goto next_line;
  275. }
  276. /*brute-force replacement of defined symbols (!!FIXME - no mem checking done !!)*/
  277. if (parser->line_pos < parser->line_size) {
  278. u32 i, count;
  279. count = gf_list_count(parser->def_symbols);
  280. while (1) {
  281. Bool found = 0;
  282. for (i=0; i<count; i++) {
  283. u32 symb_len, val_len, copy_len;
  284. BTDefSymbol *def = (BTDefSymbol *)gf_list_get(parser->def_symbols, i);
  285. char *start = strstr(parser->line_buffer, def->name);
  286. if (!start) continue;
  287. symb_len = strlen(def->name);
  288. if (!strchr(" \n\r\t,[]{}\'\"", start[symb_len])) continue;
  289. val_len = strlen(def->value);
  290. copy_len = strlen(start + symb_len) + 1;
  291. memmove(start + val_len, start + symb_len, sizeof(char)*copy_len);
  292. memcpy(start, def->value, sizeof(char)*val_len);
  293. parser->line_size = strlen(parser->line_buffer);
  294. found = 1;
  295. }
  296. if (!found) break;
  297. }
  298. }
  299. }
  300. if (!parser->line_size) {
  301. if (!gzeof(parser->gz_in)) gf_bt_check_line(parser);
  302. else parser->done = 1;
  303. }
  304. else if (!parser->done && (parser->line_size == parser->line_pos)) gf_bt_check_line(parser);
  305. }
  306. void gf_bt_force_line(GF_BTParser *parser)
  307. {
  308. parser->line_pos = parser->line_size;
  309. }
  310. Bool gf_bt_check_code(GF_BTParser *parser, char code)
  311. {
  312. gf_bt_check_line(parser);
  313. if (parser->line_buffer[parser->line_pos]==code) {
  314. parser->line_pos++;
  315. return 1;
  316. }
  317. return 0;
  318. }
  319. char *gf_bt_get_next(GF_BTParser *parser, Bool point_break)
  320. {
  321. u32 has_quote;
  322. Bool go = 1;
  323. s32 i;
  324. gf_bt_check_line(parser);
  325. i=0;
  326. has_quote = 0;
  327. while (go) {
  328. if (parser->line_buffer[parser->line_pos + i] == '\"') {
  329. if (!has_quote) has_quote = 1;
  330. else has_quote = 0;
  331. parser->line_pos += 1;
  332. if (parser->line_pos+i==parser->line_size) break;
  333. continue;
  334. }
  335. if (!has_quote) {
  336. switch (parser->line_buffer[parser->line_pos + i]) {
  337. case 0:
  338. case ' ':
  339. case '\t':
  340. case '{':
  341. case '}':
  342. case ']':
  343. case '[':
  344. case ',':
  345. go = 0;
  346. break;
  347. case '.':
  348. if (point_break) go = 0;
  349. break;
  350. }
  351. if (!go) break;
  352. }
  353. parser->cur_buffer[i] = parser->line_buffer[parser->line_pos + i];
  354. i++;
  355. if (parser->line_pos+i==parser->line_size) break;
  356. }
  357. parser->cur_buffer[i] = 0;
  358. parser->line_pos += i;
  359. return parser->cur_buffer;
  360. }
  361. char *gf_bt_get_string(GF_BTParser *parser)
  362. {
  363. char *res;
  364. s32 i, size;
  365. #define BT_STR_CHECK_ALLOC \
  366. if (i==size) { \
  367. res = (char*)realloc(res, sizeof(char) * (size+500)); \
  368. size += 500; \
  369. } \
  370. res = (char*)malloc(sizeof(char) * 500);
  371. size = 500;
  372. while (parser->line_buffer[parser->line_pos]==' ') parser->line_pos++;
  373. if (parser->line_pos==parser->line_size) {
  374. if (gzeof(parser->gz_in)) return NULL;
  375. gf_bt_check_line(parser);
  376. }
  377. i=0;
  378. while (1) {
  379. if (parser->line_buffer[parser->line_pos] == '\"')
  380. if (parser->line_buffer[parser->line_pos-1] != '\\') break;
  381. BT_STR_CHECK_ALLOC
  382. if ((parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/') && (parser->line_buffer[parser->line_pos-1]!=':') ) {
  383. /*this looks like a comment*/
  384. if (!strstr(&parser->line_buffer[parser->line_pos], "\"")) {
  385. gf_bt_check_line(parser);
  386. continue;
  387. }
  388. }
  389. if ((parser->line_buffer[parser->line_pos] != '\\') || (parser->line_buffer[parser->line_pos+1] != '"')) {
  390. /*handle UTF-8 - WARNING: if parser is in unicode string is already utf8 multibyte chars*/
  391. if (!parser->unicode_type && parser->line_buffer[parser->line_pos] & 0x80) {
  392. char c = parser->line_buffer[parser->line_pos];
  393. /*non UTF8 (likely some win-CP)*/
  394. if ( (parser->line_buffer[parser->line_pos+1] & 0xc0) != 0x80) {
  395. res[i] = 0xc0 | ( (parser->line_buffer[parser->line_pos] >> 6) & 0x3 );
  396. i++;
  397. BT_STR_CHECK_ALLOC
  398. parser->line_buffer[parser->line_pos] &= 0xbf;
  399. }
  400. /*UTF8 2 bytes char*/
  401. else if ( (c & 0xe0) == 0xc0) {
  402. res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++;
  403. BT_STR_CHECK_ALLOC
  404. }
  405. /*UTF8 3 bytes char*/
  406. else if ( (c & 0xf0) == 0xe0) {
  407. res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++;
  408. BT_STR_CHECK_ALLOC
  409. res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++;
  410. BT_STR_CHECK_ALLOC
  411. }
  412. /*UTF8 4 bytes char*/
  413. else if ( (c & 0xf8) == 0xf0) {
  414. res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++;
  415. BT_STR_CHECK_ALLOC
  416. res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++;
  417. BT_STR_CHECK_ALLOC
  418. res[i] = parser->line_buffer[parser->line_pos]; parser->line_pos++; i++;
  419. BT_STR_CHECK_ALLOC
  420. }
  421. }
  422. res[i] = parser->line_buffer[parser->line_pos];
  423. i++;
  424. }
  425. parser->line_pos++;
  426. if (parser->line_pos==parser->line_size) {
  427. gf_bt_check_line(parser);
  428. }
  429. }
  430. #undef BT_STR_CHECK_ALLOC
  431. res[i] = 0;
  432. parser->line_pos += 1;
  433. return res;
  434. }
  435. Bool gf_bt_check_externproto_field(GF_BTParser *parser, char *str)
  436. {
  437. if (!parser->is_extern_proto_field) return 0;
  438. if (!strcmp(str, "") || !strcmp(str, "field") || !strcmp(str, "eventIn") || !strcmp(str, "eventOut") || !strcmp(str, "exposedField")) {
  439. parser->last_error = GF_EOS;
  440. return 1;
  441. }
  442. return 0;
  443. }
  444. static Bool check_keyword(GF_BTParser *parser, char *str, s32 *val)
  445. {
  446. s32 res;
  447. char *sep;
  448. sep = strchr(str, '$');
  449. if (!sep) return 0;
  450. sep++;
  451. if (!strcmp(sep, "F1")) res = GF_KEY_F1;
  452. else if (!strcmp(sep, "F2")) res = GF_KEY_F2;
  453. else if (!strcmp(sep, "F3")) res = GF_KEY_F3;
  454. else if (!strcmp(sep, "F4")) res = GF_KEY_F4;
  455. else if (!strcmp(sep, "F5")) res = GF_KEY_F5;
  456. else if (!strcmp(sep, "F6")) res = GF_KEY_F6;
  457. else if (!strcmp(sep, "F7")) res = GF_KEY_F7;
  458. else if (!strcmp(sep, "F8")) res = GF_KEY_F8;
  459. else if (!strcmp(sep, "F9")) res = GF_KEY_F9;
  460. else if (!strcmp(sep, "F10")) res = GF_KEY_F10;
  461. else if (!strcmp(sep, "F11")) res = GF_KEY_F11;
  462. else if (!strcmp(sep, "F12")) res = GF_KEY_F12;
  463. else if (!strcmp(sep, "HOME")) res = GF_KEY_HOME;
  464. else if (!strcmp(sep, "END")) res = GF_KEY_END;
  465. else if (!strcmp(sep, "PREV")) res = GF_KEY_PAGEUP;
  466. else if (!strcmp(sep, "NEXT")) res = GF_KEY_PAGEDOWN;
  467. else if (!strcmp(sep, "UP")) res = GF_KEY_UP;
  468. else if (!strcmp(sep, "DOWN")) res = GF_KEY_DOWN;
  469. else if (!strcmp(sep, "LEFT")) res = GF_KEY_LEFT;
  470. else if (!strcmp(sep, "RIGHT")) res = GF_KEY_RIGHT;
  471. else if (!strcmp(sep, "RETURN")) res = GF_KEY_ENTER;
  472. else if (!strcmp(sep, "BACK")) res = GF_KEY_BACKSPACE;
  473. else if (!strcmp(sep, "TAB")) res = GF_KEY_TAB;
  474. else if (strlen(sep)==1) {
  475. char c;
  476. sscanf(sep, "%c", &c);
  477. res = c;
  478. } else {
  479. gf_bt_report(parser, GF_OK, "unrecognized keyword %s - skipping", str);
  480. res = 0;
  481. }
  482. if (strchr(str, '-')) *val = -res;
  483. else *val = res;
  484. return 1;
  485. }
  486. GF_Err gf_bt_parse_float(GF_BTParser *parser, const char *name, Fixed *val)
  487. {
  488. s32 var;
  489. Float f;
  490. char *str = gf_bt_get_next(parser, 0);
  491. if (!str) return parser->last_error = GF_IO_ERR;
  492. if (gf_bt_check_externproto_field(parser, str)) return GF_OK;
  493. if (check_keyword(parser, str, &var)) {
  494. *val = INT2FIX(var);
  495. return GF_OK;
  496. }
  497. if (sscanf(str, "%g", &f) != 1) {
  498. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name);
  499. }
  500. *val = FLT2FIX(f);
  501. return GF_OK;
  502. }
  503. GF_Err gf_bt_parse_double(GF_BTParser *parser, const char *name, SFDouble *val)
  504. {
  505. char *str = gf_bt_get_next(parser, 0);
  506. if (!str) return parser->last_error = GF_IO_ERR;
  507. if (gf_bt_check_externproto_field(parser, str)) return GF_OK;
  508. if (sscanf(str, "%lf", val) != 1) {
  509. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name);
  510. }
  511. return GF_OK;
  512. }
  513. GF_Err gf_bt_parse_int(GF_BTParser *parser, const char *name, SFInt32 *val)
  514. {
  515. char *str = gf_bt_get_next(parser, 0);
  516. if (!str) return parser->last_error = GF_IO_ERR;
  517. if (gf_bt_check_externproto_field(parser, str)) return GF_OK;
  518. if (check_keyword(parser, str, val)) return GF_OK;
  519. /*URL ODID*/
  520. if (!strnicmp(str, "od:", 3)) str += 3;
  521. if (sscanf(str, "%d", val) != 1) {
  522. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name);
  523. }
  524. return GF_OK;
  525. }
  526. GF_Err gf_bt_parse_bool(GF_BTParser *parser, const char *name, SFBool *val)
  527. {
  528. char *str = gf_bt_get_next(parser, 0);
  529. if (!str) return parser->last_error = GF_IO_ERR;
  530. if (gf_bt_check_externproto_field(parser, str)) return GF_OK;
  531. if (!stricmp(str, "true") || !strcmp(str, "1") ) {
  532. *val = 1;
  533. }
  534. else if (!stricmp(str, "false") || !strcmp(str, "0") ) {
  535. *val = 0;
  536. } else {
  537. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Boolean expected", name);
  538. }
  539. return GF_OK;
  540. }
  541. GF_Err gf_bt_parse_color(GF_BTParser *parser, const char *name, SFColor *col)
  542. {
  543. Float f;
  544. char *str = gf_bt_get_next(parser, 0);
  545. if (!str) return parser->last_error = GF_IO_ERR;
  546. if (gf_bt_check_externproto_field(parser, str)) return GF_OK;
  547. /*HTML code*/
  548. if (str[0]=='$') {
  549. u32 val;
  550. sscanf(str+1, "%x", &val);
  551. col->red = INT2FIX((val>>16) & 0xFF) / 255;
  552. col->green = INT2FIX((val>>8) & 0xFF) / 255;
  553. col->blue = INT2FIX(val & 0xFF) / 255;
  554. return parser->last_error;
  555. }
  556. if (sscanf(str, "%f", &f) != 1) {
  557. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name);
  558. }
  559. col->red = FLT2FIX(f);
  560. /*many VRML files use ',' separator*/
  561. gf_bt_check_code(parser, ',');
  562. gf_bt_parse_float(parser, name, & col->green);
  563. gf_bt_check_code(parser, ',');
  564. gf_bt_parse_float(parser, name, & col->blue);
  565. return parser->last_error;
  566. }
  567. GF_Err gf_bt_parse_colorRGBA(GF_BTParser *parser, const char *name, SFColorRGBA *col)
  568. {
  569. Float f;
  570. char *str = gf_bt_get_next(parser, 0);
  571. if (!str) return parser->last_error = GF_IO_ERR;
  572. if (gf_bt_check_externproto_field(parser, str)) return GF_OK;
  573. /*HTML code*/
  574. if (str[0]=='$') {
  575. u32 val;
  576. sscanf(str, "%x", &val);
  577. col->red = INT2FIX((val>>24) & 0xFF) / 255;
  578. col->green = INT2FIX((val>>16) & 0xFF) / 255;
  579. col->blue = INT2FIX((val>>8) & 0xFF) / 255;
  580. col->alpha = INT2FIX(val & 0xFF) / 255;
  581. return parser->last_error;
  582. }
  583. if (sscanf(str, "%f", &f) != 1) {
  584. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name);
  585. }
  586. col->red = FLT2FIX(f);
  587. gf_bt_check_code(parser, ',');
  588. gf_bt_parse_float(parser, name, & col->green);
  589. gf_bt_check_code(parser, ',');
  590. gf_bt_parse_float(parser, name, & col->blue);
  591. gf_bt_check_code(parser, ',');
  592. gf_bt_parse_float(parser, name, & col->alpha);
  593. return parser->last_error;
  594. }
  595. static void gf_bt_offset_time(GF_BTParser *parser, Double *time)
  596. {
  597. if (!parser->is_wrl) {
  598. Double res;
  599. res = parser->au_time;
  600. res /= parser->bifs_es->timeScale;
  601. *time += res;
  602. }
  603. }
  604. static void gf_bt_check_time_offset(GF_BTParser *parser, GF_Node *n, GF_FieldInfo *info)
  605. {
  606. if (!n || !(parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK)) return;
  607. if (gf_node_get_tag(n) != TAG_ProtoNode) {
  608. if (!stricmp(info->name, "startTime") || !stricmp(info->name, "stopTime"))
  609. gf_bt_offset_time(parser, (Double *)info->far_ptr);
  610. } else if (gf_sg_proto_field_is_sftime_offset(n, info)) {
  611. gf_bt_offset_time(parser, (Double *)info->far_ptr);
  612. }
  613. }
  614. static void gf_bt_update_timenode(GF_BTParser *parser, GF_Node *node)
  615. {
  616. if (!node || !(parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK)) return;
  617. switch (gf_node_get_tag(node)) {
  618. case TAG_MPEG4_AnimationStream:
  619. gf_bt_offset_time(parser, & ((M_AnimationStream*)node)->startTime);
  620. gf_bt_offset_time(parser, & ((M_AnimationStream*)node)->stopTime);
  621. break;
  622. case TAG_MPEG4_AudioBuffer:
  623. gf_bt_offset_time(parser, & ((M_AudioBuffer*)node)->startTime);
  624. gf_bt_offset_time(parser, & ((M_AudioBuffer*)node)->stopTime);
  625. break;
  626. case TAG_MPEG4_AudioClip:
  627. gf_bt_offset_time(parser, & ((M_AudioClip*)node)->startTime);
  628. gf_bt_offset_time(parser, & ((M_AudioClip*)node)->stopTime);
  629. break;
  630. case TAG_MPEG4_AudioSource:
  631. gf_bt_offset_time(parser, & ((M_AudioSource*)node)->startTime);
  632. gf_bt_offset_time(parser, & ((M_AudioSource*)node)->stopTime);
  633. break;
  634. case TAG_MPEG4_MovieTexture:
  635. gf_bt_offset_time(parser, & ((M_MovieTexture*)node)->startTime);
  636. gf_bt_offset_time(parser, & ((M_MovieTexture*)node)->stopTime);
  637. break;
  638. case TAG_MPEG4_TimeSensor:
  639. gf_bt_offset_time(parser, & ((M_TimeSensor*)node)->startTime);
  640. gf_bt_offset_time(parser, & ((M_TimeSensor*)node)->stopTime);
  641. break;
  642. case TAG_ProtoNode:
  643. {
  644. u32 i, nbFields;
  645. GF_FieldInfo inf;
  646. nbFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL);
  647. for (i=0; i<nbFields; i++) {
  648. gf_node_get_field(node, i, &inf);
  649. if (inf.fieldType != GF_SG_VRML_SFTIME) continue;
  650. gf_bt_check_time_offset(parser, node, &inf);
  651. }
  652. }
  653. break;
  654. }
  655. }
  656. void gf_bt_sffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n)
  657. {
  658. switch (info->fieldType) {
  659. case GF_SG_VRML_SFINT32:
  660. gf_bt_parse_int(parser, info->name, (SFInt32 *)info->far_ptr);
  661. if (parser->last_error) return;
  662. break;
  663. case GF_SG_VRML_SFBOOL:
  664. gf_bt_parse_bool(parser, info->name, (SFBool *)info->far_ptr);
  665. if (parser->last_error) return;
  666. break;
  667. case GF_SG_VRML_SFFLOAT:
  668. gf_bt_parse_float(parser, info->name, (SFFloat *)info->far_ptr);
  669. if (parser->last_error) return;
  670. break;
  671. case GF_SG_VRML_SFDOUBLE:
  672. gf_bt_parse_double(parser, info->name, (SFDouble *)info->far_ptr);
  673. if (parser->last_error) return;
  674. break;
  675. case GF_SG_VRML_SFTIME:
  676. gf_bt_parse_double(parser, info->name, (SFDouble *)info->far_ptr);
  677. if (parser->last_error) return;
  678. gf_bt_check_time_offset(parser, n, info);
  679. break;
  680. case GF_SG_VRML_SFCOLOR:
  681. gf_bt_parse_color(parser, info->name, (SFColor *)info->far_ptr);
  682. break;
  683. case GF_SG_VRML_SFCOLORRGBA:
  684. gf_bt_parse_colorRGBA(parser, info->name, (SFColorRGBA *)info->far_ptr);
  685. break;
  686. case GF_SG_VRML_SFVEC2F:
  687. gf_bt_parse_float(parser, info->name, & ((SFVec2f *)info->far_ptr)->x);
  688. if (parser->last_error) return;
  689. /*many VRML files use ',' separator*/
  690. gf_bt_check_code(parser, ',');
  691. gf_bt_parse_float(parser, info->name, & ((SFVec2f *)info->far_ptr)->y);
  692. if (parser->last_error) return;
  693. break;
  694. case GF_SG_VRML_SFVEC2D:
  695. gf_bt_parse_double(parser, info->name, & ((SFVec2d *)info->far_ptr)->x);
  696. if (parser->last_error) return;
  697. /*many VRML files use ',' separator*/
  698. gf_bt_check_code(parser, ',');
  699. gf_bt_parse_double(parser, info->name, & ((SFVec2d *)info->far_ptr)->y);
  700. if (parser->last_error) return;
  701. break;
  702. case GF_SG_VRML_SFVEC3F:
  703. gf_bt_parse_float(parser, info->name, & ((SFVec3f *)info->far_ptr)->x);
  704. if (parser->last_error) return;
  705. /*many VRML files use ',' separator*/
  706. gf_bt_check_code(parser, ',');
  707. gf_bt_parse_float(parser, info->name, & ((SFVec3f *)info->far_ptr)->y);
  708. if (parser->last_error) return;
  709. /*many VRML files use ',' separator*/
  710. gf_bt_check_code(parser, ',');
  711. gf_bt_parse_float(parser, info->name, & ((SFVec3f *)info->far_ptr)->z);
  712. if (parser->last_error) return;
  713. break;
  714. case GF_SG_VRML_SFVEC3D:
  715. gf_bt_parse_double(parser, info->name, & ((SFVec3d *)info->far_ptr)->x);
  716. if (parser->last_error) return;
  717. /*many VRML files use ',' separator*/
  718. gf_bt_check_code(parser, ',');
  719. gf_bt_parse_double(parser, info->name, & ((SFVec3d *)info->far_ptr)->y);
  720. if (parser->last_error) return;
  721. /*many VRML files use ',' separator*/
  722. gf_bt_check_code(parser, ',');
  723. gf_bt_parse_double(parser, info->name, & ((SFVec3d *)info->far_ptr)->z);
  724. if (parser->last_error) return;
  725. break;
  726. case GF_SG_VRML_SFROTATION:
  727. gf_bt_parse_float(parser, info->name, & ((SFRotation *)info->far_ptr)->x);
  728. if (parser->last_error) return;
  729. gf_bt_parse_float(parser, info->name, & ((SFRotation *)info->far_ptr)->y);
  730. if (parser->last_error) return;
  731. gf_bt_parse_float(parser, info->name, & ((SFRotation *)info->far_ptr)->z);
  732. if (parser->last_error) return;
  733. gf_bt_parse_float(parser, info->name, & ((SFRotation *)info->far_ptr)->q);
  734. if (parser->last_error) return;
  735. break;
  736. case GF_SG_VRML_SFSTRING:
  737. if (gf_bt_check_code(parser, '\"') || gf_bt_check_code(parser, '\'')) {
  738. char *str = gf_bt_get_string(parser);
  739. if (!str)
  740. goto err;
  741. if (((SFString *)info->far_ptr)->buffer) free(((SFString *)info->far_ptr)->buffer);
  742. ((SFString *)info->far_ptr)->buffer = NULL;
  743. if (strlen(str))
  744. ((SFString *)info->far_ptr)->buffer = str;
  745. else
  746. free(str);
  747. } else {
  748. goto err;
  749. }
  750. break;
  751. case GF_SG_VRML_SFURL:
  752. if (gf_bt_check_code(parser, '\"') || gf_bt_check_code(parser, '\'')) {
  753. SFURL *url = (SFURL *)info->far_ptr;
  754. char *str = gf_bt_get_string(parser);
  755. if (!str) goto err;
  756. if (url->url) free(url->url);
  757. url->url = NULL;
  758. url->OD_ID = 0;
  759. if (strchr(str, '#')) {
  760. url->url = str;
  761. } else {
  762. u32 id = 0;
  763. char *odstr = str;
  764. if (!strnicmp(str, "od:", 3)) odstr += 3;
  765. /*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/
  766. if (sscanf(odstr, "%d", &id) == 1) {
  767. char szURL[20];
  768. sprintf(szURL, "%d", id);
  769. if (strcmp(szURL, odstr)) id=0;
  770. }
  771. if (id) {
  772. url->OD_ID = id;
  773. free(str);
  774. } else {
  775. url->url = str;
  776. }
  777. }
  778. } else {
  779. s32 val;
  780. gf_bt_parse_int(parser, info->name, & val );
  781. if (parser->last_error) return;
  782. ((SFURL *)info->far_ptr)->OD_ID = val;
  783. }
  784. break;
  785. case GF_SG_VRML_SFCOMMANDBUFFER:
  786. {
  787. SFCommandBuffer *cb = (SFCommandBuffer *)info->far_ptr;
  788. if (gf_bt_check_code(parser, '{')) {
  789. GF_Command *prev_com = parser->cur_com;
  790. while (!parser->last_error) {
  791. if (gf_bt_check_code(parser, '}')) break;
  792. parser->last_error = gf_bt_parse_bifs_command(parser, NULL, cb->commandList);
  793. }
  794. parser->cur_com = prev_com;
  795. }
  796. }
  797. break;
  798. case GF_SG_VRML_SFIMAGE:
  799. {
  800. u32 i, size, v;
  801. char *str;
  802. SFImage *img = (SFImage *)info->far_ptr;
  803. gf_bt_parse_int(parser, "width", (SFInt32 *)&img->width);
  804. if (parser->last_error) return;
  805. gf_bt_parse_int(parser, "height", (SFInt32 *)&img->height);
  806. if (parser->last_error) return;
  807. gf_bt_parse_int(parser, "nbComp", (SFInt32 *)&v);
  808. if (parser->last_error) return;
  809. img->numComponents = v;
  810. size = img->width * img->height * img->numComponents;
  811. if (img->pixels) free(img->pixels);
  812. img->pixels = (unsigned char*)malloc(sizeof(char) * size);
  813. for (i=0; i<size; i++) {
  814. str = gf_bt_get_next(parser, 0);
  815. if (strstr(str, "0x")) sscanf(str, "%x", &v);
  816. else sscanf(str, "%d", &v);
  817. switch (img->numComponents) {
  818. case 1:
  819. img->pixels[i] = (char) v;
  820. break;
  821. case 2:
  822. img->pixels[i] = (char) (v>>8)&0xFF;
  823. img->pixels[i+1] = (char) (v)&0xFF;
  824. i++;
  825. break;
  826. case 3:
  827. img->pixels[i] = (char) (v>>16)&0xFF;
  828. img->pixels[i+1] = (char) (v>>8)&0xFF;
  829. img->pixels[i+2] = (char) (v)&0xFF;
  830. i+=2;
  831. break;
  832. case 4:
  833. img->pixels[i] = (char) (v>>24)&0xFF;
  834. img->pixels[i+1] = (char) (v>>16)&0xFF;
  835. img->pixels[i+2] = (char) (v>>8)&0xFF;
  836. img->pixels[i+3] = (char) (v)&0xFF;
  837. i+=3;
  838. break;
  839. }
  840. }
  841. }
  842. break;
  843. case GF_SG_VRML_SFSCRIPT:
  844. {
  845. SFScript *sc = (SFScript *) info->far_ptr;
  846. if (!gf_bt_check_code(parser, '\"')) {
  847. gf_bt_report(parser, GF_BAD_PARAM, "\" expected in Script");
  848. }
  849. sc->script_text = (unsigned char*)gf_bt_get_string(parser);
  850. }
  851. break;
  852. default:
  853. parser->last_error = GF_NOT_SUPPORTED;
  854. break;
  855. }
  856. gf_bt_check_code(parser, ',');
  857. return;
  858. err:
  859. gf_bt_report(parser, GF_BAD_PARAM, "%s: Invalid field syntax", info->name);
  860. }
  861. void gf_bt_mffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n)
  862. {
  863. GF_FieldInfo sfInfo;
  864. Bool force_single = 0;
  865. if (!gf_bt_check_code(parser, '[')) {
  866. if (parser->is_extern_proto_field) return;
  867. force_single = 1;
  868. }
  869. sfInfo.fieldType = gf_sg_vrml_get_sf_type(info->fieldType);
  870. sfInfo.name = info->name;
  871. gf_sg_vrml_mf_reset(info->far_ptr, info->fieldType);
  872. while (!gf_bt_check_code(parser, ']')) {
  873. gf_sg_vrml_mf_append(info->far_ptr, info->fieldType, &sfInfo.far_ptr);
  874. gf_bt_sffield(parser, &sfInfo, n);
  875. if (parser->last_error) return;
  876. gf_bt_check_code(parser, ',');
  877. if (force_single) break;
  878. }
  879. }
  880. Bool gf_bt_check_ndt(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *node, GF_Node *parent)
  881. {
  882. if (!node) return 1;
  883. if (parent->sgprivate->tag == TAG_MPEG4_Script) return 1;
  884. if (parent->sgprivate->tag == TAG_X3D_Script) return 1;
  885. if (node->sgprivate->tag == TAG_UndefinedNode) return 1;
  886. /*this handles undefined nodes*/
  887. if (gf_node_in_table(node, info->NDTtype)) return 1;
  888. /*not found*/
  889. gf_bt_report(parser, GF_BAD_PARAM, "node %s not valid in field %s\n", gf_node_get_class_name(node), info->name);
  890. gf_node_unregister(node, parent);
  891. return 0;
  892. }
  893. u32 gf_bt_get_next_node_id(GF_BTParser *parser)
  894. {
  895. u32 ID;
  896. GF_SceneGraph *sc = parser->load->scene_graph;
  897. if (parser->parsing_proto) sc = gf_sg_proto_get_graph(parser->parsing_proto);
  898. ID = gf_sg_get_next_available_node_id(sc);
  899. if (parser->load->ctx && (ID>parser->load->ctx->max_node_id))
  900. parser->load->ctx->max_node_id = ID;
  901. return ID;
  902. }
  903. u32 gf_bt_get_next_route_id(GF_BTParser *parser)
  904. {
  905. u32 ID;
  906. GF_SceneGraph *sg = parser->load->scene_graph;
  907. if (parser->parsing_proto) sg = gf_sg_proto_get_graph(parser->parsing_proto);
  908. ID = gf_sg_get_next_available_route_id(sg);
  909. if (parser->load->ctx && (ID>parser->load->ctx->max_route_id))
  910. parser->load->ctx->max_route_id = ID;
  911. return ID;
  912. }
  913. u32 gf_bt_get_next_proto_id(GF_BTParser *parser)
  914. {
  915. u32 ID;
  916. GF_SceneGraph *sc = parser->load->scene_graph;
  917. if (parser->parsing_proto) sc = gf_sg_proto_get_graph(parser->parsing_proto);
  918. ID = gf_sg_get_next_available_proto_id(sc);
  919. if (parser->load->ctx && (ID>parser->load->ctx->max_node_id))
  920. parser->load->ctx->max_proto_id = ID;
  921. return ID;
  922. }
  923. u32 gf_bt_get_def_id(GF_BTParser *parser, char *defName)
  924. {
  925. GF_Node *n;
  926. u32 ID;
  927. if (sscanf(defName, "N%d", &ID) == 1) {
  928. ID ++;
  929. n = gf_sg_find_node(parser->load->scene_graph, ID);
  930. /*if an existing node use*/
  931. if (n) {
  932. u32 id;
  933. u32 nID = gf_bt_get_next_node_id(parser);
  934. const char *name = gf_node_get_name_and_id(n, &id);
  935. gf_bt_report(parser, GF_OK, "changing node \"%s\" ID from %d to %d", name, id -1, nID-1);
  936. gf_node_set_id(n, nID, name);
  937. }
  938. if (parser->load->ctx && (parser->load->ctx->max_node_id<ID)) parser->load->ctx->max_node_id=ID;
  939. } else {
  940. ID = gf_bt_get_next_node_id(parser);
  941. }
  942. return ID;
  943. }
  944. Bool gf_bt_set_field_is(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n)
  945. {
  946. GF_Err e;
  947. u32 i;
  948. GF_ProtoFieldInterface *pfield;
  949. GF_FieldInfo pinfo;
  950. char *str;
  951. gf_bt_check_line(parser);
  952. i=0;
  953. while ((parser->line_buffer[parser->line_pos + i] == ' ') || (parser->line_buffer[parser->line_pos + i] == '\t')) i++;
  954. if (strnicmp(&parser->line_buffer[parser->line_pos + i] , "IS", 2)) return 0;
  955. str = gf_bt_get_next(parser, 0);
  956. str = gf_bt_get_next(parser, 0);
  957. /*that's an ISed field*/
  958. pfield = gf_sg_proto_field_find_by_name(parser->parsing_proto, str);
  959. if (!pfield) {
  960. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown proto field", str);
  961. return 1;
  962. }
  963. gf_sg_proto_field_get_field(pfield, &pinfo);
  964. e = gf_sg_proto_field_set_ised(parser->parsing_proto, pinfo.fieldIndex, n, info->fieldIndex);
  965. if (e) gf_bt_report(parser, GF_BAD_PARAM, "IS: Invalid field type for field %s", info->name);
  966. return 1;
  967. }
  968. void gf_bt_check_unresolved_nodes(GF_BTParser *parser)
  969. {
  970. u32 i, count;
  971. count = gf_list_count(parser->undef_nodes);
  972. if (!count) return;
  973. for (i=0; i<count; i++) {
  974. GF_Node *n = (GF_Node *)gf_list_get(parser->undef_nodes, i);
  975. gf_bt_report(parser, GF_BAD_PARAM, "Cannot find node %s\n", gf_node_get_name(n) );
  976. }
  977. parser->last_error = GF_BAD_PARAM;
  978. }
  979. Bool gf_bt_has_been_def(GF_BTParser *parser, char *node_name)
  980. {
  981. u32 i, count;
  982. count = gf_list_count(parser->def_nodes);
  983. for (i=0; i<count; i++) {
  984. GF_Node *n = (GF_Node *) gf_list_get(parser->def_nodes, i);
  985. if (!strcmp(gf_node_get_name(n), node_name)) return 1;
  986. }
  987. return 0;
  988. }
  989. u32 gf_bt_get_node_tag(GF_BTParser *parser, char *node_name)
  990. {
  991. u32 tag;
  992. /*if VRML and allowing non MPEG4 nodes, use X3D*/
  993. if (parser->is_wrl && !(parser->load->flags & GF_SM_LOAD_MPEG4_STRICT)) {
  994. tag = gf_node_x3d_type_by_class_name(node_name);
  995. if (!tag) tag = gf_node_mpeg4_type_by_class_name(node_name);
  996. if (tag) return tag;
  997. if (!strcmp(node_name, "Rectangle")) return TAG_X3D_Rectangle2D;
  998. if (!strcmp(node_name, "Circle")) return TAG_X3D_Circle2D;
  999. } else {
  1000. tag = gf_node_mpeg4_type_by_class_name(node_name);
  1001. if (!tag) {
  1002. if (!strcmp(node_name, "Rectangle2D")) return TAG_MPEG4_Rectangle;
  1003. if (!strcmp(node_name, "Circle2D")) return TAG_MPEG4_Circle;
  1004. if (!(parser->load->flags & GF_SM_LOAD_MPEG4_STRICT)) return gf_node_x3d_type_by_class_name(node_name);
  1005. }
  1006. }
  1007. return tag;
  1008. }
  1009. GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, char *szDEFName)
  1010. {
  1011. u32 tag, ID;
  1012. Bool is_script, replace_prev, register_def;
  1013. GF_Proto *proto;
  1014. GF_Node *node, *newnode, *undef_node;
  1015. GF_FieldInfo info;
  1016. Bool init_node;
  1017. char *name;
  1018. char * str;
  1019. init_node = 0;
  1020. if (node_name) {
  1021. str = node_name;
  1022. } else {
  1023. str = gf_bt_get_next(parser, 0);
  1024. }
  1025. name = NULL;
  1026. if (!strcmp(str, "NULL")) return NULL;
  1027. ID = 0;
  1028. register_def = 0;
  1029. replace_prev = 0;
  1030. undef_node = NULL;
  1031. if (!strcmp(str, "DEF")) {
  1032. register_def = 1;
  1033. str = gf_bt_get_next(parser, 0);
  1034. name = strdup(str);
  1035. str = gf_bt_get_next(parser, 0);
  1036. } else if (szDEFName) {
  1037. name = strdup(szDEFName);
  1038. register_def = 1;
  1039. }
  1040. if (name) {
  1041. undef_node = gf_sg_find_node_by_name(parser->load->scene_graph, name);
  1042. if (undef_node) {
  1043. gf_list_del_item(parser->peeked_nodes, undef_node);
  1044. ID = gf_node_get_id(undef_node);
  1045. /*if we see twice a DEF N1 then force creation of a new node*/
  1046. if (gf_bt_has_been_def(parser, name)) {
  1047. undef_node = NULL;
  1048. ID = gf_bt_get_def_id(parser, name);
  1049. gf_bt_report(parser, GF_OK, "Node %s has been DEFed several times, IDs may get corrupted", name);
  1050. }
  1051. } else {
  1052. ID = gf_bt_get_def_id(parser, name);
  1053. }
  1054. }
  1055. else if (!strcmp(str, "USE")) {
  1056. str = gf_bt_get_next(parser, 0);
  1057. node = gf_sg_find_node_by_name(parser->load->scene_graph, str);
  1058. if (!node) {
  1059. /*create a temp node (undefined)*/
  1060. node = gf_bt_new_node(parser, TAG_UndefinedNode);
  1061. ID = gf_bt_get_def_id(parser, str);
  1062. gf_node_set_id(node, ID, str);
  1063. gf_list_add(parser->undef_nodes, node);
  1064. }
  1065. gf_node_register(node, parent);
  1066. return node;
  1067. }
  1068. proto = NULL;
  1069. tag = gf_bt_get_node_tag(parser, str);
  1070. if (!tag) {
  1071. GF_SceneGraph *sg = parser->load->scene_graph;
  1072. while (1) {
  1073. proto = gf_sg_find_proto(sg, 0, str);
  1074. if (proto) break;
  1075. sg = sg->parent_scene;
  1076. if (!sg) break;
  1077. }
  1078. if (!proto) {
  1079. /*locate proto*/
  1080. gf_bt_report(parser, GF_BAD_PARAM, "%s: not a valid/supported node", str);
  1081. return NULL;
  1082. }
  1083. tag = TAG_ProtoNode;
  1084. }
  1085. if (undef_node && (undef_node->sgprivate->tag == tag)) {
  1086. node = undef_node;
  1087. } else {
  1088. if (undef_node) replace_prev = 1;
  1089. if (proto) {
  1090. node = gf_sg_proto_create_instance(parser->load->scene_graph, proto);
  1091. } else {
  1092. node = gf_bt_new_node(parser, tag);
  1093. }
  1094. if (!parser->parsing_proto) init_node = 1;
  1095. }
  1096. is_script = 0;
  1097. if ((tag==TAG_MPEG4_Script) || (tag==TAG_X3D_Script))
  1098. is_script = 1;
  1099. if (!node) {
  1100. parser->last_error = GF_SG_UNKNOWN_NODE;
  1101. return NULL;
  1102. }
  1103. if (register_def) gf_list_add(parser->def_nodes, node);
  1104. gf_node_register(node, parent);
  1105. /*VRML: "The transformation hierarchy shall be a directed acyclic graph; results are undefined if a node
  1106. in the transformation hierarchy is its own ancestor"
  1107. that's good, because the scene graph can't handle cyclic graphs (destroy will never be called).
  1108. However we still have to register the node before parsing it, to update node registry and get correct IDs*/
  1109. if (name) {
  1110. if (!undef_node || replace_prev) {
  1111. gf_node_set_id(node, ID, name);
  1112. }
  1113. free(name);
  1114. name = NULL;
  1115. }
  1116. if (!parser->parsing_proto) gf_bt_update_timenode(parser, node);
  1117. if (gf_bt_check_code(parser, '{')) {
  1118. while (1) {
  1119. if (gf_bt_check_code(parser, '}'))
  1120. break;
  1121. str = gf_bt_get_next(parser, 0);
  1122. if (!str) {
  1123. gf_bt_report(parser, GF_BAD_PARAM, "Invalid node syntax");
  1124. goto err;
  1125. }
  1126. /*VRML/X3D specific */
  1127. if (parser->is_wrl) {
  1128. /*we ignore bboxCenter and bboxSize*/
  1129. if (!strcmp(str, "bboxCenter") || !strcmp(str, "bboxSize")) {
  1130. Fixed f;
  1131. gf_bt_parse_float(parser, "x", &f);
  1132. gf_bt_parse_float(parser, "y", &f);
  1133. gf_bt_parse_float(parser, "z", &f);
  1134. continue;
  1135. }
  1136. /*some VRML files declare routes almost anywhere*/
  1137. if (!strcmp(str, "ROUTE")) {
  1138. gf_bt_parse_route(parser, 1, 0, NULL);
  1139. continue;
  1140. }
  1141. }
  1142. parser->last_error = gf_node_get_field_by_name(node, str, &info);
  1143. /*check common VRML fields removed in MPEG4*/
  1144. if (parser->last_error) {
  1145. if (!parser->is_wrl) {
  1146. /*we ignore 'solid' for MPEG4 box/cone/etc*/
  1147. if (!strcmp(str, "solid")) {
  1148. Bool b;
  1149. gf_bt_parse_bool(parser, "solid", &b);
  1150. parser->last_error = GF_OK;
  1151. continue;
  1152. }
  1153. /*we ignore 'description' for MPEG4 sensors*/
  1154. else if (!strcmp(str, "description")) {
  1155. char *str = gf_bt_get_string(parser);
  1156. free(str);
  1157. parser->last_error = GF_OK;
  1158. continue;
  1159. }
  1160. /*remaps X3D to old VRML/MPEG4*/
  1161. else if ((tag==TAG_MPEG4_LOD) && !strcmp(str, "children")) {
  1162. str = "level";
  1163. parser->last_error = gf_node_get_field_by_name(node, str, &info);
  1164. }
  1165. else if ((tag==TAG_MPEG4_Switch) && !strcmp(str, "children")) {
  1166. str = "choice";
  1167. parser->last_error = gf_node_get_field_by_name(node, str, &info);
  1168. }
  1169. else if (!strcmp(str, "enabled")) {
  1170. Bool b;
  1171. gf_bt_parse_bool(parser, "collide", &b);
  1172. parser->last_error = GF_OK;
  1173. continue;
  1174. }
  1175. } else {
  1176. /*remaps old VRML/MPEG4 to X3D if possible*/
  1177. if ((tag==TAG_X3D_LOD) && !strcmp(str, "level")) {
  1178. str = "children";
  1179. parser->last_error = gf_node_get_field_by_name(node, str, &info);
  1180. }
  1181. else if ((tag==TAG_X3D_Switch) && !strcmp(str, "choice")) {
  1182. str = "children";
  1183. parser->last_error = gf_node_get_field_by_name(node, str, &info);
  1184. }
  1185. else if (!strcmp(str, "collide")) {
  1186. Bool b;
  1187. gf_bt_parse_bool(parser, "enabled", &b);
  1188. parser->last_error = GF_OK;
  1189. continue;
  1190. }
  1191. }
  1192. }
  1193. if (is_script && parser->last_error) {
  1194. u32 eType, fType;
  1195. GF_ScriptField *sf;
  1196. eType = 0;
  1197. if (!strcmp(str, "eventIn") || !strcmp(str, "inputOnly")) eType = GF_SG_SCRIPT_TYPE_EVENT_IN;
  1198. else if (!strcmp(str, "eventOut") || !strcmp(str, "outputOnly")) eType = GF_SG_SCRIPT_TYPE_EVENT_OUT;
  1199. else if (!strcmp(str, "field") || !strcmp(str, "initializeOnly")) eType = GF_SG_SCRIPT_TYPE_FIELD;
  1200. else {
  1201. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown script event type", str);
  1202. goto err;
  1203. }
  1204. str = gf_bt_get_next(parser, 0);
  1205. fType = gf_sg_field_type_by_name(str);
  1206. if (fType==GF_SG_VRML_UNKNOWN) {
  1207. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown script field type", str);
  1208. goto err;
  1209. }
  1210. parser->last_error = GF_OK;
  1211. str = gf_bt_get_next(parser, 0);
  1212. sf = gf_sg_script_field_new(node, eType, fType, str);
  1213. parser->last_error = gf_node_get_field_by_name(node, str, &info);
  1214. if (parser->parsing_proto && gf_bt_set_field_is(parser, &info, node)) continue;
  1215. if ((eType == GF_SG_SCRIPT_TYPE_EVENT_IN) || (eType == GF_SG_SCRIPT_TYPE_EVENT_OUT)) continue;
  1216. }
  1217. if (parser->last_error) {
  1218. gf_bt_report(parser, GF_OK, "%s: Unknown field", str);
  1219. goto err;
  1220. }
  1221. if (parser->parsing_proto && gf_bt_set_field_is(parser, &info, node)) continue;
  1222. switch (info.fieldType) {
  1223. case GF_SG_VRML_SFNODE:
  1224. /*if redefining node reset it - this happens with CreateVrmlFromString*/
  1225. if (* ((GF_Node **)info.far_ptr) ) {
  1226. gf_node_unregister(* ((GF_Node **)info.far_ptr), node);
  1227. * ((GF_Node **)info.far_ptr) = NULL;
  1228. }
  1229. newnode = gf_bt_sf_node(parser, NULL, node, NULL);
  1230. if (!newnode && parser->last_error) goto err;
  1231. if (newnode) {
  1232. if (!gf_bt_check_ndt(parser, &info, newnode, node)) goto err;
  1233. * ((GF_Node **)info.far_ptr) = newnode;
  1234. }
  1235. break;
  1236. case GF_SG_VRML_MFNODE:
  1237. {
  1238. GF_ChildNodeItem *last = NULL;
  1239. Bool single_child = 0;
  1240. if (!gf_bt_check_code(parser, '[')) {
  1241. if (parser->is_wrl) single_child = 1;
  1242. else break;
  1243. }
  1244. /*if redefining node reset it - this happens with CreateVrmlFromString*/
  1245. if (undef_node==node) {
  1246. gf_node_unregister_children(node, *(GF_ChildNodeItem **)info.far_ptr);
  1247. *(GF_ChildNodeItem **)info.far_ptr = NULL;
  1248. }
  1249. while (single_child || !gf_bt_check_code(parser, ']')) {
  1250. /*VRML seems to allow that*/
  1251. gf_bt_check_code(parser, ',');
  1252. newnode = gf_bt_sf_node(parser, NULL, node, NULL);
  1253. if (!newnode && parser->last_error) goto err;
  1254. if (newnode) {
  1255. if (!gf_bt_check_ndt(parser, &info, newnode, node)) goto err;
  1256. gf_node_list_add_child_last( (GF_ChildNodeItem **)info.far_ptr, newnode, &last);
  1257. }
  1258. if (single_child) break;
  1259. }
  1260. }
  1261. break;
  1262. default:
  1263. if (gf_sg_vrml_is_sf_field(info.fieldType)) {
  1264. gf_bt_sffield(parser, &info, node);
  1265. } else {
  1266. gf_bt_mffield(parser, &info, node);
  1267. }
  1268. if (parser->last_error) goto err;
  1269. break;
  1270. }
  1271. /*VRML seems to allow that*/
  1272. gf_bt_check_code(parser, ',');
  1273. if (proto) gf_sg_proto_mark_field_loaded(node, &info);
  1274. }
  1275. }
  1276. /*VRML seems to allow that*/
  1277. gf_bt_check_code(parser, ',');
  1278. /*we must init the node once ID is set in case we're creating rendering stacks*/
  1279. if (init_node && (gf_node_get_tag(node)!=TAG_ProtoNode) ) gf_node_init(node);
  1280. /*remove temp node*/
  1281. if (replace_prev) {
  1282. gf_node_replace(undef_node, node, 0);
  1283. gf_list_del_item(parser->undef_nodes, undef_node);
  1284. }
  1285. if (!parser->parsing_proto && is_script && (parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK) ) {
  1286. if (parser->cur_com) {
  1287. if (!parser->cur_com->scripts_to_load) parser->cur_com->scripts_to_load = gf_list_new();
  1288. gf_list_add(parser->cur_com->scripts_to_load, node);
  1289. } else {
  1290. /*postpone script init since it may use routes/nodes not yet defined ...*/
  1291. gf_list_add(parser->scripts, node);
  1292. }
  1293. }
  1294. return node;
  1295. err:
  1296. gf_node_unregister(node, parent);
  1297. if (name) free(name);
  1298. return NULL;
  1299. }
  1300. /*
  1301. locate node, if not defined yet parse ahead in current AU
  1302. optimization: we actually peek ALL DEF NODES till end of AU
  1303. */
  1304. GF_Node *gf_bt_peek_node(GF_BTParser *parser, char *defID)
  1305. {
  1306. GF_Node *n, *the_node;
  1307. u32 tag, ID;
  1308. Bool prev_is_insert = 0;
  1309. char *str, *ret;
  1310. char nName[1000];
  1311. u32 pos, line, line_pos, i, count;
  1312. n = gf_sg_find_node_by_name(parser->load->scene_graph, defID);
  1313. if (n) return n;
  1314. count = gf_list_count(parser->peeked_nodes);
  1315. for (i=0; i<count; i++) {
  1316. n = (GF_Node *)gf_list_get(parser->peeked_nodes, i);
  1317. if (!strcmp(gf_node_get_name(n), defID)) return n;
  1318. }
  1319. the_node = NULL;
  1320. pos = parser->line_start_pos;
  1321. line_pos = parser->line_pos;
  1322. line = parser->line;
  1323. strcpy(nName, defID);
  1324. n = NULL;
  1325. while (!parser->done && !the_node) {
  1326. str = gf_bt_get_next(parser, 0);
  1327. gf_bt_check_code(parser, '[');
  1328. gf_bt_check_code(parser, ']');
  1329. gf_bt_check_code(parser, '{');
  1330. gf_bt_check_code(parser, '}');
  1331. gf_bt_check_code(parser, ',');
  1332. gf_bt_check_code(parser, '.');
  1333. if ( (!prev_is_insert && !strcmp(str, "AT")) || !strcmp(str, "PROTO") ) {
  1334. /*only check in current command (but be aware of conditionals..)*/
  1335. if (!the_node && gf_list_find(parser->bifs_au->commands, parser->cur_com)) {
  1336. gf_bt_report(parser, GF_BAD_PARAM, "Cannot find node %s\n", nName);
  1337. break;
  1338. }
  1339. continue;
  1340. }
  1341. if (!strcmp(str, "INSERT")) prev_is_insert = 1;
  1342. else prev_is_insert = 0;
  1343. if (strcmp(str, "DEF")) continue;
  1344. str = gf_bt_get_next(parser, 0);
  1345. ret = strdup(str);
  1346. str = gf_bt_get_next(parser, 0);
  1347. if (!strcmp(str, "ROUTE")) {
  1348. free(ret);
  1349. continue;
  1350. }
  1351. tag = gf_bt_get_node_tag(parser, str);
  1352. if (!tag) {
  1353. GF_Proto *p;
  1354. GF_SceneGraph *sg = parser->load->scene_graph;
  1355. while (1) {
  1356. p = gf_sg_find_proto(sg, 0, str);
  1357. if (p) break;
  1358. sg = sg->parent_scene;
  1359. if (!sg) break;
  1360. }
  1361. if (!p) {
  1362. /*locate proto*/
  1363. gf_bt_report(parser, GF_BAD_PARAM, "%s: not a valid/supported node", str);
  1364. free(ret);
  1365. return NULL;
  1366. }
  1367. n = gf_sg_proto_create_instance(parser->load->scene_graph, p);
  1368. } else {
  1369. n = gf_bt_new_node(parser, tag);
  1370. }
  1371. ID = gf_bt_get_def_id(parser, ret);
  1372. if (n) {
  1373. gf_node_set_id(n, ID, ret);
  1374. gf_list_add(parser->peeked_nodes, n);
  1375. if (!parser->parsing_proto) gf_node_init(n);
  1376. if (!strcmp(ret, nName)) the_node = n;
  1377. }
  1378. free(ret);
  1379. /*NO REGISTER on peek (both scene graph or DEF list) because peek is only used to get node type
  1380. and fields, never to insert in the graph*/
  1381. /*go on till end of AU*/
  1382. }
  1383. /*restore context*/
  1384. parser->done = 0;
  1385. gzrewind(parser->gz_in);
  1386. gzseek(parser->gz_in, pos, SEEK_SET);
  1387. parser->line_pos = parser->line_size;
  1388. gf_bt_check_line(parser);
  1389. parser->line = line;
  1390. parser->line_pos = line_pos;
  1391. return the_node;
  1392. }
  1393. u32 gf_bt_get_route(GF_BTParser *parser, char *name)
  1394. {
  1395. u32 i;
  1396. GF_Command *com;
  1397. GF_Route *r = gf_sg_route_find_by_name(parser->load->scene_graph, name);
  1398. if (r) return r->ID;
  1399. i=0;
  1400. while ((com = (GF_Command *)gf_list_enum(parser->inserted_routes, &i))) {
  1401. if (com->def_name && !strcmp(com->def_name, name)) return com->RouteID;
  1402. }
  1403. return 0;
  1404. }
  1405. Bool gf_bt_route_id_used(GF_BTParser *parser, u32 ID)
  1406. {
  1407. u32 i;
  1408. GF_Command *com;
  1409. GF_Route *r = gf_sg_route_find(parser->load->scene_graph, ID);
  1410. if (r) return 1;
  1411. i=0;
  1412. while ((com = (GF_Command *)gf_list_enum(parser->inserted_routes, &i))) {
  1413. if (com->RouteID == ID) return 1;
  1414. }
  1415. return 0;
  1416. }
  1417. static u32 get_evt_type(char *eventName)
  1418. {
  1419. if (!strcmp(eventName, "eventIn") || !strcmp(eventName, "inputOnly")) return GF_SG_EVENT_IN;
  1420. else if (!strcmp(eventName, "eventOut") || !strcmp(eventName, "outputOnly")) return GF_SG_EVENT_OUT;
  1421. else if (!strcmp(eventName, "field") || !strcmp(eventName, "initializeOnly")) return GF_SG_EVENT_FIELD;
  1422. else if (!strcmp(eventName, "exposedField") || !strcmp(eventName, "inputOutput")) return GF_SG_EVENT_EXPOSED_FIELD;
  1423. else return GF_SG_EVENT_UNKNOWN;
  1424. }
  1425. GF_Err gf_bt_parse_proto(GF_BTParser *parser, char *proto_code, GF_List *proto_list)
  1426. {
  1427. GF_FieldInfo info;
  1428. u32 fType, eType, QPType, pID;
  1429. Bool externProto;
  1430. GF_Proto *proto, *prevproto;
  1431. GF_ProtoFieldInterface *pfield;
  1432. GF_SceneGraph *sg;
  1433. char *str, *name;
  1434. char szDefName[1024];
  1435. Bool isDEF;
  1436. if (proto_code)
  1437. str = proto_code;
  1438. else
  1439. str = gf_bt_get_next(parser, 0);
  1440. externProto = !strcmp(str, "EXTERNPROTO") ? 1 : 0;
  1441. str = gf_bt_get_next(parser, 0);
  1442. name = strdup(str);
  1443. if (!gf_bt_check_code(parser, '[')) {
  1444. return gf_bt_report(parser, GF_BAD_PARAM, "[ expected in proto declare");
  1445. }
  1446. pID = gf_bt_get_next_proto_id(parser);
  1447. /*if redefinition remove it - WRL only, may be used by loadVRMLFormString*/
  1448. if (!proto_list && parser->is_wrl) {
  1449. proto = gf_sg_find_proto(parser->load->scene_graph, pID, name);
  1450. if (proto) gf_sg_proto_del(proto);
  1451. }
  1452. proto = gf_sg_proto_new(parser->load->scene_graph, pID, name, proto_list ? 1 : 0);
  1453. if (proto_list) gf_list_add(proto_list, proto);
  1454. if (parser->load->ctx && (parser->load->ctx->max_proto_id<pID)) parser->load->ctx->max_proto_id = pID;
  1455. /*hack for VRML, where externProto default field values are not mandatory*/
  1456. parser->is_extern_proto_field = externProto;
  1457. free(name);
  1458. /*get all fields*/
  1459. while (!parser->last_error && !gf_bt_check_code(parser, ']')) {
  1460. str = gf_bt_get_next(parser, 0);
  1461. next_field:
  1462. if (gf_bt_check_code(parser, ']')) break;
  1463. eType = get_evt_type(str);
  1464. if (eType==GF_SG_EVENT_UNKNOWN) {
  1465. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown event type", str);
  1466. goto err;
  1467. }
  1468. str = gf_bt_get_next(parser, 0);
  1469. fType = gf_sg_field_type_by_name(str);
  1470. if (fType==GF_SG_VRML_UNKNOWN) {
  1471. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown field type", str);
  1472. goto err;
  1473. }
  1474. str = gf_bt_get_next(parser, 0);
  1475. pfield = gf_sg_proto_field_new(proto, fType, eType, str);
  1476. if ((eType==GF_SG_EVENT_IN) || (eType==GF_SG_EVENT_OUT)) continue;
  1477. gf_sg_proto_field_get_field(pfield, &info);
  1478. if (fType==GF_SG_VRML_SFNODE) {
  1479. str = gf_bt_get_next(parser, 0);
  1480. if (strcmp(str, "NULL")) {
  1481. if ( (!strlen(str) || (get_evt_type(str)!=GF_SG_EVENT_UNKNOWN)) && parser->is_extern_proto_field) goto next_field;
  1482. pfield->def_sfnode_value = gf_bt_sf_node(parser, str, NULL, NULL);
  1483. }
  1484. } else if (fType==GF_SG_VRML_MFNODE) {
  1485. GF_ChildNodeItem *last = NULL;
  1486. if (gf_bt_check_code(parser, '[')) {
  1487. while (1) {
  1488. GF_Node *pf_node;
  1489. if (gf_bt_check_code(parser, ']')) break;
  1490. pf_node = gf_bt_sf_node(parser, NULL, NULL, NULL);
  1491. if (pf_node) gf_node_list_add_child_last( &pfield->def_mfnode_value, pf_node, &last);
  1492. }
  1493. }
  1494. } else if (gf_sg_vrml_is_sf_field(fType)) {
  1495. gf_bt_sffield(parser, &info, NULL);
  1496. if (parser->last_error==GF_EOS) {
  1497. gf_sg_proto_field_set_value_undefined(pfield);
  1498. parser->last_error=GF_OK;
  1499. goto next_field;
  1500. }
  1501. } else {
  1502. gf_bt_mffield(parser, &info, NULL);
  1503. }
  1504. /*check QP info*/
  1505. if (!gf_bt_check_code(parser, '{')) continue;
  1506. if (gf_bt_check_code(parser, '}')) continue;
  1507. str = gf_bt_get_next(parser, 0);
  1508. if (!strcmp(str, "QP")) {
  1509. u32 nbBits, hasMin;
  1510. Fixed ftMin, ftMax;
  1511. gf_bt_parse_int(parser, "QPType", (SFInt32*)&QPType);
  1512. nbBits = 0;
  1513. str = gf_bt_get_next(parser, 0);
  1514. if (!strcmp(str, "nbBits")) {
  1515. gf_bt_parse_int(parser, "nbBits", (SFInt32*)&nbBits);
  1516. str = gf_bt_get_next(parser, 0);
  1517. }
  1518. hasMin = 0;
  1519. eType = 0;
  1520. if (!strcmp(str, "b")) {
  1521. hasMin = 1;
  1522. if (!gf_bt_check_code(parser, '{')) {
  1523. gf_bt_report(parser, GF_BAD_PARAM, "%s: Invalid proto coding parameter declare", str);
  1524. goto err;
  1525. }
  1526. gf_bt_parse_float(parser, "min", &ftMin);
  1527. gf_bt_parse_float(parser, "max", &ftMax);
  1528. if (!gf_bt_check_code(parser, '}')) {
  1529. gf_bt_report(parser, GF_BAD_PARAM, "Invalid proto coding parameter declare");
  1530. goto err;
  1531. }
  1532. if (gf_sg_vrml_get_sf_type(fType) == GF_SG_VRML_SFINT32) {
  1533. eType = GF_SG_VRML_SFINT32;
  1534. } else {
  1535. eType = GF_SG_VRML_SFFLOAT;
  1536. }
  1537. }
  1538. gf_bifs_proto_field_set_aq_info(pfield, QPType, hasMin, eType, &ftMin, &ftMax, nbBits);
  1539. if (!gf_bt_check_code(parser, '}')) {
  1540. gf_bt_report(parser, GF_BAD_PARAM, "Invalid proto coding parameter declare");
  1541. goto err;
  1542. }
  1543. }
  1544. }
  1545. parser->is_extern_proto_field = 0;
  1546. if (externProto) {
  1547. SFURL *url;
  1548. u32 nb_urls;
  1549. Bool has_urls = 0;
  1550. if (gf_bt_check_code(parser, '[')) has_urls = 1;
  1551. gf_sg_vrml_mf_reset(&proto->ExternProto, GF_SG_VRML_MFURL);
  1552. nb_urls = 0;
  1553. do {
  1554. str = gf_bt_get_next(parser, 0);
  1555. gf_sg_vrml_mf_append(&proto->ExternProto, GF_SG_VRML_MFURL, (void **) &url);
  1556. if (!strnicmp(str, "od:", 3)) {
  1557. sscanf(str, "od:%d", &url->OD_ID);
  1558. } else {
  1559. if (!sscanf(str, "%d", &url->OD_ID)) {
  1560. url->url = strdup(str);
  1561. } else {
  1562. char szURL[20];
  1563. sprintf(szURL, "%d", url->OD_ID);
  1564. if (strcmp(szURL, str)) {
  1565. url->OD_ID = 0;
  1566. url->url = strdup(str);
  1567. }
  1568. }
  1569. }
  1570. if (has_urls) {
  1571. gf_bt_check_code(parser, ',');
  1572. if (gf_bt_check_code(parser, ']')) has_urls = 0;
  1573. }
  1574. } while (has_urls);
  1575. return GF_OK;
  1576. }
  1577. /*parse proto code */
  1578. if (!gf_bt_check_code(parser, '{')) {
  1579. gf_bt_report(parser, GF_OK, "empty proto body");
  1580. return GF_OK;
  1581. }
  1582. prevproto = parser->parsing_proto;
  1583. sg = parser->load->scene_graph;
  1584. parser->parsing_proto = proto;
  1585. parser->load->scene_graph = gf_sg_proto_get_graph(proto);
  1586. isDEF = 0;
  1587. while (!gf_bt_check_code(parser, '}')) {
  1588. str = gf_bt_get_next(parser, 0);
  1589. if (!strcmp(str, "PROTO") || !strcmp(str, "EXTERNPROTO")) {
  1590. gf_bt_parse_proto(parser, str, NULL);
  1591. } else if (!strcmp(str, "DEF")) {
  1592. isDEF = 1;
  1593. str = gf_bt_get_next(parser, 0);
  1594. strcpy(szDefName, str);
  1595. } else if (!strcmp(str, "ROUTE")) {
  1596. GF_Route *r = gf_bt_parse_route(parser, 1, 0, NULL);
  1597. if (isDEF) {
  1598. u32 rID = gf_bt_get_route(parser, szDefName);
  1599. if (!rID) rID = gf_bt_get_next_route_id(parser);
  1600. parser->last_error = gf_sg_route_set_id(r, rID);
  1601. gf_sg_route_set_name(r, szDefName);
  1602. isDEF = 0;
  1603. }
  1604. } else {
  1605. GF_Node *n = gf_bt_sf_node(parser, str, NULL, isDEF ? szDefName : NULL);
  1606. isDEF = 0;
  1607. if (!n) goto err;
  1608. if (0 && isDEF) {
  1609. u32 ID = gf_bt_get_def_id(parser, szDefName);
  1610. isDEF = 0;
  1611. gf_node_set_id(n, ID, szDefName);
  1612. }
  1613. gf_sg_proto_add_node_code(proto, n);
  1614. }
  1615. }
  1616. gf_bt_resolve_routes(parser, 1);
  1617. gf_bt_check_unresolved_nodes(parser);
  1618. parser->load->scene_graph = sg;
  1619. parser->parsing_proto = prevproto;
  1620. return parser->last_error;
  1621. err:
  1622. if (proto_list) gf_list_del_item(proto_list, proto);
  1623. gf_sg_proto_del(proto);
  1624. return parser->last_error;
  1625. }
  1626. GF_Route *gf_bt_parse_route(GF_BTParser *parser, Bool skip_def, Bool is_insert, GF_Command *com)
  1627. {
  1628. GF_Route *r;
  1629. char *str, nstr[1000], rName[1000];
  1630. u32 rID;
  1631. GF_Node *orig, *dest;
  1632. GF_FieldInfo orig_field, dest_field;
  1633. GF_Err e;
  1634. rID = 0;
  1635. strcpy(nstr, gf_bt_get_next(parser, 1));
  1636. if (!skip_def && !strcmp(nstr, "DEF")) {
  1637. str = gf_bt_get_next(parser, 0);
  1638. strcpy(rName, str);
  1639. rID = gf_bt_get_route(parser, rName);
  1640. if (!rID && (str[0]=='R') ) {
  1641. rID = atoi(&str[1]);
  1642. if (rID) {
  1643. rID++;
  1644. if (gf_bt_route_id_used(parser, rID)) rID = 0;
  1645. }
  1646. }
  1647. if (!rID) rID = gf_bt_get_next_route_id(parser);
  1648. strcpy(nstr, gf_bt_get_next(parser, 1));
  1649. }
  1650. orig = gf_bt_peek_node(parser, nstr);
  1651. if (!orig) {
  1652. gf_bt_report(parser, GF_BAD_PARAM, "cannot find node %s", nstr);
  1653. return NULL;
  1654. }
  1655. if (!gf_bt_check_code(parser, '.')) {
  1656. gf_bt_report(parser, GF_BAD_PARAM, ". expected in route decl");
  1657. return NULL;
  1658. }
  1659. str = gf_bt_get_next(parser, 0);
  1660. e = gf_node_get_field_by_name(orig, str, &orig_field);
  1661. /*VRML loosy syntax*/
  1662. if ((e != GF_OK) && parser->is_wrl && !strnicmp(str, "set_", 4))
  1663. e = gf_node_get_field_by_name(orig, &str[4], &orig_field);
  1664. if ((e != GF_OK) && parser->is_wrl && strstr(str, "_changed")) {
  1665. char *s = strstr(str, "_changed");
  1666. s[0] = 0;
  1667. e = gf_node_get_field_by_name(orig, str, &orig_field);
  1668. }
  1669. if (e != GF_OK) {
  1670. gf_bt_report(parser, GF_BAD_PARAM, "%s not a field of node %s (%s)", str, gf_node_get_name(orig), gf_node_get_class_name(orig));
  1671. return NULL;
  1672. }
  1673. str = gf_bt_get_next(parser, 0);
  1674. if (strcmp(str, "TO")) {
  1675. gf_bt_report(parser, GF_BAD_PARAM, "TO expected in route declaration - got \"%s\"", str);
  1676. return NULL;
  1677. }
  1678. strcpy(nstr, gf_bt_get_next(parser, 1));
  1679. dest = gf_bt_peek_node(parser, nstr);
  1680. if (!dest) {
  1681. gf_bt_report(parser, GF_BAD_PARAM, "cannot find node %s", nstr);
  1682. return NULL;
  1683. }
  1684. if (!gf_bt_check_code(parser, '.')) {
  1685. gf_bt_report(parser, GF_BAD_PARAM, ". expected in route decl");
  1686. return NULL;
  1687. }
  1688. str = gf_bt_get_next(parser, 0);
  1689. e = gf_node_get_field_by_name(dest, str, &dest_field);
  1690. /*VRML loosy syntax*/
  1691. if ((e != GF_OK) && parser->is_wrl && !strnicmp(str, "set_", 4))
  1692. e = gf_node_get_field_by_name(dest, &str[4], &dest_field);
  1693. if ((e != GF_OK) && parser->is_wrl && strstr(str, "_changed")) {
  1694. char *s = strstr(str, "_changed");
  1695. s[0] = 0;
  1696. e = gf_node_get_field_by_name(dest, str, &dest_field);
  1697. }
  1698. if (e != GF_OK) {
  1699. gf_bt_report(parser, GF_BAD_PARAM, "%s not a field of node %s (%s)", str, gf_node_get_name(dest), gf_node_get_class_name(dest));
  1700. return NULL;
  1701. }
  1702. if (com) {
  1703. com->fromNodeID = gf_node_get_id(orig);
  1704. com->fromFieldIndex = orig_field.fieldIndex;
  1705. com->toNodeID = gf_node_get_id(dest);
  1706. com->toFieldIndex = dest_field.fieldIndex;
  1707. if (rID) {
  1708. com->RouteID = rID;
  1709. com->def_name = strdup(rName);
  1710. /*whenever inserting routes, keep track of max defined ID*/
  1711. if (is_insert) {
  1712. gf_sg_set_max_defined_route_id(parser->load->scene_graph, rID);
  1713. if (parser->load->ctx && (rID>parser->load->ctx->max_route_id))
  1714. parser->load->ctx->max_route_id = rID;
  1715. }
  1716. }
  1717. return NULL;
  1718. }
  1719. r = gf_sg_route_new(parser->load->scene_graph, orig, orig_field.fieldIndex, dest, dest_field.fieldIndex);
  1720. if (r && rID) {
  1721. gf_sg_route_set_id(r, rID);
  1722. gf_sg_route_set_name(r, rName);
  1723. }
  1724. return r;
  1725. }
  1726. void gf_bt_resolve_routes(GF_BTParser *parser, Bool clean)
  1727. {
  1728. GF_Command *com;
  1729. /*resolve all commands*/
  1730. while(gf_list_count(parser->unresolved_routes) ) {
  1731. com = (GF_Command *)gf_list_get(parser->unresolved_routes, 0);
  1732. gf_list_rem(parser->unresolved_routes, 0);
  1733. switch (com->tag) {
  1734. case GF_SG_ROUTE_DELETE:
  1735. case GF_SG_ROUTE_REPLACE:
  1736. com->RouteID = gf_bt_get_route(parser, com->unres_name);
  1737. if (!com->RouteID) gf_bt_report(parser, GF_BAD_PARAM, "Cannot resolve Route %s", com->unres_name);
  1738. free(com->unres_name);
  1739. com->unres_name = NULL;
  1740. com->unresolved = 0;
  1741. break;
  1742. }
  1743. }
  1744. if (!clean) return;
  1745. while (gf_list_count(parser->inserted_routes)) gf_list_rem(parser->inserted_routes, 0);
  1746. }
  1747. static void bd_set_com_node(GF_Command *com, GF_Node *node)
  1748. {
  1749. com->node = node;
  1750. gf_node_register(com->node, NULL);
  1751. }
  1752. GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdList)
  1753. {
  1754. s32 pos;
  1755. GF_Route *r;
  1756. GF_Node *n, *newnode;
  1757. GF_Command *com;
  1758. GF_CommandField *inf;
  1759. GF_FieldInfo info;
  1760. char *str, field[1000];
  1761. if (!name) {
  1762. str = gf_bt_get_next(parser, 0);
  1763. } else {
  1764. str = name;
  1765. }
  1766. com = NULL;
  1767. pos = -2;
  1768. /*REPLACE commands*/
  1769. if (!strcmp(str, "REPLACE")) {
  1770. str = gf_bt_get_next(parser, 1);
  1771. if (!strcmp(str, "ROUTE")) {
  1772. str = gf_bt_get_next(parser, 0);
  1773. r = gf_sg_route_find_by_name(parser->load->scene_graph, str);
  1774. if (!r) strcpy(field, str);
  1775. str = gf_bt_get_next(parser, 0);
  1776. if (strcmp(str, "BY")) {
  1777. return gf_bt_report(parser, GF_BAD_PARAM, "BY expected got %s", str);
  1778. }
  1779. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_ROUTE_REPLACE);
  1780. if (r) {
  1781. com->RouteID = r->ID;
  1782. } else {
  1783. com->unres_name = strdup(field);
  1784. com->unresolved = 1;
  1785. gf_list_add(parser->unresolved_routes, com);
  1786. }
  1787. gf_bt_parse_route(parser, 1, 0, com);
  1788. gf_list_add(cmdList, com);
  1789. return parser->last_error;
  1790. }
  1791. /*scene replace*/
  1792. if (!strcmp(str, "SCENE")) {
  1793. str = gf_bt_get_next(parser, 0);
  1794. if (strcmp(str, "BY")) {
  1795. return gf_bt_report(parser, GF_BAD_PARAM, "BY expected got %s", str);
  1796. }
  1797. gf_bt_resolve_routes(parser, 1);
  1798. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_SCENE_REPLACE);
  1799. while (gf_list_count(parser->def_nodes)) gf_list_rem(parser->def_nodes, 0);
  1800. /*note we're extremely lucky in BT, REPLACE SCENE can't use protos, it's just a top scene*/
  1801. n = gf_bt_sf_node(parser, NULL, NULL, NULL);
  1802. if (parser->last_error) goto err;
  1803. com->node = n;
  1804. gf_list_add(cmdList, com);
  1805. parser->cur_com = com;
  1806. return GF_OK;
  1807. }
  1808. if (!strcmp(str, "LAST")) pos = -1;
  1809. else if (!strcmp(str, "BEGIN")) pos = 0;
  1810. gf_bt_check_code(parser, '.');
  1811. strcpy(field, str);
  1812. n = gf_bt_peek_node(parser, str);
  1813. if (!n) return gf_bt_report(parser, GF_BAD_PARAM, "%s: unknown node", field);
  1814. str = gf_bt_get_next(parser, 0);
  1815. strcpy(field, str);
  1816. if (gf_bt_check_code(parser, '[')) {
  1817. if ( (parser->last_error = gf_bt_parse_int(parser, "index", &pos)) ) return parser->last_error;
  1818. if (!gf_bt_check_code(parser, ']'))
  1819. return gf_bt_report(parser, GF_BAD_PARAM, "] expected");
  1820. }
  1821. /*node replace*/
  1822. if (!strcmp(field, "BY")) {
  1823. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_NODE_REPLACE);
  1824. bd_set_com_node(com, n);
  1825. inf = gf_sg_command_field_new(com);
  1826. inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL);
  1827. inf->fieldType = GF_SG_VRML_SFNODE;
  1828. inf->field_ptr = &inf->new_node;
  1829. gf_list_add(cmdList, com);
  1830. parser->cur_com = com;
  1831. return parser->last_error;
  1832. }
  1833. str = gf_bt_get_next(parser, 0);
  1834. if (strcmp(str, "BY")) return gf_bt_report(parser, GF_BAD_PARAM, "BY expected got %s", str);
  1835. parser->last_error = gf_node_get_field_by_name(n, field, &info);
  1836. if (parser->last_error)
  1837. return gf_bt_report(parser, parser->last_error, "%s: Unknown node field", field);
  1838. /*field replace*/
  1839. if (pos==-2) {
  1840. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_FIELD_REPLACE);
  1841. bd_set_com_node(com, n);
  1842. inf = gf_sg_command_field_new(com);
  1843. inf->fieldIndex = info.fieldIndex;
  1844. inf->fieldType = info.fieldType;
  1845. switch (info.fieldType) {
  1846. case GF_SG_VRML_SFNODE:
  1847. inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL);
  1848. inf->field_ptr = &inf->new_node;
  1849. if (!gf_bt_check_ndt(parser, &info, inf->new_node, n)) goto err;
  1850. break;
  1851. case GF_SG_VRML_MFNODE:
  1852. {
  1853. GF_ChildNodeItem *last = NULL;
  1854. if (!gf_bt_check_code(parser, '[')) break;
  1855. inf->field_ptr = &inf->node_list;
  1856. while (!gf_bt_check_code(parser, ']')) {
  1857. newnode = gf_bt_sf_node(parser, NULL, NULL, NULL);
  1858. if (!newnode) goto err;
  1859. if (parser->last_error!=GF_OK) goto err;
  1860. if (!gf_bt_check_ndt(parser, &info, newnode, n)) goto err;
  1861. gf_node_list_add_child_last(& inf->node_list, newnode, &last);
  1862. }
  1863. }
  1864. break;
  1865. default:
  1866. inf->field_ptr = gf_sg_vrml_field_pointer_new(info.fieldType);
  1867. info.far_ptr = inf->field_ptr;
  1868. if (gf_sg_vrml_is_sf_field(info.fieldType)) {
  1869. gf_bt_sffield(parser, &info, n);
  1870. } else {
  1871. gf_bt_mffield(parser, &info, n);
  1872. }
  1873. if (parser->last_error) goto err;
  1874. break;
  1875. }
  1876. gf_list_add(cmdList, com);
  1877. parser->cur_com = com;
  1878. return parser->last_error;
  1879. }
  1880. /*indexed field replace*/
  1881. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_INDEXED_REPLACE);
  1882. bd_set_com_node(com, n);
  1883. inf = gf_sg_command_field_new(com);
  1884. inf->pos = pos;
  1885. inf->fieldIndex = info.fieldIndex;
  1886. if (gf_sg_vrml_is_sf_field(info.fieldType)) {
  1887. gf_bt_report(parser, GF_BAD_PARAM, "%s: MF type field expected", info.name);
  1888. goto err;
  1889. }
  1890. inf->fieldType = gf_sg_vrml_get_sf_type(info.fieldType);
  1891. switch (info.fieldType) {
  1892. case GF_SG_VRML_MFNODE:
  1893. inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL);
  1894. inf->field_ptr = &inf->new_node;
  1895. break;
  1896. default:
  1897. info.fieldType = inf->fieldType;
  1898. info.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
  1899. gf_bt_sffield(parser, &info, n);
  1900. break;
  1901. }
  1902. if (parser->last_error) goto err;
  1903. gf_list_add(cmdList, com);
  1904. parser->cur_com = com;
  1905. return parser->last_error;
  1906. }
  1907. /*INSERT commands*/
  1908. if (!strcmp(str, "INSERT") || !strcmp(str, "APPEND")) {
  1909. Bool is_append = !strcmp(str, "APPEND") ? 1 : 0;
  1910. str = gf_bt_get_next(parser, 0);
  1911. if (!strcmp(str, "ROUTE")) {
  1912. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_ROUTE_INSERT);
  1913. gf_bt_parse_route(parser, 0, 1, com);
  1914. if (parser->last_error) goto err;
  1915. gf_list_add(cmdList, com);
  1916. gf_list_add(parser->inserted_routes, com);
  1917. parser->cur_com = com;
  1918. return GF_OK;
  1919. }
  1920. if (strcmp(str, "AT") && strcmp(str, "TO")) {
  1921. return gf_bt_report(parser, GF_BAD_PARAM, (char*) (is_append ? "TO expected got %s" : "AT expected got %s"), str);
  1922. }
  1923. str = gf_bt_get_next(parser, 1);
  1924. strcpy(field, str);
  1925. n = gf_bt_peek_node(parser, str);
  1926. if (!n) {
  1927. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown node", field);
  1928. }
  1929. if (!gf_bt_check_code(parser, '.')) {
  1930. return gf_bt_report(parser, GF_BAD_PARAM, ". expected");
  1931. }
  1932. str = gf_bt_get_next(parser, 1);
  1933. strcpy(field, str);
  1934. if (!is_append) {
  1935. if (!gf_bt_check_code(parser, '[')) {
  1936. return gf_bt_report(parser, GF_BAD_PARAM, "[ expected");
  1937. }
  1938. gf_bt_parse_int(parser, "index", &pos);
  1939. if (!gf_bt_check_code(parser, ']')) {
  1940. return gf_bt_report(parser, GF_BAD_PARAM, "] expected");
  1941. }
  1942. } else {
  1943. if (gf_bt_check_code(parser, '[')) {
  1944. return gf_bt_report(parser, GF_BAD_PARAM, "[ unexpected in Append command");
  1945. }
  1946. pos = -1;
  1947. }
  1948. if (!strcmp(field, "children")) {
  1949. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_NODE_INSERT);
  1950. bd_set_com_node(com, n);
  1951. inf = gf_sg_command_field_new(com);
  1952. inf->pos = pos;
  1953. inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL);
  1954. inf->fieldType = GF_SG_VRML_SFNODE;
  1955. inf->field_ptr = &inf->new_node;
  1956. if (parser->last_error) goto err;
  1957. parser->cur_com = com;
  1958. return gf_list_add(cmdList, com);
  1959. }
  1960. gf_node_get_field_by_name(n, field, &info);
  1961. if (gf_sg_vrml_is_sf_field(info.fieldType)) {
  1962. gf_bt_report(parser, GF_BAD_PARAM, "%s: MF type field expected", info.name);
  1963. goto err;
  1964. }
  1965. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_INDEXED_INSERT);
  1966. bd_set_com_node(com, n);
  1967. inf = gf_sg_command_field_new(com);
  1968. inf->pos = pos;
  1969. inf->fieldIndex = info.fieldIndex;
  1970. inf->fieldType = gf_sg_vrml_get_sf_type(info.fieldType);
  1971. switch (info.fieldType) {
  1972. case GF_SG_VRML_MFNODE:
  1973. inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL);
  1974. inf->field_ptr = &inf->new_node;
  1975. break;
  1976. default:
  1977. info.fieldType = inf->fieldType;
  1978. inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
  1979. info.far_ptr = inf->field_ptr;
  1980. gf_bt_sffield(parser, &info, n);
  1981. break;
  1982. }
  1983. if (parser->last_error) goto err;
  1984. gf_list_add(cmdList, com);
  1985. parser->cur_com = com;
  1986. return parser->last_error;
  1987. }
  1988. /*DELETE commands*/
  1989. if (!strcmp(str, "DELETE")) {
  1990. str = gf_bt_get_next(parser, 1);
  1991. if (!strcmp(str, "ROUTE")) {
  1992. str = gf_bt_get_next(parser, 0);
  1993. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_ROUTE_DELETE);
  1994. com->RouteID = gf_bt_get_route(parser, str);
  1995. if (!com->RouteID) {
  1996. com->unres_name = strdup(str);
  1997. com->unresolved = 1;
  1998. gf_list_add(parser->unresolved_routes, com);
  1999. }
  2000. /*for bt<->xmt conversions*/
  2001. com->def_name = strdup(str);
  2002. return gf_list_add(cmdList, com);
  2003. }
  2004. strcpy(field, str);
  2005. n = gf_bt_peek_node(parser, str);
  2006. if (!n) {
  2007. return gf_bt_report(parser, GF_BAD_PARAM, "DELETE %s: Unknown Node", field);
  2008. }
  2009. if (!gf_bt_check_code(parser, '.')) {
  2010. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_NODE_DELETE);
  2011. bd_set_com_node(com, n);
  2012. return gf_list_add(cmdList, com);
  2013. }
  2014. str = gf_bt_get_next(parser, 0);
  2015. if (gf_node_get_field_by_name(n, str, &info) != GF_OK) {
  2016. return gf_bt_report(parser, GF_BAD_PARAM, "%s not a field of node %s", str, gf_node_get_class_name(n) );
  2017. }
  2018. if (gf_bt_check_code(parser, '[')) {
  2019. gf_bt_parse_int(parser, "index", &pos);
  2020. if (!gf_bt_check_code(parser, ']'))
  2021. return gf_bt_report(parser, GF_BAD_PARAM, "[ expected");
  2022. }
  2023. if (gf_sg_vrml_is_sf_field(info.fieldType)) {
  2024. if (info.fieldType == GF_SG_VRML_SFNODE) {
  2025. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_FIELD_REPLACE);
  2026. bd_set_com_node(com, n);
  2027. inf = gf_sg_command_field_new(com);
  2028. inf->fieldIndex = info.fieldIndex;
  2029. inf->fieldType = info.fieldType;
  2030. inf->new_node = NULL;
  2031. inf->field_ptr = &inf->new_node;
  2032. return gf_list_add(cmdList, com);
  2033. }
  2034. return gf_bt_report(parser, GF_BAD_PARAM, "%s is an SFField - cannot indexed delete", info.name);
  2035. }
  2036. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_INDEXED_DELETE);
  2037. bd_set_com_node(com, n);
  2038. inf = gf_sg_command_field_new(com);
  2039. inf->fieldIndex = info.fieldIndex;
  2040. inf->fieldType = info.fieldType;
  2041. inf->pos = pos;
  2042. return gf_list_add(cmdList, com);
  2043. }
  2044. /*Extended BIFS commands*/
  2045. /*GlobalQP commands*/
  2046. if (!strcmp(str, "GLOBALQP")) {
  2047. newnode = gf_bt_sf_node(parser, NULL, NULL, NULL);
  2048. if (newnode && (newnode->sgprivate->tag != TAG_MPEG4_QuantizationParameter)) {
  2049. gf_bt_report(parser, GF_BAD_PARAM, "Only QuantizationParameter node allowed in GLOBALQP");
  2050. gf_node_unregister(newnode, NULL);
  2051. return parser->last_error;
  2052. }
  2053. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_GLOBAL_QUANTIZER);
  2054. com->node = NULL;
  2055. inf = gf_sg_command_field_new(com);
  2056. inf->new_node = newnode;
  2057. inf->field_ptr = &inf->new_node;
  2058. inf->fieldType = GF_SG_VRML_SFNODE;
  2059. return gf_list_add(cmdList, com);
  2060. }
  2061. /*MultipleReplace commands*/
  2062. if (!strcmp(str, "MULTIPLEREPLACE")) {
  2063. str = gf_bt_get_next(parser, 0);
  2064. strcpy(field, str);
  2065. n = gf_bt_peek_node(parser, str);
  2066. if (!n) {
  2067. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown node", field);
  2068. }
  2069. if (!gf_bt_check_code(parser, '{')) {
  2070. return gf_bt_report(parser, GF_BAD_PARAM, "{ expected");
  2071. }
  2072. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_MULTIPLE_REPLACE);
  2073. bd_set_com_node(com, n);
  2074. while (!gf_bt_check_code(parser, '}')) {
  2075. str = gf_bt_get_next(parser, 0);
  2076. parser->last_error = gf_node_get_field_by_name(n, str, &info);
  2077. if (parser->last_error) {
  2078. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown node field", str);
  2079. goto err;
  2080. }
  2081. inf = gf_sg_command_field_new(com);
  2082. inf->fieldIndex = info.fieldIndex;
  2083. inf->fieldType = info.fieldType;
  2084. inf->pos = -1;
  2085. switch (info.fieldType) {
  2086. case GF_SG_VRML_SFNODE:
  2087. inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL);
  2088. if (parser->last_error) goto err;
  2089. if (!gf_bt_check_ndt(parser, &info, inf->new_node, n)) goto err;
  2090. inf->field_ptr = &inf->new_node;
  2091. break;
  2092. case GF_SG_VRML_MFNODE:
  2093. {
  2094. GF_ChildNodeItem *last = NULL;
  2095. if (!gf_bt_check_code(parser, '[')) {
  2096. gf_bt_report(parser, GF_BAD_PARAM, "[ expected");
  2097. goto err;
  2098. }
  2099. info.far_ptr = inf->field_ptr = &inf->node_list;
  2100. while (!gf_bt_check_code(parser, ']')) {
  2101. newnode = gf_bt_sf_node(parser, NULL, NULL, NULL);
  2102. if (parser->last_error!=GF_OK) goto err;
  2103. if (!gf_bt_check_ndt(parser, &info, newnode, n)) goto err;
  2104. gf_node_list_add_child_last( & inf->node_list, newnode, &last);
  2105. }
  2106. }
  2107. break;
  2108. default:
  2109. info.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
  2110. if (gf_sg_vrml_is_sf_field(info.fieldType)) {
  2111. gf_bt_sffield(parser, &info, n);
  2112. } else {
  2113. gf_bt_mffield(parser, &info, n);
  2114. }
  2115. if (parser->last_error) goto err;
  2116. break;
  2117. }
  2118. }
  2119. parser->cur_com = com;
  2120. return gf_list_add(cmdList, com);
  2121. }
  2122. /*MultipleIndexReplace commands*/
  2123. if (!strcmp(str, "MULTIPLEINDREPLACE")) {
  2124. str = gf_bt_get_next(parser, 1);
  2125. strcpy(field, str);
  2126. n = gf_bt_peek_node(parser, str);
  2127. if (!n) {
  2128. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown node", field);
  2129. }
  2130. if (!gf_bt_check_code(parser, '.')) {
  2131. return gf_bt_report(parser, GF_BAD_PARAM, ". expected");
  2132. }
  2133. str = gf_bt_get_next(parser, 0);
  2134. parser->last_error = gf_node_get_field_by_name(n, str, &info);
  2135. if (parser->last_error) {
  2136. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown field", info.name);
  2137. }
  2138. if (gf_sg_vrml_is_sf_field(info.fieldType)) {
  2139. return gf_bt_report(parser, GF_BAD_PARAM, "Only MF field allowed");
  2140. }
  2141. if (!gf_bt_check_code(parser, '[')) {
  2142. return gf_bt_report(parser, GF_BAD_PARAM, "[ expected");
  2143. }
  2144. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_MULTIPLE_INDEXED_REPLACE);
  2145. bd_set_com_node(com, n);
  2146. info.fieldType = gf_sg_vrml_get_sf_type(info.fieldType);
  2147. while (!gf_bt_check_code(parser, ']')) {
  2148. u32 pos;
  2149. if (gf_bt_parse_int(parser, "position", (SFInt32 *)&pos)) goto err;
  2150. str = gf_bt_get_next(parser, 0);
  2151. if (strcmp(str, "BY")) {
  2152. gf_bt_report(parser, GF_BAD_PARAM, "BY expected");
  2153. goto err;
  2154. }
  2155. inf = gf_sg_command_field_new(com);
  2156. inf->fieldIndex = info.fieldIndex;
  2157. inf->fieldType = info.fieldType;
  2158. inf->pos = pos;
  2159. if (inf->fieldType==GF_SG_VRML_SFNODE) {
  2160. info.far_ptr = inf->field_ptr = &inf->new_node;
  2161. inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL);
  2162. if (parser->last_error) goto err;
  2163. if (!gf_bt_check_ndt(parser, &info, inf->new_node, n)) goto err;
  2164. inf->field_ptr = &inf->new_node;
  2165. } else {
  2166. info.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
  2167. gf_bt_sffield(parser, &info, n);
  2168. if (parser->last_error) goto err;
  2169. }
  2170. }
  2171. parser->cur_com = com;
  2172. return gf_list_add(cmdList, com);
  2173. }
  2174. if (!strcmp(str, "XDELETE")) {
  2175. str = gf_bt_get_next(parser, 1);
  2176. strcpy(field, str);
  2177. n = gf_bt_peek_node(parser, str);
  2178. if (!n) {
  2179. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown Node", field);
  2180. }
  2181. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_NODE_DELETE_EX);
  2182. bd_set_com_node(com, n);
  2183. return gf_list_add(cmdList, com);
  2184. }
  2185. if (!strcmp(str, "INSERTPROTO")) {
  2186. if (!gf_bt_check_code(parser, '[')) {
  2187. return gf_bt_report(parser, GF_BAD_PARAM, "[ expected");
  2188. }
  2189. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_PROTO_INSERT);
  2190. while (!gf_bt_check_code(parser, ']')) {
  2191. parser->last_error = gf_bt_parse_proto(parser, NULL, com->new_proto_list);
  2192. if (parser->last_error) goto err;
  2193. }
  2194. gf_list_add(cmdList, com);
  2195. return GF_OK;
  2196. }
  2197. if (!strcmp(str, "DELETEPROTO")) {
  2198. if (!gf_bt_check_code(parser, '[')) {
  2199. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_PROTO_DELETE_ALL);
  2200. str = gf_bt_get_next(parser, 0);
  2201. if (strcmp(str, "ALL")) {
  2202. gf_bt_report(parser, GF_BAD_PARAM, "ALL expected");
  2203. goto err;
  2204. }
  2205. return gf_list_add(cmdList, com);
  2206. }
  2207. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_PROTO_DELETE);
  2208. while (!gf_bt_check_code(parser, ']')) {
  2209. GF_Proto *proto;
  2210. str = gf_bt_get_next(parser, 0);
  2211. proto = gf_sg_find_proto(parser->load->scene_graph, 0, str);
  2212. if (!proto) {
  2213. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown proto", str);
  2214. goto err;
  2215. }
  2216. com->del_proto_list = (u32*)realloc(com->del_proto_list, sizeof(u32)*(com->del_proto_list_size+1));
  2217. com->del_proto_list[com->del_proto_list_size] = proto->ID;
  2218. com->del_proto_list_size++;
  2219. }
  2220. gf_list_add(cmdList, com);
  2221. return GF_OK;
  2222. }
  2223. return gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown command syntax, str");
  2224. err:
  2225. if (com) gf_sg_command_del(com);
  2226. return parser->last_error;
  2227. }
  2228. GF_Descriptor *gf_bt_parse_descriptor(GF_BTParser *parser, char *name);
  2229. GF_IPMPX_Data *gf_bt_parse_ipmpx(GF_BTParser *parser, char *name)
  2230. {
  2231. char *str, field[500];
  2232. GF_IPMPX_Data *desc, *subdesc;
  2233. GF_Descriptor *oddesc;
  2234. GF_Err e;
  2235. u32 type;
  2236. u8 tag;
  2237. if (name) {
  2238. str = name;
  2239. } else {
  2240. str = gf_bt_get_next(parser, 0);
  2241. }
  2242. tag = gf_ipmpx_get_tag(str);
  2243. if (!tag) {
  2244. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown IPMPX Data", str);
  2245. return NULL;
  2246. }
  2247. desc = gf_ipmpx_data_new(tag);
  2248. if (!desc) return NULL;
  2249. if (!gf_bt_check_code(parser, '{')) return desc;
  2250. while (1) {
  2251. /*done*/
  2252. if (gf_bt_check_code(parser, '}')) break;
  2253. str = gf_bt_get_next(parser, 0);
  2254. strcpy(field, str);
  2255. type = gf_ipmpx_get_field_type(desc, str);
  2256. switch (type) {
  2257. /*single descriptor*/
  2258. case GF_ODF_FT_OD:
  2259. assert(desc->tag==GF_IPMPX_CONNECT_TOOL_TAG);
  2260. str = gf_bt_get_next(parser, 0);
  2261. oddesc = gf_bt_parse_descriptor(parser, str);
  2262. if (!oddesc) {
  2263. gf_bt_report(parser, GF_BAD_PARAM, "Unknown desc %s in field %s", str, field);
  2264. gf_ipmpx_data_del(desc);
  2265. return NULL;
  2266. }
  2267. assert(oddesc->tag==GF_ODF_IPMP_TAG);
  2268. ((GF_IPMPX_ConnectTool *)desc)->toolDescriptor = (GF_IPMP_Descriptor *)oddesc;
  2269. break;
  2270. /*descriptor list*/
  2271. case GF_ODF_FT_OD_LIST:
  2272. assert(desc->tag==GF_IPMPX_GET_TOOLS_RESPONSE_TAG);
  2273. if (gf_bt_check_code(parser, '[')) {
  2274. while (!gf_bt_check_code(parser, ']')) {
  2275. GF_Descriptor *ipmp_t = gf_bt_parse_descriptor(parser, NULL);
  2276. if (!ipmp_t) {
  2277. gf_ipmpx_data_del(desc);
  2278. parser->last_error = GF_BAD_PARAM;
  2279. return NULL;
  2280. }
  2281. assert(ipmp_t->tag==GF_ODF_IPMP_TOOL_TAG);
  2282. gf_list_add( ((GF_IPMPX_GetToolsResponse *)desc)->ipmp_tools, ipmp_t);
  2283. }
  2284. }
  2285. break;
  2286. /*IPMPX ByteArray list*/
  2287. case GF_ODF_FT_IPMPX_BA_LIST:
  2288. if (gf_bt_check_code(parser, '[')) {
  2289. while (!gf_bt_check_code(parser, ']')) {
  2290. str = gf_bt_get_next(parser, 0);
  2291. if (!str) continue;
  2292. if (gf_ipmpx_set_byte_array(desc, field, str) != GF_OK) {
  2293. gf_bt_report(parser, GF_OK, "Invalid ipmpx %s in field %s - skipping", str, field);
  2294. }
  2295. gf_bt_check_code(parser, ',');
  2296. }
  2297. }
  2298. break;
  2299. /*IPMPX ByteArray: check if declared as sub-data or not*/
  2300. case GF_ODF_FT_IPMPX_BA:
  2301. str = NULL;
  2302. if (gf_bt_check_code(parser, '{')) {
  2303. str = gf_bt_get_next(parser, 0);
  2304. if (stricmp(str, "array")) {
  2305. gf_bt_report(parser, GF_BAD_PARAM, "IPMP ByteArray syntax is %s { array \"...\" } or %s \"....\"\n", field, field);
  2306. gf_ipmpx_data_del(desc);
  2307. return NULL;
  2308. }
  2309. str = gf_bt_get_next(parser, 0);
  2310. gf_bt_check_code(parser, '}');
  2311. } else {
  2312. str = gf_bt_get_next(parser, 0);
  2313. }
  2314. e = gf_ipmpx_set_byte_array(desc, field, str);
  2315. if (e) {
  2316. gf_bt_report(parser, e, "Error assigning IPMP ByteArray %s\n", field);
  2317. gf_ipmpx_data_del(desc);
  2318. return NULL;
  2319. }
  2320. break;
  2321. /*IPMPX Data list*/
  2322. case GF_ODF_FT_IPMPX_LIST:
  2323. if (gf_bt_check_code(parser, '[')) {
  2324. while (!gf_bt_check_code(parser, ']')) {
  2325. subdesc = gf_bt_parse_ipmpx(parser, NULL);
  2326. if (!subdesc) {
  2327. gf_ipmpx_data_del(desc);
  2328. parser->last_error = GF_BAD_PARAM;
  2329. return NULL;
  2330. }
  2331. if (gf_ipmpx_set_sub_data(desc, field, subdesc) != GF_OK) {
  2332. gf_bt_report(parser, GF_BAD_PARAM, "Invalid ipmpx %s in field %s - skipping", str, field);
  2333. gf_ipmpx_data_del(subdesc);
  2334. }
  2335. }
  2336. }
  2337. break;
  2338. /*regular IPMPX Data*/
  2339. case GF_ODF_FT_IPMPX:
  2340. str = gf_bt_get_next(parser, 0);
  2341. subdesc = gf_bt_parse_ipmpx(parser, str);
  2342. if (!subdesc) {
  2343. gf_bt_report(parser, GF_BAD_PARAM, "Unknown ipmpx %s in field %s", str, field);
  2344. gf_ipmpx_data_del(desc);
  2345. return NULL;
  2346. }
  2347. if (gf_ipmpx_set_sub_data(desc, field, subdesc) != GF_OK) {
  2348. gf_bt_report(parser, GF_BAD_PARAM, "Invalid ipmpx in field %s - skipping", field);
  2349. gf_ipmpx_data_del(subdesc);
  2350. }
  2351. break;
  2352. default:
  2353. str = gf_bt_get_next(parser, 0);
  2354. parser->last_error = gf_ipmpx_set_field(desc, field, str);
  2355. if (parser->last_error) {
  2356. gf_bt_report(parser, GF_BAD_PARAM, "Invalid value %s in field %s", str, field);
  2357. gf_ipmpx_data_del(desc);
  2358. return NULL;
  2359. }
  2360. break;
  2361. }
  2362. }
  2363. return desc;
  2364. }
  2365. static void gf_bt_add_desc(GF_BTParser *parser, GF_Descriptor *par, GF_Descriptor *child, char *fieldName)
  2366. {
  2367. GF_Err e = gf_odf_desc_add_desc(par, child);
  2368. if (e) {
  2369. gf_bt_report(parser, GF_OK, "Invalid child descriptor in field %s - skipping", fieldName);
  2370. gf_odf_desc_del(child);
  2371. }
  2372. }
  2373. GF_Descriptor *gf_bt_parse_descriptor(GF_BTParser *parser, char *name)
  2374. {
  2375. char *str, field[500];
  2376. GF_Descriptor *desc, *subdesc;
  2377. u32 type;
  2378. u8 tag;
  2379. if (name) {
  2380. str = name;
  2381. } else {
  2382. str = gf_bt_get_next(parser, 0);
  2383. }
  2384. tag = gf_odf_get_tag_by_name(str);
  2385. if (!tag) {
  2386. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown descriptor", str);
  2387. return NULL;
  2388. }
  2389. desc = gf_odf_desc_new(tag);
  2390. if (!desc) return NULL;
  2391. if (!gf_bt_check_code(parser, '{')) return desc;
  2392. while (1) {
  2393. Bool is_anim_mask = 0;
  2394. /*done*/
  2395. if (gf_bt_check_code(parser, '}')) break;
  2396. str = gf_bt_get_next(parser, 0);
  2397. strcpy(field, str);
  2398. if ((tag==GF_ODF_BIFS_CFG_TAG) && !strcmp(field, "animationMask")) {
  2399. gf_bt_get_next(parser, 0);
  2400. if (gf_bt_check_code(parser, '{')) is_anim_mask = 1;
  2401. str = gf_bt_get_next(parser, 0);
  2402. strcpy(field, str);
  2403. }
  2404. type = gf_odf_get_field_type(desc, str);
  2405. switch (type) {
  2406. /*IPMPX list*/
  2407. case GF_ODF_FT_IPMPX_LIST:
  2408. if(desc->tag!=GF_ODF_IPMP_TAG) {
  2409. gf_bt_report(parser, GF_BAD_PARAM, "IPMPX_Data list only allowed in GF_IPMP_Descriptor");
  2410. gf_odf_desc_del(desc);
  2411. return NULL;
  2412. }
  2413. if (gf_bt_check_code(parser, '[')) {
  2414. while (!gf_bt_check_code(parser, ']')) {
  2415. GF_IPMPX_Data *ipmpx = gf_bt_parse_ipmpx(parser, NULL);
  2416. if (!ipmpx) {
  2417. gf_odf_desc_del(desc);
  2418. parser->last_error = GF_BAD_PARAM;
  2419. return NULL;
  2420. }
  2421. gf_list_add( ((GF_IPMP_Descriptor *)desc)->ipmpx_data, ipmpx);
  2422. }
  2423. }
  2424. break;
  2425. /*IPMPX*/
  2426. case GF_ODF_FT_IPMPX:
  2427. if(desc->tag!=GF_ODF_IPMP_TOOL_TAG) {
  2428. gf_bt_report(parser, GF_BAD_PARAM, "IPMPX_Data only allowed in GF_IPMP_Tool");
  2429. gf_odf_desc_del(desc);
  2430. return NULL;
  2431. }
  2432. if (gf_bt_check_code(parser, '[')) {
  2433. while (!gf_bt_check_code(parser, ']')) {
  2434. GF_IPMPX_Data *ipmpx = gf_bt_parse_ipmpx(parser, NULL);
  2435. if (!ipmpx) {
  2436. gf_odf_desc_del(desc);
  2437. parser->last_error = GF_BAD_PARAM;
  2438. return NULL;
  2439. }
  2440. if (ipmpx->tag==GF_IPMPX_PARAMETRIC_DESCRIPTION_TAG) {
  2441. GF_IPMP_Tool *it = (GF_IPMP_Tool *)desc;
  2442. if (it->toolParamDesc) gf_ipmpx_data_del((GF_IPMPX_Data *)it->toolParamDesc);
  2443. it->toolParamDesc = (GF_IPMPX_ParametricDescription*)ipmpx;
  2444. } else {
  2445. gf_bt_report(parser, GF_OK, "Only ToolParametricDescription allowed in GF_IPMP_Tool - skipping");
  2446. gf_ipmpx_data_del(ipmpx);
  2447. }
  2448. }
  2449. }
  2450. break;
  2451. /*descriptor list*/
  2452. case GF_ODF_FT_OD_LIST:
  2453. if (gf_bt_check_code(parser, '[')) {
  2454. while (!gf_bt_check_code(parser, ']')) {
  2455. subdesc = gf_bt_parse_descriptor(parser, NULL);
  2456. if (!subdesc) {
  2457. gf_odf_desc_del(desc);
  2458. parser->last_error = GF_BAD_PARAM;
  2459. return NULL;
  2460. }
  2461. gf_bt_add_desc(parser, desc, subdesc, field);
  2462. }
  2463. }
  2464. if (is_anim_mask)
  2465. gf_bt_check_code(parser, '}');
  2466. break;
  2467. /*single descriptor*/
  2468. case GF_ODF_FT_OD:
  2469. str = gf_bt_get_next(parser, 0);
  2470. subdesc = gf_bt_parse_descriptor(parser, str);
  2471. if (!subdesc) {
  2472. gf_bt_report(parser, GF_BAD_PARAM, "Unknown desc %s in field %s", str, field);
  2473. gf_odf_desc_del(desc);
  2474. return NULL;
  2475. }
  2476. gf_bt_add_desc(parser, desc, subdesc, field);
  2477. break;
  2478. /*regular field*/
  2479. default:
  2480. str = gf_bt_get_next(parser, 0);
  2481. parser->last_error = gf_odf_set_field(desc, field, str);
  2482. if (parser->last_error) {
  2483. gf_bt_report(parser, GF_BAD_PARAM, "Invalid value %s in field %s", str, field);
  2484. gf_odf_desc_del(desc);
  2485. return NULL;
  2486. }
  2487. break;
  2488. }
  2489. }
  2490. if (desc->tag == GF_ODF_BIFS_CFG_TAG) {
  2491. GF_BIFSConfig *bcfg = (GF_BIFSConfig *)desc;
  2492. if (!parser->load->ctx->scene_width) {
  2493. parser->load->ctx->scene_width = bcfg->pixelWidth;
  2494. parser->load->ctx->scene_height = bcfg->pixelHeight;
  2495. parser->load->ctx->is_pixel_metrics = bcfg->pixelMetrics;
  2496. }
  2497. /*for bt->xmt*/
  2498. if (!bcfg->version) bcfg->version = 1;
  2499. }
  2500. else if (desc->tag==GF_ODF_ESD_TAG) {
  2501. GF_ESD *esd =(GF_ESD*)desc;
  2502. if (esd->decoderConfig) {
  2503. /*watchout for default BIFS stream*/
  2504. if (parser->bifs_es && !parser->base_bifs_id && (esd->decoderConfig->streamType==GF_STREAM_SCENE)) {
  2505. parser->bifs_es->ESID = parser->base_bifs_id = esd->ESID;
  2506. parser->bifs_es->timeScale = esd->slConfig ? esd->slConfig->timestampResolution : 1000;
  2507. } else {
  2508. GF_StreamContext *sc = gf_sm_stream_new(parser->load->ctx, esd->ESID, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication);
  2509. /*set default timescale for systems tracks (ignored for other)*/
  2510. if (sc) sc->timeScale = esd->slConfig ? esd->slConfig->timestampResolution : 1000;
  2511. /*assign base OD*/
  2512. if (!parser->base_od_id && (esd->decoderConfig->streamType==GF_STREAM_OD)) parser->base_od_id = esd->ESID;
  2513. }
  2514. }
  2515. }
  2516. return desc;
  2517. }
  2518. void gf_bt_parse_od_command(GF_BTParser *parser, char *name)
  2519. {
  2520. u32 val;
  2521. char *str;
  2522. GF_Descriptor *desc;
  2523. if (!strcmp(name, "UPDATE")) {
  2524. str = gf_bt_get_next(parser, 0);
  2525. /*OD update*/
  2526. if (!strcmp(str, "OD")) {
  2527. GF_ODUpdate *odU;
  2528. if (!gf_bt_check_code(parser, '[')) {
  2529. gf_bt_report(parser, GF_BAD_PARAM, "[ expected");
  2530. return;
  2531. }
  2532. odU = (GF_ODUpdate *) gf_odf_com_new(GF_ODF_OD_UPDATE_TAG);
  2533. gf_list_add(parser->od_au->commands, odU);
  2534. while (!parser->done) {
  2535. str = gf_bt_get_next(parser, 0);
  2536. if (gf_bt_check_code(parser, ']')) break;
  2537. if (strcmp(str, "ObjectDescriptor") && strcmp(str, "InitialObjectDescriptor")) {
  2538. gf_bt_report(parser, GF_BAD_PARAM, "Object Descriptor expected got %s", str);
  2539. break;
  2540. }
  2541. desc = gf_bt_parse_descriptor(parser, str);
  2542. if (!desc) break;
  2543. gf_list_add(odU->objectDescriptors, desc);
  2544. }
  2545. return;
  2546. }
  2547. /*ESD update*/
  2548. if (!strcmp(str, "ESD")) {
  2549. GF_ESDUpdate *esdU;
  2550. str = gf_bt_get_next(parser, 0);
  2551. if (strcmp(str, "IN")) {
  2552. gf_bt_report(parser, GF_BAD_PARAM, "IN expected got %s", str);
  2553. return;
  2554. }
  2555. esdU = (GF_ESDUpdate *) gf_odf_com_new(GF_ODF_ESD_UPDATE_TAG);
  2556. parser->last_error = gf_bt_parse_int(parser, "OD_ID", (SFInt32*)&val);
  2557. if (parser->last_error) return;
  2558. esdU->ODID = val;
  2559. gf_list_add(parser->od_au->commands, esdU);
  2560. if (!gf_bt_check_code(parser, '[')) {
  2561. str = gf_bt_get_next(parser, 0);
  2562. if (strcmp(str, "esDescr")) {
  2563. gf_bt_report(parser, GF_BAD_PARAM, "esDescr expected got %s", str);
  2564. return;
  2565. }
  2566. if (!gf_bt_check_code(parser, '[')) {
  2567. gf_bt_report(parser, GF_BAD_PARAM, "[ expected");
  2568. return;
  2569. }
  2570. }
  2571. while (!parser->done) {
  2572. str = gf_bt_get_next(parser, 0);
  2573. if (gf_bt_check_code(parser, ']')) break;
  2574. if (strcmp(str, "ESDescriptor")) {
  2575. gf_bt_report(parser, GF_BAD_PARAM, "ESDescriptor expected got %s", str);
  2576. break;
  2577. }
  2578. desc = gf_bt_parse_descriptor(parser, str);
  2579. if (!desc) break;
  2580. gf_list_add(esdU->ESDescriptors, desc);
  2581. }
  2582. return;
  2583. }
  2584. /*IPMP descriptor update*/
  2585. if (!strcmp(str, "IPMPD") || !strcmp(str, "IPMPDX")) {
  2586. GF_IPMPUpdate *ipU;
  2587. if (!gf_bt_check_code(parser, '[')) {
  2588. gf_bt_report(parser, GF_BAD_PARAM, "[ expected");
  2589. return;
  2590. }
  2591. ipU = (GF_IPMPUpdate *) gf_odf_com_new(GF_ODF_IPMP_UPDATE_TAG);
  2592. gf_list_add(parser->od_au->commands, ipU);
  2593. while (!parser->done) {
  2594. str = gf_bt_get_next(parser, 0);
  2595. if (gf_bt_check_code(parser, ']')) break;
  2596. if (strcmp(str, "IPMP_Descriptor")) {
  2597. gf_bt_report(parser, GF_BAD_PARAM, "IPMP_Descriptor expected got %s", str);
  2598. break;
  2599. }
  2600. desc = gf_bt_parse_descriptor(parser, str);
  2601. if (!desc) break;
  2602. gf_list_add(ipU->IPMPDescList, desc);
  2603. }
  2604. return;
  2605. }
  2606. gf_bt_report(parser, GF_BAD_PARAM, "unknown OD command", str);
  2607. return;
  2608. }
  2609. if (!strcmp(name, "REMOVE")) {
  2610. str = gf_bt_get_next(parser, 0);
  2611. /*OD remove*/
  2612. if (!strcmp(str, "OD")) {
  2613. GF_ODRemove *odR;
  2614. if (!gf_bt_check_code(parser, '[')) {
  2615. gf_bt_report(parser, GF_BAD_PARAM, "[ expected");
  2616. return;
  2617. }
  2618. odR = (GF_ODRemove *) gf_odf_com_new(GF_ODF_OD_REMOVE_TAG);
  2619. gf_list_add(parser->od_au->commands, odR);
  2620. while (!parser->done) {
  2621. u32 id;
  2622. if (gf_bt_check_code(parser, ']')) break;
  2623. gf_bt_parse_int(parser, "ODID", (SFInt32*)&id);
  2624. if (parser->last_error) return;
  2625. odR->OD_ID = (u16*)realloc(odR->OD_ID, sizeof(u16) * (odR->NbODs+1));
  2626. odR->OD_ID[odR->NbODs] = id;
  2627. odR->NbODs++;
  2628. }
  2629. return;
  2630. }
  2631. /*ESD remove*/
  2632. if (!strcmp(str, "ESD")) {
  2633. u32 odid;
  2634. GF_ESDRemove *esdR;
  2635. str = gf_bt_get_next(parser, 0);
  2636. if (strcmp(str, "FROM")) {
  2637. gf_bt_report(parser, GF_BAD_PARAM, "FROM expected got %s", str);
  2638. return;
  2639. }
  2640. gf_bt_parse_int(parser, "ODID", (SFInt32*)&odid);
  2641. if (parser->last_error) return;
  2642. if (!gf_bt_check_code(parser, '[')) {
  2643. gf_bt_report(parser, GF_BAD_PARAM, "[ expected");
  2644. return;
  2645. }
  2646. esdR = (GF_ESDRemove *) gf_odf_com_new(GF_ODF_ESD_REMOVE_TAG);
  2647. esdR->ODID = odid;
  2648. gf_list_add(parser->od_au->commands, esdR);
  2649. while (!parser->done) {
  2650. u32 id;
  2651. if (gf_bt_check_code(parser, ']')) break;
  2652. gf_bt_parse_int(parser, "ES_ID", (SFInt32*)&id);
  2653. if (parser->last_error) return;
  2654. esdR->ES_ID = (u16*)realloc(esdR->ES_ID, sizeof(u16) * (esdR->NbESDs+1));
  2655. esdR->ES_ID[esdR->NbESDs] = id;
  2656. esdR->NbESDs++;
  2657. }
  2658. return;
  2659. }
  2660. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown OD command", str);
  2661. return;
  2662. }
  2663. }
  2664. GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool initial_run)
  2665. {
  2666. char *str;
  2667. GF_Node *node, *vrml_root_node;
  2668. Bool in_com;
  2669. GF_Route *r;
  2670. Bool has_id;
  2671. char szDEFName[1000];
  2672. vrml_root_node = NULL;
  2673. has_id = 0;
  2674. in_com = init_com ? 0 : 1;
  2675. parser->cur_com = init_com;
  2676. /*create a default root node for all VRML nodes*/
  2677. if ((parser->is_wrl && !parser->top_nodes) && !vrml_root_node) {
  2678. if (initial_run ) {
  2679. vrml_root_node = gf_node_new(parser->load->scene_graph, (parser->load->flags & GF_SM_LOAD_MPEG4_STRICT) ? TAG_MPEG4_Group : TAG_X3D_Group);
  2680. gf_node_register(vrml_root_node, NULL);
  2681. gf_node_init(vrml_root_node);
  2682. gf_sg_set_root_node(parser->load->scene_graph, vrml_root_node);
  2683. } else {
  2684. vrml_root_node = gf_sg_get_root_node(parser->load->scene_graph);
  2685. }
  2686. }
  2687. /*parse all top-level items*/
  2688. while (!parser->last_error) {
  2689. str = gf_bt_get_next(parser, 0);
  2690. if (parser->done) break;
  2691. /*X3D specific things (ignored for now)*/
  2692. if (!strcmp(str, "PROFILE")) gf_bt_force_line(parser);
  2693. else if (!strcmp(str, "COMPONENT")) gf_bt_force_line(parser);
  2694. else if (!strcmp(str, "META")) gf_bt_force_line(parser);
  2695. else if (!strcmp(str, "IMPORT") || !strcmp(str, "EXPORT")) {
  2696. gf_bt_report(parser, GF_NOT_SUPPORTED, "X3D IMPORT/EXPORT not implemented");
  2697. break;
  2698. }
  2699. /*IOD*/
  2700. else if (!strcmp(str, "InitialObjectDescriptor") || !strcmp(str, "ObjectDescriptor")) {
  2701. parser->load->ctx->root_od = (GF_ObjectDescriptor *) gf_bt_parse_descriptor(parser, str);
  2702. }
  2703. /*explicit command*/
  2704. else if (!strcmp(str, "AT") || !strcmp(str, "RAP")) {
  2705. parser->au_is_rap = 0;
  2706. if (!strcmp(str, "RAP")) {
  2707. parser->au_is_rap = 1;
  2708. str = gf_bt_get_next(parser, 0);
  2709. if (strcmp(str, "AT")) {
  2710. gf_bt_report(parser, GF_BAD_PARAM, "AT expected got %s", str);
  2711. parser->last_error = GF_BAD_PARAM;
  2712. break;
  2713. }
  2714. }
  2715. str = gf_bt_get_next(parser, 0);
  2716. if (str[0] == 'D') {
  2717. parser->au_time += atoi(&str[1]);
  2718. } else {
  2719. if (sscanf(str, "%d", &parser->au_time) != 1) {
  2720. gf_bt_report(parser, GF_BAD_PARAM, "Number expected got %s", str);
  2721. break;
  2722. }
  2723. }
  2724. if (parser->last_error) break;
  2725. /*reset all contexts*/
  2726. if (parser->od_au && (parser->od_au->timing != parser->au_time)) parser->od_au = NULL;
  2727. if (parser->bifs_au && (parser->bifs_au->timing != parser->au_time)) {
  2728. gf_bt_check_unresolved_nodes(parser);
  2729. parser->bifs_au = NULL;
  2730. }
  2731. parser->stream_id = 0;
  2732. /*fix for mp4tool bt which doesn't support RAP signaling: assume the first AU
  2733. is always RAP*/
  2734. if (!parser->au_time) parser->au_is_rap = 1;
  2735. in_com = 1;
  2736. if (!gf_bt_check_code(parser, '{')) {
  2737. str = gf_bt_get_next(parser, 0);
  2738. if (!strcmp(str, "IN")) {
  2739. gf_bt_parse_int(parser, "IN", (SFInt32*)&parser->stream_id);
  2740. if (parser->last_error) break;
  2741. }
  2742. if (!gf_bt_check_code(parser, '{')) {
  2743. gf_bt_report(parser, GF_BAD_PARAM, "{ expected");
  2744. }
  2745. }
  2746. /*done loading init frame*/
  2747. if (init_com) break;
  2748. }
  2749. else if (!strcmp(str, "PROTO") || !strcmp(str, "EXTERNPROTO")) {
  2750. gf_bt_parse_proto(parser, str, init_com ? init_com->new_proto_list : NULL);
  2751. }
  2752. /*compatibility for old bt (mp4tool) in ProtoLibs*/
  2753. else if (!strcmp(str, "NULL")) {
  2754. }
  2755. else if (!strcmp(str, "DEF")) {
  2756. str = gf_bt_get_next(parser, 0);
  2757. strcpy(szDEFName, str);
  2758. has_id = 1;
  2759. }
  2760. else if (!strcmp(str, "ROUTE")) {
  2761. GF_Command *com = NULL;
  2762. if (!parser->top_nodes && parser->bifs_au && !parser->is_wrl) {
  2763. /*if doing a scene replace, we need route insert stuff*/
  2764. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_ROUTE_INSERT);
  2765. gf_list_add(parser->bifs_au->commands, com);
  2766. gf_list_add(parser->inserted_routes, com);
  2767. }
  2768. r = gf_bt_parse_route(parser, 1, 0, com);
  2769. if (has_id) {
  2770. u32 rID = gf_bt_get_route(parser, szDEFName);
  2771. if (!rID) rID = gf_bt_get_next_route_id(parser);
  2772. if (com) {
  2773. com->RouteID = rID;
  2774. com->def_name = strdup(szDEFName);
  2775. gf_sg_set_max_defined_route_id(parser->load->scene_graph, rID);
  2776. } else if (r) {
  2777. gf_sg_route_set_id(r, rID);
  2778. gf_sg_route_set_name(r, szDEFName);
  2779. }
  2780. has_id = 0;
  2781. }
  2782. }
  2783. /*OD commands*/
  2784. else if (!strcmp(str, "UPDATE") || !strcmp(str, "REMOVE")) {
  2785. Bool is_base_stream = parser->stream_id ? 0 : 1;
  2786. if (!parser->stream_id || parser->stream_id==parser->bifs_es->ESID) parser->stream_id = parser->base_od_id;
  2787. if (parser->od_es && (parser->od_es->ESID != parser->stream_id)) {
  2788. GF_StreamContext *prev = parser->od_es;
  2789. parser->od_es = gf_sm_stream_new(parser->load->ctx, (u16) parser->stream_id, GF_STREAM_OD, 0);
  2790. /*force new AU if stream changed*/
  2791. if (parser->od_es != prev) parser->bifs_au = NULL;
  2792. }
  2793. if (!parser->od_es) parser->od_es = gf_sm_stream_new(parser->load->ctx, (u16) parser->stream_id, GF_STREAM_OD, 0);
  2794. if (!parser->od_au) parser->od_au = gf_sm_stream_au_new(parser->od_es, parser->au_time, 0, parser->au_is_rap);
  2795. gf_bt_parse_od_command(parser, str);
  2796. if (is_base_stream) parser->stream_id= 0;
  2797. }
  2798. /*BIFS commands*/
  2799. else if (!strcmp(str, "REPLACE") || !strcmp(str, "INSERT") || !strcmp(str, "APPEND") || !strcmp(str, "DELETE")
  2800. /*BIFS extended commands*/
  2801. || !strcmp(str, "GLOBALQP") || !strcmp(str, "MULTIPLEREPLACE") || !strcmp(str, "MULTIPLEINDREPLACE") || !strcmp(str, "XDELETE") || !strcmp(str, "DELETEPROTO") || !strcmp(str, "INSERTPROTO") ) {
  2802. Bool is_base_stream = parser->stream_id ? 0 : 1;
  2803. if (!parser->stream_id) parser->stream_id = parser->base_bifs_id;
  2804. if (!parser->stream_id || (parser->od_es && (parser->stream_id==parser->od_es->ESID)) ) parser->stream_id = parser->base_bifs_id;
  2805. if (parser->bifs_es->ESID != parser->stream_id) {
  2806. GF_StreamContext *prev = parser->bifs_es;
  2807. parser->bifs_es = gf_sm_stream_new(parser->load->ctx, (u16) parser->stream_id, GF_STREAM_SCENE, 0);
  2808. /*force new AU if stream changed*/
  2809. if (parser->bifs_es != prev) {
  2810. gf_bt_check_unresolved_nodes(parser);
  2811. parser->bifs_au = NULL;
  2812. }
  2813. }
  2814. if (!parser->bifs_au) parser->bifs_au = gf_sm_stream_au_new(parser->bifs_es, parser->au_time, 0, parser->au_is_rap);
  2815. gf_bt_parse_bifs_command(parser, str, parser->bifs_au->commands);
  2816. if (is_base_stream) parser->stream_id= 0;
  2817. }
  2818. /*implicit BIFS command on SFTopNodes only*/
  2819. else if (!strcmp(str, "OrderedGroup")
  2820. || !strcmp(str, "Group")
  2821. || !strcmp(str, "Layer2D")
  2822. || !strcmp(str, "Layer3D")
  2823. /* VRML parsing: all nodes are allowed*/
  2824. || parser->is_wrl
  2825. )
  2826. {
  2827. node = gf_bt_sf_node(parser, str, vrml_root_node, has_id ? szDEFName : NULL);
  2828. has_id = 0;
  2829. if (!node) break;
  2830. if (parser->top_nodes) {
  2831. gf_list_add(parser->top_nodes, node);
  2832. } else if (!vrml_root_node) {
  2833. if (init_com) init_com->node = node;
  2834. else if (parser->load->flags & GF_SM_LOAD_CONTEXT_READY) {
  2835. GF_Command *com = gf_sg_command_new(parser->load->scene_graph, GF_SG_SCENE_REPLACE);
  2836. assert(!parser->bifs_au);
  2837. assert(parser->bifs_es);
  2838. parser->bifs_au = gf_sm_stream_au_new(parser->bifs_es, 0, 0, 1);
  2839. gf_list_add(parser->bifs_au->commands, com);
  2840. com->node = node;
  2841. }
  2842. } else {
  2843. gf_node_insert_child(vrml_root_node, node, -1);
  2844. }
  2845. }
  2846. /*if in command, check command end*/
  2847. else {
  2848. /*check command end*/
  2849. if (/*in_com && */gf_bt_check_code(parser, '}')) in_com = 0;
  2850. else if (strlen(str)) {
  2851. gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown top-level element", str);
  2852. }
  2853. parser->au_is_rap = 0;
  2854. }
  2855. }
  2856. gf_bt_resolve_routes(parser, 0);
  2857. gf_bt_check_unresolved_nodes(parser);
  2858. /*load scripts*/
  2859. while (gf_list_count(parser->scripts)) {
  2860. GF_Node *n = (GF_Node *)gf_list_get(parser->scripts, 0);
  2861. gf_list_rem(parser->scripts, 0);
  2862. gf_sg_script_load(n);
  2863. }
  2864. return parser->last_error;
  2865. }
  2866. GF_Err gf_sm_load_init_BT(GF_SceneLoader *load)
  2867. {
  2868. u32 size;
  2869. gzFile gzInput;
  2870. GF_Err e;
  2871. GF_BTParser *parser;
  2872. GF_Command *com;
  2873. FILE *test;
  2874. unsigned char BOM[5];
  2875. if (!load->ctx || !load->fileName) return GF_BAD_PARAM;
  2876. test = fopen(load->fileName, "rb");
  2877. if (!test) return GF_URL_ERROR;
  2878. fseek(test, 0, SEEK_END);
  2879. size = ftell(test);
  2880. fclose(test);
  2881. gzInput = gzopen(load->fileName, "rb");
  2882. if (!gzInput) return GF_IO_ERR;
  2883. GF_SAFEALLOC(parser, GF_BTParser);
  2884. parser->load = load;
  2885. parser->line_buffer = (char *) malloc(sizeof(char)*BT_LINE_SIZE);
  2886. memset(parser->line_buffer, 0, sizeof(char)*BT_LINE_SIZE);
  2887. parser->file_size = size;
  2888. gzgets(gzInput, (char*) BOM, 5);
  2889. gzseek(gzInput, 0, SEEK_SET);
  2890. /*0: no unicode, 1: UTF-16BE, 2: UTF-16LE*/
  2891. if ((BOM[0]==0xFF) && (BOM[1]==0xFE)) {
  2892. if (!BOM[2] && !BOM[3]) {
  2893. gf_bt_report(parser, GF_NOT_SUPPORTED, "UTF-32 Text Files not supported");
  2894. gzclose(gzInput);
  2895. free(parser);
  2896. return GF_NOT_SUPPORTED;
  2897. } else {
  2898. parser->unicode_type = 2;
  2899. gzseek(gzInput, 2, SEEK_CUR);
  2900. }
  2901. } else if ((BOM[0]==0xFE) && (BOM[1]==0xFF)) {
  2902. if (!BOM[2] && !BOM[3]) {
  2903. gf_bt_report(parser, GF_NOT_SUPPORTED, "UTF-32 Text Files not supported");
  2904. gzclose(gzInput);
  2905. free(parser);
  2906. return GF_NOT_SUPPORTED;
  2907. } else {
  2908. parser->unicode_type = 1;
  2909. gzseek(gzInput, 2, SEEK_CUR);
  2910. }
  2911. } else if ((BOM[0]==0xEF) && (BOM[1]==0xBB) && (BOM[2]==0xBF)) {
  2912. /*we handle UTF8 as asci*/
  2913. parser->unicode_type = 0;
  2914. gzseek(gzInput, 3, SEEK_CUR);
  2915. }
  2916. parser->gz_in = gzInput;
  2917. load->loader_priv = parser;
  2918. parser->def_symbols = gf_list_new();
  2919. parser->unresolved_routes = gf_list_new();
  2920. parser->inserted_routes = gf_list_new();
  2921. parser->undef_nodes = gf_list_new();
  2922. parser->def_nodes = gf_list_new();
  2923. parser->peeked_nodes = gf_list_new();
  2924. parser->scripts = gf_list_new();
  2925. /*chunk parsing*/
  2926. if (load->flags & GF_SM_LOAD_CONTEXT_READY) {
  2927. u32 i;
  2928. GF_StreamContext *sc;
  2929. if (!load->ctx) {
  2930. gf_sm_load_done_BT(load);
  2931. return GF_BAD_PARAM;
  2932. }
  2933. /*restore context - note that base layer are ALWAYS declared BEFORE enhancement layers with gpac parsers*/
  2934. i=0;
  2935. while ((sc = (GF_StreamContext*)gf_list_enum(load->ctx->streams, &i))) {
  2936. switch (sc->streamType) {
  2937. case GF_STREAM_SCENE: if (!parser->bifs_es) parser->bifs_es = sc; break;
  2938. case GF_STREAM_OD: if (!parser->od_es) parser->od_es = sc; break;
  2939. default: break;
  2940. }
  2941. }
  2942. /*need at least one scene stream*/
  2943. if (!parser->bifs_es) {
  2944. gf_sm_load_done_BT(load);
  2945. return GF_BAD_PARAM;
  2946. }
  2947. parser->base_bifs_id = parser->bifs_es->ESID;
  2948. if (parser->od_es) parser->base_od_id = parser->od_es->ESID;
  2949. GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("BT: MPEG-4 (BT) Scene Chunk Parsing"));
  2950. /*that's it, nothing else to do*/
  2951. return GF_OK;
  2952. }
  2953. parser->load = NULL;
  2954. gf_bt_check_line(parser);
  2955. parser->load = load;
  2956. /*create at least one empty BIFS stream*/
  2957. if (!parser->is_wrl) {
  2958. parser->bifs_es = gf_sm_stream_new(load->ctx, 0, GF_STREAM_SCENE, 0);
  2959. parser->bifs_au = gf_sm_stream_au_new(parser->bifs_es, 0, 0, 1);
  2960. parser->load->ctx->is_pixel_metrics = 1;
  2961. }
  2962. GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ( ((parser->is_wrl==2) ? "BT: X3D (WRL) Scene Parsing\n" : (parser->is_wrl ? "BT: VRML Scene Parsing\n" : "BT: MPEG-4 Scene Parsing\n")) ));
  2963. /*default scene replace - we create it no matter what since it is used to store BIFS config
  2964. when parsing IOD.*/
  2965. com = NULL;
  2966. if (!parser->is_wrl) {
  2967. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_SCENE_REPLACE);
  2968. gf_list_add(parser->bifs_au->commands, com);
  2969. }
  2970. e = gf_bt_loader_run_intern(parser, com, 1);
  2971. if (e) gf_sm_load_done_BT(load);
  2972. return e;
  2973. }
  2974. void gf_sm_load_done_BT(GF_SceneLoader *load)
  2975. {
  2976. GF_BTParser *parser = (GF_BTParser *)load->loader_priv;
  2977. if (!parser) return;
  2978. gf_list_del(parser->unresolved_routes);
  2979. gf_list_del(parser->inserted_routes);
  2980. gf_list_del(parser->undef_nodes);
  2981. gf_list_del(parser->def_nodes);
  2982. gf_list_del(parser->peeked_nodes);
  2983. while (gf_list_count(parser->def_symbols)) {
  2984. BTDefSymbol *d = (BTDefSymbol *)gf_list_get(parser->def_symbols, 0);
  2985. gf_list_rem(parser->def_symbols, 0);
  2986. free(d->name);
  2987. free(d->value);
  2988. free(d);
  2989. }
  2990. gf_list_del(parser->def_symbols);
  2991. gf_list_del(parser->scripts);
  2992. gzclose(parser->gz_in);
  2993. free(parser->line_buffer);
  2994. free(parser);
  2995. load->loader_priv = NULL;
  2996. return;
  2997. }
  2998. GF_Err gf_sm_load_run_BT(GF_SceneLoader *load)
  2999. {
  3000. GF_BTParser *parser = (GF_BTParser *)load->loader_priv;
  3001. if (!parser) return GF_BAD_PARAM;
  3002. return gf_bt_loader_run_intern(parser, NULL, 0);
  3003. }
  3004. GF_List *gf_sm_load_bt_from_string(GF_SceneGraph *in_scene, char *node_str)
  3005. {
  3006. GF_SceneLoader ctx;
  3007. GF_BTParser parser;
  3008. memset(&ctx, 0, sizeof(GF_SceneLoader));
  3009. ctx.scene_graph = in_scene;
  3010. memset(&parser, 0, sizeof(GF_BTParser));
  3011. parser.line_buffer = node_str;
  3012. parser.line_size = strlen(node_str);
  3013. parser.load = &ctx;
  3014. parser.top_nodes = gf_list_new();
  3015. parser.undef_nodes = gf_list_new();
  3016. parser.def_nodes = gf_list_new();
  3017. parser.peeked_nodes = gf_list_new();
  3018. parser.is_wrl = 1;
  3019. gf_bt_loader_run_intern(&parser, NULL, 1);
  3020. gf_list_del(parser.undef_nodes);
  3021. gf_list_del(parser.def_nodes);
  3022. gf_list_del(parser.peeked_nodes);
  3023. while (gf_list_count(parser.def_symbols)) {
  3024. BTDefSymbol *d = (BTDefSymbol *)gf_list_get(parser.def_symbols, 0);
  3025. gf_list_rem(parser.def_symbols, 0);
  3026. free(d->name);
  3027. free(d->value);
  3028. free(d);
  3029. }
  3030. gf_list_del(parser.def_symbols);
  3031. gf_list_del(parser.scripts);
  3032. return parser.top_nodes;
  3033. }
  3034. GF_Err gf_sm_load_done_BTString(GF_SceneLoader *load)
  3035. {
  3036. GF_BTParser *parser = (GF_BTParser *)load->loader_priv;
  3037. if (!parser) return GF_OK;
  3038. gf_list_del(parser->unresolved_routes);
  3039. gf_list_del(parser->inserted_routes);
  3040. gf_list_del(parser->undef_nodes);
  3041. gf_list_del(parser->def_nodes);
  3042. gf_list_del(parser->scripts);
  3043. free(parser);
  3044. load->loader_priv = NULL;
  3045. return GF_OK;
  3046. }
  3047. GF_Err gf_sm_load_init_BTString(GF_SceneLoader *load, char *str)
  3048. {
  3049. GF_Err e;
  3050. GF_BTParser *parser;
  3051. GF_Command *com;
  3052. if (!load || (!load->ctx && !load->scene_graph) || !str) return GF_BAD_PARAM;
  3053. if (!load->scene_graph) load->scene_graph = load->ctx->scene_graph;
  3054. parser = (GF_BTParser *)malloc(sizeof(GF_BTParser));
  3055. if (parser) memset(parser, 0, sizeof(GF_BTParser));
  3056. else
  3057. return GF_OUT_OF_MEM;
  3058. parser->is_wrl = 0;
  3059. parser->load = load;
  3060. /*we suppose an ascii string*/
  3061. parser->unicode_type = 0;
  3062. parser->line_buffer = str;
  3063. parser->line_size = (s32)strlen(str);
  3064. parser->gz_in = NULL;
  3065. load->loader_priv = parser;
  3066. parser->unresolved_routes = gf_list_new();
  3067. parser->inserted_routes = gf_list_new();
  3068. parser->undef_nodes = gf_list_new();
  3069. parser->def_nodes = gf_list_new();
  3070. parser->scripts = gf_list_new();
  3071. /*chunk parsing*/
  3072. if (load->flags & GF_SM_LOAD_CONTEXT_READY) {
  3073. u32 i;
  3074. GF_StreamContext *sc;
  3075. if (!load->ctx) {
  3076. gf_sm_load_done_BT(load);
  3077. return GF_BAD_PARAM;
  3078. }
  3079. /*restore context - note that base layer are ALWAYS declared BEFORE enhancement layers with gpac parsers*/
  3080. i=0;
  3081. while ((sc = (GF_StreamContext*)gf_list_enum(load->ctx->streams, &i))){
  3082. switch (sc->streamType) {
  3083. case GF_STREAM_SCENE:
  3084. case GF_STREAM_PRIVATE_SCENE:
  3085. if (!parser->bifs_es) parser->bifs_es = sc; break;
  3086. case GF_STREAM_OD: if (!parser->od_es) parser->od_es = sc; break;
  3087. default: break;
  3088. }
  3089. }
  3090. /*scene creation - pick up a size*/
  3091. if (!parser->bifs_es) {
  3092. parser->bifs_es = gf_sm_stream_new(load->ctx, 0, GF_STREAM_SCENE, 0);
  3093. parser->load->ctx->scene_width = 0;
  3094. parser->load->ctx->scene_height = 0;
  3095. parser->load->ctx->is_pixel_metrics = 1;
  3096. }
  3097. else parser->base_bifs_id = parser->bifs_es->ESID;
  3098. if (parser->od_es) parser->base_od_id = parser->od_es->ESID;
  3099. /*that's it, nothing else to do*/
  3100. return GF_OK;
  3101. }
  3102. /*create at least one empty BIFS stream*/
  3103. parser->bifs_es = gf_sm_stream_new(load->ctx, 0, GF_STREAM_SCENE, 0);
  3104. parser->bifs_au = gf_sm_stream_au_new(parser->bifs_es, 0, 0, 1);
  3105. /*default scene replace - we create it no matter what since it is used to store BIFS config
  3106. when parsing IOD.*/
  3107. com = gf_sg_command_new(parser->load->scene_graph, GF_SG_SCENE_REPLACE);
  3108. gf_list_add(parser->bifs_au->commands, com);
  3109. e = gf_bt_loader_run_intern(parser, com, 1);
  3110. if (e) gf_sm_load_done_BTString(load);
  3111. return e;
  3112. }