Coverage Report

Created: 2026-04-12 08:39

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