Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2012
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / Scene Management sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include <gpac/scene_manager.h>
27 : #include <gpac/constants.h>
28 : #include <gpac/utf.h>
29 : #include <gpac/internal/scenegraph_dev.h>
30 : #include <gpac/nodes_x3d.h>
31 : #include <gpac/nodes_svg.h>
32 : #include <gpac/events.h>
33 : #include <gpac/base_coding.h>
34 :
35 : #ifndef __SYMBIAN32__
36 : #include <wchar.h>
37 : #endif
38 :
39 : #ifndef GPAC_DISABLE_SCENE_DUMP
40 :
41 : /*for QP types*/
42 : #include "../bifs/quant.h"
43 :
44 : struct _scenedump
45 : {
46 : /*the scene we're dumping - set at each SceneReplace or mannually*/
47 : GF_SceneGraph *sg;
48 : #ifndef GPAC_DISABLE_VRML
49 : /*the proto we're dumping*/
50 : GF_Proto *current_proto;
51 : #endif
52 : FILE *trace;
53 : u32 indent;
54 : char *filename;
55 :
56 : GF_SceneDumpFormat dump_mode;
57 : u16 CurrentESID;
58 : u8 ind_char;
59 : Bool XMLDump, X3DDump, LSRDump;
60 :
61 : GF_List *dump_nodes;
62 :
63 : /*nodes created through conditionals while parsing but not applied*/
64 : GF_List *mem_def_nodes;
65 :
66 : Bool skip_scene_replace;
67 : /*for route insert/replace in conditionals in current scene replace*/
68 : GF_List *current_com_list;
69 : GF_List *inserted_routes;
70 :
71 : Bool in_text;
72 : };
73 :
74 : static GF_Err gf_dump_vrml_route(GF_SceneDumper *sdump, GF_Route *r, u32 dump_type);
75 : static void gf_dump_vrml_node(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldContainer);
76 :
77 : #ifndef GPAC_DISABLE_SVG
78 : void gf_dump_svg_element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool is_root);
79 : #endif
80 :
81 : GF_EXPORT
82 19 : GF_SceneDumper *gf_sm_dumper_new(GF_SceneGraph *graph, char *_rad_name, Bool is_final_name, char indent_char, GF_SceneDumpFormat dump_mode)
83 : {
84 : GF_SceneDumper *tmp;
85 19 : if (!graph) return NULL;
86 19 : GF_SAFEALLOC(tmp, GF_SceneDumper);
87 19 : if (!tmp) return NULL;
88 :
89 : /*store original*/
90 19 : tmp->dump_mode = dump_mode;
91 :
92 : #ifndef GPAC_DISABLE_SVG
93 19 : if ((graph->RootNode && (graph->RootNode->sgprivate->tag>=GF_NODE_RANGE_LAST_VRML) )
94 19 : || (dump_mode==GF_SM_DUMP_LASER) || (dump_mode==GF_SM_DUMP_SVG)) {
95 2 : tmp->XMLDump = GF_TRUE;
96 2 : if (dump_mode==GF_SM_DUMP_LASER) {
97 2 : tmp->LSRDump = GF_TRUE;
98 : }
99 2 : if (_rad_name) {
100 2 : const char* ext_name = tmp->LSRDump ? ".xsr" : ".svg";
101 2 : tmp->filename = (char *)gf_malloc(strlen(_rad_name) + strlen(ext_name) + 1);
102 : strcpy(tmp->filename, _rad_name);
103 2 : if (!is_final_name) strcat(tmp->filename, ext_name);
104 2 : tmp->trace = gf_fopen(tmp->filename, "wt");
105 2 : if (!tmp->trace) {
106 0 : gf_free(tmp);
107 0 : return NULL;
108 : }
109 : } else {
110 0 : tmp->trace = stdout;
111 : }
112 : } else
113 : #endif
114 : {
115 :
116 17 : if (dump_mode==GF_SM_DUMP_AUTO_TXT) {
117 0 : if (!graph->RootNode || (graph->RootNode->sgprivate->tag<=GF_NODE_RANGE_LAST_MPEG4) ) {
118 : dump_mode = GF_SM_DUMP_BT;
119 0 : } else if (graph->RootNode->sgprivate->tag<=GF_NODE_RANGE_LAST_X3D) {
120 : dump_mode = GF_SM_DUMP_X3D_VRML;
121 : }
122 : }
123 17 : else if (dump_mode==GF_SM_DUMP_AUTO_XML) {
124 0 : if (!graph->RootNode || (graph->RootNode->sgprivate->tag<=GF_NODE_RANGE_LAST_MPEG4) ) {
125 : dump_mode = GF_SM_DUMP_XMTA;
126 : } else {
127 : dump_mode = GF_SM_DUMP_X3D_XML;
128 : }
129 : }
130 :
131 17 : if (_rad_name) {
132 : const char* ext_name;
133 15 : switch (dump_mode) {
134 0 : case GF_SM_DUMP_X3D_XML:
135 : ext_name = ".x3d";
136 0 : tmp->XMLDump = GF_TRUE;
137 0 : tmp->X3DDump = GF_TRUE;
138 0 : break;
139 7 : case GF_SM_DUMP_XMTA:
140 : ext_name = ".xmt";
141 7 : tmp->XMLDump = GF_TRUE;
142 7 : break;
143 0 : case GF_SM_DUMP_X3D_VRML:
144 : ext_name = ".x3dv";
145 0 : tmp->X3DDump = GF_TRUE;
146 0 : break;
147 : case GF_SM_DUMP_VRML:
148 : ext_name = ".wrl";
149 : break;
150 8 : default:
151 : ext_name = ".bt";
152 8 : break;
153 : }
154 :
155 15 : tmp->filename = (char *)gf_malloc(strlen(_rad_name ? _rad_name : "") + strlen(ext_name) + 1);
156 : strcpy(tmp->filename, _rad_name ? _rad_name : "");
157 15 : if (!is_final_name) strcat(tmp->filename, ext_name);
158 15 : tmp->trace = gf_fopen(tmp->filename, "wt");
159 15 : if (!tmp->trace) {
160 0 : gf_free(tmp);
161 0 : return NULL;
162 : }
163 : } else {
164 2 : tmp->trace = stdout;
165 2 : switch (dump_mode) {
166 0 : case GF_SM_DUMP_X3D_XML:
167 0 : tmp->XMLDump = GF_TRUE;
168 0 : tmp->X3DDump = GF_TRUE;
169 0 : break;
170 0 : case GF_SM_DUMP_XMTA:
171 0 : tmp->XMLDump = GF_TRUE;
172 0 : break;
173 0 : case GF_SM_DUMP_X3D_VRML:
174 0 : tmp->X3DDump = GF_TRUE;
175 0 : break;
176 : default:
177 : break;
178 : }
179 : }
180 : }
181 19 : tmp->ind_char = indent_char;
182 19 : tmp->dump_nodes = gf_list_new();
183 19 : tmp->mem_def_nodes = gf_list_new();
184 19 : tmp->inserted_routes = gf_list_new();
185 19 : tmp->sg = graph;
186 19 : return tmp;
187 : }
188 :
189 : GF_EXPORT
190 0 : void gf_sm_dumper_set_extra_graph(GF_SceneDumper *sdump, GF_SceneGraph *extra)
191 : {
192 0 : sdump->sg = extra;
193 0 : }
194 :
195 : GF_EXPORT
196 19 : void gf_sm_dumper_del(GF_SceneDumper *sdump)
197 : {
198 19 : gf_list_del(sdump->dump_nodes);
199 38 : while (gf_list_count(sdump->mem_def_nodes)) {
200 0 : GF_Node *tmp = (GF_Node *)gf_list_get(sdump->mem_def_nodes, 0);
201 0 : gf_list_rem(sdump->mem_def_nodes, 0);
202 0 : gf_node_unregister(tmp, NULL);
203 : }
204 19 : gf_list_del(sdump->mem_def_nodes);
205 19 : gf_list_del(sdump->inserted_routes);
206 19 : if (sdump->trace != stdout) gf_fclose(sdump->trace);
207 19 : if (sdump->filename) {
208 17 : gf_free(sdump->filename);
209 17 : sdump->filename = NULL;
210 : }
211 19 : gf_free(sdump);
212 19 : }
213 :
214 0 : char *gf_sm_dump_get_name(GF_SceneDumper *bd)
215 : {
216 0 : if (!bd) return NULL;
217 0 : return bd->filename;
218 : }
219 :
220 19 : static void gf_dump_setup(GF_SceneDumper *sdump, GF_Descriptor *root_od)
221 : {
222 19 : if (sdump->XMLDump) {
223 9 : gf_fprintf(sdump->trace, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
224 9 : if (sdump->dump_mode==GF_SM_DUMP_XML) return;
225 18 : gf_fprintf(sdump->trace, "<!-- %s Scene Dump -->\n",
226 : (sdump->dump_mode==GF_SM_DUMP_SVG) ? "SVG" :
227 9 : (sdump->dump_mode==GF_SM_DUMP_LASER) ? "LASeR" :
228 7 : sdump->X3DDump ? "X3D" : "XMT-A"
229 : );
230 : }
231 19 : if (sdump->dump_mode==GF_SM_DUMP_SVG) return;
232 19 : if (sdump->LSRDump) {
233 2 : gf_fprintf(sdump->trace, "<saf:SAFSession xmlns:saf=\"urn:mpeg:mpeg4:SAF:2005\" >\n");
234 : #ifndef GPAC_DISABLE_OD_DUMP
235 2 : if (root_od) {
236 : GF_ObjectDescriptor *iod = (GF_ObjectDescriptor *)root_od;
237 : u32 i, count;
238 2 : gf_fprintf(sdump->trace, "<saf:sceneHeader>\n");
239 2 : count = gf_list_count(iod->ESDescriptors);
240 5 : for (i=0; i<count; i++) {
241 : GF_LASERConfig lsrcfg;
242 3 : GF_ESD *esd = (GF_ESD *)gf_list_get(iod->ESDescriptors, i);
243 4 : if (esd->decoderConfig->streamType != GF_STREAM_SCENE) continue;
244 2 : if (esd->decoderConfig->objectTypeIndication != 0x09) continue;
245 2 : if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->data) continue;
246 2 : gf_odf_get_laser_config(esd->decoderConfig->decoderSpecificInfo, &lsrcfg);
247 2 : gf_odf_dump_desc((GF_Descriptor*)&lsrcfg, sdump->trace, 1, 1);
248 : }
249 2 : gf_fprintf(sdump->trace, "</saf:sceneHeader>\n");
250 : }
251 : #endif
252 : return;
253 : }
254 :
255 17 : if (!sdump->X3DDump) {
256 : /*setup XMT*/
257 17 : if (sdump->XMLDump) {
258 7 : gf_fprintf(sdump->trace, "<XMT-A xmlns=\"urn:mpeg:mpeg4:xmta:schema:2002\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:mpeg:mpeg4:xmta:schema:2002 xmt-a.xsd\">\n");
259 7 : gf_fprintf(sdump->trace, " <Header>\n");
260 : #ifndef GPAC_DISABLE_OD_DUMP
261 7 : if (root_od) gf_odf_dump_desc(root_od, sdump->trace, 1, 1);
262 : #endif
263 7 : gf_fprintf(sdump->trace, " </Header>\n");
264 7 : gf_fprintf(sdump->trace, " <Body>\n");
265 7 : if (!root_od) {
266 0 : gf_fprintf(sdump->trace, " <Replace>\n");
267 : }
268 : } else {
269 10 : if (sdump->dump_mode==GF_SM_DUMP_VRML) {
270 0 : gf_fprintf(sdump->trace, "#VRML V2.0\n");
271 : } else {
272 : /*dump root OD*/
273 : #ifndef GPAC_DISABLE_OD_DUMP
274 10 : if (root_od) gf_odf_dump_desc(root_od, sdump->trace, 0, 0);
275 : #endif
276 : }
277 10 : gf_fprintf(sdump->trace, "\n");
278 : }
279 : } else {
280 0 : if (sdump->XMLDump) {
281 0 : gf_fprintf(sdump->trace, "<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\" \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n");
282 0 : gf_fprintf(sdump->trace, "<X3D xmlns:xsd=\"http://www.w3.org/2001/XMLSchema-instance\" xsd:noNamespaceSchemaLocation=\"http://www.web3d.org/specifications/x3d-3.0.xsd\" version=\"3.0\">\n");
283 0 : gf_fprintf(sdump->trace, "<head>\n");
284 0 : gf_fprintf(sdump->trace, "<meta content=\"X3D File Converted/Dumped by GPAC Version %s - %s\" name=\"generator\"/>\n", gf_gpac_version(), gf_gpac_copyright() );
285 0 : gf_fprintf(sdump->trace, "</head>\n");
286 0 : gf_fprintf(sdump->trace, " <Scene>\n");
287 : } else {
288 0 : gf_fprintf(sdump->trace, "#X3D V3.0\n\n");
289 : }
290 : }
291 : }
292 :
293 19 : static void gf_dump_finalize(GF_SceneDumper *sdump, GF_Descriptor *root_od)
294 : {
295 19 : if (sdump->dump_mode==GF_SM_DUMP_SVG) return;
296 :
297 19 : if (sdump->LSRDump) {
298 2 : gf_fprintf(sdump->trace, "<saf:endOfSAFSession/>\n</saf:SAFSession>\n");
299 2 : return;
300 : }
301 17 : if (!sdump->XMLDump) return;
302 :
303 7 : if (!sdump->X3DDump) {
304 7 : if (!root_od) {
305 0 : gf_fprintf(sdump->trace, " </Replace>\n");
306 : }
307 7 : gf_fprintf(sdump->trace, " </Body>\n");
308 7 : gf_fprintf(sdump->trace, "</XMT-A>\n");
309 : } else {
310 0 : gf_fprintf(sdump->trace, " </Scene>\n");
311 0 : gf_fprintf(sdump->trace, "</X3D>\n");
312 : }
313 : }
314 :
315 535 : static Bool gf_dump_vrml_is_def_node(GF_SceneDumper *sdump, GF_Node *node)
316 : {
317 535 : s32 i = gf_list_find(sdump->dump_nodes, node);
318 535 : if (i>=0) return 0;
319 472 : gf_list_add(sdump->dump_nodes, node);
320 : return 1;
321 : }
322 :
323 : static GF_Node *gf_dump_find_node(GF_SceneDumper *sdump, u32 ID)
324 : {
325 144 : GF_Node *ret = gf_sg_find_node(sdump->sg, ID);
326 144 : if (ret) return ret;
327 : return NULL;
328 : }
329 :
330 : #define DUMP_IND(sdump) \
331 : if (sdump->trace) { \
332 : u32 z; \
333 : for (z=0; z<sdump->indent; z++) gf_fprintf(sdump->trace, "%c", sdump->ind_char); \
334 : }
335 :
336 :
337 1466 : static void StartElement(GF_SceneDumper *sdump, const char *name)
338 : {
339 1466 : if (!sdump->trace) return;
340 10957 : DUMP_IND(sdump);
341 1466 : if (!sdump->XMLDump) {
342 26 : gf_fprintf(sdump->trace, "%s {\n", name);
343 : } else {
344 1440 : gf_fprintf(sdump->trace, "<%s", name);
345 : }
346 : }
347 :
348 1613 : static void EndElementHeader(GF_SceneDumper *sdump, Bool has_sub_el)
349 : {
350 2222 : if (!sdump->trace) return;
351 2222 : if (sdump->XMLDump) {
352 857 : if (has_sub_el) {
353 1041 : gf_fprintf(sdump->trace, ">\n");
354 : } else {
355 399 : gf_fprintf(sdump->trace, "/>\n");
356 : }
357 : }
358 : }
359 :
360 1766 : static void EndElement(GF_SceneDumper *sdump, const char *name, Bool had_sub_el)
361 : {
362 1766 : if (!sdump->trace) return;
363 1766 : if (!sdump->XMLDump) {
364 1536 : DUMP_IND(sdump);
365 356 : gf_fprintf(sdump->trace, "}\n");
366 : } else {
367 1410 : if (had_sub_el) {
368 7585 : DUMP_IND(sdump);
369 1041 : gf_fprintf(sdump->trace, "</%s>\n", name);
370 : }
371 : }
372 : }
373 :
374 2334 : static void StartAttribute(GF_SceneDumper *sdump, const char *name)
375 : {
376 2334 : if (!sdump->trace) return;
377 2334 : if (!sdump->XMLDump) {
378 7073 : DUMP_IND(sdump);
379 1161 : gf_fprintf(sdump->trace, "%s ", name);
380 : } else {
381 1173 : gf_fprintf(sdump->trace, " %s=\"", name);
382 : }
383 : }
384 :
385 2334 : static void EndAttribute(GF_SceneDumper *sdump)
386 : {
387 2334 : if (!sdump->trace) return;
388 2334 : if (!sdump->XMLDump) {
389 1161 : gf_fprintf(sdump->trace, "\n");
390 : } else {
391 1173 : gf_fprintf(sdump->trace, "\"");
392 : }
393 : }
394 :
395 :
396 189 : static void StartList(GF_SceneDumper *sdump, const char *name)
397 : {
398 189 : if (!sdump->trace) return;
399 902 : DUMP_IND(sdump);
400 189 : if (!sdump->XMLDump) {
401 92 : if (name)
402 92 : gf_fprintf(sdump->trace, "%s [\n", name);
403 : else
404 0 : gf_fprintf(sdump->trace, "[\n");
405 : } else {
406 97 : gf_fprintf(sdump->trace, "<%s>\n", name);
407 : }
408 : }
409 :
410 190 : static void EndList(GF_SceneDumper *sdump, const char *name)
411 : {
412 190 : if (!sdump->trace) return;
413 904 : DUMP_IND(sdump);
414 190 : if (!sdump->XMLDump) {
415 93 : gf_fprintf(sdump->trace, "]\n");
416 : } else {
417 97 : gf_fprintf(sdump->trace, "</%s>\n", name);
418 : }
419 : }
420 :
421 :
422 140 : static void scene_dump_utf_string(GF_SceneDumper *sdump, Bool escape_xml, char *str)
423 : {
424 : size_t _len;
425 : u32 len, i;
426 : u16 *uniLine;
427 140 : if (!str) return;
428 140 : len = (u32) strlen(str);
429 140 : if (!len) return;
430 140 : uniLine = (u16*)gf_malloc(sizeof(u16) * len*4);
431 140 : _len = gf_utf8_mbstowcs(uniLine, len, (const char **) &str);
432 140 : if (_len != (size_t) (-1)) {
433 140 : len = (u32) _len;
434 39299 : for (i=0; i<len; i++) {
435 : //if (uniLine[i] == (u16) '\"') gf_fprintf(sdump->trace, "\\");
436 39299 : switch (uniLine[i]) {
437 0 : case '\'':
438 0 : if (escape_xml) gf_fprintf(sdump->trace, "'");
439 0 : else gf_fprintf(sdump->trace, "'");
440 : break;
441 0 : case '\"':
442 0 : if (escape_xml) gf_fprintf(sdump->trace, """);
443 0 : else gf_fprintf(sdump->trace, "\"");
444 : break;
445 0 : case '&':
446 0 : gf_fprintf(sdump->trace, "&");
447 : break;
448 0 : case '>':
449 0 : gf_fprintf(sdump->trace, ">");
450 : break;
451 0 : case '<':
452 0 : gf_fprintf(sdump->trace, "<");
453 : break;
454 : case '\r':
455 : case '\n':
456 : /* Does nothing : gf_fprintf(sdump->trace, "");, fflush instead ?*/
457 : break;
458 39285 : default:
459 39285 : if (uniLine[i]<128) {
460 39285 : gf_fprintf(sdump->trace, "%c", (u8) uniLine[i]);
461 : } else {
462 0 : gf_fprintf(sdump->trace, "&#%d;", uniLine[i]);
463 : }
464 : break;
465 : }
466 : }
467 : }
468 140 : gf_free(uniLine);
469 : }
470 :
471 : #ifndef GPAC_DISABLE_VRML
472 :
473 857 : static void scene_dump_vrml_id(GF_SceneDumper *sdump, GF_Node *node)
474 : {
475 : u32 id;
476 : const char *node_name;
477 857 : if (!sdump->trace) return;
478 : /*FIXME - optimize id/name fetch*/
479 857 : node_name = gf_node_get_name_and_id(node, &id);
480 857 : if (node_name)
481 301 : gf_fprintf(sdump->trace, "%s", node_name);
482 : else
483 556 : gf_fprintf(sdump->trace, "N%d", id - 1);
484 : }
485 :
486 27 : static Bool scene_dump_vrml_find_route_name(GF_SceneDumper *sdump, u32 ID, const char **outName)
487 : {
488 : GF_Route *r;
489 : u32 i;
490 : GF_Command *com;
491 27 : r = gf_sg_route_find(sdump->sg, ID);
492 27 : if (r) {
493 0 : (*outName) = r->name;
494 0 : return 1;
495 : }
496 :
497 27 : i=0;
498 54 : while ((com = (GF_Command *)gf_list_enum(sdump->inserted_routes, &i))) {
499 27 : if (com->tag == GF_SG_ROUTE_INSERT) {
500 27 : if (com->RouteID==ID) {
501 27 : (*outName) = com->def_name;
502 27 : return 1;
503 : }
504 : }
505 : }
506 0 : if (!sdump->current_com_list) return 0;
507 0 : i=1;
508 0 : while ((com = (GF_Command *)gf_list_enum(sdump->current_com_list, &i))) {
509 0 : if ((com->tag == GF_SG_ROUTE_INSERT) || (com->tag == GF_SG_ROUTE_REPLACE)) {
510 0 : if (com->RouteID==ID) {
511 0 : (*outName) = com->def_name;
512 0 : return 1;
513 : }
514 : } else return 0;
515 : }
516 : return 0;
517 : }
518 :
519 27 : static void scene_dump_vrml_route_id(GF_SceneDumper *sdump, u32 routeID, char *rName)
520 : {
521 27 : if (!sdump->trace) return;
522 27 : if (!rName) scene_dump_vrml_find_route_name(sdump, routeID, (const char **) &rName);
523 :
524 27 : if (rName)
525 9 : gf_fprintf(sdump->trace, "%s", rName);
526 : else
527 18 : gf_fprintf(sdump->trace, "R%d", routeID - 1);
528 : }
529 :
530 :
531 5310 : static void gf_dump_vrml_sffield(GF_SceneDumper *sdump, u32 type, void *ptr, Bool is_mf, GF_Node *node)
532 : {
533 5310 : switch (type) {
534 280 : case GF_SG_VRML_SFBOOL:
535 280 : gf_fprintf(sdump->trace, "%s", * ((SFBool *)ptr) ? "true" : "false");
536 280 : break;
537 999 : case GF_SG_VRML_SFINT32:
538 999 : gf_fprintf(sdump->trace, "%d", * ((SFInt32 *)ptr) );
539 999 : break;
540 1774 : case GF_SG_VRML_SFFLOAT:
541 1774 : gf_fprintf(sdump->trace, "%g", FIX2FLT( * ((SFFloat *)ptr) ) );
542 1774 : break;
543 0 : case GF_SG_VRML_SFDOUBLE:
544 0 : gf_fprintf(sdump->trace, "%g", * ((SFDouble *)ptr) );
545 0 : break;
546 9 : case GF_SG_VRML_SFTIME:
547 9 : gf_fprintf(sdump->trace, "%g", * ((SFTime *)ptr) );
548 9 : break;
549 462 : case GF_SG_VRML_SFCOLOR:
550 462 : gf_fprintf(sdump->trace, "%g %g %g", FIX2FLT( ((SFColor *)ptr)->red ), FIX2FLT( ((SFColor *)ptr)->green ), FIX2FLT( ((SFColor *)ptr)->blue ));
551 462 : break;
552 0 : case GF_SG_VRML_SFCOLORRGBA:
553 0 : gf_fprintf(sdump->trace, "%g %g %g %g", FIX2FLT( ((SFColorRGBA *)ptr)->red ), FIX2FLT( ((SFColorRGBA *)ptr)->green ), FIX2FLT( ((SFColorRGBA *)ptr)->blue ), FIX2FLT( ((SFColorRGBA *)ptr)->alpha ));
554 0 : break;
555 1040 : case GF_SG_VRML_SFVEC2F:
556 1040 : gf_fprintf(sdump->trace, "%g %g", FIX2FLT( ((SFVec2f *)ptr)->x ), FIX2FLT( ((SFVec2f *)ptr)->y ));
557 1040 : break;
558 0 : case GF_SG_VRML_SFVEC2D:
559 0 : gf_fprintf(sdump->trace, "%g %g", ((SFVec2d *)ptr)->x, ((SFVec2d *)ptr)->y);
560 0 : break;
561 397 : case GF_SG_VRML_SFVEC3F:
562 397 : gf_fprintf(sdump->trace, "%g %g %g", FIX2FLT( ((SFVec3f *)ptr)->x ), FIX2FLT( ((SFVec3f *)ptr)->y ), FIX2FLT( ((SFVec3f *)ptr)->z ));
563 397 : break;
564 0 : case GF_SG_VRML_SFVEC3D:
565 0 : gf_fprintf(sdump->trace, "%g %g %g", ((SFVec3d *)ptr)->x, ((SFVec3d *)ptr)->y, ((SFVec3d *)ptr)->z);
566 0 : break;
567 19 : case GF_SG_VRML_SFROTATION:
568 19 : gf_fprintf(sdump->trace, "%g %g %g %g", FIX2FLT( ((SFRotation *)ptr)->x ), FIX2FLT( ((SFRotation *)ptr)->y ), FIX2FLT( ((SFRotation *)ptr)->z ), FIX2FLT( ((SFRotation *)ptr)->q ) );
569 19 : break;
570 :
571 0 : case GF_SG_VRML_SFATTRREF:
572 : {
573 : SFAttrRef *ar = (SFAttrRef *)ptr;
574 0 : if (ar->node) {
575 : GF_FieldInfo pinfo;
576 0 : gf_node_get_field(ar->node, ar->fieldIndex, &pinfo);
577 0 : scene_dump_vrml_id(sdump, ar->node);
578 0 : gf_fprintf(sdump->trace, ".%s", pinfo.name);
579 : }
580 : }
581 : break;
582 9 : case GF_SG_VRML_SFSCRIPT:
583 : {
584 : u32 len, i;
585 : char *str;
586 9 : str = (char*)((SFScript *)ptr)->script_text;
587 9 : len = (u32)strlen(str);
588 :
589 9 : if (!sdump->XMLDump) {
590 4 : gf_fprintf(sdump->trace, "\"%s\"", str);
591 : }
592 : else {
593 : size_t _len;
594 : u16 *uniLine;
595 :
596 5 : uniLine = (u16*)gf_malloc(sizeof(short) * (len + 1));
597 5 : _len = gf_utf8_mbstowcs(uniLine, len, (const char **)&str);
598 :
599 5 : if (_len != (size_t)-1) {
600 5 : len = (u32)_len;
601 :
602 5394 : for (i = 0; i<len; i++) {
603 :
604 5389 : switch (uniLine[i]) {
605 20 : case '&':
606 20 : gf_fprintf(sdump->trace, "&");
607 20 : break;
608 35 : case '<':
609 35 : gf_fprintf(sdump->trace, "<");
610 35 : break;
611 60 : case '>':
612 60 : gf_fprintf(sdump->trace, ">");
613 60 : break;
614 30 : case '\'':
615 : case '"':
616 30 : gf_fprintf(sdump->trace, "'");
617 30 : break;
618 : case 0:
619 : break;
620 : /*FIXME: how the heck can we preserve newlines and spaces of JavaScript in
621 : an XML attribute in any viewer ? */
622 5244 : default:
623 5244 : if (uniLine[i]<128) {
624 5244 : gf_fprintf(sdump->trace, "%c", (u8)uniLine[i]);
625 : }
626 : else {
627 0 : gf_fprintf(sdump->trace, "&#%d;", uniLine[i]);
628 : }
629 : break;
630 : }
631 : }
632 : }
633 5 : gf_free(uniLine);
634 : }
635 9 : DUMP_IND(sdump);
636 : }
637 9 : break;
638 :
639 251 : case GF_SG_VRML_SFSTRING:
640 : {
641 : char *str;
642 251 : if (sdump->XMLDump) {
643 117 : if (is_mf) gf_fprintf(sdump->trace, sdump->X3DDump ? "\"" : """);
644 : } else {
645 134 : gf_fprintf(sdump->trace, "\"");
646 : }
647 : /*dump in unicode*/
648 251 : str = ((SFString *)ptr)->buffer;
649 :
650 251 : if (node && (gf_node_get_tag(node)==TAG_MPEG4_BitWrapper)) {
651 9 : u32 bufsize = 50+ ((M_BitWrapper*)node)->buffer_len * 2;
652 9 : str = gf_malloc(sizeof(char)* bufsize);
653 9 : if (str) {
654 : s32 res;
655 : strcpy(str, "data:application/octet-string;base64,");
656 9 : res = gf_base64_encode(((M_BitWrapper*)node)->buffer.buffer, ((M_BitWrapper*)node)->buffer_len, str+37, bufsize-37);
657 9 : if (res<0) {
658 0 : gf_free(str);
659 : str = NULL;
660 : } else {
661 9 : str[res+37] = 0;
662 : }
663 : }
664 : }
665 251 : if (str && str[0]) {
666 239 : if (sdump->XMLDump) {
667 112 : scene_dump_utf_string(sdump, 1, str);
668 127 : } else if (!strchr(str, '\"')) {
669 127 : gf_fprintf(sdump->trace, "%s", str);
670 : } else {
671 0 : u32 i, len = (u32)strlen(str);
672 0 : for (i=0; i<len; i++) {
673 0 : if (str[i]=='\"') gf_fputc('\\', sdump->trace);
674 0 : gf_fputc(str[i], sdump->trace);
675 : }
676 : }
677 : }
678 251 : if (node && (gf_node_get_tag(node)==TAG_MPEG4_BitWrapper)) {
679 9 : if (str) gf_free(str);
680 : }
681 :
682 251 : if (sdump->XMLDump) {
683 117 : if (is_mf) gf_fprintf(sdump->trace, sdump->X3DDump ? "\"" : """);
684 : } else {
685 134 : gf_fprintf(sdump->trace, "\"");
686 : }
687 : }
688 : break;
689 :
690 61 : case GF_SG_VRML_SFURL:
691 61 : if (((SFURL *)ptr)->url) {
692 : #if 0
693 : u32 len;
694 : char *str;
695 : short uniLine[5000];
696 : str = ((SFURL *)ptr)->url;
697 : len = gf_utf8_mbstowcs(uniLine, 5000, (const char **) &str);
698 : if (len != (size_t) -1) {
699 : gf_fprintf(sdump->trace, sdump->XMLDump ? (sdump->X3DDump ? "'" : """) : "\"");
700 : fwprintf(sdump->trace, (unsigned short *) uniLine);
701 : gf_fprintf(sdump->trace, sdump->XMLDump ? (sdump->X3DDump ? "'" : """) : "\"");
702 : }
703 : #else
704 18 : gf_fprintf(sdump->trace, sdump->XMLDump ? (sdump->X3DDump ? "'" : """) : "\"");
705 18 : gf_fprintf(sdump->trace, "%s", ((SFURL *)ptr)->url);
706 18 : gf_fprintf(sdump->trace, sdump->XMLDump ? (sdump->X3DDump ? "'" : """) : "\"");
707 : #endif
708 : } else {
709 43 : if (sdump->XMLDump) {
710 22 : gf_fprintf(sdump->trace, ""od://od%d"", ((SFURL *)ptr)->OD_ID);
711 : } else {
712 21 : gf_fprintf(sdump->trace, "od:%d", ((SFURL *)ptr)->OD_ID);
713 : }
714 : }
715 : break;
716 9 : case GF_SG_VRML_SFIMAGE:
717 : {
718 : u32 i, count;
719 : SFImage *img = (SFImage *)ptr;
720 9 : gf_fprintf(sdump->trace, "%d %d %d", img->width, img->height, img->numComponents);
721 9 : count = img->width * img->height * img->numComponents;
722 162 : for (i=0; i<count; ) {
723 144 : switch (img->numComponents) {
724 144 : case 1:
725 144 : gf_fprintf(sdump->trace, " 0x%02X", img->pixels[i]);
726 144 : i++;
727 144 : break;
728 0 : case 2:
729 0 : gf_fprintf(sdump->trace, " 0x%02X%02X", img->pixels[i], img->pixels[i+1]);
730 0 : i+=2;
731 0 : break;
732 0 : case 3:
733 0 : gf_fprintf(sdump->trace, " 0x%02X%02X%02X", img->pixels[i], img->pixels[i+1], img->pixels[i+2]);
734 0 : i+=3;
735 0 : break;
736 0 : case 4:
737 0 : gf_fprintf(sdump->trace, " 0x%02X%02X%02X%02X", img->pixels[i], img->pixels[i+1], img->pixels[i+2], img->pixels[i+3]);
738 0 : i+=4;
739 0 : break;
740 : }
741 : }
742 : }
743 : break;
744 : }
745 5310 : }
746 :
747 :
748 245 : static void gf_dump_vrml_simple_field(GF_SceneDumper *sdump, GF_FieldInfo field, GF_Node *parent)
749 : {
750 : u32 i, sf_type;
751 : GF_ChildNodeItem *list;
752 : void *slot_ptr;
753 :
754 245 : switch (field.fieldType) {
755 0 : case GF_SG_VRML_SFNODE:
756 : assert ( *(GF_Node **)field.far_ptr);
757 0 : gf_dump_vrml_node(sdump, *(GF_Node **)field.far_ptr, 0, NULL);
758 0 : return;
759 0 : case GF_SG_VRML_MFNODE:
760 0 : list = * ((GF_ChildNodeItem **) field.far_ptr);
761 : assert( list );
762 0 : sdump->indent++;
763 0 : while (list) {
764 0 : gf_dump_vrml_node(sdump, list->node, 1, NULL);
765 0 : list = list->next;
766 : }
767 0 : sdump->indent--;
768 : return;
769 : case GF_SG_VRML_SFCOMMANDBUFFER:
770 : return;
771 : }
772 245 : if (gf_sg_vrml_is_sf_field(field.fieldType)) {
773 245 : if (sdump->XMLDump) StartAttribute(sdump, "value");
774 245 : gf_dump_vrml_sffield(sdump, field.fieldType, field.far_ptr, 0, parent);
775 245 : if (sdump->XMLDump) EndAttribute(sdump);
776 : } else {
777 : GenMFField *mffield;
778 : mffield = (GenMFField *) field.far_ptr;
779 0 : sf_type = gf_sg_vrml_get_sf_type(field.fieldType);
780 0 : if (!sdump->XMLDump) {
781 0 : gf_fprintf(sdump->trace, "[");
782 0 : } else if (sf_type==GF_SG_VRML_SFSTRING) {
783 0 : gf_fprintf(sdump->trace, " value=\'");
784 : } else {
785 0 : StartAttribute(sdump, "value");
786 : }
787 0 : for (i=0; i<mffield->count; i++) {
788 0 : if (i) gf_fprintf(sdump->trace, " ");
789 0 : gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i);
790 : /*this is to cope with single MFString which shall appear as SF in XMT*/
791 0 : gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, 1, parent);
792 : }
793 0 : if (!sdump->XMLDump) {
794 0 : gf_fprintf(sdump->trace, "]");
795 0 : } else if (sf_type==GF_SG_VRML_SFSTRING) {
796 0 : gf_fprintf(sdump->trace, "\'");
797 : } else {
798 0 : EndAttribute(sdump);
799 : }
800 : }
801 : }
802 :
803 2668 : static void gf_dump_vrml_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field)
804 : {
805 : u32 i, sf_type;
806 : Bool needs_field_container;
807 : GF_ChildNodeItem *list;
808 : void *slot_ptr;
809 :
810 2668 : switch (field.fieldType) {
811 854 : case GF_SG_VRML_SFNODE:
812 : assert ( *(GF_Node **)field.far_ptr);
813 :
814 854 : if (sdump->XMLDump) {
815 444 : if (!sdump->X3DDump) {
816 444 : StartElement(sdump, (char *) field.name);
817 444 : EndElementHeader(sdump, 1);
818 444 : sdump->indent++;
819 : }
820 : } else {
821 410 : StartAttribute(sdump, field.name);
822 : }
823 854 : gf_dump_vrml_node(sdump, *(GF_Node **)field.far_ptr, 0, NULL);
824 :
825 854 : if (sdump->XMLDump) {
826 444 : if (!sdump->X3DDump) {
827 444 : sdump->indent--;
828 444 : EndElement(sdump, (char *) field.name, 1);
829 : }
830 : } else {
831 410 : EndAttribute(sdump);
832 : }
833 1100 : return;
834 189 : case GF_SG_VRML_MFNODE:
835 : needs_field_container = 0;
836 189 : if (sdump->XMLDump && sdump->X3DDump) {
837 : u32 count, nb_ndt;
838 : GF_FieldInfo info;
839 0 : if (!strcmp(field.name, "children")) {
840 : needs_field_container = 0;
841 : } else {
842 : nb_ndt = 0;
843 0 : count = gf_node_get_field_count(node);
844 0 : for (i=0; i<count; i++) {
845 0 : gf_node_get_field(node, i, &info);
846 0 : if ((info.eventType==GF_SG_EVENT_IN) || (info.eventType==GF_SG_EVENT_OUT)) continue;
847 0 : if (info.NDTtype==field.NDTtype) nb_ndt++;
848 : }
849 0 : needs_field_container = (nb_ndt>1) ? 1 : 0;
850 : }
851 : }
852 :
853 : #ifndef GPAC_DISABLE_X3D
854 189 : if (!sdump->X3DDump) {
855 189 : if (gf_node_get_tag(node)==TAG_X3D_Switch) field.name = "choice";
856 : }
857 : #endif
858 189 : list = * ((GF_ChildNodeItem **) field.far_ptr);
859 : assert(list);
860 189 : if (!sdump->XMLDump || !sdump->X3DDump) StartList(sdump, field.name);
861 189 : sdump->indent++;
862 1092 : while (list) {
863 903 : gf_dump_vrml_node(sdump, list->node, 1, needs_field_container ? (char *) field.name : NULL);
864 903 : list = list->next;
865 : }
866 189 : sdump->indent--;
867 189 : if (!sdump->XMLDump || !sdump->X3DDump) EndList(sdump, field.name);
868 : return;
869 57 : case GF_SG_VRML_SFCOMMANDBUFFER:
870 : {
871 : SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr;
872 57 : StartElement(sdump, (char *) field.name);
873 57 : EndElementHeader(sdump, 1);
874 57 : sdump->indent++;
875 57 : if (!gf_list_count(cb->commandList)) {
876 : /*the arch does not allow for that (we would need a codec and so on, or decompress the command list
877 : in all cases...)*/
878 0 : if (sdump->trace && cb->bufferSize) {
879 0 : if (sdump->XMLDump) gf_fprintf(sdump->trace, "<!--SFCommandBuffer cannot be dumped while playing - use MP4Box instead-->\n");
880 0 : else gf_fprintf(sdump->trace, "#SFCommandBuffer cannot be dumped while playing - use MP4Box instead\n");
881 : }
882 : } else {
883 57 : gf_sm_dump_command_list(sdump, cb->commandList, sdump->indent, 0);
884 : }
885 57 : sdump->indent--;
886 57 : EndElement(sdump, (char *) field.name, 1);
887 : }
888 : return;
889 :
890 0 : case GF_SG_VRML_MFATTRREF:
891 0 : if (sdump->XMLDump) {
892 : MFAttrRef *ar = (MFAttrRef *)field.far_ptr;
893 0 : StartElement(sdump, (char *) field.name);
894 0 : EndElementHeader(sdump, 1);
895 0 : sdump->indent++;
896 :
897 0 : for (i=0; i<ar->count; i++) {
898 0 : if (ar->vals[i].node) {
899 : GF_FieldInfo pinfo;
900 0 : DUMP_IND(sdump);
901 0 : gf_node_get_field(ar->vals[i].node, ar->vals[i].fieldIndex, &pinfo);
902 0 : gf_fprintf(sdump->trace, "<store node=\"");
903 0 : scene_dump_vrml_id(sdump, ar->vals[i].node);
904 0 : gf_fprintf(sdump->trace, "\" field=\"%s\"/>\n", pinfo.name);
905 : }
906 : }
907 :
908 0 : sdump->indent--;
909 0 : EndElement(sdump, (char *) field.name, 1);
910 : return;
911 : }
912 : break;
913 : }
914 :
915 :
916 1568 : if (gf_sg_vrml_is_sf_field(field.fieldType)) {
917 1114 : StartAttribute(sdump, field.name);
918 1114 : gf_dump_vrml_sffield(sdump, field.fieldType, field.far_ptr, 0, node);
919 1114 : EndAttribute(sdump);
920 : } else {
921 : GenMFField *mffield = (GenMFField *) field.far_ptr;
922 454 : sf_type = gf_sg_vrml_get_sf_type(field.fieldType);
923 :
924 454 : if (sdump->XMLDump && sdump->X3DDump) {
925 : switch (sf_type) {
926 0 : case GF_SG_VRML_SFSTRING:
927 : case GF_SG_VRML_SFSCRIPT:
928 : case GF_SG_VRML_SFURL:
929 0 : gf_fprintf(sdump->trace, " %s=\'", (char *) field.name);
930 : break;
931 0 : default:
932 0 : StartAttribute(sdump, field.name);
933 : break;
934 : }
935 : } else {
936 454 : StartAttribute(sdump, field.name);
937 : }
938 :
939 454 : if (!sdump->XMLDump) gf_fprintf(sdump->trace, "[");
940 3747 : for (i=0; i<mffield->count; i++) {
941 3747 : if (i) gf_fprintf(sdump->trace, " ");
942 3747 : gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i);
943 3747 : gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, 1, node);
944 : }
945 454 : if (!sdump->XMLDump) gf_fprintf(sdump->trace, "]");
946 :
947 454 : if (sdump->XMLDump && sdump->X3DDump) {
948 : switch (sf_type) {
949 0 : case GF_SG_VRML_SFSTRING:
950 : case GF_SG_VRML_SFSCRIPT:
951 : case GF_SG_VRML_SFURL:
952 0 : gf_fprintf(sdump->trace, "\'");
953 : break;
954 0 : default:
955 0 : EndAttribute(sdump);
956 : break;
957 : }
958 : } else {
959 454 : EndAttribute(sdump);
960 : }
961 : }
962 : }
963 :
964 110 : static const char *GetXMTFieldTypeName(u32 fieldType)
965 : {
966 110 : switch (fieldType) {
967 : case GF_SG_VRML_SFBOOL:
968 : return "Boolean";
969 0 : case GF_SG_VRML_SFINT32:
970 0 : return "Integer";
971 20 : case GF_SG_VRML_SFCOLOR:
972 20 : return "Color";
973 20 : case GF_SG_VRML_SFVEC2F:
974 20 : return "Vector2";
975 0 : case GF_SG_VRML_SFIMAGE:
976 0 : return "Image";
977 5 : case GF_SG_VRML_SFTIME:
978 5 : return "Time";
979 30 : case GF_SG_VRML_SFFLOAT:
980 30 : return "Float";
981 0 : case GF_SG_VRML_SFVEC3F:
982 0 : return "Vector3";
983 0 : case GF_SG_VRML_SFROTATION:
984 0 : return "Rotation";
985 0 : case GF_SG_VRML_SFSTRING:
986 0 : return "String";
987 15 : case GF_SG_VRML_SFNODE:
988 15 : return "Node";
989 0 : case GF_SG_VRML_MFBOOL:
990 0 : return "Booleans";
991 0 : case GF_SG_VRML_MFINT32:
992 0 : return "Integers";
993 0 : case GF_SG_VRML_MFCOLOR:
994 0 : return "Colors";
995 0 : case GF_SG_VRML_MFVEC2F:
996 0 : return "Vector2Array";
997 0 : case GF_SG_VRML_MFIMAGE:
998 0 : return "Images";
999 0 : case GF_SG_VRML_MFTIME:
1000 0 : return "Times";
1001 0 : case GF_SG_VRML_MFFLOAT:
1002 0 : return "Floats";
1003 0 : case GF_SG_VRML_MFVEC3F:
1004 0 : return "Vector3Array";
1005 0 : case GF_SG_VRML_MFROTATION:
1006 0 : return "Rotations";
1007 0 : case GF_SG_VRML_MFSTRING:
1008 0 : return "Strings";
1009 0 : case GF_SG_VRML_MFNODE:
1010 0 : return "Nodes";
1011 0 : default:
1012 0 : return "unknown";
1013 : }
1014 : }
1015 195 : static const char *GetXMTFieldTypeValueName(u32 fieldType)
1016 : {
1017 195 : switch (fieldType) {
1018 : case GF_SG_VRML_SFBOOL:
1019 : return "booleanValue";
1020 0 : case GF_SG_VRML_SFINT32:
1021 0 : return "intValue";
1022 50 : case GF_SG_VRML_SFCOLOR:
1023 50 : return "colorValue";
1024 45 : case GF_SG_VRML_SFVEC2F:
1025 45 : return "vector2Value";
1026 0 : case GF_SG_VRML_SFIMAGE:
1027 0 : return "imageValue";
1028 0 : case GF_SG_VRML_SFTIME:
1029 0 : return "timeValue";
1030 75 : case GF_SG_VRML_SFFLOAT:
1031 75 : return "floatValue";
1032 0 : case GF_SG_VRML_SFVEC3F:
1033 0 : return "vector3Value";
1034 0 : case GF_SG_VRML_SFROTATION:
1035 0 : return "rotationValue";
1036 0 : case GF_SG_VRML_SFSTRING:
1037 0 : return "stringValue";
1038 0 : case GF_SG_VRML_MFBOOL:
1039 0 : return "booleanArrayValue";
1040 0 : case GF_SG_VRML_MFINT32:
1041 0 : return "intArrayValue";
1042 0 : case GF_SG_VRML_MFCOLOR:
1043 0 : return "colorArrayValue";
1044 0 : case GF_SG_VRML_MFVEC2F:
1045 0 : return "vector2ArrayValue";
1046 0 : case GF_SG_VRML_MFIMAGE:
1047 0 : return "imageArrayValue";
1048 0 : case GF_SG_VRML_MFTIME:
1049 0 : return "timeArrayValue";
1050 0 : case GF_SG_VRML_MFFLOAT:
1051 0 : return "floatArrayValue";
1052 0 : case GF_SG_VRML_MFVEC3F:
1053 0 : return "vector3ArrayValue";
1054 0 : case GF_SG_VRML_MFROTATION:
1055 0 : return "rotationArrayValue";
1056 0 : case GF_SG_VRML_MFSTRING:
1057 0 : return "stringArrayValue";
1058 0 : default:
1059 0 : return "unknown";
1060 : }
1061 : }
1062 :
1063 : /*field dumping for proto declaration and Script*/
1064 198 : static void gf_dump_vrml_dyn_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool has_sublist)
1065 : {
1066 : u32 i, sf_type;
1067 : void *slot_ptr;
1068 :
1069 198 : if (gf_sg_vrml_is_sf_field(field.fieldType)) {
1070 198 : DUMP_IND(sdump);
1071 198 : if (sdump->XMLDump) {
1072 110 : if (sdump->X3DDump) {
1073 0 : gf_fprintf(sdump->trace, "<field name=\"%s\" type=\"%s\" accessType=\"%s\"",
1074 : field.name, gf_sg_vrml_get_field_type_name(field.fieldType), gf_sg_vrml_get_event_type_name(field.eventType, 1));
1075 : } else {
1076 110 : gf_fprintf(sdump->trace, "<field name=\"%s\" type=\"%s\" vrml97Hint=\"%s\"",
1077 : field.name, GetXMTFieldTypeName(field.fieldType), gf_sg_vrml_get_event_type_name(field.eventType, 0));
1078 : }
1079 :
1080 110 : if ((field.eventType == GF_SG_EVENT_FIELD) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD)) {
1081 95 : if (field.fieldType == GF_SG_VRML_SFNODE) {
1082 15 : if (!sdump->X3DDump) {
1083 15 : gf_fprintf(sdump->trace, ">\n");
1084 15 : sdump->indent++;
1085 15 : gf_fprintf(sdump->trace, "<node>");
1086 15 : gf_dump_vrml_node(sdump, field.far_ptr ? *(GF_Node **)field.far_ptr : NULL, 0, NULL);
1087 15 : gf_fprintf(sdump->trace, "</node>");
1088 15 : sdump->indent--;
1089 15 : if (!has_sublist)
1090 15 : gf_fprintf(sdump->trace, "</field>\n");
1091 : } else {
1092 0 : if (field.far_ptr) {
1093 0 : gf_fprintf(sdump->trace, ">\n");
1094 0 : gf_dump_vrml_node(sdump, *(GF_Node **)field.far_ptr, 0, NULL);
1095 0 : gf_fprintf(sdump->trace, "</field>\n");
1096 : } else {
1097 0 : gf_fprintf(sdump->trace, "/>\n");
1098 : }
1099 : }
1100 15 : DUMP_IND(sdump);
1101 : } else {
1102 80 : if (sdump->X3DDump) {
1103 0 : gf_fprintf(sdump->trace, " value=\"");
1104 : } else {
1105 80 : gf_fprintf(sdump->trace, " %s=\"", GetXMTFieldTypeValueName(field.fieldType));
1106 : }
1107 80 : gf_dump_vrml_sffield(sdump, field.fieldType, field.far_ptr, 0, node);
1108 80 : if (has_sublist)
1109 0 : gf_fprintf(sdump->trace, "\">\n");
1110 : else
1111 80 : gf_fprintf(sdump->trace, "\"/>\n");
1112 : }
1113 : } else {
1114 15 : gf_fprintf(sdump->trace, "/>\n");
1115 : }
1116 : } else {
1117 88 : gf_fprintf(sdump->trace, "%s %s %s", gf_sg_vrml_get_event_type_name(field.eventType, sdump->X3DDump), gf_sg_vrml_get_field_type_name(field.fieldType), field.name);
1118 88 : if ((field.eventType==GF_SG_EVENT_FIELD) || (field.eventType==GF_SG_EVENT_EXPOSED_FIELD)) {
1119 76 : gf_fprintf(sdump->trace, " ");
1120 76 : if (field.fieldType == GF_SG_VRML_SFNODE) {
1121 12 : gf_dump_vrml_node(sdump, field.far_ptr ? *(GF_Node **)field.far_ptr : NULL, 0, NULL);
1122 : } else {
1123 64 : gf_dump_vrml_simple_field(sdump, field, node);
1124 : }
1125 : }
1126 88 : gf_fprintf(sdump->trace, "\n");
1127 : }
1128 : } else {
1129 : GenMFField *mffield = (GenMFField *) field.far_ptr;
1130 0 : sf_type = gf_sg_vrml_get_sf_type(field.fieldType);
1131 :
1132 0 : DUMP_IND(sdump);
1133 0 : if (!sdump->XMLDump) {
1134 0 : gf_fprintf(sdump->trace, "%s %s %s", gf_sg_vrml_get_event_type_name(field.eventType, sdump->X3DDump), gf_sg_vrml_get_field_type_name(field.fieldType), field.name);
1135 0 : if ((field.eventType==GF_SG_EVENT_FIELD) || (field.eventType==GF_SG_EVENT_EXPOSED_FIELD)) {
1136 0 : gf_fprintf(sdump->trace, " [");
1137 :
1138 0 : if (sf_type == GF_SG_VRML_SFNODE) {
1139 0 : GF_ChildNodeItem *l = *(GF_ChildNodeItem **)field.far_ptr;
1140 0 : gf_fprintf(sdump->trace, "\n");
1141 0 : sdump->indent++;
1142 0 : while (l) {
1143 0 : gf_dump_vrml_node(sdump, l->node, 1, NULL);
1144 0 : l = l->next;
1145 : }
1146 0 : sdump->indent--;
1147 0 : DUMP_IND(sdump);
1148 : } else {
1149 0 : for (i=0; i<mffield->count; i++) {
1150 0 : if (i) gf_fprintf(sdump->trace, " ");
1151 0 : if (field.fieldType != GF_SG_VRML_MFNODE) {
1152 0 : gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i);
1153 0 : gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, (mffield->count>1) ? 1 : 0, node);
1154 : }
1155 : }
1156 : }
1157 0 : gf_fprintf(sdump->trace, "]");
1158 : }
1159 0 : gf_fprintf(sdump->trace, "\n");
1160 : } else {
1161 0 : if (sdump->X3DDump) {
1162 0 : gf_fprintf(sdump->trace, "<field name=\"%s\" type=\"%s\" accessType=\"%s\"",
1163 : field.name, gf_sg_vrml_get_field_type_name(field.fieldType), gf_sg_vrml_get_event_type_name(field.eventType, 1));
1164 : } else {
1165 0 : gf_fprintf(sdump->trace, "<field name=\"%s\" type=\"%s\" vrml97Hint=\"%s\"",
1166 : field.name, GetXMTFieldTypeName(field.fieldType), gf_sg_vrml_get_event_type_name(field.eventType, 0));
1167 : }
1168 :
1169 0 : if ((field.eventType==GF_SG_EVENT_FIELD) || (field.eventType==GF_SG_EVENT_EXPOSED_FIELD)) {
1170 0 : if (sf_type == GF_SG_VRML_SFNODE) {
1171 0 : GF_ChildNodeItem *list = *(GF_ChildNodeItem **)field.far_ptr;
1172 0 : gf_fprintf(sdump->trace, ">\n");
1173 0 : sdump->indent++;
1174 0 : if (!sdump->X3DDump) gf_fprintf(sdump->trace, "<nodes>");
1175 0 : while (list) {
1176 0 : gf_dump_vrml_node(sdump, list->node, 1, NULL);
1177 0 : list = list->next;
1178 : }
1179 0 : if (!sdump->X3DDump) gf_fprintf(sdump->trace, "</nodes>");
1180 0 : sdump->indent++;
1181 0 : DUMP_IND(sdump);
1182 0 : if (!has_sublist)
1183 0 : gf_fprintf(sdump->trace, "</field>\n");
1184 : } else {
1185 0 : if (sdump->X3DDump) {
1186 0 : gf_fprintf(sdump->trace, " value=\"");
1187 : } else {
1188 0 : gf_fprintf(sdump->trace, " %s=\"", GetXMTFieldTypeValueName(field.fieldType));
1189 : }
1190 0 : for (i=0; i<mffield->count; i++) {
1191 0 : if (i) gf_fprintf(sdump->trace, " ");
1192 0 : if (field.fieldType != GF_SG_VRML_MFNODE) {
1193 0 : gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i);
1194 0 : gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, (mffield->count>1) ? 1 : 0, node);
1195 : }
1196 : }
1197 0 : if (has_sublist)
1198 0 : gf_fprintf(sdump->trace, "\">\n");
1199 : else
1200 0 : gf_fprintf(sdump->trace, "\"/>\n");
1201 : }
1202 : } else {
1203 0 : gf_fprintf(sdump->trace, "/>\n");
1204 : }
1205 : }
1206 : }
1207 198 : }
1208 :
1209 :
1210 : /*field dumping for proto instance*/
1211 130 : static void gf_dump_vrml_proto_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field)
1212 : {
1213 : u32 i, sf_type;
1214 : void *slot_ptr;
1215 :
1216 130 : DUMP_IND(sdump);
1217 130 : gf_fprintf(sdump->trace, "<fieldValue name=\"%s\" ", field.name);
1218 130 : if (gf_sg_vrml_is_sf_field(field.fieldType)) {
1219 130 : if (field.fieldType == GF_SG_VRML_SFNODE) {
1220 15 : gf_fprintf(sdump->trace, ">\n");
1221 15 : sdump->indent++;
1222 15 : if (!sdump->X3DDump) gf_fprintf(sdump->trace, "<node>");
1223 15 : gf_dump_vrml_node(sdump, field.far_ptr ? *(GF_Node **)field.far_ptr : NULL, 0, NULL);
1224 15 : if (!sdump->X3DDump) gf_fprintf(sdump->trace, "</node>");
1225 15 : sdump->indent--;
1226 15 : DUMP_IND(sdump);
1227 15 : gf_fprintf(sdump->trace, "</fieldValue>\n");
1228 : } else {
1229 115 : if (sdump->X3DDump) {
1230 0 : gf_fprintf(sdump->trace, " value=\"");
1231 : } else {
1232 115 : gf_fprintf(sdump->trace, " %s=\"", GetXMTFieldTypeValueName(field.fieldType));
1233 : }
1234 115 : gf_dump_vrml_sffield(sdump, field.fieldType, field.far_ptr, 0, node);
1235 115 : gf_fprintf(sdump->trace, "\"/>\n");
1236 : }
1237 : } else {
1238 : GenMFField *mffield = (GenMFField *) field.far_ptr;
1239 0 : sf_type = gf_sg_vrml_get_sf_type(field.fieldType);
1240 :
1241 0 : if ((field.eventType==GF_SG_EVENT_FIELD) || (field.eventType==GF_SG_EVENT_EXPOSED_FIELD)) {
1242 0 : if (sf_type == GF_SG_VRML_SFNODE) {
1243 0 : GF_ChildNodeItem *list = *(GF_ChildNodeItem **)field.far_ptr;
1244 0 : gf_fprintf(sdump->trace, ">\n");
1245 0 : sdump->indent++;
1246 0 : if (!sdump->X3DDump) gf_fprintf(sdump->trace, "<nodes>");
1247 0 : while (list) {
1248 0 : gf_dump_vrml_node(sdump, list->node, 1, NULL);
1249 0 : list = list->next;
1250 : }
1251 0 : if (!sdump->X3DDump) gf_fprintf(sdump->trace, "</nodes>");
1252 0 : sdump->indent--;
1253 0 : DUMP_IND(sdump);
1254 0 : gf_fprintf(sdump->trace, "</fieldValue>\n");
1255 : } else {
1256 0 : if (sdump->X3DDump) {
1257 0 : gf_fprintf(sdump->trace, " value=\"");
1258 : } else {
1259 0 : gf_fprintf(sdump->trace, " %s=\"", GetXMTFieldTypeValueName(field.fieldType));
1260 : }
1261 0 : for (i=0; i<mffield->count; i++) {
1262 0 : if (i) gf_fprintf(sdump->trace, " ");
1263 0 : if (field.fieldType != GF_SG_VRML_MFNODE) {
1264 0 : gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i);
1265 0 : gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, (mffield->count>1) ? 1 : 0, node);
1266 : }
1267 : }
1268 0 : gf_fprintf(sdump->trace, "\"/>\n");
1269 : }
1270 : }
1271 : }
1272 130 : }
1273 :
1274 513 : static GF_Route *gf_dump_vrml_get_IS(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo *field)
1275 : {
1276 : u32 i;
1277 : GF_Route *r;
1278 513 : i=0;
1279 5499 : while ((r = (GF_Route*)gf_list_enum(sdump->current_proto->sub_graph->Routes, &i))) {
1280 5184 : if (!r->IS_route) continue;
1281 5184 : if ((r->ToNode==node) && (r->ToField.fieldIndex==field->fieldIndex)) return r;
1282 : }
1283 315 : if (!node || !node->sgprivate->interact || !node->sgprivate->interact->routes) return NULL;
1284 144 : i=0;
1285 369 : while ((r = (GF_Route*)gf_list_enum(node->sgprivate->interact->routes, &i))) {
1286 225 : if (!r->IS_route) continue;
1287 225 : if (r->FromField.fieldIndex == field->fieldIndex) return r;
1288 : }
1289 : return NULL;
1290 : }
1291 :
1292 99 : static void gf_dump_vrml_IS_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool isScript, Bool skip_is)
1293 : {
1294 : GF_FieldInfo pfield;
1295 :
1296 99 : GF_Route *r = gf_dump_vrml_get_IS(sdump, node, &field);
1297 99 : if (r->FromNode) {
1298 0 : pfield.fieldIndex = r->ToField.fieldIndex;
1299 0 : gf_sg_proto_get_field(sdump->current_proto, NULL, &pfield);
1300 : } else {
1301 99 : pfield.fieldIndex = r->FromField.fieldIndex;
1302 99 : gf_sg_proto_get_field(sdump->current_proto, NULL, &pfield);
1303 : }
1304 :
1305 99 : if (!sdump->XMLDump) {
1306 44 : DUMP_IND(sdump);
1307 44 : if (isScript) gf_fprintf(sdump->trace, "%s %s ", gf_sg_vrml_get_event_type_name(field.eventType, sdump->X3DDump), gf_sg_vrml_get_field_type_name(field.fieldType));
1308 44 : gf_fprintf(sdump->trace, "%s IS %s\n", field.name, pfield.name);
1309 : } else {
1310 55 : if (!skip_is) {
1311 5 : StartElement(sdump, "IS");
1312 5 : EndElementHeader(sdump, 1);
1313 5 : sdump->indent++;
1314 : }
1315 55 : DUMP_IND(sdump);
1316 55 : gf_fprintf(sdump->trace, "<connect nodeField=\"%s\" protoField=\"%s\"/>\n", field.name, pfield.name);
1317 55 : if (!skip_is) {
1318 5 : sdump->indent--;
1319 5 : EndElement(sdump, "IS", 1);
1320 : }
1321 : }
1322 99 : }
1323 :
1324 1928 : static Bool scene_dump_vrml_can_dump(GF_SceneDumper *sdump, GF_Node *node)
1325 : {
1326 : #ifndef GPAC_DISABLE_VRML
1327 : u32 tag;
1328 :
1329 1928 : if (node->sgprivate->tag==TAG_ProtoNode) return 1;
1330 :
1331 1892 : if (sdump->X3DDump || (sdump->dump_mode==GF_SM_DUMP_VRML)) {
1332 0 : if (node->sgprivate->tag>=GF_NODE_RANGE_FIRST_X3D) return 1;
1333 0 : if (node->sgprivate->tag==TAG_MPEG4_Rectangle) return 1;
1334 0 : if (node->sgprivate->tag==TAG_MPEG4_Circle) return 1;
1335 : #ifndef GPAC_DISABLE_X3D
1336 0 : tag = gf_node_x3d_type_by_class_name(gf_node_get_class_name(node));
1337 0 : return tag ? 1 : 0;
1338 : #else
1339 : return 0;
1340 : #endif
1341 : } else {
1342 1892 : if (node->sgprivate->tag<=GF_NODE_RANGE_LAST_MPEG4) return 1;
1343 : #ifndef GPAC_DISABLE_X3D
1344 0 : if (node->sgprivate->tag==TAG_X3D_Rectangle2D) return 1;
1345 0 : if (node->sgprivate->tag==TAG_X3D_Circle2D) return 1;
1346 : #endif
1347 0 : tag = gf_node_mpeg4_type_by_class_name(gf_node_get_class_name(node));
1348 0 : return tag ? 1 : 0;
1349 : }
1350 : #else
1351 : return 1;
1352 : #endif
1353 : }
1354 :
1355 1998 : static void gf_dump_vrml_node(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldContainer)
1356 : {
1357 : u32 i, count, to_dump, sub_el, ID;
1358 : u32 *def_fields;
1359 : Bool isDEF, isScript, isProto, hasISed;
1360 : char *name;
1361 : GF_Node *base;
1362 : GF_FieldInfo field, base_field;
1363 :
1364 1998 : if (!node) {
1365 70 : gf_fprintf(sdump->trace, "NULL");
1366 70 : return;
1367 : }
1368 :
1369 : /*this dumper works only for VRML like graphs*/
1370 1928 : if (node->sgprivate->tag>GF_NODE_RANGE_LAST_X3D) return;
1371 :
1372 1928 : if (!scene_dump_vrml_can_dump(sdump, node)) {
1373 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[Scene Dump] node %s not part of %s standard - removing\n", gf_node_get_class_name(node), sdump->X3DDump ? "X3D" : (sdump->dump_mode==GF_SM_DUMP_VRML) ? "VRML" : "MPEG4"));
1374 0 : if (!in_list) gf_fprintf(sdump->trace, "NULL");
1375 : return;
1376 : }
1377 :
1378 : /*convert whatever possible*/
1379 1928 : name = (char*)gf_node_get_class_name(node);
1380 : #ifndef GPAC_DISABLE_VRML
1381 1928 : if (sdump->X3DDump) {
1382 0 : if (node->sgprivate->tag == TAG_MPEG4_Circle) name = "Circle2D";
1383 0 : else if (node->sgprivate->tag == TAG_MPEG4_Rectangle) name = "Rectangle2D";
1384 : #ifndef GPAC_DISABLE_X3D
1385 : } else {
1386 1928 : if (node->sgprivate->tag == TAG_X3D_Circle2D) name = "Circle";
1387 1928 : else if (node->sgprivate->tag == TAG_X3D_Rectangle2D) name = "Rectangle";
1388 : #endif
1389 : }
1390 : #endif
1391 :
1392 :
1393 :
1394 1928 : isProto = (gf_node_get_tag(node) == TAG_ProtoNode) ? 1 : 0;
1395 1928 : ID = gf_node_get_id(node);
1396 : isDEF = 0;
1397 1928 : if (ID) {
1398 535 : isDEF = gf_dump_vrml_is_def_node(sdump, node);
1399 535 : if (!isDEF) {
1400 63 : if (!sdump->XMLDump) {
1401 33 : if (in_list) DUMP_IND(sdump);
1402 33 : gf_fprintf(sdump->trace, "USE ");
1403 33 : scene_dump_vrml_id(sdump, node);
1404 33 : if (in_list) gf_fprintf(sdump->trace, "\n");
1405 : } else {
1406 30 : if (isProto) {
1407 0 : StartElement(sdump, "ProtoInstance");
1408 0 : StartAttribute(sdump, "name");
1409 0 : gf_fprintf(sdump->trace, "%s", name);
1410 0 : EndAttribute(sdump);
1411 : } else {
1412 30 : StartElement(sdump, name);
1413 : }
1414 30 : StartAttribute(sdump, "USE");
1415 30 : scene_dump_vrml_id(sdump, node);
1416 30 : EndAttribute(sdump);
1417 30 : EndElementHeader(sdump, 0);
1418 : }
1419 : return;
1420 : }
1421 : }
1422 :
1423 : /*get all fields*/
1424 1865 : count = gf_node_get_field_count(node);
1425 1865 : def_fields = (u32*)gf_malloc(sizeof(u32) * count);
1426 :
1427 : base = NULL;
1428 1865 : switch (gf_node_get_tag(node)) {
1429 : #ifndef GPAC_DISABLE_VRML
1430 : #ifndef GPAC_DISABLE_X3D
1431 : case TAG_X3D_Script:
1432 : #endif
1433 : case TAG_MPEG4_Script:
1434 : isScript = 1;
1435 : break;
1436 : #endif
1437 : default:
1438 : isScript = 0;
1439 : break;
1440 : }
1441 :
1442 :
1443 : if (!isScript) {
1444 1856 : if (isProto) {
1445 36 : base = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);
1446 : } else {
1447 1820 : base = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag);
1448 : }
1449 : }
1450 :
1451 1865 : if (base) gf_node_register(base, NULL);
1452 :
1453 : hasISed = 0;
1454 : to_dump = sub_el = 0;
1455 13195 : for (i=0; i<count; i++) {
1456 13195 : if (isScript) {
1457 : /*dyn script fields are complex types*/
1458 45 : def_fields[i] = (i>2) ? 2 : 1;
1459 : } else {
1460 13150 : def_fields[i] = 0;
1461 : }
1462 :
1463 13195 : gf_node_get_field(node, i, &field);
1464 :
1465 13195 : if (sdump->current_proto) {
1466 414 : if (gf_dump_vrml_get_IS(sdump, node, &field) != NULL) {
1467 99 : def_fields[i] = 3;
1468 99 : if ((field.fieldType == GF_SG_VRML_SFNODE) || (field.fieldType == GF_SG_VRML_MFNODE))
1469 9 : def_fields[i] = sdump->XMLDump ? 4 : 3;
1470 : /*in XMT the ISed is not an attribute*/
1471 99 : if (sdump->XMLDump) sub_el++;
1472 99 : to_dump++;
1473 : hasISed = 1;
1474 99 : continue;
1475 : }
1476 : }
1477 :
1478 13096 : if (!isScript && ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) ) {
1479 4064 : continue;
1480 : }
1481 : /*proto instance in XMT lists all fields as elements*/
1482 9032 : if (sdump->XMLDump && isProto) {
1483 130 : def_fields[i] = 2;
1484 130 : to_dump++;
1485 130 : sub_el++;
1486 130 : continue;
1487 : }
1488 8902 : switch (field.fieldType) {
1489 1675 : case GF_SG_VRML_SFNODE:
1490 1675 : if (* (GF_Node **) field.far_ptr) {
1491 854 : def_fields[i] = 2;
1492 854 : to_dump++;
1493 854 : sub_el++;
1494 : }
1495 : break;
1496 318 : case GF_SG_VRML_MFNODE:
1497 318 : if (* (GF_ChildNodeItem**) field.far_ptr) {
1498 186 : def_fields[i] = 2;
1499 186 : to_dump++;
1500 186 : sub_el++;
1501 : }
1502 : break;
1503 72 : case GF_SG_VRML_SFCOMMANDBUFFER:
1504 : {
1505 72 : SFCommandBuffer *p = (SFCommandBuffer *)field.far_ptr;
1506 72 : if (p->bufferSize || gf_list_count(p->commandList)) {
1507 57 : def_fields[i] = 2;
1508 57 : to_dump++;
1509 57 : sub_el++;
1510 : }
1511 : }
1512 : break;
1513 0 : case GF_SG_VRML_MFATTRREF:
1514 : {
1515 0 : MFAttrRef *p = (MFAttrRef*)field.far_ptr;
1516 0 : if (p->count) {
1517 0 : def_fields[i] = 2;
1518 0 : to_dump++;
1519 0 : sub_el++;
1520 : }
1521 : }
1522 : break;
1523 6837 : default:
1524 6837 : if (isScript) {
1525 36 : to_dump++;
1526 : } else {
1527 6801 : gf_node_get_field(base, i, &base_field);
1528 6801 : if (!gf_sg_vrml_field_equal(base_field.far_ptr, field.far_ptr, field.fieldType)) {
1529 1551 : def_fields[i] = 1;
1530 1551 : to_dump++;
1531 : }
1532 : }
1533 : break;
1534 : }
1535 : }
1536 1865 : if (base) gf_node_unregister(base, NULL);
1537 :
1538 1865 : if (!to_dump) {
1539 252 : if (in_list) DUMP_IND(sdump);
1540 252 : if (!sdump->XMLDump) {
1541 111 : if (isDEF) {
1542 48 : gf_fprintf(sdump->trace, "DEF ");
1543 48 : scene_dump_vrml_id(sdump, node);
1544 48 : gf_fprintf(sdump->trace, " ");
1545 : }
1546 111 : gf_fprintf(sdump->trace, "%s {}\n", name);
1547 : } else {
1548 141 : if (isDEF) {
1549 60 : if (isProto) {
1550 0 : gf_fprintf(sdump->trace, "<ProtoInstance name=\"%s\" DEF=\"", name);
1551 : } else {
1552 60 : gf_fprintf(sdump->trace, "<%s DEF=\"", name);
1553 : }
1554 60 : scene_dump_vrml_id(sdump, node);
1555 60 : gf_fprintf(sdump->trace, "\"/>\n");
1556 : } else {
1557 81 : if (isProto) {
1558 0 : gf_fprintf(sdump->trace, "<ProtoInstance name=\"%s\"/>\n", name);
1559 : } else {
1560 81 : gf_fprintf(sdump->trace, "<%s/>\n", name);
1561 : }
1562 : }
1563 : }
1564 252 : gf_free(def_fields);
1565 252 : return;
1566 : }
1567 :
1568 1613 : if (!sdump->XMLDump) {
1569 756 : if (in_list) DUMP_IND(sdump);
1570 756 : if (isDEF) {
1571 168 : gf_fprintf(sdump->trace, "DEF ");
1572 168 : scene_dump_vrml_id(sdump, node);
1573 168 : gf_fprintf(sdump->trace, " ");
1574 : }
1575 756 : gf_fprintf(sdump->trace, "%s {\n", name);
1576 : } else {
1577 857 : if (isProto) {
1578 20 : StartElement(sdump, "ProtoInstance");
1579 20 : StartAttribute(sdump, "name");
1580 20 : gf_fprintf(sdump->trace, "%s", name);
1581 20 : EndAttribute(sdump);
1582 : } else {
1583 837 : StartElement(sdump, name);
1584 : }
1585 857 : if (isDEF) {
1586 196 : StartAttribute(sdump, "DEF");
1587 196 : scene_dump_vrml_id(sdump, node);
1588 196 : EndAttribute(sdump);
1589 : }
1590 : }
1591 :
1592 1613 : sdump->indent ++;
1593 10879 : for (i=0; i<count; i++) {
1594 9266 : switch (def_fields[i]) {
1595 : /*regular field*/
1596 1578 : case 1:
1597 1578 : gf_node_get_field(node, i, &field);
1598 1578 : if (!isScript) {
1599 1551 : gf_dump_vrml_field(sdump, node, field);
1600 : }
1601 : /*special script dump case, static fields except url*/
1602 27 : else if (i==1 || i==2) {
1603 18 : if (*((SFBool *)field.far_ptr)) gf_dump_vrml_field(sdump, node, field);
1604 : }
1605 : /*in bt first dump fields - in XMT first dump url*/
1606 9 : else if (i && !sdump->XMLDump) {
1607 0 : gf_dump_vrml_dyn_field(sdump, node, field, 0);
1608 9 : } else if (!i && sdump->XMLDump) {
1609 5 : gf_dump_vrml_field(sdump, node, field);
1610 : }
1611 : break;
1612 : /*IS field*/
1613 94 : case 3:
1614 94 : if (sdump->XMLDump) break;
1615 44 : gf_node_get_field(node, i, &field);
1616 44 : gf_dump_vrml_IS_field(sdump, node, field, isScript, 0);
1617 44 : def_fields[i] = 0;
1618 44 : break;
1619 : default:
1620 : break;
1621 : }
1622 50 : }
1623 1613 : if (fieldContainer) gf_fprintf(sdump->trace, " fieldContainer=\"%s\"", fieldContainer);
1624 :
1625 1613 : if (isScript) sub_el = 1;
1626 1613 : EndElementHeader(sdump, sub_el ? 1 : 0);
1627 :
1628 1613 : if (sub_el) {
1629 : /*dump all normal IS elements for XMT*/
1630 917 : if (hasISed && sdump->XMLDump) {
1631 35 : StartElement(sdump, "IS");
1632 35 : EndElementHeader(sdump, 1);
1633 35 : sdump->indent++;
1634 : }
1635 4568 : for (i=0; i<count; i++) {
1636 4568 : if (def_fields[i]==3) {
1637 50 : gf_node_get_field(node, i, &field);
1638 50 : gf_dump_vrml_IS_field(sdump, node, field, isScript, 1);
1639 : }
1640 : }
1641 917 : if (hasISed && sdump->XMLDump) {
1642 35 : sdump->indent--;
1643 35 : EndElement(sdump, "IS", 1);
1644 : }
1645 : /*dump all sub elements and complex IS*/
1646 4568 : for (i=0; i<count; i++) {
1647 4568 : switch (def_fields[i]) {
1648 1236 : case 2:
1649 1236 : gf_node_get_field(node, i, &field);
1650 1236 : if (!isScript) {
1651 1218 : if (isProto && sdump->XMLDump) {
1652 130 : gf_dump_vrml_proto_field(sdump, node, field);
1653 : } else {
1654 1088 : gf_dump_vrml_field(sdump, node, field);
1655 : }
1656 : } else {
1657 : #ifndef GPAC_DISABLE_X3D
1658 : /*X3D script metadata, NOT DYN*/
1659 18 : if ((i==3) && (node->sgprivate->tag==TAG_X3D_Script) ) {
1660 0 : if (*((GF_Node **)field.far_ptr)) gf_dump_vrml_field(sdump, node, field);
1661 : } else
1662 : #endif
1663 : {
1664 18 : gf_dump_vrml_dyn_field(sdump, node, field, 0);
1665 : }
1666 : }
1667 : break;
1668 5 : case 4:
1669 5 : gf_node_get_field(node, i, &field);
1670 5 : gf_dump_vrml_IS_field(sdump, node, field, isScript, 0);
1671 5 : break;
1672 : }
1673 : }
1674 : }
1675 :
1676 : /*finally dump script - XMT dumping is broken!!*/
1677 1613 : if (isScript && !sdump->XMLDump) {
1678 4 : gf_node_get_field(node, 0, &field);
1679 4 : gf_dump_vrml_field(sdump, node, field);
1680 : }
1681 :
1682 1613 : sdump->indent --;
1683 1613 : if (!sdump->XMLDump && !in_list) {
1684 426 : DUMP_IND(sdump);
1685 426 : gf_fprintf(sdump->trace, "}");
1686 : } else {
1687 1187 : EndElement(sdump, isProto ? "ProtoInstance" : name, sub_el);
1688 : }
1689 1613 : gf_free(def_fields);
1690 : }
1691 :
1692 :
1693 9 : static GF_Err DumpMultipleIndexedReplace(GF_SceneDumper *sdump, GF_Command *com)
1694 : {
1695 : u32 i;
1696 : GF_FieldInfo field;
1697 : GF_CommandField *inf;
1698 9 : if (!gf_list_count(com->command_fields)) return GF_OK;
1699 9 : inf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
1700 9 : gf_node_get_field(com->node, inf->fieldIndex, &field);
1701 9 : field.fieldType = inf->fieldType;
1702 :
1703 9 : DUMP_IND(sdump);
1704 9 : if (sdump->XMLDump) {
1705 5 : gf_fprintf(sdump->trace, "<Replace extended=\"indices\" atNode=\"");
1706 5 : scene_dump_vrml_id(sdump, com->node);
1707 5 : gf_fprintf(sdump->trace, "\" atField=\"%s\">\n", field.name);
1708 : } else {
1709 4 : gf_fprintf(sdump->trace, "MULTIPLEINDREPLACE ");
1710 4 : scene_dump_vrml_id(sdump, com->node);
1711 4 : gf_fprintf(sdump->trace, ".%s [\n", field.name);
1712 : }
1713 9 : sdump->indent++;
1714 9 : i=0;
1715 36 : while ((inf = (GF_CommandField *) gf_list_enum(com->command_fields, &i))) {
1716 27 : field.far_ptr = inf->field_ptr;
1717 :
1718 27 : DUMP_IND(sdump);
1719 27 : if (sdump->XMLDump) {
1720 15 : gf_fprintf(sdump->trace, "<repValue position=\"%d\" ", inf->pos);
1721 : } else {
1722 12 : gf_fprintf(sdump->trace, "%d BY ", inf->pos);
1723 : }
1724 27 : gf_dump_vrml_simple_field(sdump, field, com->node);
1725 27 : if (sdump->XMLDump) {
1726 15 : gf_fprintf(sdump->trace, "/>");
1727 : } else {
1728 12 : gf_fprintf(sdump->trace, "\n");
1729 : }
1730 : }
1731 9 : sdump->indent--;
1732 9 : DUMP_IND(sdump);
1733 9 : if (sdump->XMLDump) {
1734 5 : gf_fprintf(sdump->trace, "</Replace>\n");
1735 : } else {
1736 4 : gf_fprintf(sdump->trace, "]\n");
1737 : }
1738 : return GF_OK;
1739 : }
1740 :
1741 12 : static GF_Err DumpMultipleReplace(GF_SceneDumper *sdump, GF_Command *com)
1742 : {
1743 : u32 i;
1744 : GF_FieldInfo info;
1745 : GF_CommandField *inf;
1746 12 : if (!gf_list_count(com->command_fields)) return GF_OK;
1747 :
1748 12 : DUMP_IND(sdump);
1749 12 : if (sdump->XMLDump) {
1750 7 : gf_fprintf(sdump->trace, "<Replace extended=\"fields\" atNode=\"");
1751 7 : scene_dump_vrml_id(sdump, com->node);
1752 7 : gf_fprintf(sdump->trace, "\">\n");
1753 :
1754 7 : sdump->indent++;
1755 7 : i=0;
1756 24 : while ((inf = (GF_CommandField *) gf_list_enum(com->command_fields, &i))) {
1757 17 : gf_node_get_field(com->node, inf->fieldIndex, &info);
1758 17 : info.far_ptr = inf->field_ptr;
1759 :
1760 17 : DUMP_IND(sdump);
1761 17 : if (gf_sg_vrml_get_sf_type(info.fieldType) != GF_SG_VRML_SFNODE) {
1762 10 : gf_fprintf(sdump->trace, "<repField atField=\"%s\" ", info.name);
1763 10 : gf_dump_vrml_simple_field(sdump, info, com->node);
1764 10 : gf_fprintf(sdump->trace, "/>\n");
1765 : } else {
1766 7 : gf_fprintf(sdump->trace, "<repField>");
1767 7 : gf_dump_vrml_field(sdump, com->node, info);
1768 7 : gf_fprintf(sdump->trace, "</repField>\n");
1769 : }
1770 : }
1771 7 : sdump->indent--;
1772 :
1773 7 : DUMP_IND(sdump);
1774 7 : gf_fprintf(sdump->trace, "</Replace>\n");
1775 : } else {
1776 5 : gf_fprintf(sdump->trace, "MULTIPLEREPLACE ");
1777 5 : scene_dump_vrml_id(sdump, com->node);
1778 5 : gf_fprintf(sdump->trace, " {\n");
1779 5 : sdump->indent++;
1780 5 : i=0;
1781 18 : while ((inf = (GF_CommandField *) gf_list_enum(com->command_fields, &i))) {
1782 13 : gf_node_get_field(com->node, inf->fieldIndex, &info);
1783 13 : info.far_ptr = inf->field_ptr;
1784 13 : gf_dump_vrml_field(sdump, com->node, info);
1785 : }
1786 5 : sdump->indent--;
1787 5 : DUMP_IND(sdump);
1788 5 : gf_fprintf(sdump->trace, "}\n");
1789 : }
1790 : return GF_OK;
1791 : }
1792 :
1793 9 : static GF_Err DumpGlobalQP(GF_SceneDumper *sdump, GF_Command *com)
1794 : {
1795 : GF_CommandField *inf;
1796 9 : if (!gf_list_count(com->command_fields)) return GF_OK;
1797 9 : inf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
1798 :
1799 9 : DUMP_IND(sdump);
1800 9 : if (sdump->XMLDump) {
1801 5 : gf_fprintf(sdump->trace, "<Replace extended=\"globalQuant\">\n");
1802 : } else {
1803 4 : gf_fprintf(sdump->trace, "GLOBALQP ");
1804 : }
1805 9 : gf_dump_vrml_node(sdump, inf->new_node, 0, NULL);
1806 9 : if (sdump->XMLDump) gf_fprintf(sdump->trace, "</Replace>\n");
1807 4 : else gf_fprintf(sdump->trace, "\n");
1808 : return GF_OK;
1809 : }
1810 :
1811 45 : static GF_Err DumpNodeInsert(GF_SceneDumper *sdump, GF_Command *com)
1812 : {
1813 : GF_CommandField *inf;
1814 : char posname[20];
1815 45 : if (!gf_list_count(com->command_fields)) return GF_OK;
1816 45 : inf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
1817 :
1818 45 : switch (inf->pos) {
1819 : case 0:
1820 : strcpy(posname, "BEGIN");
1821 : break;
1822 : case -1:
1823 : strcpy(posname, "END");
1824 : break;
1825 0 : default:
1826 : sprintf(posname, "%d", inf->pos);
1827 : break;
1828 : }
1829 :
1830 45 : DUMP_IND(sdump);
1831 45 : if (sdump->XMLDump) {
1832 25 : gf_fprintf(sdump->trace, "<Insert atNode=\"");
1833 25 : scene_dump_vrml_id(sdump, com->node);
1834 25 : gf_fprintf(sdump->trace, "\" position=\"%s\">", posname);
1835 : } else {
1836 20 : if (inf->pos==-1) {
1837 12 : gf_fprintf(sdump->trace, "APPEND TO ");
1838 : }
1839 8 : else gf_fprintf(sdump->trace, "INSERT AT ");
1840 20 : scene_dump_vrml_id(sdump, com->node);
1841 20 : gf_fprintf(sdump->trace, ".children");
1842 20 : if (inf->pos!=-1) gf_fprintf(sdump->trace, "[%d]", inf->pos);
1843 20 : gf_fprintf(sdump->trace, " ");
1844 : }
1845 :
1846 45 : gf_dump_vrml_node(sdump, inf->new_node, 0, NULL);
1847 45 : if (sdump->XMLDump) gf_fprintf(sdump->trace, "</Insert>");
1848 45 : gf_fprintf(sdump->trace, "\n");
1849 : return GF_OK;
1850 : }
1851 :
1852 63 : static GF_Err DumpRouteInsert(GF_SceneDumper *sdump, GF_Command *com, Bool is_scene_replace)
1853 : {
1854 : GF_Route r;
1855 :
1856 : memset(&r, 0, sizeof(GF_Route));
1857 63 : r.ID = com->RouteID;
1858 63 : r.name = com->def_name;
1859 126 : r.FromNode = gf_dump_find_node(sdump, com->fromNodeID);
1860 63 : r.FromField.fieldIndex = com->fromFieldIndex;
1861 126 : r.ToNode = gf_dump_find_node(sdump, com->toNodeID);
1862 63 : r.ToField.fieldIndex = com->toFieldIndex;
1863 :
1864 63 : gf_list_add(sdump->inserted_routes, com);
1865 :
1866 63 : if (is_scene_replace) {
1867 54 : gf_dump_vrml_route(sdump, &r, 0);
1868 : } else {
1869 9 : DUMP_IND(sdump);
1870 9 : if (sdump->XMLDump) {
1871 5 : gf_fprintf(sdump->trace, "<Insert>\n");
1872 : } else {
1873 4 : gf_fprintf(sdump->trace, "INSERT ");
1874 : }
1875 9 : gf_dump_vrml_route(sdump, &r, 2);
1876 9 : if (sdump->XMLDump) gf_fprintf(sdump->trace, "</Insert>");
1877 : }
1878 63 : return GF_OK;
1879 : }
1880 :
1881 4 : static GF_Err DumpIndexInsert(GF_SceneDumper *sdump, GF_Command *com)
1882 : {
1883 : GF_Err e;
1884 : GF_FieldInfo field, sffield;
1885 : GF_CommandField *inf;
1886 : char posname[20];
1887 4 : if (!gf_list_count(com->command_fields)) return GF_OK;
1888 4 : inf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
1889 :
1890 4 : switch (inf->pos) {
1891 : case 0:
1892 : strcpy(posname, "BEGIN");
1893 : break;
1894 : case -1:
1895 : strcpy(posname, "END");
1896 : break;
1897 0 : default:
1898 : sprintf(posname, "%d", inf->pos);
1899 : break;
1900 : }
1901 :
1902 4 : e = gf_node_get_field(com->node, inf->fieldIndex, &field);
1903 4 : if (e) return e;
1904 4 : if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
1905 :
1906 4 : DUMP_IND(sdump);
1907 4 : if (sdump->XMLDump) {
1908 3 : gf_fprintf(sdump->trace, "<Insert atNode=\"");
1909 3 : scene_dump_vrml_id(sdump, com->node);
1910 3 : gf_fprintf(sdump->trace, "\" atField=\"%s\" position=\"%s\"", field.name, posname);
1911 : } else {
1912 1 : if (inf->pos==-1) {
1913 0 : gf_fprintf(sdump->trace, "APPEND TO ");
1914 : }
1915 1 : else gf_fprintf(sdump->trace, "INSERT AT ");
1916 1 : scene_dump_vrml_id(sdump, com->node);
1917 1 : gf_fprintf(sdump->trace, ".%s", field.name);
1918 1 : if (inf->pos!=-1) gf_fprintf(sdump->trace, "[%d]", inf->pos);
1919 1 : gf_fprintf(sdump->trace, " ");
1920 : }
1921 :
1922 : memcpy(&sffield, &field, sizeof(GF_FieldInfo));
1923 4 : sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
1924 :
1925 4 : if (field.fieldType==GF_SG_VRML_MFNODE) {
1926 2 : if (sdump->XMLDump) gf_fprintf(sdump->trace, ">\n");
1927 2 : gf_dump_vrml_node(sdump, inf->new_node, 0, NULL);
1928 2 : if (sdump->XMLDump) gf_fprintf(sdump->trace, "</Insert>");
1929 2 : gf_fprintf(sdump->trace, "\n");
1930 : } else {
1931 2 : sffield.far_ptr = inf->field_ptr;
1932 2 : gf_dump_vrml_simple_field(sdump, sffield, com->node);
1933 2 : if (sdump->XMLDump) gf_fprintf(sdump->trace, "/>");
1934 2 : gf_fprintf(sdump->trace, "\n");
1935 : }
1936 : return e;
1937 : }
1938 :
1939 9 : static GF_Err DumpIndexDelete(GF_SceneDumper *sdump, GF_Command *com)
1940 : {
1941 : char posname[20];
1942 : GF_FieldInfo field;
1943 : GF_CommandField *inf;
1944 9 : if (!gf_list_count(com->command_fields)) return GF_OK;
1945 9 : inf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
1946 :
1947 9 : switch (inf->pos) {
1948 0 : case -1:
1949 0 : strcpy(posname, sdump->XMLDump ? "END" : "LAST");
1950 : break;
1951 : case 0:
1952 : strcpy(posname, "BEGIN");
1953 : break;
1954 0 : default:
1955 : sprintf(posname, "%d", inf->pos);
1956 : break;
1957 : }
1958 :
1959 9 : gf_node_get_field(com->node, inf->fieldIndex, &field);
1960 :
1961 9 : DUMP_IND(sdump);
1962 9 : if (sdump->XMLDump) {
1963 5 : gf_fprintf(sdump->trace, "<Delete atNode=\"");
1964 5 : scene_dump_vrml_id(sdump, com->node);
1965 5 : gf_fprintf(sdump->trace, "\" atField=\"%s\" position=\"%s\"/>", field.name, posname);
1966 : } else {
1967 4 : gf_fprintf(sdump->trace, "DELETE ");
1968 4 : if (inf->pos==-1) gf_fprintf(sdump->trace, "%s ", posname);
1969 4 : scene_dump_vrml_id(sdump, com->node);
1970 4 : gf_fprintf(sdump->trace, ".%s", field.name);
1971 4 : if (inf->pos!=-1) gf_fprintf(sdump->trace, "[%d]", inf->pos);
1972 4 : gf_fprintf(sdump->trace, "\n");
1973 : }
1974 : return GF_OK;
1975 : }
1976 :
1977 :
1978 18 : static GF_Err DumpNodeDelete(GF_SceneDumper *sdump, GF_Command *com)
1979 : {
1980 18 : DUMP_IND(sdump);
1981 18 : if (sdump->XMLDump) {
1982 10 : if (com->tag==GF_SG_NODE_DELETE_EX) {
1983 5 : gf_fprintf(sdump->trace, "<Delete extended=\"deleteOrder\" atNode=\"");
1984 : } else {
1985 5 : gf_fprintf(sdump->trace, "<Delete atNode=\"");
1986 : }
1987 10 : scene_dump_vrml_id(sdump, com->node);
1988 10 : gf_fprintf(sdump->trace, "\"/>\n");
1989 : } else {
1990 8 : if (com->tag==GF_SG_NODE_DELETE_EX) gf_fprintf(sdump->trace, "X");
1991 8 : gf_fprintf(sdump->trace, "DELETE ");
1992 8 : scene_dump_vrml_id(sdump, com->node);
1993 8 : gf_fprintf(sdump->trace, "\n");
1994 : }
1995 18 : return GF_OK;
1996 : }
1997 :
1998 9 : static GF_Err DumpRouteDelete(GF_SceneDumper *sdump, GF_Command *com)
1999 : {
2000 9 : DUMP_IND(sdump);
2001 9 : if (sdump->XMLDump) {
2002 5 : gf_fprintf(sdump->trace, "<Delete atRoute=\"");
2003 5 : scene_dump_vrml_route_id(sdump, com->RouteID, com->def_name);
2004 5 : gf_fprintf(sdump->trace, "\"/>\n");
2005 : } else {
2006 4 : gf_fprintf(sdump->trace, "DELETE ROUTE ");
2007 4 : scene_dump_vrml_route_id(sdump, com->RouteID, com->def_name);
2008 4 : gf_fprintf(sdump->trace, "\n");
2009 : }
2010 9 : return GF_OK;
2011 : }
2012 :
2013 :
2014 :
2015 45 : static GF_Err DumpNodeReplace(GF_SceneDumper *sdump, GF_Command *com)
2016 : {
2017 : GF_CommandField *inf;
2018 45 : if (!gf_list_count(com->command_fields)) return GF_OK;
2019 43 : inf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
2020 43 : DUMP_IND(sdump);
2021 43 : if (sdump->XMLDump) {
2022 25 : gf_fprintf(sdump->trace, "<Replace atNode=\"");
2023 25 : scene_dump_vrml_id(sdump, com->node);
2024 25 : gf_fprintf(sdump->trace, "\">");
2025 25 : gf_dump_vrml_node(sdump, inf->new_node, 0, NULL);
2026 25 : gf_fprintf(sdump->trace, "</Replace>\n");
2027 : } else {
2028 18 : gf_fprintf(sdump->trace, "REPLACE ");
2029 18 : scene_dump_vrml_id(sdump, com->node);
2030 18 : gf_fprintf(sdump->trace, " BY ");
2031 18 : gf_dump_vrml_node(sdump, inf->new_node, 0, NULL);
2032 18 : gf_fprintf(sdump->trace, "\n");
2033 : }
2034 : return GF_OK;
2035 : }
2036 :
2037 133 : static GF_Err DumpFieldReplace(GF_SceneDumper *sdump, GF_Command *com)
2038 : {
2039 : GF_Err e;
2040 : GF_FieldInfo field;
2041 : GF_CommandField *inf;
2042 133 : if (!gf_list_count(com->command_fields)) return GF_OK;
2043 133 : inf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
2044 :
2045 133 : e = gf_node_get_field(com->node, inf->fieldIndex, &field);
2046 :
2047 133 : DUMP_IND(sdump);
2048 133 : if (sdump->XMLDump) {
2049 74 : gf_fprintf(sdump->trace, "<Replace atNode=\"");
2050 74 : scene_dump_vrml_id(sdump, com->node);
2051 74 : gf_fprintf(sdump->trace, "\" atField=\"%s\" ", field.name);
2052 : } else {
2053 59 : gf_fprintf(sdump->trace, "REPLACE ");
2054 59 : scene_dump_vrml_id(sdump, com->node);
2055 59 : gf_fprintf(sdump->trace, ".%s BY ", field.name);
2056 : }
2057 :
2058 133 : switch (field.fieldType) {
2059 6 : case GF_SG_VRML_SFNODE:
2060 6 : if (sdump->XMLDump) gf_fprintf(sdump->trace, ">");
2061 6 : gf_dump_vrml_node(sdump, inf->new_node, 0, NULL);
2062 6 : if (sdump->XMLDump) gf_fprintf(sdump->trace, "</Replace>");
2063 2 : else gf_fprintf(sdump->trace, "\n");
2064 : break;
2065 3 : case GF_SG_VRML_MFNODE:
2066 : {
2067 : GF_ChildNodeItem *tmp;
2068 3 : if (sdump->XMLDump) {
2069 2 : gf_fprintf(sdump->trace, ">");
2070 : } else {
2071 1 : gf_fprintf(sdump->trace, " [\n");
2072 : }
2073 3 : sdump->indent++;
2074 3 : tmp = inf->node_list;
2075 6 : while (tmp) {
2076 3 : gf_dump_vrml_node(sdump, tmp->node, 1, NULL);
2077 3 : tmp = tmp->next;
2078 : }
2079 3 : sdump->indent--;
2080 3 : if (sdump->XMLDump) {
2081 2 : gf_fprintf(sdump->trace, "</Replace>");
2082 : } else {
2083 1 : EndList(sdump, NULL);
2084 : }
2085 : }
2086 : break;
2087 0 : case GF_SG_VRML_SFCOMMANDBUFFER:
2088 0 : if (sdump->XMLDump) {
2089 0 : SFCommandBuffer *cb = (SFCommandBuffer*)inf->field_ptr;
2090 0 : gf_fprintf(sdump->trace, ">\n");
2091 0 : gf_sm_dump_command_list(sdump, cb->commandList, sdump->indent+1, 0);
2092 0 : DUMP_IND(sdump);
2093 0 : gf_fprintf(sdump->trace, "</Replace>\n");
2094 : } else {
2095 0 : SFCommandBuffer *cb = (SFCommandBuffer*)inf->field_ptr;
2096 0 : gf_fprintf(sdump->trace, " {\n");
2097 0 : gf_sm_dump_command_list(sdump, cb->commandList, sdump->indent+1, 0);
2098 0 : DUMP_IND(sdump);
2099 0 : gf_fprintf(sdump->trace, "}\n");
2100 : }
2101 : break;
2102 124 : default:
2103 124 : field.far_ptr = inf->field_ptr;
2104 124 : gf_dump_vrml_simple_field(sdump, field, com->node);
2105 124 : if (sdump->XMLDump) gf_fprintf(sdump->trace, "/>");
2106 124 : gf_fprintf(sdump->trace, "\n");
2107 : }
2108 : return e;
2109 : }
2110 :
2111 :
2112 27 : static GF_Err DumpIndexReplace(GF_SceneDumper *sdump, GF_Command *com)
2113 : {
2114 : char posname[20];
2115 : GF_Err e;
2116 : GF_FieldInfo field;
2117 : GF_CommandField *inf;
2118 27 : if (!gf_list_count(com->command_fields)) return GF_OK;
2119 27 : inf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
2120 :
2121 27 : e = gf_node_get_field(com->node, inf->fieldIndex, &field);
2122 27 : if (e) return e;
2123 27 : if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
2124 :
2125 27 : switch (inf->pos) {
2126 : case 0:
2127 : strcpy(posname, "BEGIN");
2128 : break;
2129 0 : case -1:
2130 0 : strcpy(posname, sdump->XMLDump ? "END" : "LAST");
2131 : break;
2132 9 : default:
2133 : sprintf(posname, "%d", inf->pos);
2134 : break;
2135 : }
2136 :
2137 27 : DUMP_IND(sdump);
2138 27 : if (sdump->XMLDump) {
2139 15 : gf_fprintf(sdump->trace, "<Replace atNode=\"");
2140 15 : scene_dump_vrml_id(sdump, com->node);
2141 15 : gf_fprintf(sdump->trace, "\" atField=\"%s\" position=\"%s\"", field.name, posname);
2142 : } else {
2143 12 : gf_fprintf(sdump->trace, "REPLACE ");
2144 12 : if (inf->pos==-1) gf_fprintf(sdump->trace, "%s ", posname);
2145 12 : scene_dump_vrml_id(sdump, com->node);
2146 12 : gf_fprintf(sdump->trace, ".%s", field.name);
2147 12 : if (inf->pos!=-1) gf_fprintf(sdump->trace, "[%d]", inf->pos);
2148 12 : gf_fprintf(sdump->trace, " BY ");
2149 : }
2150 :
2151 27 : if (field.fieldType == GF_SG_VRML_MFNODE) {
2152 18 : if (sdump->XMLDump) gf_fprintf(sdump->trace, ">\n");
2153 18 : gf_dump_vrml_node(sdump, inf->new_node, 0, NULL);
2154 18 : gf_fprintf(sdump->trace, (sdump->XMLDump) ? "</Replace>\n" : "\n");
2155 : } else {
2156 9 : field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
2157 9 : field.far_ptr = inf->field_ptr;
2158 9 : gf_dump_vrml_simple_field(sdump, field, com->node);
2159 9 : gf_fprintf(sdump->trace, sdump->XMLDump ? "/>\n" : "\n");
2160 : }
2161 : return GF_OK;
2162 : }
2163 :
2164 :
2165 18 : static GF_Err DumpXReplace(GF_SceneDumper *sdump, GF_Command *com)
2166 : {
2167 : char posname[20];
2168 : GF_Err e;
2169 : GF_FieldInfo field, idxField;
2170 : GF_Node *toNode, *target;
2171 : GF_CommandField *inf;
2172 18 : if (!gf_list_count(com->command_fields)) return GF_OK;
2173 18 : inf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
2174 :
2175 18 : e = gf_node_get_field(com->node, inf->fieldIndex, &field);
2176 18 : if (e) return e;
2177 :
2178 : toNode = target = NULL;
2179 : /*indexed replacement with index given by other node field*/
2180 18 : if (com->toNodeID) {
2181 9 : toNode = gf_sg_find_node(com->in_scene, com->toNodeID);
2182 9 : if (!toNode) return GF_NON_COMPLIANT_BITSTREAM;
2183 9 : e = gf_node_get_field(toNode, com->toFieldIndex, &idxField);
2184 9 : if (e) return e;
2185 : }
2186 : else {
2187 : /*indexed replacement */
2188 9 : if (inf->pos>=-1) {
2189 7 : if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
2190 0 : switch (inf->pos) {
2191 : case 0:
2192 : strcpy(posname, "BEGIN");
2193 : break;
2194 0 : case -1:
2195 0 : strcpy(posname, sdump->XMLDump ? "END" : "LAST");
2196 : break;
2197 0 : default:
2198 : sprintf(posname, "%d", inf->pos);
2199 : break;
2200 : }
2201 0 : field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
2202 : }
2203 : }
2204 11 : field.far_ptr = inf->field_ptr;
2205 :
2206 11 : DUMP_IND(sdump);
2207 11 : if (sdump->XMLDump) {
2208 7 : gf_fprintf(sdump->trace, "<Replace atNode=\"");
2209 7 : scene_dump_vrml_id(sdump, com->node);
2210 7 : gf_fprintf(sdump->trace, "\" atField=\"%s\"", field.name);
2211 :
2212 7 : if (toNode) {
2213 5 : gf_fprintf(sdump->trace, " atIndexNode=\"");
2214 5 : scene_dump_vrml_id(sdump, toNode);
2215 5 : gf_fprintf(sdump->trace, "\" atIndexField=\"%s\"", idxField.name);
2216 :
2217 5 : field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
2218 : }
2219 7 : if (com->ChildNodeTag) {
2220 : GF_FieldInfo cfield;
2221 : GF_Node *cnode;
2222 :
2223 5 : if (com->ChildNodeTag>0) {
2224 5 : cnode = gf_node_new(com->in_scene, com->ChildNodeTag);
2225 : } else {
2226 0 : GF_Proto *proto = gf_sg_find_proto(com->in_scene, -com->ChildNodeTag , NULL);
2227 0 : if (!proto) return GF_SG_UNKNOWN_NODE;
2228 0 : cnode = gf_sg_proto_create_instance(com->in_scene, proto);
2229 : }
2230 5 : if (!cnode) return GF_SG_UNKNOWN_NODE;
2231 5 : gf_node_register(cnode, NULL);
2232 5 : gf_node_get_field(cnode, com->child_field, &cfield);
2233 5 : gf_fprintf(sdump->trace, " atChildField=\"%s\"", cfield.name);
2234 5 : gf_node_unregister(cnode, NULL);
2235 :
2236 5 : field.fieldType = cfield.fieldType;
2237 : }
2238 :
2239 7 : if (com->fromNodeID) {
2240 2 : target = gf_sg_find_node(com->in_scene, com->fromNodeID);
2241 2 : if (!target) return GF_NON_COMPLIANT_BITSTREAM;
2242 2 : e = gf_node_get_field(target, com->fromFieldIndex, &idxField);
2243 2 : if (e) return e;
2244 :
2245 2 : gf_fprintf(sdump->trace, " fromNode=\"");
2246 2 : scene_dump_vrml_id(sdump, target);
2247 2 : gf_fprintf(sdump->trace, "\" fromField=\"%s\">\n", idxField.name);
2248 2 : return GF_OK;
2249 : } else {
2250 5 : if (inf->pos>=-1) gf_fprintf(sdump->trace, " position=\"%s\"", posname);
2251 : }
2252 : } else {
2253 4 : gf_fprintf(sdump->trace, "XREPLACE ");
2254 4 : if (inf->pos==-1) gf_fprintf(sdump->trace, "%s ", posname);
2255 4 : scene_dump_vrml_id(sdump, com->node);
2256 4 : gf_fprintf(sdump->trace, ".%s", field.name);
2257 4 : if (toNode) {
2258 4 : gf_fprintf(sdump->trace, "[");
2259 4 : scene_dump_vrml_id(sdump, toNode);
2260 4 : gf_fprintf(sdump->trace, ".%s]", idxField.name);
2261 4 : field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
2262 : }
2263 0 : else if (inf->pos!=-1) gf_fprintf(sdump->trace, "[%d]", inf->pos);
2264 4 : if (com->ChildNodeTag) {
2265 : GF_FieldInfo cfield;
2266 : GF_Node *cnode;
2267 4 : if (com->ChildNodeTag>0) {
2268 4 : cnode = gf_node_new(com->in_scene, com->ChildNodeTag);
2269 : } else {
2270 0 : GF_Proto *proto = gf_sg_find_proto(com->in_scene, -com->ChildNodeTag , NULL);
2271 0 : if (!proto) return GF_SG_UNKNOWN_NODE;
2272 0 : cnode = gf_sg_proto_create_instance(com->in_scene, proto);
2273 : }
2274 4 : if (!cnode) return GF_SG_UNKNOWN_NODE;
2275 4 : gf_node_register(cnode, NULL);
2276 4 : gf_node_get_field(cnode, com->child_field, &cfield);
2277 4 : gf_fprintf(sdump->trace, ".%s", cfield.name);
2278 4 : gf_node_unregister(cnode, NULL);
2279 4 : field.fieldType = cfield.fieldType;
2280 : }
2281 4 : gf_fprintf(sdump->trace, " BY ");
2282 : }
2283 :
2284 9 : if (field.fieldType == GF_SG_VRML_MFNODE) {
2285 0 : if (sdump->XMLDump) gf_fprintf(sdump->trace, ">\n");
2286 0 : gf_dump_vrml_node(sdump, inf->new_node, 0, NULL);
2287 0 : gf_fprintf(sdump->trace, (sdump->XMLDump) ? "</Replace>\n" : "\n");
2288 : } else {
2289 9 : gf_dump_vrml_simple_field(sdump, field, com->node);
2290 9 : gf_fprintf(sdump->trace, sdump->XMLDump ? "/>\n" : "\n");
2291 : }
2292 : return GF_OK;
2293 : }
2294 :
2295 :
2296 9 : static GF_Err DumpRouteReplace(GF_SceneDumper *sdump, GF_Command *com)
2297 : {
2298 : const char *name;
2299 : GF_Route r2;
2300 :
2301 9 : if (!scene_dump_vrml_find_route_name(sdump, com->RouteID, &name)) return GF_BAD_PARAM;
2302 :
2303 : memset(&r2, 0, sizeof(GF_Route));
2304 18 : r2.FromNode = gf_dump_find_node(sdump, com->fromNodeID);
2305 9 : r2.FromField.fieldIndex = com->fromFieldIndex;
2306 18 : r2.ToNode = gf_dump_find_node(sdump, com->toNodeID);
2307 9 : r2.ToField.fieldIndex = com->toFieldIndex;
2308 :
2309 9 : DUMP_IND(sdump);
2310 9 : if (sdump->XMLDump) {
2311 5 : gf_fprintf(sdump->trace, "<Replace atRoute=\"");
2312 5 : scene_dump_vrml_route_id(sdump, com->RouteID, (char *) name);
2313 5 : gf_fprintf(sdump->trace, "\">\n");
2314 : } else {
2315 4 : gf_fprintf(sdump->trace, "REPLACE ROUTE ");
2316 4 : scene_dump_vrml_route_id(sdump, com->RouteID, (char *) name);
2317 4 : gf_fprintf(sdump->trace, " BY ");
2318 : }
2319 9 : gf_dump_vrml_route(sdump, &r2, 1);
2320 9 : if (sdump->XMLDump ) gf_fprintf(sdump->trace, "</Replace>");
2321 : return GF_OK;
2322 : }
2323 :
2324 72 : static GF_Err gf_dump_vrml_route(GF_SceneDumper *sdump, GF_Route *r, u32 dump_type)
2325 : {
2326 : char toNode[512], fromNode[512];
2327 : const char *node_name;
2328 : u32 id;
2329 72 : if (!r->is_setup) {
2330 72 : gf_node_get_field(r->FromNode, r->FromField.fieldIndex, &r->FromField);
2331 72 : gf_node_get_field(r->ToNode, r->ToField.fieldIndex, &r->ToField);
2332 72 : r->is_setup = 1;
2333 : }
2334 72 : if (!r->FromNode || !r->ToNode) return GF_BAD_PARAM;
2335 :
2336 72 : if (sdump->XMLDump || !dump_type) DUMP_IND(sdump);
2337 :
2338 72 : node_name = gf_node_get_name_and_id(r->FromNode, &id);
2339 72 : if (node_name) {
2340 : const char *to_name;
2341 : strcpy(fromNode, node_name);
2342 24 : to_name = gf_node_get_name(r->ToNode);
2343 24 : if (to_name) {
2344 : strcpy(toNode, to_name);
2345 : } else {
2346 : char str[100];
2347 0 : id = gf_node_get_id(r->ToNode);
2348 : sprintf(str, "node_%d", id);
2349 : strcpy(toNode, str);
2350 : }
2351 : } else {
2352 48 : sprintf(fromNode, "N%d", id-1);
2353 48 : sprintf(toNode, "N%d", gf_node_get_id(r->ToNode) - 1);
2354 : }
2355 72 : if (sdump->XMLDump) {
2356 40 : gf_fprintf(sdump->trace, "<ROUTE");
2357 40 : if (r->ID) {
2358 5 : StartAttribute(sdump, "DEF");
2359 5 : scene_dump_vrml_route_id(sdump, r->ID, r->name);
2360 5 : EndAttribute(sdump);
2361 : }
2362 40 : gf_fprintf(sdump->trace, " fromNode=\"%s\" fromField=\"%s\" toNode=\"%s\" toField=\"%s\"/>\n", fromNode, r->FromField.name, toNode, r->ToField.name);
2363 : } else {
2364 32 : if (dump_type==2) gf_fprintf(sdump->trace, "ROUTE ");
2365 32 : if (r->ID) {
2366 4 : gf_fprintf(sdump->trace, "DEF ");
2367 4 : scene_dump_vrml_route_id(sdump, r->ID, r->name);
2368 4 : gf_fprintf(sdump->trace, " ");
2369 : }
2370 32 : if (dump_type==1) {
2371 4 : gf_fprintf(sdump->trace, "%s.%s TO %s.%s\n", fromNode, r->FromField.name, toNode, r->ToField.name);
2372 : } else {
2373 28 : if (dump_type!=2) gf_fprintf(sdump->trace, "ROUTE ");
2374 28 : gf_fprintf(sdump->trace, "%s.%s TO %s.%s\n", fromNode, r->FromField.name, toNode, r->ToField.name);
2375 : }
2376 : }
2377 : return GF_OK;
2378 : }
2379 :
2380 :
2381 64 : static GF_Err DumpProtos(GF_SceneDumper *sdump, GF_List *protoList)
2382 : {
2383 : #ifdef GPAC_DISABLE_VRML
2384 : return GF_OK;
2385 : #else
2386 : u32 i, j, count;
2387 : GF_FieldInfo field;
2388 : GF_Err e;
2389 : GF_SceneGraph *prev_sg;
2390 : GF_Proto *proto, *prev_proto;
2391 :
2392 64 : prev_proto = sdump->current_proto;
2393 :
2394 64 : i=0;
2395 155 : while ((proto = (GF_Proto*)gf_list_enum(protoList, &i))) {
2396 27 : sdump->current_proto = proto;
2397 :
2398 27 : DUMP_IND(sdump);
2399 27 : if (!sdump->XMLDump) {
2400 12 : gf_fprintf(sdump->trace, proto->ExternProto.count ? "EXTERNPROTO " : "PROTO ");
2401 12 : gf_fprintf(sdump->trace, "%s [\n", proto->Name);
2402 : } else {
2403 15 : gf_fprintf(sdump->trace, "<ProtoDeclare name=\"%s\" protoID=\"%d\"", proto->Name, proto->ID);
2404 15 : if (proto->ExternProto.count) {
2405 5 : gf_fprintf(sdump->trace, " locations=\"");
2406 5 : gf_dump_vrml_sffield(sdump, GF_SG_VRML_SFURL, &proto->ExternProto.vals[0], 0, NULL);
2407 5 : gf_fprintf(sdump->trace, "\"");
2408 : }
2409 15 : gf_fprintf(sdump->trace, ">\n");
2410 : }
2411 :
2412 27 : if (sdump->XMLDump && sdump->X3DDump) gf_fprintf(sdump->trace, "<ProtoInterface>");
2413 :
2414 27 : sdump->indent++;
2415 27 : count = gf_list_count(proto->proto_fields);
2416 207 : for (j=0; j<count; j++) {
2417 180 : GF_ProtoFieldInterface *pf = (GF_ProtoFieldInterface *)gf_list_get(proto->proto_fields, j);
2418 : field.fieldIndex = pf->ALL_index;
2419 180 : field.eventType = pf->EventType;
2420 180 : field.far_ptr = pf->def_value;
2421 180 : field.fieldType = pf->FieldType;
2422 180 : field.name = pf->FieldName;
2423 : field.NDTtype = NDT_SFWorldNode;
2424 : field.on_event_in = NULL;
2425 :
2426 180 : gf_dump_vrml_dyn_field(sdump, NULL, field, pf->QP_Type ? 1 : 0);
2427 :
2428 180 : if (!pf->QP_Type) continue;
2429 :
2430 : /*dump interface coding - BT/TXT extensions, not supported by any other tool*/
2431 0 : sdump->indent++;
2432 0 : DUMP_IND(sdump);
2433 0 : if (sdump->XMLDump) {
2434 : const char *quant_catname = "unknown";
2435 : #ifndef GPAC_DISABLE_BIFS
2436 0 : switch (pf->QP_Type) {
2437 0 : case QC_3DPOS: quant_catname = "position3D"; break;
2438 0 : case QC_2DPOS: quant_catname = "position2D"; break;
2439 0 : case QC_ORDER: quant_catname = "drawingOrder"; break;
2440 0 : case QC_COLOR: quant_catname = "color"; break;
2441 0 : case QC_TEXTURE_COORD: quant_catname = "textureCoordinate"; break;
2442 0 : case QC_ANGLE: quant_catname = "angle"; break;
2443 0 : case QC_SCALE: quant_catname = "scale"; break;
2444 0 : case QC_INTERPOL_KEYS: quant_catname = "keys"; break;
2445 0 : case QC_NORMALS: quant_catname = "normals"; break;
2446 0 : case QC_ROTATION: quant_catname = "rotations"; break;
2447 0 : case QC_SIZE_3D: quant_catname = "size3D"; break;
2448 0 : case QC_SIZE_2D: quant_catname = "size2D"; break;
2449 0 : case QC_LINEAR_SCALAR: quant_catname = "linear"; break;
2450 0 : case QC_COORD_INDEX:quant_catname = "coordIndex"; break;
2451 : }
2452 : #endif
2453 0 : gf_fprintf(sdump->trace, "<InterfaceCodingParameters quantCategoy=\"%s\"", quant_catname);
2454 : } else {
2455 0 : gf_fprintf(sdump->trace, "{QP %d", pf->QP_Type);
2456 : }
2457 : #ifndef GPAC_DISABLE_BIFS
2458 0 : if (pf->QP_Type==QC_LINEAR_SCALAR) gf_fprintf(sdump->trace, sdump->XMLDump ? " nbBits=\"%d\"" : " nbBits %d", pf->NumBits);
2459 0 : if (pf->hasMinMax) {
2460 0 : switch (pf->QP_Type) {
2461 0 : case QC_LINEAR_SCALAR:
2462 : case QC_COORD_INDEX:
2463 0 : if (sdump->XMLDump) {
2464 0 : gf_fprintf(sdump->trace, " intMin=\"%d\" intMax=\"%d\"", *((SFInt32 *)pf->qp_min_value), *((SFInt32 *)pf->qp_max_value));
2465 : } else {
2466 0 : gf_fprintf(sdump->trace, " b {%d %d}", *((SFInt32 *)pf->qp_min_value), *((SFInt32 *)pf->qp_max_value));
2467 : }
2468 : break;
2469 0 : default:
2470 0 : if (sdump->XMLDump) {
2471 0 : gf_fprintf(sdump->trace, " floatMin=\"%g\" floatMax=\"%g\"", FIX2FLT( *((SFFloat *)pf->qp_min_value) ), FIX2FLT( *((SFFloat *)pf->qp_max_value) ));
2472 : } else {
2473 0 : gf_fprintf(sdump->trace, " b {%g %g}", FIX2FLT( *((SFFloat *)pf->qp_min_value) ), FIX2FLT( *((SFFloat *)pf->qp_max_value) ) );
2474 : }
2475 : break;
2476 : }
2477 0 : }
2478 : #endif
2479 0 : gf_fprintf(sdump->trace, sdump->XMLDump ? "/>\n" : "}\n");
2480 0 : sdump->indent--;
2481 0 : if (sdump->XMLDump) {
2482 0 : DUMP_IND(sdump);
2483 0 : gf_fprintf(sdump->trace, "</field>\n");
2484 : }
2485 :
2486 : }
2487 :
2488 27 : sdump->indent--;
2489 27 : DUMP_IND(sdump);
2490 27 : if (!sdump->XMLDump) {
2491 12 : gf_fprintf(sdump->trace, "]");
2492 15 : } else if (sdump->X3DDump) gf_fprintf(sdump->trace, "</ProtoInterface>\n");
2493 :
2494 27 : if (proto->ExternProto.count) {
2495 9 : if (!sdump->XMLDump) {
2496 4 : gf_fprintf(sdump->trace, " \"");
2497 4 : gf_dump_vrml_sffield(sdump, GF_SG_VRML_SFURL, &proto->ExternProto.vals[0], 0, NULL);
2498 4 : gf_fprintf(sdump->trace, "\"\n\n");
2499 : } else {
2500 5 : gf_fprintf(sdump->trace, "</ProtoDeclare>\n");
2501 : }
2502 9 : continue;
2503 : }
2504 18 : if (!sdump->XMLDump) gf_fprintf(sdump->trace, " {\n");
2505 :
2506 18 : sdump->indent++;
2507 :
2508 18 : if (sdump->XMLDump && sdump->X3DDump) gf_fprintf(sdump->trace, "<ProtoBody>\n");
2509 :
2510 18 : e = DumpProtos(sdump, proto->sub_graph->protos);
2511 18 : if (e) return e;
2512 :
2513 : /*set namespace to the proto one*/
2514 18 : prev_sg = sdump->sg;
2515 18 : sdump->sg = gf_sg_proto_get_graph(proto);
2516 :
2517 18 : count = gf_list_count(proto->node_code);
2518 54 : for (j=0; j<count; j++) {
2519 36 : GF_Node *n = (GF_Node*)gf_list_get(proto->node_code, j);
2520 36 : gf_dump_vrml_node(sdump, n, 1, NULL);
2521 : }
2522 18 : count = gf_list_count(proto->sub_graph->Routes);
2523 198 : for (j=0; j<count; j++) {
2524 180 : GF_Route *r = (GF_Route *)gf_list_get(proto->sub_graph->Routes, j);
2525 180 : if (r->IS_route) continue;
2526 0 : gf_dump_vrml_route(sdump, r, 0);
2527 : }
2528 :
2529 18 : if (sdump->XMLDump && sdump->X3DDump) gf_fprintf(sdump->trace, "</ProtoBody>\n");
2530 :
2531 : /*restore namespace*/
2532 18 : sdump->sg = prev_sg;
2533 :
2534 18 : sdump->indent--;
2535 18 : DUMP_IND(sdump);
2536 18 : if (!sdump->XMLDump) {
2537 8 : gf_fprintf(sdump->trace, "}\n");
2538 : } else {
2539 10 : gf_fprintf(sdump->trace, "</ProtoDeclare>\n");
2540 : }
2541 : }
2542 64 : sdump->current_proto = prev_proto;
2543 64 : return GF_OK;
2544 : #endif
2545 : }
2546 :
2547 35 : static GF_Err DumpSceneReplace(GF_SceneDumper *sdump, GF_Command *com)
2548 : {
2549 35 : if (sdump->XMLDump) {
2550 19 : if (!sdump->X3DDump) {
2551 19 : StartElement(sdump, "Replace");
2552 19 : EndElementHeader(sdump, 1);
2553 19 : sdump->indent++;
2554 : }
2555 : //scene tag is already dumped with X3D header
2556 19 : if (!sdump->X3DDump) StartElement(sdump, "Scene");
2557 19 : if (!sdump->X3DDump && com->use_names) {
2558 0 : StartAttribute(sdump, "USENAMES");
2559 0 : gf_fprintf(sdump->trace, "%s", com->use_names ? "true" : "false");
2560 0 : EndAttribute(sdump);
2561 : }
2562 19 : if (!sdump->X3DDump) EndElementHeader(sdump, 1);
2563 19 : sdump->indent++;
2564 : } else {
2565 16 : if (!sdump->skip_scene_replace) {
2566 13 : DUMP_IND(sdump);
2567 13 : gf_fprintf(sdump->trace, "REPLACE SCENE BY ");
2568 : }
2569 : }
2570 35 : DumpProtos(sdump, com->new_proto_list);
2571 35 : gf_dump_vrml_node(sdump, com->node, 0, NULL);
2572 35 : if (!sdump->XMLDump) gf_fprintf(sdump->trace, "\n\n");
2573 :
2574 35 : if (com->aggregated) {
2575 : u32 i, count;
2576 1 : count = gf_list_count(com->node->sgprivate->scenegraph->Routes);
2577 1 : for (i=0; i<count; i++) {
2578 0 : GF_Route *r = (GF_Route *)gf_list_get(com->node->sgprivate->scenegraph->Routes, i);
2579 0 : if (r->IS_route) continue;
2580 0 : gf_dump_vrml_route(sdump, r, 0);
2581 : }
2582 : }
2583 :
2584 35 : return GF_OK;
2585 : }
2586 :
2587 9 : static GF_Err DumpProtoInsert(GF_SceneDumper *sdump, GF_Command *com)
2588 : {
2589 9 : DUMP_IND(sdump);
2590 9 : if (sdump->XMLDump) {
2591 5 : gf_fprintf(sdump->trace, "<Insert extended=\"proto\">\n");
2592 : } else {
2593 4 : gf_fprintf(sdump->trace, "INSERTPROTO [\n");
2594 : }
2595 9 : sdump->indent++;
2596 9 : DumpProtos(sdump, com->new_proto_list);
2597 9 : sdump->indent--;
2598 9 : DUMP_IND(sdump);
2599 9 : if (sdump->XMLDump) {
2600 5 : gf_fprintf(sdump->trace, "</Insert>\n");
2601 : } else {
2602 4 : gf_fprintf(sdump->trace, "]\n");
2603 : }
2604 9 : return GF_OK;
2605 : }
2606 :
2607 : #endif /*GPAC_DISABLE_VRML*/
2608 :
2609 :
2610 : #ifndef GPAC_DISABLE_SVG
2611 256 : static char *lsr_format_node_id(GF_Node *n, u32 NodeID, char *str)
2612 : {
2613 256 : if (!n) sprintf(str, "N%d", NodeID-1);
2614 : else {
2615 254 : const char *name = gf_node_get_name_and_id(n, &NodeID);
2616 254 : if (name) sprintf(str, "%s", name);
2617 254 : else sprintf(str, "N%d", NodeID - 1);
2618 : }
2619 256 : return str;
2620 : }
2621 :
2622 : static char szLSRName[1024];
2623 :
2624 182 : static char *sd_get_lsr_namespace(GF_SceneGraph *sg)
2625 : {
2626 182 : char *lsrns = (char *) gf_sg_get_namespace_qname(sg, GF_XMLNS_LASER);
2627 182 : if (lsrns) {
2628 : sprintf(szLSRName, "%s:", lsrns);
2629 0 : return szLSRName;
2630 : }
2631 : return "";
2632 : }
2633 :
2634 2 : static GF_Err DumpLSRNewScene(GF_SceneDumper *sdump, GF_Command *com)
2635 : {
2636 2 : char *lsrns = sd_get_lsr_namespace(com->in_scene);
2637 2 : gf_fprintf(sdump->trace, "<%sNewScene>\n", lsrns);
2638 2 : gf_dump_svg_element(sdump, com->node, NULL, 0);
2639 2 : gf_fprintf(sdump->trace, "</%sNewScene>\n", lsrns);
2640 2 : return GF_OK;
2641 : }
2642 :
2643 62 : static GF_Err DumpLSRAddReplaceInsert(GF_SceneDumper *sdump, GF_Command *com)
2644 : {
2645 : char szID[100];
2646 : Bool is_text = 0;
2647 : GF_CommandField *f;
2648 62 : char *lsrns = sd_get_lsr_namespace(com->in_scene);
2649 :
2650 62 : const char *com_name = (com->tag==GF_SG_LSR_REPLACE) ? "Replace" : ( (com->tag==GF_SG_LSR_ADD) ? "Add" : "Insert" );
2651 :
2652 62 : DUMP_IND(sdump);
2653 :
2654 62 : gf_fprintf(sdump->trace, "<%s%s ref=\"%s\" ", lsrns, com_name, lsr_format_node_id(com->node, com->RouteID, szID));
2655 62 : f = (GF_CommandField *) gf_list_get(com->command_fields, 0);
2656 62 : if (f && (f->pos>=0) ) gf_fprintf(sdump->trace, "index=\"%d\" ", f->pos);
2657 62 : if (f) {
2658 : GF_FieldInfo info;
2659 62 : if (!f->new_node && !f->node_list) {
2660 : char *att_name = NULL;
2661 52 : if (f->fieldType==SVG_Transform_Scale_datatype) att_name = "scale";
2662 52 : else if (f->fieldType==SVG_Transform_Rotate_datatype) att_name = "rotation";
2663 52 : else if (f->fieldType==SVG_Transform_Translate_datatype) att_name = "translation";
2664 52 : else if (f->fieldIndex==(u32) -1) att_name = "textContent";
2665 52 : else att_name = (char*) gf_svg_get_attribute_name(com->node, f->fieldIndex);
2666 :
2667 52 : gf_fprintf(sdump->trace, "attributeName=\"%s\" ", att_name);
2668 52 : if (f->field_ptr) {
2669 : char *att;
2670 50 : info.far_ptr = f->field_ptr;
2671 50 : info.fieldIndex = f->fieldIndex;
2672 50 : info.fieldType = f->fieldType;
2673 50 : info.name = att_name;
2674 :
2675 50 : if ((s32) f->pos >= 0) {
2676 12 : att = gf_svg_dump_attribute_indexed(com->node, &info);
2677 : } else {
2678 38 : att = gf_svg_dump_attribute(com->node, &info);
2679 : }
2680 50 : gf_fprintf(sdump->trace, "value=\"%s\" ", att ? att : "");
2681 50 : if (att) gf_free(att);
2682 : }
2683 :
2684 52 : if (com->fromNodeID) {
2685 : GF_FieldInfo op_info;
2686 2 : GF_Node *op = gf_sg_find_node(sdump->sg, com->fromNodeID);
2687 2 : gf_fprintf(sdump->trace, "operandElementId=\"%s\" ", lsr_format_node_id(op, com->RouteID, szID));
2688 2 : gf_node_get_field(op, com->fromFieldIndex, &op_info);
2689 2 : gf_fprintf(sdump->trace, "operandAttributeName=\"%s\" ", op_info.name);
2690 : }
2691 :
2692 52 : gf_fprintf(sdump->trace, "/>\n");
2693 52 : return GF_OK;
2694 : }
2695 10 : if (f->new_node && f->new_node->sgprivate->tag==TAG_DOMText) is_text = 1;
2696 : /*if fieldIndex (eg attributeName) is set, this is children replacement*/
2697 10 : if (f->fieldIndex>0)
2698 0 : gf_fprintf(sdump->trace, "attributeName=\"children\" ");
2699 : }
2700 :
2701 :
2702 10 : gf_fprintf(sdump->trace, ">");
2703 10 : if (!is_text) {
2704 6 : gf_fprintf(sdump->trace, "\n");
2705 6 : sdump->indent++;
2706 : }
2707 10 : if (f) {
2708 10 : if (f->new_node) {
2709 8 : gf_dump_svg_element(sdump, f->new_node, com->node, 0);
2710 2 : } else if (f->node_list) {
2711 : GF_ChildNodeItem *list = f->node_list;
2712 80 : while (list) {
2713 78 : gf_dump_svg_element(sdump, list->node, com->node, 0);
2714 78 : list = list->next;
2715 : }
2716 : }
2717 : }
2718 10 : if (!is_text) {
2719 6 : sdump->indent--;
2720 6 : DUMP_IND(sdump);
2721 : }
2722 10 : gf_fprintf(sdump->trace, "</%s%s>\n", lsrns, com_name);
2723 10 : return GF_OK;
2724 : }
2725 :
2726 6 : static GF_Err DumpLSRDelete(GF_SceneDumper *sdump, GF_Command *com)
2727 : {
2728 : char szID[1024];
2729 : GF_CommandField *f;
2730 6 : char *lsrns = sd_get_lsr_namespace(com->in_scene);
2731 6 : DUMP_IND(sdump);
2732 6 : gf_fprintf(sdump->trace, "<%sDelete ref=\"%s\" ", lsrns, lsr_format_node_id(com->node, com->RouteID, szID));
2733 6 : f = (GF_CommandField *) gf_list_get(com->command_fields, 0);
2734 6 : if (f && (f->pos>=0) ) gf_fprintf(sdump->trace, "index=\"%d\" ", f->pos);
2735 6 : gf_fprintf(sdump->trace, "/>\n");
2736 6 : return GF_OK;
2737 : }
2738 : #ifdef GPAC_UNUSED_FUNC
2739 : static GF_Err DumpLSRInsert(GF_SceneDumper *sdump, GF_Command *com)
2740 : {
2741 : return GF_OK;
2742 : }
2743 :
2744 : static GF_Err SD_SetSceneGraph(GF_SceneDumper *sdump, GF_SceneGraph *sg)
2745 : {
2746 : if (sdump) sdump->sg = sg;
2747 : return GF_OK;
2748 : }
2749 :
2750 : static GF_Err DumpLSRClean(GF_SceneDumper *sdump, GF_Command *com)
2751 : {
2752 : return GF_OK;
2753 : }
2754 :
2755 : static GF_Err DumpLSRRestore(GF_SceneDumper *sdump, GF_Command *com)
2756 : {
2757 : return GF_OK;
2758 : }
2759 : static GF_Err DumpLSRSave(GF_SceneDumper *sdump, GF_Command *com)
2760 : {
2761 : return GF_OK;
2762 : }
2763 : #endif /*GPAC_UNUSED_FUNC*/
2764 :
2765 108 : static GF_Err DumpLSRSendEvent(GF_SceneDumper *sdump, GF_Command *com)
2766 : {
2767 : char szID[1024];
2768 108 : char *lsrns = sd_get_lsr_namespace(com->in_scene);
2769 108 : DUMP_IND(sdump);
2770 108 : gf_fprintf(sdump->trace, "<%sSendEvent ref=\"%s\" event=\"%s\"", lsrns,
2771 : lsr_format_node_id(com->node, com->RouteID, szID),
2772 108 : gf_dom_event_get_name(com->send_event_name)
2773 : );
2774 108 : if (com->send_event_name <= GF_EVENT_MOUSEWHEEL)
2775 12 : gf_fprintf(sdump->trace, " pointvalue=\"%g %g\"", FIX2FLT(com->send_event_x), FIX2FLT(com->send_event_y) );
2776 :
2777 108 : switch (com->send_event_name) {
2778 52 : case GF_EVENT_KEYDOWN:
2779 : case GF_EVENT_LONGKEYPRESS:
2780 : case GF_EVENT_REPEAT_KEY:
2781 : case GF_EVENT_SHORT_ACCESSKEY:
2782 52 : if (com->send_event_integer) {
2783 50 : gf_fprintf(sdump->trace, " stringvalue=\"%s\"", gf_dom_get_key_name(com->send_event_integer) );
2784 50 : break;
2785 : }
2786 : default:
2787 58 : if (com->send_event_integer)
2788 6 : gf_fprintf(sdump->trace, " intvalue=\"%d\"", com->send_event_integer);
2789 58 : if (com->send_event_string)
2790 0 : gf_fprintf(sdump->trace, " stringvalue=\"%s\"", com->send_event_string);
2791 : break;
2792 : }
2793 :
2794 108 : gf_fprintf(sdump->trace, "/>\n");
2795 108 : return GF_OK;
2796 : }
2797 4 : static GF_Err DumpLSRActivate(GF_SceneDumper *sdump, GF_Command *com)
2798 : {
2799 : char szID[1024];
2800 4 : char *lsrns = sd_get_lsr_namespace(com->in_scene);
2801 4 : DUMP_IND(sdump);
2802 4 : if (com->tag==GF_SG_LSR_ACTIVATE) {
2803 2 : gf_fprintf(sdump->trace, "<%sActivate ref=\"%s\" />\n", lsrns, lsr_format_node_id(com->node, com->RouteID, szID));
2804 : } else {
2805 2 : gf_fprintf(sdump->trace, "<%sDeactivate ref=\"%s\" />\n", lsrns, lsr_format_node_id(com->node, com->RouteID, szID));
2806 : }
2807 4 : return GF_OK;
2808 : }
2809 :
2810 : #endif
2811 :
2812 : GF_EXPORT
2813 207 : GF_Err gf_sm_dump_command_list(GF_SceneDumper *sdump, GF_List *comList, u32 indent, Bool skip_first_replace)
2814 : {
2815 : GF_Err e;
2816 : u32 i, count;
2817 : u32 prev_ind;
2818 : #ifndef GPAC_DISABLE_VRML
2819 : u32 remain = 0, has_scene_replace = 0;
2820 : #endif
2821 : Bool prev_skip;
2822 :
2823 207 : if (!sdump || !sdump->trace|| !comList || !sdump->sg) return GF_BAD_PARAM;
2824 :
2825 207 : prev_skip = sdump->skip_scene_replace;
2826 207 : sdump->skip_scene_replace = skip_first_replace;
2827 207 : prev_ind = sdump->indent;
2828 207 : sdump->indent = indent;
2829 :
2830 : e = GF_OK;
2831 207 : count = gf_list_count(comList);
2832 854 : for (i=0; i<count; i++) {
2833 654 : GF_Command *com = (GF_Command *) gf_list_get(comList, i);
2834 1308 : if (i
2835 : #ifndef GPAC_DISABLE_VRML
2836 654 : && !remain
2837 : #endif
2838 391 : && (sdump->X3DDump || (sdump->dump_mode==GF_SM_DUMP_VRML))
2839 : ) {
2840 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[Scene Dump] MPEG-4 Commands found, not supported in %s - skipping\n", sdump->X3DDump ? "X3D" : "VRML"));
2841 : break;
2842 : }
2843 : #ifndef GPAC_DISABLE_VRML
2844 654 : if (has_scene_replace && (com->tag != GF_SG_ROUTE_INSERT)) {
2845 : has_scene_replace = 0;
2846 2 : if (sdump->XMLDump) {
2847 2 : sdump->indent--;
2848 2 : EndElement(sdump, "Scene", 1);
2849 2 : sdump->indent--;
2850 2 : EndElement(sdump, "Replace", 1);
2851 : } else {
2852 0 : DUMP_IND(sdump);
2853 0 : gf_fprintf(sdump->trace, "\nAT 0 {\n");
2854 0 : sdump->indent++;
2855 : }
2856 : }
2857 : #endif
2858 :
2859 654 : switch (com->tag) {
2860 : #ifndef GPAC_DISABLE_VRML
2861 : /*insert commands*/
2862 45 : case GF_SG_NODE_INSERT:
2863 45 : e = DumpNodeInsert(sdump, com);
2864 45 : break;
2865 4 : case GF_SG_INDEXED_INSERT:
2866 4 : e = DumpIndexInsert(sdump, com);
2867 4 : break;
2868 63 : case GF_SG_ROUTE_INSERT:
2869 63 : e = DumpRouteInsert(sdump, com, has_scene_replace);
2870 63 : if (remain) remain--;
2871 : break;
2872 : /*delete commands*/
2873 9 : case GF_SG_NODE_DELETE:
2874 9 : e = DumpNodeDelete(sdump, com);
2875 9 : break;
2876 9 : case GF_SG_INDEXED_DELETE:
2877 9 : e = DumpIndexDelete(sdump, com);
2878 9 : break;
2879 9 : case GF_SG_ROUTE_DELETE:
2880 9 : e = DumpRouteDelete(sdump, com);
2881 9 : break;
2882 : /*replace commands*/
2883 45 : case GF_SG_NODE_REPLACE:
2884 45 : e = DumpNodeReplace(sdump, com);
2885 45 : break;
2886 133 : case GF_SG_FIELD_REPLACE:
2887 133 : e = DumpFieldReplace(sdump, com);
2888 133 : break;
2889 27 : case GF_SG_INDEXED_REPLACE:
2890 27 : e = DumpIndexReplace(sdump, com);
2891 27 : break;
2892 9 : case GF_SG_ROUTE_REPLACE:
2893 9 : e = DumpRouteReplace(sdump, com);
2894 9 : break;
2895 18 : case GF_SG_XREPLACE:
2896 18 : e = DumpXReplace(sdump, com);
2897 18 : break;
2898 35 : case GF_SG_SCENE_REPLACE:
2899 : /*we don't support replace scene in conditional*/
2900 : assert(!sdump->current_com_list);
2901 35 : sdump->current_com_list = comList;
2902 35 : e = DumpSceneReplace(sdump, com);
2903 35 : sdump->current_com_list = NULL;
2904 : has_scene_replace = 1;
2905 35 : remain = count - i - 1;
2906 35 : break;
2907 : /*extended commands*/
2908 9 : case GF_SG_PROTO_INSERT:
2909 9 : e = DumpProtoInsert(sdump, com);
2910 9 : break;
2911 9 : case GF_SG_PROTO_DELETE_ALL:
2912 9 : DUMP_IND(sdump);
2913 9 : if (sdump->XMLDump) {
2914 5 : gf_fprintf(sdump->trace, "<Delete extended=\"allProtos\"/>\n");
2915 : } else {
2916 4 : gf_fprintf(sdump->trace, "DELETEPROTO ALL\n");
2917 : }
2918 : e = GF_OK;
2919 : break;
2920 9 : case GF_SG_PROTO_DELETE:
2921 : {
2922 : u32 j;
2923 9 : DUMP_IND(sdump);
2924 9 : if (sdump->XMLDump) {
2925 5 : gf_fprintf(sdump->trace, "<Delete extended=\"protos\" value=\"");
2926 : } else {
2927 4 : gf_fprintf(sdump->trace, "DELETEPROTO [");
2928 : }
2929 9 : for (j=0; j<com->del_proto_list_size; j++) {
2930 9 : if (j) gf_fprintf(sdump->trace, " ");
2931 9 : gf_fprintf(sdump->trace, "%d", com->del_proto_list[j]);
2932 : }
2933 9 : if (sdump->XMLDump) {
2934 5 : gf_fprintf(sdump->trace, "\"/>\n");
2935 : } else {
2936 4 : gf_fprintf(sdump->trace, "]\n");
2937 : }
2938 : e = GF_OK;
2939 : }
2940 : break;
2941 9 : case GF_SG_GLOBAL_QUANTIZER:
2942 9 : e = DumpGlobalQP(sdump, com);
2943 9 : break;
2944 12 : case GF_SG_MULTIPLE_REPLACE:
2945 12 : e = DumpMultipleReplace(sdump, com);
2946 12 : break;
2947 9 : case GF_SG_MULTIPLE_INDEXED_REPLACE:
2948 9 : e = DumpMultipleIndexedReplace(sdump, com);
2949 9 : break;
2950 9 : case GF_SG_NODE_DELETE_EX:
2951 9 : e = DumpNodeDelete(sdump, com);
2952 9 : break;
2953 :
2954 : #endif
2955 :
2956 :
2957 : #ifndef GPAC_DISABLE_SVG
2958 : /*laser commands*/
2959 2 : case GF_SG_LSR_NEW_SCENE:
2960 2 : e = DumpLSRNewScene(sdump, com);
2961 2 : break;
2962 0 : case GF_SG_LSR_ADD:
2963 0 : e = DumpLSRAddReplaceInsert(sdump, com);
2964 0 : break;
2965 : case GF_SG_LSR_CLEAN:
2966 : //e = DumpLSRClean(sdump, com);
2967 : break;
2968 58 : case GF_SG_LSR_REPLACE:
2969 58 : e = DumpLSRAddReplaceInsert(sdump, com);
2970 58 : break;
2971 6 : case GF_SG_LSR_DELETE:
2972 6 : e = DumpLSRDelete(sdump, com);
2973 6 : break;
2974 4 : case GF_SG_LSR_INSERT:
2975 4 : e = DumpLSRAddReplaceInsert(sdump, com);
2976 4 : break;
2977 : case GF_SG_LSR_RESTORE:
2978 : //e = DumpLSRRestore(sdump, com);
2979 : break;
2980 : case GF_SG_LSR_SAVE:
2981 : //e = DumpLSRSave(sdump, com);
2982 : break;
2983 108 : case GF_SG_LSR_SEND_EVENT:
2984 108 : e = DumpLSRSendEvent(sdump, com);
2985 108 : break;
2986 4 : case GF_SG_LSR_ACTIVATE:
2987 : case GF_SG_LSR_DEACTIVATE:
2988 4 : e = DumpLSRActivate(sdump, com);
2989 4 : break;
2990 : #endif
2991 : }
2992 654 : if (e) break;
2993 :
2994 :
2995 647 : if (sdump->skip_scene_replace
2996 : #ifndef GPAC_DISABLE_VRML
2997 44 : && !has_scene_replace
2998 : #endif
2999 : ) {
3000 2 : sdump->skip_scene_replace = 0;
3001 2 : if (!sdump->XMLDump && (i+1<count)) {
3002 0 : DUMP_IND(sdump);
3003 0 : gf_fprintf(sdump->trace, "\nAT 0 {\n");
3004 0 : sdump->indent++;
3005 : }
3006 : }
3007 : }
3008 :
3009 : #ifndef GPAC_DISABLE_VRML
3010 207 : if (remain && !sdump->XMLDump) {
3011 0 : sdump->indent--;
3012 0 : DUMP_IND(sdump);
3013 0 : gf_fprintf(sdump->trace, "}\n");
3014 : }
3015 : #endif
3016 :
3017 207 : if (has_scene_replace && sdump->XMLDump) {
3018 17 : sdump->indent--;
3019 17 : if (!sdump->X3DDump) {
3020 17 : EndElement(sdump, "Scene", 1);
3021 17 : sdump->indent--;
3022 17 : EndElement(sdump, "Replace", 1);
3023 : }
3024 : }
3025 :
3026 207 : sdump->indent = prev_ind;
3027 207 : sdump->skip_scene_replace = prev_skip;
3028 207 : return e;
3029 : }
3030 :
3031 : #ifndef GPAC_DISABLE_SVG
3032 382 : void gf_dump_svg_element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool is_root)
3033 : {
3034 : GF_ChildNodeItem *list;
3035 : char attName[100], *attValue;
3036 : u32 nID;
3037 : SVG_Element *svg = (SVG_Element *)n;
3038 : GF_FieldInfo info;
3039 : SVGAttribute *att;
3040 : u32 tag, ns;
3041 696 : if (!n) return;
3042 :
3043 382 : nID = gf_node_get_id(n);
3044 382 : tag = n->sgprivate->tag;
3045 : /*remove undef listener/handlers*/
3046 382 : if (!nID) {
3047 308 : switch (tag) {
3048 : case TAG_SVG_listener:
3049 : if ((0) && gf_node_get_attribute_by_tag(n, TAG_XMLEV_ATT_handler, 0, 0, &info)==GF_OK) {
3050 : if (((XMLRI*)info.far_ptr)->target && !gf_node_get_id(((XMLRI*)info.far_ptr)->target) )
3051 : return;
3052 : }
3053 : break;
3054 0 : case TAG_SVG_handler:
3055 : /*this handler was not declared in the graph*/
3056 0 : if (!n->sgprivate->parents || (n->sgprivate->parents->node != parent))
3057 : return;
3058 : break;
3059 28 : case TAG_DOMText:
3060 : {
3061 : GF_DOMText *txt = (GF_DOMText *)n;
3062 28 : if (txt->textContent) {
3063 28 : if ((txt->type==GF_DOM_TEXT_CDATA)
3064 28 : || (parent && (parent->sgprivate->tag == TAG_SVG_script))
3065 28 : || (parent && (parent->sgprivate->tag == TAG_SVG_handler))
3066 : ) {
3067 0 : gf_fprintf(sdump->trace, "<![CDATA[");
3068 0 : gf_fprintf(sdump->trace, "%s", txt->textContent);
3069 0 : gf_fprintf(sdump->trace, "]]>");
3070 28 : } else if (txt->type==GF_DOM_TEXT_REGULAR) {
3071 28 : scene_dump_utf_string(sdump, 0, txt->textContent);
3072 : }
3073 : }
3074 : }
3075 : return;
3076 : }
3077 : }
3078 :
3079 354 : if (!sdump->in_text) {
3080 354 : DUMP_IND(sdump);
3081 : }
3082 :
3083 : /*register all namespaces specified on this element */
3084 354 : gf_xml_push_namespaces((GF_DOMNode *)n);
3085 :
3086 354 : gf_fprintf(sdump->trace, "<%s", gf_node_get_class_name(n));
3087 354 : ns = gf_xml_get_element_namespace(n);
3088 :
3089 354 : if (nID) {
3090 : char attID[100];
3091 74 : gf_fprintf(sdump->trace, " id=\"%s\"", lsr_format_node_id(n, 0, attID));
3092 : }
3093 354 : att = svg->attributes;
3094 1966 : while (att) {
3095 1258 : if (att->data_type==SVG_ID_datatype) {
3096 0 : att = att->next;
3097 0 : continue;
3098 : }
3099 :
3100 1258 : info.fieldIndex = att->tag;
3101 1258 : info.fieldType = att->data_type;
3102 1258 : if (att->tag==TAG_DOM_ATT_any) {
3103 0 : u32 att_ns = ((GF_DOMFullAttribute*)att)->xmlns;
3104 0 : info.name = ((GF_DOMFullAttribute*)att)->name;
3105 0 : if ((att_ns != ns) && strncmp(info.name, "xmlns", 5)) {
3106 0 : sprintf(attName, "%s:%s", gf_sg_get_namespace_qname(gf_node_get_graph(n), att_ns), ((GF_DOMFullAttribute*)att)->name);
3107 0 : info.name = attName;
3108 : }
3109 : } else {
3110 1258 : info.name = gf_svg_get_attribute_name(n, att->tag);
3111 : }
3112 :
3113 1258 : if (att->data_type==XMLRI_datatype) {
3114 116 : XMLRI *xlink = (XMLRI *)att->data;
3115 116 : if (xlink->type==XMLRI_ELEMENTID) {
3116 94 : if (!xlink->target || !gf_node_get_id((GF_Node*)xlink->target) ) {
3117 28 : att = att->next;
3118 28 : continue;
3119 : }
3120 66 : if (parent && (parent == (GF_Node *) xlink->target)) {
3121 30 : att = att->next;
3122 30 : continue;
3123 : }
3124 : }
3125 22 : else if (xlink->type==XMLRI_STREAMID) {
3126 2 : gf_fprintf(sdump->trace, " %s=\"#stream%d\"", info.name, xlink->lsr_stream_id);
3127 2 : att = att->next;
3128 2 : continue;
3129 : } else {
3130 20 : gf_fprintf(sdump->trace, " %s=\"%s\"", info.name, xlink->string);
3131 20 : att = att->next;
3132 20 : continue;
3133 : }
3134 : }
3135 1178 : info.far_ptr = att->data;
3136 1178 : attValue = gf_svg_dump_attribute((GF_Node*)svg, &info);
3137 1178 : if (attValue) {
3138 1178 : if (/*strcmp(info.name, "xmlns") &&*/ (info.fieldType = (u32) strlen(attValue)))
3139 1064 : gf_fprintf(sdump->trace, " %s=\"%s\"", info.name, attValue);
3140 1178 : gf_free(attValue);
3141 : }
3142 1178 : att = att->next;
3143 : }
3144 :
3145 354 : gf_dom_event_dump_listeners(n, sdump->trace);
3146 354 : if (svg->children) {
3147 72 : gf_fprintf(sdump->trace, ">");
3148 : } else {
3149 282 : gf_fprintf(sdump->trace, "/>");
3150 282 : return;
3151 : }
3152 :
3153 72 : if (n->sgprivate->tag==TAG_LSR_conditional) {
3154 4 : GF_DOMUpdates *up = svg->children ? (GF_DOMUpdates *)svg->children->node : NULL;
3155 4 : sdump->indent++;
3156 4 : if (up && (up->sgprivate->tag==TAG_DOMUpdates)) {
3157 4 : if (gf_list_count(up->updates)) {
3158 2 : gf_fprintf(sdump->trace, "\n");
3159 2 : gf_sm_dump_command_list(sdump, up->updates, sdump->indent, 0);
3160 2 : } else if (up->data) {
3161 0 : gf_fprintf(sdump->trace, "<!-- WARNING: LASeR scripts cannot be dumped at run-time -->\n");
3162 : }
3163 : }
3164 4 : sdump->indent--;
3165 4 : DUMP_IND(sdump);
3166 4 : gf_fprintf(sdump->trace, "</%s>\n", gf_node_get_class_name(n));
3167 4 : return;
3168 : }
3169 :
3170 68 : if (tag==TAG_SVG_text || tag==TAG_SVG_textArea) sdump->in_text = 1;
3171 68 : sdump->indent++;
3172 68 : list = svg->children;
3173 430 : while (list) {
3174 294 : if (!sdump->in_text) gf_fprintf(sdump->trace, "\n");
3175 294 : gf_dump_svg_element(sdump, list->node, n, 0);
3176 294 : list = list->next;
3177 : }
3178 68 : if (!sdump->in_text) gf_fprintf(sdump->trace, "\n");
3179 68 : sdump->indent--;
3180 68 : if (!sdump->in_text) DUMP_IND(sdump);
3181 68 : gf_fprintf(sdump->trace, "</%s>", gf_node_get_class_name(n));
3182 68 : if (tag==TAG_SVG_text || tag==TAG_SVG_textArea) sdump->in_text = 0;
3183 : /*removes all namespaces specified on this element */
3184 68 : gf_xml_pop_namespaces((GF_DOMNode *)n);
3185 : }
3186 : #endif
3187 :
3188 6 : static void gf_sm_dump_saf_hdr(GF_SceneDumper *dumper, char *unit_name, u64 au_time, Bool is_rap)
3189 : {
3190 6 : gf_fprintf(dumper->trace, "<saf:%s", unit_name);
3191 6 : if (au_time) gf_fprintf(dumper->trace, " time=\""LLD"\"", au_time);
3192 6 : if (is_rap) gf_fprintf(dumper->trace, " rap=\"true\"");
3193 6 : gf_fprintf(dumper->trace, ">\n");
3194 6 : }
3195 :
3196 1 : static void dump_od_to_saf(GF_SceneDumper *dumper, GF_AUContext *au, u32 indent)
3197 : {
3198 : u32 i, count;
3199 :
3200 1 : count = gf_list_count(au->commands);
3201 1 : for (i=0; i<count; i++) {
3202 : u32 j, c2;
3203 1 : GF_ODUpdate *com = (GF_ODUpdate *)gf_list_get(au->commands, i);
3204 1 : if (com->tag != GF_ODF_OD_UPDATE_TAG) continue;
3205 :
3206 1 : c2 = gf_list_count(com->objectDescriptors);
3207 1 : for (j=0; j<c2; j++) {
3208 1 : GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)gf_list_get(com->objectDescriptors, j);
3209 1 : GF_ESD *esd = (GF_ESD *) gf_list_get(od->ESDescriptors, 0);
3210 : GF_MuxInfo *mux;
3211 1 : if (!esd) {
3212 1 : if (od->URLString) {
3213 1 : gf_fprintf(dumper->trace, "<saf:RemoteStreamHeader streamID=\"stream%d\" url=\"%s\"", au->owner->ESID, od->URLString);
3214 1 : if (au->timing) gf_fprintf(dumper->trace, " time=\""LLD"\"", au->timing);
3215 1 : gf_fprintf(dumper->trace, "/>\n");
3216 : }
3217 1 : continue;
3218 : }
3219 0 : mux = (GF_MuxInfo *)gf_list_get(esd->extensionDescriptors, 0);
3220 0 : if (!mux || (mux->tag!=GF_ODF_MUXINFO_TAG)) mux = NULL;
3221 :
3222 :
3223 0 : gf_fprintf(dumper->trace, "<saf:mediaHeader streamID=\"stream%d\"", esd->ESID);
3224 0 : gf_fprintf(dumper->trace, " streamType=\"%d\" objectTypeIndication=\"%d\" timeStampResolution=\"%d\"", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication, au->owner->timeScale);
3225 0 : if (au->timing) gf_fprintf(dumper->trace, " time=\""LLD"\"", au->timing);
3226 0 : if (mux && mux->file_name) gf_fprintf(dumper->trace, " source=\"%s\"", mux->file_name);
3227 0 : gf_fprintf(dumper->trace, "/>\n");
3228 : }
3229 :
3230 :
3231 : }
3232 1 : gf_fprintf(dumper->trace, "</saf:mediaUnit>\n");
3233 1 : }
3234 :
3235 : #ifndef GPAC_DISABLE_SVG
3236 0 : static GF_Err SD_DumpDOMElement(GF_SceneDumper *sdump, GF_DOMFullNode *node)
3237 : {
3238 : const char *ns;
3239 : u32 child_type = 0;
3240 : GF_DOMFullAttribute *att;
3241 : GF_ChildNodeItem *child;
3242 : GF_DOMText *txt;
3243 0 : ns = gf_sg_get_namespace_qname(node->sgprivate->scenegraph, node->ns);
3244 :
3245 0 : DUMP_IND(sdump);
3246 0 : if (ns) gf_fprintf(sdump->trace, "<%s:%s", ns, node->name);
3247 0 : else gf_fprintf(sdump->trace, "<%s", node->name);
3248 0 : att = (GF_DOMFullAttribute *)node->attributes;
3249 0 : while (att) {
3250 0 : gf_fprintf(sdump->trace, " %s=\"%s\"", att->name, (char *) att->data);
3251 0 : att = (GF_DOMFullAttribute *)att->next;
3252 : }
3253 0 : if (!node->children) {
3254 0 : gf_fprintf(sdump->trace, "/>\n");
3255 0 : return GF_OK;
3256 : }
3257 0 : gf_fprintf(sdump->trace, ">");
3258 0 : sdump->indent++;
3259 0 : child = node->children;
3260 0 : while (child) {
3261 0 : switch(child->node->sgprivate->tag) {
3262 0 : case TAG_DOMFullNode:
3263 0 : if (!child_type) gf_fprintf(sdump->trace, "\n");
3264 : child_type = 1;
3265 0 : SD_DumpDOMElement(sdump, (GF_DOMFullNode*)child->node);
3266 0 : break;
3267 0 : case TAG_DOMText:
3268 : child_type = 2;
3269 : txt = (GF_DOMText *)child->node;
3270 0 : if (txt->type==GF_DOM_TEXT_REGULAR) {
3271 0 : scene_dump_utf_string(sdump, 0, txt->textContent);
3272 0 : } else if (txt->type==GF_DOM_TEXT_CDATA) {
3273 0 : gf_fprintf(sdump->trace, "<![CDATA[");
3274 0 : gf_fprintf(sdump->trace, "%s", txt->textContent);
3275 0 : gf_fprintf(sdump->trace, "]]>");
3276 : }
3277 : break;
3278 : }
3279 0 : child = child->next;
3280 : }
3281 :
3282 0 : sdump->indent--;
3283 0 : if (child_type!=2) {
3284 0 : DUMP_IND(sdump);
3285 : }
3286 :
3287 0 : if (ns) gf_fprintf(sdump->trace, "</%s:%s>\n", ns, node->name);
3288 0 : else gf_fprintf(sdump->trace, "</%s>\n", node->name);
3289 :
3290 : return GF_OK;
3291 : }
3292 : #endif
3293 :
3294 : GF_EXPORT
3295 2 : GF_Err gf_sm_dump_graph(GF_SceneDumper *sdump, Bool skip_proto, Bool skip_routes)
3296 : {
3297 : u32 tag;
3298 2 : if (!sdump->trace || !sdump->sg || !sdump->sg->RootNode) return GF_BAD_PARAM;
3299 :
3300 2 : tag = sdump->sg->RootNode->sgprivate->tag;
3301 :
3302 2 : if (tag<=GF_NODE_RANGE_LAST_X3D) {
3303 2 : gf_dump_setup(sdump, NULL);
3304 :
3305 2 : if (sdump->XMLDump) {
3306 0 : StartElement(sdump, "Scene");
3307 0 : EndElementHeader(sdump, 1);
3308 0 : sdump->indent++;
3309 : }
3310 :
3311 : #ifndef GPAC_DISABLE_VRML
3312 : GF_Err e;
3313 2 : if (!skip_proto) {
3314 2 : e = DumpProtos(sdump, sdump->sg->protos);
3315 2 : if (e) return e;
3316 : }
3317 :
3318 2 : if (sdump->X3DDump) {
3319 0 : GF_ChildNodeItem *list = ((GF_ParentNode *)sdump->sg->RootNode)->children;
3320 0 : while (list) {
3321 0 : gf_dump_vrml_node(sdump, list->node, 0, NULL);
3322 0 : list = list->next;
3323 : }
3324 : } else {
3325 2 : gf_dump_vrml_node(sdump, sdump->sg->RootNode, 0, NULL);
3326 : }
3327 2 : if (!sdump->XMLDump) gf_fprintf(sdump->trace, "\n\n");
3328 2 : if (!skip_routes) {
3329 : GF_Route *r;
3330 2 : u32 i=0;
3331 4 : while ((r = (GF_Route*)gf_list_enum(sdump->sg->Routes, &i))) {
3332 0 : if (r->IS_route || (r->graph!=sdump->sg)) continue;
3333 0 : e = gf_dump_vrml_route(sdump, r, 0);
3334 0 : if (e) return e;
3335 : }
3336 : }
3337 2 : if (sdump->XMLDump) {
3338 0 : sdump->indent--;
3339 0 : EndElement(sdump, "Scene", 1);
3340 : }
3341 : #endif /*GPAC_DISABLE_VRML*/
3342 :
3343 2 : gf_dump_finalize(sdump, NULL);
3344 2 : return GF_OK;
3345 : }
3346 : #ifndef GPAC_DISABLE_SVG
3347 0 : else if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) {
3348 0 : sdump->dump_mode = GF_SM_DUMP_SVG;
3349 0 : gf_dump_setup(sdump, NULL);
3350 0 : gf_dump_svg_element(sdump, sdump->sg->RootNode, NULL, 1);
3351 0 : return GF_OK;
3352 : }
3353 0 : else if (tag==TAG_DOMFullNode) {
3354 0 : sdump->dump_mode = GF_SM_DUMP_XML;
3355 0 : gf_dump_setup(sdump, NULL);
3356 0 : SD_DumpDOMElement(sdump, (GF_DOMFullNode*)sdump->sg->RootNode);
3357 : }
3358 : #endif
3359 :
3360 : return GF_OK;
3361 : }
3362 :
3363 :
3364 :
3365 :
3366 194 : static void ReorderAUContext(GF_List *sample_list, GF_AUContext *au, Bool lsr_dump)
3367 : {
3368 : u64 autime, time;
3369 : u32 i;
3370 : Bool has_base;
3371 : GF_AUContext *ptr;
3372 :
3373 : /*
3374 : this happens when converting from bt to xmt
3375 : NOTE: Comment is wrong? this happens when just loading BT
3376 : */
3377 194 : if (!au->timing_sec) {
3378 69 : au->timing_sec = (Double) (s64) au->timing;
3379 : /* Hack to avoid timescale=0 which happens when loading a BT with no SLConfig*/
3380 69 : if (!au->owner->timeScale) au->owner->timeScale = 1000;
3381 69 : au->timing_sec /= au->owner->timeScale;
3382 : }
3383 : /*this happens when converting from xmt to bt*/
3384 194 : if (!au->timing) {
3385 : assert(au->owner->timeScale);
3386 51 : au->timing = (u64) (au->timing_sec * au->owner->timeScale);
3387 : }
3388 :
3389 194 : autime = au->timing + au->owner->imp_exp_time;
3390 : has_base = 0;
3391 194 : i=0;
3392 1412 : while ((ptr = (GF_AUContext*)gf_list_enum(sample_list, &i))) {
3393 1065 : time = ptr->timing + ptr->owner->imp_exp_time;
3394 1065 : if (
3395 : /*time ordered*/
3396 : (time > autime)
3397 : /*set bifs first for first AU*/
3398 1025 : || (!has_base && (time == autime) && (ptr->owner->streamType < au->owner->streamType) )
3399 : /*set OD first for laser*/
3400 1024 : || (lsr_dump && (au->owner->streamType==GF_STREAM_OD))
3401 : ) {
3402 41 : gf_list_insert(sample_list, au, i-1);
3403 41 : return;
3404 : }
3405 :
3406 : has_base = 0;
3407 1024 : if ( (ptr->owner->streamType == au->owner->streamType) && (time == autime) ) has_base = 1;
3408 : }
3409 153 : gf_list_add(sample_list, au);
3410 : }
3411 :
3412 :
3413 : GF_EXPORT
3414 17 : GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, Bool is_final_name, GF_SceneDumpFormat dump_mode)
3415 : {
3416 : GF_Err e;
3417 : GF_List *sample_list;
3418 : Bool first_par;
3419 : u32 i, j, indent, num_scene, num_od, first_bifs, num_tracks;
3420 : Double time;
3421 : GF_SceneDumper *dumper;
3422 : GF_StreamContext *sc;
3423 : GF_AUContext *au;
3424 : Bool no_root_found = 1;
3425 :
3426 17 : sample_list = gf_list_new();
3427 :
3428 : num_scene = num_od = 0;
3429 : num_tracks = 0;
3430 : indent = 0;
3431 17 : dumper = gf_sm_dumper_new(ctx->scene_graph, rad_name, is_final_name, ' ', dump_mode);
3432 : e = GF_OK;
3433 : /*configure all systems streams we're dumping*/
3434 17 : i=0;
3435 82 : while ((sc = (GF_StreamContext*)gf_list_enum(ctx->streams, &i))) {
3436 :
3437 48 : switch (sc->streamType) {
3438 18 : case GF_STREAM_SCENE:
3439 18 : num_scene ++;
3440 : num_tracks ++;
3441 18 : break;
3442 16 : case GF_STREAM_OD:
3443 16 : num_od ++;
3444 : num_tracks ++;
3445 16 : break;
3446 14 : default:
3447 14 : continue;
3448 : }
3449 :
3450 34 : j=0;
3451 262 : while ((au = (GF_AUContext*)gf_list_enum(sc->AUs, &j))) {
3452 194 : ReorderAUContext(sample_list, au, dumper->LSRDump);
3453 194 : if (dumper->dump_mode==GF_SM_DUMP_SVG) break;
3454 : }
3455 34 : if (dumper->dump_mode==GF_SM_DUMP_SVG) break;
3456 : }
3457 17 : first_bifs = (num_scene==1) ? 1 : 0;
3458 17 : num_scene = (num_scene>1) ? 1 : 0;
3459 17 : num_od = (num_od>1) ? 1 : 0;
3460 :
3461 17 : gf_dump_setup(dumper, (GF_Descriptor *) ctx->root_od);
3462 :
3463 : #ifndef GPAC_DISABLE_SVG
3464 17 : if (dumper->dump_mode==GF_SM_DUMP_SVG) {
3465 0 : au = (GF_AUContext*)gf_list_get(sample_list, 0);
3466 : GF_Command *com = NULL;
3467 0 : if (au) com = (GF_Command*)gf_list_get(au->commands, 0);
3468 0 : if (!au) {
3469 0 : gf_dump_svg_element(dumper, dumper->sg->RootNode, NULL, 1);
3470 0 : } else if (!com || (com->tag!=GF_SG_LSR_NEW_SCENE) || !com->node) {
3471 : e = GF_NOT_SUPPORTED;
3472 : } else {
3473 0 : gf_dump_svg_element(dumper, com->node, NULL, 1);
3474 : }
3475 0 : gf_dump_finalize(dumper, (GF_Descriptor *) ctx->root_od);
3476 0 : gf_sm_dumper_del(dumper);
3477 0 : gf_list_del(sample_list);
3478 0 : return e;
3479 : }
3480 : #endif
3481 :
3482 17 : time = dumper->LSRDump ? -1 : 0;
3483 : first_par = 0;
3484 :
3485 211 : while (gf_list_count(sample_list)) {
3486 194 : au = (GF_AUContext*)gf_list_get(sample_list, 0);
3487 194 : gf_list_rem(sample_list, 0);
3488 :
3489 194 : if (!dumper->XMLDump) {
3490 :
3491 86 : if (!first_bifs || (au->owner->streamType != GF_STREAM_SCENE) ) {
3492 83 : if (au->flags & GF_SM_AU_RAP) gf_fprintf(dumper->trace, "RAP ");
3493 83 : gf_fprintf(dumper->trace, "AT "LLD" ", au->timing);
3494 83 : if ( (au->owner->streamType==GF_STREAM_OD && num_od) || (au->owner->streamType==GF_STREAM_SCENE && num_scene)) {
3495 2 : gf_fprintf(dumper->trace, "IN %d ", au->owner->ESID);
3496 : }
3497 83 : gf_fprintf(dumper->trace, "{\n");
3498 83 : indent++;
3499 : }
3500 :
3501 86 : switch (au->owner->streamType) {
3502 21 : case GF_STREAM_OD:
3503 21 : if (dumper->LSRDump) {
3504 0 : dump_od_to_saf(dumper, au, indent);
3505 : } else {
3506 : #ifndef GPAC_DISABLE_OD_DUMP
3507 21 : e = gf_odf_dump_com_list(au->commands, dumper->trace, indent+1, 0);
3508 : #endif
3509 : }
3510 : break;
3511 65 : case GF_STREAM_SCENE:
3512 65 : e = gf_sm_dump_command_list(dumper, au->commands, indent, first_bifs);
3513 65 : break;
3514 : }
3515 86 : if (first_bifs) {
3516 : first_bifs = 0;
3517 7 : gf_fprintf(dumper->trace, "\n");
3518 :
3519 : } else {
3520 79 : indent--;
3521 79 : gf_fprintf(dumper->trace, "}\n\n");
3522 : }
3523 : }
3524 : else {
3525 108 : if (dumper->LSRDump) {
3526 : /* if (time != au->timing_sec) {
3527 : time = au->timing_sec;
3528 : }
3529 : */
3530 101 : } else if (!time && !num_scene && first_bifs) {
3531 89 : } else if (num_scene || num_od) {
3532 0 : if (!first_par) {
3533 : first_par = 1;
3534 0 : indent += 1;
3535 : } else {
3536 0 : gf_fprintf(dumper->trace, " </par>\n");
3537 : }
3538 0 : gf_fprintf(dumper->trace, " <par begin=\"%g\" atES_ID=\"es%d\" isRAP=\"%s\">\n", au->timing_sec, au->owner->ESID, (au->flags & GF_SM_AU_RAP) ? "yes" : "no");
3539 89 : } else if (au->timing_sec>time) {
3540 82 : if (!first_par) {
3541 : first_par = 1;
3542 5 : indent += 1;
3543 : } else {
3544 77 : gf_fprintf(dumper->trace, " </par>\n");
3545 : }
3546 82 : gf_fprintf(dumper->trace, "<par begin=\"%g\">\n", au->timing_sec);
3547 : }
3548 108 : switch (au->owner->streamType) {
3549 25 : case GF_STREAM_OD:
3550 25 : if (dumper->LSRDump) {
3551 1 : dump_od_to_saf(dumper, au, indent+1);
3552 : } else {
3553 : #ifndef GPAC_DISABLE_OD_DUMP
3554 24 : e = gf_odf_dump_com_list(au->commands, dumper->trace, indent+1, 1);
3555 : #endif
3556 : }
3557 : break;
3558 83 : case GF_STREAM_SCENE:
3559 83 : if (gf_list_count(au->commands)) {
3560 83 : if (dumper->LSRDump)
3561 6 : gf_sm_dump_saf_hdr(dumper, "sceneUnit", au->timing, au->flags & GF_SM_AU_RAP);
3562 :
3563 83 : e = gf_sm_dump_command_list(dumper, au->commands, indent+1, first_bifs);
3564 : first_bifs = 0;
3565 : no_root_found = 0;
3566 :
3567 83 : if (dumper->LSRDump)
3568 6 : gf_fprintf(dumper->trace, "</saf:sceneUnit>\n");
3569 : }
3570 : break;
3571 : }
3572 108 : time = au->timing_sec;
3573 : }
3574 194 : if (dumper->X3DDump || (dumper->dump_mode==GF_SM_DUMP_VRML)) break;
3575 : }
3576 :
3577 : #ifndef GPAC_DISABLE_VRML
3578 17 : if (no_root_found && ctx->scene_graph->RootNode) {
3579 : GF_Route *r;
3580 0 : DumpProtos(dumper, ctx->scene_graph->protos);
3581 0 : gf_dump_vrml_node(dumper, ctx->scene_graph->RootNode, 0, NULL);
3582 0 : i=0;
3583 0 : gf_fprintf(dumper->trace, "\n");
3584 0 : while ((r = (GF_Route*)gf_list_enum(dumper->sg->Routes, &i))) {
3585 0 : if (r->IS_route || (r->graph!=dumper->sg)) continue;
3586 0 : e = gf_dump_vrml_route(dumper, r, 0);
3587 0 : if (e) return e;
3588 : }
3589 : }
3590 : #endif
3591 :
3592 :
3593 : /*close command*/
3594 17 : if (!dumper->X3DDump && first_par) gf_fprintf(dumper->trace, " </par>\n");
3595 :
3596 17 : if (gf_list_count(sample_list) && (dumper->X3DDump || (dumper->dump_mode==GF_SM_DUMP_VRML)) ) {
3597 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[Scene Dump] MPEG-4 Commands found, not supported in %s - skipping\n", dumper->X3DDump ? "X3D" : "VRML"));
3598 : }
3599 :
3600 17 : gf_dump_finalize(dumper, (GF_Descriptor *) ctx->root_od);
3601 17 : gf_sm_dumper_del(dumper);
3602 17 : gf_list_del(sample_list);
3603 17 : return e;
3604 : }
3605 :
3606 : #endif /*GPAC_DISABLE_SCENE_DUMP*/
|