PageRenderTime 71ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/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

Large files files are truncated, but you can click here to view the full file

  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_ch

Large files files are truncated, but you can click here to view the full file