Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2005-2019
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / LASeR codec 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/internal/laser_dev.h>
27 : #include <gpac/internal/scenegraph_dev.h>
28 : #include <gpac/bitstream.h>
29 : #include <gpac/events.h>
30 :
31 : #ifndef GPAC_DISABLE_LASER
32 :
33 :
34 : #define GF_LSR_READ_INT(_codec, _val, _nbBits, _str) {\
35 : (_val) = gf_bs_read_int(_codec->bs, _nbBits); \
36 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", _str, _nbBits, _val)); \
37 : }\
38 :
39 :
40 : static void lsr_read_group_content(GF_LASeRCodec *lsr, GF_Node *elt, Bool skip_object_content);
41 : static void lsr_read_group_content_post_init(GF_LASeRCodec *lsr, SVG_Element *elt, Bool skip_init);
42 : static GF_Err lsr_read_command_list(GF_LASeRCodec *lsr, GF_List *comList, SVG_Element *cond, Bool first_imp);
43 : static GF_Err lsr_decode_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list);
44 : static void lsr_read_path_type(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_PathData *path, const char *name);
45 : static void lsr_read_point_sequence(GF_LASeRCodec *lsr, GF_List *pts, const char *name);
46 : static Bool lsr_setup_smil_anim(GF_LASeRCodec *lsr, SVG_Element *anim, SVG_Element *anim_parent);
47 :
48 : GF_EXPORT
49 19 : GF_LASeRCodec *gf_laser_decoder_new(GF_SceneGraph *graph)
50 : {
51 : GF_LASeRCodec *tmp;
52 19 : GF_SAFEALLOC(tmp, GF_LASeRCodec);
53 19 : if (!tmp) return NULL;
54 19 : tmp->streamInfo = gf_list_new();
55 19 : tmp->font_table = gf_list_new();
56 19 : tmp->deferred_hrefs = gf_list_new();
57 19 : tmp->deferred_listeners = gf_list_new();
58 19 : tmp->deferred_anims = gf_list_new();
59 19 : tmp->unresolved_commands = gf_list_new();
60 19 : tmp->sg = graph;
61 19 : return tmp;
62 : }
63 :
64 : GF_EXPORT
65 19 : void gf_laser_decoder_del(GF_LASeRCodec *codec)
66 : {
67 : /*destroy all config*/
68 41 : while (gf_list_count(codec->streamInfo)) {
69 3 : LASeRStreamInfo *p = (LASeRStreamInfo *)gf_list_last(codec->streamInfo);
70 3 : gf_free(p);
71 3 : gf_list_rem_last(codec->streamInfo);
72 : }
73 19 : gf_list_del(codec->streamInfo);
74 19 : if (codec->col_table) gf_free(codec->col_table);
75 25 : while (gf_list_count(codec->font_table)) {
76 6 : char *ft = (char *)gf_list_last(codec->font_table);
77 6 : gf_free(ft);
78 6 : gf_list_rem_last(codec->font_table);
79 : }
80 19 : gf_list_del(codec->font_table);
81 : #if 0
82 : while (gf_list_count(codec->deferred_hrefs)) {
83 : XMLRI *iri = (XMLRI *)gf_list_last(codec->deferred_hrefs);
84 : gf_list_rem_last(codec->deferred_hrefs);
85 : if (iri->string) gf_free(iri->string);
86 : iri->string = NULL;
87 : }
88 : #endif
89 19 : gf_list_del(codec->deferred_hrefs);
90 19 : gf_list_del(codec->deferred_anims);
91 19 : gf_list_del(codec->deferred_listeners);
92 19 : gf_list_del(codec->unresolved_commands);
93 19 : gf_free(codec);
94 19 : }
95 :
96 12 : static LASeRStreamInfo *lsr_get_stream(GF_LASeRCodec *codec, u16 ESID)
97 : {
98 12 : u32 i=0;
99 : LASeRStreamInfo *ptr;
100 24 : while ((ptr = (LASeRStreamInfo *)gf_list_enum(codec->streamInfo, &i))) {
101 9 : if (!ESID || (ptr->ESID==ESID)) return ptr;
102 : }
103 : return NULL;
104 : }
105 :
106 :
107 : GF_EXPORT
108 3 : GF_Err gf_laser_decoder_configure_stream(GF_LASeRCodec *codec, u16 ESID, u8 *dsi, u32 dsi_len)
109 : {
110 : LASeRStreamInfo *info;
111 : GF_BitStream *bs;
112 3 : if (lsr_get_stream(codec, ESID) != NULL) return GF_BAD_PARAM;
113 3 : GF_SAFEALLOC(info, LASeRStreamInfo);
114 3 : if (!info) return GF_OUT_OF_MEM;
115 3 : info->ESID = ESID;
116 3 : bs = gf_bs_new(dsi, dsi_len, GF_BITSTREAM_READ);
117 :
118 3 : info->cfg.profile = gf_bs_read_int(bs, 8);
119 3 : info->cfg.level = gf_bs_read_int(bs, 8);
120 3 : /*info->cfg.reserved = */ gf_bs_read_int(bs, 3);
121 3 : info->cfg.pointsCodec = gf_bs_read_int(bs, 2);
122 3 : info->cfg.pathComponents = gf_bs_read_int(bs, 4);
123 3 : info->cfg.fullRequestHost = gf_bs_read_int(bs, 1);
124 3 : if (gf_bs_read_int(bs, 1)) {
125 0 : info->cfg.time_resolution = gf_bs_read_int(bs, 16);
126 : } else {
127 3 : info->cfg.time_resolution = 1000;
128 : }
129 3 : info->cfg.colorComponentBits = gf_bs_read_int(bs, 4);
130 3 : info->cfg.colorComponentBits += 1;
131 3 : info->cfg.resolution = gf_bs_read_int(bs, 4);
132 3 : if (info->cfg.resolution>7) info->cfg.resolution -= 16;
133 3 : info->cfg.coord_bits = gf_bs_read_int(bs, 5);
134 3 : info->cfg.scale_bits_minus_coord_bits = gf_bs_read_int(bs, 4);
135 3 : info->cfg.newSceneIndicator = gf_bs_read_int(bs, 1);
136 3 : /*reserved*/ gf_bs_read_int(bs, 3);
137 3 : info->cfg.extensionIDBits = gf_bs_read_int(bs, 4);
138 : /*we ignore the rest*/
139 3 : gf_list_add(codec->streamInfo, info);
140 3 : gf_bs_del(bs);
141 3 : return GF_OK;
142 : }
143 :
144 : GF_EXPORT
145 1 : GF_Err gf_laser_decoder_remove_stream(GF_LASeRCodec *codec, u16 ESID)
146 : {
147 : u32 i, count;
148 1 : count = gf_list_count(codec->streamInfo);
149 1 : for (i=0; i<count; i++) {
150 0 : LASeRStreamInfo *ptr = (LASeRStreamInfo *) gf_list_get(codec->streamInfo, i);
151 0 : if (ptr->ESID==ESID) {
152 0 : gf_free(ptr);
153 0 : gf_list_rem(codec->streamInfo, i);
154 0 : return GF_OK;
155 : }
156 : }
157 : return GF_BAD_PARAM;
158 : }
159 :
160 :
161 : void gf_bs_set_eos_callback(GF_BitStream *bs, void (*EndOfStream)(void *par), void *par);
162 :
163 0 : void lsr_end_of_stream(void *co)
164 : {
165 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[LASeR] memory overread - corrupted decoding\n"));
166 0 : ((GF_LASeRCodec *) co)->last_error = GF_NON_COMPLIANT_BITSTREAM;
167 0 : }
168 :
169 : GF_EXPORT
170 1 : Bool gf_laser_decode_has_conditionnals(GF_LASeRCodec *codec)
171 : {
172 1 : return codec && codec->has_conditionnals ? GF_TRUE : GF_FALSE;
173 : }
174 :
175 : GF_EXPORT
176 3 : GF_Err gf_laser_decode_au(GF_LASeRCodec *codec, u16 ESID, const u8 *data, u32 data_len)
177 : {
178 : GF_Err e;
179 3 : if (!codec || !data || !data_len) return GF_BAD_PARAM;
180 :
181 3 : codec->info = lsr_get_stream(codec, ESID);
182 3 : if (!codec->info) return GF_BAD_PARAM;
183 3 : codec->coord_bits = codec->info->cfg.coord_bits;
184 3 : codec->scale_bits = codec->info->cfg.scale_bits_minus_coord_bits;
185 3 : codec->time_resolution = codec->info->cfg.time_resolution;
186 3 : codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1;
187 3 : if (codec->info->cfg.resolution >= 0)
188 3 : codec->res_factor = INT2FIX(1<<codec->info->cfg.resolution);
189 : else
190 0 : codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1 << (-codec->info->cfg.resolution)) );
191 :
192 3 : codec->bs = gf_bs_new(data, data_len, GF_BITSTREAM_READ);
193 3 : gf_bs_set_eos_callback(codec->bs, lsr_end_of_stream, codec);
194 3 : codec->memory_dec = GF_FALSE;
195 3 : e = lsr_decode_laser_unit(codec, NULL);
196 3 : gf_bs_del(codec->bs);
197 3 : codec->bs = NULL;
198 3 : return e;
199 : }
200 :
201 : GF_EXPORT
202 6 : GF_Err gf_laser_decode_command_list(GF_LASeRCodec *codec, u16 ESID, u8 *data, u32 data_len, GF_List *com_list)
203 : {
204 : GF_Err e;
205 : u32 i;
206 6 : if (!codec || !data || !data_len) return GF_BAD_PARAM;
207 :
208 6 : codec->info = lsr_get_stream(codec, ESID);
209 6 : if (!codec->info) return GF_BAD_PARAM;
210 6 : codec->coord_bits = codec->info->cfg.coord_bits;
211 6 : codec->scale_bits = codec->info->cfg.scale_bits_minus_coord_bits;
212 6 : codec->time_resolution = codec->info->cfg.time_resolution;
213 6 : codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1;
214 6 : if (codec->info->cfg.resolution >= 0)
215 6 : codec->res_factor = INT2FIX(1<<codec->info->cfg.resolution);
216 : else
217 0 : codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1 << (-codec->info->cfg.resolution)) );
218 :
219 6 : codec->bs = gf_bs_new(data, data_len, GF_BITSTREAM_READ);
220 6 : gf_bs_set_eos_callback(codec->bs, lsr_end_of_stream, codec);
221 6 : codec->memory_dec = GF_TRUE;
222 6 : e = lsr_decode_laser_unit(codec, com_list);
223 6 : gf_bs_del(codec->bs);
224 6 : codec->bs = NULL;
225 6 : if (e) return e;
226 :
227 6 : for (i=0; i<gf_list_count(codec->unresolved_commands); i++) {
228 6 : GF_Command *com = (GF_Command *)gf_list_get(codec->unresolved_commands, i);
229 : assert(!com->node);
230 6 : com->node = gf_sg_find_node(codec->sg, com->RouteID);
231 6 : if (com->node) {
232 0 : gf_node_register(com->node, NULL);
233 0 : com->RouteID = 0;
234 0 : gf_list_rem(codec->unresolved_commands, i);
235 0 : i--;
236 : }
237 : }
238 : return GF_OK;
239 : }
240 :
241 : GF_EXPORT
242 1 : void gf_laser_decoder_set_clock(GF_LASeRCodec *codec, Double (*GetSceneTime)(void *st_cbk), void *st_cbk )
243 : {
244 1 : codec->GetSceneTime = GetSceneTime;
245 1 : codec->cbk = st_cbk;
246 1 : }
247 :
248 1508 : static u32 lsr_read_vluimsbf5(GF_LASeRCodec *lsr, const char *name)
249 : {
250 : u32 nb_words = 0;
251 : u32 nb_tot, nb_bits, val;
252 :
253 732 : while (gf_bs_read_int(lsr->bs, 1)) nb_words++;
254 1508 : nb_words++;
255 : nb_tot = nb_words;
256 1508 : nb_bits = nb_words*4;
257 1508 : nb_tot += nb_bits;
258 1508 : val = gf_bs_read_int(lsr->bs, nb_bits);
259 1508 : if (name) GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_tot, val));
260 1508 : return val;
261 : }
262 174 : static u32 lsr_read_vluimsbf8(GF_LASeRCodec *lsr, const char *name)
263 : {
264 : u32 nb_words = 0;
265 : u32 nb_tot, nb_bits, val;
266 :
267 0 : while (gf_bs_read_int(lsr->bs, 1)) nb_words++;
268 174 : nb_words++;
269 : nb_tot = nb_words;
270 174 : nb_bits = nb_words*7;
271 174 : nb_tot += nb_bits;
272 174 : val = gf_bs_read_int(lsr->bs, nb_bits);
273 174 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_tot, val));
274 174 : return val;
275 : }
276 :
277 0 : static void lsr_read_extension(GF_LASeRCodec *lsr, const char *name)
278 : {
279 0 : u32 len = lsr_read_vluimsbf5(lsr, name);
280 : #if 0
281 : *out_data = gf_malloc(sizeof(char)*len);
282 : gf_bs_read_data(lsr->bs, *out_data, len);
283 : *out_len = len;
284 : #else
285 0 : while (len && gf_bs_available(lsr->bs) ) {
286 0 : gf_bs_read_int(lsr->bs, 8);
287 0 : len--;
288 : }
289 0 : if (len) lsr->last_error = GF_NON_COMPLIANT_BITSTREAM;
290 : #endif
291 0 : }
292 :
293 0 : static void lsr_read_extend_class(GF_LASeRCodec *lsr, char **out_data, u32 *out_len, const char *name)
294 : {
295 : u32 len;
296 0 : GF_LSR_READ_INT(lsr, len, lsr->info->cfg.extensionIDBits, "reserved");
297 0 : len = lsr_read_vluimsbf5(lsr, "len");
298 : // while (len) gf_bs_read_int(lsr->bs, 1);
299 0 : gf_bs_read_long_int(lsr->bs, len);
300 0 : if (out_data) *out_data = NULL;
301 0 : if (out_len) *out_len = 0;
302 0 : }
303 :
304 0 : static void lsr_read_private_element_container(GF_LASeRCodec *lsr)
305 : {
306 : u32 val, len;
307 0 : GF_LSR_READ_INT(lsr, val, 4, "ch4");
308 0 : switch (val) {
309 : /*privateAnyXMLElement*/
310 0 : case 0:
311 0 : len = lsr_read_vluimsbf5(lsr, "len");
312 0 : gf_bs_skip_bytes(lsr->bs, len);
313 0 : break;
314 : /*privateOpaqueElement*/
315 0 : case 1:
316 0 : len = lsr_read_vluimsbf5(lsr, "len");
317 0 : gf_bs_skip_bytes(lsr->bs, len);
318 0 : break;
319 : /*element_any*/
320 0 : case 2:
321 0 : lsr_read_extend_class(lsr, NULL, 0, "reserved");
322 0 : break;
323 : /*attr_custom_extension*/
324 0 : default:
325 0 : len = lsr_read_vluimsbf5(lsr, "len");
326 0 : gf_bs_skip_bytes(lsr->bs, len);
327 0 : break;
328 : }
329 0 : }
330 :
331 0 : static void lsr_read_private_attribute_container(GF_LASeRCodec *lsr)
332 : {
333 : u32 val;
334 : do {
335 : u32 skip_len;
336 0 : GF_LSR_READ_INT(lsr, val, 2, "privateDataType");
337 0 : skip_len = lsr_read_vluimsbf5(lsr, "skipLen");
338 0 : gf_bs_align(lsr->bs);
339 : /*just skip data*/
340 : #if 1
341 0 : if (skip_len>gf_bs_available(lsr->bs)) {
342 0 : lsr->last_error = GF_NON_COMPLIANT_BITSTREAM;
343 0 : return;
344 : }
345 0 : gf_bs_skip_bytes(lsr->bs, skip_len);
346 : #else
347 : switch (val) {
348 : /*private data of type "anyXML"*/
349 : case 0:
350 : count = lsr_read_vluimsbf5(lsr, "count");
351 : for (i=0; i<count; i++) {
352 : privateAttribute(0) attr[i];
353 : }
354 : break;
355 : case 1:
356 : /*TODO FIXME - nameSpaceIndexBits is not defined in the spec*/
357 : uint(nameSpaceIndexBits) nameSpaceIndex;
358 : gf_bs_align(lsr->bs);
359 : byte[skipLen - ((nameSpaceIndexBits+7)%8)] data;
360 : break;
361 : default:
362 : /*TODO - spec is wrong here (typo, "len" instead of "skipLen" )*/
363 : gf_bs_skip_bytes(skipLen);
364 : break;
365 : }
366 : #endif
367 0 : gf_bs_align(lsr->bs);
368 0 : GF_LSR_READ_INT(lsr, val, 1, "hasMorePrivateData");
369 0 : } while (val);
370 : }
371 :
372 701 : static void lsr_read_any_attribute(GF_LASeRCodec *lsr, GF_Node *node, Bool skippable)
373 : {
374 : u32 val = 1;
375 701 : if (skippable) GF_LSR_READ_INT(lsr, val, 1, "has_attrs");
376 701 : if (val) {
377 : do {
378 0 : GF_LSR_READ_INT(lsr, val, lsr->info->cfg.extensionIDBits, "reserved");
379 0 : val = lsr_read_vluimsbf5(lsr, "len");//len in BITS
380 0 : GF_LSR_READ_INT(lsr, val, val, "reserved_val");
381 0 : GF_LSR_READ_INT(lsr, val, 1, "hasNextExtension");
382 0 : } while (val);
383 : }
384 701 : }
385 :
386 436 : static void lsr_read_object_content(GF_LASeRCodec *lsr, SVG_Element *elt)
387 : {
388 : u32 val;
389 436 : GF_LSR_READ_INT(lsr, val, 1, "has_private_attr");
390 436 : if (val) lsr_read_private_attribute_container(lsr);
391 436 : }
392 :
393 77 : static void lsr_read_codec_IDREF(GF_LASeRCodec *lsr, XMLRI *href, const char *name)
394 : {
395 : GF_Node *n;
396 : u32 flag;
397 77 : u32 nID = 1+lsr_read_vluimsbf5(lsr, name);
398 :
399 77 : GF_LSR_READ_INT(lsr, flag, 1, "reserved");
400 77 : if (flag) {
401 0 : u32 len = lsr_read_vluimsbf5(lsr, "len");
402 0 : GF_LSR_READ_INT(lsr, flag, len, "reserved");
403 : }
404 :
405 77 : n = gf_sg_find_node(lsr->sg, nID);
406 77 : if (!n) {
407 : char NodeID[1024];
408 : sprintf(NodeID, "N%d", nID-1);
409 30 : href->string = gf_strdup(NodeID);
410 30 : if (href->type!=0xFF)
411 30 : gf_list_add(lsr->deferred_hrefs, href);
412 30 : href->type = XMLRI_ELEMENTID;
413 : return;
414 : }
415 47 : href->target = (SVG_Element *)n;
416 47 : href->type = XMLRI_ELEMENTID;
417 47 : gf_node_register_iri(lsr->sg, href);
418 : }
419 :
420 269 : static u32 lsr_read_codec_IDREF_command(GF_LASeRCodec *lsr, const char *name)
421 : {
422 : u32 flag;
423 269 : u32 nID = 1+lsr_read_vluimsbf5(lsr, name);
424 :
425 269 : GF_LSR_READ_INT(lsr, flag, 1, "reserved");
426 269 : if (flag) {
427 0 : u32 len = lsr_read_vluimsbf5(lsr, "len");
428 0 : GF_LSR_READ_INT(lsr, flag, len, "reserved");
429 : }
430 269 : return nID;
431 : }
432 :
433 230 : static Fixed lsr_read_fixed_16_8(GF_LASeRCodec *lsr, const char *name)
434 : {
435 : u32 val;
436 230 : GF_LSR_READ_INT(lsr, val, 24, name);
437 230 : if (val & (1<<23)) {
438 3 : s32 res = val - (1<<24);
439 : #ifdef GPAC_FIXED_POINT
440 : return res*256;
441 : #else
442 3 : return INT2FIX(res) / 256;
443 : #endif
444 : } else {
445 : #ifdef GPAC_FIXED_POINT
446 : return val*256;
447 : #else
448 227 : return INT2FIX(val) / 256;
449 : #endif
450 : }
451 : }
452 :
453 36 : static void lsr_read_fixed_16_8i(GF_LASeRCodec *lsr, SVG_Number *n, const char *name)
454 : {
455 : s32 val;
456 36 : GF_LSR_READ_INT(lsr, val, 1, name);
457 36 : if (val) {
458 0 : n->type=SVG_NUMBER_INHERIT;
459 : } else {
460 36 : n->type=SVG_NUMBER_VALUE;
461 36 : n->value = lsr_read_fixed_16_8(lsr, name);
462 : }
463 36 : }
464 :
465 :
466 157 : static void lsr_get_color(GF_LASeRCodec *lsr, u32 idx, SVG_Color *color)
467 : {
468 : LSRCol *c;
469 157 : if (idx>=lsr->nb_cols) return;
470 :
471 157 : c = &lsr->col_table[idx];
472 157 : color->red = INT2FIX(c->r) / lsr->color_scale;
473 157 : color->green = INT2FIX(c->g) / lsr->color_scale;
474 157 : color->blue = INT2FIX(c->b) / lsr->color_scale;
475 157 : color->type = SVG_COLOR_RGBCOLOR;
476 : }
477 :
478 :
479 9 : static void lsr_read_line_increment_type(GF_LASeRCodec *lsr, SVG_Number *li, const char *name)
480 : {
481 : u32 val;
482 9 : GF_LSR_READ_INT(lsr, val, 1, "choice");
483 9 : if (val==1) {
484 6 : GF_LSR_READ_INT(lsr, val, 1, "type");
485 6 : if (val==1) li->type=SVG_NUMBER_INHERIT;
486 3 : else li->type=SVG_NUMBER_AUTO;
487 : } else {
488 3 : li->value = lsr_read_fixed_16_8(lsr, "line-increment-value");
489 : }
490 9 : }
491 :
492 174 : static void lsr_read_byte_align_string(GF_LASeRCodec *lsr, char **str, const char *name)
493 : {
494 : u32 len;
495 174 : gf_bs_align(lsr->bs);
496 174 : len = lsr_read_vluimsbf8(lsr, "len");
497 174 : if (str) {
498 165 : if (*str) gf_free(*str);
499 165 : *str = NULL;
500 165 : if (len) {
501 162 : if (len > gf_bs_available(lsr->bs) ) {
502 0 : lsr->last_error = GF_NON_COMPLIANT_BITSTREAM;
503 0 : return;
504 : }
505 162 : *str = (char*)gf_malloc(sizeof(char)*(len+1));
506 162 : gf_bs_read_data(lsr->bs, *str, len);
507 162 : (*str) [len] = 0;
508 : }
509 : } else {
510 66 : while (len) {
511 57 : gf_bs_read_int(lsr->bs, 8);
512 57 : len--;
513 : }
514 : }
515 174 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%s\n", name, 8*len, str ? *str : ""));
516 : }
517 :
518 39 : static void lsr_read_text_content(GF_LASeRCodec *lsr, GF_Node *elt)
519 : {
520 39 : char *str = NULL;
521 39 : lsr_read_byte_align_string(lsr, &str, "textContent");
522 42 : if (!str) return;
523 36 : gf_dom_add_text_node(elt, str);
524 : }
525 :
526 12 : static void lsr_read_byte_align_string_list(GF_LASeRCodec *lsr, GF_List *l, const char *name, Bool is_iri, Bool is_font)
527 : {
528 : XMLRI *iri;
529 : char *text, *sep, *sep2, *cur;
530 24 : while (gf_list_count(l)) {
531 0 : char *str = (char *)gf_list_last(l);
532 0 : gf_list_rem_last(l);
533 0 : gf_free(str);
534 : }
535 12 : text = NULL;
536 12 : lsr_read_byte_align_string(lsr, &text, name);
537 12 : cur = text;
538 27 : while (cur) {
539 15 : sep = strchr(cur, '\'');
540 15 : if (!sep && is_font) {
541 6 : sep = strchr(cur, ',');
542 6 : if (!sep) sep = strchr(cur, ';');
543 : }
544 15 : if (!sep) {
545 12 : if (is_iri) {
546 3 : GF_SAFEALLOC(iri, XMLRI);
547 3 : if (iri) {
548 3 : iri->string = gf_strdup(cur);
549 3 : iri->type = XMLRI_STRING;
550 3 : gf_list_add(l, iri);
551 : }
552 : } else {
553 9 : gf_list_add(l, gf_strdup(cur));
554 : }
555 : break;
556 : }
557 3 : sep2 = strchr(sep + 1, '\'');
558 3 : if (!sep2 && !is_font) {
559 0 : if (is_iri) {
560 0 : GF_SAFEALLOC(iri, XMLRI);
561 0 : if (iri) {
562 0 : iri->string = gf_strdup(cur);
563 0 : iri->type = XMLRI_STRING;
564 0 : gf_list_add(l, iri);
565 : }
566 : } else {
567 0 : gf_list_add(l, gf_strdup(cur));
568 : }
569 : break;
570 : }
571 3 : if (sep2)
572 0 : sep2[0] = 0;
573 : else
574 3 : sep[0] = 0;
575 3 : if (is_iri) {
576 0 : GF_SAFEALLOC(iri, XMLRI);
577 0 : if (iri) {
578 0 : iri->string = gf_strdup(sep+1);
579 0 : iri->type = XMLRI_STRING;
580 0 : gf_list_add(l, iri);
581 : }
582 : } else {
583 3 : gf_list_add(l, gf_strdup(sep+1));
584 : }
585 3 : if (sep2) {
586 0 : sep2[0] = '\'';
587 0 : cur = sep2 + 1;
588 : } else {
589 3 : sep[0] = ';';
590 : cur = sep + 1;
591 : }
592 : }
593 12 : gf_free(text);
594 12 : }
595 :
596 110 : static void lsr_read_any_uri(GF_LASeRCodec *lsr, XMLRI *iri, const char *name)
597 : {
598 : u32 val;
599 110 : GF_LSR_READ_INT(lsr, val, 1, "hasUri");
600 110 : if (val) {
601 36 : char *s = NULL;
602 36 : iri->type=XMLRI_STRING;
603 36 : if (iri->string) {
604 0 : gf_free(iri->string);
605 0 : iri->string = NULL;
606 : }
607 36 : lsr_read_byte_align_string(lsr, &s, "uri");
608 36 : GF_LSR_READ_INT(lsr, val, 1, "hasData");
609 36 : if (!val) {
610 33 : iri->string = s;
611 : } else {
612 : u32 len_rad, len;
613 3 : len = lsr_read_vluimsbf5(lsr, "len");
614 3 : len_rad = s ? (u32) strlen(s) : 0;
615 3 : iri->string = (char*)gf_malloc(sizeof(char)*(len_rad+1+len+1));
616 3 : iri->string[0] = 0;
617 3 : if (s) {
618 3 : strcpy(iri->string, s);
619 3 : gf_free(s);
620 : }
621 3 : strcat(iri->string, ",");
622 3 : gf_bs_read_data(lsr->bs, iri->string + len_rad + 1, len);
623 3 : iri->string[len_rad + 1 + len] = 0;
624 : }
625 : }
626 110 : GF_LSR_READ_INT(lsr, val, 1, "hasID");
627 110 : if (val) lsr_read_codec_IDREF(lsr, iri, "idref");
628 :
629 110 : GF_LSR_READ_INT(lsr, val, 1, "hasStreamID");
630 110 : if (val) {
631 3 : iri->type = XMLRI_STREAMID;
632 3 : iri->lsr_stream_id = lsr_read_vluimsbf5(lsr, name);
633 3 : GF_LSR_READ_INT(lsr, val, 1, "reserved");
634 3 : if (val) {
635 0 : u32 len = lsr_read_vluimsbf5(lsr, "len");
636 0 : GF_LSR_READ_INT(lsr, val, len, "reserved");
637 : }
638 : }
639 110 : }
640 :
641 193 : static void lsr_read_paint(GF_LASeRCodec *lsr, SVG_Paint *paint, const char *name)
642 : {
643 : u32 val;
644 193 : GF_LSR_READ_INT(lsr, val, 1, "hasIndex");
645 193 : if (val) {
646 157 : GF_LSR_READ_INT(lsr, val, lsr->colorIndexBits, name);
647 157 : lsr_get_color(lsr, val, &paint->color);
648 157 : paint->type = SVG_PAINT_COLOR;
649 157 : paint->color.type = 0;
650 : } else {
651 36 : GF_LSR_READ_INT(lsr, val, 2, "enum");
652 36 : switch (val) {
653 27 : case 0:
654 27 : GF_LSR_READ_INT(lsr, val, 2, "choice");
655 27 : switch (val) {
656 12 : case 0:
657 12 : paint->type = SVG_PAINT_INHERIT;
658 12 : break;
659 3 : case 1:
660 3 : paint->type = SVG_PAINT_COLOR;
661 3 : paint->color.type = SVG_COLOR_CURRENTCOLOR;
662 3 : break;
663 12 : default:
664 12 : paint->type = SVG_PAINT_NONE;
665 12 : break;
666 : }
667 : break;
668 : case 1:
669 : {
670 : XMLRI iri;
671 : memset(&iri, 0, sizeof(XMLRI));
672 9 : iri.type = 0xFF;
673 9 : lsr_read_any_uri(lsr, &iri, name);
674 9 : gf_node_unregister_iri(lsr->sg, &iri);
675 9 : paint->type = SVG_PAINT_URI;
676 9 : if (iri.string) {
677 : paint->type = SVG_PAINT_URI;
678 0 : paint->iri.type = XMLRI_STRING;
679 0 : paint->iri.string = iri.string;
680 9 : } else if (iri.target) {
681 9 : paint->iri.type = XMLRI_ELEMENTID;
682 9 : paint->iri.target = iri.target;
683 : }
684 : }
685 9 : break;
686 0 : case 2:
687 : {
688 0 : char *sysPaint=NULL;
689 0 : lsr_read_byte_align_string(lsr, &sysPaint, "systemsPaint");
690 0 : if (sysPaint) {
691 0 : paint->type = SVG_PAINT_COLOR;
692 0 : paint->color.type = gf_svg_get_system_paint_server_type(sysPaint);
693 0 : gf_free(sysPaint);
694 : }
695 : }
696 0 : break;
697 0 : case 3:
698 0 : lsr_read_extension(lsr, name);
699 0 : break;
700 : }
701 : }
702 193 : }
703 :
704 15 : static void lsr_read_string_attribute(GF_LASeRCodec *lsr, GF_Node *elt, u32 tag, char *name)
705 : {
706 : u32 val;
707 15 : GF_LSR_READ_INT(lsr, val, 1, name);
708 15 : if (val) {
709 : GF_FieldInfo info;
710 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, tag, GF_TRUE, GF_FALSE, &info);
711 0 : lsr_read_byte_align_string(lsr, info.far_ptr, name);
712 : }
713 15 : }
714 492 : static void lsr_read_id(GF_LASeRCodec *lsr, GF_Node *n)
715 : {
716 : GF_FieldInfo info;
717 : u32 val, id, i, count;
718 : char *name;
719 492 : GF_LSR_READ_INT(lsr, val, 1, "has_id");
720 873 : if (!val) return;
721 :
722 : name = NULL;
723 111 : id = 1+lsr_read_vluimsbf5(lsr, "ID");
724 111 : gf_node_set_id(n, id, name);
725 :
726 111 : GF_LSR_READ_INT(lsr, val, 1, "reserved");
727 : /*currently not used*/
728 111 : if (val) {
729 0 : u32 len = lsr_read_vluimsbf5(lsr, "len");
730 0 : GF_LSR_READ_INT(lsr, val, len, "reserved");
731 : }
732 :
733 : /*update all pending HREFs*/
734 111 : count = gf_list_count(lsr->deferred_hrefs);
735 144 : for (i=0; i<count; i++) {
736 33 : XMLRI *href = (XMLRI *)gf_list_get(lsr->deferred_hrefs, i);
737 33 : char *str_id = href->string;
738 33 : if (str_id[0] == '#') str_id++;
739 : /*skip 'N'*/
740 33 : str_id++;
741 33 : if (id == (1 + (u32) atoi(str_id))) {
742 30 : href->target = (SVG_Element*) n;
743 30 : gf_free(href->string);
744 30 : href->string = NULL;
745 30 : gf_list_rem(lsr->deferred_hrefs, i);
746 30 : i--;
747 30 : count--;
748 : }
749 : }
750 :
751 : /*update unresolved listeners*/
752 111 : count = gf_list_count(lsr->deferred_listeners);
753 111 : for (i=0; i<count; i++) {
754 : GF_Node *par;
755 : XMLRI *observer = NULL;
756 0 : GF_Node *listener = (GF_Node *)gf_list_get(lsr->deferred_listeners, i);
757 :
758 : par = NULL;
759 0 : if (gf_node_get_attribute_by_tag(listener, TAG_XMLEV_ATT_observer, GF_FALSE, GF_FALSE, &info) == GF_OK) {
760 0 : observer = (XMLRI*)info.far_ptr;
761 0 : if (observer->type == XMLRI_ELEMENTID) {
762 0 : if (!observer->target) continue;
763 : else par = (GF_Node*)observer->target;
764 : }
765 : }
766 0 : if (gf_node_get_attribute_by_tag(listener, TAG_XMLEV_ATT_target, GF_FALSE, GF_FALSE, &info) == GF_OK) {
767 0 : if (((XMLRI*)info.far_ptr)->type == XMLRI_ELEMENTID) {
768 0 : if (!((XMLRI*)info.far_ptr)->target) continue;
769 0 : else if (!par) par = (GF_Node*)((XMLRI*)info.far_ptr)->target;
770 : }
771 : }
772 : /*FIXME - double check with XML events*/
773 0 : if (!par && !observer) {
774 0 : if (gf_node_get_attribute_by_tag(listener, TAG_XMLEV_ATT_event, GF_FALSE, GF_FALSE, &info) == GF_OK) {
775 0 : XMLEV_Event *ev = (XMLEV_Event *)info.far_ptr;
776 : /*all non-UI get attched to root*/
777 0 : if (ev && (ev->type>GF_EVENT_MOUSEWHEEL)) {
778 0 : par = (GF_Node*) lsr->current_root;
779 : }
780 : }
781 : }
782 :
783 : assert(par);
784 0 : gf_node_dom_listener_add(par, listener);
785 0 : gf_list_rem(lsr->deferred_listeners, i);
786 0 : i--;
787 0 : count--;
788 : }
789 :
790 : /*update all pending animations*/
791 111 : count = gf_list_count(lsr->deferred_anims);
792 432 : for (i=0; i<count; i++) {
793 321 : SVG_Element *elt = (SVG_Element *)gf_list_get(lsr->deferred_anims, i);
794 321 : if (lsr_setup_smil_anim(lsr, elt, NULL)) {
795 27 : gf_list_rem(lsr->deferred_anims, i);
796 27 : i--;
797 27 : count--;
798 27 : gf_node_init((GF_Node*)elt);
799 : }
800 : }
801 : }
802 :
803 : static Fixed lsr_translate_coords(GF_LASeRCodec *lsr, u32 val, u32 nb_bits)
804 : {
805 : #ifdef GPAC_FIXED_POINT
806 : if (val >> (nb_bits-1) ) {
807 : s32 neg = (s32) val - (1<<nb_bits);
808 : if (neg < -FIX_ONE / 2)
809 : return 2 * gf_divfix(INT2FIX(neg/2), lsr->res_factor);
810 : return gf_divfix(INT2FIX(neg), lsr->res_factor);
811 : } else {
812 : if (val > FIX_ONE / 2)
813 : return 2 * gf_divfix(INT2FIX(val/2), lsr->res_factor);
814 : return gf_divfix(INT2FIX(val), lsr->res_factor);
815 : }
816 : #else
817 1213 : if (val >> (nb_bits-1) ) {
818 171 : s32 neg = (s32) val - (1<<nb_bits);
819 171 : return gf_divfix(INT2FIX(neg), lsr->res_factor);
820 : } else {
821 1042 : return gf_divfix(INT2FIX(val), lsr->res_factor);
822 : }
823 : #endif
824 : }
825 :
826 : static Fixed lsr_translate_scale(GF_LASeRCodec *lsr, u32 val)
827 : {
828 30 : if (val >> (lsr->coord_bits-1) ) {
829 6 : s32 v = val - (1<<lsr->coord_bits);
830 6 : return INT2FIX(v) / 256 ;
831 : } else {
832 24 : return INT2FIX(val) / 256;
833 : }
834 : }
835 21 : static void lsr_read_matrix(GF_LASeRCodec *lsr, SVG_Transform *mx)
836 : {
837 : u32 flag;
838 42 : gf_mx2d_init(mx->mat);
839 21 : mx->is_ref = 0;
840 21 : GF_LSR_READ_INT(lsr, flag, 1, "isNotMatrix");
841 21 : if (flag) {
842 3 : GF_LSR_READ_INT(lsr, flag, 1, "isRef");
843 3 : if (flag) {
844 3 : GF_LSR_READ_INT(lsr, flag, 1, "hasXY");
845 3 : if (flag) {
846 3 : mx->mat.m[2] = lsr_read_fixed_16_8(lsr, "valueX");
847 3 : mx->mat.m[5] = lsr_read_fixed_16_8(lsr, "valueY");
848 : }
849 : } else {
850 0 : lsr_read_extension(lsr, "ext");
851 : }
852 : } else {
853 18 : lsr->coord_bits += lsr->scale_bits;
854 18 : GF_LSR_READ_INT(lsr, flag, 1, "xx_yy_present");
855 18 : if (flag) {
856 9 : GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, "xx");
857 18 : mx->mat.m[0] = lsr_translate_scale(lsr, flag);
858 9 : GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, "yy");
859 18 : mx->mat.m[4] = lsr_translate_scale(lsr, flag);
860 : } else {
861 9 : mx->mat.m[0] = mx->mat.m[4] = FIX_ONE;
862 : }
863 18 : GF_LSR_READ_INT(lsr, flag, 1, "xy_yx_present");
864 18 : if (flag) {
865 6 : GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, "xy");
866 12 : mx->mat.m[1] = lsr_translate_scale(lsr, flag);
867 6 : GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, "yx");
868 12 : mx->mat.m[3] = lsr_translate_scale(lsr, flag);
869 : }
870 :
871 18 : GF_LSR_READ_INT(lsr, flag, 1, "xz_yz_present");
872 18 : if (flag) {
873 12 : GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, "xz");
874 24 : mx->mat.m[2] = lsr_translate_coords(lsr, flag, lsr->coord_bits);
875 12 : GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, "yz");
876 24 : mx->mat.m[5] = lsr_translate_coords(lsr, flag, lsr->coord_bits);
877 : }
878 18 : lsr->coord_bits -= lsr->scale_bits;
879 : }
880 21 : }
881 :
882 51 : static Fixed lsr_read_fixed_clamp(GF_LASeRCodec *lsr, const char *name)
883 : {
884 : s32 val;
885 51 : GF_LSR_READ_INT(lsr, val, 8, name);
886 51 : return INT2FIX(val) / 255;
887 : }
888 :
889 30 : static void lsr_read_focus(GF_LASeRCodec *lsr, SVG_Focus *foc, const char *name)
890 : {
891 : u32 flag;
892 :
893 30 : if (foc->target.string) {
894 0 : gf_free(foc->target.string);
895 0 : foc->target.string = NULL;
896 : }
897 30 : if (foc->target.target) foc->target.target = NULL;
898 30 : gf_node_unregister_iri(lsr->sg, &foc->target);
899 :
900 30 : GF_LSR_READ_INT(lsr, flag, 1, "isEnum");
901 30 : if (flag) {
902 27 : GF_LSR_READ_INT(lsr, foc->type, 1, "enum");
903 : } else {
904 3 : foc->type = SVG_FOCUS_IRI;
905 3 : lsr_read_codec_IDREF(lsr, &foc->target, "id");
906 : }
907 30 : }
908 :
909 54 : static void lsr_restore_base(GF_LASeRCodec *lsr, SVG_Element *elt, SVG_Element *base, Bool reset_fill, Bool reset_stroke)
910 : {
911 : GF_Err e;
912 : GF_FieldInfo f_base, f_clone;
913 : SVGAttribute *att;
914 :
915 : /*clone all propertie from base*/
916 54 : att = base->attributes;
917 246 : while (att) {
918 : Bool is_fill, is_stroke;
919 : is_fill = is_stroke = GF_FALSE;
920 192 : switch (att->tag) {
921 : /*for all properties*/
922 6 : case TAG_SVG_ATT_fill:
923 : is_fill = GF_TRUE;
924 : break;
925 9 : case TAG_SVG_ATT_stroke:
926 : is_stroke = GF_TRUE;
927 : break;
928 : case TAG_SVG_ATT_audio_level:
929 : case TAG_SVG_ATT_color:
930 : case TAG_SVG_ATT_color_rendering:
931 : case TAG_SVG_ATT_display:
932 : case TAG_SVG_ATT_display_align:
933 : case TAG_SVG_ATT_fill_opacity:
934 : case TAG_SVG_ATT_fill_rule:
935 : case TAG_SVG_ATT_font_family:
936 : case TAG_SVG_ATT_font_size:
937 : case TAG_SVG_ATT_font_style:
938 : case TAG_SVG_ATT_font_variant:
939 : case TAG_SVG_ATT_font_weight:
940 : case TAG_SVG_ATT_image_rendering:
941 : case TAG_SVG_ATT_line_increment:
942 : case TAG_SVG_ATT_opacity:
943 : case TAG_SVG_ATT_pointer_events:
944 : case TAG_SVG_ATT_shape_rendering:
945 : case TAG_SVG_ATT_solid_color:
946 : case TAG_SVG_ATT_solid_opacity:
947 : case TAG_SVG_ATT_stop_color:
948 : case TAG_SVG_ATT_stop_opacity:
949 : case TAG_SVG_ATT_stroke_dasharray:
950 : case TAG_SVG_ATT_stroke_dashoffset:
951 : case TAG_SVG_ATT_stroke_linecap:
952 : case TAG_SVG_ATT_stroke_linejoin:
953 : case TAG_SVG_ATT_stroke_miterlimit:
954 : case TAG_SVG_ATT_stroke_opacity:
955 : case TAG_SVG_ATT_stroke_width:
956 : case TAG_SVG_ATT_text_align:
957 : case TAG_SVG_ATT_text_anchor:
958 : case TAG_SVG_ATT_text_rendering:
959 : case TAG_SVG_ATT_vector_effect:
960 : case TAG_SVG_ATT_viewport_fill:
961 : case TAG_SVG_ATT_viewport_fill_opacity:
962 : case TAG_SVG_ATT_visibility:
963 : /*and xml:_class*/
964 : case TAG_SVG_ATT__class:
965 : case TAG_SVG_ATT_externalResourcesRequired:
966 : break;
967 :
968 : /*pathLength for path*/
969 : case TAG_SVG_ATT_pathLength:
970 : break;
971 : /*rx & ry for rect*/
972 0 : case TAG_SVG_ATT_rx:
973 : case TAG_SVG_ATT_ry:
974 0 : if (base->sgprivate->tag!=TAG_SVG_rect) {
975 0 : att = att->next;
976 0 : continue;
977 : }
978 : break;
979 : /*x & y for use*/
980 72 : case TAG_SVG_ATT_x:
981 : case TAG_SVG_ATT_y:
982 72 : if (base->sgprivate->tag!=TAG_SVG_use) {
983 72 : att = att->next;
984 72 : continue;
985 : }
986 : break;
987 : /*editable & rotate for text*/
988 0 : case TAG_SVG_ATT_editable:
989 : case TAG_SVG_ATT_rotate:
990 0 : if (base->sgprivate->tag!=TAG_SVG_text) {
991 0 : att = att->next;
992 0 : continue;
993 : }
994 : break;
995 : case TAG_SVG_ATT_transform:
996 : break;
997 90 : default:
998 90 : att = att->next;
999 90 : continue;
1000 : }
1001 : /*clone field*/
1002 30 : e = gf_node_get_attribute_by_tag((GF_Node*)elt, att->tag, GF_TRUE, GF_FALSE, &f_clone);
1003 30 : if (e) goto err_exit;
1004 30 : f_base.fieldIndex = att->tag;
1005 30 : f_base.fieldType = att->data_type;
1006 30 : f_base.far_ptr = att->data;
1007 30 : e = gf_svg_attributes_copy(&f_clone, &f_base, GF_FALSE);
1008 30 : if (e) goto err_exit;
1009 :
1010 30 : if (is_fill && reset_fill) {
1011 3 : SVG_Paint*p = (SVG_Paint*)f_clone.far_ptr;
1012 3 : if (p->iri.string) gf_free(p->iri.string);
1013 : memset(p, 0, sizeof(SVG_Paint));
1014 : }
1015 30 : if (is_stroke && reset_stroke) {
1016 0 : SVG_Paint*p = (SVG_Paint*)f_clone.far_ptr;
1017 0 : if (p->iri.string) gf_free(p->iri.string);
1018 : memset(p, 0, sizeof(SVG_Paint));
1019 : }
1020 30 : att = att->next;
1021 : }
1022 54 : return;
1023 :
1024 0 : err_exit:
1025 0 : lsr->last_error = e;
1026 : }
1027 :
1028 :
1029 : static u32 lsr_to_dom_key(u32 lsr_k)
1030 : {
1031 : switch (lsr_k) {
1032 : case 0:
1033 : return GF_KEY_STAR;
1034 : case 1:
1035 : return GF_KEY_0;
1036 : case 2:
1037 : return GF_KEY_1;
1038 : case 3:
1039 : return GF_KEY_2;
1040 : case 4:
1041 : return GF_KEY_3;
1042 : case 5:
1043 : return GF_KEY_4;
1044 : case 6:
1045 : return GF_KEY_5;
1046 : case 7:
1047 : return GF_KEY_6;
1048 : case 8:
1049 : return GF_KEY_7;
1050 : case 9:
1051 : return GF_KEY_8;
1052 : case 10:
1053 : return GF_KEY_9;
1054 : case 12:
1055 : return GF_KEY_DOWN;
1056 : case 14:
1057 : return GF_KEY_LEFT;
1058 : case 16:
1059 : return GF_KEY_RIGHT;
1060 : case 20:
1061 : return GF_KEY_UP;
1062 : /*WHAT IS ANY_KEY (11) ??*/
1063 : case 13:
1064 : return GF_KEY_ENTER;
1065 : case 15:
1066 : return GF_KEY_ESCAPE;
1067 : case 17:
1068 : return GF_KEY_NUMBER;
1069 : case 18:
1070 : return GF_KEY_CELL_SOFT1;
1071 : case 19:
1072 : return GF_KEY_CELL_SOFT2;
1073 : default:
1074 : /*use '*' by default ... */
1075 : return 0;
1076 : }
1077 : }
1078 :
1079 168 : static void lsr_read_event_type(GF_LASeRCodec *lsr, XMLEV_Event *evtType)
1080 : {
1081 : u32 flag;
1082 : memset(evtType, 0, sizeof(XMLEV_Event));
1083 :
1084 168 : GF_LSR_READ_INT(lsr, flag, 1, "choice");
1085 168 : if (!flag) {
1086 : char *evtName, *sep;
1087 6 : evtName = NULL;
1088 6 : lsr_read_byte_align_string(lsr, &evtName, "evtString");
1089 6 : evtType->type = evtType->parameter = 0;
1090 6 : if (evtName) {
1091 6 : sep = strchr(evtName, '(');
1092 6 : if (sep) {
1093 : char *param;
1094 3 : sep[0] = 0;
1095 3 : evtType->type = gf_dom_event_type_by_name(evtName);
1096 3 : sep[0] = '(';
1097 3 : param = sep+1;
1098 3 : sep = strchr(evtName, ')');
1099 3 : if (sep) sep[0]=0;
1100 3 : if (evtType->type==GF_EVENT_REPEAT) {
1101 0 : evtType->parameter = atoi(param);
1102 : } else {
1103 3 : evtType->parameter = gf_dom_get_key_type(param);
1104 : }
1105 : } else {
1106 3 : evtType->type = gf_dom_event_type_by_name(evtName);
1107 : }
1108 6 : gf_free(evtName);
1109 : }
1110 : } else {
1111 162 : evtType->parameter = 0;
1112 162 : GF_LSR_READ_INT(lsr, flag, 6, "event");
1113 162 : switch (flag) {
1114 9 : case LSR_EVT_abort:
1115 9 : evtType->type = GF_EVENT_ABORT;
1116 9 : break;
1117 3 : case LSR_EVT_accessKey:
1118 3 : evtType->type = GF_EVENT_KEYDOWN;
1119 3 : break;
1120 3 : case LSR_EVT_activate:
1121 3 : evtType->type = GF_EVENT_ACTIVATE;
1122 3 : break;
1123 3 : case LSR_EVT_activatedEvent:
1124 3 : evtType->type = GF_EVENT_ACTIVATED;
1125 3 : break;
1126 3 : case LSR_EVT_beginEvent:
1127 3 : evtType->type = GF_EVENT_BEGIN_EVENT;
1128 3 : break;
1129 3 : case LSR_EVT_click:
1130 3 : evtType->type = GF_EVENT_CLICK;
1131 3 : break;
1132 3 : case LSR_EVT_deactivatedEvent:
1133 3 : evtType->type = GF_EVENT_DEACTIVATED;
1134 3 : break;
1135 3 : case LSR_EVT_endEvent:
1136 3 : evtType->type = GF_EVENT_END_EVENT;
1137 3 : break;
1138 3 : case LSR_EVT_error:
1139 3 : evtType->type = GF_EVENT_ERROR;
1140 3 : break;
1141 3 : case LSR_EVT_executionTime:
1142 3 : evtType->type = GF_EVENT_EXECUTION_TIME;
1143 3 : break;
1144 3 : case LSR_EVT_focusin:
1145 3 : evtType->type = GF_EVENT_FOCUSIN;
1146 3 : break;
1147 3 : case LSR_EVT_focusout:
1148 3 : evtType->type = GF_EVENT_FOCUSOUT;
1149 3 : break;
1150 0 : case LSR_EVT_keydown:
1151 0 : evtType->type = GF_EVENT_KEYDOWN;
1152 0 : break;
1153 3 : case LSR_EVT_keyup:
1154 3 : evtType->type = GF_EVENT_KEYUP;
1155 3 : break;
1156 3 : case LSR_EVT_load:
1157 3 : evtType->type = GF_EVENT_LOAD;
1158 3 : break;
1159 66 : case LSR_EVT_longAccessKey:
1160 66 : evtType->type = GF_EVENT_LONGKEYPRESS;
1161 66 : break;
1162 3 : case LSR_EVT_mousedown:
1163 3 : evtType->type = GF_EVENT_MOUSEDOWN;
1164 3 : break;
1165 3 : case LSR_EVT_mousemove:
1166 3 : evtType->type = GF_EVENT_MOUSEMOVE;
1167 3 : break;
1168 3 : case LSR_EVT_mouseout:
1169 3 : evtType->type = GF_EVENT_MOUSEOUT;
1170 3 : break;
1171 3 : case LSR_EVT_mouseover:
1172 3 : evtType->type = GF_EVENT_MOUSEOVER;
1173 3 : break;
1174 3 : case LSR_EVT_mouseup:
1175 3 : evtType->type = GF_EVENT_MOUSEUP;
1176 3 : break;
1177 3 : case LSR_EVT_pause:
1178 3 : evtType->type = GF_EVENT_PAUSE;
1179 3 : break;
1180 3 : case LSR_EVT_pausedEvent:
1181 3 : evtType->type = GF_EVENT_PAUSED_EVENT;
1182 3 : break;
1183 3 : case LSR_EVT_play:
1184 3 : evtType->type = GF_EVENT_PLAY;
1185 3 : break;
1186 3 : case LSR_EVT_repeatEvent:
1187 3 : evtType->type = GF_EVENT_REPEAT_EVENT;
1188 3 : break;
1189 3 : case LSR_EVT_repeatKey:
1190 3 : evtType->type = GF_EVENT_REPEAT_KEY;
1191 3 : break;
1192 3 : case LSR_EVT_resize:
1193 3 : evtType->type = GF_EVENT_RESIZE;
1194 3 : break;
1195 3 : case LSR_EVT_resumedEvent:
1196 3 : evtType->type = GF_EVENT_RESUME_EVENT;
1197 3 : break;
1198 3 : case LSR_EVT_scroll:
1199 3 : evtType->type = GF_EVENT_SCROLL;
1200 3 : break;
1201 0 : case LSR_EVT_shortAccessKey:
1202 0 : evtType->type = GF_EVENT_SHORT_ACCESSKEY;
1203 0 : break;
1204 3 : case LSR_EVT_textinput:
1205 3 : evtType->type = GF_EVENT_TEXTINPUT;
1206 3 : break;
1207 3 : case LSR_EVT_unload:
1208 3 : evtType->type = GF_EVENT_UNLOAD;
1209 3 : break;
1210 3 : case LSR_EVT_zoom:
1211 3 : evtType->type = GF_EVENT_ZOOM;
1212 3 : break;
1213 0 : default:
1214 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[LASeR] Undefined LASeR event %d\n", flag));
1215 : break;
1216 : }
1217 : switch (flag) {
1218 72 : case LSR_EVT_accessKey:
1219 : case LSR_EVT_longAccessKey:
1220 : case LSR_EVT_repeatKey:
1221 : case LSR_EVT_shortAccessKey:
1222 72 : evtType->parameter = lsr_read_vluimsbf5(lsr, "keyCode");
1223 72 : evtType->parameter = lsr_to_dom_key(evtType->parameter);
1224 72 : break;
1225 : }
1226 : }
1227 168 : }
1228 :
1229 63 : static SMIL_Time *lsr_read_smil_time(GF_LASeRCodec *lsr, GF_Node *n)
1230 : {
1231 : SMIL_Time *t;
1232 : u32 val;
1233 :
1234 63 : GF_SAFEALLOC(t, SMIL_Time);
1235 63 : if (!t) return NULL;
1236 63 : t->type = GF_SMIL_TIME_CLOCK;
1237 :
1238 63 : GF_LSR_READ_INT(lsr, val, 1, "hasEvent");
1239 63 : if (val) {
1240 3 : t->type = GF_SMIL_TIME_EVENT;
1241 3 : GF_LSR_READ_INT(lsr, val, 1, "hasIdentifier");
1242 3 : if (val) {
1243 : XMLRI iri;
1244 3 : iri.type = 0xFF;
1245 3 : iri.string = NULL;
1246 3 : lsr_read_codec_IDREF(lsr, &iri, "idref");
1247 3 : gf_node_unregister_iri(lsr->sg, &iri);
1248 3 : if (iri.string) {
1249 0 : t->element_id = iri.string;
1250 : } else {
1251 3 : t->element = (GF_Node *)iri.target;
1252 : }
1253 : }
1254 3 : lsr_read_event_type(lsr, &t->event);
1255 3 : if (t->event.type==GF_EVENT_EXECUTION_TIME) {
1256 0 : t->type = GF_SMIL_TIME_CLOCK;
1257 0 : t->clock = gf_node_get_scene_time(n);
1258 : }
1259 : }
1260 63 : GF_LSR_READ_INT(lsr, val, 1, "hasClock");
1261 63 : if (val) {
1262 : u32 now;
1263 45 : GF_LSR_READ_INT(lsr, val, 1, "sign");
1264 45 : now = lsr_read_vluimsbf5(lsr, "value");
1265 45 : t->clock = now;
1266 45 : t->clock /= lsr->time_resolution;
1267 45 : if (val) t->clock *= -1;
1268 : }
1269 : return t;
1270 : }
1271 :
1272 281 : static void lsr_read_smil_times(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SMIL_Times *times, const char *name, Bool skipable)
1273 : {
1274 : GF_FieldInfo info;
1275 : SMIL_Time *v;
1276 : u32 val, i, count;
1277 :
1278 281 : if (skipable) {
1279 142 : GF_LSR_READ_INT(lsr, val, 1, name);
1280 230 : if (!val) return;
1281 : }
1282 202 : if (!times) {
1283 63 : lsr->last_error = gf_node_get_attribute_by_tag(n, tag, GF_TRUE, GF_FALSE, &info);
1284 63 : times = (SMIL_Times*)info.far_ptr;
1285 : }
1286 :
1287 202 : while (gf_list_count(*times)) {
1288 0 : v = (SMIL_Time *)gf_list_last(*times);
1289 0 : gf_list_rem_last(*times);
1290 0 : if (v->element_id) gf_free(v->element_id);
1291 0 : gf_free(v);
1292 : }
1293 :
1294 202 : GF_LSR_READ_INT(lsr, val, 1, "choice");
1295 202 : if (val) {
1296 9 : GF_SAFEALLOC(v, SMIL_Time);
1297 9 : if (v) {
1298 9 : v->type = GF_SMIL_TIME_INDEFINITE;
1299 9 : gf_list_add(*times, v);
1300 : }
1301 : return;
1302 : }
1303 193 : count = lsr_read_vluimsbf5(lsr, "count");
1304 253 : for (i=0; i<count; i++) {
1305 60 : v = lsr_read_smil_time(lsr, n);
1306 60 : gf_list_add(*times, v);
1307 : }
1308 : }
1309 :
1310 143 : static void lsr_read_duration_ex(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SMIL_Duration *smil, const char *name, Bool skipable)
1311 : {
1312 : GF_FieldInfo info;
1313 : u32 val = 1;
1314 :
1315 143 : if (skipable) {
1316 137 : GF_LSR_READ_INT(lsr, val, 1, name);
1317 157 : if (!val) return;
1318 : }
1319 123 : if (!smil) {
1320 117 : lsr->last_error = gf_node_get_attribute_by_tag(n, tag, GF_TRUE, GF_FALSE, &info);
1321 117 : if (lsr->last_error) return;
1322 117 : smil = (SMIL_Duration *)info.far_ptr;
1323 : }
1324 123 : smil->type = 0;
1325 123 : smil->clock_value=0;
1326 :
1327 123 : GF_LSR_READ_INT(lsr, val, 1, "choice");
1328 123 : if (val) {
1329 3 : GF_LSR_READ_INT(lsr, smil->type, 2, "time");
1330 : } else {
1331 : Bool sign;
1332 : u32 now;
1333 120 : GF_LSR_READ_INT(lsr, sign, 1, "sign");
1334 120 : now = lsr_read_vluimsbf5(lsr, "value");
1335 120 : smil->clock_value = now;
1336 120 : smil->clock_value /= lsr->time_resolution;
1337 120 : if (sign) smil->clock_value *= -1;
1338 120 : smil->type = SMIL_DURATION_DEFINED;
1339 : }
1340 : }
1341 : static void lsr_read_duration(GF_LASeRCodec *lsr, GF_Node *n)
1342 : {
1343 137 : lsr_read_duration_ex(lsr, n, TAG_SVG_ATT_dur, NULL, "dur", GF_TRUE);
1344 : }
1345 : /*TODO Add decent error checking...*/
1346 438 : static void lsr_read_rare_full(GF_LASeRCodec *lsr, GF_Node *n)
1347 : {
1348 : GF_FieldInfo info;
1349 : u32 i, nb_rare, field_rare;
1350 : s32 field_tag;
1351 :
1352 438 : GF_LSR_READ_INT(lsr, nb_rare, 1, "has_rare");
1353 623 : if (!nb_rare) return;
1354 253 : GF_LSR_READ_INT(lsr, nb_rare, 6, "nbOfAttributes");
1355 :
1356 448 : for (i=0; i<nb_rare; i++) {
1357 448 : GF_LSR_READ_INT(lsr, field_rare, 6, "attributeRARE");
1358 :
1359 : /*lsr extend*/
1360 448 : if (field_rare==49) {
1361 : u32 extID, len, j;
1362 : while (1) {
1363 15 : GF_LSR_READ_INT(lsr, extID, lsr->info->cfg.extensionIDBits, "extensionID");
1364 15 : len = lsr_read_vluimsbf5(lsr, "len");
1365 15 : if (extID==2) {
1366 15 : GF_LSR_READ_INT(lsr, len, 2, "nbOfAttributes");
1367 15 : for (j=0; j<len; j++) {
1368 15 : GF_LSR_READ_INT(lsr, extID, 3, "attributeRARE");
1369 15 : switch (extID) {
1370 3 : case 0:
1371 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_syncMaster, GF_TRUE, GF_FALSE, &info);
1372 3 : GF_LSR_READ_INT(lsr, *(SVG_Boolean *)info.far_ptr, 1, "syncMaster");
1373 : break;
1374 3 : case 1:
1375 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_focusHighlight, GF_TRUE, GF_FALSE, &info);
1376 3 : GF_LSR_READ_INT(lsr, *(SVG_FocusHighlight *)info.far_ptr, 2, "focusHighlight");
1377 : break;
1378 3 : case 2:
1379 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_initialVisibility, GF_TRUE, GF_FALSE, &info);
1380 3 : GF_LSR_READ_INT(lsr, *(SVG_InitialVisibility *)info.far_ptr, 2, "initialVisibility");
1381 : break;
1382 3 : case 3:
1383 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_fullscreen, GF_TRUE, GF_FALSE, &info);
1384 3 : GF_LSR_READ_INT(lsr, *(SVG_Boolean *)info.far_ptr, 1, "fullscreen");
1385 : break;
1386 3 : case 4:
1387 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_requiredFonts, GF_TRUE, GF_FALSE, &info);
1388 3 : lsr_read_byte_align_string_list(lsr, *(GF_List **)info.far_ptr, "requiredFonts", GF_FALSE, GF_TRUE);
1389 3 : break;
1390 : }
1391 : }
1392 : } else {
1393 0 : gf_bs_read_int(lsr->bs, len);
1394 : }
1395 15 : GF_LSR_READ_INT(lsr, extID, 1, "hasNextExtension");
1396 15 : if (!extID) break;
1397 : }
1398 15 : continue;
1399 : }
1400 433 : field_tag = gf_lsr_rare_type_to_attribute(field_rare);
1401 433 : if (field_tag==-1) {
1402 : return;
1403 : }
1404 433 : lsr->last_error = gf_node_get_attribute_by_tag(n, field_tag, GF_TRUE, GF_FALSE, &info);
1405 433 : if (!info.far_ptr) lsr->last_error = GF_NOT_SUPPORTED;
1406 433 : if (lsr->last_error) return;
1407 :
1408 433 : switch (field_tag) {
1409 0 : case TAG_SVG_ATT__class:
1410 0 : lsr_read_byte_align_string(lsr, info.far_ptr, "class");
1411 0 : break;
1412 : /*properties*/
1413 3 : case TAG_SVG_ATT_audio_level:
1414 3 : ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "audio-level");
1415 3 : break;
1416 6 : case TAG_SVG_ATT_color:
1417 6 : lsr_read_paint(lsr, (SVG_Paint *)info.far_ptr, "color");
1418 6 : break;
1419 6 : case TAG_SVG_ATT_color_rendering:
1420 6 : GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 2, "color-rendering");
1421 : break;
1422 12 : case TAG_SVG_ATT_display:
1423 12 : GF_LSR_READ_INT(lsr, *(SVG_Display*)info.far_ptr, 5, "display");
1424 : break;
1425 3 : case TAG_SVG_ATT_display_align:
1426 3 : GF_LSR_READ_INT(lsr, *(SVG_DisplayAlign*)info.far_ptr, 3, "display-align");
1427 : break;
1428 6 : case TAG_SVG_ATT_fill_opacity:
1429 6 : ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE;
1430 6 : ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "fill-opacity");
1431 6 : break;
1432 3 : case TAG_SVG_ATT_fill_rule:
1433 3 : GF_LSR_READ_INT(lsr, *(SVG_FillRule*)info.far_ptr, 2, "fill-rule");
1434 : break;
1435 3 : case TAG_SVG_ATT_image_rendering:
1436 3 : GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 2, "image-rendering");
1437 : break;
1438 9 : case TAG_SVG_ATT_line_increment:
1439 9 : lsr_read_line_increment_type(lsr, info.far_ptr, "line-increment");
1440 9 : break;
1441 3 : case TAG_SVG_ATT_pointer_events:
1442 3 : GF_LSR_READ_INT(lsr, *(SVG_PointerEvents*)info.far_ptr, 4, "pointer-events");
1443 : break;
1444 3 : case TAG_SVG_ATT_shape_rendering:
1445 3 : GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 3, "shape-rendering");
1446 : break;
1447 6 : case TAG_SVG_ATT_solid_color:
1448 6 : lsr_read_paint(lsr, info.far_ptr, "solid-color");
1449 6 : break;
1450 3 : case TAG_SVG_ATT_solid_opacity:
1451 3 : ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE;
1452 3 : ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "solid-opacity");
1453 3 : break;
1454 21 : case TAG_SVG_ATT_stop_color:
1455 21 : lsr_read_paint(lsr, info.far_ptr, "stop-color");
1456 21 : break;
1457 24 : case TAG_SVG_ATT_stop_opacity:
1458 24 : ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE;
1459 24 : ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "stop-opacity");
1460 24 : break;
1461 9 : case TAG_SVG_ATT_stroke_dasharray:
1462 : {
1463 : u32 j, flag;
1464 : SVG_StrokeDashArray *da = (SVG_StrokeDashArray *)info.far_ptr;
1465 9 : GF_LSR_READ_INT(lsr, flag, 1, "dashArray");
1466 9 : if (flag) {
1467 6 : da->type=SVG_STROKEDASHARRAY_INHERIT;
1468 : } else {
1469 3 : da->type=SVG_STROKEDASHARRAY_ARRAY;
1470 3 : da->array.count = lsr_read_vluimsbf5(lsr, "len");
1471 3 : da->array.vals = (Fixed*)gf_malloc(sizeof(Fixed)*da->array.count);
1472 3 : da->array.units = (u8*)gf_malloc(sizeof(u8)*da->array.count);
1473 12 : for (j=0; j<da->array.count; j++) {
1474 9 : da->array.vals[j] = lsr_read_fixed_16_8(lsr, "dash");
1475 9 : da->array.units[j] = 0;
1476 : }
1477 : }
1478 : }
1479 : break;
1480 3 : case TAG_SVG_ATT_stroke_dashoffset:
1481 3 : lsr_read_fixed_16_8i(lsr, info.far_ptr, "dashOffset");
1482 3 : break;
1483 :
1484 3 : case TAG_SVG_ATT_stroke_linecap:
1485 3 : GF_LSR_READ_INT(lsr, *(SVG_StrokeLineCap*)info.far_ptr, 2, "stroke-linecap");
1486 : break;
1487 3 : case TAG_SVG_ATT_stroke_linejoin:
1488 3 : GF_LSR_READ_INT(lsr, *(SVG_StrokeLineJoin*)info.far_ptr, 2, "stroke-linejoin");
1489 : break;
1490 3 : case TAG_SVG_ATT_stroke_miterlimit:
1491 3 : lsr_read_fixed_16_8i(lsr, info.far_ptr, "miterLimit");
1492 3 : break;
1493 6 : case TAG_SVG_ATT_stroke_opacity:
1494 6 : ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE;
1495 6 : ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "stroke-opacity");
1496 6 : break;
1497 27 : case TAG_SVG_ATT_stroke_width:
1498 27 : lsr_read_fixed_16_8i(lsr, info.far_ptr, "strokeWidth");
1499 27 : break;
1500 3 : case TAG_SVG_ATT_text_anchor:
1501 3 : GF_LSR_READ_INT(lsr, *(SVG_TextAnchor*)info.far_ptr, 2, "text-achor");
1502 : break;
1503 3 : case TAG_SVG_ATT_text_rendering:
1504 3 : GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 3, "text-rendering");
1505 : break;
1506 3 : case TAG_SVG_ATT_viewport_fill:
1507 3 : lsr_read_paint(lsr, info.far_ptr, "viewport-fill");
1508 3 : break;
1509 3 : case TAG_SVG_ATT_viewport_fill_opacity:
1510 3 : ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE;
1511 3 : ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "viewport-fill-opacity");
1512 3 : break;
1513 3 : case TAG_SVG_ATT_vector_effect:
1514 3 : GF_LSR_READ_INT(lsr, *(SVG_VectorEffect*)info.far_ptr, 4, "vector-effect");
1515 : break;
1516 3 : case TAG_SVG_ATT_visibility:
1517 3 : GF_LSR_READ_INT(lsr, *(SVG_Visibility*)info.far_ptr, 2, "visibility");
1518 : break;
1519 3 : case TAG_SVG_ATT_requiredExtensions:
1520 3 : lsr_read_byte_align_string_list(lsr, *(GF_List**)info.far_ptr, "requiredExtensions", GF_TRUE, GF_FALSE);
1521 3 : break;
1522 3 : case TAG_SVG_ATT_requiredFormats:
1523 3 : lsr_read_byte_align_string_list(lsr, *(GF_List**)info.far_ptr, "requiredFormats", GF_FALSE, GF_FALSE);
1524 3 : break;
1525 3 : case TAG_SVG_ATT_requiredFeatures:
1526 : {
1527 3 : u32 j, fcount = lsr_read_vluimsbf5(lsr, "count");
1528 105 : for (j=0; j<fcount; j++) {
1529 : u32 fval;
1530 102 : GF_LSR_READ_INT(lsr, fval, 6, "feature");
1531 : }
1532 : }
1533 : break;
1534 3 : case TAG_SVG_ATT_systemLanguage:
1535 3 : lsr_read_byte_align_string_list(lsr, *(GF_List**)info.far_ptr, "systemLanguage", GF_FALSE, GF_FALSE);
1536 3 : break;
1537 3 : case TAG_XML_ATT_base:
1538 3 : lsr_read_byte_align_string(lsr, &((XMLRI*)info.far_ptr)->string, "xml:base");
1539 3 : ((XMLRI*)info.far_ptr)->type = XMLRI_STRING;
1540 3 : break;
1541 3 : case TAG_XML_ATT_lang:
1542 3 : lsr_read_byte_align_string(lsr, info.far_ptr, "xml:lang");
1543 3 : break;
1544 3 : case TAG_XML_ATT_space:
1545 3 : GF_LSR_READ_INT(lsr, *(XML_Space*)info.far_ptr, 1, "xml:space");
1546 : break;
1547 : /*focusable*/
1548 3 : case TAG_SVG_ATT_nav_next:
1549 3 : lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusNext");
1550 3 : break;
1551 3 : case TAG_SVG_ATT_nav_up:
1552 3 : lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusNorth");
1553 3 : break;
1554 3 : case TAG_SVG_ATT_nav_up_left:
1555 3 : lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusNorthEast");
1556 3 : break;
1557 3 : case TAG_SVG_ATT_nav_up_right:
1558 3 : lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusNorthWest");
1559 3 : break;
1560 3 : case TAG_SVG_ATT_nav_prev:
1561 3 : lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusPrev");
1562 3 : break;
1563 3 : case TAG_SVG_ATT_nav_down:
1564 3 : lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusSouth");
1565 3 : break;
1566 3 : case TAG_SVG_ATT_nav_down_left:
1567 3 : lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusSouthEast");
1568 3 : break;
1569 3 : case TAG_SVG_ATT_nav_down_right:
1570 3 : lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusSouthWest");
1571 3 : break;
1572 3 : case TAG_SVG_ATT_nav_left:
1573 3 : lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusEast");
1574 3 : break;
1575 3 : case TAG_SVG_ATT_focusable:
1576 3 : GF_LSR_READ_INT(lsr, *(SVG_Focusable*)info.far_ptr, 2, "focusable");
1577 : break;
1578 3 : case TAG_SVG_ATT_nav_right:
1579 3 : lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusWest");
1580 3 : break;
1581 18 : case TAG_SVG_ATT_transform:
1582 18 : lsr_read_matrix(lsr, info.far_ptr);
1583 18 : break;
1584 : case TAG_SVG_ATT_text_decoration:
1585 : /*FIXME ASAP*/
1586 : assert(0);
1587 : break;
1588 :
1589 3 : case TAG_SVG_ATT_font_variant:
1590 3 : GF_LSR_READ_INT(lsr, *(SVG_FontVariant*)info.far_ptr, 2, "font-variant");
1591 : break;
1592 3 : case TAG_SVG_ATT_font_family:
1593 : {
1594 : u32 flag;
1595 3 : GF_LSR_READ_INT(lsr, flag, 1, "isInherit");
1596 3 : if (flag) {
1597 3 : ((SVG_FontFamily*)info.far_ptr)->type = SVG_FONTFAMILY_INHERIT;
1598 : } else {
1599 : char *ft;
1600 0 : ((SVG_FontFamily*)info.far_ptr)->type = SVG_FONTFAMILY_VALUE;
1601 0 : GF_LSR_READ_INT(lsr, flag, lsr->fontIndexBits, "fontIndex");
1602 0 : ft = (char*)gf_list_get(lsr->font_table, flag);
1603 0 : if (ft) ((SVG_FontFamily*)info.far_ptr)->value = gf_strdup(ft);
1604 : }
1605 : }
1606 : break;
1607 3 : case TAG_SVG_ATT_font_size:
1608 3 : lsr_read_fixed_16_8i(lsr, info.far_ptr, "fontSize");
1609 3 : break;
1610 3 : case TAG_SVG_ATT_font_style:
1611 3 : GF_LSR_READ_INT(lsr, *(SVG_FontStyle*)info.far_ptr, 3, "fontStyle");
1612 : break;
1613 3 : case TAG_SVG_ATT_font_weight:
1614 3 : GF_LSR_READ_INT(lsr, *(SVG_FontWeight*)info.far_ptr, 4, "fontWeight");
1615 : break;
1616 3 : case TAG_XLINK_ATT_title:
1617 3 : lsr_read_byte_align_string(lsr, info.far_ptr, "xlink:title");
1618 3 : break;
1619 3 : case TAG_XLINK_ATT_type:
1620 : /*TODO FIXME*/
1621 3 : GF_LSR_READ_INT(lsr, field_rare, 3, "xlink:type");
1622 : break;
1623 3 : case TAG_XLINK_ATT_role:
1624 3 : lsr_read_any_uri(lsr, info.far_ptr, "xlink:role");
1625 3 : break;
1626 3 : case TAG_XLINK_ATT_arcrole:
1627 3 : lsr_read_any_uri(lsr, info.far_ptr, "xlink:arcrole");
1628 3 : break;
1629 3 : case TAG_XLINK_ATT_actuate:
1630 : /*TODO FIXME*/
1631 3 : GF_LSR_READ_INT(lsr, field_rare, 2, "xlink:actuate");
1632 : break;
1633 3 : case TAG_XLINK_ATT_show:
1634 : /*TODO FIXME*/
1635 3 : GF_LSR_READ_INT(lsr, field_rare, 3, "xlink:show");
1636 : break;
1637 139 : case TAG_SVG_ATT_end:
1638 139 : lsr_read_smil_times(lsr, NULL, 0, info.far_ptr, "end", 0);
1639 139 : break;
1640 3 : case TAG_SVG_ATT_max:
1641 3 : lsr_read_duration_ex(lsr, NULL, 0, info.far_ptr, "min", 0);
1642 3 : break;
1643 3 : case TAG_SVG_ATT_min:
1644 3 : lsr_read_duration_ex(lsr, NULL, 0, info.far_ptr, "min", 0);
1645 3 : break;
1646 : }
1647 433 : if (lsr->last_error) break;
1648 : }
1649 : }
1650 :
1651 : #define lsr_read_rare(_a, _b) lsr_read_rare_full(_a, _b)
1652 :
1653 239 : static void lsr_read_fill(GF_LASeRCodec *lsr, GF_Node *n)
1654 : {
1655 : Bool has_fill;
1656 239 : GF_LSR_READ_INT(lsr, has_fill, 1, "fill");
1657 239 : if (has_fill) {
1658 : GF_FieldInfo info;
1659 60 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_fill, GF_TRUE, GF_FALSE, &info);
1660 60 : lsr_read_paint(lsr, info.far_ptr, "fill");
1661 : }
1662 239 : }
1663 :
1664 230 : static void lsr_read_stroke(GF_LASeRCodec *lsr, GF_Node *n)
1665 : {
1666 : Bool has_stroke;
1667 230 : GF_LSR_READ_INT(lsr, has_stroke, 1, "has_stroke");
1668 230 : if (has_stroke) {
1669 : GF_FieldInfo info;
1670 54 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_stroke, GF_TRUE, GF_FALSE, &info);
1671 54 : lsr_read_paint(lsr, info.far_ptr, "stroke");
1672 : }
1673 230 : }
1674 215 : static void lsr_read_href(GF_LASeRCodec *lsr, GF_Node *n)
1675 : {
1676 : Bool has_href;
1677 215 : GF_LSR_READ_INT(lsr, has_href, 1, "has_href");
1678 215 : if (has_href) {
1679 : GF_FieldInfo info;
1680 71 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_XLINK_ATT_href, GF_TRUE, GF_FALSE, &info);
1681 71 : lsr_read_any_uri(lsr, info.far_ptr, "href");
1682 : }
1683 215 : }
1684 :
1685 125 : static void lsr_read_accumulate(GF_LASeRCodec *lsr, GF_Node *n)
1686 : {
1687 : Bool v;
1688 125 : GF_LSR_READ_INT(lsr, v, 1, "has_accumulate");
1689 125 : if (v) {
1690 : GF_FieldInfo info;
1691 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_accumulate, GF_TRUE, GF_FALSE, &info);
1692 3 : GF_LSR_READ_INT(lsr, *(SMIL_Accumulate*)info.far_ptr, 1, "accumulate");
1693 : }
1694 125 : }
1695 125 : static void lsr_read_additive(GF_LASeRCodec *lsr, GF_Node *n)
1696 : {
1697 : Bool v;
1698 125 : GF_LSR_READ_INT(lsr, v, 1, "has_additive");
1699 125 : if (v) {
1700 : GF_FieldInfo info;
1701 6 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_additive, GF_TRUE, GF_FALSE, &info);
1702 6 : GF_LSR_READ_INT(lsr, *(SMIL_Additive*)info.far_ptr, 1, "additive");
1703 : }
1704 125 : }
1705 125 : static void lsr_read_calc_mode(GF_LASeRCodec *lsr, GF_Node *n)
1706 : {
1707 : u32 v;
1708 : /*SMIL_CALCMODE_LINEAR is default and 0 in our code*/
1709 125 : GF_LSR_READ_INT(lsr, v, 1, "has_calcMode");
1710 125 : if (v) {
1711 : GF_FieldInfo info;
1712 15 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_calcMode, GF_TRUE, GF_FALSE, &info);
1713 15 : GF_LSR_READ_INT(lsr, *(SMIL_CalcMode*)info.far_ptr, 2, "calcMode");
1714 : }
1715 125 : }
1716 :
1717 119 : static void lsr_read_attribute_name_ex(GF_LASeRCodec *lsr, GF_Node *n, Bool skippable)
1718 : {
1719 : u32 val = 1;
1720 119 : if (skippable) {
1721 119 : GF_LSR_READ_INT(lsr, val, 1, "hasAttributeName");
1722 119 : if (!val) return;
1723 : }
1724 :
1725 110 : GF_LSR_READ_INT(lsr, val, 1, "choice");
1726 110 : if (val) {
1727 0 : lsr_read_vluimsbf5(lsr, "item[i]");
1728 0 : lsr_read_vluimsbf5(lsr, "item[i]");
1729 0 : return;
1730 : } else {
1731 : GF_FieldInfo info;
1732 110 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_attributeName, GF_TRUE, GF_FALSE, &info);
1733 110 : GF_LSR_READ_INT(lsr, val, 8, "attributeType");
1734 :
1735 : /*translate type to attribute tag*/
1736 110 : ((SMIL_AttributeName*)info.far_ptr)->type = gf_lsr_anim_type_to_attribute(val);
1737 : }
1738 : }
1739 : static void lsr_read_attribute_name(GF_LASeRCodec *lsr, GF_Node *n)
1740 : {
1741 119 : lsr_read_attribute_name_ex(lsr, n, GF_TRUE);
1742 : }
1743 :
1744 48 : static void lsr_translate_anim_value(SMIL_AnimateValue *val, u32 coded_type)
1745 : {
1746 48 : switch (val->type) {
1747 0 : case SVG_StrokeDashArray_datatype:
1748 : {
1749 : SVG_StrokeDashArray *da;
1750 0 : GF_List *l = (GF_List *)val->value;
1751 : u32 i;
1752 0 : GF_SAFEALLOC(da, SVG_StrokeDashArray);
1753 0 : if (!da) return;
1754 0 : da->array.count = gf_list_count(l);
1755 0 : if (!da->array.count) {
1756 0 : da->type = SVG_STROKEDASHARRAY_INHERIT;
1757 : } else {
1758 0 : da->type = SVG_STROKEDASHARRAY_ARRAY;
1759 0 : da->array.vals = (Fixed *) gf_malloc(sizeof(Fixed)*da->array.count);
1760 0 : da->array.units = (u8 *) gf_malloc(sizeof(u8)*da->array.count);
1761 0 : for (i=0; i<da->array.count; i++) {
1762 0 : Fixed *v = (Fixed *)gf_list_get(l, i);
1763 0 : da->array.vals[i] = *v;
1764 0 : da->array.units[i] = 0;
1765 0 : gf_free(v);
1766 : }
1767 0 : gf_list_del(l);
1768 0 : val->value = da;
1769 : }
1770 : }
1771 : break;
1772 0 : case SVG_ViewBox_datatype:
1773 : {
1774 : SVG_ViewBox *vb;
1775 0 : GF_List *l = (GF_List *)val->value;
1776 0 : GF_SAFEALLOC(vb, SVG_ViewBox);
1777 0 : if (!vb) return;
1778 0 : if (gf_list_count(l)==4) {
1779 0 : vb->x = * ((Fixed *)gf_list_get(l, 0));
1780 0 : vb->y = * ((Fixed *)gf_list_get(l, 1));
1781 0 : vb->width = * ((Fixed *)gf_list_get(l, 2));
1782 0 : vb->height = * ((Fixed *)gf_list_get(l, 3));
1783 : }
1784 0 : while (gf_list_count(l)) {
1785 0 : Fixed *v = (Fixed *)gf_list_last(l);
1786 0 : gf_free(v);
1787 0 : gf_list_rem_last(l);
1788 : }
1789 0 : gf_list_del(l);
1790 0 : val->value = vb;
1791 : }
1792 : break;
1793 0 : case SVG_Coordinates_datatype:
1794 : {
1795 : SVG_Coordinates *coords;
1796 0 : if (coded_type==1) {
1797 0 : GF_List *l = gf_list_new();
1798 : /*allocated value is already an SVG number*/
1799 0 : gf_list_add(l, val->value);
1800 0 : coords = (SVG_Coordinates*)gf_malloc(sizeof(SVG_Coordinates));
1801 0 : *coords = l;
1802 0 : val->value = coords;
1803 0 : } else if (coded_type==8) {
1804 0 : GF_List *l = (GF_List *)val->value;
1805 0 : u32 i, count = gf_list_count(l);
1806 0 : for (i=0; i<count; i++) {
1807 : SVG_Coordinate *c;
1808 0 : Fixed *v = (Fixed *)gf_list_get(l, i);
1809 0 : c = (SVG_Coordinate*)gf_malloc(sizeof(SVG_Coordinate));
1810 0 : c->type = SVG_NUMBER_VALUE;
1811 0 : c->value = *v;
1812 0 : gf_free(v);
1813 0 : gf_list_rem(l, i);
1814 0 : gf_list_insert(l, c, i);
1815 : }
1816 0 : coords = (SVG_Coordinates*)gf_malloc(sizeof(SVG_Coordinates));
1817 0 : *coords = (GF_List *) val->value;
1818 0 : val->value = coords;
1819 : }
1820 : }
1821 : break;
1822 0 : case SVG_Motion_datatype:
1823 0 : if (coded_type==9) {
1824 : GF_Matrix2D *mat;
1825 0 : SVG_Point *pt = (SVG_Point *)val->value;
1826 0 : GF_SAFEALLOC(mat, GF_Matrix2D);
1827 0 : if (mat) {
1828 0 : gf_mx2d_init(*mat);
1829 0 : mat->m[2] = pt->x;
1830 0 : mat->m[5] = pt->y;
1831 0 : val->value = mat;
1832 : }
1833 0 : gf_free(pt);
1834 : }
1835 : break;
1836 : }
1837 : }
1838 57 : static void lsr_translate_anim_values(SMIL_AnimateValues *val, u32 coded_type)
1839 : {
1840 : u32 i, count;
1841 : GF_List *list, *new_list;
1842 :
1843 57 : list = val->values;
1844 57 : switch (val->type) {
1845 : case SVG_StrokeDashArray_datatype:
1846 : break;
1847 : case SVG_ViewBox_datatype:
1848 : break;
1849 : case SVG_Coordinates_datatype:
1850 : break;
1851 0 : case SVG_Motion_datatype:
1852 0 : if (coded_type!=9) return;
1853 : break;
1854 : default:
1855 : return;
1856 : }
1857 3 : val->values = new_list = gf_list_new();
1858 3 : count = gf_list_count(list);
1859 12 : for (i=0; i<count; i++) {
1860 9 : switch (val->type) {
1861 9 : case SVG_StrokeDashArray_datatype:
1862 : {
1863 : SVG_StrokeDashArray *da;
1864 9 : GF_List *l = (GF_List *)gf_list_get(list, i);
1865 : u32 j;
1866 9 : GF_SAFEALLOC(da, SVG_StrokeDashArray);
1867 9 : if (!da) return;
1868 9 : da->array.count = gf_list_count(l);
1869 9 : if (!da->array.count) {
1870 3 : da->type = SVG_STROKEDASHARRAY_INHERIT;
1871 : } else {
1872 6 : da->type = SVG_STROKEDASHARRAY_ARRAY;
1873 6 : da->array.vals = (Fixed *)gf_malloc(sizeof(Fixed)*da->array.count);
1874 6 : da->array.units = (u8 *) gf_malloc(sizeof(u8)*da->array.count);
1875 24 : for (j=0; j<da->array.count; j++) {
1876 18 : Fixed *v = (Fixed *)gf_list_get(l, j);
1877 18 : da->array.vals[j] = *v;
1878 18 : da->array.units[j] = 0;
1879 18 : gf_free(v);
1880 : }
1881 : }
1882 9 : gf_list_del(l);
1883 9 : gf_list_add(new_list, da);
1884 : }
1885 9 : break;
1886 0 : case SVG_ViewBox_datatype:
1887 : {
1888 : SVG_ViewBox *vb;
1889 0 : GF_List *l = (GF_List *)gf_list_get(list, i);
1890 0 : GF_SAFEALLOC(vb, SVG_ViewBox);
1891 0 : if (!vb) return;
1892 0 : if (gf_list_count(l)==4) {
1893 0 : vb->x = * ((Fixed *)gf_list_get(l, 0));
1894 0 : vb->y = * ((Fixed *)gf_list_get(l, 1));
1895 0 : vb->width = * ((Fixed *)gf_list_get(l, 2));
1896 0 : vb->height = * ((Fixed *)gf_list_get(l, 3));
1897 : }
1898 0 : while (gf_list_count(l)) {
1899 0 : Fixed *v=(Fixed *)gf_list_last(l);
1900 0 : gf_free(v);
1901 0 : gf_list_rem_last(l);
1902 : }
1903 0 : gf_list_del(l);
1904 0 : gf_list_add(new_list, vb);
1905 : }
1906 0 : break;
1907 0 : case SVG_Coordinates_datatype:
1908 : {
1909 : SVG_Coordinates *coords;
1910 0 : GF_List *l = (GF_List *)gf_list_get(list, i);
1911 : u32 j, count2;
1912 0 : count2 = gf_list_count(l);
1913 0 : for (j=0; j<count2; j++) {
1914 0 : SVG_Coordinate *c = (SVG_Coordinate *)gf_malloc(sizeof(SVG_Coordinate));
1915 0 : Fixed *v = (Fixed *)gf_list_get(l, j);
1916 0 : c->type = SVG_NUMBER_VALUE;
1917 0 : c->value = *v;
1918 0 : gf_list_rem(l, j);
1919 0 : gf_list_insert(l, c, j);
1920 0 : gf_free(v);
1921 : }
1922 :
1923 0 : coords = (SVG_Coordinates*)gf_malloc(sizeof(SVG_Coordinates));
1924 0 : *coords = l;
1925 0 : gf_list_add(new_list, coords);
1926 : }
1927 0 : break;
1928 :
1929 0 : case SVG_Motion_datatype:
1930 : {
1931 0 : GF_Matrix2D *m = (GF_Matrix2D *)gf_malloc(sizeof(GF_Matrix2D ));
1932 0 : GF_Point2D *pt = (GF_Point2D *)gf_list_get(list, i);
1933 0 : gf_mx2d_init(*m);
1934 0 : m->m[2] = pt->x;
1935 0 : m->m[5] = pt->y;
1936 0 : gf_free(pt);
1937 0 : gf_list_add(new_list, m);
1938 : }
1939 0 : break;
1940 : }
1941 : }
1942 3 : gf_list_del(list);
1943 : }
1944 :
1945 613 : static Bool lsr_init_smil_times(GF_LASeRCodec *lsr, SVG_Element *anim, GF_List *times, SVG_Element *parent)
1946 : {
1947 : u32 i, count;
1948 613 : count = gf_list_count(times);
1949 270 : for (i=0; i<count; i++) {
1950 270 : SMIL_Time *t = (SMIL_Time *)gf_list_get(times, i);
1951 270 : if (t->type==GF_SMIL_TIME_EVENT) {
1952 3 : if (t->element_id) {
1953 0 : if (t->element_id[0]=='N') {
1954 0 : t->element = gf_sg_find_node(lsr->sg, atoi(t->element_id+1) + 1);
1955 : } else {
1956 0 : t->element = gf_sg_find_node_by_name(lsr->sg, t->element_id);
1957 : }
1958 0 : if (!t->element) return GF_FALSE;
1959 0 : gf_free(t->element_id);
1960 0 : t->element_id = NULL;
1961 : }
1962 3 : else if (!t->element) {
1963 0 : if (t->event.parameter && (t->event.type==GF_EVENT_KEYDOWN) ) {
1964 0 : t->element = lsr->sg->RootNode ? lsr->sg->RootNode : lsr->current_root;
1965 : } else {
1966 0 : t->element = (GF_Node*)parent;
1967 : }
1968 : }
1969 : }
1970 : }
1971 : return GF_TRUE;
1972 : }
1973 :
1974 448 : static Bool lsr_setup_smil_anim(GF_LASeRCodec *lsr, SVG_Element *anim, SVG_Element *anim_parent)
1975 : {
1976 : GF_FieldInfo info;
1977 : u32 coded_type, not_res;
1978 : GF_Node *target;
1979 : Bool is_animateMotion, is_animateTransform;
1980 : XMLRI *xlink;
1981 : SMIL_AttributeName *name = NULL;
1982 : SMIL_AnimateValue *value;
1983 :
1984 : /*setup smil events*/
1985 : not_res = 0;
1986 448 : if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_SVG_ATT_begin, GF_FALSE, GF_FALSE, &info)==GF_OK) {
1987 264 : if (!lsr_init_smil_times(lsr, anim, *(GF_List**)info.far_ptr, anim_parent)) not_res++;
1988 : }
1989 :
1990 448 : if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_SVG_ATT_end, GF_FALSE, GF_FALSE, &info)==GF_OK) {
1991 349 : if (!lsr_init_smil_times(lsr, anim, *(GF_List**)info.far_ptr, anim_parent)) not_res++;
1992 : }
1993 :
1994 :
1995 : /*get xlink*/
1996 : xlink = NULL;
1997 448 : if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_XLINK_ATT_href, GF_FALSE, GF_FALSE, &info)==GF_OK) {
1998 365 : xlink = info.far_ptr;
1999 : }
2000 :
2001 : /*setup target node*/
2002 365 : if (!xlink || !xlink->target) {
2003 : /*target not received*/
2004 110 : if (xlink && (xlink->type == XMLRI_ELEMENTID)) return GF_FALSE;
2005 :
2006 83 : if (!xlink) {
2007 : /*target is parent, initialize xlink (needed by anim module)*/
2008 83 : if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_XLINK_ATT_href, GF_TRUE, GF_FALSE, &info)==GF_OK) {
2009 83 : xlink = info.far_ptr;
2010 : } else {
2011 : return GF_FALSE;
2012 : }
2013 : }
2014 :
2015 83 : xlink->type = XMLRI_ELEMENTID;
2016 83 : xlink->target = anim_parent;
2017 83 : gf_node_register_iri(lsr->sg, xlink);
2018 83 : target = (GF_Node *)anim_parent;
2019 : } else {
2020 : target = (GF_Node *)xlink->target;
2021 : }
2022 421 : if (!target || not_res) return GF_FALSE;
2023 :
2024 : is_animateTransform = is_animateMotion = GF_FALSE;
2025 421 : if (anim->sgprivate->tag==TAG_SVG_animateMotion) is_animateMotion = GF_TRUE;
2026 413 : else if (anim->sgprivate->tag==TAG_SVG_animateTransform) {
2027 : is_animateTransform = GF_TRUE;
2028 : }
2029 : if (is_animateMotion) goto translate_vals;
2030 :
2031 : /*for all except animateMotion, get attributeName*/
2032 413 : if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_SVG_ATT_attributeName, GF_FALSE, GF_FALSE, &info)==GF_OK) {
2033 110 : name = info.far_ptr;
2034 : }
2035 110 : if (!name) {
2036 : return GF_FALSE;
2037 : }
2038 :
2039 110 : if (!name->field_ptr) {
2040 110 : if (gf_node_get_attribute_by_tag((GF_Node *)target, name->type, GF_TRUE, GF_FALSE, &info)!=GF_OK) return GF_FALSE;
2041 110 : name->field_ptr = info.far_ptr;
2042 110 : name->type = info.fieldType;
2043 110 : name->tag = info.fieldIndex;
2044 : }
2045 :
2046 :
2047 : /*browse all anim types and retranslate anim values. This must be done in 2 steps since we may not have received
2048 : the target node when parsing the animation node*/
2049 118 : translate_vals:
2050 :
2051 : /*and setup anim values*/
2052 118 : if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_SVG_ATT_from, GF_FALSE, GF_FALSE, &info)==GF_OK) {
2053 27 : if (is_animateTransform) {
2054 6 : name->type = ((SMIL_AnimateValue*)info.far_ptr)->type;
2055 : } else {
2056 21 : value = info.far_ptr;
2057 21 : coded_type = value->type;
2058 21 : value->type = is_animateMotion ? SVG_Motion_datatype : name->type;
2059 21 : lsr_translate_anim_value(value, coded_type);
2060 : }
2061 : }
2062 118 : if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_SVG_ATT_by, GF_FALSE, GF_FALSE, &info)==GF_OK) {
2063 9 : if (is_animateTransform) {
2064 6 : name->type = ((SMIL_AnimateValue*)info.far_ptr)->type;
2065 : } else {
2066 3 : value = info.far_ptr;
2067 3 : coded_type = value->type;
2068 3 : value->type = is_animateMotion ? SVG_Motion_datatype : name->type;
2069 3 : lsr_translate_anim_value(value, coded_type);
2070 : }
2071 : }
2072 118 : if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_SVG_ATT_to, GF_FALSE, GF_FALSE, &info)==GF_OK) {
2073 30 : if (is_animateTransform) {
2074 6 : name->type = ((SMIL_AnimateValue*)info.far_ptr)->type;
2075 : } else {
2076 24 : value = info.far_ptr;
2077 24 : coded_type = value->type;
2078 24 : value->type = is_animateMotion ? SVG_Motion_datatype : name->type;
2079 24 : lsr_translate_anim_value(value, coded_type);
2080 : }
2081 : }
2082 118 : if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_SVG_ATT_values, GF_FALSE, GF_FALSE, &info)==GF_OK) {
2083 57 : if (is_animateTransform) {
2084 0 : name->type = ((SMIL_AnimateValues*)info.far_ptr)->type;
2085 : } else {
2086 57 : SMIL_AnimateValues *values = info.far_ptr;
2087 57 : coded_type = values->type;
2088 57 : values->type = is_animateMotion ? SVG_Motion_datatype : name->type;
2089 57 : values->laser_strings = 0;
2090 57 : lsr_translate_anim_values(values, coded_type);
2091 : }
2092 : }
2093 :
2094 : return GF_TRUE;
2095 : }
2096 :
2097 127 : static void lsr_read_anim_fill(GF_LASeRCodec *lsr, GF_Node *n)
2098 : {
2099 : u32 val;
2100 :
2101 127 : GF_LSR_READ_INT(lsr, val, 1, "has_smil_fill");
2102 127 : if (val) {
2103 : GF_FieldInfo info;
2104 24 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_smil_fill, GF_TRUE, 0, &info);
2105 : /*enumeration freeze{0} remove{1}*/
2106 24 : GF_LSR_READ_INT(lsr, val, 1, "smil_fill");
2107 24 : *(SMIL_Fill*)info.far_ptr = val ? SMIL_FILL_REMOVE : SMIL_FILL_FREEZE;
2108 : }
2109 127 : }
2110 137 : static void lsr_read_anim_repeatCount(GF_LASeRCodec *lsr, GF_Node *n)
2111 : {
2112 : u32 val;
2113 137 : GF_LSR_READ_INT(lsr, val, 1, "has_repeatCount");
2114 137 : if (val) {
2115 : GF_FieldInfo info;
2116 21 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_repeatCount, GF_TRUE, 0, &info);
2117 21 : GF_LSR_READ_INT(lsr, val, 1, "repeatCount");
2118 21 : if (val) ((SMIL_RepeatCount*)info.far_ptr)->type = SMIL_REPEATCOUNT_INDEFINITE;
2119 : else {
2120 9 : ((SMIL_RepeatCount*)info.far_ptr)->type = SMIL_REPEATCOUNT_DEFINED;
2121 9 : ((SMIL_RepeatCount*)info.far_ptr)->count = lsr_read_fixed_16_8(lsr, "repeatCount");
2122 : }
2123 : }
2124 137 : }
2125 137 : static void lsr_read_repeat_duration(GF_LASeRCodec *lsr, GF_Node *n)
2126 : {
2127 : u32 flag;
2128 137 : GF_LSR_READ_INT(lsr, flag, 1, "has_repeatDur");
2129 137 : if (flag) {
2130 : GF_FieldInfo info;
2131 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_repeatDur, GF_TRUE, 0, &info);
2132 3 : GF_LSR_READ_INT(lsr, flag, 1, "choice");
2133 :
2134 3 : if (flag) {
2135 0 : ((SMIL_Duration *)info.far_ptr)->type = SMIL_DURATION_INDEFINITE;
2136 : } else {
2137 3 : ((SMIL_Duration *)info.far_ptr)->clock_value = (Double) lsr_read_vluimsbf5(lsr, "value");
2138 3 : ((SMIL_Duration *)info.far_ptr)->clock_value /= lsr->time_resolution;
2139 3 : ((SMIL_Duration *)info.far_ptr)->type = SMIL_DURATION_DEFINED;
2140 : }
2141 : }
2142 137 : }
2143 137 : static void lsr_read_anim_restart(GF_LASeRCodec *lsr, GF_Node *n)
2144 : {
2145 : u32 val;
2146 137 : GF_LSR_READ_INT(lsr, val, 1, "has_restart");
2147 137 : if (val) {
2148 : GF_FieldInfo info;
2149 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_restart, GF_TRUE, 0, &info);
2150 : /*enumeration always{0} never{1} whenNotActive{2}*/
2151 3 : GF_LSR_READ_INT(lsr, *(SMIL_Restart*)info.far_ptr, 2, "restart");
2152 : }
2153 137 : }
2154 :
2155 321 : static void *lsr_read_an_anim_value(GF_LASeRCodec *lsr, u32 coded_type, const char *name)
2156 : {
2157 : u32 flag;
2158 : u32 escapeFlag, escape_val = 0;
2159 : u8 *enum_val;
2160 : u32 *id_val;
2161 : char *string;
2162 : SVG_String *svg_string;
2163 : SVG_Number *num;
2164 : XMLRI *iri;
2165 : SVG_Point *pt;
2166 : SVG_Paint *paint;
2167 :
2168 321 : GF_LSR_READ_INT(lsr, escapeFlag, 1, "escapeFlag");
2169 321 : if (escapeFlag) GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum");
2170 :
2171 321 : switch (coded_type) {
2172 48 : case 0:
2173 48 : string = NULL;
2174 48 : lsr_read_byte_align_string(lsr, &string, name);
2175 48 : GF_SAFEALLOC(svg_string, SVG_String);
2176 48 : if (!svg_string) return NULL;
2177 48 : *svg_string = string;
2178 48 : return svg_string;
2179 81 : case 1:
2180 81 : num = (SVG_Number*)gf_malloc(sizeof(SVG_Number));
2181 81 : if (escapeFlag) {
2182 3 : num->type = (escape_val==1) ? SVG_NUMBER_INHERIT : SVG_NUMBER_VALUE;
2183 : } else {
2184 78 : num->type = SVG_NUMBER_VALUE;
2185 78 : num->value = lsr_read_fixed_16_8(lsr, name);
2186 : }
2187 : return num;
2188 6 : case 2:
2189 : {
2190 6 : SVG_PathData *pd = (SVG_PathData *)gf_svg_create_attribute_value(SVG_PathData_datatype);
2191 6 : lsr_read_path_type(lsr, NULL, 0, pd, name);
2192 6 : return pd;
2193 : }
2194 0 : case 3:
2195 : {
2196 0 : SVG_Points *pts = (SVG_Points *)gf_svg_create_attribute_value(SVG_Points_datatype);
2197 0 : lsr_read_point_sequence(lsr, *pts, name);
2198 0 : return pts;
2199 : }
2200 0 : case 4:
2201 0 : num = (SVG_Number*)gf_malloc(sizeof(SVG_Number));
2202 0 : if (escapeFlag) {
2203 0 : num->type = (escape_val==1) ? SVG_NUMBER_INHERIT : SVG_NUMBER_VALUE;
2204 : } else {
2205 0 : num->type = SVG_NUMBER_VALUE;
2206 0 : num->value = lsr_read_fixed_clamp(lsr, name);
2207 : }
2208 : return num;
2209 39 : case 5:
2210 39 : GF_SAFEALLOC(paint, SVG_Paint);
2211 39 : if (!paint) return NULL;
2212 39 : if (escapeFlag) {
2213 0 : paint->type = SVG_PAINT_INHERIT;
2214 : } else {
2215 39 : lsr_read_paint(lsr, paint, name);
2216 : }
2217 : return paint;
2218 93 : case 6:
2219 93 : enum_val = (u8*)gf_malloc(sizeof(u8));
2220 93 : *enum_val = lsr_read_vluimsbf5(lsr, name);
2221 93 : return enum_val;
2222 : /*TODO check this is correct*/
2223 0 : case 7:
2224 : {
2225 0 : GF_List *l = gf_list_new();
2226 : u32 i, count;
2227 0 : count = lsr_read_vluimsbf5(lsr, "count");
2228 0 : for (i=0; i<count; i++) {
2229 0 : u8 *v = (u8 *)gf_malloc(sizeof(u8));
2230 0 : *v = lsr_read_vluimsbf5(lsr, "val");
2231 0 : gf_list_add(l, v);
2232 : }
2233 : return l;
2234 : }
2235 : /*TODO check this is correct*/
2236 15 : case 8: // floats
2237 : {
2238 15 : GF_List *l = gf_list_new();
2239 : u32 i, count;
2240 15 : count = lsr_read_vluimsbf5(lsr, "count");
2241 51 : for (i=0; i<count; i++) {
2242 36 : Fixed *v = (Fixed *)gf_malloc(sizeof(Fixed));
2243 36 : *v = lsr_read_fixed_16_8(lsr, "val");
2244 36 : gf_list_add(l, v);
2245 : }
2246 : return l;
2247 : }
2248 :
2249 : /*point */
2250 3 : case 9:
2251 3 : pt = (SVG_Point*)gf_malloc(sizeof(SVG_Point));
2252 3 : GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, "valX");
2253 6 : pt->x = lsr_translate_coords(lsr, flag, lsr->coord_bits);
2254 3 : GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, "valY");
2255 6 : pt->y = lsr_translate_coords(lsr, flag, lsr->coord_bits);
2256 3 : return pt;
2257 0 : case 10:
2258 0 : id_val = (u32*)gf_malloc(sizeof(u32));
2259 0 : *id_val = lsr_read_vluimsbf5(lsr, name);
2260 0 : return id_val;
2261 15 : case 11:
2262 : {
2263 : SVG_FontFamily *ft;
2264 : u32 idx;
2265 15 : GF_SAFEALLOC(ft, SVG_FontFamily);
2266 15 : if (!ft) return NULL;
2267 15 : if (escapeFlag) {
2268 0 : ft->type = SVG_FONTFAMILY_INHERIT;
2269 : } else {
2270 15 : idx = lsr_read_vluimsbf5(lsr, name);
2271 15 : ft->type = SVG_FONTFAMILY_VALUE;
2272 15 : ft->value = (char*)gf_list_get(lsr->font_table, idx);
2273 15 : if (ft->value) ft->value = gf_strdup(ft->value);
2274 : }
2275 : return ft;
2276 : }
2277 21 : case 12:
2278 21 : GF_SAFEALLOC(iri, XMLRI);
2279 21 : if (iri)
2280 21 : lsr_read_any_uri(lsr, iri, name);
2281 : return iri;
2282 0 : default:
2283 0 : lsr_read_extension(lsr, name);
2284 : break;
2285 : }
2286 0 : return NULL;
2287 : }
2288 :
2289 18 : static void lsr_translate_anim_trans_value(SMIL_AnimateValue *val, u32 transform_type)
2290 : {
2291 : SVG_Point_Angle *p;
2292 : Fixed *f;
2293 18 : u32 coded_type = val->type;
2294 :
2295 18 : switch(transform_type) {
2296 3 : case SVG_TRANSFORM_TRANSLATE:
2297 3 : val->type = SVG_Transform_Translate_datatype;
2298 3 : break;
2299 0 : case SVG_TRANSFORM_SCALE:
2300 0 : val->type = SVG_Transform_Scale_datatype;
2301 0 : break;
2302 6 : case SVG_TRANSFORM_ROTATE:
2303 6 : val->type = SVG_Transform_Rotate_datatype;
2304 6 : break;
2305 3 : case SVG_TRANSFORM_SKEWX:
2306 3 : val->type = SVG_Transform_SkewX_datatype;
2307 3 : break;
2308 6 : case SVG_TRANSFORM_SKEWY:
2309 6 : val->type = SVG_Transform_SkewY_datatype;
2310 6 : break;
2311 0 : case SVG_TRANSFORM_MATRIX:
2312 0 : val->type = SVG_Transform_datatype;
2313 0 : break;
2314 0 : default:
2315 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[LSR Parsing] unknown datatype for animate transform.\n"));
2316 : return;
2317 : }
2318 18 : if (!val->value) return;
2319 18 : switch (transform_type) {
2320 6 : case SVG_TRANSFORM_ROTATE:
2321 6 : p = (SVG_Point_Angle*)gf_malloc(sizeof(SVG_Point_Angle));
2322 6 : p->x = p->y = 0;
2323 6 : if (coded_type==8) {
2324 6 : GF_List *l = (GF_List *)val->value;
2325 6 : f = (Fixed*)gf_list_get(l, 0);
2326 6 : if (f) {
2327 6 : p->angle = *f;
2328 6 : gf_free(f);
2329 : }
2330 6 : f = (Fixed*)gf_list_get(l, 1);
2331 6 : if (f) {
2332 6 : p->x = *f;
2333 6 : gf_free(f);
2334 : }
2335 6 : f = (Fixed*)gf_list_get(l, 2);
2336 6 : if (f) {
2337 6 : p->y = *f;
2338 6 : gf_free(f);
2339 : }
2340 6 : gf_list_del(l);
2341 : } else {
2342 0 : p->angle = ((SVG_Number *)val->value)->value;
2343 0 : gf_free(val->value);
2344 : }
2345 6 : p->angle = gf_muldiv(p->angle, GF_PI, INT2FIX(180) );
2346 6 : val->value = p;
2347 6 : break;
2348 0 : case SVG_TRANSFORM_SCALE:
2349 0 : if (coded_type==8) {
2350 : SVG_Point *pt;
2351 : GF_List *l = (GF_List *)val->value;
2352 0 : GF_SAFEALLOC(pt , SVG_Point);
2353 0 : if (!pt) return;
2354 0 : f = (Fixed*)gf_list_get(l, 0);
2355 0 : if (f) {
2356 0 : pt->x = *f;
2357 0 : gf_free(f);
2358 : }
2359 0 : f = (Fixed*)gf_list_get(l, 1);
2360 0 : if (f) {
2361 0 : pt->y = *f;
2362 0 : gf_free(f);
2363 : }
2364 0 : else pt->y = pt->x;
2365 0 : gf_list_del(l);
2366 0 : val->value = pt;
2367 : }
2368 : break;
2369 9 : case SVG_TRANSFORM_SKEWX:
2370 : case SVG_TRANSFORM_SKEWY:
2371 9 : f = (Fixed*)gf_malloc(sizeof(Fixed));
2372 9 : *f = ((SVG_Number *)val->value)->value;
2373 9 : gf_free(val->value);
2374 9 : val->value = f;
2375 9 : break;
2376 : }
2377 : }
2378 :
2379 0 : static void lsr_translate_anim_trans_values(SMIL_AnimateValues *val, u32 transform_type)
2380 : {
2381 : u32 count, i, coded_type;
2382 : SVG_Point_Angle *p;
2383 : SVG_Point *pt;
2384 : Fixed *f;
2385 : GF_List *l;
2386 :
2387 0 : coded_type = val->type;
2388 0 : switch(transform_type) {
2389 0 : case SVG_TRANSFORM_TRANSLATE:
2390 0 : val->type = SVG_Transform_Translate_datatype;
2391 0 : break;
2392 0 : case SVG_TRANSFORM_SCALE:
2393 0 : val->type = SVG_Transform_Scale_datatype;
2394 0 : break;
2395 0 : case SVG_TRANSFORM_ROTATE:
2396 0 : val->type = SVG_Transform_Rotate_datatype;
2397 0 : break;
2398 0 : case SVG_TRANSFORM_SKEWX:
2399 0 : val->type = SVG_Transform_SkewX_datatype;
2400 0 : break;
2401 0 : case SVG_TRANSFORM_SKEWY:
2402 0 : val->type = SVG_Transform_SkewY_datatype;
2403 0 : break;
2404 0 : case SVG_TRANSFORM_MATRIX:
2405 0 : val->type = SVG_Transform_datatype;
2406 0 : break;
2407 0 : default:
2408 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] unknown datatype for animate transform.\n"));
2409 : return;
2410 : }
2411 0 : count = gf_list_count(val->values);
2412 0 : if (!count) return;
2413 :
2414 0 : if (transform_type==SVG_TRANSFORM_TRANSLATE)
2415 : return;
2416 :
2417 0 : for (i=0; i<count; i++) {
2418 0 : void *a_val = gf_list_get(val->values, i);
2419 0 : switch (transform_type) {
2420 0 : case SVG_TRANSFORM_ROTATE:
2421 0 : GF_SAFEALLOC(p, SVG_Point_Angle);
2422 0 : if (!p) return;
2423 :
2424 0 : if (coded_type==8) {
2425 : l = (GF_List*)a_val;
2426 0 : f = (Fixed*)gf_list_get(l, 0);
2427 0 : p->angle = *f;
2428 0 : f = (Fixed*)gf_list_get(l, 1);
2429 0 : if (f) p->x = *f;
2430 0 : f = (Fixed*)gf_list_get(l, 2);
2431 0 : if (f) p->y = *f;
2432 0 : while (gf_list_count(l)) {
2433 0 : f = (Fixed*)gf_list_last(l);
2434 0 : gf_list_rem_last(l);
2435 0 : gf_free(f);
2436 : }
2437 0 : gf_list_del(l);
2438 0 : } else if (coded_type==1) {
2439 0 : p->angle = ((SVG_Number *)a_val)->value;
2440 0 : gf_free(a_val);
2441 : }
2442 0 : p->angle = gf_muldiv(p->angle, GF_PI, INT2FIX(180) );
2443 0 : gf_list_rem(val->values, i);
2444 0 : gf_list_insert(val->values, p, i);
2445 0 : break;
2446 0 : case SVG_TRANSFORM_SKEWX:
2447 : case SVG_TRANSFORM_SKEWY:
2448 0 : f = (Fixed*)gf_malloc(sizeof(Fixed));
2449 0 : *f = ((SVG_Number *)a_val)->value;
2450 0 : gf_free(a_val);
2451 0 : gf_list_rem(val->values, i);
2452 0 : gf_list_insert(val->values, f, i);
2453 0 : break;
2454 0 : case SVG_TRANSFORM_SCALE:
2455 0 : pt = (SVG_Point*)gf_malloc(sizeof(SVG_Point));
2456 : l = (GF_List*)a_val;
2457 0 : f = (Fixed*)gf_list_get(l, 0);
2458 0 : if (f) pt->x = *f;
2459 0 : f = (Fixed*)gf_list_get(l, 1);
2460 0 : if (f) pt->y = *f;
2461 0 : else pt->y = pt->x;
2462 0 : while (gf_list_count(l)) {
2463 0 : f = (Fixed*)gf_list_last(l);
2464 0 : gf_list_rem_last(l);
2465 0 : gf_free(f);
2466 : }
2467 0 : gf_list_del(l);
2468 0 : gf_list_rem(val->values, i);
2469 0 : gf_list_insert(val->values, pt, i);
2470 0 : break;
2471 0 : default:
2472 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[LASeR] unknown transform type %d\n", transform_type));
2473 : break;
2474 : }
2475 : }
2476 : }
2477 :
2478 377 : static void lsr_read_anim_value_ex(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, const char *name, u32 *tr_type)
2479 : {
2480 : u32 val, coded_type;
2481 377 : GF_LSR_READ_INT(lsr, val, 1, name);
2482 377 : if (val) {
2483 : GF_FieldInfo info;
2484 66 : lsr->last_error = gf_node_get_attribute_by_tag(n, tag, GF_TRUE, 0, &info);
2485 :
2486 66 : GF_LSR_READ_INT(lsr, coded_type, 4, "type");
2487 66 : ((SMIL_AnimateValue*)info.far_ptr)->value = lsr_read_an_anim_value(lsr, coded_type, name);
2488 66 : ((SMIL_AnimateValue*)info.far_ptr)->type = coded_type;
2489 :
2490 66 : if (tr_type) {
2491 18 : lsr_translate_anim_trans_value(info.far_ptr, *tr_type);
2492 : }
2493 : }
2494 377 : }
2495 :
2496 125 : static void lsr_read_anim_values_ex(GF_LASeRCodec *lsr, GF_Node *n, u32 *tr_type)
2497 : {
2498 : u32 flag, i, count = 0;
2499 : u32 coded_type;
2500 : GF_FieldInfo info;
2501 : SMIL_AnimateValues *values;
2502 :
2503 125 : GF_LSR_READ_INT(lsr, flag, 1, "values");
2504 187 : if (!flag) return;
2505 :
2506 63 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_values, GF_TRUE, 0, &info);
2507 63 : values = (SMIL_AnimateValues *)info.far_ptr;
2508 :
2509 63 : GF_LSR_READ_INT(lsr, coded_type, 4, "type");
2510 63 : values->type = coded_type;
2511 63 : values->laser_strings = 1;
2512 :
2513 63 : count = lsr_read_vluimsbf5(lsr, "count");
2514 318 : for (i=0; i<count; i++) {
2515 255 : void *att = lsr_read_an_anim_value(lsr, coded_type, "a_value");
2516 255 : if (att) gf_list_add(values->values, att);
2517 : }
2518 63 : if (tr_type) {
2519 0 : lsr_translate_anim_trans_values(info.far_ptr, *tr_type);
2520 : }
2521 : }
2522 : #define lsr_read_anim_value(_a, _b, _c, _d) lsr_read_anim_value_ex(_a, _b, _c, _d, NULL)
2523 : #define lsr_read_anim_values(_a, _b) lsr_read_anim_values_ex(_a, _b, NULL)
2524 :
2525 63 : static Fixed *lsr_read_fraction_12_item(GF_LASeRCodec *lsr)
2526 : {
2527 : u32 flag;
2528 : Fixed *f;
2529 63 : GF_SAFEALLOC(f, Fixed);
2530 63 : if (!f) {
2531 0 : lsr->last_error = GF_OUT_OF_MEM;
2532 : return NULL;
2533 : }
2534 63 : GF_LSR_READ_INT(lsr, flag, 1, "hasShort");
2535 63 : if (flag) {
2536 45 : GF_LSR_READ_INT(lsr, flag, 1, "isZero");
2537 45 : if (flag) *f = 0;
2538 21 : else *f = FIX_ONE;
2539 : } else {
2540 : u32 v;
2541 18 : GF_LSR_READ_INT(lsr, v, 12, "val");
2542 18 : *f = INT2FIX(v) / 4096/*(1<<12)*/;
2543 : }
2544 : return f;
2545 : }
2546 :
2547 250 : static void lsr_read_fraction_12(GF_LASeRCodec *lsr, GF_Node *elt, u32 tag, const char *name)
2548 : {
2549 : GF_FieldInfo info;
2550 : u32 i, count;
2551 250 : GF_LSR_READ_INT(lsr, count, 1, name);
2552 491 : if (!count) return;
2553 :
2554 9 : lsr->last_error = gf_node_get_attribute_by_tag(elt, tag, GF_TRUE, 0, &info);
2555 :
2556 9 : count = lsr_read_vluimsbf5(lsr, "name");
2557 66 : for (i=0; i<count; i++) {
2558 57 : Fixed *f = lsr_read_fraction_12_item(lsr);
2559 57 : gf_list_add( *((SMIL_KeyTimes*)info.far_ptr), f);
2560 : }
2561 : }
2562 25 : static void lsr_read_float_list(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_Coordinates*coords, const char *name)
2563 : {
2564 : u32 i, count;
2565 25 : GF_LSR_READ_INT(lsr, count, 1, name);
2566 25 : if (!count) return;
2567 :
2568 3 : if (!coords) {
2569 : GF_FieldInfo info;
2570 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, tag, GF_TRUE, 0, &info);
2571 3 : coords = (SVG_Coordinates*)info.far_ptr;
2572 : } else {
2573 0 : while (gf_list_count(*coords)) {
2574 0 : Fixed *v = (Fixed *)gf_list_last(*coords);
2575 0 : gf_list_rem_last(*coords);
2576 0 : gf_free(v);
2577 : }
2578 : }
2579 3 : count = lsr_read_vluimsbf5(lsr, "count");
2580 3 : if (tag == TAG_SVG_ATT_text_rotate) {
2581 0 : for (i=0; i<count; i++) {
2582 0 : SVG_Number *num = (SVG_Number *)gf_malloc(sizeof(SVG_Number));
2583 0 : num->type = SVG_NUMBER_VALUE;
2584 0 : num->value = lsr_read_fixed_16_8(lsr, "val");
2585 0 : gf_list_add(*coords, num);
2586 : }
2587 : }
2588 : else {
2589 9 : for (i=0; i<count; i++) {
2590 9 : Fixed *num = (Fixed *)gf_malloc(sizeof(Fixed));
2591 9 : *num = lsr_read_fixed_16_8(lsr, "val");
2592 9 : gf_list_add(*coords, num);
2593 : }
2594 : }
2595 : }
2596 :
2597 63 : static void lsr_read_point_sequence(GF_LASeRCodec *lsr, GF_List *pts, const char *name)
2598 : {
2599 : u32 flag, i, count;
2600 :
2601 63 : while (gf_list_count(pts)) {
2602 0 : SVG_Point *v = (SVG_Point *)gf_list_last(pts);
2603 0 : gf_list_rem_last(pts);
2604 0 : gf_free(v);
2605 : }
2606 63 : count = lsr_read_vluimsbf5(lsr, "nbPoints");
2607 63 : if (!count) return;
2608 : /*TODO golomb coding*/
2609 57 : GF_LSR_READ_INT(lsr, flag, 1, "flag");
2610 57 : if (!flag) {
2611 57 : if (count < 3) {
2612 : u32 nb_bits, v;
2613 6 : GF_LSR_READ_INT(lsr, nb_bits, 5, "bits");
2614 12 : for (i=0; i<count; i++) {
2615 12 : SVG_Point *pt = (SVG_Point *)gf_malloc(sizeof(SVG_Point));
2616 12 : gf_list_add(pts, pt);
2617 12 : GF_LSR_READ_INT(lsr, v, nb_bits, "x");
2618 24 : pt->x = lsr_translate_coords(lsr, v, nb_bits);
2619 12 : GF_LSR_READ_INT(lsr, v, nb_bits, "y");
2620 24 : pt->y = lsr_translate_coords(lsr, v, nb_bits);
2621 : }
2622 : } else {
2623 : u32 nb_dx, nb_dy, k;
2624 : Fixed x, y;
2625 51 : SVG_Point *pt = (SVG_Point *)gf_malloc(sizeof(SVG_Point));
2626 51 : gf_list_add(pts, pt);
2627 :
2628 51 : GF_LSR_READ_INT(lsr, nb_dx, 5, "bits");
2629 51 : GF_LSR_READ_INT(lsr, k, nb_dx, "x");
2630 102 : x = pt->x = lsr_translate_coords(lsr, k, nb_dx);
2631 51 : GF_LSR_READ_INT(lsr, k, nb_dx, "y");
2632 102 : y = pt->y = lsr_translate_coords(lsr, k, nb_dx);
2633 :
2634 51 : GF_LSR_READ_INT(lsr, nb_dx, 5, "bitsx");
2635 51 : GF_LSR_READ_INT(lsr, nb_dy, 5, "bitsy");
2636 303 : for (i=1; i<count; i++) {
2637 303 : pt = (SVG_Point *)gf_malloc(sizeof(SVG_Point));
2638 303 : gf_list_add(pts, pt);
2639 303 : GF_LSR_READ_INT(lsr, k, nb_dx, "dx");
2640 606 : pt->x = x + lsr_translate_coords(lsr, k, nb_dx);
2641 : x = pt->x;
2642 303 : GF_LSR_READ_INT(lsr, k, nb_dy, "dy");
2643 606 : pt->y = y + lsr_translate_coords(lsr, k, nb_dy);
2644 : y = pt->y;
2645 : }
2646 : }
2647 : }
2648 : }
2649 32 : static void lsr_read_path_type(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_PathData *path, const char *name)
2650 : {
2651 : #if USE_GF_PATH
2652 : GF_Point2D *pt, *ct1, *ct2, *end;
2653 : GF_Point2D orig, ct_orig;
2654 : u32 i, count, cur_pt, type;
2655 32 : GF_List *pts = gf_list_new();
2656 32 : lsr_read_point_sequence(lsr, pts, "seq");
2657 :
2658 32 : if (!path) {
2659 : GF_FieldInfo info;
2660 26 : gf_node_get_attribute_by_tag(n, tag, GF_TRUE, 0, &info);
2661 26 : path = (SVG_PathData*)info.far_ptr;
2662 : } else {
2663 6 : gf_path_reset(path);
2664 : }
2665 : /*first MoveTo is skipped in LASeR*/
2666 32 : pt = (GF_Point2D*)gf_list_get(pts, 0);
2667 32 : if (pt) {
2668 30 : ct_orig = orig = *pt;
2669 30 : gf_path_add_move_to_vec(path, pt);
2670 : } else {
2671 : orig.x = orig.y = 0;
2672 2 : ct_orig = orig;
2673 2 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] Empty path found.\n"));
2674 : }
2675 : cur_pt = 1;
2676 32 : count = lsr_read_vluimsbf5(lsr, "nbOfTypes");
2677 140 : for (i=0; i<count; i++) {
2678 108 : GF_LSR_READ_INT(lsr, type, 5, name);
2679 108 : switch (type) {
2680 30 : case LSR_PATH_COM_h:
2681 : case LSR_PATH_COM_l:
2682 : case LSR_PATH_COM_v:
2683 : case LSR_PATH_COM_H:
2684 : case LSR_PATH_COM_V:
2685 : case LSR_PATH_COM_L:
2686 30 : pt = (GF_Point2D*)gf_list_get(pts, cur_pt);
2687 30 : if (!pt) goto err_exit;
2688 30 : gf_path_add_line_to_vec(path, pt);
2689 30 : cur_pt++;
2690 30 : break;
2691 0 : case LSR_PATH_COM_m:
2692 : case LSR_PATH_COM_M:
2693 0 : pt = (GF_Point2D*)gf_list_get(pts, cur_pt);
2694 0 : if (!pt) goto err_exit;
2695 0 : gf_path_add_move_to_vec(path, pt);
2696 0 : cur_pt++;
2697 0 : break;
2698 3 : case LSR_PATH_COM_q:
2699 : case LSR_PATH_COM_Q:
2700 3 : ct1 = (GF_Point2D*)gf_list_get(pts, cur_pt);
2701 3 : end = (GF_Point2D*)gf_list_get(pts, cur_pt+1);
2702 3 : if (!ct1 || !end) goto err_exit;
2703 3 : gf_path_add_quadratic_to_vec(path, ct1, end);
2704 3 : orig = *end;
2705 3 : cur_pt+=2;
2706 3 : break;
2707 54 : case LSR_PATH_COM_c:
2708 : case LSR_PATH_COM_C:
2709 54 : ct1 = (GF_Point2D*)gf_list_get(pts, cur_pt);
2710 54 : ct2 = (GF_Point2D*)gf_list_get(pts, cur_pt+1);
2711 54 : end = (GF_Point2D*)gf_list_get(pts, cur_pt+2);
2712 108 : if (!ct1 || !ct2 || !end) goto err_exit;
2713 54 : gf_path_add_cubic_to_vec(path, ct1, ct2, end);
2714 54 : cur_pt+=3;
2715 54 : ct_orig = *ct2;
2716 54 : orig = *end;
2717 54 : break;
2718 0 : case LSR_PATH_COM_s:
2719 : case LSR_PATH_COM_S:
2720 0 : ct_orig.x = 2*orig.x - ct_orig.x;
2721 0 : ct_orig.y = 2*orig.y - ct_orig.y;
2722 0 : ct2 = (GF_Point2D*)gf_list_get(pts, cur_pt);
2723 0 : end = (GF_Point2D*)gf_list_get(pts, cur_pt+1);
2724 0 : if (!ct2 || !end) goto err_exit;
2725 0 : gf_path_add_cubic_to_vec(path, &ct_orig, ct2, end);
2726 0 : ct_orig = *ct2;
2727 0 : orig = *end;
2728 0 : cur_pt+=2;
2729 0 : break;
2730 0 : case LSR_PATH_COM_t:
2731 : case LSR_PATH_COM_T:
2732 0 : ct_orig.x = 2*orig.x - ct_orig.x;
2733 0 : ct_orig.y = 2*orig.y - ct_orig.y;
2734 0 : end = gf_list_get(pts, cur_pt);
2735 0 : if (!end) goto err_exit;
2736 0 : gf_path_add_quadratic_to_vec(path, &ct_orig, end);
2737 0 : orig = *end;
2738 0 : break;
2739 21 : case LSR_PATH_COM_z:
2740 : case LSR_PATH_COM_Z:
2741 21 : gf_path_close(path);
2742 21 : break;
2743 : }
2744 : }
2745 : goto exit;
2746 :
2747 0 : err_exit:
2748 0 : lsr->last_error = GF_NON_COMPLIANT_BITSTREAM;
2749 :
2750 : exit:
2751 260 : while (gf_list_count(pts)) {
2752 228 : end = (GF_Point2D*)gf_list_get(pts, 0);
2753 228 : gf_list_rem(pts, 0);
2754 228 : gf_free(end);
2755 : }
2756 32 : gf_list_del(pts);
2757 :
2758 : #else
2759 : u32 i, count, c;
2760 : if (!path) {
2761 : lsr->last_error = GF_BAD_PARAM;
2762 : return;
2763 : }
2764 : lsr_read_point_sequence(lsr, path->points, "seq");
2765 : while (gf_list_count(path->commands)) {
2766 : u8 *v = (u8 *)gf_list_last(path->commands);
2767 : gf_list_rem_last(path->commands);
2768 : gf_free(v);
2769 : }
2770 :
2771 : count = lsr_read_vluimsbf5(lsr, "nbOfTypes");
2772 : for (i=0; i<count; i++) {
2773 : u8 *type = (u8 *)gf_malloc(sizeof(u8));
2774 : GF_LSR_READ_INT(lsr, c, 5, name);
2775 :
2776 : switch (c) {
2777 : case LSR_PATH_COM_h:
2778 : case LSR_PATH_COM_l:
2779 : case LSR_PATH_COM_v:
2780 : case LSR_PATH_COM_H:
2781 : case LSR_PATH_COM_V:
2782 : case LSR_PATH_COM_L:
2783 : *type=SVG_PATHCOMMAND_L;
2784 : break;
2785 : case LSR_PATH_COM_m:
2786 : case LSR_PATH_COM_M:
2787 : *type=SVG_PATHCOMMAND_M;
2788 : break;
2789 : case LSR_PATH_COM_q:
2790 : case LSR_PATH_COM_Q:
2791 : *type=SVG_PATHCOMMAND_Q;
2792 : break;
2793 : case LSR_PATH_COM_c:
2794 : case LSR_PATH_COM_C:
2795 : *type=SVG_PATHCOMMAND_C;
2796 : break;
2797 : case LSR_PATH_COM_s:
2798 : case LSR_PATH_COM_S:
2799 : *type=SVG_PATHCOMMAND_S;
2800 : break;
2801 : case LSR_PATH_COM_t:
2802 : case LSR_PATH_COM_T:
2803 : *type=SVG_PATHCOMMAND_T;
2804 : break;
2805 : case LSR_PATH_COM_z:
2806 : case LSR_PATH_COM_Z:
2807 : *type=SVG_PATHCOMMAND_Z;
2808 : break;
2809 : }
2810 : gf_list_add(path->commands, type);
2811 : }
2812 : #endif
2813 32 : }
2814 :
2815 8 : static void lsr_read_rotate_type(GF_LASeRCodec *lsr, GF_Node *n)
2816 : {
2817 : u32 flag;
2818 8 : GF_LSR_READ_INT(lsr, flag, 1, "rotate");
2819 8 : if (flag) {
2820 : GF_FieldInfo info;
2821 6 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_rotate, GF_TRUE, 0, &info);
2822 6 : GF_LSR_READ_INT(lsr, flag, 1, "choice");
2823 :
2824 6 : if (flag) {
2825 3 : GF_LSR_READ_INT(lsr, flag, 1, "rotate");
2826 3 : ((SVG_Number *)info.far_ptr)->type = flag ? SVG_NUMBER_AUTO_REVERSE : SVG_NUMBER_AUTO;
2827 : } else {
2828 3 : ((SVG_Number *)info.far_ptr)->value = lsr_read_fixed_16_8(lsr, "rotate");
2829 3 : ((SVG_Number *)info.far_ptr)->type = SVG_NUMBER_VALUE;
2830 : }
2831 : }
2832 8 : }
2833 10 : static void lsr_read_sync_behavior(GF_LASeRCodec *lsr, GF_Node *n)
2834 : {
2835 : u32 flag;
2836 10 : GF_LSR_READ_INT(lsr, flag, 1, "syncBehavior");
2837 10 : if (flag) {
2838 : GF_FieldInfo info;
2839 3 : GF_LSR_READ_INT(lsr, flag, 2, "syncBehavior");
2840 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_syncBehavior, GF_TRUE, 0, &info);
2841 3 : *(SMIL_SyncBehavior*)info.far_ptr = flag + 1;
2842 : }
2843 10 : }
2844 10 : static void lsr_read_sync_tolerance(GF_LASeRCodec *lsr, GF_Node *n)
2845 : {
2846 : u32 flag;
2847 10 : GF_LSR_READ_INT(lsr, flag, 1, "syncTolerance");
2848 10 : if (flag) {
2849 : GF_FieldInfo info;
2850 6 : GF_LSR_READ_INT(lsr, flag, 1, "syncTolerance");
2851 6 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_syncTolerance, GF_TRUE, 0, &info);
2852 6 : if (flag) ((SMIL_SyncTolerance *)info.far_ptr)->type = SMIL_SYNCTOLERANCE_DEFAULT;
2853 : else {
2854 3 : u32 v = lsr_read_vluimsbf5(lsr, "value");
2855 3 : ((SMIL_SyncTolerance *)info.far_ptr)->value = INT2FIX(v);
2856 3 : ((SMIL_SyncTolerance *)info.far_ptr)->value /= lsr->time_resolution;
2857 : }
2858 : }
2859 10 : }
2860 10 : static void lsr_read_sync_reference(GF_LASeRCodec *lsr, GF_Node *n)
2861 : {
2862 : u32 flag;
2863 10 : GF_LSR_READ_INT(lsr, flag, 1, "hasSyncReference");
2864 10 : if (flag) {
2865 : GF_FieldInfo info;
2866 0 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_syncReference, GF_TRUE, 0, &info);
2867 0 : lsr_read_any_uri(lsr, info.far_ptr, "syncReference");
2868 : }
2869 10 : }
2870 :
2871 67 : static void lsr_read_coordinate(GF_LASeRCodec *lsr, SVG_Number *coord, Bool skipable, const char *name)
2872 : {
2873 : u32 flag;
2874 67 : if (skipable) {
2875 0 : GF_LSR_READ_INT(lsr, flag, 1, name);
2876 0 : if (!flag) {
2877 : //coord->type = SVG_NUMBER_UNKNOWN;
2878 : //coord->value = 0;
2879 : return;
2880 : }
2881 : }
2882 67 : coord->type = SVG_NUMBER_VALUE;
2883 67 : GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, name);
2884 134 : coord->value = lsr_translate_coords(lsr, flag, lsr->coord_bits);
2885 : }
2886 701 : static void lsr_read_coordinate_ptr(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, Bool skipable, const char *name)
2887 : {
2888 : u32 flag;
2889 : GF_FieldInfo info;
2890 701 : if (skipable) {
2891 518 : GF_LSR_READ_INT(lsr, flag, 1, name);
2892 853 : if (!flag) return;
2893 : }
2894 366 : lsr->last_error = gf_node_get_attribute_by_tag(n, tag, GF_TRUE, 0, &info);
2895 :
2896 366 : ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE;
2897 366 : GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, name);
2898 732 : ((SVG_Number*)info.far_ptr)->value = lsr_translate_coords(lsr, flag, lsr->coord_bits);
2899 : }
2900 :
2901 34 : static void lsr_read_coord_list(GF_LASeRCodec *lsr, GF_Node *elt, u32 tag, const char *name)
2902 : {
2903 : GF_FieldInfo info;
2904 : u32 i, count;
2905 34 : GF_LSR_READ_INT(lsr, count, 1, name);
2906 50 : if (!count) return;
2907 18 : count = lsr_read_vluimsbf5(lsr, "nb_coords");
2908 18 : if (!count) return;
2909 18 : if (count>1000000) {
2910 0 : lsr->last_error = GF_NON_COMPLIANT_BITSTREAM;
2911 0 : return;
2912 : }
2913 :
2914 18 : lsr->last_error = gf_node_get_attribute_by_tag(elt, tag, GF_TRUE, 0, &info);
2915 :
2916 36 : for (i=0; i<count; i++) {
2917 : u32 res;
2918 : SVG_Coordinate *f;
2919 18 : GF_SAFEALLOC(f, SVG_Coordinate );
2920 18 : if (!f) {
2921 0 : lsr->last_error = GF_OUT_OF_MEM;
2922 0 : return;
2923 : }
2924 18 : GF_LSR_READ_INT(lsr, res, lsr->coord_bits, name);
2925 36 : f->value = lsr_translate_coords(lsr, res, lsr->coord_bits);
2926 18 : gf_list_add(*(SVG_Coordinates*)info.far_ptr, f);
2927 : }
2928 : }
2929 :
2930 46 : static void lsr_read_transform_behavior(GF_LASeRCodec *lsr, GF_Node *n)
2931 : {
2932 : GF_FieldInfo info;
2933 : u32 flag;
2934 46 : GF_LSR_READ_INT(lsr, flag, 1, "hasTransformBehavior");
2935 46 : if (flag) {
2936 0 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_transformBehavior, GF_TRUE, 0, &info);
2937 0 : GF_LSR_READ_INT(lsr, *(SVG_TransformBehavior*)info.far_ptr, 4, "transformBehavior");
2938 : }
2939 46 : }
2940 :
2941 51 : static void lsr_read_content_type(GF_LASeRCodec *lsr, GF_Node *n)
2942 : {
2943 : u32 flag;
2944 51 : GF_LSR_READ_INT(lsr, flag, 1, "hasType");
2945 51 : if (flag) {
2946 : GF_FieldInfo info;
2947 0 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_type, GF_TRUE, 0, &info);
2948 0 : lsr_read_byte_align_string(lsr, info.far_ptr, "type");
2949 : }
2950 51 : }
2951 5 : static void lsr_read_script_type(GF_LASeRCodec *lsr, GF_Node *n)
2952 : {
2953 : u32 flag;
2954 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasType");
2955 5 : if (flag) {
2956 : GF_FieldInfo info;
2957 3 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_XLINK_ATT_type, GF_TRUE, 0, &info);
2958 3 : GF_LSR_READ_INT(lsr, flag, 1, "choice");
2959 3 : if (flag) {
2960 3 : GF_LSR_READ_INT(lsr, flag, 1, "script");
2961 3 : switch (flag) {
2962 3 : case 0:
2963 3 : *(SVG_String*)info.far_ptr = gf_strdup("application/ecmascript");
2964 3 : break;
2965 0 : case 1:
2966 0 : *(SVG_String*)info.far_ptr = gf_strdup("application/jar-archive");
2967 0 : break;
2968 : default:
2969 : break;
2970 : }
2971 : } else {
2972 0 : lsr_read_byte_align_string(lsr, info.far_ptr, "type");
2973 : }
2974 : }
2975 5 : }
2976 13 : static void lsr_read_value_with_units(GF_LASeRCodec *lsr, SVG_Number *n, const char *name)
2977 : {
2978 : s32 val;
2979 13 : GF_LSR_READ_INT(lsr, val, 32, name);
2980 : #ifdef GPAC_FIXED_POINT
2981 : n->value = val << 8;
2982 : #else
2983 13 : n->value = INT2FIX(val) / (1<<8);
2984 : #endif
2985 13 : GF_LSR_READ_INT(lsr, val, 3, "units");
2986 13 : switch (val) {
2987 0 : case 1:
2988 0 : n->type = SVG_NUMBER_IN;
2989 : break;
2990 0 : case 2:
2991 0 : n->type = SVG_NUMBER_CM;
2992 : break;
2993 0 : case 3:
2994 0 : n->type = SVG_NUMBER_MM;
2995 : break;
2996 0 : case 4:
2997 0 : n->type = SVG_NUMBER_PT;
2998 : break;
2999 0 : case 5:
3000 0 : n->type = SVG_NUMBER_PC;
3001 : break;
3002 3 : case 6:
3003 3 : n->type = SVG_NUMBER_PERCENTAGE;
3004 : break;
3005 10 : default:
3006 10 : n->type = SVG_NUMBER_VALUE;
3007 : break;
3008 : }
3009 13 : }
3010 :
3011 :
3012 20 : static void lsr_read_clip_time(GF_LASeRCodec *lsr, GF_Node *elt, u32 tag, const char *name)
3013 : {
3014 : GF_FieldInfo info;
3015 : u32 flag;
3016 20 : GF_LSR_READ_INT(lsr, flag, 1, name);
3017 20 : if (flag) {
3018 2 : lsr->last_error = gf_node_get_attribute_by_tag(elt, tag, 1, 0, &info);
3019 2 : GF_LSR_READ_INT(lsr, flag, 1, "isEnum");
3020 2 : if (!flag) {
3021 2 : GF_LSR_READ_INT(lsr, flag, 1, "sign");
3022 2 : flag = lsr_read_vluimsbf5(lsr, "val");
3023 2 : *((SVG_Clock *)info.far_ptr) = flag;
3024 2 : *((SVG_Clock *)info.far_ptr) /= lsr->time_resolution;
3025 : }
3026 : }
3027 20 : }
3028 :
3029 127 : static void lsr_read_attribute_type(GF_LASeRCodec *lsr, GF_Node *elt)
3030 : {
3031 : GF_FieldInfo info;
3032 : u32 flag;
3033 127 : GF_LSR_READ_INT(lsr, flag, 1, "hasAttributeType");
3034 254 : if (!flag) return;
3035 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_attributeType, 1, 0, &info);
3036 0 : GF_LSR_READ_INT(lsr, *(SMIL_AttributeType*)info.far_ptr, 2, "attributeType");
3037 : }
3038 :
3039 51 : static void lsr_read_preserve_aspect_ratio(GF_LASeRCodec *lsr, GF_Node *n)
3040 : {
3041 : GF_FieldInfo info;
3042 : u32 flag;
3043 : SVG_PreserveAspectRatio *par;
3044 :
3045 51 : GF_LSR_READ_INT(lsr, flag, 1, "hasPreserveAspectRatio");
3046 63 : if (!flag) return;
3047 :
3048 39 : lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_preserveAspectRatio, 1, 0, &info);
3049 39 : par = (SVG_PreserveAspectRatio *)info.far_ptr;
3050 :
3051 39 : GF_LSR_READ_INT(lsr, flag, 1, "choice (meetOrSlice)");
3052 39 : GF_LSR_READ_INT(lsr, par->defer, 1, "choice (defer)");
3053 39 : GF_LSR_READ_INT(lsr, flag, 4, "alignXandY");
3054 39 : switch (flag) {
3055 3 : case 1:
3056 3 : par->align = SVG_PRESERVEASPECTRATIO_XMAXYMAX;
3057 : break;
3058 3 : case 2:
3059 3 : par->align = SVG_PRESERVEASPECTRATIO_XMAXYMID;
3060 : break;
3061 3 : case 3:
3062 3 : par->align = SVG_PRESERVEASPECTRATIO_XMAXYMIN;
3063 : break;
3064 3 : case 4:
3065 3 : par->align = SVG_PRESERVEASPECTRATIO_XMIDYMAX;
3066 : break;
3067 12 : case 5:
3068 12 : par->align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
3069 : break;
3070 3 : case 6:
3071 3 : par->align = SVG_PRESERVEASPECTRATIO_XMIDYMIN;
3072 : break;
3073 3 : case 7:
3074 3 : par->align = SVG_PRESERVEASPECTRATIO_XMINYMAX;
3075 : break;
3076 3 : case 8:
3077 3 : par->align = SVG_PRESERVEASPECTRATIO_XMINYMID;
3078 : break;
3079 3 : case 9:
3080 3 : par->align = SVG_PRESERVEASPECTRATIO_XMINYMIN;
3081 : break;
3082 3 : default:
3083 3 : par->align = SVG_PRESERVEASPECTRATIO_NONE;
3084 : break;
3085 : }
3086 : }
3087 :
3088 142 : static void lsr_read_eRR(GF_LASeRCodec *lsr, GF_Node *elt)
3089 : {
3090 : u32 err;
3091 142 : GF_LSR_READ_INT(lsr, err, 1, "externalResourcesRequired");
3092 142 : if (err) {
3093 : GF_FieldInfo info;
3094 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_externalResourcesRequired, 1, 0, &info);
3095 0 : *(SVG_Boolean*)info.far_ptr = 1;
3096 : }
3097 142 : }
3098 :
3099 137 : static void lsr_read_lsr_enabled(GF_LASeRCodec *lsr, GF_Node *elt)
3100 : {
3101 : u32 err;
3102 137 : GF_LSR_READ_INT(lsr, err, 1, "enabled");
3103 137 : if (err) {
3104 : GF_FieldInfo info;
3105 15 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_LSR_ATT_enabled, 1, 0, &info);
3106 15 : *(SVG_Boolean*)info.far_ptr = 1;
3107 : }
3108 137 : }
3109 :
3110 14 : static GF_Node *lsr_read_a(GF_LASeRCodec *lsr)
3111 : {
3112 : Bool flag;
3113 14 : GF_Node *elt = (GF_Node*) gf_node_new(lsr->sg, TAG_SVG_a);
3114 14 : lsr_read_id(lsr, elt);
3115 14 : lsr_read_rare_full(lsr, elt);
3116 14 : lsr_read_fill(lsr, elt);
3117 14 : lsr_read_stroke(lsr, elt);
3118 14 : lsr_read_eRR(lsr, elt);
3119 14 : GF_LSR_READ_INT(lsr, flag, 1, "hasTarget");
3120 14 : if (flag) {
3121 : GF_FieldInfo info;
3122 3 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_target, 1, 0, &info);
3123 3 : lsr_read_byte_align_string(lsr, info.far_ptr, "target");
3124 : }
3125 14 : lsr_read_href(lsr, elt);
3126 14 : lsr_read_any_attribute(lsr, elt, 1);
3127 14 : lsr_read_group_content(lsr, elt, 0);
3128 14 : return elt;
3129 : }
3130 :
3131 :
3132 :
3133 103 : static GF_Node *lsr_read_animate(GF_LASeRCodec *lsr, SVG_Element *parent, Bool is_animateColor)
3134 : {
3135 103 : GF_Node *elt = gf_node_new(lsr->sg, is_animateColor ? TAG_SVG_animateColor : TAG_SVG_animate);
3136 103 : lsr_read_id(lsr, elt);
3137 103 : lsr_read_rare(lsr, elt);
3138 : lsr_read_attribute_name(lsr, elt);
3139 :
3140 103 : lsr_read_accumulate(lsr, elt);
3141 103 : lsr_read_additive(lsr, elt);
3142 103 : lsr_read_anim_value(lsr, elt, TAG_SVG_ATT_by, "by");
3143 103 : lsr_read_calc_mode(lsr, elt);
3144 103 : lsr_read_anim_value(lsr, elt, TAG_SVG_ATT_from, "from");
3145 103 : lsr_read_fraction_12(lsr, elt, TAG_SVG_ATT_keySplines, "keySplines");
3146 103 : lsr_read_fraction_12(lsr, elt, TAG_SVG_ATT_keyTimes, "keyTimes");
3147 103 : lsr_read_anim_values(lsr, elt);
3148 103 : lsr_read_attribute_type(lsr, elt);
3149 103 : lsr_read_smil_times(lsr, elt, TAG_SVG_ATT_begin, NULL, "begin", 1);
3150 : lsr_read_duration(lsr, elt);
3151 103 : lsr_read_anim_fill(lsr, elt);
3152 103 : lsr_read_anim_repeatCount(lsr, elt);
3153 103 : lsr_read_repeat_duration(lsr, elt);
3154 103 : lsr_read_anim_restart(lsr, elt);
3155 103 : lsr_read_anim_value(lsr, elt, TAG_SVG_ATT_to, "to");
3156 103 : lsr_read_href(lsr, elt);
3157 103 : lsr_read_lsr_enabled(lsr, elt);
3158 103 : lsr_read_any_attribute(lsr, elt, 1);
3159 :
3160 103 : if (!lsr_setup_smil_anim(lsr, (SVG_Element*)elt, parent)) {
3161 36 : gf_list_add(lsr->deferred_anims, elt);
3162 36 : lsr_read_group_content_post_init(lsr, (SVG_Element*)elt, 1);
3163 : } else {
3164 67 : lsr_read_group_content(lsr, elt, 0);
3165 : }
3166 103 : return elt;
3167 : }
3168 :
3169 :
3170 8 : static GF_Node *lsr_read_animateMotion(GF_LASeRCodec *lsr, SVG_Element *parent)
3171 : {
3172 : Bool flag;
3173 8 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_animateMotion);
3174 8 : lsr_read_id(lsr, elt);
3175 8 : lsr_read_rare(lsr, elt);
3176 8 : lsr_read_accumulate(lsr, elt);
3177 8 : lsr_read_additive(lsr, elt);
3178 8 : lsr_read_anim_value(lsr, elt, TAG_SVG_ATT_by, "by");
3179 8 : lsr_read_calc_mode(lsr, elt);
3180 8 : lsr_read_anim_value(lsr, elt, TAG_SVG_ATT_from, "from");
3181 8 : lsr_read_fraction_12(lsr, elt, TAG_SVG_ATT_keySplines, "keySplines");
3182 8 : lsr_read_fraction_12(lsr, elt, TAG_SVG_ATT_keyTimes, "keyTimes");
3183 8 : lsr_read_anim_values(lsr, elt);
3184 8 : lsr_read_attribute_type(lsr, elt);
3185 8 : lsr_read_smil_times(lsr, elt, TAG_SVG_ATT_begin, NULL, "begin", 1);
3186 : lsr_read_duration(lsr, elt);
3187 8 : lsr_read_anim_fill(lsr, elt);
3188 8 : lsr_read_anim_repeatCount(lsr, elt);
3189 8 : lsr_read_repeat_duration(lsr, elt);
3190 8 : lsr_read_anim_restart(lsr, elt);
3191 8 : lsr_read_anim_value(lsr, elt, TAG_SVG_ATT_to, "to");
3192 8 : lsr_read_float_list(lsr, elt, TAG_SVG_ATT_keyPoints, NULL, "keyPoints");
3193 8 : GF_LSR_READ_INT(lsr, flag, 1, "hasPath");
3194 8 : if (flag) lsr_read_path_type(lsr, elt, TAG_SVG_ATT_path, NULL, "path");
3195 :
3196 8 : lsr_read_rotate_type(lsr, elt);
3197 8 : lsr_read_href(lsr, elt);
3198 8 : lsr_read_lsr_enabled(lsr, elt);
3199 8 : lsr_read_any_attribute(lsr, elt, 1);
3200 :
3201 8 : if (!lsr_setup_smil_anim(lsr, (SVG_Element*)elt, parent)) {
3202 0 : gf_list_add(lsr->deferred_anims, elt);
3203 0 : lsr_read_group_content_post_init(lsr, (SVG_Element*)elt, 1);
3204 : } else {
3205 8 : lsr_read_group_content_post_init(lsr, (SVG_Element*)elt, 0);
3206 : }
3207 8 : return elt;
3208 : }
3209 :
3210 :
3211 14 : static GF_Node *lsr_read_animateTransform(GF_LASeRCodec *lsr, SVG_Element *parent)
3212 : {
3213 : u32 type;
3214 : u32 flag;
3215 : GF_FieldInfo info;
3216 14 : GF_Node *elt= gf_node_new(lsr->sg, TAG_SVG_animateTransform);
3217 14 : lsr_read_id(lsr, elt);
3218 14 : lsr_read_rare(lsr, elt);
3219 : lsr_read_attribute_name(lsr, elt);
3220 :
3221 : /*enumeration rotate{0} scale{1} skewX{2} skewY{3} translate{4}*/
3222 14 : GF_LSR_READ_INT(lsr, flag, 3, "rotscatra");
3223 14 : switch (flag) {
3224 3 : case 0:
3225 3 : type = SVG_TRANSFORM_ROTATE;
3226 3 : break;
3227 0 : case 1:
3228 0 : type = SVG_TRANSFORM_SCALE;
3229 0 : break;
3230 3 : case 2:
3231 3 : type = SVG_TRANSFORM_SKEWX;
3232 3 : break;
3233 3 : case 3:
3234 3 : type = SVG_TRANSFORM_SKEWY;
3235 3 : break;
3236 5 : case 4:
3237 5 : type = SVG_TRANSFORM_TRANSLATE;
3238 5 : break;
3239 0 : default:
3240 0 : type = SVG_TRANSFORM_ROTATE;
3241 0 : break;
3242 : }
3243 14 : if (gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_transform_type, 1, 0, &info)==GF_OK) {
3244 14 : *(SVG_TransformType *)info.far_ptr = type;
3245 : }
3246 :
3247 14 : lsr_read_accumulate(lsr, elt);
3248 14 : lsr_read_additive(lsr, elt);
3249 14 : lsr_read_anim_value_ex(lsr, elt, TAG_SVG_ATT_by, "by", &type);
3250 14 : lsr_read_calc_mode(lsr, elt);
3251 14 : lsr_read_anim_value_ex(lsr, elt, TAG_SVG_ATT_from, "from", &type);
3252 14 : lsr_read_fraction_12(lsr, elt, TAG_SVG_ATT_keySplines, "keySplines");
3253 14 : lsr_read_fraction_12(lsr, elt, TAG_SVG_ATT_keyTimes, "keyTimes");
3254 14 : lsr_read_anim_values_ex(lsr, elt, &type);
3255 14 : lsr_read_attribute_type(lsr, elt);
3256 :
3257 14 : lsr_read_smil_times(lsr, elt, TAG_SVG_ATT_begin, NULL, "begin", 1);
3258 : lsr_read_duration(lsr, elt);
3259 14 : lsr_read_anim_fill(lsr, elt);
3260 14 : lsr_read_anim_repeatCount(lsr, elt);
3261 14 : lsr_read_repeat_duration(lsr, elt);
3262 14 : lsr_read_anim_restart(lsr, elt);
3263 14 : lsr_read_anim_value_ex(lsr, elt, TAG_SVG_ATT_to, "to", &type);
3264 :
3265 14 : lsr_read_href(lsr, elt);
3266 14 : lsr_read_lsr_enabled(lsr, elt);
3267 14 : lsr_read_any_attribute(lsr, elt, 1);
3268 :
3269 14 : if (!lsr_setup_smil_anim(lsr, (SVG_Element*)elt, parent)) {
3270 0 : gf_list_add(lsr->deferred_anims, elt);
3271 0 : lsr_read_group_content_post_init(lsr, (SVG_Element*)elt, 1);
3272 : } else {
3273 14 : lsr_read_group_content(lsr, elt, 0);
3274 : }
3275 14 : return elt;
3276 : }
3277 :
3278 5 : static GF_Node *lsr_read_audio(GF_LASeRCodec *lsr, SVG_Element *parent)
3279 : {
3280 5 : GF_Node *elt= gf_node_new(lsr->sg, TAG_SVG_audio);
3281 5 : lsr_read_id(lsr, elt);
3282 5 : lsr_read_rare(lsr, elt);
3283 5 : lsr_read_smil_times(lsr, elt, TAG_SVG_ATT_begin, NULL, "begin", 1);
3284 : lsr_read_duration(lsr, elt);
3285 5 : lsr_read_eRR(lsr, elt);
3286 5 : lsr_read_anim_repeatCount(lsr, elt);
3287 5 : lsr_read_repeat_duration(lsr, elt);
3288 5 : lsr_read_anim_restart(lsr, elt);
3289 5 : lsr_read_sync_behavior(lsr, elt);
3290 5 : lsr_read_sync_tolerance(lsr, elt);
3291 5 : lsr_read_content_type(lsr, elt);
3292 5 : lsr_read_href(lsr, elt);
3293 :
3294 5 : lsr_read_clip_time(lsr, elt, TAG_SVG_ATT_clipBegin, "clipBegin");
3295 5 : lsr_read_clip_time(lsr, elt, TAG_SVG_ATT_clipEnd, "clipEnd");
3296 5 : lsr_read_sync_reference(lsr, elt);
3297 5 : lsr_read_any_attribute(lsr, elt, 1);
3298 5 : lsr_read_group_content(lsr, elt, 0);
3299 5 : return elt;
3300 : }
3301 11 : static GF_Node *lsr_read_circle(GF_LASeRCodec *lsr)
3302 : {
3303 11 : GF_Node *elt= gf_node_new(lsr->sg, TAG_SVG_circle);
3304 11 : lsr_read_id(lsr, elt);
3305 11 : lsr_read_rare_full(lsr, elt);
3306 11 : lsr_read_fill(lsr, elt);
3307 11 : lsr_read_stroke(lsr, elt);
3308 11 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_cx, 1, "cx");
3309 11 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_cy, 1, "cy");
3310 11 : lsr_read_coordinate_ptr(lsr, elt,TAG_SVG_ATT_r, 0, "r");
3311 11 : lsr_read_any_attribute(lsr, elt, 1);
3312 11 : lsr_read_group_content(lsr, elt, 0);
3313 11 : return elt;
3314 : }
3315 5 : static GF_Node *lsr_read_conditional(GF_LASeRCodec *lsr)
3316 : {
3317 5 : GF_Node *elt = gf_node_new(lsr->sg, TAG_LSR_conditional);
3318 5 : lsr_read_id(lsr, elt);
3319 5 : lsr_read_rare(lsr, elt);
3320 5 : lsr_read_smil_times(lsr, elt, TAG_SVG_ATT_begin, NULL, "begin", 1);
3321 5 : lsr_read_eRR(lsr, elt);
3322 5 : lsr_read_lsr_enabled(lsr, elt);
3323 5 : lsr_read_any_attribute(lsr, elt, 1);
3324 5 : lsr_read_command_list(lsr, NULL, (SVG_Element*)elt, 0);
3325 :
3326 5 : lsr->has_conditionnals = GF_TRUE;
3327 5 : gf_node_init(elt);
3328 5 : return elt;
3329 : }
3330 2 : static GF_Node *lsr_read_cursorManager(GF_LASeRCodec *lsr)
3331 : {
3332 2 : GF_Node *elt = gf_node_new(lsr->sg, TAG_LSR_cursorManager);
3333 2 : lsr_read_id(lsr, elt);
3334 2 : lsr_read_rare(lsr, elt);
3335 2 : lsr_read_coordinate_ptr(lsr, elt,TAG_SVG_ATT_x, 1, "x");
3336 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y, 1, "y");
3337 2 : lsr_read_href(lsr, elt);
3338 2 : lsr_read_any_attribute(lsr, elt, 1);
3339 2 : lsr_read_group_content(lsr, elt, 0);
3340 2 : return elt;
3341 : }
3342 :
3343 8 : static GF_Node *lsr_read_data(GF_LASeRCodec *lsr, u32 node_tag)
3344 : {
3345 8 : GF_Node *elt = gf_node_new(lsr->sg, node_tag);
3346 8 : lsr_read_id(lsr, elt);
3347 8 : lsr_read_rare(lsr, elt);
3348 8 : lsr_read_any_attribute(lsr, elt, 1);
3349 8 : lsr_read_group_content(lsr, elt, 0);
3350 8 : return elt;
3351 : }
3352 :
3353 2 : static GF_Node *lsr_read_defs(GF_LASeRCodec *lsr)
3354 : {
3355 2 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_defs);
3356 2 : lsr_read_id(lsr, elt);
3357 2 : lsr_read_rare(lsr, elt);
3358 2 : lsr_read_fill(lsr, elt);
3359 2 : lsr_read_stroke(lsr, elt);
3360 2 : lsr_read_any_attribute(lsr, elt, 1);
3361 2 : lsr_read_group_content(lsr, elt, 0);
3362 2 : return elt;
3363 : }
3364 2 : static GF_Node *lsr_read_ellipse(GF_LASeRCodec *lsr)
3365 : {
3366 2 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_ellipse);
3367 2 : lsr_read_id(lsr, elt);
3368 2 : lsr_read_rare_full(lsr, elt);
3369 2 : lsr_read_fill(lsr, elt);
3370 2 : lsr_read_stroke(lsr, elt);
3371 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_cx, 1, "cx");
3372 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_cy, 1, "cy");
3373 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_rx, 0, "rx");
3374 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_ry, 0, "ry");
3375 2 : lsr_read_any_attribute(lsr, elt, 1);
3376 2 : lsr_read_group_content(lsr, elt, 0);
3377 2 : return elt;
3378 : }
3379 2 : static GF_Node *lsr_read_foreignObject(GF_LASeRCodec *lsr)
3380 : {
3381 : u32 flag;
3382 2 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_foreignObject);
3383 2 : lsr_read_id(lsr, elt);
3384 2 : lsr_read_rare_full(lsr, elt);
3385 2 : lsr_read_fill(lsr, elt);
3386 2 : lsr_read_stroke(lsr, elt);
3387 2 : lsr_read_eRR(lsr, elt);
3388 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_height, 0, "height");
3389 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_width, 0, "width");
3390 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_x, 1, "x");
3391 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y, 1, "y");
3392 :
3393 2 : lsr_read_any_attribute(lsr, elt, 1);
3394 : /* TODO
3395 : bit(1) opt_group;
3396 : if(opt_group) {
3397 : vluimsbf5 occ1;
3398 : for(int t=0;t<occ1;t++) {
3399 : privateElementContainer child0[[t]];
3400 : }
3401 : }
3402 : */
3403 2 : GF_LSR_READ_INT(lsr, flag, 1, "opt_group");
3404 2 : return elt;
3405 : }
3406 :
3407 :
3408 29 : static GF_Node *lsr_read_g(GF_LASeRCodec *lsr, Bool is_same)
3409 : {
3410 29 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_g);
3411 29 : if (is_same) {
3412 0 : if (lsr->prev_g) {
3413 0 : lsr_restore_base(lsr, (SVG_Element*) elt, lsr->prev_g, 0, 0);
3414 : } else {
3415 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] sameg coded in bitstream but no g defined !\n"));
3416 : }
3417 0 : lsr_read_id(lsr, elt);
3418 : } else {
3419 29 : lsr_read_id(lsr, elt);
3420 29 : lsr_read_rare_full(lsr, elt);
3421 29 : lsr_read_fill(lsr, elt);
3422 29 : lsr_read_stroke(lsr, elt);
3423 29 : lsr_read_eRR(lsr, elt);
3424 29 : lsr_read_any_attribute(lsr, elt, 1);
3425 29 : lsr->prev_g = (SVG_Element*)elt;
3426 : }
3427 29 : lsr_read_group_content(lsr, elt, is_same);
3428 29 : return elt;
3429 : }
3430 :
3431 41 : static void lsr_read_opacity(GF_LASeRCodec *lsr, GF_Node *elt)
3432 : {
3433 : u32 flag;
3434 : GF_FieldInfo info;
3435 41 : GF_LSR_READ_INT(lsr, flag, 1, "opacity");
3436 41 : if (flag) {
3437 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_opacity, 1, 0, &info);
3438 0 : ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE;
3439 0 : ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "opacity");
3440 : }
3441 :
3442 41 : }
3443 41 : static GF_Node *lsr_read_image(GF_LASeRCodec *lsr)
3444 : {
3445 41 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_image);
3446 41 : lsr_read_id(lsr, elt);
3447 41 : lsr_read_rare_full(lsr, elt);
3448 41 : lsr_read_eRR(lsr, elt);
3449 41 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_height, 1, "height");
3450 41 : lsr_read_opacity(lsr, elt);
3451 :
3452 41 : lsr_read_preserve_aspect_ratio(lsr, elt);
3453 41 : lsr_read_content_type(lsr, elt);
3454 41 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_width, 1, "width");
3455 41 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_x, 1, "x");
3456 41 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y, 1, "y");
3457 41 : lsr_read_href(lsr, elt);
3458 41 : lsr_read_transform_behavior(lsr, elt);
3459 41 : lsr_read_any_attribute(lsr, elt, 1);
3460 41 : lsr_read_group_content(lsr, elt, 0);
3461 41 : return elt;
3462 : }
3463 5 : static GF_Node *lsr_read_line(GF_LASeRCodec *lsr, Bool is_same)
3464 : {
3465 5 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_line);
3466 :
3467 5 : if (is_same) {
3468 0 : if (lsr->prev_line) {
3469 0 : lsr_restore_base(lsr, (SVG_Element*) elt, (SVG_Element *)lsr->prev_line, 0, 0);
3470 : } else {
3471 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] sameline coded in bitstream but no line defined !\n"));
3472 : }
3473 0 : lsr_read_id(lsr, elt);
3474 : } else {
3475 5 : lsr_read_id(lsr, elt);
3476 5 : lsr_read_rare_full(lsr, elt);
3477 5 : lsr_read_fill(lsr, elt);
3478 5 : lsr_read_stroke(lsr, elt);
3479 : }
3480 5 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_x1, 1, "x1");
3481 5 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_x2, 0, "x2");
3482 5 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y1, 1, "y1");
3483 5 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y2, 0, "y2");
3484 5 : if (!is_same) {
3485 5 : lsr_read_any_attribute(lsr, elt, 1);
3486 5 : lsr->prev_line = (SVG_Element*)elt;
3487 : }
3488 5 : lsr_read_group_content(lsr, elt, is_same);
3489 5 : return elt;
3490 : }
3491 :
3492 10 : static void lsr_read_gradient_units(GF_LASeRCodec *lsr, GF_Node *elt)
3493 : {
3494 : u32 flag;
3495 : GF_FieldInfo info;
3496 10 : GF_LSR_READ_INT(lsr, flag, 1, "hasGradientUnits");
3497 10 : if (flag) {
3498 3 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_gradientUnits, 1, 0, &info);
3499 3 : GF_LSR_READ_INT(lsr, *(SVG_GradientUnit*)info.far_ptr, 1, "gradientUnits");
3500 : }
3501 10 : }
3502 8 : static GF_Node *lsr_read_linearGradient(GF_LASeRCodec *lsr)
3503 : {
3504 8 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_linearGradient);
3505 8 : lsr_read_id(lsr, elt);
3506 8 : lsr_read_rare(lsr, elt);
3507 8 : lsr_read_fill(lsr, elt);
3508 8 : lsr_read_stroke(lsr, elt);
3509 8 : lsr_read_gradient_units(lsr, elt);
3510 8 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_x1, 1, "x1");
3511 8 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_x2, 1, "x2");
3512 8 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y1, 1, "y1");
3513 8 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y2, 1, "y2");
3514 8 : lsr_read_any_attribute(lsr, elt, 1);
3515 8 : lsr_read_group_content(lsr, elt, 0);
3516 8 : return elt;
3517 : }
3518 5 : static GF_Node *lsr_read_mpath(GF_LASeRCodec *lsr)
3519 : {
3520 5 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_mpath);
3521 5 : lsr_read_id(lsr, elt);
3522 5 : lsr_read_rare(lsr, elt);
3523 5 : lsr_read_href(lsr, elt);
3524 5 : lsr_read_any_attribute(lsr, elt, 1);
3525 5 : lsr_read_group_content(lsr, elt, 0);
3526 5 : return elt;
3527 : }
3528 23 : static GF_Node *lsr_read_path(GF_LASeRCodec *lsr, u32 same_type)
3529 : {
3530 : u32 flag;
3531 23 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_path);
3532 :
3533 23 : if (same_type) {
3534 6 : if (lsr->prev_path) {
3535 6 : lsr_restore_base(lsr, (SVG_Element*)elt, (SVG_Element *)lsr->prev_path, (same_type==2) ? 1 : 0, 0);
3536 : } else {
3537 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] samepath coded in bitstream but no path defined !\n"));
3538 : }
3539 6 : lsr_read_id(lsr, elt);
3540 6 : if (same_type==2) lsr_read_fill(lsr, elt);
3541 6 : lsr_read_path_type(lsr, elt, TAG_SVG_ATT_d, NULL, "d");
3542 : } else {
3543 17 : lsr_read_id(lsr, elt);
3544 17 : lsr_read_rare_full(lsr, elt);
3545 17 : lsr_read_fill(lsr, elt);
3546 17 : lsr_read_stroke(lsr, elt);
3547 17 : lsr_read_path_type(lsr, elt, TAG_SVG_ATT_d, NULL, "d");
3548 17 : GF_LSR_READ_INT(lsr, flag, 1, "hasPathLength");
3549 17 : if (flag) {
3550 : GF_FieldInfo info;
3551 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_pathLength, 1, 0, &info);
3552 0 : ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_16_8(lsr, "pathLength");
3553 : }
3554 17 : lsr_read_any_attribute(lsr, elt, 1);
3555 17 : lsr->prev_path = (SVG_Element*)elt;
3556 : }
3557 23 : lsr_read_group_content(lsr, elt, same_type);
3558 23 : return elt;
3559 : }
3560 31 : static GF_Node *lsr_read_polygon(GF_LASeRCodec *lsr, Bool is_polyline, u32 same_type)
3561 : {
3562 : GF_FieldInfo info;
3563 31 : GF_Node *elt = gf_node_new(lsr->sg, is_polyline ? TAG_SVG_polyline : TAG_SVG_polygon);
3564 :
3565 31 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_points, 1, 0, &info);
3566 :
3567 31 : if (same_type) {
3568 9 : if (lsr->prev_polygon) {
3569 9 : lsr_restore_base(lsr, (SVG_Element*)elt, (SVG_Element *)lsr->prev_polygon, /*(same_type==2) ? 1 : */ 0, /*(same_type==3) ? 1 : */ 0);
3570 : } else {
3571 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] samepolyXXX coded in bitstream but no polyXXX defined !\n"));
3572 : }
3573 9 : lsr_read_id(lsr, elt);
3574 9 : if (same_type==2) lsr_read_fill(lsr, elt);
3575 3 : else if (same_type==3) lsr_read_stroke(lsr, elt);
3576 9 : lsr_read_point_sequence(lsr, *(GF_List**)info.far_ptr, "points");
3577 : } else {
3578 22 : lsr_read_id(lsr, elt);
3579 22 : lsr_read_rare_full(lsr, elt);
3580 22 : lsr_read_fill(lsr, elt);
3581 22 : lsr_read_stroke(lsr, elt);
3582 22 : lsr_read_point_sequence(lsr, *(GF_List**)info.far_ptr, "points");
3583 22 : lsr_read_any_attribute(lsr, elt, 1);
3584 22 : lsr->prev_polygon = (SVG_Element*)elt;
3585 : }
3586 31 : lsr_read_group_content(lsr, elt, same_type);
3587 31 : return elt;
3588 : }
3589 2 : static GF_Node *lsr_read_radialGradient(GF_LASeRCodec *lsr)
3590 : {
3591 2 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_radialGradient);
3592 2 : lsr_read_id(lsr, elt);
3593 2 : lsr_read_rare(lsr, elt);
3594 2 : lsr_read_fill(lsr, elt);
3595 2 : lsr_read_stroke(lsr, elt);
3596 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_cx, 1, "cx");
3597 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_cy, 1, "cy");
3598 2 : lsr_read_gradient_units(lsr, elt);
3599 2 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_r, 1, "r");
3600 2 : lsr_read_any_attribute(lsr, elt, 1);
3601 2 : lsr_read_group_content(lsr, elt, 0);
3602 2 : return elt;
3603 : }
3604 77 : static GF_Node *lsr_read_rect(GF_LASeRCodec *lsr, u32 same_type)
3605 : {
3606 77 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_rect);
3607 :
3608 77 : if (same_type) {
3609 36 : if (lsr->prev_rect) {
3610 36 : lsr_restore_base(lsr, (SVG_Element*)elt, (SVG_Element *)lsr->prev_rect, (same_type==2) ? 1 : 0, 0);
3611 : } else {
3612 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] samerect coded in bitstream but no rect defined !\n"));
3613 : }
3614 36 : lsr_read_id(lsr, elt);
3615 36 : if (same_type==2) lsr_read_fill(lsr, elt);
3616 36 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_height, 0, "height");
3617 36 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_width, 0, "width");
3618 36 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_x, 1, "x");
3619 36 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y, 1, "y");
3620 : } else {
3621 41 : lsr_read_id(lsr, elt);
3622 41 : lsr_read_rare_full(lsr, elt);
3623 41 : lsr_read_fill(lsr, elt);
3624 41 : lsr_read_stroke(lsr, elt);
3625 41 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_height, 0, "height");
3626 41 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_rx, 1, "rx");
3627 41 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_ry, 1, "ry");
3628 41 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_width, 0, "width");
3629 41 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_x, 1, "x");
3630 41 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y, 1, "y");
3631 41 : lsr_read_any_attribute(lsr, elt, 1);
3632 41 : lsr->prev_rect = (SVG_Element*)elt;
3633 : }
3634 77 : lsr_read_group_content(lsr, elt, same_type);
3635 77 : return elt;
3636 : }
3637 :
3638 5 : static GF_Node *lsr_read_rectClip(GF_LASeRCodec *lsr)
3639 : {
3640 : u32 flag;
3641 5 : GF_Node *elt = gf_node_new(lsr->sg, TAG_LSR_rectClip);
3642 5 : lsr_read_id(lsr, elt);
3643 5 : lsr_read_rare_full(lsr, elt);
3644 5 : lsr_read_fill(lsr, elt);
3645 5 : lsr_read_stroke(lsr, elt);
3646 5 : lsr_read_eRR(lsr, elt);
3647 5 : GF_LSR_READ_INT(lsr, flag, 1, "has_size");
3648 5 : if (flag) {
3649 : SVG_Number num;
3650 : GF_FieldInfo info;
3651 3 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_size, 1, 0, &info);
3652 3 : lsr_read_coordinate(lsr, & num, 0, "width");
3653 3 : ((LASeR_Size*)info.far_ptr)->width = num.value;
3654 3 : lsr_read_coordinate(lsr, & num, 0, "height");
3655 3 : ((LASeR_Size*)info.far_ptr)->height = num.value;
3656 : }
3657 5 : lsr_read_any_attribute(lsr, elt, 1);
3658 5 : lsr_read_group_content(lsr, elt, 0);
3659 5 : return elt;
3660 : }
3661 :
3662 5 : static GF_Node *lsr_read_script(GF_LASeRCodec *lsr)
3663 : {
3664 5 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_script);
3665 5 : lsr_read_id(lsr, elt);
3666 5 : lsr_read_rare(lsr, elt);
3667 5 : lsr_read_eRR(lsr, elt);
3668 5 : lsr_read_script_type(lsr, elt);
3669 5 : lsr_read_href(lsr, elt);
3670 5 : lsr_read_any_attribute(lsr, elt, 1);
3671 5 : lsr_read_group_content(lsr, elt, 0);
3672 5 : return elt;
3673 : }
3674 :
3675 11 : static GF_Node *lsr_read_selector(GF_LASeRCodec *lsr)
3676 : {
3677 : u32 flag;
3678 11 : GF_Node *elt = gf_node_new(lsr->sg, TAG_LSR_selector);
3679 11 : lsr_read_id(lsr, elt);
3680 11 : lsr_read_rare_full(lsr, elt);
3681 11 : lsr_read_fill(lsr, elt);
3682 11 : lsr_read_stroke(lsr, elt);
3683 11 : lsr_read_eRR(lsr, elt);
3684 11 : GF_LSR_READ_INT(lsr, flag, 1, "hasChoice");
3685 11 : if (flag) {
3686 : GF_FieldInfo info;
3687 9 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_choice, 1, 0, &info);
3688 9 : GF_LSR_READ_INT(lsr, flag, 1, "choice");
3689 9 : if (flag) {
3690 6 : GF_LSR_READ_INT(lsr, ((LASeR_Choice*)info.far_ptr)->type, 1, "type");
3691 : } else {
3692 3 : GF_LSR_READ_INT(lsr, ((LASeR_Choice*)info.far_ptr)->choice_index, 8, "value");
3693 3 : ((LASeR_Choice*)info.far_ptr)->type = LASeR_CHOICE_N;
3694 : }
3695 : }
3696 11 : lsr_read_any_attribute(lsr, elt, 1);
3697 11 : lsr_read_group_content(lsr, elt, 0);
3698 11 : return elt;
3699 : }
3700 :
3701 2 : static GF_Node *lsr_read_set(GF_LASeRCodec *lsr, SVG_Element *parent)
3702 : {
3703 2 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_set);
3704 2 : lsr_read_id(lsr, elt);
3705 2 : lsr_read_rare(lsr, elt);
3706 : lsr_read_attribute_name(lsr, elt);
3707 2 : lsr_read_attribute_type(lsr, elt);
3708 :
3709 2 : lsr_read_smil_times(lsr, elt, TAG_SVG_ATT_begin, NULL, "begin", 1);
3710 : lsr_read_duration(lsr, elt);
3711 2 : lsr_read_anim_fill(lsr, elt);
3712 2 : lsr_read_anim_repeatCount(lsr, elt);
3713 2 : lsr_read_repeat_duration(lsr, elt);
3714 2 : lsr_read_anim_restart(lsr, elt);
3715 2 : lsr_read_anim_value(lsr, elt, TAG_SVG_ATT_to, "to");
3716 2 : lsr_read_href(lsr, elt);
3717 2 : lsr_read_lsr_enabled(lsr, elt);
3718 2 : lsr_read_any_attribute(lsr, elt, 1);
3719 :
3720 2 : if (!lsr_setup_smil_anim(lsr, (SVG_Element*)elt, parent)) {
3721 0 : gf_list_add(lsr->deferred_anims, elt);
3722 0 : lsr_read_group_content_post_init(lsr, (SVG_Element*)elt, 1);
3723 : } else {
3724 2 : lsr_read_group_content(lsr, elt, 0);
3725 : }
3726 2 : return elt;
3727 : }
3728 :
3729 5 : static GF_Node *lsr_read_simpleLayout(GF_LASeRCodec *lsr)
3730 : {
3731 : u32 flag;
3732 5 : GF_Node *elt = gf_node_new(lsr->sg, TAG_LSR_simpleLayout);
3733 5 : lsr_read_id(lsr, elt);
3734 5 : lsr_read_rare_full(lsr, elt);
3735 5 : lsr_read_fill(lsr, elt);
3736 5 : lsr_read_stroke(lsr, elt);
3737 5 : GF_LSR_READ_INT(lsr, flag, 1, "has_delta");
3738 5 : if (flag) {
3739 : SVG_Number num;
3740 : GF_FieldInfo info;
3741 2 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_delta, 1, 0, &info);
3742 2 : lsr_read_coordinate(lsr, & num, 0, "width");
3743 2 : ((LASeR_Size*)info.far_ptr)->width = num.value;
3744 2 : lsr_read_coordinate(lsr, & num, 0, "height");
3745 2 : ((LASeR_Size*)info.far_ptr)->height = num.value;
3746 : }
3747 5 : lsr_read_eRR(lsr, elt);
3748 5 : lsr_read_any_attribute(lsr, elt, 1);
3749 5 : lsr_read_group_content(lsr, elt, 0);
3750 5 : return elt;
3751 : }
3752 :
3753 20 : static GF_Node *lsr_read_stop(GF_LASeRCodec *lsr)
3754 : {
3755 : GF_FieldInfo info;
3756 20 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_stop);
3757 20 : lsr_read_id(lsr, elt);
3758 20 : lsr_read_rare(lsr, elt);
3759 20 : lsr_read_fill(lsr, elt);
3760 20 : lsr_read_stroke(lsr, elt);
3761 :
3762 20 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_offset, 1, 0, &info);
3763 20 : ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_16_8(lsr, "offset");
3764 20 : lsr_read_any_attribute(lsr, elt, 1);
3765 20 : lsr_read_group_content(lsr, elt, 0);
3766 20 : return elt;
3767 : }
3768 5 : static GF_Node *lsr_read_svg(GF_LASeRCodec *lsr, Bool init_node)
3769 : {
3770 : GF_FieldInfo info;
3771 : SMIL_Duration snap;
3772 : u32 flag;
3773 5 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_svg);
3774 5 : lsr_read_id(lsr, elt);
3775 5 : lsr_read_rare(lsr, elt);
3776 5 : lsr_read_fill(lsr, elt);
3777 5 : lsr_read_stroke(lsr, elt);
3778 5 : lsr_read_string_attribute(lsr, elt, TAG_SVG_ATT_baseProfile, "baseProfile");
3779 5 : lsr_read_string_attribute(lsr, elt, TAG_SVG_ATT_contentScriptType, "contentScriptType");
3780 5 : lsr_read_eRR(lsr, elt);
3781 5 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_height, 1, 0, &info);
3782 5 : lsr_read_value_with_units(lsr, info.far_ptr, "height");
3783 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasPlaybackOrder");
3784 5 : if (flag) {
3785 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_playbackOrder, 1, 1, &info);
3786 0 : GF_LSR_READ_INT(lsr, flag, 1, "playbackOrder");
3787 0 : if (flag) *(SVG_PlaybackOrder*)info.far_ptr = SVG_PLAYBACKORDER_FORWARDONLY;
3788 : }
3789 :
3790 5 : lsr_read_preserve_aspect_ratio(lsr, elt);
3791 :
3792 :
3793 5 : GF_LSR_READ_INT(lsr, flag, 1, "has_snapshotTime");
3794 5 : if (flag) {
3795 0 : lsr_read_duration_ex(lsr, NULL, 0, &snap, "snapshotTime", 0);
3796 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_snapshotTime, 1, 1, &info);
3797 0 : if (snap.type==SMIL_DURATION_DEFINED) *((SVG_Clock *)info.far_ptr) = snap.clock_value;
3798 : }
3799 :
3800 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasSyncBehavior");
3801 5 : if (flag) {
3802 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_syncBehaviorDefault, 1, 0, &info);
3803 0 : GF_LSR_READ_INT(lsr, flag, 2, "syncBehaviorDefault");
3804 0 : switch (flag) {
3805 0 : case 0:
3806 0 : *((SMIL_SyncBehavior*)info.far_ptr) = SMIL_SYNCBEHAVIOR_CANSLIP;
3807 0 : break;
3808 0 : case 1:
3809 0 : *((SMIL_SyncBehavior*)info.far_ptr) = SMIL_SYNCBEHAVIOR_INDEPENDENT;
3810 0 : break;
3811 0 : case 3:
3812 0 : *((SMIL_SyncBehavior*)info.far_ptr) = SMIL_SYNCBEHAVIOR_LOCKED;
3813 0 : break;
3814 0 : default:
3815 0 : *((SMIL_SyncBehavior*)info.far_ptr) = SMIL_SYNCBEHAVIOR_INHERIT;
3816 0 : break;
3817 : }
3818 5 : }
3819 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasSyncToleranceDefault");
3820 5 : if (flag) {
3821 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_syncToleranceDefault, 1, 0, &info);
3822 0 : ((SMIL_SyncTolerance*)info.far_ptr)->type = SMIL_SYNCTOLERANCE_VALUE;
3823 0 : GF_LSR_READ_INT(lsr, flag, 1, "choice");
3824 0 : ((SMIL_SyncTolerance*)info.far_ptr)->value = lsr_read_vluimsbf5(lsr, "value");
3825 0 : ((SMIL_SyncTolerance*)info.far_ptr)->value /= lsr->time_resolution;
3826 : }
3827 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasTimelineBegin");
3828 5 : if (flag) {
3829 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_timelineBegin, 1, 0, &info);
3830 0 : GF_LSR_READ_INT(lsr, flag, 1, "timelineBegin");
3831 0 : if (flag) *(SVG_TimelineBegin*)info.far_ptr = SVG_TIMELINEBEGIN_ONLOAD;
3832 : }
3833 5 : lsr_read_string_attribute(lsr, elt, TAG_SVG_ATT_version, "version");
3834 :
3835 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasViewBox");
3836 5 : if (flag) {
3837 3 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_viewBox, 1, 0, &info);
3838 3 : ((SVG_ViewBox*)info.far_ptr)->x = lsr_read_fixed_16_8(lsr, "viewbox.x");
3839 3 : ((SVG_ViewBox*)info.far_ptr)->y = lsr_read_fixed_16_8(lsr, "viewbox.y");
3840 3 : ((SVG_ViewBox*)info.far_ptr)->width = lsr_read_fixed_16_8(lsr, "viewbox.width");
3841 3 : ((SVG_ViewBox*)info.far_ptr)->height = lsr_read_fixed_16_8(lsr, "viewbox.height");
3842 3 : ((SVG_ViewBox*)info.far_ptr)->is_set = 1;
3843 : }
3844 :
3845 5 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_width, 1, 0, &info);
3846 5 : lsr_read_value_with_units(lsr, info.far_ptr, "width");
3847 :
3848 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasZoomAndPan");
3849 5 : if (flag) {
3850 3 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_zoomAndPan, 1, 0, &info);
3851 3 : GF_LSR_READ_INT(lsr, flag, 1, "zoomAndPan");
3852 3 : *((SVG_ZoomAndPan*)info.far_ptr) = flag ? SVG_ZOOMANDPAN_MAGNIFY : SVG_ZOOMANDPAN_DISABLE;
3853 : }
3854 5 : lsr_read_any_attribute(lsr, elt, 1);
3855 : /*store current root for listeners with no focus target*/
3856 5 : lsr->current_root = elt;
3857 :
3858 5 : if (init_node) {
3859 1 : gf_node_register(elt, NULL);
3860 1 : gf_sg_set_root_node(lsr->sg, elt);
3861 : }
3862 :
3863 5 : lsr_read_group_content(lsr, elt, 0);
3864 5 : return elt;
3865 : }
3866 :
3867 2 : static GF_Node *lsr_read_switch(GF_LASeRCodec *lsr)
3868 : {
3869 2 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_switch);
3870 2 : lsr_read_id(lsr, elt);
3871 2 : lsr_read_rare_full(lsr, elt);
3872 2 : lsr_read_fill(lsr, elt);
3873 2 : lsr_read_stroke(lsr, elt);
3874 2 : lsr_read_eRR(lsr, elt);
3875 2 : lsr_read_any_attribute(lsr, elt, 1);
3876 2 : lsr_read_group_content(lsr, elt, 0);
3877 2 : return elt;
3878 : }
3879 :
3880 :
3881 17 : static GF_Node *lsr_read_text(GF_LASeRCodec *lsr, u32 same_type)
3882 : {
3883 : u32 flag;
3884 : GF_FieldInfo info;
3885 17 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_text);
3886 17 : if (same_type) {
3887 0 : if (lsr->prev_text) {
3888 0 : lsr_restore_base(lsr, (SVG_Element *)elt, (SVG_Element *)lsr->prev_text, (same_type==2) ? 1 : 0, 0);
3889 : } else {
3890 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] sametext coded in bitstream but no text defined !\n"));
3891 : }
3892 0 : lsr_read_id(lsr, elt);
3893 0 : if (same_type==2) lsr_read_fill(lsr, elt);
3894 0 : lsr_read_coord_list(lsr, elt, TAG_SVG_ATT_text_x, "x");
3895 0 : lsr_read_coord_list(lsr, elt, TAG_SVG_ATT_text_y, "y");
3896 : } else {
3897 17 : lsr_read_id(lsr, elt);
3898 17 : lsr_read_rare_full(lsr, elt);
3899 17 : lsr_read_fill(lsr, elt);
3900 17 : lsr_read_stroke(lsr, elt);
3901 :
3902 17 : GF_LSR_READ_INT(lsr, flag, 1, "editable");
3903 17 : if (flag) {
3904 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_editable, 1, 0, &info);
3905 0 : *(SVG_Boolean*)info.far_ptr = flag;
3906 : }
3907 17 : lsr_read_float_list(lsr, elt, TAG_SVG_ATT_text_rotate, NULL, "rotate");
3908 17 : lsr_read_coord_list(lsr, elt, TAG_SVG_ATT_text_x, "x");
3909 17 : lsr_read_coord_list(lsr, elt, TAG_SVG_ATT_text_y, "y");
3910 17 : lsr_read_any_attribute(lsr, elt, 1);
3911 17 : lsr->prev_text = (SVG_Element*)elt;
3912 : }
3913 17 : lsr_read_group_content(lsr, elt, same_type);
3914 17 : return elt;
3915 : }
3916 :
3917 2 : static GF_Node *lsr_read_tspan(GF_LASeRCodec *lsr)
3918 : {
3919 2 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_tspan);
3920 2 : lsr_read_id(lsr, elt);
3921 2 : lsr_read_rare(lsr, elt);
3922 2 : lsr_read_fill(lsr, elt);
3923 2 : lsr_read_stroke(lsr, elt);
3924 2 : lsr_read_any_attribute(lsr, elt, 1);
3925 2 : lsr_read_group_content(lsr, elt, 0);
3926 2 : return elt;
3927 : }
3928 :
3929 11 : static GF_Node *lsr_read_use(GF_LASeRCodec *lsr, Bool is_same)
3930 : {
3931 : GF_FieldInfo info;
3932 : u32 flag;
3933 11 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_use);
3934 11 : if (is_same) {
3935 3 : if (lsr->prev_use) {
3936 3 : lsr_restore_base(lsr, (SVG_Element *)elt, lsr->prev_use, 0, 0);
3937 : } else {
3938 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] sameuse coded in bitstream but no use defined !\n"));
3939 : }
3940 3 : lsr_read_id(lsr, elt);
3941 3 : lsr_read_href(lsr, elt);
3942 : } else {
3943 8 : lsr_read_id(lsr, elt);
3944 8 : lsr_read_rare_full(lsr, elt);
3945 8 : lsr_read_fill(lsr, elt);
3946 8 : lsr_read_stroke(lsr, elt);
3947 8 : lsr_read_eRR(lsr, elt);
3948 :
3949 8 : GF_LSR_READ_INT(lsr, flag, 1, "hasOverflow");
3950 8 : if (flag) {
3951 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_overflow, 1, 0, &info);
3952 0 : GF_LSR_READ_INT(lsr, *(SVG_Overflow*)info.far_ptr, 2, "overflow");
3953 : }
3954 8 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_x, 1, "x");
3955 8 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y, 1, "y");
3956 8 : lsr_read_href(lsr, elt);
3957 8 : lsr_read_any_attribute(lsr, elt, 1);
3958 8 : lsr->prev_use = (SVG_Element*)elt;
3959 : }
3960 11 : lsr_read_group_content(lsr, elt, is_same);
3961 11 : return elt;
3962 : }
3963 :
3964 5 : static GF_Node *lsr_read_video(GF_LASeRCodec *lsr, SVG_Element *parent)
3965 : {
3966 : GF_FieldInfo info;
3967 : u32 flag;
3968 5 : GF_Node*elt = gf_node_new(lsr->sg, TAG_SVG_video);
3969 5 : lsr_read_id(lsr, elt);
3970 5 : lsr_read_rare_full(lsr, elt);
3971 5 : lsr_read_smil_times(lsr, elt, TAG_SVG_ATT_begin, NULL, "begin", 1);
3972 : lsr_read_duration(lsr, elt);
3973 5 : lsr_read_eRR(lsr, elt);
3974 5 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_height, 1, "height");
3975 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasOverlay");
3976 5 : if (flag) {
3977 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_overlay, 1, 1, &info);
3978 0 : GF_LSR_READ_INT(lsr, flag, 1, "choice");
3979 0 : if (flag) {
3980 0 : GF_LSR_READ_INT(lsr, *(SVG_Overlay*)info.far_ptr, 1, "choice");
3981 : } else {
3982 0 : char *str = NULL;
3983 0 : lsr_read_byte_align_string(lsr, & str, "overlayExt");
3984 0 : if (str) gf_free(str);
3985 : }
3986 : }
3987 5 : lsr_read_preserve_aspect_ratio(lsr, elt);
3988 5 : lsr_read_anim_repeatCount(lsr, elt);
3989 5 : lsr_read_repeat_duration(lsr, elt);
3990 5 : lsr_read_anim_restart(lsr, elt);
3991 5 : lsr_read_sync_behavior(lsr, elt);
3992 5 : lsr_read_sync_tolerance(lsr, elt);
3993 5 : lsr_read_transform_behavior(lsr, elt);
3994 5 : lsr_read_content_type(lsr, elt);
3995 5 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_width, 1, "width");
3996 5 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_x, 1, "x");
3997 5 : lsr_read_coordinate_ptr(lsr, elt, TAG_SVG_ATT_y, 1, "y");
3998 5 : lsr_read_href(lsr, elt);
3999 :
4000 5 : lsr_read_clip_time(lsr, elt, TAG_SVG_ATT_clipBegin, "clipBegin");
4001 5 : lsr_read_clip_time(lsr, elt, TAG_SVG_ATT_clipEnd, "clipEnd");
4002 :
4003 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasFullscreen");
4004 5 : if (flag) {
4005 3 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_SVG_ATT_fullscreen, 1, 0, &info);
4006 3 : GF_LSR_READ_INT(lsr, *(SVG_Boolean *)info.far_ptr, 1, "fullscreen");
4007 : }
4008 :
4009 5 : lsr_read_sync_reference(lsr, elt);
4010 5 : lsr_read_any_attribute(lsr, elt, 1);
4011 5 : lsr_read_group_content(lsr, elt, 0);
4012 5 : return elt;
4013 : }
4014 :
4015 5 : static GF_Node *lsr_read_listener(GF_LASeRCodec *lsr, SVG_Element *parent)
4016 : {
4017 : u32 flag;
4018 : GF_FieldInfo info;
4019 : XMLEV_Event *ev = NULL;
4020 : XMLRI *observer, *target, *handler;
4021 5 : GF_Node *elt = gf_node_new(lsr->sg, TAG_SVG_listener);
4022 :
4023 : observer = target = handler = NULL;
4024 :
4025 5 : lsr_read_id(lsr, elt);
4026 5 : lsr_read_rare(lsr, elt);
4027 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasDefaultAction");
4028 5 : if (flag) {
4029 3 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_XMLEV_ATT_defaultAction, 1, 0, &info);
4030 3 : GF_LSR_READ_INT(lsr, *(XMLEV_DefaultAction*)info.far_ptr, 1, "defaultAction");
4031 : }
4032 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasEvent");
4033 5 : if (flag) {
4034 3 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_XMLEV_ATT_event, 1, 0, &info);
4035 3 : lsr_read_event_type(lsr, info.far_ptr);
4036 3 : ev = info.far_ptr;
4037 : }
4038 : /*create default handler but UNINITIALIZED*/
4039 5 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_XMLEV_ATT_handler, 1, 0, &info);
4040 5 : handler = info.far_ptr;
4041 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasHandler");
4042 5 : if (flag) {
4043 3 : lsr_read_any_uri(lsr, info.far_ptr, "handler");
4044 : }
4045 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasObserver");
4046 : /*TODO double check spec here*/
4047 5 : if (flag) {
4048 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_XMLEV_ATT_observer, 1, 0, &info);
4049 0 : lsr_read_codec_IDREF(lsr, info.far_ptr, "observer");
4050 0 : observer = info.far_ptr;
4051 : }
4052 :
4053 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasPhase");
4054 5 : if (flag) {
4055 3 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_XMLEV_ATT_phase, 1, 0, &info);
4056 3 : GF_LSR_READ_INT(lsr, *(XMLEV_Phase*)info.far_ptr, 1, "phase");
4057 : }
4058 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasPropagate");
4059 5 : if (flag) {
4060 3 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_XMLEV_ATT_propagate, 1, 0, &info);
4061 3 : GF_LSR_READ_INT(lsr, *(XMLEV_Propagate*)info.far_ptr, 1, "propagate");
4062 : }
4063 5 : GF_LSR_READ_INT(lsr, flag, 1, "hasTarget");
4064 5 : if (flag) {
4065 0 : lsr->last_error = gf_node_get_attribute_by_tag(elt, TAG_XMLEV_ATT_target, 1, 0, &info);
4066 0 : lsr_read_codec_IDREF(lsr, info.far_ptr, "target");
4067 0 : target = info.far_ptr;
4068 : }
4069 :
4070 5 : lsr_read_lsr_enabled(lsr, elt);
4071 5 : lsr_read_any_attribute(lsr, elt, 1);
4072 5 : lsr_read_group_content(lsr, elt, 0);
4073 :
4074 : /*register listener element*/
4075 : {
4076 : Bool post_pone = 0;
4077 : SVG_Element *par = NULL;
4078 5 : if (observer && observer->type == XMLRI_ELEMENTID) {
4079 0 : if (observer->target) par = observer->target;
4080 : }
4081 5 : if (!par && target && (target->type == XMLRI_ELEMENTID)) {
4082 0 : if (!target->target) post_pone = 1;
4083 : else par = target->target;
4084 : }
4085 5 : if (!handler->target && !handler->string) {
4086 2 : handler->type = XMLRI_ELEMENTID;
4087 2 : handler->target = parent;
4088 : }
4089 : /*FIXME - double check with XML events*/
4090 5 : if (!par && !observer) {
4091 : /*all non-UI get attched to root*/
4092 5 : if (ev && (ev->type>GF_EVENT_MOUSEWHEEL)) {
4093 3 : par = (SVG_Element*) lsr->current_root;
4094 : }
4095 2 : else if (parent) par = parent;
4096 0 : else par = (SVG_Element*) lsr->current_root;
4097 : }
4098 5 : if (!par) post_pone = 1;
4099 :
4100 5 : if (post_pone) {
4101 0 : gf_list_add(lsr->deferred_listeners, elt);
4102 : } else {
4103 : if (!par) par = parent;
4104 5 : gf_node_dom_listener_add((GF_Node *)par, elt);
4105 : }
4106 : }
4107 5 : return elt;
4108 : }
4109 :
4110 444 : static GF_Node *lsr_read_scene_content_model(GF_LASeRCodec *lsr, SVG_Element *parent)
4111 : {
4112 : GF_Node *n;
4113 : u32 ntype;
4114 444 : GF_LSR_READ_INT(lsr, ntype, 6, "ch4");
4115 : n = NULL;
4116 444 : switch (ntype) {
4117 12 : case LSR_SCENE_CONTENT_MODEL_a:
4118 12 : n = lsr_read_a(lsr);
4119 12 : break;
4120 99 : case LSR_SCENE_CONTENT_MODEL_animate:
4121 99 : n = lsr_read_animate(lsr, parent, 0);
4122 99 : break;
4123 0 : case LSR_SCENE_CONTENT_MODEL_animateColor:
4124 0 : n = lsr_read_animate(lsr, parent, 1);
4125 0 : break;
4126 6 : case LSR_SCENE_CONTENT_MODEL_animateMotion:
4127 6 : n = lsr_read_animateMotion(lsr, parent);
4128 6 : break;
4129 12 : case LSR_SCENE_CONTENT_MODEL_animateTransform:
4130 12 : n = lsr_read_animateTransform(lsr, parent);
4131 12 : break;
4132 3 : case LSR_SCENE_CONTENT_MODEL_audio:
4133 3 : n = lsr_read_audio(lsr, parent);
4134 3 : break;
4135 9 : case LSR_SCENE_CONTENT_MODEL_circle:
4136 9 : n = lsr_read_circle(lsr);
4137 9 : break;
4138 3 : case LSR_SCENE_CONTENT_MODEL_conditional:
4139 3 : n = lsr_read_conditional(lsr);
4140 3 : break;
4141 0 : case LSR_SCENE_CONTENT_MODEL_cursorManager:
4142 0 : n = lsr_read_cursorManager(lsr);
4143 0 : break;
4144 0 : case LSR_SCENE_CONTENT_MODEL_defs:
4145 0 : n = lsr_read_defs(lsr);
4146 0 : break;
4147 0 : case LSR_SCENE_CONTENT_MODEL_desc:
4148 0 : n = lsr_read_data(lsr, TAG_SVG_desc);
4149 0 : break;
4150 0 : case LSR_SCENE_CONTENT_MODEL_ellipse:
4151 0 : n = lsr_read_ellipse(lsr);
4152 0 : break;
4153 0 : case LSR_SCENE_CONTENT_MODEL_foreignObject:
4154 0 : n = lsr_read_foreignObject(lsr);
4155 0 : break;
4156 27 : case LSR_SCENE_CONTENT_MODEL_g:
4157 27 : n = lsr_read_g(lsr, 0);
4158 27 : break;
4159 39 : case LSR_SCENE_CONTENT_MODEL_image:
4160 39 : n = lsr_read_image(lsr);
4161 39 : break;
4162 3 : case LSR_SCENE_CONTENT_MODEL_line:
4163 3 : n = lsr_read_line(lsr, 0);
4164 3 : break;
4165 6 : case LSR_SCENE_CONTENT_MODEL_linearGradient:
4166 6 : n = lsr_read_linearGradient(lsr);
4167 6 : break;
4168 0 : case LSR_SCENE_CONTENT_MODEL_metadata:
4169 0 : n = lsr_read_data(lsr, TAG_SVG_metadata);
4170 0 : break;
4171 3 : case LSR_SCENE_CONTENT_MODEL_mpath:
4172 3 : n = lsr_read_mpath(lsr);
4173 3 : break;
4174 15 : case LSR_SCENE_CONTENT_MODEL_path:
4175 15 : n = lsr_read_path(lsr, 0);
4176 15 : break;
4177 9 : case LSR_SCENE_CONTENT_MODEL_polygon:
4178 9 : n = lsr_read_polygon(lsr, 0, 0);
4179 9 : break;
4180 9 : case LSR_SCENE_CONTENT_MODEL_polyline:
4181 9 : n = lsr_read_polygon(lsr, 1, 0);
4182 9 : break;
4183 0 : case LSR_SCENE_CONTENT_MODEL_radialGradient:
4184 0 : n = lsr_read_radialGradient(lsr);
4185 0 : break;
4186 36 : case LSR_SCENE_CONTENT_MODEL_rect:
4187 36 : n = lsr_read_rect(lsr, 0);
4188 36 : break;
4189 3 : case LSR_SCENE_CONTENT_MODEL_rectClip:
4190 3 : n = lsr_read_rectClip(lsr);
4191 3 : break;
4192 0 : case LSR_SCENE_CONTENT_MODEL_sameg:
4193 0 : n = lsr_read_g(lsr, 1);
4194 0 : break;
4195 0 : case LSR_SCENE_CONTENT_MODEL_sameline:
4196 0 : n = lsr_read_line(lsr, 1);
4197 0 : break;
4198 3 : case LSR_SCENE_CONTENT_MODEL_samepath:
4199 3 : n = lsr_read_path(lsr, 1);
4200 3 : break;
4201 3 : case LSR_SCENE_CONTENT_MODEL_samepathfill:
4202 3 : n = lsr_read_path(lsr, 2);
4203 3 : break;
4204 0 : case LSR_SCENE_CONTENT_MODEL_samepolygon:
4205 0 : n = lsr_read_polygon(lsr, 0, 1);
4206 0 : break;
4207 6 : case LSR_SCENE_CONTENT_MODEL_samepolygonfill:
4208 6 : n = lsr_read_polygon(lsr, 0, 2);
4209 6 : break;
4210 0 : case LSR_SCENE_CONTENT_MODEL_samepolygonstroke:
4211 0 : n = lsr_read_polygon(lsr, 0, 3);
4212 0 : break;
4213 3 : case LSR_SCENE_CONTENT_MODEL_samepolyline:
4214 3 : n = lsr_read_polygon(lsr, 1, 1);
4215 3 : break;
4216 0 : case LSR_SCENE_CONTENT_MODEL_samepolylinefill:
4217 0 : n = lsr_read_polygon(lsr, 1, 2);
4218 0 : break;
4219 0 : case LSR_SCENE_CONTENT_MODEL_samepolylinestroke:
4220 0 : n = lsr_read_polygon(lsr, 1, 3);
4221 0 : break;
4222 36 : case LSR_SCENE_CONTENT_MODEL_samerect:
4223 36 : n = lsr_read_rect(lsr, 1);
4224 36 : break;
4225 0 : case LSR_SCENE_CONTENT_MODEL_samerectfill:
4226 0 : n = lsr_read_rect(lsr, 2);
4227 0 : break;
4228 0 : case LSR_SCENE_CONTENT_MODEL_sametext:
4229 0 : n = lsr_read_text(lsr, 1);
4230 0 : break;
4231 0 : case LSR_SCENE_CONTENT_MODEL_sametextfill:
4232 0 : n = lsr_read_text(lsr, 2);
4233 0 : break;
4234 3 : case LSR_SCENE_CONTENT_MODEL_sameuse:
4235 3 : n = lsr_read_use(lsr, 1);
4236 3 : break;
4237 3 : case LSR_SCENE_CONTENT_MODEL_script:
4238 3 : n = lsr_read_script(lsr);
4239 3 : break;
4240 9 : case LSR_SCENE_CONTENT_MODEL_selector:
4241 9 : n = lsr_read_selector(lsr);
4242 9 : break;
4243 0 : case LSR_SCENE_CONTENT_MODEL_set:
4244 0 : n = lsr_read_set(lsr, parent);
4245 0 : break;
4246 3 : case LSR_SCENE_CONTENT_MODEL_simpleLayout:
4247 3 : n = lsr_read_simpleLayout(lsr);
4248 3 : break;
4249 18 : case LSR_SCENE_CONTENT_MODEL_stop:
4250 18 : n = lsr_read_stop(lsr);
4251 18 : break;
4252 0 : case LSR_SCENE_CONTENT_MODEL_switch:
4253 0 : n = lsr_read_switch(lsr);
4254 0 : break;
4255 12 : case LSR_SCENE_CONTENT_MODEL_text:
4256 12 : n = lsr_read_text(lsr, 0);
4257 12 : break;
4258 0 : case LSR_SCENE_CONTENT_MODEL_title:
4259 0 : n = lsr_read_data(lsr, TAG_SVG_title);
4260 0 : break;
4261 0 : case LSR_SCENE_CONTENT_MODEL_tspan:
4262 0 : n = lsr_read_tspan(lsr);
4263 0 : break;
4264 6 : case LSR_SCENE_CONTENT_MODEL_use:
4265 6 : n = lsr_read_use(lsr, 0);
4266 6 : break;
4267 3 : case LSR_SCENE_CONTENT_MODEL_video:
4268 3 : n = lsr_read_video(lsr, parent);
4269 3 : break;
4270 3 : case LSR_SCENE_CONTENT_MODEL_listener:
4271 3 : n = lsr_read_listener(lsr, parent);
4272 3 : break;
4273 0 : case LSR_SCENE_CONTENT_MODEL_element_any:
4274 0 : lsr_read_extend_class(lsr, NULL, 0, "node");
4275 : break;
4276 0 : case LSR_SCENE_CONTENT_MODEL_privateContainer:
4277 0 : lsr_read_private_element_container(lsr);
4278 : break;
4279 39 : case LSR_SCENE_CONTENT_MODEL_textContent:
4280 39 : lsr_read_text_content(lsr, (GF_Node*)parent);
4281 : break;
4282 : default:
4283 : break;
4284 : }
4285 405 : if (n && n->sgprivate->interact && n->sgprivate->interact->dom_evt) {
4286 : GF_DOM_Event evt;
4287 : memset(&evt, 0, sizeof(GF_DOM_Event));
4288 4 : evt.type = GF_EVENT_LOAD;
4289 4 : gf_dom_event_fire(n, &evt);
4290 : }
4291 444 : return n;
4292 : }
4293 :
4294 84 : static GF_Node *lsr_read_update_content_model(GF_LASeRCodec *lsr, SVG_Element *parent)
4295 : {
4296 : u32 flag;
4297 : GF_Node *n=NULL;
4298 84 : GF_LSR_READ_INT(lsr, flag, 1, "ch4");
4299 84 : if (flag) {
4300 10 : GF_LSR_READ_INT(lsr, flag, 3, "ch61");
4301 10 : switch (flag) {
4302 2 : case LSR_UPDATE_CONTENT_MODEL2_conditional:
4303 2 : n = lsr_read_conditional(lsr);
4304 2 : break;
4305 2 : case LSR_UPDATE_CONTENT_MODEL2_cursorManager:
4306 2 : n = lsr_read_cursorManager(lsr);
4307 2 : break;
4308 0 : case LSR_UPDATE_CONTENT_MODEL2_extend:
4309 0 : lsr_read_extend_class(lsr, NULL, 0, "extend");
4310 0 : return NULL;
4311 0 : case LSR_UPDATE_CONTENT_MODEL2_private:
4312 0 : lsr_read_private_element_container(lsr);
4313 0 : return NULL;
4314 2 : case LSR_UPDATE_CONTENT_MODEL2_rectClip:
4315 2 : n = lsr_read_rectClip(lsr);
4316 2 : break;
4317 2 : case LSR_UPDATE_CONTENT_MODEL2_simpleLayout:
4318 2 : n = lsr_read_simpleLayout(lsr);
4319 2 : break;
4320 2 : case LSR_UPDATE_CONTENT_MODEL2_selector:
4321 2 : n = lsr_read_selector(lsr);
4322 2 : break;
4323 : }
4324 : } else {
4325 74 : GF_LSR_READ_INT(lsr, flag, 6, "ch6");
4326 74 : switch(flag) {
4327 2 : case LSR_UPDATE_CONTENT_MODEL_a:
4328 2 : n = lsr_read_a(lsr);
4329 2 : break;
4330 2 : case LSR_UPDATE_CONTENT_MODEL_animate:
4331 2 : n = lsr_read_animate(lsr, parent, 0);
4332 2 : break;
4333 2 : case LSR_UPDATE_CONTENT_MODEL_animateColor:
4334 2 : n = lsr_read_animate(lsr, parent, 1);
4335 2 : break;
4336 2 : case LSR_UPDATE_CONTENT_MODEL_animateMotion:
4337 2 : n = lsr_read_animateMotion(lsr, parent);
4338 2 : break;
4339 2 : case LSR_UPDATE_CONTENT_MODEL_animateTransform:
4340 2 : n = lsr_read_animateTransform(lsr, parent);
4341 2 : break;
4342 2 : case LSR_UPDATE_CONTENT_MODEL_audio:
4343 2 : n = lsr_read_audio(lsr, parent);
4344 2 : break;
4345 2 : case LSR_UPDATE_CONTENT_MODEL_circle:
4346 2 : n = lsr_read_circle(lsr);
4347 2 : break;
4348 2 : case LSR_UPDATE_CONTENT_MODEL_defs:
4349 2 : n = lsr_read_defs(lsr);
4350 2 : break;
4351 4 : case LSR_UPDATE_CONTENT_MODEL_desc:
4352 4 : n = lsr_read_data(lsr, TAG_SVG_desc);
4353 4 : break;
4354 2 : case LSR_UPDATE_CONTENT_MODEL_ellipse:
4355 2 : n = lsr_read_ellipse(lsr);
4356 2 : break;
4357 2 : case LSR_UPDATE_CONTENT_MODEL_foreignObject:
4358 2 : n = lsr_read_foreignObject(lsr);
4359 2 : break;
4360 2 : case LSR_UPDATE_CONTENT_MODEL_g:
4361 2 : n = lsr_read_g(lsr, 0);
4362 2 : break;
4363 2 : case LSR_UPDATE_CONTENT_MODEL_image:
4364 2 : n = lsr_read_image(lsr);
4365 2 : break;
4366 2 : case LSR_UPDATE_CONTENT_MODEL_line:
4367 2 : n = lsr_read_line(lsr, 0);
4368 2 : break;
4369 2 : case LSR_UPDATE_CONTENT_MODEL_linearGradient:
4370 2 : n = lsr_read_linearGradient(lsr);
4371 2 : break;
4372 2 : case LSR_UPDATE_CONTENT_MODEL_metadata:
4373 2 : n = lsr_read_data(lsr, TAG_SVG_metadata);
4374 2 : break;
4375 2 : case LSR_UPDATE_CONTENT_MODEL_mpath:
4376 2 : n = lsr_read_mpath(lsr);
4377 2 : break;
4378 2 : case LSR_UPDATE_CONTENT_MODEL_path:
4379 2 : n = lsr_read_path(lsr, 0);
4380 2 : break;
4381 2 : case LSR_UPDATE_CONTENT_MODEL_polygon:
4382 2 : n = lsr_read_polygon(lsr, 0, 0);
4383 2 : break;
4384 2 : case LSR_UPDATE_CONTENT_MODEL_polyline:
4385 2 : n = lsr_read_polygon(lsr, 1, 0);
4386 2 : break;
4387 2 : case LSR_UPDATE_CONTENT_MODEL_radialGradient:
4388 2 : n = lsr_read_radialGradient(lsr);
4389 2 : break;
4390 5 : case LSR_UPDATE_CONTENT_MODEL_rect:
4391 5 : n = lsr_read_rect(lsr, 0);
4392 5 : break;
4393 2 : case LSR_UPDATE_CONTENT_MODEL_script:
4394 2 : n = lsr_read_script(lsr);
4395 2 : break;
4396 2 : case LSR_UPDATE_CONTENT_MODEL_set:
4397 2 : n = lsr_read_set(lsr, parent);
4398 2 : break;
4399 2 : case LSR_UPDATE_CONTENT_MODEL_stop:
4400 2 : n = lsr_read_stop(lsr);
4401 2 : break;
4402 2 : case LSR_UPDATE_CONTENT_MODEL_svg:
4403 2 : n = lsr_read_svg(lsr, 0);
4404 2 : break;
4405 2 : case LSR_UPDATE_CONTENT_MODEL_switch:
4406 2 : n = lsr_read_switch(lsr);
4407 2 : break;
4408 5 : case LSR_UPDATE_CONTENT_MODEL_text:
4409 5 : n = lsr_read_text(lsr, 0);
4410 5 : break;
4411 2 : case LSR_UPDATE_CONTENT_MODEL_title:
4412 2 : n = lsr_read_data(lsr, TAG_SVG_title);
4413 2 : break;
4414 2 : case LSR_UPDATE_CONTENT_MODEL_tspan:
4415 2 : n = lsr_read_tspan(lsr);
4416 2 : break;
4417 2 : case LSR_UPDATE_CONTENT_MODEL_use:
4418 2 : n = lsr_read_use(lsr, 0);
4419 2 : break;
4420 2 : case LSR_UPDATE_CONTENT_MODEL_video:
4421 2 : n = lsr_read_video(lsr, parent);
4422 2 : break;
4423 2 : case LSR_UPDATE_CONTENT_MODEL_listener:
4424 2 : n = lsr_read_listener(lsr, parent);
4425 2 : break;
4426 : }
4427 : }
4428 84 : if (n && n->sgprivate->interact && n->sgprivate->interact->dom_evt) {
4429 : GF_DOM_Event evt;
4430 : memset(&evt, 0, sizeof(GF_DOM_Event));
4431 0 : evt.type = GF_EVENT_LOAD;
4432 0 : gf_dom_event_fire(n, &evt);
4433 : }
4434 : return n;
4435 : }
4436 :
4437 441 : static void lsr_read_group_content(GF_LASeRCodec *lsr, GF_Node *elt, Bool skip_object_content)
4438 : {
4439 : u32 i, count;
4440 441 : if (lsr->last_error) return;
4441 :
4442 441 : if (!skip_object_content) lsr_read_object_content(lsr, (SVG_Element*)elt);
4443 :
4444 :
4445 : /*node attributes are all parsed*/
4446 441 : if (elt->sgprivate->tag!=TAG_SVG_script)
4447 436 : gf_node_init(elt);
4448 :
4449 441 : GF_LSR_READ_INT(lsr, count, 1, "opt_group");
4450 441 : if (count) {
4451 99 : GF_ChildNodeItem *last = NULL;
4452 99 : count = lsr_read_vluimsbf5(lsr, "occ0");
4453 540 : for (i=0; i<count; i++) {
4454 : GF_Node *n;
4455 441 : if (lsr->last_error) break;
4456 441 : n = lsr_read_scene_content_model(lsr, (SVG_Element*)elt);
4457 441 : if (n) {
4458 402 : gf_node_register(n, elt);
4459 402 : gf_node_list_add_child_last(& ((SVG_Element*)elt)->children, n, &last);
4460 402 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] ############## end %s ###########\n", gf_node_get_class_name(n)));
4461 : } else {
4462 : /*either error or text content*/
4463 : }
4464 : }
4465 : }
4466 :
4467 441 : if (elt->sgprivate->tag==TAG_SVG_script)
4468 5 : gf_node_init(elt);
4469 : }
4470 :
4471 44 : static void lsr_read_group_content_post_init(GF_LASeRCodec *lsr, SVG_Element *elt, Bool skip_init)
4472 : {
4473 : u32 i, count;
4474 44 : if (lsr->last_error) return;
4475 44 : lsr_read_object_content(lsr, elt);
4476 :
4477 44 : GF_LSR_READ_INT(lsr, count, 1, "opt_group");
4478 44 : if (count) {
4479 3 : GF_ChildNodeItem *last = NULL;
4480 3 : count = lsr_read_vluimsbf5(lsr, "occ0");
4481 6 : for (i=0; i<count; i++) {
4482 : GF_Node *n;
4483 3 : if (lsr->last_error) return;
4484 3 : n = lsr_read_scene_content_model(lsr, elt);
4485 3 : if (n) {
4486 3 : gf_node_register(n, (GF_Node*)elt);
4487 3 : gf_node_list_add_child_last(&elt->children, n, &last);
4488 3 : GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] ############## end %s ###########\n", gf_node_get_class_name(n)));
4489 : } else {
4490 : /*either error or text content*/
4491 : }
4492 : }
4493 : }
4494 44 : if (!skip_init) gf_node_init((GF_Node*)elt);
4495 : }
4496 :
4497 18 : static void *lsr_read_update_value_indexed(GF_LASeRCodec *lsr, GF_Node*node, u32 fieldType, void *rep_val, u32 idx, Bool is_insert, Bool is_com, u32 *single_field_type)
4498 : {
4499 : Fixed *f_val;
4500 : SVG_Number num;
4501 :
4502 18 : switch (fieldType) {
4503 3 : case SVG_Points_datatype/*ITYPE_point*/:
4504 : {
4505 : SVG_Point *pt;
4506 : ListOfXXX *res;
4507 3 : GF_SAFEALLOC(res, ListOfXXX);
4508 3 : if (!res) return NULL;
4509 3 : *res = gf_list_new();
4510 3 : pt = (SVG_Point*)gf_malloc(sizeof(SVG_Point));
4511 3 : if (pt) {
4512 3 : lsr_read_coordinate(lsr, &num, 0, "coordX");
4513 3 : pt->x = num.value;
4514 3 : lsr_read_coordinate(lsr, &num, 0, "coordY");
4515 3 : pt->y = num.value;
4516 3 : gf_list_add(*res, pt);
4517 : }
4518 : return res;
4519 : }
4520 3 : case SMIL_KeySplines_datatype/*ITYPE_float*/:
4521 : {
4522 : ListOfXXX *res;
4523 3 : GF_SAFEALLOC(res, ListOfXXX);
4524 3 : if (!res) return NULL;
4525 3 : *res = gf_list_new();
4526 3 : f_val = (Fixed*)gf_malloc(sizeof(Fixed));
4527 3 : if (f_val) {
4528 3 : *f_val = lsr_read_fixed_16_8(lsr, "floatValue");
4529 3 : gf_list_add(*res, f_val);
4530 : }
4531 : return res;
4532 : }
4533 0 : case SVG_StrokeDashArray_datatype:
4534 : case SVG_ViewBox_datatype:
4535 0 : f_val = (Fixed*)gf_malloc(sizeof(Fixed));
4536 0 : if (!f_val) {
4537 0 : lsr->last_error = GF_OUT_OF_MEM;
4538 : return NULL;
4539 : }
4540 0 : *f_val = lsr_read_fixed_16_8(lsr, "floatValue");
4541 : return f_val;
4542 6 : case SMIL_KeyTimes_datatype/*ITYPE_keyTime*/:
4543 : {
4544 : ListOfXXX *res;
4545 6 : GF_SAFEALLOC(res, ListOfXXX);
4546 6 : if (!res) return NULL;
4547 6 : *res = gf_list_new();
4548 6 : f_val = lsr_read_fraction_12_item(lsr);
4549 6 : if (f_val) gf_list_add(*res, f_val);
4550 : return res;
4551 : }
4552 3 : case SMIL_KeyPoints_datatype/*ITYPE_0to1 - keyPoints*/:
4553 : {
4554 : ListOfXXX *res;
4555 3 : GF_SAFEALLOC(res, ListOfXXX);
4556 3 : if (!res) return NULL;
4557 3 : *res = gf_list_new();
4558 3 : f_val = (Fixed*)gf_malloc(sizeof(Fixed));
4559 3 : if (f_val) {
4560 3 : *f_val = lsr_read_fixed_clamp(lsr, "value");
4561 3 : gf_list_add(*res, f_val);
4562 : }
4563 : return res;
4564 : }
4565 3 : case SMIL_Times_datatype/*ITYPE_smil_time*/:
4566 : {
4567 : ListOfXXX *res;
4568 3 : GF_SAFEALLOC(res, ListOfXXX);
4569 3 : if (!res) return NULL;
4570 3 : *res = gf_list_new();
4571 3 : gf_list_add(*res, lsr_read_smil_time(lsr, node) );
4572 : return res;
4573 : }
4574 0 : default:
4575 0 : lsr_read_extension(lsr, "privateData");
4576 : break;
4577 : }
4578 : return NULL;
4579 : }
4580 :
4581 54 : static void lsr_read_update_value(GF_LASeRCodec *lsr, GF_Node *node, u32 att_tag, u32 fieldType, void *val, u32 node_tag)
4582 : {
4583 : u32 is_default, has_escape, escape_val = 0;
4584 : SVG_Number num, *n;
4585 :
4586 54 : switch (fieldType) {
4587 0 : case SVG_Boolean_datatype:
4588 0 : GF_LSR_READ_INT(lsr, *(SVG_Boolean*)val, 1, "val");
4589 : break;
4590 4 : case SVG_Paint_datatype:
4591 4 : lsr_read_paint(lsr, (SVG_Paint*)val, "val");
4592 4 : break;
4593 : /*
4594 : case SVG_AudioLevel_datatype:
4595 : n = val;
4596 : GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue");
4597 : if (is_default) n->type=SVG_NUMBER_INHERIT;
4598 : else {
4599 : n->type = SVG_NUMBER_VALUE;
4600 : n->value = lsr_read_fixed_clamp(lsr, "val");
4601 : }
4602 : break;
4603 : */
4604 0 : case SVG_Transform_Scale_datatype:
4605 0 : ((SVG_Point *)val)->x = lsr_read_fixed_16_8(lsr, "scale_x");
4606 0 : ((SVG_Point *)val)->y = lsr_read_fixed_16_8(lsr, "scale_y");
4607 0 : break;
4608 3 : case LASeR_Size_datatype:
4609 : case SVG_Transform_Translate_datatype:
4610 3 : lsr_read_coordinate(lsr, &num, 0, "translation_x");
4611 3 : ((SVG_Point *)val)->x = num.value;
4612 3 : lsr_read_coordinate(lsr, &num, 0, "translation_y");
4613 3 : ((SVG_Point *)val)->y = num.value;
4614 3 : break;
4615 0 : case SVG_Transform_Rotate_datatype:
4616 0 : GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue");
4617 0 : if (is_default) ((SVG_Point_Angle*)val)->angle = 0;
4618 : else {
4619 0 : GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag");
4620 0 : if (has_escape) {
4621 0 : GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum");
4622 0 : ((SVG_Point_Angle*)val)->angle = 0;
4623 : }
4624 : else {
4625 0 : ((SVG_Point_Angle*)val)->angle = lsr_read_fixed_16_8(lsr, "rotate");
4626 : }
4627 : }
4628 : break;
4629 3 : case SVG_Transform_datatype:
4630 3 : lsr_read_matrix(lsr, val);
4631 3 : break;
4632 21 : case SVG_Number_datatype:
4633 : case SVG_FontSize_datatype:
4634 : case SVG_Length_datatype:
4635 : n = (SVG_Number*)val;
4636 21 : switch (att_tag) {
4637 : /*fractions*/
4638 6 : case TAG_SVG_ATT_audio_level:
4639 : case TAG_SVG_ATT_fill_opacity:
4640 : case TAG_SVG_ATT_offset:
4641 : case TAG_SVG_ATT_opacity:
4642 : case TAG_SVG_ATT_solid_opacity:
4643 : case TAG_SVG_ATT_stop_opacity:
4644 : case TAG_SVG_ATT_stroke_opacity:
4645 : case TAG_SVG_ATT_viewport_fill_opacity:
4646 6 : GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue");
4647 6 : if (is_default) n->type=SVG_NUMBER_INHERIT;
4648 : else {
4649 3 : n->type = SVG_NUMBER_VALUE;
4650 3 : n->value = lsr_read_fixed_clamp(lsr, "val");
4651 : }
4652 : break;
4653 9 : case TAG_SVG_ATT_width:
4654 : case TAG_SVG_ATT_height:
4655 9 : if (node_tag==TAG_SVG_svg) {
4656 3 : lsr_read_value_with_units(lsr, n, "val");
4657 : } else {
4658 6 : lsr_read_coordinate(lsr, n, 0, "val");
4659 : }
4660 : break;
4661 6 : default:
4662 6 : GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue");
4663 6 : if (is_default) n->type=SVG_NUMBER_INHERIT;
4664 : else {
4665 3 : GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag");
4666 3 : if (has_escape) {
4667 0 : GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum");
4668 0 : n->type = SVG_NUMBER_AUTO;//only lineIncrement
4669 : } else {
4670 3 : n->type = SVG_NUMBER_VALUE;
4671 3 : n->value = lsr_read_fixed_16_8(lsr, "val");
4672 : }
4673 : }
4674 : break;
4675 : }
4676 : break;
4677 3 : case SVG_Coordinate_datatype:
4678 : n = (SVG_Number*)val;
4679 3 : n->type = SVG_NUMBER_VALUE;
4680 3 : lsr_read_coordinate(lsr, n, 0, "val");
4681 3 : break;
4682 :
4683 6 : case SVG_Rotate_datatype:
4684 : n = (SVG_Number*)val;
4685 6 : GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue");
4686 6 : if (is_default) n->type=SVG_NUMBER_INHERIT;
4687 : else {
4688 6 : GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag");
4689 6 : if (has_escape) {
4690 3 : GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum");
4691 3 : n->type = escape_val ? SVG_NUMBER_AUTO_REVERSE : SVG_NUMBER_AUTO;
4692 : } else {
4693 3 : n->type = SVG_NUMBER_VALUE;
4694 3 : n->value = lsr_read_fixed_16_8(lsr, "rotate");
4695 : }
4696 : }
4697 : break;
4698 0 : case SVG_Coordinates_datatype:
4699 0 : lsr_read_float_list(lsr, NULL, 0, val, "val");
4700 0 : break;
4701 0 : case SVG_ViewBox_datatype:
4702 : {
4703 : u32 count;
4704 : SVG_ViewBox *vb = (SVG_ViewBox *)val;
4705 0 : GF_LSR_READ_INT(lsr, count, 1, "isDefault");
4706 0 : if (count) {
4707 0 : vb->is_set = 0;
4708 : } else {
4709 0 : vb->is_set = 1;
4710 0 : GF_LSR_READ_INT(lsr, count, 1, "escapeFlag");
4711 0 : count = lsr_read_vluimsbf5(lsr, "count");
4712 0 : if (count) {
4713 0 : vb->x = lsr_read_fixed_16_8(lsr, "val");
4714 0 : count--;
4715 : }
4716 0 : if (count) {
4717 0 : vb->y = lsr_read_fixed_16_8(lsr, "val");
4718 0 : count--;
4719 : }
4720 0 : if (count) {
4721 0 : vb->width = lsr_read_fixed_16_8(lsr, "val");
4722 0 : count--;
4723 : }
4724 0 : if (count) {
4725 0 : vb->height = lsr_read_fixed_16_8(lsr, "val");
4726 : }
4727 : }
4728 : }
4729 : break;
4730 9 : case XMLRI_datatype:
4731 : case SVG_Focus_datatype:
4732 9 : if ((att_tag==TAG_XLINK_ATT_href) || (att_tag==TAG_SVG_ATT_syncReference)) {
4733 0 : lsr_read_any_uri(lsr, (XMLRI*)val, "val");
4734 : } else {
4735 : Bool is_escape;
4736 : u32 ID;
4737 : escape_val = ID = 0;
4738 : is_escape = 0;
4739 9 : GF_LSR_READ_INT(lsr, is_default, 1, "isDefault");
4740 9 : if (!is_default) {
4741 6 : GF_LSR_READ_INT(lsr, is_escape, 1, "isEscape");
4742 6 : if (is_escape) {
4743 3 : GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnumVal");
4744 : } else {
4745 3 : ID = lsr_read_vluimsbf5(lsr, "ID");
4746 : }
4747 : }
4748 9 : if (att_tag==SVG_Focus_datatype) {
4749 0 : if (is_default) ((SVG_Focus*)val)->type = SVG_FOCUS_AUTO;
4750 0 : else if (is_escape) ((SVG_Focus*)val)->type = escape_val;
4751 : else {
4752 0 : ((SVG_Focus*)val)->type = SVG_FOCUS_IRI;
4753 0 : ((SVG_Focus*)val)->target.type = XMLRI_ELEMENTID;
4754 0 : ((SVG_Focus*)val)->target.node_id = ID;
4755 : }
4756 : } else {
4757 9 : if (is_default) ((XMLRI*)val)->type = XMLRI_STRING;
4758 : else {
4759 6 : ((XMLRI *)val)->type = XMLRI_ELEMENTID;
4760 6 : ((XMLRI *)val)->node_id = ID;
4761 : }
4762 : }
4763 : }
4764 : break;
4765 :
4766 0 : case DOM_String_datatype:
4767 : case SVG_ContentType_datatype:
4768 : case SVG_LanguageID_datatype:
4769 0 : lsr_read_byte_align_string(lsr, (char**)val, "val");
4770 0 : break;
4771 0 : case SVG_Motion_datatype:
4772 0 : lsr_read_coordinate(lsr, &num, 0, "pointValueX");
4773 0 : ((GF_Matrix2D*)val)->m[2] = num.value;
4774 0 : lsr_read_coordinate(lsr, &num, 0, "pointValueY");
4775 0 : ((GF_Matrix2D*)val)->m[5] = num.value;
4776 0 : break;
4777 0 : case SVG_Points_datatype:
4778 0 : lsr_read_point_sequence(lsr, *(GF_List **)val, "val");
4779 0 : break;
4780 0 : case SVG_PathData_datatype:
4781 0 : lsr_read_path_type(lsr, NULL, 0, (SVG_PathData*)val, "val");
4782 0 : break;
4783 2 : case SVG_FontFamily_datatype:
4784 : {
4785 : u32 idx;
4786 : SVG_FontFamily *ff = (SVG_FontFamily *)val;
4787 2 : GF_LSR_READ_INT(lsr, idx, 1, "isDefault");
4788 2 : ff->type = SVG_FONTFAMILY_INHERIT;
4789 2 : if (!idx) {
4790 : char *ft;
4791 2 : GF_LSR_READ_INT(lsr, idx, 1, "escapeFlag");
4792 2 : idx = lsr_read_vluimsbf5(lsr, "index");
4793 2 : if (ff->value) gf_free(ff->value);
4794 2 : ff->value = NULL;
4795 2 : ft = (char*)gf_list_get(lsr->font_table, idx);
4796 2 : if (ft) {
4797 2 : ff->value = gf_strdup(ft);
4798 2 : ff->type = SVG_FONTFAMILY_VALUE;
4799 : }
4800 : }
4801 : }
4802 : break;
4803 0 : case LASeR_Choice_datatype:
4804 0 : GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue");
4805 0 : if (is_default) ((LASeR_Choice *)val)->type = LASeR_CHOICE_ALL;
4806 : else {
4807 0 : GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag");
4808 0 : if (has_escape) {
4809 0 : GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum");
4810 0 : ((LASeR_Choice *)val)->type = escape_val ? LASeR_CHOICE_NONE : LASeR_CHOICE_ALL;
4811 : } else {
4812 0 : ((LASeR_Choice *)val)->type = LASeR_CHOICE_N;
4813 0 : ((LASeR_Choice *)val)->choice_index = lsr_read_vluimsbf5(lsr, "value");
4814 : }
4815 : }
4816 : break;
4817 3 : default:
4818 3 : if ((fieldType>=SVG_FillRule_datatype) && (fieldType<=SVG_LAST_U8_PROPERTY)) {
4819 : /*TODO fixme, check inherit values*/
4820 3 : GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue");
4821 3 : if (is_default) *(u8 *)val = 0;
4822 3 : else *(u8 *)val = lsr_read_vluimsbf5(lsr, "val");
4823 : } else {
4824 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] Warning: update value not supported: fieldType %d - attribute tag %d\n", fieldType, att_tag));
4825 : }
4826 : }
4827 54 : if (node) {
4828 : //gf_node_dirty_set(node, 0, 0);
4829 16 : gf_node_changed(node, NULL);
4830 : }
4831 54 : }
4832 :
4833 98 : static u32 lsr_get_attribute_name(GF_LASeRCodec *lsr)
4834 : {
4835 : u32 val = 1;
4836 98 : GF_LSR_READ_INT(lsr, val, 1, "has_attributeName");
4837 98 : if (!val) return -1;
4838 :
4839 84 : GF_LSR_READ_INT(lsr, val, 1, "choice");
4840 84 : if (val) {
4841 0 : lsr_read_vluimsbf5(lsr, "item[i]");
4842 0 : lsr_read_vluimsbf5(lsr, "item[i]");
4843 0 : return -1;
4844 : } else {
4845 84 : GF_LSR_READ_INT(lsr, val, 8, "attributeName");
4846 : return val;
4847 : }
4848 : }
4849 :
4850 90 : static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, u32 com_type)
4851 : {
4852 : GF_FieldInfo info;
4853 : GF_Node *n, *operandNode;
4854 : GF_Command *com;
4855 : GF_CommandField *field;
4856 : s32 idx, att_type, op_att_type;
4857 : u32 type, idref, op_idref = 0;
4858 :
4859 : operandNode = NULL;
4860 : op_att_type = -1;
4861 :
4862 90 : att_type = lsr_get_attribute_name(lsr);
4863 :
4864 : idx = -1;
4865 90 : if (com_type) {
4866 90 : GF_LSR_READ_INT(lsr, type, 1, "has_index");
4867 90 : if (type) idx = lsr_read_vluimsbf5(lsr, "index");
4868 : }
4869 90 : if (com_type!=3) {
4870 84 : GF_LSR_READ_INT(lsr, type, 1, "has_operandAttribute");
4871 84 : if (type) GF_LSR_READ_INT(lsr, op_att_type, 8, "attributeName");
4872 84 : GF_LSR_READ_INT(lsr, type, 1, "has_operandElementId");
4873 84 : if (type) {
4874 3 : op_idref = lsr_read_codec_IDREF_command(lsr, "operandElementId");
4875 3 : operandNode = gf_sg_find_node(lsr->sg, op_idref);
4876 3 : if (!operandNode)
4877 : return GF_NON_COMPLIANT_BITSTREAM;
4878 : }
4879 : }
4880 90 : idref = lsr_read_codec_IDREF_command(lsr, "ref");
4881 :
4882 90 : n = gf_sg_find_node(lsr->sg, idref);
4883 90 : if (!n) {
4884 0 : if (!com_list) {
4885 : return GF_NON_COMPLIANT_BITSTREAM;
4886 : }
4887 : }
4888 :
4889 90 : GF_LSR_READ_INT(lsr, type, 1, "has_value");
4890 90 : if (type) {
4891 : /*node or node-list replacement*/
4892 78 : if (att_type==-2) {
4893 0 : lsr_read_byte_align_string(lsr, NULL, "anyXML");
4894 : }
4895 78 : else if (att_type<0) {
4896 : GF_Node *new_node;
4897 0 : if (!com_type)
4898 : return GF_NON_COMPLIANT_BITSTREAM;
4899 0 : GF_LSR_READ_INT(lsr, type, 1, "isInherit");
4900 0 : if (type)
4901 : return GF_NON_COMPLIANT_BITSTREAM;
4902 0 : if (idx==-1) {
4903 0 : GF_LSR_READ_INT(lsr, type, 1, "escapeFlag");
4904 0 : if (type)
4905 : return GF_NON_COMPLIANT_BITSTREAM;
4906 : }
4907 :
4908 0 : new_node = lsr_read_update_content_model(lsr, (idx==-1) ? NULL : (SVG_Element *)n);
4909 0 : if (com_list) {
4910 0 : com = gf_sg_command_new(lsr->sg, (com_type==3) ? GF_SG_LSR_INSERT : GF_SG_LSR_REPLACE);
4911 0 : gf_list_add(com_list, com);
4912 0 : if (n) {
4913 0 : com->node = n;
4914 0 : gf_node_register(com->node, NULL);
4915 : } else {
4916 0 : com->RouteID = idref;
4917 0 : gf_list_add(lsr->unresolved_commands, com);
4918 : }
4919 0 : field = gf_sg_command_field_new(com);
4920 0 : field->pos = idx;
4921 0 : field->new_node = new_node;
4922 0 : if (new_node) gf_node_register(new_node, NULL);
4923 0 : } else if (com_type==3) {
4924 0 : gf_node_list_insert_child(& ((SVG_Element *)n)->children, new_node, idx);
4925 0 : if (new_node) gf_node_register(new_node, n);
4926 : } else {
4927 : /*child replacement*/
4928 0 : if (idx!=-1) {
4929 0 : GF_Node *old = gf_node_list_get_child( ((SVG_Element *)n)->children, idx);
4930 0 : if (old)
4931 0 : gf_node_replace(old, new_node, 0);
4932 : else {
4933 0 : gf_node_list_add_child( & ((SVG_Element *)n)->children, new_node);
4934 0 : if (new_node) gf_node_register(new_node, n);
4935 : }
4936 : } else {
4937 : /*node replacement*/
4938 0 : gf_node_replace(n, new_node, 0);
4939 : }
4940 : }
4941 : }
4942 : /*value replace/add*/
4943 78 : else if (com_list) {
4944 : u32 field_type;
4945 : Bool text_content = 0;
4946 54 : com = gf_sg_command_new(lsr->sg, (com_type==0) ? GF_SG_LSR_ADD : (com_type==3) ? GF_SG_LSR_INSERT : GF_SG_LSR_REPLACE);
4947 54 : field = gf_sg_command_field_new(com);
4948 54 : field->pos = idx;
4949 : field_type = 0;
4950 54 : switch (att_type) {
4951 : /*text*/
4952 : case LSR_UPDATE_TYPE_TEXT_CONTENT:
4953 : text_content = 1;
4954 : break;
4955 : /*matrix.translation, scale or rotate*/
4956 0 : case LSR_UPDATE_TYPE_SCALE:
4957 0 : field->fieldType = field_type = SVG_Transform_Scale_datatype;
4958 0 : field->fieldIndex = gf_lsr_anim_type_to_attribute(att_type);
4959 0 : break;
4960 0 : case LSR_UPDATE_TYPE_ROTATE:
4961 0 : field->fieldType = field_type = SVG_Transform_Rotate_datatype;
4962 0 : field->fieldIndex = TAG_SVG_ATT_transform;
4963 0 : break;
4964 0 : case LSR_UPDATE_TYPE_TRANSLATION:
4965 0 : field->fieldType = field_type = SVG_Transform_Translate_datatype;
4966 0 : field->fieldIndex = gf_lsr_anim_type_to_attribute(att_type);
4967 0 : break;
4968 0 : case LSR_UPDATE_TYPE_SVG_HEIGHT:
4969 0 : field->fieldIndex = TAG_SVG_ATT_height;
4970 0 : field_type = field->fieldType = SVG_Length_datatype;
4971 0 : break;
4972 0 : case LSR_UPDATE_TYPE_SVG_WIDTH:
4973 0 : field->fieldIndex = TAG_SVG_ATT_width;
4974 0 : field_type = field->fieldType = SVG_Length_datatype;
4975 0 : break;
4976 50 : default:
4977 50 : field->fieldIndex = gf_lsr_anim_type_to_attribute(att_type);
4978 50 : if (field->fieldIndex == (u32)-1) {
4979 0 : lsr->last_error = GF_NON_COMPLIANT_BITSTREAM;
4980 0 : gf_sg_command_del(com);
4981 0 : return lsr->last_error;
4982 : }
4983 50 : field_type = field->fieldType = gf_xml_get_attribute_type(field->fieldIndex);
4984 50 : break;
4985 : }
4986 54 : gf_list_add(com_list, com);
4987 54 : if (n) {
4988 54 : com->node = n;
4989 54 : gf_node_register(com->node, NULL);
4990 : } else {
4991 0 : com->RouteID = idref;
4992 0 : gf_list_add(lsr->unresolved_commands, com);
4993 : }
4994 54 : if (idx==-1) {
4995 42 : if (text_content) {
4996 4 : GF_DOMText *text = gf_dom_new_text_node(lsr->sg);
4997 4 : gf_node_register((GF_Node *)text, NULL);
4998 4 : lsr_read_byte_align_string(lsr, &text->textContent, "val");
4999 4 : field->new_node = (GF_Node*)text;
5000 : } else {
5001 38 : field->field_ptr = gf_svg_create_attribute_value(field_type);
5002 38 : lsr_read_update_value(lsr, NULL, field->fieldIndex, field->fieldType, field->field_ptr, n ? n->sgprivate->tag : 0);
5003 : }
5004 : } else {
5005 12 : field->field_ptr = lsr_read_update_value_indexed(lsr, (GF_Node*)n, field_type, NULL, idx, com_type==LSR_UPDATE_INSERT, 1, &field->fieldType);
5006 : }
5007 : } else {
5008 : GF_Point2D matrix_tmp;
5009 : SVG_Point_Angle matrix_tmp_rot;
5010 : u32 fieldIndex = 0;
5011 : u32 field_type = 0;
5012 : Bool text_content = 0;
5013 : Bool is_lsr_transform = 0;
5014 24 : switch (att_type) {
5015 : /*text*/
5016 : case LSR_UPDATE_TYPE_TEXT_CONTENT:
5017 : text_content = 1;
5018 : break;
5019 : /*matrix.translation, scale or rotate*/
5020 0 : case LSR_UPDATE_TYPE_SCALE:
5021 0 : info.far_ptr = (void *)&matrix_tmp;
5022 : field_type = SVG_Transform_Scale_datatype;
5023 : is_lsr_transform = 1;
5024 0 : break;
5025 0 : case LSR_UPDATE_TYPE_ROTATE:
5026 0 : info.far_ptr = (void *)&matrix_tmp_rot;
5027 : field_type = SVG_Transform_Rotate_datatype;
5028 : is_lsr_transform = 1;
5029 0 : break;
5030 0 : case LSR_UPDATE_TYPE_TRANSLATION:
5031 0 : info.far_ptr = (void *)&matrix_tmp;
5032 : field_type = SVG_Transform_Translate_datatype;
5033 : is_lsr_transform = 1;
5034 0 : break;
5035 22 : default:
5036 22 : fieldIndex = gf_lsr_anim_type_to_attribute(att_type);
5037 22 : gf_node_get_attribute_by_tag(n, fieldIndex, 1, 0, &info);
5038 22 : field_type = info.fieldType;
5039 22 : break;
5040 : }
5041 24 : info.fieldType = field_type;
5042 24 : if (is_lsr_transform) {
5043 : SVG_Transform *dest;
5044 0 : if (idx==-1) {
5045 0 : lsr_read_update_value(lsr, NULL, fieldIndex, field_type, info.far_ptr, 0);
5046 : } else {
5047 : assert(0);
5048 : }
5049 :
5050 :
5051 : // fieldIndex = gf_node_get_attribute_by_tag((GF_Node*)n, TAG_SVG_ATT_transform, 1, 1, &info);
5052 0 : dest = (SVG_Transform *)info.far_ptr;
5053 0 : if (com_type) {
5054 : GF_Point2D scale, translate;
5055 : SVG_Point_Angle rotate;
5056 0 : if (gf_mx2d_decompose(&dest->mat, &scale, &rotate.angle, &translate)) {
5057 0 : gf_mx2d_init(dest->mat);
5058 0 : if (att_type==LSR_UPDATE_TYPE_SCALE) scale = matrix_tmp;
5059 0 : else if (att_type==LSR_UPDATE_TYPE_TRANSLATION) translate = matrix_tmp;
5060 0 : else if (att_type==LSR_UPDATE_TYPE_ROTATE) rotate = matrix_tmp_rot;
5061 :
5062 0 : gf_mx2d_add_scale(&dest->mat, scale.x, scale.y);
5063 0 : gf_mx2d_add_rotation(&dest->mat, 0, 0, rotate.angle);
5064 0 : gf_mx2d_add_translation(&dest->mat, translate.x, translate.y);
5065 : }
5066 : }
5067 0 : else if (att_type==LSR_UPDATE_TYPE_SCALE) gf_mx2d_add_scale(&dest->mat, matrix_tmp.x, matrix_tmp.y);
5068 0 : else if (att_type==LSR_UPDATE_TYPE_TRANSLATION) gf_mx2d_add_translation(&dest->mat, matrix_tmp.x, matrix_tmp.y);
5069 0 : else if (att_type==LSR_UPDATE_TYPE_ROTATE) gf_mx2d_add_rotation(&dest->mat, 0, 0, matrix_tmp_rot.angle);
5070 :
5071 0 : gf_node_changed((GF_Node*)n, &info);
5072 : }
5073 24 : else if (com_type) {
5074 24 : if (text_content) {
5075 : GF_DOMText *t = NULL;
5076 2 : if (idx>=0) {
5077 0 : if (com_type==LSR_UPDATE_INSERT) {
5078 0 : t = gf_dom_new_text_node(n->sgprivate->scenegraph);
5079 0 : gf_node_register((GF_Node *)t, n);
5080 0 : gf_node_list_insert_child(&((GF_ParentNode *)n)->children, (GF_Node*)t, idx);
5081 : } else {
5082 0 : t = (GF_DOMText *) gf_node_list_get_child(((SVG_Element*)n)->children, idx);
5083 0 : if (t->sgprivate->tag!=TAG_DOMText) t = NULL;
5084 : }
5085 : } else {
5086 : /*this is a replace, reset ALL node content*/
5087 2 : gf_sg_parent_reset(n);
5088 2 : t = gf_dom_add_text_node(n, NULL);
5089 : }
5090 2 : lsr_read_byte_align_string(lsr, t ? &t->textContent : NULL, "textContent");
5091 2 : gf_node_changed(n, NULL);
5092 22 : } else if (idx==-1) {
5093 16 : lsr_read_update_value(lsr, (GF_Node*)n, fieldIndex, field_type, info.far_ptr, n->sgprivate->tag);
5094 : } else {
5095 : Fixed *v1, *v2;
5096 : //SMIL_Time *t;
5097 : void *prev, *new_item;
5098 6 : void *tmp = lsr_read_update_value_indexed(lsr, (GF_Node*)n, field_type, info.far_ptr, idx, com_type==LSR_UPDATE_INSERT, 0, NULL);
5099 6 : switch (field_type) {
5100 : /*generic GF_List containers, no type translation needed*/
5101 5 : case SMIL_KeyTimes_datatype/*ITYPE_keyTime*/:
5102 : case SMIL_KeySplines_datatype/*ITYPE_float*/:
5103 : case SVG_Points_datatype/*ITYPE_point*/:
5104 : case SMIL_Times_datatype/*ITYPE_smil_time*/:
5105 5 : new_item = gf_list_pop_front(*(GF_List **)tmp);
5106 5 : if (com_type==LSR_UPDATE_INSERT) {
5107 0 : gf_list_insert(*(SVG_Coordinates*)info.far_ptr, new_item, idx);
5108 : } else {
5109 5 : prev = gf_list_get(*(SVG_Coordinates*)info.far_ptr, idx);
5110 5 : gf_free(prev);
5111 5 : gf_list_rem(*(SVG_Coordinates*)info.far_ptr, idx);
5112 5 : gf_list_insert(*(SVG_Coordinates*)info.far_ptr, new_item, idx);
5113 : }
5114 5 : gf_node_changed((GF_Node*)n, NULL);
5115 5 : gf_list_del(*(GF_List **)tmp);
5116 5 : gf_free(tmp);
5117 5 : break;
5118 : /*list of floats - to check when implementing it...*/
5119 1 : case SMIL_KeyPoints_datatype/*ITYPE_0to1 - keyPoints*/:
5120 1 : v1 = (Fixed *) gf_list_pop_front(*(GF_List **)tmp);
5121 1 : v2 = (Fixed *) gf_list_pop_front(*(GF_List **)tmp);
5122 1 : gf_list_del(*(GF_List **)tmp);
5123 1 : gf_free(tmp);
5124 :
5125 1 : if (com_type==LSR_UPDATE_INSERT) {
5126 0 : gf_list_insert(*(SVG_Coordinates*)info.far_ptr, v1, idx);
5127 0 : gf_list_insert(*(SVG_Coordinates*)info.far_ptr, v2, idx+1);
5128 : } else {
5129 1 : prev = gf_list_get(*(SVG_Coordinates*)info.far_ptr, idx);
5130 1 : gf_free(prev);
5131 1 : gf_list_rem(*(SVG_Coordinates*)info.far_ptr, idx);
5132 1 : prev = gf_list_get(*(SVG_Coordinates*)info.far_ptr, idx);
5133 1 : gf_free(prev);
5134 1 : gf_list_rem(*(SVG_Coordinates*)info.far_ptr, idx);
5135 1 : gf_list_insert(*(SVG_Coordinates*)info.far_ptr, v1, idx);
5136 1 : gf_list_insert(*(SVG_Coordinates*)info.far_ptr, v2, idx);
5137 : }
5138 1 : gf_node_changed((GF_Node*)n, NULL);
5139 1 : break;
5140 0 : case SVG_ViewBox_datatype:
5141 : v1 = (Fixed*)tmp;
5142 0 : switch (idx) {
5143 0 : case 0:
5144 0 : ((SVG_ViewBox*)info.far_ptr)->x = *v1;
5145 0 : break;
5146 0 : case 1:
5147 0 : ((SVG_ViewBox*)info.far_ptr)->y = *v1;
5148 0 : break;
5149 0 : case 2:
5150 0 : ((SVG_ViewBox*)info.far_ptr)->width = *v1;
5151 0 : break;
5152 0 : case 3:
5153 0 : ((SVG_ViewBox*)info.far_ptr)->height = *v1;
5154 0 : break;
5155 : }
5156 0 : gf_free(tmp);
5157 0 : gf_node_changed((GF_Node*)n, NULL);
5158 0 : break;
5159 0 : case SVG_StrokeDashArray_datatype:
5160 : v1 = (Fixed*)tmp;
5161 0 : if (com_type==LSR_UPDATE_INSERT) {
5162 0 : SVG_StrokeDashArray*da = (SVG_StrokeDashArray*)info.far_ptr;
5163 : /*use MFFloat for insert*/
5164 0 : if (gf_sg_vrml_mf_insert(&da->array, GF_SG_VRML_MFFLOAT, (void*) &v2, idx)==GF_OK)
5165 0 : *v2 = *v1;
5166 : } else {
5167 0 : SVG_StrokeDashArray*da = (SVG_StrokeDashArray*)info.far_ptr;
5168 0 : if (idx<(s32)da->array.count) da->array.vals[idx] = *v1;
5169 : }
5170 0 : gf_free(tmp);
5171 0 : gf_node_changed((GF_Node*)n, NULL);
5172 0 : break;
5173 0 : default:
5174 0 : gf_free(tmp);
5175 0 : break;
5176 : }
5177 : }
5178 : } else {
5179 : GF_FieldInfo tmp;
5180 0 : tmp = info;
5181 0 : if (idx==-1) {
5182 0 : tmp.far_ptr = gf_svg_create_attribute_value(info.fieldType);
5183 0 : lsr_read_update_value(lsr, n, fieldIndex, field_type, tmp.far_ptr, n->sgprivate->tag);
5184 : } else {
5185 0 : tmp.far_ptr = lsr_read_update_value_indexed(lsr, n, field_type, NULL, idx, 0, 1, NULL);
5186 : }
5187 0 : gf_svg_attributes_add(&info, &tmp, &info, 0);
5188 0 : gf_svg_delete_attribute_value(info.fieldType, tmp.far_ptr, gf_node_get_graph(n));
5189 : }
5190 : }
5191 : }
5192 : /*copy from node*/
5193 12 : else if (operandNode && (op_att_type>=0)) {
5194 3 : u32 opFieldIndex = gf_lsr_anim_type_to_attribute(op_att_type);
5195 3 : if (com_list) {
5196 2 : com = gf_sg_command_new(lsr->sg, com_type ? GF_SG_LSR_REPLACE : GF_SG_LSR_ADD);
5197 2 : gf_list_add(com_list, com);
5198 2 : com->node = n;
5199 2 : gf_node_register(com->node, NULL);
5200 2 : com->fromNodeID = op_idref;
5201 2 : com->fromFieldIndex = opFieldIndex;
5202 2 : field = gf_sg_command_field_new(com);
5203 2 : field->pos = idx;
5204 2 : field->fieldIndex = gf_lsr_anim_type_to_attribute(att_type);
5205 : } else {
5206 : u32 fieldIndex;
5207 : GF_FieldInfo op_info;
5208 1 : fieldIndex = gf_lsr_anim_type_to_attribute(att_type);
5209 1 : gf_node_get_field(n, fieldIndex, &info);
5210 1 : gf_node_get_field(operandNode, opFieldIndex, &op_info);
5211 1 : if (com_type) {
5212 1 : gf_svg_attributes_copy(&info, &op_info, 0);
5213 : } else {
5214 0 : gf_svg_attributes_add(&info, &op_info, &info, 0);
5215 : }
5216 : }
5217 : }
5218 :
5219 90 : lsr_read_any_attribute(lsr, NULL, 1);
5220 :
5221 : /*if not add*/
5222 90 : if (!com_type) return GF_OK;
5223 :
5224 : /*list replacement*/
5225 90 : GF_LSR_READ_INT(lsr, type, 1, "opt_group");
5226 90 : if (type) {
5227 :
5228 9 : if (com_list) {
5229 : u32 count;
5230 6 : GF_ChildNodeItem *last = NULL;
5231 :
5232 6 : if (com_type==LSR_UPDATE_INSERT) count = 1;
5233 2 : else count = lsr_read_vluimsbf5(lsr, "count");
5234 :
5235 6 : com = gf_sg_command_new(lsr->sg, (com_type==LSR_UPDATE_REPLACE) ? GF_SG_LSR_REPLACE : GF_SG_LSR_INSERT);
5236 6 : gf_list_add(com_list, com);
5237 6 : com->node = n;
5238 6 : gf_node_register(com->node, NULL);
5239 6 : field = gf_sg_command_field_new(com);
5240 6 : field->pos = idx;
5241 :
5242 6 : if (!count && (att_type==LSR_UPDATE_TYPE_TEXT_CONTENT)) {
5243 0 : field->fieldIndex = -1;
5244 6 : } else if (count==1) {
5245 4 : field->new_node = lsr_read_update_content_model(lsr, (SVG_Element *) n);
5246 4 : gf_node_register(field->new_node, NULL);
5247 4 : if (att_type>=0) field->fieldIndex = gf_lsr_anim_type_to_attribute(att_type);
5248 : } else {
5249 2 : field->field_ptr = &field->node_list;
5250 82 : while (count) {
5251 78 : GF_Node *new_node = lsr_read_update_content_model(lsr, (SVG_Element *) n);
5252 78 : gf_node_register(new_node, NULL);
5253 78 : gf_node_list_add_child_last(& field->node_list, new_node, &last);
5254 78 : count--;
5255 : }
5256 : }
5257 : } else {
5258 : SVG_Element*elt = (SVG_Element*)n;
5259 3 : GF_ChildNodeItem *last = NULL;
5260 : u32 count;
5261 3 : if (com_type==LSR_UPDATE_INSERT) count = 1;
5262 1 : else count = lsr_read_vluimsbf5(lsr, "count");
5263 :
5264 3 : if (com_type==LSR_UPDATE_REPLACE) {
5265 1 : if (idx>=0) {
5266 0 : GF_Node *new_node = gf_node_list_del_child_idx(&elt->children, idx);
5267 0 : if (new_node) gf_node_unregister(new_node, n);
5268 : } else {
5269 1 : gf_node_unregister_children(n, elt->children);
5270 1 : elt->children = NULL;
5271 : }
5272 : }
5273 3 : if ((com_type==LSR_UPDATE_INSERT) || (gf_lsr_anim_type_to_attribute(att_type) == TAG_LSR_ATT_children)) {
5274 4 : while (count) {
5275 2 : GF_Node *new_node = lsr_read_update_content_model(lsr, elt);
5276 2 : if (new_node) {
5277 2 : if (idx>=0) {
5278 2 : gf_node_list_insert_child(&elt->children, new_node, idx);
5279 : } else {
5280 0 : gf_node_list_add_child_last(&elt->children, new_node, &last);
5281 : }
5282 2 : gf_node_register(new_node, n);
5283 : }
5284 2 : count--;
5285 : }
5286 2 : gf_node_changed(n, NULL);
5287 : }
5288 : /*node replacement*/
5289 1 : else if ((att_type==-1) && (count==1)) {
5290 0 : GF_Node *new_node = lsr_read_update_content_model(lsr, elt);
5291 0 : gf_node_replace((GF_Node*)elt, new_node, 0);
5292 : }
5293 : }
5294 : }
5295 : return GF_OK;
5296 : }
5297 :
5298 8 : static GF_Err lsr_read_delete(GF_LASeRCodec *lsr, GF_List *com_list)
5299 : {
5300 : GF_FieldInfo info;
5301 : s32 idx, att_type;
5302 : u32 type, idref;
5303 :
5304 8 : att_type = lsr_get_attribute_name(lsr);
5305 :
5306 : idx = -2;
5307 8 : GF_LSR_READ_INT(lsr, type, 1, "has_index");
5308 8 : if (type) idx = (s32) lsr_read_vluimsbf5(lsr, "index");
5309 8 : idref = lsr_read_codec_IDREF_command(lsr, "ref");
5310 :
5311 8 : lsr_read_any_attribute(lsr, NULL, 1);
5312 8 : if (com_list) {
5313 : GF_Command *com;
5314 6 : com = gf_sg_command_new(lsr->sg, GF_SG_LSR_DELETE);
5315 6 : gf_list_add(com_list, com);
5316 6 : com->node = gf_sg_find_node(lsr->sg, idref);
5317 6 : if (!com->node) {
5318 2 : com->RouteID = idref;
5319 2 : gf_list_add(lsr->unresolved_commands, com);
5320 : } else {
5321 4 : gf_node_register(com->node, NULL);
5322 : }
5323 :
5324 6 : if ((idx>=0) || (att_type>=0)) {
5325 2 : GF_CommandField *field = gf_sg_command_field_new(com);
5326 2 : field->pos = idx;
5327 2 : if (att_type>=0) {
5328 2 : field->fieldIndex = gf_lsr_anim_type_to_attribute(att_type);
5329 2 : gf_node_get_field(com->node, field->fieldIndex, &info);
5330 2 : field->fieldType = info.fieldType;
5331 : }
5332 : }
5333 : } else {
5334 2 : SVG_Element *elt = (SVG_Element *) gf_sg_find_node(lsr->sg, idref);
5335 2 : if (!elt)
5336 : return GF_NON_COMPLIANT_BITSTREAM;
5337 :
5338 2 : if (att_type>=0) {
5339 1 : s32 fieldIndex = gf_lsr_anim_type_to_attribute(att_type);
5340 1 : gf_node_get_field((GF_Node*)elt, fieldIndex, &info);
5341 : /*TODO implement*/
5342 : }
5343 : /*node deletion*/
5344 1 : else if (idx>=0) {
5345 0 : GF_Node *c = (GF_Node *)gf_node_list_get_child(elt->children, idx);
5346 0 : if (c) {
5347 0 : if (!gf_node_list_del_child( & elt->children, c))
5348 : return GF_IO_ERR;
5349 0 : gf_node_unregister(c, (GF_Node*)elt);
5350 : }
5351 : } else {
5352 1 : gf_node_replace((GF_Node*)elt, NULL, 0);
5353 : }
5354 : }
5355 : return GF_OK;
5356 : }
5357 :
5358 162 : static GF_Err lsr_read_send_event(GF_LASeRCodec *lsr, GF_List *com_list)
5359 : {
5360 : u32 flag, idref;
5361 : s32 detail;
5362 : SVG_Number x, y;
5363 : XMLEV_Event event;
5364 162 : lsr_read_event_type(lsr, &event);
5365 :
5366 : detail = 0;
5367 162 : GF_LSR_READ_INT(lsr, flag, 1, "has_intvalue");
5368 162 : if (flag) {
5369 78 : GF_LSR_READ_INT(lsr, flag, 1, "sign");
5370 78 : detail = lsr_read_vluimsbf5(lsr, "value");
5371 78 : if (flag) detail = -detail;
5372 :
5373 78 : switch (event.type) {
5374 69 : case GF_EVENT_KEYDOWN:
5375 : case GF_EVENT_LONGKEYPRESS:
5376 : case GF_EVENT_REPEAT_KEY:
5377 : case GF_EVENT_SHORT_ACCESSKEY:
5378 69 : detail = lsr_to_dom_key(detail);
5379 69 : break;
5380 : default:
5381 : break;
5382 : }
5383 84 : }
5384 162 : x.value = y.value = 0;
5385 162 : GF_LSR_READ_INT(lsr, flag, 1, "has_pointvalue");
5386 162 : if (flag) {
5387 18 : lsr_read_coordinate(lsr, &x, 0, "x");
5388 18 : lsr_read_coordinate(lsr, &y, 0, "y");
5389 : }
5390 162 : idref = lsr_read_codec_IDREF_command(lsr, "idref");
5391 :
5392 162 : GF_LSR_READ_INT(lsr, flag, 1, "has_pointvalue");
5393 162 : if (flag) {
5394 9 : lsr_read_byte_align_string(lsr, NULL, "string");
5395 : }
5396 162 : lsr_read_any_attribute(lsr, NULL, 1);
5397 :
5398 162 : if (!com_list) {
5399 : GF_DOM_Event evt;
5400 54 : GF_Node *target = gf_sg_find_node(lsr->sg, idref);
5401 54 : if (!target) return GF_OK;
5402 :
5403 : memset(&evt, 0, sizeof(GF_DOM_Event));
5404 54 : evt.type = event.type;
5405 54 : evt.detail = detail ? detail : (s32) event.parameter;
5406 54 : evt.clientX = FIX2INT(x.value);
5407 54 : evt.clientY = FIX2INT(y.value);
5408 54 : gf_dom_event_fire(target, &evt);
5409 :
5410 : } else {
5411 108 : GF_Command *com = gf_sg_command_new(lsr->sg, GF_SG_LSR_SEND_EVENT);
5412 108 : gf_list_add(com_list, com);
5413 108 : com->node = gf_sg_find_node(lsr->sg, idref);
5414 108 : if (!com->node) {
5415 0 : com->RouteID = idref;
5416 0 : gf_list_add(lsr->unresolved_commands, com);
5417 : } else {
5418 108 : gf_node_register(com->node, NULL);
5419 : }
5420 108 : com->send_event_integer = detail ? detail : (s32) event.parameter;
5421 108 : com->send_event_name = event.type;
5422 108 : com->send_event_x = FIX2INT(x.value);
5423 108 : com->send_event_y = FIX2INT(y.value);
5424 : }
5425 : return GF_OK;
5426 : }
5427 :
5428 0 : static GF_Err lsr_read_save(GF_LASeRCodec *lsr, GF_List *com_list)
5429 : {
5430 : u32 i, count;
5431 0 : count = lsr_read_vluimsbf5(lsr, "nbIds");
5432 0 : for (i=0; i<count; i++) {
5433 : u32 flag;
5434 0 : lsr_read_vluimsbf5(lsr, "ref[[i]]");
5435 0 : GF_LSR_READ_INT(lsr, flag, 1, "reserved");
5436 :
5437 0 : lsr_get_attribute_name(lsr);
5438 : }
5439 0 : lsr_read_byte_align_string(lsr, NULL, "groupID");
5440 0 : lsr_read_any_attribute(lsr, NULL, 1);
5441 0 : return GF_OK;
5442 : }
5443 :
5444 0 : static GF_Err lsr_read_restore(GF_LASeRCodec *lsr, GF_List *com_list)
5445 : {
5446 0 : lsr_read_byte_align_string(lsr, NULL, "groupID");
5447 0 : lsr_read_any_attribute(lsr, NULL, 1);
5448 0 : return GF_OK;
5449 : }
5450 :
5451 5 : void lsr_exec_command_list(GF_Node *node, void *par, Bool is_destroy)
5452 : {
5453 : GF_DOMUpdates *up = (GF_DOMUpdates *)node;
5454 5 : GF_LASeRCodec *codec = (GF_LASeRCodec *)gf_node_get_private((GF_Node*)node);
5455 :
5456 5 : if (is_destroy || !up || (up->sgprivate->tag!=TAG_DOMUpdates)) return;
5457 : assert(!codec->bs);
5458 :
5459 0 : codec->info = lsr_get_stream(codec, 0);
5460 0 : if (!codec->info) return;
5461 0 : codec->coord_bits = codec->info->cfg.coord_bits;
5462 0 : codec->scale_bits = codec->info->cfg.scale_bits_minus_coord_bits;
5463 0 : codec->time_resolution = codec->info->cfg.time_resolution;
5464 0 : codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1;
5465 0 : if (codec->info->cfg.resolution >= 0)
5466 0 : codec->res_factor = INT2FIX(1<<codec->info->cfg.resolution);
5467 : else
5468 0 : codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1 << (-codec->info->cfg.resolution)) );
5469 :
5470 0 : codec->bs = gf_bs_new(up->data, up->data_size, GF_BITSTREAM_READ);
5471 0 : codec->memory_dec = 0;
5472 0 : lsr_read_command_list(codec, NULL, NULL, 0);
5473 0 : gf_bs_del(codec->bs);
5474 0 : codec->bs = NULL;
5475 : }
5476 :
5477 14 : static GF_Err lsr_read_command_list(GF_LASeRCodec *lsr, GF_List *com_list, SVG_Element *cond, Bool first_imp)
5478 : {
5479 : GF_Node *n;
5480 : GF_Command *com;
5481 : u32 i, type, count;
5482 :
5483 14 : if (cond) {
5484 : u32 s_len;
5485 5 : GF_DOMUpdates *up = gf_dom_add_updates_node((GF_Node*)cond);
5486 5 : gf_node_set_callback_function((GF_Node*)up, lsr_exec_command_list);
5487 5 : gf_node_set_private((GF_Node *) up, lsr);
5488 :
5489 5 : s_len = lsr_read_vluimsbf5(lsr, NULL/*"encoding-length" - don't log to avoid corrupting the log order!!*/);
5490 5 : gf_bs_align(lsr->bs);
5491 : /*not in memory mode, direct decode*/
5492 5 : if (!lsr->memory_dec) {
5493 : com_list = NULL;
5494 1 : up->data_size = s_len;
5495 1 : up->data = (char*)gf_malloc(sizeof(char)*s_len);
5496 1 : gf_bs_read_data(lsr->bs, up->data, s_len);
5497 1 : goto exit;
5498 : }
5499 : /*memory mode, decode commands*/
5500 : else {
5501 4 : com_list = up->updates;
5502 : }
5503 : }
5504 13 : count = lsr_read_vluimsbf5(lsr, "occ0");
5505 13 : if (first_imp) count++;
5506 :
5507 282 : for (i=0; i<count; i++) {
5508 269 : GF_LSR_READ_INT(lsr, type, 4, "ch4");
5509 269 : switch (type) {
5510 90 : case LSR_UPDATE_ADD:
5511 : case LSR_UPDATE_INSERT:
5512 : case LSR_UPDATE_REPLACE:
5513 90 : lsr_read_add_replace_insert(lsr, com_list, type);
5514 90 : break;
5515 8 : case LSR_UPDATE_DELETE:
5516 8 : lsr_read_delete(lsr, com_list);
5517 8 : break;
5518 3 : case LSR_UPDATE_NEW_SCENE:
5519 : case LSR_UPDATE_REFRESH_SCENE: /*TODO FIXME, depends on decoder state*/
5520 3 : if (type==5) lsr_read_vluimsbf5(lsr, "time");
5521 3 : lsr_read_any_attribute(lsr, NULL, 1);
5522 3 : if (com_list) {
5523 2 : n = lsr_read_svg(lsr, 0);
5524 2 : if (!n)
5525 0 : return (lsr->last_error = GF_NON_COMPLIANT_BITSTREAM);
5526 2 : gf_node_register(n, NULL);
5527 2 : com = gf_sg_command_new(lsr->sg, (type==5) ? GF_SG_LSR_REFRESH_SCENE : GF_SG_LSR_NEW_SCENE);
5528 2 : com->node = n;
5529 2 : gf_list_add(com_list, com);
5530 : } else {
5531 1 : gf_sg_reset(lsr->sg);
5532 1 : gf_sg_set_scene_size_info(lsr->sg, 0, 0, 1);
5533 1 : n = lsr_read_svg(lsr, 1);
5534 1 : if (!n)
5535 0 : return (lsr->last_error = GF_NON_COMPLIANT_BITSTREAM);
5536 : }
5537 : break;
5538 0 : case LSR_UPDATE_TEXT_CONTENT:
5539 0 : lsr_read_byte_align_string(lsr, NULL, "textContent");
5540 0 : break;
5541 162 : case LSR_UPDATE_SEND_EVENT:
5542 162 : lsr_read_send_event(lsr, com_list);
5543 162 : break;
5544 0 : case LSR_UPDATE_RESTORE:
5545 0 : lsr_read_restore(lsr, com_list);
5546 0 : break;
5547 0 : case LSR_UPDATE_SAVE:
5548 0 : lsr_read_save(lsr, com_list);
5549 0 : break;
5550 6 : case LSR_UPDATE_EXTEND:
5551 : {
5552 : u32 extID;
5553 6 : GF_LSR_READ_INT(lsr, extID, lsr->info->cfg.extensionIDBits, "extensionID");
5554 6 : /*len = */lsr_read_vluimsbf5(lsr, "len");
5555 6 : if (extID==2) {
5556 : u32 j, sub_count;
5557 6 : lsr_read_vluimsbf5(lsr, "reserved");
5558 6 : sub_count = lsr_read_vluimsbf5(lsr, "occ2");
5559 12 : for (j=0; j<sub_count; j++) {
5560 : u32 k, occ3;
5561 6 : GF_LSR_READ_INT(lsr, k, 2, "reserved");
5562 6 : occ3 = lsr_read_vluimsbf5(lsr, "occ3");
5563 12 : for (k=0; k<occ3; k++) {
5564 : u32 sub_type, idref;
5565 6 : GF_LSR_READ_INT(lsr, sub_type, 2, "ch5");
5566 6 : switch (sub_type) {
5567 6 : case 1:
5568 : case 2:
5569 6 : idref = lsr_read_codec_IDREF_command(lsr, "ref");
5570 :
5571 6 : n = gf_sg_find_node(lsr->sg, idref);
5572 6 : if (com_list) {
5573 4 : com = gf_sg_command_new(lsr->sg, (sub_type==1) ? GF_SG_LSR_ACTIVATE : GF_SG_LSR_DEACTIVATE);
5574 4 : if (n) {
5575 4 : com->node = n;
5576 4 : gf_node_register(n, NULL);
5577 : } else {
5578 0 : com->RouteID = idref;
5579 : }
5580 4 : gf_list_add(com_list, com);
5581 2 : } else if (sub_type==1) {
5582 1 : if (!n) return GF_NON_COMPLIANT_BITSTREAM;
5583 1 : gf_node_activate(n);
5584 : } else {
5585 1 : if (!n) return GF_NON_COMPLIANT_BITSTREAM;
5586 1 : gf_node_deactivate(n);
5587 : }
5588 : break;
5589 0 : default:
5590 0 : lsr_read_private_element_container(lsr);
5591 0 : break;
5592 : }
5593 : }
5594 : }
5595 : }
5596 : }
5597 : break;
5598 0 : default:
5599 0 : return (lsr->last_error = GF_NON_COMPLIANT_BITSTREAM);
5600 : }
5601 : /*same-coding scope is command-based (to check in the spec)*/
5602 269 : if (cond) {
5603 8 : lsr->prev_g = NULL;
5604 8 : lsr->prev_line = NULL;
5605 8 : lsr->prev_path = NULL;
5606 8 : lsr->prev_polygon = NULL;
5607 8 : lsr->prev_rect = NULL;
5608 8 : lsr->prev_text = NULL;
5609 8 : lsr->prev_use = NULL;
5610 : }
5611 :
5612 269 : if (lsr->last_error)
5613 : return lsr->last_error;
5614 : }
5615 13 : exit:
5616 : /*script is align*/
5617 14 : if (cond) {
5618 5 : gf_bs_align(lsr->bs);
5619 5 : lsr_read_object_content(lsr, (SVG_Element*)cond);
5620 5 : lsr->prev_g = NULL;
5621 5 : lsr->prev_line = NULL;
5622 5 : lsr->prev_path = NULL;
5623 5 : lsr->prev_polygon = NULL;
5624 5 : lsr->prev_rect = NULL;
5625 5 : lsr->prev_text = NULL;
5626 5 : lsr->prev_use = NULL;
5627 : }
5628 : return GF_OK;
5629 : }
5630 :
5631 9 : static GF_Err lsr_decode_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list)
5632 : {
5633 : GF_Err e;
5634 : Bool reset_encoding_context;
5635 : u32 flag, i, count = 0, privateDataIdentifierIndexBits;
5636 :
5637 9 : lsr->last_error = GF_OK;
5638 :
5639 : /*
5640 : * 1 - laser unit header
5641 : */
5642 9 : GF_LSR_READ_INT(lsr, reset_encoding_context, 1, "resetEncodingContext");
5643 9 : GF_LSR_READ_INT(lsr, flag, 1, "opt_group");
5644 9 : if (flag) lsr_read_extension(lsr, "ext");
5645 :
5646 : /*clean all tables*/
5647 9 : if (reset_encoding_context) {
5648 0 : lsr->nb_cols = 0;
5649 0 : if (lsr->col_table) gf_free(lsr->col_table);
5650 0 : lsr->col_table = NULL;
5651 0 : while (gf_list_count(lsr->font_table)) {
5652 0 : char *ft = (char *)gf_list_last(lsr->font_table);
5653 0 : gf_free(ft);
5654 0 : gf_list_rem_last(lsr->font_table);
5655 : }
5656 0 : lsr->privateData_id_index = lsr->privateTag_index = 0;
5657 : }
5658 :
5659 : /*
5660 : * 2 - codecInitialisations
5661 : */
5662 :
5663 : /*
5664 : * 2.a - condecInitialization.color
5665 : */
5666 9 : GF_LSR_READ_INT(lsr, flag, 1, "colorInitialisation");
5667 :
5668 9 : if (flag) {
5669 3 : count = lsr_read_vluimsbf5(lsr, "count");
5670 3 : lsr->col_table = (LSRCol*)gf_realloc(lsr->col_table, sizeof(LSRCol)*(lsr->nb_cols+count));
5671 48 : for (i=0; i<count; i++) {
5672 : LSRCol c;
5673 45 : GF_LSR_READ_INT(lsr, c.r, lsr->info->cfg.colorComponentBits, "red");
5674 45 : GF_LSR_READ_INT(lsr, c.g, lsr->info->cfg.colorComponentBits, "green");
5675 45 : GF_LSR_READ_INT(lsr, c.b, lsr->info->cfg.colorComponentBits, "blue");
5676 45 : lsr->col_table[lsr->nb_cols+i] = c;
5677 : }
5678 3 : lsr->nb_cols += count;
5679 : }
5680 9 : lsr->colorIndexBits = gf_get_bit_size(lsr->nb_cols);
5681 : /*
5682 : * 2.b - condecInitialization.fonts
5683 : */
5684 9 : GF_LSR_READ_INT(lsr, flag, 1, "fontInitialisation");
5685 : count = 0;
5686 9 : if (flag) {
5687 3 : count = lsr_read_vluimsbf5(lsr, "count");
5688 9 : for (i=0; i<count; i++) {
5689 6 : char *ft = NULL;
5690 6 : lsr_read_byte_align_string(lsr, &ft, "font");
5691 6 : gf_list_add(lsr->font_table, ft);
5692 : }
5693 : }
5694 9 : lsr->fontIndexBits = gf_get_bit_size(count);
5695 : /*
5696 : * 2.c - condecInitialization.private
5697 : */
5698 9 : GF_LSR_READ_INT(lsr, flag, 1, "privateDataIdentifierInitialisation");
5699 :
5700 9 : if (flag) {
5701 0 : count = lsr_read_vluimsbf5(lsr, "nbPrivateDataIdentifiers");
5702 0 : for (i=0; i<count; i++) {
5703 0 : lsr->privateData_id_index++;
5704 0 : lsr_read_byte_align_string(lsr, NULL, "privateDataIdentifier");
5705 : }
5706 : }
5707 : /*
5708 : * 2.d - condecInitialization.anyXML
5709 : */
5710 9 : GF_LSR_READ_INT(lsr, flag, 1, "anyXMLInitialisation");
5711 :
5712 9 : if (flag) {
5713 0 : privateDataIdentifierIndexBits = gf_get_bit_size(lsr->privateData_id_index);
5714 0 : count = lsr_read_vluimsbf5(lsr, "nbTags");
5715 0 : for (i=0; i<count; i++) {
5716 0 : lsr->privateTag_index++;
5717 0 : if (i) {
5718 : /* uint(privateDataIdentifierIndexBits) = */
5719 0 : GF_LSR_READ_INT(lsr, flag, privateDataIdentifierIndexBits, "privateDataIdentifierIndex");
5720 0 : lsr_read_byte_align_string(lsr, NULL, "tag");
5721 : }
5722 0 : GF_LSR_READ_INT(lsr, flag, 1, "hasAttrs");
5723 0 : if (flag) {
5724 0 : u32 k, c2 = lsr_read_vluimsbf5(lsr, "nbAttrNames");
5725 0 : for (k=0; k<c2; k++) {
5726 0 : if (!i) {
5727 : /* uint(privateDataIdentifierIndexBits) = */
5728 0 : GF_LSR_READ_INT(lsr, flag, privateDataIdentifierIndexBits, "privateDataIdentifierIndex");
5729 : }
5730 0 : lsr_read_byte_align_string(lsr, NULL, "tag");
5731 : }
5732 : }
5733 : }
5734 : }
5735 : /*
5736 : * 2.e - condecInitialization.extension
5737 : */
5738 9 : count = lsr_read_vluimsbf5(lsr, "countG");
5739 9 : for (i=0; i<count; i++) {
5740 0 : /*u32 locID = */lsr_read_vluimsbf5(lsr, "binaryIdForThisStringID");
5741 0 : lsr_read_byte_align_string(lsr, NULL, "stringID");
5742 : }
5743 9 : GF_LSR_READ_INT(lsr, flag, 1, "hasExtension");
5744 9 : if (flag) {
5745 0 : u32 len = lsr_read_vluimsbf5(lsr, "len");
5746 0 : u32 pos = gf_bs_get_bit_offset(lsr->bs);
5747 :
5748 0 : count = lsr_read_vluimsbf5(lsr, "len");
5749 0 : for (i=0; i<count; i++) {
5750 0 : /*u32 locID = */lsr_read_vluimsbf5(lsr, "localStreamIdForThisGlobal");
5751 0 : lsr_read_byte_align_string(lsr, NULL, "globalName");
5752 : }
5753 0 : pos = gf_bs_get_bit_offset(lsr->bs) - pos;
5754 0 : if (len<pos)
5755 : return GF_NON_COMPLIANT_BITSTREAM;
5756 :
5757 0 : GF_LSR_READ_INT(lsr, flag, pos, "remainingData");
5758 : }
5759 :
5760 9 : e = lsr_read_command_list(lsr, com_list, NULL, 1);
5761 9 : GF_LSR_READ_INT(lsr, flag, 1, "opt_group");
5762 9 : if (flag) lsr_read_extension(lsr, "ext");
5763 : return e;
5764 : }
5765 :
5766 : #endif /*GPAC_DISABLE_LASER*/
|