PageRenderTime 59ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 1ms

/src/laser/lsr_enc.c

https://github.com/svettom/gpac
C | 3947 lines | 3507 code | 277 blank | 163 comment | 783 complexity | d622c0273c617b70ebfe62a0d11d276f MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. /*
  2. * GPAC - Multimedia Framework C SDK
  3. *
  4. * Authors: Jean Le Feuvre
  5. * Copyright (c) Telecom ParisTech 2005-2012
  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. #include "../../include/gpac/internal/laser_dev.h"
  26. #include "../../include/gpac/internal/scenegraph_dev.h"
  27. #include "../../include/gpac/bitstream.h"
  28. #include "../../include/gpac/math.h"
  29. #ifndef GPAC_DISABLE_LASER
  30. #include "../../include/gpac/events.h"
  31. #define GF_LSR_WRITE_INT(_codec, _val, _nbBits, _str) {\
  32. gf_bs_write_int(_codec->bs, _val, _nbBits); \
  33. GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", _str, _nbBits, _val)); \
  34. }\
  35. static void lsr_write_group_content(GF_LASeRCodec *lsr, SVG_Element *elt, Bool skip_object_content);
  36. static GF_Err lsr_write_command_list(GF_LASeRCodec *lsr, GF_List *comList, SVG_Element *script, Bool first_implicit);
  37. static GF_Err lsr_write_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list, Bool reset_encoding_context);
  38. static void lsr_write_point_sequence(GF_LASeRCodec *lsr, GF_List **pts, const char *name);
  39. static void lsr_write_path_type(GF_LASeRCodec *lsr, SVG_PathData *path, const char *name);
  40. GF_LASeRCodec *gf_laser_encoder_new(GF_SceneGraph *graph)
  41. {
  42. GF_LASeRCodec *tmp;
  43. GF_SAFEALLOC(tmp, GF_LASeRCodec);
  44. if (!tmp) return NULL;
  45. tmp->streamInfo = gf_list_new();
  46. tmp->font_table = gf_list_new();
  47. tmp->sg = graph;
  48. return tmp;
  49. }
  50. void gf_laser_encoder_del(GF_LASeRCodec *codec)
  51. {
  52. /*destroy all config*/
  53. while (gf_list_count(codec->streamInfo)) {
  54. LASeRStreamInfo *p = (LASeRStreamInfo *)gf_list_last(codec->streamInfo);
  55. gf_free(p);
  56. gf_list_rem_last(codec->streamInfo);
  57. }
  58. gf_list_del(codec->streamInfo);
  59. if (codec->col_table) gf_free(codec->col_table);
  60. while (gf_list_count(codec->font_table)) {
  61. char *ft = (char *)gf_list_last(codec->font_table);
  62. gf_free(ft);
  63. gf_list_rem_last(codec->font_table);
  64. }
  65. gf_list_del(codec->font_table);
  66. gf_free(codec);
  67. }
  68. static LASeRStreamInfo *lsr_get_stream(GF_LASeRCodec *codec, u16 ESID)
  69. {
  70. LASeRStreamInfo *ptr;
  71. u32 i = 0;
  72. while ((ptr = (LASeRStreamInfo *)gf_list_enum(codec->streamInfo, &i))) {
  73. if(ptr->ESID==ESID) return ptr;
  74. }
  75. return NULL;
  76. }
  77. GF_Err gf_laser_encoder_new_stream(GF_LASeRCodec *codec, u16 ESID, GF_LASERConfig *cfg)
  78. {
  79. LASeRStreamInfo *pInfo;
  80. if (lsr_get_stream(codec, ESID) != NULL) return GF_BAD_PARAM;
  81. GF_SAFEALLOC(pInfo, LASeRStreamInfo);
  82. pInfo->ESID = ESID;
  83. memcpy(&pInfo->cfg, cfg, sizeof(GF_LASERConfig));
  84. if (!pInfo->cfg.time_resolution) pInfo->cfg.time_resolution = 1000;
  85. if (!pInfo->cfg.colorComponentBits) pInfo->cfg.colorComponentBits = 8;
  86. if (!pInfo->cfg.coord_bits) pInfo->cfg.coord_bits = 12;
  87. if (pInfo->cfg.resolution<-8) pInfo->cfg.resolution = (s8) -8;
  88. else if (pInfo->cfg.resolution>7) pInfo->cfg.resolution=7;
  89. gf_list_add(codec->streamInfo, pInfo);
  90. return GF_OK;
  91. }
  92. GF_Err gf_laser_encoder_get_config(GF_LASeRCodec *codec, u16 ESID, char **out_data, u32 *out_data_length)
  93. {
  94. GF_BitStream *bs;
  95. if (!codec || !out_data || !out_data_length) return GF_BAD_PARAM;
  96. codec->info = lsr_get_stream(codec, ESID);
  97. if (!codec->info) return GF_BAD_PARAM;
  98. bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
  99. gf_bs_write_int(bs, codec->info->cfg.profile, 8);
  100. gf_bs_write_int(bs, codec->info->cfg.level, 8);
  101. gf_bs_write_int(bs, 0 /*codec->info->cfg.reserved*/, 3);
  102. gf_bs_write_int(bs, codec->info->cfg.pointsCodec, 2);
  103. gf_bs_write_int(bs, codec->info->cfg.pathComponents, 4);
  104. gf_bs_write_int(bs, codec->info->cfg.fullRequestHost, 1);
  105. if (codec->info->cfg.time_resolution != 1000) {
  106. gf_bs_write_int(bs, 1, 1);
  107. gf_bs_write_int(bs, codec->info->cfg.time_resolution , 16);
  108. } else {
  109. gf_bs_write_int(bs, 0, 1);
  110. }
  111. gf_bs_write_int(bs, codec->info->cfg.colorComponentBits - 1, 4);
  112. if (codec->info->cfg.resolution<0)
  113. gf_bs_write_int(bs, 16 + codec->info->cfg.resolution, 4);
  114. else
  115. gf_bs_write_int(bs, codec->info->cfg.resolution, 4);
  116. gf_bs_write_int(bs, codec->info->cfg.coord_bits, 5);
  117. gf_bs_write_int(bs, codec->info->cfg.scale_bits_minus_coord_bits, 4);
  118. gf_bs_write_int(bs, codec->info->cfg.newSceneIndicator ? 1 : 0, 1);
  119. gf_bs_write_int(bs, 0, 3);
  120. gf_bs_write_int(bs, codec->info->cfg.extensionIDBits, 4);
  121. /*no extConfig*/
  122. gf_bs_write_int(bs, 0, 1);
  123. /*no extensions*/
  124. gf_bs_write_int(bs, 0, 1);
  125. gf_bs_align(bs);
  126. gf_bs_get_content(bs, out_data, out_data_length);
  127. gf_bs_del(bs);
  128. return GF_OK;
  129. }
  130. GF_Err gf_laser_encode_au(GF_LASeRCodec *codec, u16 ESID, GF_List *command_list, Bool reset_context, char **out_data, u32 *out_data_length)
  131. {
  132. GF_Err e;
  133. if (!codec || !command_list || !out_data || !out_data_length) return GF_BAD_PARAM;
  134. codec->info = lsr_get_stream(codec, ESID);
  135. if (!codec->info) return GF_BAD_PARAM;
  136. codec->coord_bits = codec->info->cfg.coord_bits;
  137. codec->scale_bits = codec->info->cfg.scale_bits_minus_coord_bits;
  138. codec->time_resolution = codec->info->cfg.time_resolution;
  139. codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1;
  140. if (codec->info->cfg.resolution>=0)
  141. codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1<<codec->info->cfg.resolution) );
  142. else
  143. codec->res_factor = INT2FIX(1 << (-codec->info->cfg.resolution));
  144. codec->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
  145. e = lsr_write_laser_unit(codec, command_list, reset_context);
  146. if (!e) {
  147. gf_bs_align(codec->bs);
  148. gf_bs_get_content(codec->bs, out_data, out_data_length);
  149. }
  150. gf_bs_del(codec->bs);
  151. codec->bs = NULL;
  152. return e;
  153. }
  154. GF_Err gf_laser_encoder_get_rap(GF_LASeRCodec *codec, char **out_data, u32 *out_data_length)
  155. {
  156. GF_Err e;
  157. if (!codec->info) codec->info = (LASeRStreamInfo*)gf_list_get(codec->streamInfo, 0);
  158. codec->coord_bits = codec->info->cfg.coord_bits;
  159. codec->scale_bits = codec->info->cfg.scale_bits_minus_coord_bits;
  160. codec->time_resolution = codec->info->cfg.time_resolution;
  161. codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1;
  162. if (codec->info->cfg.resolution>=0)
  163. codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1<<codec->info->cfg.resolution) );
  164. else
  165. codec->res_factor = INT2FIX(1 << (-codec->info->cfg.resolution));
  166. codec->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
  167. e = lsr_write_laser_unit(codec, NULL, 0);
  168. if (e == GF_OK) gf_bs_get_content(codec->bs, out_data, out_data_length);
  169. gf_bs_del(codec->bs);
  170. codec->bs = NULL;
  171. return e;
  172. }
  173. static void lsr_write_vluimsbf5(GF_LASeRCodec *lsr, u32 val, const char *name)
  174. {
  175. u32 nb_words;
  176. u32 nb_bits = val ? gf_get_bit_size(val) : 1;
  177. nb_words = nb_bits / 4;
  178. if (nb_bits%4) nb_words++;
  179. assert(nb_words * 4 >= nb_bits);
  180. nb_bits = 4*nb_words;
  181. while (nb_words) {
  182. nb_words--;
  183. gf_bs_write_int(lsr->bs, nb_words ? 1 : 0, 1);
  184. }
  185. gf_bs_write_int(lsr->bs, val, nb_bits);
  186. GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_bits + (nb_bits/4), val));
  187. }
  188. static void lsr_write_vluimsbf5_ex(GF_LASeRCodec *lsr, u32 val, u32 extra_words, const char *name)
  189. {
  190. u32 nb_words;
  191. u32 nb_bits = val ? gf_get_bit_size(val) : 1;
  192. nb_words = nb_bits / 4;
  193. if (nb_bits%4) nb_words++;
  194. nb_words += extra_words;
  195. assert(nb_words * 4 >= nb_bits);
  196. nb_bits = 4*nb_words;
  197. while (nb_words) {
  198. nb_words--;
  199. gf_bs_write_int(lsr->bs, nb_words ? 1 : 0, 1);
  200. }
  201. gf_bs_write_int(lsr->bs, val, nb_bits);
  202. GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_bits + (nb_bits/4), val));
  203. }
  204. static u32 lsr_get_vluimsbf5_size(u32 val, u32 extra_words)
  205. {
  206. u32 nb_words;
  207. u32 nb_bits = val ? gf_get_bit_size(val) : 1;
  208. nb_words = nb_bits / 4;
  209. if (nb_bits%4) nb_words++;
  210. nb_words += extra_words;
  211. return 4*nb_words + nb_words;
  212. }
  213. static void lsr_write_vluimsbf8(GF_LASeRCodec *lsr, u32 val, const char *name)
  214. {
  215. u32 nb_words;
  216. u32 nb_tot, nb_bits = val ? gf_get_bit_size(val) : 1;
  217. nb_words = nb_bits / 7;
  218. if (nb_bits%7) nb_words++;
  219. assert(nb_words * 7 >= nb_bits);
  220. nb_bits = nb_words * 7;
  221. nb_tot = nb_words+nb_bits;
  222. while (nb_words) {
  223. nb_words--;
  224. gf_bs_write_int(lsr->bs, nb_words ? 1 : 0, 1);
  225. }
  226. gf_bs_write_int(lsr->bs, val, nb_bits);
  227. GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_tot, val));
  228. }
  229. static void lsr_write_extension(GF_LASeRCodec *lsr, char *data, u32 len, const char *name)
  230. {
  231. if (!len) len = (u32) strlen(name);
  232. lsr_write_vluimsbf5(lsr, len, name);
  233. gf_bs_write_data(lsr->bs, data, len);
  234. }
  235. static void lsr_write_codec_IDREF(GF_LASeRCodec *lsr, XMLRI *href, const char *name)
  236. {
  237. u32 nID = 0;
  238. if (href && href->target) nID = gf_node_get_id((GF_Node *)href->target);
  239. else if (name[0]=='#') {
  240. GF_Node *n = gf_sg_find_node_by_name(lsr->sg, (char *) name + 1);
  241. if (n) nID = gf_node_get_id((GF_Node *)href->target);
  242. }
  243. else nID = 1+href->lsr_stream_id;
  244. assert(nID);
  245. lsr_write_vluimsbf5(lsr, nID-1, name);
  246. GF_LSR_WRITE_INT(lsr, 0, 1, "reserved");
  247. }
  248. static void lsr_write_codec_IDREF_Node(GF_LASeRCodec *lsr, GF_Node *href, const char *name)
  249. {
  250. u32 nID = gf_node_get_id(href);
  251. assert(nID);
  252. lsr_write_vluimsbf5(lsr, nID-1, name);
  253. GF_LSR_WRITE_INT(lsr, 0, 1, "reserved");
  254. }
  255. static u32 lsr_get_IDREF_nb_bits(GF_LASeRCodec *lsr, GF_Node *href)
  256. {
  257. u32 nb_bits, nb_words, nID;
  258. nID = gf_node_get_id(href);
  259. assert(nID);
  260. nb_bits = nID ? gf_get_bit_size(nID) : 1;
  261. nb_words = nb_bits / 4;
  262. if (nb_bits%4) nb_words++;
  263. assert(nb_words * 4 >= nb_bits);
  264. nb_bits = nb_words * 4;
  265. return nb_words+nb_bits /*IDREF part*/ + 1 /*reserevd bit*/;
  266. }
  267. static void lsr_write_fixed_16_8(GF_LASeRCodec *lsr, Fixed fix, const char *name)
  268. {
  269. u32 val;
  270. if (fix<0) {
  271. #ifdef GPAC_FIXED_POINT
  272. val = (1<<24) + fix / 256;
  273. #else
  274. val = (1<<24) + FIX2INT(fix * 256);
  275. #endif
  276. } else {
  277. #ifdef GPAC_FIXED_POINT
  278. val = fix/256;
  279. #else
  280. val = FIX2INT(fix*256);
  281. #endif
  282. }
  283. val &= 0x00FFFFFF;
  284. GF_LSR_WRITE_INT(lsr, val, 24, name);
  285. }
  286. static void lsr_write_fixed_16_8i(GF_LASeRCodec *lsr, SVG_Number *n, const char *name)
  287. {
  288. if (n->type==SVG_NUMBER_INHERIT) {
  289. GF_LSR_WRITE_INT(lsr, 1, 1, name);
  290. } else {
  291. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  292. lsr_write_fixed_16_8(lsr, n->value, name);
  293. }
  294. }
  295. static s32 lsr_get_font_index(GF_LASeRCodec *lsr, SVG_FontFamily *font)
  296. {
  297. u32 i, count;
  298. if ((font->type!=SVG_FONTFAMILY_VALUE) || !font->value) return -1;
  299. count = gf_list_count(lsr->font_table);
  300. for (i=0; i<count; i++) {
  301. char *n = (char *)gf_list_get(lsr->font_table, i);
  302. if (!strcmp(n, font->value)) return (s32) i;
  303. }
  304. return -2;
  305. }
  306. static s32 lsr_get_col_index(GF_LASeRCodec *lsr, SVG_Color *color)
  307. {
  308. u16 r, g, b;
  309. u32 i;
  310. if (color->type!=SVG_COLOR_RGBCOLOR) return -1;
  311. r = FIX2INT(color->red*lsr->color_scale);
  312. g = FIX2INT(color->green*lsr->color_scale);
  313. b = FIX2INT(color->blue*lsr->color_scale);
  314. for (i=0; i<lsr->nb_cols; i++) {
  315. LSRCol *c = &lsr->col_table[i];
  316. if ((c->r == r) && (c->g == g) && (c->b == b)) return (s32) i;
  317. }
  318. return -2;
  319. }
  320. static void lsr_write_line_increment_type(GF_LASeRCodec *lsr, SVG_Number *li, const char *name)
  321. {
  322. if (li->type==SVG_NUMBER_INHERIT) {
  323. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  324. GF_LSR_WRITE_INT(lsr, 1, 1, "inherit");
  325. } else if (li->type==SVG_NUMBER_AUTO) {
  326. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  327. GF_LSR_WRITE_INT(lsr, 0, 1, "auto");
  328. } else {
  329. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  330. lsr_write_fixed_16_8(lsr, li->value, "line-increment-value");
  331. }
  332. }
  333. static void lsr_write_byte_align_string(GF_LASeRCodec *lsr, char *str, const char *name)
  334. {
  335. u32 len = str ? (u32) strlen(str) : 0;
  336. gf_bs_align(lsr->bs);
  337. lsr_write_vluimsbf8(lsr, len, "len");
  338. if (len) gf_bs_write_data(lsr->bs, str, len);
  339. GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%s\n", name, 8*len, str ? str : ""));
  340. }
  341. static void lsr_write_byte_align_string_list(GF_LASeRCodec *lsr, GF_List *l, const char *name, Bool is_iri)
  342. {
  343. char text[4096];
  344. u32 i, count = gf_list_count(l);
  345. text[0] = 0;
  346. for (i=0; i<count; i++) {
  347. char *str;
  348. if (is_iri) {
  349. XMLRI *iri = (XMLRI *)gf_list_get(l, i);
  350. str = iri->string;
  351. } else {
  352. str = (char*)gf_list_get(l, i);
  353. }
  354. strcat(text, str);
  355. if (i+1<count) strcat(text, ";");
  356. }
  357. lsr_write_byte_align_string(lsr, text, name);
  358. }
  359. static void lsr_write_any_uri(GF_LASeRCodec *lsr, XMLRI *iri, const char *name)
  360. {
  361. Bool is_iri = 0;
  362. if (iri->type==XMLRI_STRING) {
  363. is_iri = 1;
  364. if (iri->string[0]=='#') {
  365. iri->target = (SVG_Element*)gf_sg_find_node_by_name(lsr->sg, iri->string+1);
  366. if (iri->target) {
  367. is_iri = 0;
  368. iri->type = XMLRI_ELEMENTID;
  369. }
  370. }
  371. }
  372. GF_LSR_WRITE_INT(lsr, is_iri, 1, "hasUri");
  373. if (is_iri) {
  374. if (!iri->string || strnicmp(iri->string, "data:", 5)) {
  375. lsr_write_byte_align_string(lsr, iri->string, "uri");
  376. GF_LSR_WRITE_INT(lsr, 0, 1, "hasData");
  377. } else {
  378. u32 len;
  379. char *sep = strchr(iri->string, ',');
  380. sep[0] = 0;
  381. lsr_write_byte_align_string(lsr, iri->string, "uri");
  382. sep[0] = ',';
  383. len = (u32) strlen(sep+1);
  384. GF_LSR_WRITE_INT(lsr, 1, 1, "hasData");
  385. lsr_write_vluimsbf5(lsr, len, "len");
  386. gf_bs_write_data(lsr->bs, sep+1, len);
  387. }
  388. }
  389. GF_LSR_WRITE_INT(lsr, (iri->type==XMLRI_ELEMENTID) ? 1 : 0, 1, "hasID");
  390. if (iri->type==XMLRI_ELEMENTID) lsr_write_codec_IDREF(lsr, iri, "idref");
  391. GF_LSR_WRITE_INT(lsr, (iri->type==XMLRI_STREAMID) ? 1 : 0, 1, "hasID");
  392. if (iri->type==XMLRI_STREAMID)
  393. lsr_write_codec_IDREF(lsr, iri, "ref");
  394. }
  395. static void lsr_write_paint(GF_LASeRCodec *lsr, SVG_Paint *paint, const char *name)
  396. {
  397. if ((paint->type==SVG_PAINT_COLOR) && (paint->color.type==SVG_COLOR_RGBCOLOR)) {
  398. s32 idx;
  399. GF_LSR_WRITE_INT(lsr, 1, 1, "hasIndex");
  400. idx = lsr_get_col_index(lsr, &paint->color);
  401. if (idx<0) {
  402. idx = 0;
  403. GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[LASeR] color not in colorTable\n"));
  404. }
  405. GF_LSR_WRITE_INT(lsr, (u32) idx, lsr->colorIndexBits, name);
  406. } else {
  407. GF_LSR_WRITE_INT(lsr, 0, 1, "hasIndex");
  408. switch (paint->type) {
  409. case SVG_PAINT_INHERIT:
  410. GF_LSR_WRITE_INT(lsr, 0, 2, "enum");
  411. GF_LSR_WRITE_INT(lsr, 0, 2, "choice");
  412. break;
  413. case SVG_PAINT_NONE:
  414. GF_LSR_WRITE_INT(lsr, 0, 2, "enum");
  415. GF_LSR_WRITE_INT(lsr, 2, 2, "choice");
  416. break;
  417. case SVG_PAINT_COLOR:
  418. if (paint->color.type == SVG_COLOR_CURRENTCOLOR) {
  419. GF_LSR_WRITE_INT(lsr, 0, 2, "enum");
  420. GF_LSR_WRITE_INT(lsr, 1, 2, "choice");
  421. } else {
  422. GF_LSR_WRITE_INT(lsr, 2, 2, "enum");
  423. lsr_write_byte_align_string(lsr, (char*)gf_svg_get_system_paint_server_name(paint->color.type), "systemsPaint");
  424. }
  425. break;
  426. case SVG_PAINT_URI:
  427. GF_LSR_WRITE_INT(lsr, 1, 2, "enum");
  428. lsr_write_any_uri(lsr, &paint->iri, "uri");
  429. break;
  430. default:
  431. GF_LSR_WRITE_INT(lsr, 3, 2, "enum");
  432. lsr_write_extension(lsr, "ERROR", 5, "colorExType0");
  433. break;
  434. }
  435. }
  436. }
  437. #ifdef GPAC_UNUSED_FUNC
  438. static void lsr_write_private_element_container(GF_LASeRCodec *lsr)
  439. {
  440. /*NO PRIVATE DATA ON ENCODING YET*/
  441. assert(0);
  442. }
  443. static void lsr_write_private_att_class(GF_LASeRCodec *lsr)
  444. {
  445. /*NO PRIVATE DATA ON ENCODING YET*/
  446. assert(0);
  447. }
  448. static void lsr_write_extend_class(GF_LASeRCodec *lsr, char *data, u32 len, const char *name)
  449. {
  450. u32 i=0;
  451. GF_LSR_WRITE_INT(lsr, 0, lsr->info->cfg.extensionIDBits, "reserved");
  452. lsr_write_vluimsbf5(lsr, len, "len");
  453. while (i<len) {
  454. gf_bs_write_int(lsr->bs, data[i], 8);
  455. i++;
  456. }
  457. }
  458. static void lsr_write_private_attr_container(GF_LASeRCodec *lsr, u32 index, const char *name)
  459. {
  460. assert(0);
  461. }
  462. static Bool lsr_float_list_equal(GF_List *l1, GF_List *l2)
  463. {
  464. u32 i, count = gf_list_count(l1);
  465. if (count != gf_list_count(l2)) return 0;
  466. for (i=0;i<count;i++) {
  467. Fixed *v1 = (Fixed *)gf_list_get(l1, i);
  468. Fixed *v2 = (Fixed *)gf_list_get(l2, i);
  469. if (*v1 != *v2) return 0;
  470. }
  471. return 1;
  472. }
  473. #endif /*GPAC_UNUSED_FUNC*/
  474. static void lsr_write_any_attribute(GF_LASeRCodec *lsr, SVG_Element *node, Bool skippable)
  475. {
  476. if (1) {
  477. if (skippable) GF_LSR_WRITE_INT(lsr, 0, 1, "has_attrs");
  478. } else {
  479. if (skippable) GF_LSR_WRITE_INT(lsr, 1, 1, "has_attrs");
  480. /*
  481. do () {
  482. GF_LSR_WRITE_INT(lsr, 0, lsr->info->cfg.extensionIDBits, "reserved");
  483. lsr_write_vluimsbf5(lsr, 0, "len");//len in BITS
  484. GF_LSR_WRITE_INT(lsr, 0, 0, "reserved_val");
  485. } while ()
  486. */
  487. }
  488. }
  489. static void lsr_write_private_attributes(GF_LASeRCodec *lsr, SVG_Element *elt)
  490. {
  491. if (1) {
  492. GF_LSR_WRITE_INT(lsr, 0, 1, "has_private_attr");
  493. } else {
  494. GF_LSR_WRITE_INT(lsr, 1, 1, "has_private_attr");
  495. #ifdef GPAC_UNUSED_FUNC
  496. lsr_write_private_att_class(lsr);
  497. #endif /*GPAC_UNUSED_FUNC*/
  498. }
  499. }
  500. static void lsr_write_string_attribute(GF_LASeRCodec *lsr, char *class_attr, char *name)
  501. {
  502. if (class_attr) {
  503. GF_LSR_WRITE_INT(lsr, 1, 1, name);
  504. lsr_write_byte_align_string(lsr, class_attr, name);
  505. } else {
  506. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  507. }
  508. }
  509. static void lsr_write_id(GF_LASeRCodec *lsr, GF_Node *n)
  510. {
  511. u32 id = gf_node_get_id(n);
  512. if (id) {
  513. GF_LSR_WRITE_INT(lsr, 1, 1, "has_id");
  514. lsr_write_vluimsbf5(lsr, id-1, "ID");
  515. #if TODO_LASER_EXTENSIONS
  516. if (0) {
  517. GF_LSR_WRITE_INT(lsr, 1, 1, "reserved");
  518. lsr_write_vluimsbf5(lsr, reserved_len, "len");
  519. GF_LSR_WRITE_INT(lsr, 0, reserved_len, "reserved");
  520. } else
  521. #endif
  522. GF_LSR_WRITE_INT(lsr, 0, 1, "reserved");
  523. } else {
  524. GF_LSR_WRITE_INT(lsr, 0, 1, "has_id");
  525. }
  526. }
  527. static u32 lsr_translate_coords(GF_LASeRCodec *lsr, Fixed x, u32 nb_bits)
  528. {
  529. s32 res, max;
  530. res = FIX2INT( gf_divfix(x, lsr->res_factor) );
  531. /*don't loose too much*/
  532. if (!res && x) {
  533. GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] resolution factor %g too small to allow coding of %g - adjusting to smallest integer!\n", lsr->res_factor, FIX2FLT(x) ));
  534. res = (x>0) ? 1 : -1;
  535. }
  536. max = (1<<(nb_bits-1)) - 1;
  537. if (res>=0) {
  538. if (res > max) {
  539. GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] nb_bits %d not large enough to encode positive number %g!\n", nb_bits, FIX2FLT(x) ));
  540. res = max;
  541. }
  542. assert( ! (res & (1<<(nb_bits-1)) ));
  543. return (u32) res;
  544. }
  545. res += 1<<(nb_bits);
  546. if (res<=max){
  547. GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] nb_bits %d not large enough to encode negative number %g!\n", nb_bits, FIX2FLT(x) ));
  548. res = max+1;
  549. }
  550. assert( res & (1<<(nb_bits-1)) );
  551. return res;
  552. }
  553. static u32 lsr_translate_scale(GF_LASeRCodec *lsr, Fixed v)
  554. {
  555. s32 res;
  556. /*always 8 bits for fractional part*/
  557. if (ABS(v) * 256 < 1) v = 0;
  558. v = v*256;
  559. if (v<0) {
  560. res = FIX2INT(v) + (1<<lsr->coord_bits);
  561. if (res<0) GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[LASeR] nb_bits %d not large enough to encode negative number %d!\n", lsr->coord_bits, res));
  562. return res;
  563. }
  564. res = FIX2INT(v);
  565. if (res & (1<<(lsr->coord_bits-1)) ) {
  566. GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[LASeR] nb_bits %d not large enough to encode positive number %d!\n", lsr->coord_bits, res));
  567. }
  568. return res;
  569. }
  570. static void lsr_write_matrix(GF_LASeRCodec *lsr, SVG_Transform *mx)
  571. {
  572. u32 res;
  573. if (mx->is_ref) {
  574. GF_LSR_WRITE_INT(lsr, 1, 1, "isNotMatrix");
  575. GF_LSR_WRITE_INT(lsr, 1, 1, "isRef");
  576. GF_LSR_WRITE_INT(lsr, 1, 1, "hasXY");
  577. lsr_write_fixed_16_8(lsr, mx->mat.m[2], "valueX");
  578. lsr_write_fixed_16_8(lsr, mx->mat.m[5], "valueY");
  579. } else {
  580. GF_LSR_WRITE_INT(lsr, 0, 1, "isNotMatrix");
  581. lsr->coord_bits += lsr->scale_bits;
  582. if ((mx->mat.m[0]!=FIX_ONE) || (mx->mat.m[4]!=FIX_ONE)) {
  583. GF_LSR_WRITE_INT(lsr, 1, 1, "xx_yy_present");
  584. res = lsr_translate_scale(lsr, mx->mat.m[0]);
  585. GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "xx");
  586. res = lsr_translate_scale(lsr, mx->mat.m[4]);
  587. GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "yy");
  588. } else {
  589. GF_LSR_WRITE_INT(lsr, 0, 1, "xx_yy_present");
  590. }
  591. if (mx->mat.m[1] || mx->mat.m[3]) {
  592. GF_LSR_WRITE_INT(lsr, 1, 1, "xy_yx_present");
  593. res = lsr_translate_scale(lsr, mx->mat.m[1]);
  594. GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "xy");
  595. res = lsr_translate_scale(lsr, mx->mat.m[3]);
  596. GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "yx");
  597. } else {
  598. GF_LSR_WRITE_INT(lsr, 0, 1, "xy_yx_present");
  599. }
  600. if (mx->mat.m[2] || mx->mat.m[5]) {
  601. GF_LSR_WRITE_INT(lsr, 1, 1, "xz_yz_present");
  602. res = lsr_translate_coords(lsr, mx->mat.m[2], lsr->coord_bits);
  603. GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "xz");
  604. res = lsr_translate_coords(lsr, mx->mat.m[5], lsr->coord_bits);
  605. GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "yz");
  606. } else {
  607. GF_LSR_WRITE_INT(lsr, 0, 1, "xz_yz_present");
  608. }
  609. lsr->coord_bits -= lsr->scale_bits;
  610. }
  611. }
  612. static void lsr_write_fixed_clamp(GF_LASeRCodec *lsr, Fixed f, const char *name)
  613. {
  614. #ifdef GPAC_FIXED_POINT
  615. s32 val = f >> 8;
  616. #else
  617. s32 val = (u32) (255 * f);
  618. #endif
  619. if (val<0) val = 0;
  620. else if (val>255) val = 255;
  621. GF_LSR_WRITE_INT(lsr, (u32) val, 8, name);
  622. }
  623. u32 dom_to_lsr_key(u32 dom_k)
  624. {
  625. switch (dom_k) {
  626. case GF_KEY_STAR: return 0;
  627. case GF_KEY_0: return 1;
  628. case GF_KEY_1: return 2;
  629. case GF_KEY_2: return 3;
  630. case GF_KEY_3: return 4;
  631. case GF_KEY_4: return 5;
  632. case GF_KEY_5: return 6;
  633. case GF_KEY_6: return 7;
  634. case GF_KEY_7: return 8;
  635. case GF_KEY_8: return 9;
  636. case GF_KEY_9: return 10;
  637. case GF_KEY_DOWN: return 12;
  638. case GF_KEY_LEFT: return 14;
  639. case GF_KEY_RIGHT: return 16;
  640. case GF_KEY_UP: return 20;
  641. /*WHAT IS ANY_KEY (11) ??*/
  642. case GF_KEY_ENTER:
  643. case GF_KEY_EXECUTE:
  644. return 13;
  645. case GF_KEY_ESCAPE:
  646. return 15;
  647. case GF_KEY_NUMBER:
  648. return 17;
  649. case GF_KEY_CELL_SOFT1:
  650. return 18;
  651. case GF_KEY_CELL_SOFT2:
  652. return 19;
  653. default:
  654. return 100;
  655. }
  656. }
  657. static void lsr_write_event_type(GF_LASeRCodec *lsr, u32 evtType, u32 evtParam)
  658. {
  659. Bool force_string = 0;
  660. switch (evtType) {
  661. case GF_EVENT_KEYDOWN:
  662. case GF_EVENT_LONGKEYPRESS:
  663. case GF_EVENT_REPEAT_KEY:
  664. case GF_EVENT_SHORT_ACCESSKEY:
  665. if (dom_to_lsr_key(evtParam)==100) force_string = 2;
  666. break;
  667. case GF_EVENT_BEGIN:
  668. case GF_EVENT_END:
  669. force_string = 1;
  670. break;
  671. case GF_EVENT_REPEAT:
  672. force_string = 1;
  673. break;
  674. }
  675. if (force_string) {
  676. char szName[1024];
  677. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  678. if (evtParam) {
  679. if (force_string==2) {
  680. sprintf(szName, "%s(%s)", gf_dom_event_get_name(evtType), gf_dom_get_key_name(evtParam) );
  681. } else {
  682. sprintf(szName, "%s(%d)", gf_dom_event_get_name(evtType), evtParam);
  683. }
  684. } else {
  685. sprintf(szName, "%s", gf_dom_event_get_name(evtType));
  686. }
  687. lsr_write_byte_align_string(lsr, szName, "evtString");
  688. } else {
  689. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  690. switch (evtType) {
  691. case GF_EVENT_ABORT:
  692. GF_LSR_WRITE_INT(lsr, LSR_EVT_abort, 6, "event"); break;
  693. case GF_EVENT_ACTIVATE:
  694. GF_LSR_WRITE_INT(lsr, LSR_EVT_activate, 6, "event"); break;
  695. case GF_EVENT_ACTIVATED:
  696. GF_LSR_WRITE_INT(lsr, LSR_EVT_activatedEvent, 6, "event"); break;
  697. case GF_EVENT_BEGIN:/*SPEC IS BROKEN, CANNOT ENCODE elt.begin !! */
  698. case GF_EVENT_BEGIN_EVENT:
  699. GF_LSR_WRITE_INT(lsr, LSR_EVT_beginEvent, 6, "event"); break;
  700. case GF_EVENT_CLICK:
  701. GF_LSR_WRITE_INT(lsr, LSR_EVT_click, 6, "event"); break;
  702. case GF_EVENT_DEACTIVATED:
  703. GF_LSR_WRITE_INT(lsr, LSR_EVT_deactivatedEvent, 6, "event"); break;
  704. case GF_EVENT_END:/*SPEC IS BROKEN, CANNOT ENCODE elt.end !! */
  705. case GF_EVENT_END_EVENT:
  706. GF_LSR_WRITE_INT(lsr, LSR_EVT_endEvent, 6, "event"); break;
  707. case GF_EVENT_ERROR:
  708. GF_LSR_WRITE_INT(lsr, LSR_EVT_error, 6, "event"); break;
  709. case GF_EVENT_EXECUTION_TIME:
  710. GF_LSR_WRITE_INT(lsr, LSR_EVT_executionTime, 6, "event"); break;
  711. case GF_EVENT_FOCUSIN:
  712. GF_LSR_WRITE_INT(lsr, LSR_EVT_focusin, 6, "event"); break;
  713. case GF_EVENT_FOCUSOUT:
  714. GF_LSR_WRITE_INT(lsr, LSR_EVT_focusout, 6, "event"); break;
  715. case GF_EVENT_KEYDOWN:
  716. /*encode as accessKey() if param*/
  717. GF_LSR_WRITE_INT(lsr, evtParam ? LSR_EVT_accessKey : LSR_EVT_keydown, 6, "event");
  718. break;
  719. case GF_EVENT_KEYUP:
  720. GF_LSR_WRITE_INT(lsr, LSR_EVT_keyup, 6, "event"); break;
  721. case GF_EVENT_LOAD:
  722. GF_LSR_WRITE_INT(lsr, LSR_EVT_load, 6, "event"); break;
  723. case GF_EVENT_LONGKEYPRESS:
  724. GF_LSR_WRITE_INT(lsr, LSR_EVT_longAccessKey, 6, "event"); break;
  725. case GF_EVENT_MOUSEDOWN:
  726. GF_LSR_WRITE_INT(lsr, LSR_EVT_mousedown, 6, "event"); break;
  727. case GF_EVENT_MOUSEMOVE:
  728. GF_LSR_WRITE_INT(lsr, LSR_EVT_mousemove, 6, "event"); break;
  729. case GF_EVENT_MOUSEOUT:
  730. GF_LSR_WRITE_INT(lsr, LSR_EVT_mouseout, 6, "event"); break;
  731. case GF_EVENT_MOUSEOVER:
  732. GF_LSR_WRITE_INT(lsr, LSR_EVT_mouseover, 6, "event"); break;
  733. case GF_EVENT_MOUSEUP:
  734. GF_LSR_WRITE_INT(lsr, LSR_EVT_mouseup, 6, "event"); break;
  735. case GF_EVENT_PAUSE:
  736. GF_LSR_WRITE_INT(lsr, LSR_EVT_pause, 6, "event"); break;
  737. case GF_EVENT_PAUSED_EVENT:
  738. GF_LSR_WRITE_INT(lsr, LSR_EVT_pausedEvent, 6, "event"); break;
  739. case GF_EVENT_PLAY:
  740. GF_LSR_WRITE_INT(lsr, LSR_EVT_play, 6, "event"); break;
  741. case GF_EVENT_REPEAT_EVENT:
  742. GF_LSR_WRITE_INT(lsr, LSR_EVT_repeatEvent, 6, "event"); break;
  743. case GF_EVENT_REPEAT_KEY:
  744. GF_LSR_WRITE_INT(lsr, LSR_EVT_repeatKey, 6, "event"); break;
  745. case GF_EVENT_RESIZE:
  746. GF_LSR_WRITE_INT(lsr, LSR_EVT_resize, 6, "event"); break;
  747. case GF_EVENT_RESUME_EVENT:
  748. GF_LSR_WRITE_INT(lsr, LSR_EVT_resumedEvent, 6, "event"); break;
  749. case GF_EVENT_SCROLL:
  750. GF_LSR_WRITE_INT(lsr, LSR_EVT_scroll, 6, "event"); break;
  751. case GF_EVENT_SHORT_ACCESSKEY:
  752. GF_LSR_WRITE_INT(lsr, LSR_EVT_shortAccessKey, 6, "event"); break;
  753. case GF_EVENT_TEXTINPUT:
  754. GF_LSR_WRITE_INT(lsr, LSR_EVT_textinput, 6, "event"); break;
  755. case GF_EVENT_UNLOAD:
  756. GF_LSR_WRITE_INT(lsr, LSR_EVT_unload, 6, "event"); break;
  757. case GF_EVENT_ZOOM:
  758. GF_LSR_WRITE_INT(lsr, LSR_EVT_zoom, 6, "event"); break;
  759. default:
  760. GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] Unsupported LASER event %d\n", evtType) );
  761. GF_LSR_WRITE_INT(lsr, 0, 6, "event"); break;
  762. return;
  763. }
  764. switch (evtType) {
  765. case GF_EVENT_KEYDOWN:
  766. if (!evtParam) break;
  767. case GF_EVENT_LONGKEYPRESS:
  768. case GF_EVENT_REPEAT_KEY:
  769. case GF_EVENT_SHORT_ACCESSKEY:
  770. lsr_write_vluimsbf5(lsr, dom_to_lsr_key(evtParam), "keyCode");
  771. break;
  772. }
  773. }
  774. }
  775. static void lsr_write_smil_time(GF_LASeRCodec *lsr, SMIL_Time *t)
  776. {
  777. s32 now;
  778. if (t->type==GF_SMIL_TIME_EVENT) {
  779. GF_LSR_WRITE_INT(lsr, 1, 1, "hasEvent");
  780. if (t->element && gf_node_get_id((GF_Node*)t->element) ) {
  781. XMLRI iri;
  782. GF_LSR_WRITE_INT(lsr, 1, 1, "hasIdentifier");
  783. iri.string = NULL;
  784. iri.type = XMLRI_ELEMENTID;
  785. iri.target = t->element;
  786. lsr_write_codec_IDREF(lsr, &iri, "idref");
  787. } else {
  788. GF_LSR_WRITE_INT(lsr, 0, 1, "hasIdentifier");
  789. }
  790. lsr_write_event_type(lsr, t->event.type, t->event.parameter);
  791. } else {
  792. GF_LSR_WRITE_INT(lsr, 0, 1, "hasEvent");
  793. }
  794. if (!t->clock) {
  795. GF_LSR_WRITE_INT(lsr, 0, 1, "hasClock");
  796. return;
  797. }
  798. GF_LSR_WRITE_INT(lsr, 1, 1, "hasClock");
  799. now = (s32) (t->clock * lsr->time_resolution);
  800. if (now<0) {
  801. now = -now;
  802. GF_LSR_WRITE_INT(lsr, 1, 1, "sign");
  803. } else {
  804. GF_LSR_WRITE_INT(lsr, 0, 1, "sign");
  805. }
  806. lsr_write_vluimsbf5(lsr, now, "value");
  807. }
  808. static void lsr_write_smil_times(GF_LASeRCodec *lsr, GF_List **l, const char *name, Bool skipable)
  809. {
  810. SMIL_Time *v;
  811. u32 r_count, i, count;
  812. Bool indef = 0;
  813. count = l ? gf_list_count(*l) : 0;
  814. r_count = 0;
  815. for (i=0; i<count; i++) {
  816. v = (SMIL_Time*)gf_list_get(*l, i);
  817. if (v->type==GF_SMIL_TIME_INDEFINITE) {
  818. indef = 1;
  819. break;
  820. }
  821. else if (v->type!=GF_SMIL_TIME_EVENT_RESOLVED) r_count++;
  822. }
  823. if (skipable && !r_count && !indef) {
  824. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  825. return;
  826. }
  827. if (skipable) GF_LSR_WRITE_INT(lsr, 1, 1, name);
  828. GF_LSR_WRITE_INT(lsr, indef, 1, "choice");
  829. if (indef) return;
  830. lsr_write_vluimsbf5(lsr, r_count, "count");
  831. for (i=0; i<count; i++) {
  832. v = (SMIL_Time*)gf_list_get(*l, i);
  833. lsr_write_smil_time(lsr, v);
  834. }
  835. }
  836. static void lsr_write_duration_ex(GF_LASeRCodec *lsr, SMIL_Duration *v, const char *name, Bool skipable)
  837. {
  838. if (skipable) {
  839. if (!v || !v->type) {
  840. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  841. return;
  842. }
  843. GF_LSR_WRITE_INT(lsr, 1, 1, name);
  844. }
  845. if (v->type==SMIL_DURATION_DEFINED) {
  846. s32 now = (s32) (v->clock_value * lsr->time_resolution);
  847. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  848. GF_LSR_WRITE_INT(lsr, (now<0) ? 1 : 0, 1, "sign");
  849. if (now<0) now = -now;
  850. lsr_write_vluimsbf5(lsr, now, "value");
  851. } else {
  852. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  853. GF_LSR_WRITE_INT(lsr, v->type, 2, "time");
  854. }
  855. }
  856. #define lsr_write_duration(a, b, c) lsr_write_duration_ex(a, b, c, 1)
  857. static void lsr_write_focus(GF_LASeRCodec *lsr, SVG_Focus *foc, const char *name)
  858. {
  859. if (foc->type==SVG_FOCUS_IRI) {
  860. GF_LSR_WRITE_INT(lsr, 0, 1, "isEnum");
  861. lsr_write_codec_IDREF(lsr, &foc->target, "id");
  862. } else {
  863. GF_LSR_WRITE_INT(lsr, 1, 1, "isEnum");
  864. GF_LSR_WRITE_INT(lsr, foc->type, 1, "enum");
  865. }
  866. }
  867. static Bool lsr_elt_has_same_base(GF_LASeRCodec *lsr, SVGAllAttributes *atts, SVG_Element *base, Bool *same_fill, Bool *same_stroke, Bool no_stroke_check)
  868. {
  869. SVGAllAttributes base_atts;
  870. GF_FieldInfo info, base_info;
  871. if (same_stroke) *same_stroke = 0;
  872. if (same_fill) *same_fill = 0;
  873. if (!base) return 0;
  874. gf_svg_flatten_attributes(base, &base_atts);
  875. if (atts->externalResourcesRequired != base_atts.externalResourcesRequired) return 0;
  876. info.fieldType = base_info.fieldType = SVG_Paint_datatype;
  877. info.far_ptr = atts->stroke;
  878. base_info.far_ptr = base_atts.stroke;
  879. /*check stroke color*/
  880. if (!gf_svg_attributes_equal(&info, &base_info)) {
  881. if (!no_stroke_check) return 0;
  882. } else {
  883. if (same_stroke) *same_stroke = 1;
  884. }
  885. if (same_fill) {
  886. info.fieldType = base_info.fieldType = SVG_Paint_datatype;
  887. info.far_ptr = atts->fill;
  888. base_info.far_ptr = base_atts.fill;
  889. /*check stroke color*/
  890. *same_fill = gf_svg_attributes_equal(&info, &base_info) ? 1 : 0;
  891. }
  892. switch (gf_node_get_tag((GF_Node*) base)) {
  893. /*check path length*/
  894. case TAG_SVG_path:
  895. info.fieldType = base_info.fieldType = SVG_Number_datatype;
  896. info.far_ptr = atts->pathLength;
  897. base_info.far_ptr = base_atts.pathLength;
  898. if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
  899. break;
  900. /*check rx and ry for rect*/
  901. case TAG_SVG_rect:
  902. info.fieldType = base_info.fieldType = SVG_Length_datatype;
  903. info.far_ptr = atts->rx;
  904. base_info.far_ptr = base_atts.rx;
  905. if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
  906. info.fieldType = base_info.fieldType = SVG_Length_datatype;
  907. info.far_ptr = atts->ry;
  908. base_info.far_ptr = base_atts.ry;
  909. if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
  910. break;
  911. /*check x and y for use*/
  912. case TAG_SVG_use:
  913. info.fieldType = base_info.fieldType = SVG_Coordinate_datatype;
  914. info.far_ptr = atts->x;
  915. base_info.far_ptr = base_atts.x;
  916. if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
  917. info.fieldType = base_info.fieldType = SVG_Coordinate_datatype;
  918. info.far_ptr = atts->y;
  919. base_info.far_ptr = base_atts.y;
  920. if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
  921. break;
  922. /*check editable and rotate for text*/
  923. case TAG_SVG_text:
  924. info.fieldType = base_info.fieldType = SVG_Boolean_datatype;
  925. info.far_ptr = atts->editable;
  926. base_info.far_ptr = base_atts.editable;
  927. if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
  928. info.fieldType = base_info.fieldType = SVG_Numbers_datatype;
  929. info.far_ptr = atts->text_rotate;
  930. base_info.far_ptr = base_atts.text_rotate;
  931. if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
  932. break;
  933. }
  934. return gf_lsr_same_rare(atts, &base_atts);
  935. }
  936. static void lsr_write_rare(GF_LASeRCodec *lsr, GF_Node *n)
  937. {
  938. u32 i, nb_rare;
  939. s32 field_rare;
  940. SVGAttribute *att;
  941. nb_rare = 0;
  942. att = ((SVG_Element*)n)->attributes;
  943. while (att) {
  944. field_rare = gf_lsr_rare_type_from_attribute(att->tag);
  945. if (field_rare>=0) nb_rare++;
  946. att = att->next;
  947. }
  948. GF_LSR_WRITE_INT(lsr, nb_rare ? 1 : 0, 1, "has_rare");
  949. if (!nb_rare) return;
  950. GF_LSR_WRITE_INT(lsr, nb_rare, 6, "nbOfAttributes");
  951. att = ((SVG_Element*)n)->attributes;
  952. while (att) {
  953. field_rare = gf_lsr_rare_type_from_attribute(att->tag);
  954. if (field_rare==-1) {
  955. att = att->next;
  956. continue;
  957. }
  958. /*RARE extension*/
  959. if (field_rare==49) {
  960. Bool is_string = 0;
  961. u32 size, cur_bits;
  962. u32 len = 2+3;
  963. switch (att->tag) {
  964. case TAG_SVG_ATT_syncMaster: len +=1; break;
  965. case TAG_SVG_ATT_requiredFonts:
  966. len += 8 * (u32) strlen(*(SVG_String*)att->data);
  967. /*get vluimsbf5 field size with one extra word (4 bits, enough to code string alignment)*/
  968. size = lsr_get_vluimsbf5_size(len, 1);
  969. cur_bits = gf_bs_get_bit_position(lsr->bs) + lsr->info->cfg.extensionIDBits + size + 5;
  970. /*count string alignment*/
  971. while (cur_bits%8) {
  972. len++;
  973. cur_bits++;
  974. }
  975. is_string = 1;
  976. break;
  977. default: len +=2; break;
  978. }
  979. GF_LSR_WRITE_INT(lsr, 49, 6, "attributeRARE");
  980. GF_LSR_WRITE_INT(lsr, 2, lsr->info->cfg.extensionIDBits, "extensionID");
  981. if (is_string) {
  982. lsr_write_vluimsbf5_ex(lsr, len, 1, "len");
  983. } else {
  984. lsr_write_vluimsbf5(lsr, len, "len");
  985. }
  986. GF_LSR_WRITE_INT(lsr, 1, 2, "nbOfAttributes");
  987. switch (att->tag) {
  988. case TAG_SVG_ATT_syncMaster:
  989. GF_LSR_WRITE_INT(lsr, 0, 3, "attributeRARE");
  990. GF_LSR_WRITE_INT(lsr, *(SVG_Boolean *)att->data ? 1 : 0, 1, "syncMaster");
  991. break;
  992. case TAG_SVG_ATT_focusHighlight:
  993. GF_LSR_WRITE_INT(lsr, 1, 3, "attributeRARE");
  994. GF_LSR_WRITE_INT(lsr, *(SVG_FocusHighlight*)att->data, 2, "focusHighlight");
  995. break;
  996. case TAG_SVG_ATT_initialVisibility:
  997. GF_LSR_WRITE_INT(lsr, 2, 3, "attributeRARE");
  998. GF_LSR_WRITE_INT(lsr, *(SVG_InitialVisibility*)att->data, 2, "initialVisibility");
  999. break;
  1000. case TAG_SVG_ATT_fullscreen:
  1001. GF_LSR_WRITE_INT(lsr, 3, 3, "attributeRARE");
  1002. GF_LSR_WRITE_INT(lsr, *(SVG_Boolean *)att->data ? 1 : 0, 2, "fullscreen");
  1003. break;
  1004. case TAG_SVG_ATT_requiredFonts:
  1005. GF_LSR_WRITE_INT(lsr, 4, 3, "attributeRARE");
  1006. lsr_write_byte_align_string(lsr, *(SVG_String*)att->data, "requiredFonts");
  1007. break;
  1008. }
  1009. GF_LSR_WRITE_INT(lsr, 0, 1, "hasNextExtension");
  1010. att = att->next;
  1011. continue;
  1012. }
  1013. GF_LSR_WRITE_INT(lsr, (u32)field_rare, 6, "attributeRARE");
  1014. switch (att->tag) {
  1015. case TAG_SVG_ATT__class: lsr_write_byte_align_string(lsr, *(SVG_String *)att->data, "class"); break;
  1016. case TAG_SVG_ATT_audio_level: lsr_write_fixed_clamp(lsr, ((SVG_Number *) att->data)->value, "audio-level"); break;
  1017. case TAG_SVG_ATT_color: lsr_write_paint(lsr, (SVG_Paint*) att->data, "color"); break;
  1018. case TAG_SVG_ATT_color_rendering: GF_LSR_WRITE_INT(lsr, *(SVG_RenderingHint*)att->data, 2, "color-rendering"); break;
  1019. case TAG_SVG_ATT_display: GF_LSR_WRITE_INT(lsr, *(SVG_Display*)att->data, 5, "display"); break;
  1020. case TAG_SVG_ATT_display_align: GF_LSR_WRITE_INT(lsr, *(SVG_DisplayAlign*)att->data, 3, "display-align"); break;
  1021. case TAG_SVG_ATT_fill_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "fill-opacity"); break;
  1022. case TAG_SVG_ATT_fill_rule: GF_LSR_WRITE_INT(lsr, *(SVG_FillRule*)att->data, 2, "fill-rule"); break;
  1023. case TAG_SVG_ATT_image_rendering: GF_LSR_WRITE_INT(lsr, *(SVG_RenderingHint*)att->data, 2, "image-rendering"); break;
  1024. case TAG_SVG_ATT_line_increment: lsr_write_line_increment_type(lsr, (SVG_Number*)att->data, "lineIncrement"); break;
  1025. case TAG_SVG_ATT_pointer_events: GF_LSR_WRITE_INT(lsr, *(SVG_PointerEvents*)att->data, 4, "pointer-events"); break;
  1026. case TAG_SVG_ATT_shape_rendering: GF_LSR_WRITE_INT(lsr, *(SVG_RenderingHint*)att->data, 3, "shape-rendering"); break;
  1027. case TAG_SVG_ATT_solid_color: lsr_write_paint(lsr, (SVG_Paint*)att->data, "solid-color"); break;
  1028. case TAG_SVG_ATT_solid_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "solid-opacity"); break;
  1029. case TAG_SVG_ATT_stop_color: lsr_write_paint(lsr, (SVG_Paint*)att->data, "stop-color"); break;
  1030. case TAG_SVG_ATT_stop_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "stop-opacity"); break;
  1031. case TAG_SVG_ATT_stroke_dasharray:
  1032. {
  1033. u32 j;
  1034. SVG_StrokeDashArray *da = (SVG_StrokeDashArray*)att->data;
  1035. if (da->type==SVG_STROKEDASHARRAY_INHERIT) {
  1036. GF_LSR_WRITE_INT(lsr, 1, 1, "dashArray");
  1037. } else {
  1038. GF_LSR_WRITE_INT(lsr, 0, 1, "dashArray");
  1039. lsr_write_vluimsbf5(lsr, da->array.count, "len");
  1040. for (j=0; j<da->array.count; j++) {
  1041. lsr_write_fixed_16_8(lsr, da->array.vals[j], "dash");
  1042. }
  1043. }
  1044. }
  1045. break;
  1046. case TAG_SVG_ATT_stroke_dashoffset:
  1047. lsr_write_fixed_16_8i(lsr, (SVG_Number*)att->data, "dashOffset"); break;
  1048. case TAG_SVG_ATT_stroke_linecap: GF_LSR_WRITE_INT(lsr, *(SVG_StrokeLineCap*)att->data, 2, "stroke-linecap"); break;
  1049. case TAG_SVG_ATT_stroke_linejoin: GF_LSR_WRITE_INT(lsr, *(SVG_StrokeLineJoin*)att->data, 2, "stroke-linejoin"); break;
  1050. case TAG_SVG_ATT_stroke_miterlimit: lsr_write_fixed_16_8i(lsr, (SVG_Number*)att->data, "miterLimit"); break;
  1051. case TAG_SVG_ATT_stroke_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "stroke-opacity"); break;
  1052. case TAG_SVG_ATT_stroke_width: lsr_write_fixed_16_8i(lsr, (SVG_Number*)att->data, "strokeWidth"); break;
  1053. case TAG_SVG_ATT_text_anchor: GF_LSR_WRITE_INT(lsr, *(SVG_TextAnchor*)att->data, 2, "text-achor"); break;
  1054. case TAG_SVG_ATT_text_rendering: GF_LSR_WRITE_INT(lsr, *(SVG_RenderingHint*)att->data, 3, "text-rendering"); break;
  1055. case TAG_SVG_ATT_viewport_fill: lsr_write_paint(lsr, (SVG_Paint*)att->data, "viewport-fill"); break;
  1056. case TAG_SVG_ATT_viewport_fill_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "viewport-fill-opacity"); break;
  1057. case TAG_SVG_ATT_vector_effect: GF_LSR_WRITE_INT(lsr, *(SVG_VectorEffect*)att->data, 4, "vector-effect"); break;
  1058. case TAG_SVG_ATT_visibility: GF_LSR_WRITE_INT(lsr, *(SVG_PointerEvents*)att->data, 2, "visibility"); break;
  1059. case TAG_SVG_ATT_requiredExtensions: lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "requiredExtensions", 1); break;
  1060. case TAG_SVG_ATT_requiredFormats: lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "requiredFormats", 0); break;
  1061. case TAG_SVG_ATT_requiredFeatures:
  1062. {
  1063. GF_List *l = *(GF_List **)att->data;
  1064. u32 j, tot_count, count = gf_list_count(l);
  1065. u8 *vals = (u8*)gf_malloc(sizeof(u8)*count);
  1066. tot_count = 0;
  1067. for (i=0; i<count; i++) {
  1068. char *ext;
  1069. XMLRI *iri = (XMLRI*)gf_list_get(l, i);
  1070. if (iri->type != XMLRI_STRING) continue;
  1071. ext = strchr(iri->string, '#');
  1072. if (!ext) continue;
  1073. if (!stricmp(ext, "Animation")) { vals[tot_count] = 0; tot_count++; }
  1074. else if (!stricmp(ext, "Audio")) { vals[tot_count] = 1; tot_count++; }
  1075. else if (!stricmp(ext, "ComposedVideo")) { vals[tot_count] = 2; tot_count++; }
  1076. else if (!stricmp(ext, "ConditionalProcessing")) { vals[tot_count] = 3; tot_count++; }
  1077. else if (!stricmp(ext, "ConditionalProcessingAttribute")) { vals[tot_count] = 4; tot_count++; }
  1078. else if (!stricmp(ext, "CoreAttribute")) { vals[tot_count] = 5; tot_count++; }
  1079. else if (!stricmp(ext, "Extensibility")) { vals[tot_count] = 6; tot_count++; }
  1080. else if (!stricmp(ext, "ExternalResourcesRequired")) { vals[tot_count] = 7; tot_count++; }
  1081. else if (!stricmp(ext, "Font")) { vals[tot_count] = 8; tot_count++; }
  1082. else if (!stricmp(ext, "Gradient")) { vals[tot_count] = 9; tot_count++; }
  1083. else if (!stricmp(ext, "GraphicsAttribute")) { vals[tot_count] = 10; tot_count++; }
  1084. else if (!stricmp(ext, "Handler")) { vals[tot_count] = 11; tot_count++; }
  1085. else if (!stricmp(ext, "Hyperlinking")) { vals[tot_count] = 12; tot_count++; }
  1086. else if (!stricmp(ext, "Image")) { vals[tot_count] = 13; tot_count++; }
  1087. else if (!stricmp(ext, "OpacityAttribute")) { vals[tot_count] = 14; tot_count++; }
  1088. else if (!stricmp(ext, "PaintAttribute")) { vals[tot_count] = 15; tot_count++; }
  1089. else if (!stricmp(ext, "Prefetch")) { vals[tot_count] = 16; tot_count++; }
  1090. else if (!stricmp(ext, "SVG")) { vals[tot_count] = 17; tot_count++; }
  1091. else if (!stricmp(ext, "SVG-animation")) { vals[tot_count] = 18; tot_count++; }
  1092. else if (!stricmp(ext, "SVG-dynamic")) { vals[tot_count] = 19; tot_count++; }
  1093. else if (!stricmp(ext, "SVG-static")) { vals[tot_count] = 20; tot_count++; }
  1094. else if (!stricmp(ext, "SVGDOM")) { vals[tot_count] = 21; tot_count++; }
  1095. else if (!stricmp(ext, "SVGDOM-animation")) { vals[tot_count] = 22; tot_count++; }
  1096. else if (!stricmp(ext, "SVGDOM-dynamic")) { vals[tot_count] = 23; tot_count++; }
  1097. else if (!stricmp(ext, "SVGDOM-static")) { vals[tot_count] = 24; tot_count++; }
  1098. else if (!stricmp(ext, "Script")) { vals[tot_count] = 25; tot_count++; }
  1099. else if (!stricmp(ext, "Shape")) { vals[tot_count] = 26; tot_count++; }
  1100. else if (!stricmp(ext, "SolidColor")) { vals[tot_count] = 27; tot_count++; }
  1101. else if (!stricmp(ext, "Structure")) { vals[tot_count] = 28; tot_count++; }
  1102. else if (!stricmp(ext, "Text")) { vals[tot_count] = 29; tot_count++; }
  1103. else if (!stricmp(ext, "TimedAnimation")) { vals[tot_count] = 30; tot_count++; }
  1104. else if (!stricmp(ext, "TransformedVideo")) { vals[tot_count] = 31; tot_count++; }
  1105. else if (!stricmp(ext, "Video")) { vals[tot_count] = 32; tot_count++; }
  1106. else if (!stricmp(ext, "XlinkAttribute")) { vals[tot_count] = 33; tot_count++; }
  1107. }
  1108. lsr_write_vluimsbf5(lsr, tot_count, "len");
  1109. for (j=0; j<tot_count; j++) {
  1110. GF_LSR_WRITE_INT(lsr, vals[j], 6, "feature");
  1111. }
  1112. gf_free(vals);
  1113. }
  1114. break;
  1115. case TAG_SVG_ATT_systemLanguage:
  1116. lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "systemLanguage", 0);
  1117. break;
  1118. case TAG_XML_ATT_base: lsr_write_byte_align_string(lsr, ((XMLRI*)att->data)->string, "xml:base"); break;
  1119. case TAG_XML_ATT_lang: lsr_write_byte_align_string(lsr, *(SVG_String *)att->data, "xml:lang"); break;
  1120. case TAG_XML_ATT_space: GF_LSR_WRITE_INT(lsr, *(XML_Space *)att->data, 1, "xml:space"); break;
  1121. case TAG_SVG_ATT_nav_next: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusNext"); break;
  1122. case TAG_SVG_ATT_nav_up: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusNorth"); break;
  1123. case TAG_SVG_ATT_nav_up_left: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusNorthEast"); break;
  1124. case TAG_SVG_ATT_nav_up_right: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusNorthWest"); break;
  1125. case TAG_SVG_ATT_nav_prev: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusPrev"); break;
  1126. case TAG_SVG_ATT_nav_down: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusSouth"); break;
  1127. case TAG_SVG_ATT_nav_down_left: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusSouthEast"); break;
  1128. case TAG_SVG_ATT_nav_down_right: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusSouthWest"); break;
  1129. case TAG_SVG_ATT_nav_right: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusWest"); break;
  1130. case TAG_SVG_ATT_nav_left: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusEast"); break;
  1131. case TAG_SVG_ATT_font_variant: GF_LSR_WRITE_INT(lsr, *(SVG_FontVariant *)att->data, 2, "font-variant"); break;
  1132. case TAG_SVG_ATT_font_family:
  1133. {
  1134. s32 idx = lsr_get_font_index(lsr, (SVG_FontFamily*)att->data);
  1135. if (idx<0) {
  1136. GF_LSR_WRITE_INT(lsr, 1, 1, "isInherit");
  1137. } else {
  1138. GF_LSR_WRITE_INT(lsr, 0, 1, "isInherit");
  1139. GF_LSR_WRITE_INT(lsr, idx, lsr->fontIndexBits, "fontIndex");
  1140. }
  1141. }
  1142. break;
  1143. case TAG_SVG_ATT_font_size: lsr_write_fixed_16_8i(lsr, (SVG_Number*)att->data, "fontSize"); break;
  1144. case TAG_SVG_ATT_font_style: GF_LSR_WRITE_INT(lsr, *((SVG_FontStyle *)att->data), 3, "fontStyle"); break;
  1145. case TAG_SVG_ATT_font_weight: GF_LSR_WRITE_INT(lsr, *((SVG_FontWeight *)att->data), 4, "fontWeight"); break;
  1146. case TAG_XLINK_ATT_title: lsr_write_byte_align_string(lsr, *(SVG_String *)att->data, "xlink:title"); break;
  1147. /*TODO FIXME*/
  1148. case TAG_XLINK_ATT_type: GF_LSR_WRITE_INT(lsr, 0, 3, "xlink:type"); break;
  1149. case TAG_XLINK_ATT_role: lsr_write_any_uri(lsr, (XMLRI*)att->data, "xlink:role"); break;
  1150. case TAG_XLINK_ATT_arcrole: lsr_write_any_uri(lsr, (XMLRI*)att->data, "xlink:arcrole"); break;
  1151. /*TODO FIXME*/
  1152. case TAG_XLINK_ATT_actuate: GF_LSR_WRITE_INT(lsr, 0, 2, "xlink:actuate"); break;
  1153. case TAG_XLINK_ATT_show: GF_LSR_WRITE_INT(lsr, 0, 3, "xlink:show"); break;
  1154. case TAG_SVG_ATT_end: lsr_write_smil_times(lsr, (GF_List **)att->data, "end", 0); break;
  1155. case TAG_SVG_ATT_min: lsr_write_duration_ex(lsr, (SMIL_Duration*)att->data, "min", 0); break;
  1156. case TAG_SVG_ATT_max: lsr_write_duration_ex(lsr, (SMIL_Duration*)att->data, "max", 0); break;
  1157. case TAG_SVG_ATT_transform: lsr_write_matrix(lsr, (SVG_Transform*)att->data); break;
  1158. }
  1159. att = att->next;
  1160. }
  1161. }
  1162. static void lsr_write_fill(GF_LASeRCodec *lsr, SVG_Element *n, SVGAllAttributes *atts)
  1163. {
  1164. if (atts->fill) {
  1165. GF_LSR_WRITE_INT(lsr, 1, 1, "fill");
  1166. lsr_write_paint(lsr, atts->fill, "fill");
  1167. } else {
  1168. GF_LSR_WRITE_INT(lsr, 0, 1, "fill");
  1169. }
  1170. }
  1171. static void lsr_write_stroke(GF_LASeRCodec *lsr, SVG_Element *n, SVGAllAttributes *atts)
  1172. {
  1173. if (atts->stroke) {
  1174. GF_LSR_WRITE_INT(lsr, 1, 1, "has_stroke");
  1175. lsr_write_paint(lsr, atts->stroke, "stroke");
  1176. } else {
  1177. GF_LSR_WRITE_INT(lsr, 0, 1, "has_stroke");
  1178. }
  1179. }
  1180. static void lsr_write_href(GF_LASeRCodec *lsr, XMLRI *iri)
  1181. {
  1182. Bool has_href = iri ? 1 : 0;
  1183. if (iri) {
  1184. if (iri->type==XMLRI_ELEMENTID) {
  1185. if (!iri->target && iri->string) iri->target = (SVG_Element *)gf_sg_find_node_by_name(lsr->sg, iri->string+1);
  1186. if (!iri->target || !gf_node_get_id((GF_Node *)iri->target)) has_href = 0;
  1187. }
  1188. else if (iri->type==XMLRI_STREAMID) {
  1189. if (!iri->lsr_stream_id) has_href = 0;
  1190. }
  1191. else if (!iri->string) has_href = 0;
  1192. }
  1193. GF_LSR_WRITE_INT(lsr, has_href, 1, "has_href");
  1194. if (has_href) lsr_write_any_uri(lsr, iri, "href");
  1195. }
  1196. static void lsr_write_accumulate(GF_LASeRCodec *lsr, SMIL_Accumulate *accum_type)
  1197. {
  1198. GF_LSR_WRITE_INT(lsr, accum_type ? 1 : 0, 1, "has_accumulate");
  1199. if (accum_type) GF_LSR_WRITE_INT(lsr, *accum_type, 1, "accumulate");
  1200. }
  1201. static void lsr_write_additive(GF_LASeRCodec *lsr, SMIL_Additive *add_type)
  1202. {
  1203. GF_LSR_WRITE_INT(lsr, add_type ? 1 : 0, 1, "has_additive");
  1204. if (add_type) GF_LSR_WRITE_INT(lsr, *add_type, 1, "additive");
  1205. }
  1206. static void lsr_write_calc_mode(GF_LASeRCodec *lsr, u8 *calc_mode)
  1207. {
  1208. /*SMIL_CALCMODE_LINEAR is default and 0 in our code*/
  1209. GF_LSR_WRITE_INT(lsr, (!calc_mode || (*calc_mode==SMIL_CALCMODE_LINEAR)) ? 0 : 1, 1, "has_calcMode");
  1210. if (calc_mode && (*calc_mode!=SMIL_CALCMODE_LINEAR)) {
  1211. GF_LSR_WRITE_INT(lsr, *calc_mode, 2, "calcMode");
  1212. }
  1213. }
  1214. static void lsr_write_animatable(GF_LASeRCodec *lsr, SMIL_AttributeName *anim_type, XMLRI *iri, const char *name)
  1215. {
  1216. s32 a_type = -1;
  1217. if (!anim_type || !iri || !iri->target) {
  1218. GF_LSR_WRITE_INT(lsr, 0, 1, "hasAttributeName");
  1219. return;
  1220. }
  1221. /*locate field - checkme, this may not work since anim is not setup...*/
  1222. assert(anim_type->name || anim_type->tag);
  1223. if (!anim_type->tag) anim_type->tag = gf_xml_get_attribute_tag((GF_Node*)iri->target, anim_type->name, 0);
  1224. if (!anim_type->type) anim_type->type = gf_xml_get_attribute_type(anim_type->tag);
  1225. a_type = gf_lsr_anim_type_from_attribute(anim_type->tag);
  1226. if (a_type<0) {
  1227. GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] Unsupported attributeName %s\n", anim_type->name));
  1228. }
  1229. GF_LSR_WRITE_INT(lsr, 1, 1, "hasAttributeName");
  1230. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  1231. GF_LSR_WRITE_INT(lsr, (u8) a_type, 8, "attributeType");
  1232. }
  1233. static void lsr_write_anim_fill(GF_LASeRCodec *lsr, u8 *animFreeze)
  1234. {
  1235. GF_LSR_WRITE_INT(lsr, animFreeze ? 1 : 0, 1, "has_smil_fill");
  1236. if (animFreeze) GF_LSR_WRITE_INT(lsr, *animFreeze, 1, "smil_fill");
  1237. }
  1238. static void lsr_write_anim_repeat(GF_LASeRCodec *lsr, SMIL_RepeatCount *repeat)
  1239. {
  1240. GF_LSR_WRITE_INT(lsr, repeat ? 1 : 0, 1, "has_repeatCount");
  1241. if (!repeat) return;
  1242. if (repeat->type==SMIL_REPEATCOUNT_DEFINED) {
  1243. GF_LSR_WRITE_INT(lsr, 0, 1, "repeatCount");
  1244. lsr_write_fixed_16_8(lsr, repeat->count, "repeatCount");
  1245. } else {
  1246. GF_LSR_WRITE_INT(lsr, 1, 1, "repeatCount");
  1247. /*enumeration indefinite{0}*/
  1248. }
  1249. }
  1250. static void lsr_write_repeat_duration(GF_LASeRCodec *lsr, SMIL_Duration *smil)
  1251. {
  1252. GF_LSR_WRITE_INT(lsr, smil ? 1 : 0, 1, "has_repeatDur");
  1253. if (!smil) return;
  1254. if (smil->type==SMIL_DURATION_DEFINED) {
  1255. u32 now = (u32) (smil->clock_value * lsr->time_resolution);
  1256. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  1257. lsr_write_vluimsbf5(lsr, now, "value");
  1258. } else {
  1259. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  1260. /*enumeration indefinite{0}*/
  1261. }
  1262. }
  1263. static void lsr_write_anim_restart(GF_LASeRCodec *lsr, u8 *animRestart)
  1264. {
  1265. GF_LSR_WRITE_INT(lsr, animRestart ? 1 : 0, 1, "has_restart");
  1266. /*enumeration always{0} never{1} whenNotActive{2}*/
  1267. if (animRestart) GF_LSR_WRITE_INT(lsr, *animRestart, 2, "restart");
  1268. }
  1269. static u32 svg_type_to_lsr_anim(u32 svg_type, u32 transform_type, GF_List *vals, void *a_val)
  1270. {
  1271. switch (svg_type) {
  1272. /*all string types*/
  1273. case DOM_String_datatype:
  1274. return 0;
  1275. /*all length types*/
  1276. case SVG_Number_datatype:
  1277. case SVG_FontSize_datatype:
  1278. case SVG_Length_datatype:
  1279. case SVG_Coordinate_datatype:
  1280. return 1;
  1281. case SVG_PathData_datatype:
  1282. return 2;
  1283. /*list of points*/
  1284. case SMIL_KeyPoints_datatype:
  1285. case SVG_Points_datatype:
  1286. return 3;
  1287. /*all 0 - 1 types*/
  1288. /*
  1289. case SVG_Opacity_datatype:
  1290. return 4;
  1291. */
  1292. case SVG_Paint_datatype:
  1293. return 5;
  1294. /*all enums (u8) types*/
  1295. case SVG_FillRule_datatype:
  1296. case SVG_StrokeLineJoin_datatype:
  1297. case SVG_StrokeLineCap_datatype:
  1298. case SVG_FontStyle_datatype:
  1299. case SVG_FontWeight_datatype:
  1300. case SVG_FontVariant_datatype:
  1301. case SVG_TextAnchor_datatype:
  1302. case SVG_TransformType_datatype:
  1303. case SVG_Display_datatype:
  1304. case SVG_Visibility_datatype:
  1305. case SVG_Overflow_datatype:
  1306. case SVG_ZoomAndPan_datatype:
  1307. case SVG_DisplayAlign_datatype:
  1308. case SVG_TextAlign_datatype:
  1309. case SVG_PointerEvents_datatype:
  1310. case SVG_RenderingHint_datatype:
  1311. case SVG_VectorEffect_datatype:
  1312. case SVG_PlaybackOrder_datatype:
  1313. case SVG_TimelineBegin_datatype:
  1314. return 6;
  1315. /*all list-of-int types*/ //return 7;
  1316. /*all list-of-float types*/
  1317. case SVG_StrokeDashArray_datatype:
  1318. case SVG_ViewBox_datatype:
  1319. case SVG_Coordinates_datatype:
  1320. return 8;
  1321. /*ID (u32) types*/ //return 10;
  1322. case SVG_FontFamily_datatype:
  1323. return 11;
  1324. case XMLRI_datatype:
  1325. return 12;
  1326. case SVG_Motion_datatype:
  1327. return 9;
  1328. /*ARG LOOKS LIKE THE SPEC IS BROKEN HERE*/
  1329. case SVG_Transform_Translate_datatype: return 9;
  1330. case SVG_Transform_Scale_datatype: return 8;
  1331. case SVG_Transform_Rotate_datatype:
  1332. if (vals) {
  1333. u32 i=0;
  1334. SVG_Point_Angle *pt;
  1335. while ((pt = (SVG_Point_Angle *) gf_list_enum(vals, &i))) {
  1336. if (pt->x || pt->y) return 8;
  1337. }
  1338. } else if (a_val) {
  1339. SVG_Point_Angle *pt = (SVG_Point_Angle *) a_val;
  1340. if (pt->x || pt->y) return 8;
  1341. }
  1342. return 1;
  1343. case SVG_Transform_SkewX_datatype: return 1;
  1344. case SVG_Transform_SkewY_datatype: return 1;
  1345. //case SVG_Transform_datatype: return;
  1346. /*FALL THROUH*/
  1347. default:
  1348. return 255;
  1349. }
  1350. }
  1351. static void lsr_write_coordinate(GF_LASeRCodec *lsr, Fixed val, Bool skipable, const char *name)
  1352. {
  1353. if (skipable && !val) {
  1354. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1355. } else {
  1356. u32 res = lsr_translate_coords(lsr, val, lsr->coord_bits);
  1357. if (skipable) GF_LSR_WRITE_INT(lsr, 1, 1, name);
  1358. GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, name);
  1359. }
  1360. }
  1361. static void lsr_write_coordinate_ptr(GF_LASeRCodec *lsr, SVG_Coordinate *val, Bool skipable, const char *name)
  1362. {
  1363. if (skipable && !val) {
  1364. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1365. } else {
  1366. u32 res = lsr_translate_coords(lsr, val ? val->value : 0, lsr->coord_bits);
  1367. if (skipable) GF_LSR_WRITE_INT(lsr, 1, 1, name);
  1368. GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, name);
  1369. }
  1370. }
  1371. static void lsr_write_an_anim_value(GF_LASeRCodec *lsr, void *val, u32 lsr_type, u32 svg_type, u32 transform_type, const char *name)
  1372. {
  1373. if ((lsr_type==1) || (lsr_type==4)) {
  1374. switch (svg_type) {
  1375. case SVG_Transform_Rotate_datatype:
  1376. case SVG_Transform_SkewX_datatype:
  1377. case SVG_Transform_SkewY_datatype:
  1378. GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag");
  1379. break;
  1380. default:
  1381. {
  1382. SVG_Number *n = (SVG_Number *) val;
  1383. if (n->type != SVG_NUMBER_VALUE) {
  1384. GF_LSR_WRITE_INT(lsr, 1, 1, "escapeFlag");
  1385. GF_LSR_WRITE_INT(lsr, n->type, 2, "escapeEnum");
  1386. } else {
  1387. GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag");
  1388. }
  1389. }
  1390. break;
  1391. }
  1392. } else if (svg_type==SVG_StrokeDashArray_datatype) {
  1393. SVG_StrokeDashArray *da = (SVG_StrokeDashArray *)val;
  1394. if (da->type==SVG_STROKEDASHARRAY_INHERIT) {
  1395. GF_LSR_WRITE_INT(lsr, 1, 1, "escapeFlag");
  1396. GF_LSR_WRITE_INT(lsr, 0, 2, "escapeEnum");
  1397. } else {
  1398. GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag");
  1399. }
  1400. } else {
  1401. GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag");
  1402. }
  1403. switch(lsr_type) {
  1404. case 0: lsr_write_byte_align_string(lsr, *(DOM_String *)val, name); break;
  1405. case 1:
  1406. if (svg_type==SVG_Transform_Rotate_datatype) {
  1407. Fixed angle = ((SVG_Point_Angle *) val)->angle;
  1408. angle = gf_muldiv(angle, INT2FIX(180), GF_PI);
  1409. lsr_write_fixed_16_8(lsr, angle, name);
  1410. } else if ((svg_type==SVG_Transform_SkewX_datatype) || (svg_type==SVG_Transform_SkewY_datatype)) {
  1411. lsr_write_fixed_16_8(lsr, *(Fixed *)val, name);
  1412. } else {
  1413. lsr_write_fixed_16_8(lsr, ((SVG_Number *) val)->value, name);
  1414. }
  1415. break;
  1416. case 12: lsr_write_any_uri(lsr, (XMLRI*)val, name); break;
  1417. case 2: lsr_write_path_type(lsr, (SVG_PathData*)val, name); break;
  1418. case 3: lsr_write_point_sequence(lsr, (GF_List **)val, name); break;
  1419. case 4: lsr_write_fixed_clamp(lsr, ((SVG_Number *) val)->value, name); break;
  1420. case 5: lsr_write_paint(lsr, (SVG_Paint*)val, name); break;
  1421. case 6: lsr_write_vluimsbf5(lsr, (u32) *(u8 *) val, name); break;
  1422. case 10: lsr_write_vluimsbf5(lsr, *(u32 *) val, name); break;
  1423. case 11:
  1424. {
  1425. s32 idx = lsr_get_font_index(lsr, (SVG_FontFamily*)val);
  1426. if (idx<0) {
  1427. GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] corrupted font table while encoding anim value\n"));
  1428. idx=0;
  1429. }
  1430. lsr_write_vluimsbf5(lsr, idx, name);
  1431. }
  1432. break;
  1433. case 7:
  1434. {
  1435. GF_List *l = *(GF_List **)val;
  1436. u32 i, count = gf_list_count(l);
  1437. lsr_write_vluimsbf5(lsr, count, "count");
  1438. for (i=0; i<count; i++) {
  1439. u8 *v = (u8 *)gf_list_get(l, i);
  1440. lsr_write_vluimsbf5(lsr, *v, "val");
  1441. }
  1442. }
  1443. break;
  1444. case 8: // floats
  1445. {
  1446. u32 i, count;
  1447. if (svg_type==SVG_StrokeDashArray_datatype) {
  1448. SVG_StrokeDashArray *da = (SVG_StrokeDashArray *)val;
  1449. lsr_write_vluimsbf5(lsr, da->array.count, "count");
  1450. for (i=0; i<da->array.count; i++) {
  1451. lsr_write_fixed_16_8(lsr, da->array.vals[i], "val");
  1452. }
  1453. } else if (svg_type==SVG_ViewBox_datatype) {
  1454. SVG_ViewBox *vb = (SVG_ViewBox *)val;
  1455. lsr_write_vluimsbf5(lsr, 4, "count");
  1456. lsr_write_fixed_16_8(lsr, vb->x, "val");
  1457. lsr_write_fixed_16_8(lsr, vb->y, "val");
  1458. lsr_write_fixed_16_8(lsr, vb->width, "val");
  1459. lsr_write_fixed_16_8(lsr, vb->height, "val");
  1460. } else if (svg_type==SVG_Coordinates_datatype) {
  1461. GF_List *l = *(GF_List **)val;
  1462. count = gf_list_count(l);
  1463. lsr_write_vluimsbf5(lsr, count, "count");
  1464. for (i=0; i<count; i++) {
  1465. SVG_Coordinate *v = (SVG_Coordinate *)gf_list_get(l, i);
  1466. lsr_write_fixed_16_8(lsr, v->value, "val");
  1467. }
  1468. } else if (svg_type==SVG_Transform_Rotate_datatype) {
  1469. SVG_Point_Angle *p = (SVG_Point_Angle *)val;
  1470. Fixed angle = gf_muldiv(p->angle, INT2FIX(180), GF_PI);
  1471. count = (p->x || p->y) ? 3 : 1;
  1472. lsr_write_vluimsbf5(lsr, count, "count");
  1473. lsr_write_fixed_16_8(lsr, angle, "val");
  1474. if (count==3) {
  1475. lsr_write_fixed_16_8(lsr, p->x, "val");
  1476. lsr_write_fixed_16_8(lsr, p->y, "val");
  1477. }
  1478. } else if (svg_type==SVG_Transform_Scale_datatype) {
  1479. SVG_Point *pt = (SVG_Point *)val;
  1480. count = (pt->x == pt->y) ? 1 : 2;
  1481. lsr_write_vluimsbf5(lsr, count, "count");
  1482. lsr_write_fixed_16_8(lsr, pt->x, "val");
  1483. if (count==2) lsr_write_fixed_16_8(lsr, pt->y, "val");
  1484. } else {
  1485. GF_List *l = *(GF_List **)val;
  1486. count = gf_list_count(l);
  1487. lsr_write_vluimsbf5(lsr, count, "count");
  1488. for (i=0; i<count; i++) {
  1489. Fixed *v = (Fixed *)gf_list_get(l, i);
  1490. lsr_write_fixed_16_8(lsr, *v, "val");
  1491. }
  1492. }
  1493. }
  1494. break;
  1495. case 9: // point
  1496. if (svg_type==SVG_Motion_datatype) {
  1497. lsr_write_coordinate(lsr, ((GF_Matrix2D*)val)->m[2], 0, "valX");
  1498. lsr_write_coordinate(lsr, ((GF_Matrix2D*)val)->m[5], 0, "valY");
  1499. } else {
  1500. lsr_write_coordinate(lsr, ((SVG_Point *)val)->x, 0, "valX");
  1501. lsr_write_coordinate(lsr, ((SVG_Point *)val)->y, 0, "valY");
  1502. }
  1503. break;
  1504. default:
  1505. lsr_write_extension(lsr, NULL, 0, name);
  1506. break;
  1507. }
  1508. }
  1509. static void lsr_write_anim_value(GF_LASeRCodec *lsr, SMIL_AnimateValue *val, const char *name)
  1510. {
  1511. if (!val || !val->type) {
  1512. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1513. } else {
  1514. u32 type = svg_type_to_lsr_anim(val->type, 0, NULL, val->value);
  1515. if (type==255) {
  1516. GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] unsupported anim type %d - skipping\n", val->type ));
  1517. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1518. } else {
  1519. GF_LSR_WRITE_INT(lsr, 1, 1, name);
  1520. GF_LSR_WRITE_INT(lsr, type, 4, "type");
  1521. lsr_write_an_anim_value(lsr, val->value, type, val->type, 0, name);
  1522. }
  1523. }
  1524. }
  1525. static void lsr_write_anim_values(GF_LASeRCodec *lsr, SMIL_AnimateValues *anims, const char *name)
  1526. {
  1527. u32 type, i, count = 0;
  1528. if (anims && anims->type) count = gf_list_count(anims->values);
  1529. if (!count) {
  1530. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1531. return;
  1532. }
  1533. type = svg_type_to_lsr_anim(anims->type, 0, anims->values, NULL);
  1534. if (type==255) {
  1535. GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] unsupported anim type %d - skipping\n", anims->type ));
  1536. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1537. } else {
  1538. GF_LSR_WRITE_INT(lsr, 1, 1, name);
  1539. GF_LSR_WRITE_INT(lsr, type, 4, "type");
  1540. lsr_write_vluimsbf5(lsr, count, "count");
  1541. for (i=0; i<count; i++) {
  1542. void *att = gf_list_get(anims->values, i);
  1543. lsr_write_an_anim_value(lsr, att, type, anims->type, 0, "a_value");
  1544. }
  1545. }
  1546. }
  1547. static void lsr_write_fraction_12(GF_LASeRCodec *lsr, GF_List **l, const char *name)
  1548. {
  1549. u32 i, count;
  1550. count = l ? gf_list_count(*l) : 0;
  1551. if (!count) {
  1552. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1553. return;
  1554. }
  1555. GF_LSR_WRITE_INT(lsr, 1, 1, name);
  1556. lsr_write_vluimsbf5(lsr, count, "name");
  1557. for (i=0; i<count; i++) {
  1558. Fixed f = * (Fixed *) gf_list_get(*l, i);
  1559. if (!f || (f == FIX_ONE)) {
  1560. GF_LSR_WRITE_INT(lsr, 1, 1, "hasShort");
  1561. GF_LSR_WRITE_INT(lsr, f ? 0 : 1, 1, "isZero");
  1562. } else {
  1563. u32 ft = (u32) ( FIX2FLT(f) * 4096/*(1<<12)*/ );
  1564. GF_LSR_WRITE_INT(lsr, 0, 1, "hasShort");
  1565. GF_LSR_WRITE_INT(lsr, ft, 12, "val");
  1566. }
  1567. }
  1568. }
  1569. static void lsr_write_float_list(GF_LASeRCodec *lsr, GF_List **l, const char *name)
  1570. {
  1571. u32 i, count = l ? gf_list_count(*l) : 0;
  1572. if (!count) {
  1573. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1574. return;
  1575. }
  1576. GF_LSR_WRITE_INT(lsr, 1, 1, name);
  1577. lsr_write_vluimsbf5(lsr, count, "count");
  1578. for (i=0;i<count;i++) {
  1579. Fixed *v = (Fixed *)gf_list_get(*l, i);
  1580. lsr_write_fixed_16_8(lsr, *v, "val");
  1581. }
  1582. }
  1583. static u32 lsr_get_bit_size(GF_LASeRCodec *lsr, Fixed v)
  1584. {
  1585. u32 val;
  1586. v = gf_divfix(v, lsr->res_factor);
  1587. val = (v<0) ? FIX2INT(-v) : FIX2INT(v);
  1588. return 1 + gf_get_bit_size(val);
  1589. }
  1590. static void lsr_write_point_sequence(GF_LASeRCodec *lsr, GF_List **pts, const char *name)
  1591. {
  1592. u32 i, count = pts ? gf_list_count(*pts) : 0;
  1593. lsr_write_vluimsbf5(lsr, count, "nbPoints");
  1594. if (!count) return;
  1595. /*TODO golomb coding*/
  1596. GF_LSR_WRITE_INT(lsr, 0, 1, "flag");
  1597. if (1) {
  1598. if (count < 3) {
  1599. u32 nb_bits = 0;
  1600. for (i=0; i<count; i++) {
  1601. u32 k;
  1602. SVG_Point *pt = (SVG_Point *)gf_list_get(*pts, i);
  1603. k = lsr_get_bit_size(lsr, pt->x); if (k>nb_bits) nb_bits = k;
  1604. k = lsr_get_bit_size(lsr, pt->y); if (k>nb_bits) nb_bits = k;
  1605. }
  1606. GF_LSR_WRITE_INT(lsr, nb_bits, 5, "bits");
  1607. for (i=0; i<count; i++) {
  1608. SVG_Point *pt = (SVG_Point *)gf_list_get(*pts, i);
  1609. u32 v = lsr_translate_coords(lsr, pt->x, nb_bits);
  1610. GF_LSR_WRITE_INT(lsr, v, nb_bits, "x");
  1611. v = lsr_translate_coords(lsr, pt->y, nb_bits);
  1612. GF_LSR_WRITE_INT(lsr, v, nb_bits, "y");
  1613. }
  1614. } else {
  1615. Fixed c_x, c_y;
  1616. u32 k, nb_dx, nb_dy;
  1617. SVG_Point *pt = (SVG_Point *)gf_list_get(*pts, 0);
  1618. nb_dx = 0;
  1619. k = lsr_get_bit_size(lsr, pt->x); if (k>nb_dx) nb_dx = k;
  1620. k = lsr_get_bit_size(lsr, pt->y); if (k>nb_dx) nb_dx = k;
  1621. GF_LSR_WRITE_INT(lsr, nb_dx, 5, "bits");
  1622. k = lsr_translate_coords(lsr, pt->x, nb_dx);
  1623. GF_LSR_WRITE_INT(lsr, k, nb_dx, "x");
  1624. k = lsr_translate_coords(lsr, pt->y, nb_dx);
  1625. GF_LSR_WRITE_INT(lsr, k, nb_dx, "y");
  1626. c_x = pt->x;
  1627. c_y = pt->y;
  1628. nb_dx = nb_dy = 0;
  1629. for (i=1; i<count; i++) {
  1630. SVG_Point *pt = (SVG_Point *)gf_list_get(*pts, i);
  1631. k = lsr_get_bit_size(lsr, pt->x - c_x); if (k>nb_dx) nb_dx = k;
  1632. k = lsr_get_bit_size(lsr, pt->y - c_y); if (k>nb_dy) nb_dy = k;
  1633. c_x = pt->x;
  1634. c_y = pt->y;
  1635. }
  1636. GF_LSR_WRITE_INT(lsr, nb_dx, 5, "bitsx");
  1637. GF_LSR_WRITE_INT(lsr, nb_dy, 5, "bitsy");
  1638. c_x = pt->x;
  1639. c_y = pt->y;
  1640. for (i=1; i<count; i++) {
  1641. SVG_Point *pt = (SVG_Point *)gf_list_get(*pts, i);
  1642. k = lsr_translate_coords(lsr, pt->x - c_x, nb_dx);
  1643. GF_LSR_WRITE_INT(lsr, k, nb_dx, "dx");
  1644. k = lsr_translate_coords(lsr, pt->y - c_y, nb_dy);
  1645. GF_LSR_WRITE_INT(lsr, k, nb_dy, "dy");
  1646. c_x = pt->x;
  1647. c_y = pt->y;
  1648. }
  1649. }
  1650. }
  1651. }
  1652. static void lsr_write_path_type(GF_LASeRCodec *lsr, SVG_PathData *path, const char *name)
  1653. {
  1654. #if USE_GF_PATH
  1655. u32 i, *contour, nb_types;
  1656. GF_List *pts = gf_list_new();
  1657. contour = path->contours;
  1658. nb_types = 0;
  1659. for (i=0; i<path->n_points; ) {
  1660. switch (path->tags[i]) {
  1661. case GF_PATH_CURVE_ON:
  1662. gf_list_add(pts, &path->points[i]);
  1663. nb_types++;
  1664. i++;
  1665. break;
  1666. case GF_PATH_CLOSE:
  1667. nb_types++;
  1668. i++;
  1669. break;
  1670. case GF_PATH_CURVE_CONIC:
  1671. gf_list_add(pts, &path->points[i]);
  1672. gf_list_add(pts, &path->points[i+1]);
  1673. i+=2;
  1674. nb_types++;
  1675. break;
  1676. case GF_PATH_CURVE_CUBIC:
  1677. gf_list_add(pts, &path->points[i]);
  1678. gf_list_add(pts, &path->points[i+1]);
  1679. gf_list_add(pts, &path->points[i+2]);
  1680. i+=3;
  1681. nb_types++;
  1682. break;
  1683. }
  1684. }
  1685. lsr_write_point_sequence(lsr, &pts, "seq");
  1686. gf_list_del(pts);
  1687. /*first moveTo is skiped*/
  1688. lsr_write_vluimsbf5(lsr, nb_types-1, "nbOfTypes");
  1689. for (i=0; i<path->n_points; ) {
  1690. switch (path->tags[i]) {
  1691. case GF_PATH_CLOSE:
  1692. /*close*/
  1693. GF_LSR_WRITE_INT(lsr, LSR_PATH_COM_Z, 5, name);
  1694. i++;
  1695. break;
  1696. case GF_PATH_CURVE_ON:
  1697. if (!i) {
  1698. } else if (*contour == i-1) {
  1699. /*moveTo*/
  1700. GF_LSR_WRITE_INT(lsr, LSR_PATH_COM_M, 5, name);
  1701. } else {
  1702. /*lineTo*/
  1703. GF_LSR_WRITE_INT(lsr, LSR_PATH_COM_L, 5, name);
  1704. }
  1705. i++;
  1706. break;
  1707. case GF_PATH_CURVE_CONIC:
  1708. /*Conic*/
  1709. GF_LSR_WRITE_INT(lsr, LSR_PATH_COM_Q, 5, name);
  1710. i+=2;
  1711. break;
  1712. case GF_PATH_CURVE_CUBIC:
  1713. /*cubic*/
  1714. GF_LSR_WRITE_INT(lsr, LSR_PATH_COM_C, 5, name);
  1715. i+=3;
  1716. break;
  1717. }
  1718. }
  1719. #else
  1720. u32 i, count;
  1721. lsr_write_point_sequence(lsr, path->points, "seq");
  1722. /*initial move is not coded*/
  1723. count = gf_list_count(path->commands);
  1724. lsr_write_vluimsbf5(lsr, count, "nbOfTypes");
  1725. for (i; i<count; i++) {
  1726. u8 type = *(u8 *) gf_list_get(path->commands, i);
  1727. GF_LSR_WRITE_INT(lsr, type, 5, name);
  1728. }
  1729. #endif
  1730. }
  1731. static void lsr_write_rotate_type(GF_LASeRCodec *lsr, SVG_Rotate *rotate, const char *name)
  1732. {
  1733. GF_LSR_WRITE_INT(lsr, rotate ? 1 : 0, 1, name);
  1734. if (!rotate) return;
  1735. if ((rotate->type == SVG_NUMBER_AUTO) || (rotate->type == SVG_NUMBER_AUTO_REVERSE)) {
  1736. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  1737. GF_LSR_WRITE_INT(lsr, (rotate->type == SVG_NUMBER_AUTO) ? 0 : 1, 1, "rotate");
  1738. } else {
  1739. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  1740. lsr_write_fixed_16_8(lsr, rotate->value, "rotate");
  1741. }
  1742. }
  1743. static void lsr_write_sync_behavior(GF_LASeRCodec *lsr, SMIL_SyncBehavior *sync, const char *name)
  1744. {
  1745. GF_LSR_WRITE_INT(lsr, sync ? 1 : 0, 1, name);
  1746. if (!sync) return;
  1747. assert(*sync!=SMIL_SYNCBEHAVIOR_INHERIT);
  1748. GF_LSR_WRITE_INT(lsr, *sync-1, 2, name);
  1749. }
  1750. static void lsr_write_sync_tolerance(GF_LASeRCodec *lsr, SMIL_SyncTolerance *sync, const char *name)
  1751. {
  1752. GF_LSR_WRITE_INT(lsr, sync ? 1 : 0, 1, name);
  1753. if (!sync) return;
  1754. assert(sync->type!=SMIL_SYNCTOLERANCE_INHERIT);
  1755. if (sync->type==SMIL_SYNCTOLERANCE_DEFAULT) {
  1756. GF_LSR_WRITE_INT(lsr, 1, 1, name);
  1757. } else {
  1758. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1759. lsr_write_vluimsbf5(lsr, (u32) (sync->value*lsr->time_resolution), "value");
  1760. }
  1761. }
  1762. static void lsr_write_coord_list(GF_LASeRCodec *lsr, GF_List **coords, const char *name)
  1763. {
  1764. u32 i, count = coords ? gf_list_count(*coords) : 0;
  1765. if (!count) {
  1766. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1767. } else {
  1768. GF_LSR_WRITE_INT(lsr, 1, 1, name);
  1769. lsr_write_vluimsbf5(lsr, count, "nb_coords");
  1770. for (i=0; i<count; i++) {
  1771. SVG_Coordinate *c = (SVG_Coordinate *)gf_list_get(*coords, i);
  1772. u32 res = lsr_translate_coords(lsr, c->value, lsr->coord_bits);
  1773. GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, name);
  1774. }
  1775. }
  1776. }
  1777. static void lsr_write_transform_behavior(GF_LASeRCodec *lsr, SVG_TransformBehavior *type)
  1778. {
  1779. GF_LSR_WRITE_INT(lsr, type ? 1 : 0, 1, "hasTransformBehavior");
  1780. if (!type) return;
  1781. GF_LSR_WRITE_INT(lsr, *type, 4, "transformBehavior");
  1782. }
  1783. static void lsr_write_gradient_units(GF_LASeRCodec *lsr, SVG_GradientUnit *type)
  1784. {
  1785. GF_LSR_WRITE_INT(lsr, type ? 1 : 0, 1, "hasGradientUnits");
  1786. if (!type) return;
  1787. GF_LSR_WRITE_INT(lsr, *type ? 1 : 0, 1, "gradientUnits");
  1788. }
  1789. static void lsr_write_content_type(GF_LASeRCodec *lsr, SVG_String *type, const char *name)
  1790. {
  1791. if (type) {
  1792. GF_LSR_WRITE_INT(lsr, 1, 1, "hasType");
  1793. lsr_write_byte_align_string(lsr, *type, "type");
  1794. } else {
  1795. GF_LSR_WRITE_INT(lsr, 0, 1, "hasType");
  1796. }
  1797. }
  1798. static void lsr_write_script_type(GF_LASeRCodec *lsr, SVG_String *type)
  1799. {
  1800. GF_LSR_WRITE_INT(lsr, type ? 1 : 0, 1, "hasType");
  1801. if (!type) return;
  1802. if (!strcmp(*type, "application/ecmascript")) {
  1803. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  1804. GF_LSR_WRITE_INT(lsr, 0, 1, "script");
  1805. } else if (!strcmp(*type, "application/jar-archive")) {
  1806. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  1807. GF_LSR_WRITE_INT(lsr, 1, 1, "script");
  1808. } else {
  1809. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  1810. lsr_write_byte_align_string(lsr, *type, "type");
  1811. }
  1812. }
  1813. static void lsr_write_value_with_units(GF_LASeRCodec *lsr, SVG_Number *n, const char *name)
  1814. {
  1815. #ifdef GPAC_FIXED_POINT
  1816. s32 val = n->value >> 8;
  1817. #else
  1818. s32 val = (s32) (n->value * (1<<8) );
  1819. #endif
  1820. GF_LSR_WRITE_INT(lsr, val, 32, name);
  1821. switch (n->type) {
  1822. case SVG_NUMBER_IN: GF_LSR_WRITE_INT(lsr, 1, 3, "units"); break;
  1823. case SVG_NUMBER_CM: GF_LSR_WRITE_INT(lsr, 2, 3, "units"); break;
  1824. case SVG_NUMBER_MM: GF_LSR_WRITE_INT(lsr, 3, 3, "units"); break;
  1825. case SVG_NUMBER_PT: GF_LSR_WRITE_INT(lsr, 4, 3, "units"); break;
  1826. case SVG_NUMBER_PC: GF_LSR_WRITE_INT(lsr, 5, 3, "units"); break;
  1827. case SVG_NUMBER_PERCENTAGE: GF_LSR_WRITE_INT(lsr, 6, 3, "units"); break;
  1828. default: GF_LSR_WRITE_INT(lsr, 0, 3, "units"); break;
  1829. }
  1830. }
  1831. static void lsr_write_clip_time(GF_LASeRCodec *lsr, SVG_Clock *clock, const char *name)
  1832. {
  1833. if (!clock || *clock <= 0) {
  1834. GF_LSR_WRITE_INT(lsr, 0, 1, name);
  1835. } else {
  1836. GF_LSR_WRITE_INT(lsr, 1, 1, name);
  1837. GF_LSR_WRITE_INT(lsr, 0, 1, "isEnum");
  1838. GF_LSR_WRITE_INT(lsr, 0, 1, "sign");
  1839. lsr_write_vluimsbf5(lsr, (u32) (lsr->time_resolution* *clock), "val");
  1840. }
  1841. }
  1842. static void lsr_write_href_anim(GF_LASeRCodec *lsr, XMLRI *href, SVG_Element *parent)
  1843. {
  1844. if (!href || (href->target && (href->target==parent))) {
  1845. GF_LSR_WRITE_INT(lsr, 0, 1, "has_href");
  1846. } else {
  1847. lsr_write_href(lsr, href);
  1848. }
  1849. }
  1850. static void lsr_write_attribute_type(GF_LASeRCodec *lsr, SVGAllAttributes *atts)
  1851. {
  1852. if (!atts->attributeType) {
  1853. GF_LSR_WRITE_INT(lsr, 0, 1, "hasAttributeType");
  1854. } else {
  1855. GF_LSR_WRITE_INT(lsr, 1, 1, "hasAttributeType");
  1856. GF_LSR_WRITE_INT(lsr, (*atts->attributeType), 2, "attributeType");
  1857. }
  1858. }
  1859. static void lsr_write_preserve_aspect_ratio(GF_LASeRCodec *lsr, SVG_PreserveAspectRatio *preserveAspectRatio)
  1860. {
  1861. GF_LSR_WRITE_INT(lsr, preserveAspectRatio ? 1 : 0, 1, "hasPreserveAspectRatio");
  1862. if (!preserveAspectRatio) return;
  1863. GF_LSR_WRITE_INT(lsr, 0, 1, "choice (meetOrSlice)");
  1864. GF_LSR_WRITE_INT(lsr, preserveAspectRatio->defer ? 1 : 0, 1, "choice (defer)");
  1865. switch (preserveAspectRatio->align) {
  1866. case SVG_PRESERVEASPECTRATIO_XMAXYMAX: GF_LSR_WRITE_INT(lsr, 1, 4, "alignXandY"); break;
  1867. case SVG_PRESERVEASPECTRATIO_XMAXYMID: GF_LSR_WRITE_INT(lsr, 2, 4, "alignXandY"); break;
  1868. case SVG_PRESERVEASPECTRATIO_XMAXYMIN: GF_LSR_WRITE_INT(lsr, 3, 4, "alignXandY"); break;
  1869. case SVG_PRESERVEASPECTRATIO_XMIDYMAX: GF_LSR_WRITE_INT(lsr, 4, 4, "alignXandY"); break;
  1870. case SVG_PRESERVEASPECTRATIO_XMIDYMID: GF_LSR_WRITE_INT(lsr, 5, 4, "alignXandY"); break;
  1871. case SVG_PRESERVEASPECTRATIO_XMIDYMIN: GF_LSR_WRITE_INT(lsr, 6, 4, "alignXandY"); break;
  1872. case SVG_PRESERVEASPECTRATIO_XMINYMAX: GF_LSR_WRITE_INT(lsr, 7, 4, "alignXandY"); break;
  1873. case SVG_PRESERVEASPECTRATIO_XMINYMID: GF_LSR_WRITE_INT(lsr, 8, 4, "alignXandY"); break;
  1874. case SVG_PRESERVEASPECTRATIO_XMINYMIN: GF_LSR_WRITE_INT(lsr, 9, 4, "alignXandY"); break;
  1875. default: GF_LSR_WRITE_INT(lsr, 0, 4, "alignXandY"); break;
  1876. }
  1877. }
  1878. #define lsr_write_err() GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired")
  1879. static void lsr_write_a(GF_LASeRCodec *lsr, SVG_Element *elt)
  1880. {
  1881. SVGAllAttributes atts;
  1882. gf_svg_flatten_attributes(elt, &atts);
  1883. lsr_write_id(lsr, (GF_Node *) elt);
  1884. lsr_write_rare(lsr, (GF_Node *) elt);
  1885. lsr_write_fill(lsr, elt, &atts);
  1886. lsr_write_stroke(lsr, elt, &atts);
  1887. lsr_write_err();
  1888. GF_LSR_WRITE_INT(lsr, (atts.target!=NULL) ? 1 : 0, 1, "hasTarget");
  1889. if (atts.target) lsr_write_byte_align_string(lsr, *(SVG_String*)atts.target, "target");
  1890. lsr_write_href(lsr, atts.xlink_href);
  1891. lsr_write_any_attribute(lsr, elt, 1);
  1892. lsr_write_group_content(lsr, elt, 0);
  1893. }
  1894. static void lsr_write_animate(GF_LASeRCodec *lsr, SVG_Element *elt, SVG_Element *parent)
  1895. {
  1896. SVGAllAttributes atts;
  1897. gf_svg_flatten_attributes(elt, &atts);
  1898. lsr_write_id(lsr, (GF_Node *) elt);
  1899. lsr_write_rare(lsr, (GF_Node *) elt);
  1900. lsr_write_animatable(lsr, atts.attributeName, atts.xlink_href, "attributeName");
  1901. lsr_write_accumulate(lsr, atts.accumulate);
  1902. lsr_write_additive(lsr, atts.additive);
  1903. lsr_write_anim_value(lsr, atts.by, "by");
  1904. lsr_write_calc_mode(lsr, atts.calcMode);
  1905. lsr_write_anim_value(lsr, atts.from, "from");
  1906. lsr_write_fraction_12(lsr, atts.keySplines, "keySplines");
  1907. lsr_write_fraction_12(lsr, atts.keyTimes, "keyTimes");
  1908. lsr_write_anim_values(lsr, atts.values, "values");
  1909. lsr_write_attribute_type(lsr, &atts);
  1910. lsr_write_smil_times(lsr, atts.begin, "begin", 1);
  1911. lsr_write_duration(lsr, atts.dur, "dur");
  1912. lsr_write_anim_fill(lsr, atts.smil_fill);
  1913. lsr_write_anim_repeat(lsr, atts.repeatCount);
  1914. lsr_write_repeat_duration(lsr, atts.repeatDur);
  1915. lsr_write_anim_restart(lsr, atts.restart);
  1916. lsr_write_anim_value(lsr, atts.to, "to");
  1917. lsr_write_href_anim(lsr, atts.xlink_href, parent);
  1918. GF_LSR_WRITE_INT(lsr, (atts.lsr_enabled && *atts.lsr_enabled) ? 1 : 0, 1, "enabled");
  1919. lsr_write_any_attribute(lsr, elt, 1);
  1920. lsr_write_group_content(lsr, elt, 0);
  1921. }
  1922. static void lsr_write_animateMotion(GF_LASeRCodec *lsr, SVG_Element*elt, SVG_Element *parent)
  1923. {
  1924. SVGAllAttributes atts;
  1925. gf_svg_flatten_attributes(elt, &atts);
  1926. lsr_write_id(lsr, (GF_Node *) elt);
  1927. lsr_write_rare(lsr, (GF_Node *) elt);
  1928. lsr_write_accumulate(lsr, atts.accumulate);
  1929. lsr_write_additive(lsr, atts.additive);
  1930. lsr_write_anim_value(lsr, atts.by, "by");
  1931. lsr_write_calc_mode(lsr, atts.calcMode);
  1932. lsr_write_anim_value(lsr, atts.from, "from");
  1933. lsr_write_fraction_12(lsr, atts.keySplines, "keySplines");
  1934. lsr_write_fraction_12(lsr, atts.keyTimes, "keyTimes");
  1935. lsr_write_anim_values(lsr, atts.values, "values");
  1936. lsr_write_attribute_type(lsr, &atts);
  1937. lsr_write_smil_times(lsr, atts.begin, "begin", 1);
  1938. lsr_write_duration(lsr, atts.dur, "dur");
  1939. lsr_write_anim_fill(lsr, atts.smil_fill);
  1940. lsr_write_anim_repeat(lsr, atts.repeatCount);
  1941. lsr_write_repeat_duration(lsr, atts.repeatDur);
  1942. lsr_write_anim_restart(lsr, atts.restart);
  1943. lsr_write_anim_value(lsr, atts.to, "to");
  1944. lsr_write_float_list(lsr, atts.keyPoints, "keyPoints");
  1945. if (atts.path) {
  1946. GF_LSR_WRITE_INT(lsr, 1, 1, "hasPath");
  1947. lsr_write_path_type(lsr, atts.path, "path");
  1948. } else {
  1949. GF_LSR_WRITE_INT(lsr, 0, 1, "hasPath");
  1950. }
  1951. lsr_write_rotate_type(lsr, atts.rotate, "rotate");
  1952. lsr_write_href_anim(lsr, atts.xlink_href, parent);
  1953. GF_LSR_WRITE_INT(lsr, (atts.lsr_enabled && *atts.lsr_enabled) ? 1 : 0, 1, "enabled");
  1954. lsr_write_any_attribute(lsr, elt, 1);
  1955. lsr_write_group_content(lsr, elt, 0);
  1956. }
  1957. static void lsr_write_animateTransform(GF_LASeRCodec *lsr, SVG_Element *elt, SVG_Element *parent)
  1958. {
  1959. u32 type;
  1960. SVGAllAttributes atts;
  1961. gf_svg_flatten_attributes(elt, &atts);
  1962. lsr_write_id(lsr, (GF_Node *) elt);
  1963. lsr_write_rare(lsr, (GF_Node *) elt);
  1964. lsr_write_animatable(lsr, atts.attributeName, atts.xlink_href, "attributeName");
  1965. /*no default value for type or we MUST code it in LASeR ...*/
  1966. type = atts.transform_type ? *atts.transform_type : SVG_TRANSFORM_TRANSLATE;
  1967. /*enumeration rotate{0} scale{1} skewX{2} skewY{3} translate{4}*/
  1968. switch (type) {
  1969. case SVG_TRANSFORM_ROTATE: GF_LSR_WRITE_INT(lsr, 0, 3, "rotscatra"); break;
  1970. case SVG_TRANSFORM_SCALE: GF_LSR_WRITE_INT(lsr, 1, 3, "rotscatra"); break;
  1971. case SVG_TRANSFORM_SKEWX: GF_LSR_WRITE_INT(lsr, 2, 3, "rotscatra"); break;
  1972. case SVG_TRANSFORM_SKEWY: GF_LSR_WRITE_INT(lsr, 3, 3, "rotscatra"); break;
  1973. case SVG_TRANSFORM_TRANSLATE: GF_LSR_WRITE_INT(lsr, 4, 3, "rotscatra"); break;
  1974. }
  1975. lsr_write_accumulate(lsr, atts.accumulate);
  1976. lsr_write_additive(lsr, atts.additive);
  1977. lsr_write_anim_value(lsr, atts.by, "by");
  1978. lsr_write_calc_mode(lsr, atts.calcMode);
  1979. lsr_write_anim_value(lsr, atts.from, "from");
  1980. lsr_write_fraction_12(lsr, atts.keySplines, "keySplines");
  1981. lsr_write_fraction_12(lsr, atts.keyTimes, "keyTimes");
  1982. lsr_write_anim_values(lsr, atts.values, "values");
  1983. lsr_write_attribute_type(lsr, &atts);
  1984. lsr_write_smil_times(lsr, atts.begin, "begin", 1);
  1985. lsr_write_duration(lsr, atts.dur, "dur");
  1986. lsr_write_anim_fill(lsr, atts.smil_fill);
  1987. lsr_write_anim_repeat(lsr, atts.repeatCount);
  1988. lsr_write_repeat_duration(lsr, atts.repeatDur);
  1989. lsr_write_anim_restart(lsr, atts.restart);
  1990. lsr_write_anim_value(lsr, atts.to, "to");
  1991. lsr_write_href_anim(lsr, atts.xlink_href, parent);
  1992. GF_LSR_WRITE_INT(lsr, (atts.lsr_enabled && *atts.lsr_enabled) ? 1 : 0, 1, "enabled");
  1993. lsr_write_any_attribute(lsr, elt, 1);
  1994. lsr_write_group_content(lsr, elt, 0);
  1995. }
  1996. static void lsr_write_audio(GF_LASeRCodec *lsr, SVG_Element *elt)
  1997. {
  1998. SVGAllAttributes atts;
  1999. gf_svg_flatten_attributes(elt, &atts);
  2000. lsr_write_id(lsr, (GF_Node *) elt);
  2001. lsr_write_rare(lsr, (GF_Node *) elt);
  2002. lsr_write_smil_times(lsr, atts.begin, "begin", 1);
  2003. lsr_write_duration(lsr, atts.dur, "dur");
  2004. GF_LSR_WRITE_INT(lsr, atts.externalResourcesRequired ? *atts.externalResourcesRequired : 0, 1, "externalResourcesRequired");
  2005. lsr_write_anim_repeat(lsr, atts.repeatCount);
  2006. lsr_write_repeat_duration(lsr, atts.repeatDur);
  2007. lsr_write_anim_restart(lsr, atts.restart);
  2008. lsr_write_sync_behavior(lsr, atts.syncBehavior, "syncBehavior");
  2009. lsr_write_sync_tolerance(lsr, atts.syncTolerance, "syncBehavior");
  2010. lsr_write_content_type(lsr, atts.xlink_type, "type");
  2011. lsr_write_href(lsr, atts.xlink_href);
  2012. lsr_write_clip_time(lsr, atts.clipBegin, "clipBegin");
  2013. lsr_write_clip_time(lsr, atts.clipEnd, "clipEnd");
  2014. GF_LSR_WRITE_INT(lsr, atts.syncReference ? 1 : 0, 1, "hasSyncReference");
  2015. if (atts.syncReference) lsr_write_any_uri(lsr, atts.syncReference, "syncReference");
  2016. lsr_write_any_attribute(lsr, elt, 1);
  2017. lsr_write_group_content(lsr, elt, 0);
  2018. }
  2019. static void lsr_write_circle(GF_LASeRCodec *lsr, SVG_Element *elt)
  2020. {
  2021. SVGAllAttributes atts;
  2022. gf_svg_flatten_attributes(elt, &atts);
  2023. lsr_write_id(lsr, (GF_Node *) elt);
  2024. lsr_write_rare(lsr, (GF_Node *) elt);
  2025. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2026. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2027. lsr_write_coordinate_ptr(lsr, atts.cx, 1, "cx");
  2028. lsr_write_coordinate_ptr(lsr, atts.cy, 1, "cy");
  2029. lsr_write_coordinate_ptr(lsr, atts.r, 0, "r");
  2030. lsr_write_any_attribute(lsr, elt, 1);
  2031. lsr_write_group_content(lsr, elt, 0);
  2032. }
  2033. static void lsr_write_conditional(GF_LASeRCodec *lsr, SVG_Element *elt)
  2034. {
  2035. GF_DOMUpdates *up;
  2036. SVGAllAttributes atts;
  2037. gf_svg_flatten_attributes(elt, &atts);
  2038. lsr_write_id(lsr, (GF_Node *) elt);
  2039. lsr_write_rare(lsr, (GF_Node *) elt);
  2040. lsr_write_smil_times(lsr, atts.begin, "begin", 1);
  2041. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2042. GF_LSR_WRITE_INT(lsr, (atts.lsr_enabled && *atts.lsr_enabled) ? 1 : 0, 1, "enabled");
  2043. lsr_write_any_attribute(lsr, elt, 1);
  2044. up = elt->children ? (GF_DOMUpdates*)elt->children->node : NULL;
  2045. lsr_write_command_list(lsr, up ? up->updates : NULL, elt, 0);
  2046. lsr_write_private_attributes(lsr, elt);
  2047. }
  2048. static void lsr_write_cursorManager(GF_LASeRCodec *lsr, SVG_Element *elt)
  2049. {
  2050. SVGAllAttributes atts;
  2051. gf_svg_flatten_attributes(elt, &atts);
  2052. lsr_write_id(lsr, (GF_Node *) elt);
  2053. lsr_write_rare(lsr, (GF_Node *) elt);
  2054. lsr_write_coordinate_ptr(lsr, atts.x, 1, "x");
  2055. lsr_write_coordinate_ptr(lsr, atts.x, 1, "y");
  2056. lsr_write_href(lsr, atts.xlink_href);
  2057. lsr_write_any_attribute(lsr, elt, 1);
  2058. lsr_write_group_content(lsr, elt, 0);
  2059. }
  2060. static void lsr_write_data(GF_LASeRCodec *lsr, SVG_Element *elt)
  2061. {
  2062. lsr_write_id(lsr, (GF_Node *) elt);
  2063. lsr_write_rare(lsr, (GF_Node *) elt);
  2064. lsr_write_any_attribute(lsr, elt, 1);
  2065. lsr_write_group_content(lsr, elt, 0);
  2066. }
  2067. static void lsr_write_defs(GF_LASeRCodec *lsr, SVG_Element *elt)
  2068. {
  2069. SVGAllAttributes atts;
  2070. gf_svg_flatten_attributes(elt, &atts);
  2071. lsr_write_id(lsr, (GF_Node *) elt);
  2072. lsr_write_rare(lsr, (GF_Node *) elt);
  2073. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2074. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2075. lsr_write_any_attribute(lsr, elt, 1);
  2076. lsr_write_group_content(lsr, elt, 0);
  2077. }
  2078. static void lsr_write_ellipse(GF_LASeRCodec *lsr, SVG_Element *elt)
  2079. {
  2080. SVGAllAttributes atts;
  2081. gf_svg_flatten_attributes(elt, &atts);
  2082. lsr_write_id(lsr, (GF_Node *) elt);
  2083. lsr_write_rare(lsr, (GF_Node *) elt);
  2084. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2085. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2086. lsr_write_coordinate_ptr(lsr, atts.cx, 1, "cx");
  2087. lsr_write_coordinate_ptr(lsr, atts.cy, 1, "cy");
  2088. lsr_write_coordinate_ptr(lsr, atts.rx, 0, "rx");
  2089. lsr_write_coordinate_ptr(lsr, atts.ry, 0, "ry");
  2090. lsr_write_any_attribute(lsr, elt, 1);
  2091. lsr_write_group_content(lsr, elt, 0);
  2092. }
  2093. static void lsr_write_foreignObject(GF_LASeRCodec *lsr, SVG_Element *elt)
  2094. {
  2095. SVGAllAttributes atts;
  2096. gf_svg_flatten_attributes(elt, &atts);
  2097. lsr_write_id(lsr, (GF_Node *) elt);
  2098. lsr_write_rare(lsr, (GF_Node *) elt);
  2099. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2100. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2101. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired&&*atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2102. lsr_write_coordinate_ptr(lsr, atts.height, 0, "height");
  2103. lsr_write_coordinate_ptr(lsr, atts.width, 0, "width");
  2104. lsr_write_coordinate_ptr(lsr, atts.x, 1, "x");
  2105. lsr_write_coordinate_ptr(lsr, atts.y, 1, "y");
  2106. lsr_write_any_attribute(lsr, elt, 1);
  2107. /* TODO
  2108. bit(1) opt_group;
  2109. if(opt_group) {
  2110. vluimsbf5 occ1;
  2111. for(int t=0;t<occ1;t++) {
  2112. privateElementContainer child0[[t]];
  2113. }
  2114. }
  2115. */
  2116. GF_LSR_WRITE_INT(lsr, 0, 1, "opt_group");
  2117. }
  2118. static void lsr_write_g(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag)
  2119. {
  2120. Bool is_same = 0;
  2121. Bool same_fill;
  2122. SVGAllAttributes atts;
  2123. gf_svg_flatten_attributes(elt, &atts);
  2124. if (!ommit_tag
  2125. && lsr_elt_has_same_base(lsr, &atts, lsr->prev_g, &same_fill, NULL, 0)
  2126. && same_fill
  2127. ) {
  2128. /*samegType*/
  2129. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sameg, 6, "ch4");
  2130. lsr_write_id(lsr, (GF_Node *) elt);
  2131. is_same = 1;
  2132. } else {
  2133. /*gType*/
  2134. if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_g, 6, "ch4");
  2135. lsr_write_id(lsr, (GF_Node *) elt);
  2136. lsr_write_rare(lsr, (GF_Node *) elt);
  2137. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2138. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2139. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2140. lsr_write_any_attribute(lsr, elt, 1);
  2141. lsr->prev_g = elt;
  2142. }
  2143. lsr_write_group_content(lsr, elt, is_same);
  2144. }
  2145. static void lsr_write_image(GF_LASeRCodec *lsr, SVG_Element *elt)
  2146. {
  2147. SVGAllAttributes atts;
  2148. gf_svg_flatten_attributes(elt, &atts);
  2149. lsr_write_id(lsr, (GF_Node *) elt);
  2150. lsr_write_rare(lsr, (GF_Node *) elt);
  2151. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2152. lsr_write_coordinate_ptr(lsr, atts.height, 1, "height");
  2153. if (atts.opacity && (atts.opacity->type == SVG_NUMBER_VALUE)) {
  2154. GF_LSR_WRITE_INT(lsr, 1, 1, "opacity");
  2155. lsr_write_fixed_clamp(lsr, atts.opacity->value, "opacity");
  2156. } else {
  2157. GF_LSR_WRITE_INT(lsr, 0, 1, "opacity");
  2158. }
  2159. lsr_write_preserve_aspect_ratio(lsr, atts.preserveAspectRatio);
  2160. lsr_write_content_type(lsr, atts.xlink_type, "type");
  2161. lsr_write_coordinate_ptr(lsr, atts.width, 1, "width");
  2162. lsr_write_coordinate_ptr(lsr, atts.x, 1, "x");
  2163. lsr_write_coordinate_ptr(lsr, atts.y, 1, "y");
  2164. lsr_write_href(lsr, atts.xlink_href);
  2165. lsr_write_transform_behavior(lsr, atts.transformBehavior);
  2166. lsr_write_any_attribute(lsr, elt, 1);
  2167. lsr_write_group_content(lsr, elt, 0);
  2168. }
  2169. static void lsr_write_line(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag)
  2170. {
  2171. Bool same_fill;
  2172. Bool is_same = 0;
  2173. SVGAllAttributes atts;
  2174. gf_svg_flatten_attributes(elt, &atts);
  2175. if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_line, &same_fill, NULL, 0)
  2176. && same_fill
  2177. ) {
  2178. /*samelineType*/
  2179. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sameline, 6, "ch4");
  2180. lsr_write_id(lsr, (GF_Node *) elt);
  2181. is_same = 1;
  2182. } else {
  2183. /*lineType*/
  2184. if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_line, 6, "ch4");
  2185. lsr_write_id(lsr, (GF_Node *) elt);
  2186. lsr_write_rare(lsr, (GF_Node *) elt);
  2187. lsr_write_fill(lsr, elt, &atts);
  2188. lsr_write_stroke(lsr, elt, &atts);
  2189. }
  2190. lsr_write_coordinate_ptr(lsr, atts.x1, 1, "x1");
  2191. lsr_write_coordinate_ptr(lsr, atts.x2, 0, "x2");
  2192. lsr_write_coordinate_ptr(lsr, atts.y1, 1, "y1");
  2193. lsr_write_coordinate_ptr(lsr, atts.y2, 0, "y2");
  2194. if (!is_same) {
  2195. lsr_write_any_attribute(lsr, elt, 1);
  2196. lsr->prev_line = elt;
  2197. }
  2198. lsr_write_group_content(lsr, elt, is_same);
  2199. }
  2200. static void lsr_write_linearGradient(GF_LASeRCodec *lsr, SVG_Element *elt)
  2201. {
  2202. SVGAllAttributes atts;
  2203. gf_svg_flatten_attributes(elt, &atts);
  2204. lsr_write_id(lsr, (GF_Node *) elt);
  2205. lsr_write_rare(lsr, (GF_Node *) elt);
  2206. lsr_write_fill(lsr, elt, &atts);
  2207. lsr_write_stroke(lsr, elt, &atts);
  2208. lsr_write_gradient_units(lsr, atts.gradientUnits);
  2209. lsr_write_coordinate_ptr(lsr, atts.x1, 1, "x1");
  2210. lsr_write_coordinate_ptr(lsr, atts.x2, 1, "x2");
  2211. lsr_write_coordinate_ptr(lsr, atts.y1, 1, "y1");
  2212. lsr_write_coordinate_ptr(lsr, atts.y2, 1, "y2");
  2213. lsr_write_any_attribute(lsr, elt, 1);
  2214. lsr_write_group_content(lsr, elt, 0);
  2215. }
  2216. static void lsr_write_mpath(GF_LASeRCodec *lsr, SVG_Element *elt)
  2217. {
  2218. SVGAllAttributes atts;
  2219. gf_svg_flatten_attributes(elt, &atts);
  2220. lsr_write_id(lsr, (GF_Node *) elt);
  2221. lsr_write_rare(lsr, (GF_Node *) elt);
  2222. lsr_write_href(lsr, atts.xlink_href);
  2223. lsr_write_any_attribute(lsr, elt, 1);
  2224. lsr_write_group_content(lsr, elt, 0);
  2225. }
  2226. static void lsr_write_path(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag)
  2227. {
  2228. Bool same_fill;
  2229. Bool is_same = 0;
  2230. SVGAllAttributes atts;
  2231. gf_svg_flatten_attributes(elt, &atts);
  2232. if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_path, &same_fill, NULL, 0) ) {
  2233. is_same = 1;
  2234. if (!same_fill) {
  2235. /*samepathfillType*/
  2236. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samepathfill, 6, "ch4");
  2237. lsr_write_id(lsr, (GF_Node *) elt);
  2238. lsr_write_fill(lsr, elt, &atts);
  2239. } else {
  2240. /*samepathType*/
  2241. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samepath, 6, "ch4");
  2242. lsr_write_id(lsr, (GF_Node *) elt);
  2243. }
  2244. lsr_write_path_type(lsr, atts.d, "d");
  2245. } else {
  2246. /*pathType*/
  2247. if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_path, 6, "ch4");
  2248. lsr_write_id(lsr, (GF_Node *) elt);
  2249. lsr_write_rare(lsr, (GF_Node *) elt);
  2250. lsr_write_fill(lsr, elt, &atts);
  2251. lsr_write_stroke(lsr, elt, &atts);
  2252. lsr_write_path_type(lsr, atts.d, "d");
  2253. if (atts.pathLength) {
  2254. GF_LSR_WRITE_INT(lsr, 1, 1, "hasPathLength");
  2255. lsr_write_fixed_16_8(lsr, atts.pathLength->value, "pathLength");
  2256. } else {
  2257. GF_LSR_WRITE_INT(lsr, 0, 1, "hasPathLength");
  2258. }
  2259. lsr_write_any_attribute(lsr, elt, 1);
  2260. lsr->prev_path = elt;
  2261. }
  2262. lsr_write_group_content(lsr, elt, is_same);
  2263. }
  2264. static void lsr_write_polygon(GF_LASeRCodec *lsr, SVG_Element *elt, Bool is_polyline, Bool ommit_tag)
  2265. {
  2266. Bool same_fill, same_stroke;
  2267. Bool same_type = 0;
  2268. SVGAllAttributes atts;
  2269. gf_svg_flatten_attributes(elt, &atts);
  2270. if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_polygon, &same_fill, &same_stroke, 1)
  2271. ) {
  2272. if (same_fill && same_stroke) same_type = 1;
  2273. else if (same_fill) same_type = 3;
  2274. else if (same_stroke) same_type = 2;
  2275. }
  2276. if (same_type) {
  2277. /*samepolylineType / samepolygonType */
  2278. u8 type = is_polyline ? LSR_SCENE_CONTENT_MODEL_samepolyline : LSR_SCENE_CONTENT_MODEL_samepolygon;
  2279. /*samepolylinefillType / samepolygonfillType */
  2280. if (same_type==2) type = is_polyline ? LSR_SCENE_CONTENT_MODEL_samepolylinefill : LSR_SCENE_CONTENT_MODEL_samepolygonfill;
  2281. /*samepolylinestrokeType / samepolygonstrokeType*/
  2282. else if (same_type==3) type = is_polyline ? LSR_SCENE_CONTENT_MODEL_samepolylinestroke : LSR_SCENE_CONTENT_MODEL_samepolygonstroke;
  2283. GF_LSR_WRITE_INT(lsr, type, 6, "ch4");
  2284. lsr_write_id(lsr, (GF_Node *) elt);
  2285. if (same_type==2) lsr_write_fill(lsr, elt, &atts);
  2286. else if (same_type==3) lsr_write_stroke(lsr, elt, &atts);
  2287. lsr_write_point_sequence(lsr, atts.points, "points");
  2288. } else {
  2289. /*polyline/polygon*/
  2290. if (!ommit_tag) GF_LSR_WRITE_INT(lsr, is_polyline ? LSR_SCENE_CONTENT_MODEL_polyline : LSR_SCENE_CONTENT_MODEL_polygon, 6, "ch4");
  2291. lsr_write_id(lsr, (GF_Node *) elt);
  2292. lsr_write_rare(lsr, (GF_Node *) elt);
  2293. lsr_write_fill(lsr, elt, &atts);
  2294. lsr_write_stroke(lsr, elt, &atts);
  2295. lsr_write_point_sequence(lsr, atts.points, "points");
  2296. lsr_write_any_attribute(lsr, elt, 1);
  2297. lsr->prev_polygon = elt;
  2298. }
  2299. lsr_write_group_content(lsr, elt, same_type);
  2300. }
  2301. static void lsr_write_radialGradient(GF_LASeRCodec *lsr, SVG_Element *elt)
  2302. {
  2303. SVGAllAttributes atts;
  2304. gf_svg_flatten_attributes(elt, &atts);
  2305. lsr_write_id(lsr, (GF_Node *) elt);
  2306. lsr_write_rare(lsr, (GF_Node *) elt);
  2307. lsr_write_fill(lsr, elt, &atts);
  2308. lsr_write_stroke(lsr, elt, &atts);
  2309. lsr_write_coordinate_ptr(lsr, atts.cx, 1, "cx");
  2310. lsr_write_coordinate_ptr(lsr, atts.cy, 1, "cy");
  2311. lsr_write_gradient_units(lsr, atts.gradientUnits);
  2312. lsr_write_coordinate_ptr(lsr, atts.r, 1, "r");
  2313. lsr_write_any_attribute(lsr, elt, 1);
  2314. lsr_write_group_content(lsr, elt, 0);
  2315. }
  2316. static void lsr_write_rect(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag)
  2317. {
  2318. Bool same_type = 0;
  2319. Bool same_fill;
  2320. SVGAllAttributes atts;
  2321. gf_svg_flatten_attributes(elt, &atts);
  2322. if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_rect, &same_fill, NULL, 0)
  2323. ) {
  2324. if (!same_fill) {
  2325. same_type = 2;
  2326. /*samerectfillType*/
  2327. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samerectfill, 6, "ch4");
  2328. } else {
  2329. same_type = 1;
  2330. /*samerectType*/
  2331. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samerect, 6, "ch4");
  2332. }
  2333. lsr_write_id(lsr, (GF_Node *) elt);
  2334. if (same_type==2) lsr_write_fill(lsr, elt, &atts);
  2335. lsr_write_coordinate_ptr(lsr, atts.height, 0, "height");
  2336. lsr_write_coordinate_ptr(lsr, atts.width, 0, "width");
  2337. lsr_write_coordinate_ptr(lsr, atts.x, 1, "x");
  2338. lsr_write_coordinate_ptr(lsr, atts.y, 1, "y");
  2339. } else {
  2340. /*rectType*/
  2341. if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_rect, 6, "ch4");
  2342. lsr_write_id(lsr, (GF_Node *) elt);
  2343. lsr_write_rare(lsr, (GF_Node *) elt);
  2344. lsr_write_fill(lsr, elt, &atts);
  2345. lsr_write_stroke(lsr, elt, &atts);
  2346. lsr_write_coordinate_ptr(lsr, atts.height, 0, "height");
  2347. lsr_write_coordinate_ptr(lsr, atts.rx, 1, "rx");
  2348. lsr_write_coordinate_ptr(lsr, atts.ry, 1, "ry");
  2349. lsr_write_coordinate_ptr(lsr, atts.width, 0, "width");
  2350. lsr_write_coordinate_ptr(lsr, atts.x, 1, "x");
  2351. lsr_write_coordinate_ptr(lsr, atts.y, 1, "y");
  2352. lsr_write_any_attribute(lsr, elt, 1);
  2353. lsr->prev_rect = elt;
  2354. }
  2355. lsr_write_group_content(lsr, elt, same_type);
  2356. }
  2357. static void lsr_write_rectClip(GF_LASeRCodec *lsr, SVG_Element *elt)
  2358. {
  2359. SVGAllAttributes atts;
  2360. gf_svg_flatten_attributes(elt, &atts);
  2361. lsr_write_id(lsr, (GF_Node *) elt);
  2362. lsr_write_rare(lsr, (GF_Node *) elt);
  2363. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2364. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2365. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2366. if (atts.size) {
  2367. GF_LSR_WRITE_INT(lsr, 1, 1, "size");
  2368. lsr_write_coordinate(lsr, atts.size->width, 0, "width");
  2369. lsr_write_coordinate(lsr, atts.size->height, 0, "height");
  2370. } else {
  2371. GF_LSR_WRITE_INT(lsr, 0, 1, "size");
  2372. }
  2373. lsr_write_any_attribute(lsr, elt, 1);
  2374. lsr_write_group_content(lsr, elt, 0);
  2375. }
  2376. static void lsr_write_script(GF_LASeRCodec *lsr, SVG_Element *elt)
  2377. {
  2378. SVGAllAttributes atts;
  2379. gf_svg_flatten_attributes(elt, &atts);
  2380. lsr_write_id(lsr, (GF_Node *) elt);
  2381. lsr_write_rare(lsr, (GF_Node *) elt);
  2382. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2383. lsr_write_script_type(lsr, atts.xlink_type);
  2384. lsr_write_href(lsr, atts.xlink_href);
  2385. lsr_write_any_attribute(lsr, elt, 1);
  2386. lsr_write_group_content(lsr, elt, 0);
  2387. }
  2388. static void lsr_write_selector(GF_LASeRCodec *lsr, SVG_Element *elt)
  2389. {
  2390. SVGAllAttributes atts;
  2391. gf_svg_flatten_attributes(elt, &atts);
  2392. lsr_write_id(lsr, (GF_Node *) elt);
  2393. lsr_write_rare(lsr, (GF_Node *) elt);
  2394. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2395. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2396. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2397. GF_LSR_WRITE_INT(lsr, atts.choice ? 1 : 0, 1, "hasChoice");
  2398. if (atts.choice) {
  2399. if (atts.choice->type==LASeR_CHOICE_N) {
  2400. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  2401. GF_LSR_WRITE_INT(lsr, atts.choice->choice_index, 8, "value");
  2402. } else {
  2403. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  2404. GF_LSR_WRITE_INT(lsr, atts.choice->type, 1, "type");
  2405. }
  2406. }
  2407. lsr_write_any_attribute(lsr, elt, 1);
  2408. lsr_write_group_content(lsr, elt, 0);
  2409. }
  2410. static void lsr_write_set(GF_LASeRCodec *lsr, SVG_Element *elt, SVG_Element *parent)
  2411. {
  2412. SVGAllAttributes atts;
  2413. gf_svg_flatten_attributes(elt, &atts);
  2414. lsr_write_id(lsr, (GF_Node *) elt);
  2415. lsr_write_rare(lsr, (GF_Node *) elt);
  2416. lsr_write_animatable(lsr, atts.attributeName, atts.xlink_href, "attributeName");
  2417. lsr_write_attribute_type(lsr, &atts);
  2418. lsr_write_smil_times(lsr, atts.begin, "begin", 1);
  2419. lsr_write_duration(lsr, atts.dur, "dur");
  2420. lsr_write_anim_fill(lsr, atts.smil_fill);
  2421. lsr_write_anim_repeat(lsr, atts.repeatCount);
  2422. lsr_write_repeat_duration(lsr, atts.repeatDur);
  2423. lsr_write_anim_restart(lsr, atts.restart);
  2424. lsr_write_anim_value(lsr, atts.to, "to");
  2425. lsr_write_href_anim(lsr, atts.xlink_href, parent);
  2426. GF_LSR_WRITE_INT(lsr, (atts.lsr_enabled && *atts.lsr_enabled) ? 1 : 0, 1, "enabled");
  2427. lsr_write_any_attribute(lsr, elt, 1);
  2428. lsr_write_group_content(lsr, elt, 0);
  2429. }
  2430. static void lsr_write_simpleLayout(GF_LASeRCodec *lsr, SVG_Element *elt)
  2431. {
  2432. SVGAllAttributes atts;
  2433. gf_svg_flatten_attributes(elt, &atts);
  2434. lsr_write_id(lsr, (GF_Node *) elt);
  2435. lsr_write_rare(lsr, (GF_Node *) elt);
  2436. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2437. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2438. if (atts.delta) {
  2439. GF_LSR_WRITE_INT(lsr, 1, 1, "delta");
  2440. lsr_write_coordinate(lsr, atts.delta->width, 0, "width");
  2441. lsr_write_coordinate(lsr, atts.delta->height, 0, "height");
  2442. } else {
  2443. GF_LSR_WRITE_INT(lsr, 0, 1, "delta");
  2444. }
  2445. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2446. lsr_write_any_attribute(lsr, elt, 1);
  2447. lsr_write_group_content(lsr, elt, 0);
  2448. }
  2449. static void lsr_write_stop(GF_LASeRCodec *lsr, SVG_Element *elt)
  2450. {
  2451. SVGAllAttributes atts;
  2452. gf_svg_flatten_attributes(elt, &atts);
  2453. lsr_write_id(lsr, (GF_Node *) elt);
  2454. lsr_write_rare(lsr, (GF_Node *) elt);
  2455. lsr_write_fill(lsr, elt, &atts);
  2456. lsr_write_stroke(lsr, elt, &atts);
  2457. lsr_write_fixed_16_8(lsr, atts.offset ? atts.offset->value : 0, "offset");
  2458. lsr_write_any_attribute(lsr, elt, 1);
  2459. lsr_write_group_content(lsr, elt, 0);
  2460. }
  2461. static void lsr_write_svg(GF_LASeRCodec *lsr, SVG_Element *elt)
  2462. {
  2463. SMIL_Duration snap;
  2464. SVGAllAttributes atts;
  2465. gf_svg_flatten_attributes(elt, &atts);
  2466. lsr_write_id(lsr, (GF_Node *) elt);
  2467. lsr_write_rare(lsr, (GF_Node *) elt);
  2468. lsr_write_fill(lsr, elt, &atts);
  2469. lsr_write_stroke(lsr, elt, &atts);
  2470. lsr_write_string_attribute(lsr, atts.baseProfile ? *atts.baseProfile : NULL, "baseProfile");
  2471. lsr_write_string_attribute(lsr, atts.contentScriptType ? *atts.contentScriptType : NULL, "contentScriptType");
  2472. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2473. lsr_write_value_with_units(lsr, atts.height, "height");
  2474. GF_LSR_WRITE_INT(lsr, atts.playbackOrder ? 1 : 0, 1, "hasPlaybackOrder");
  2475. if (atts.playbackOrder) GF_LSR_WRITE_INT(lsr, *atts.playbackOrder, 1, "playbackOrder");
  2476. lsr_write_preserve_aspect_ratio(lsr, atts.preserveAspectRatio);
  2477. snap.clock_value = atts.snapshotTime ? *atts.snapshotTime : 0;
  2478. snap.type = snap.clock_value ? SMIL_DURATION_DEFINED : SMIL_DURATION_INDEFINITE;
  2479. lsr_write_duration(lsr, atts.snapshotTime ? &snap : NULL, "has_snapshotTime");
  2480. GF_LSR_WRITE_INT(lsr, atts.syncBehaviorDefault ? 1 : 0, 1, "hasSyncBehavior");
  2481. if (atts.syncBehaviorDefault) {
  2482. switch (*atts.syncBehaviorDefault) {
  2483. case SMIL_SYNCBEHAVIOR_CANSLIP: GF_LSR_WRITE_INT(lsr, 0, 2, "syncBehavior"); break;
  2484. case SMIL_SYNCBEHAVIOR_INDEPENDENT: GF_LSR_WRITE_INT(lsr, 1, 2, "syncBehavior"); break;
  2485. case SMIL_SYNCBEHAVIOR_LOCKED: GF_LSR_WRITE_INT(lsr, 3, 2, "syncBehavior"); break;
  2486. default: GF_LSR_WRITE_INT(lsr, 2, 2, "syncBehavior"); break;
  2487. }
  2488. }
  2489. GF_LSR_WRITE_INT(lsr, atts.syncToleranceDefault ? 1 : 0, 1, "hasSyncToleranceDefault");
  2490. if (atts.syncToleranceDefault) {
  2491. if (atts.syncToleranceDefault->type==SMIL_SYNCTOLERANCE_VALUE) {
  2492. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  2493. lsr_write_vluimsbf5(lsr, (u32) (atts.syncToleranceDefault->value*lsr->time_resolution), "value");
  2494. } else {
  2495. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  2496. }
  2497. }
  2498. GF_LSR_WRITE_INT(lsr, atts.timelineBegin ? 1 : 0, 1, "hasTimelineBegin");
  2499. if (atts.timelineBegin) GF_LSR_WRITE_INT(lsr, *atts.timelineBegin, 1, "timelineBegin");
  2500. lsr_write_string_attribute(lsr, atts.version ? *atts.version : NULL, "version");
  2501. GF_LSR_WRITE_INT(lsr, atts.viewBox ? 1 : 0, 1, "hasViewBox");
  2502. if (atts.viewBox) {
  2503. lsr_write_fixed_16_8(lsr, atts.viewBox->x, "viewbox.x");
  2504. lsr_write_fixed_16_8(lsr, atts.viewBox->y, "viewbox.y");
  2505. lsr_write_fixed_16_8(lsr, atts.viewBox->width, "viewbox.width");
  2506. lsr_write_fixed_16_8(lsr, atts.viewBox->height, "viewbox.height");
  2507. }
  2508. lsr_write_value_with_units(lsr, atts.width, "width");
  2509. GF_LSR_WRITE_INT(lsr, atts.zoomAndPan ? 1 : 0, 1, "hasZoomAndPan");
  2510. if (atts.zoomAndPan) {
  2511. GF_LSR_WRITE_INT(lsr, (*atts.zoomAndPan==SVG_ZOOMANDPAN_MAGNIFY) ? 1 : 0, 1, "zoomAndPan");
  2512. }
  2513. lsr_write_any_attribute(lsr, elt, 1);
  2514. lsr_write_group_content(lsr, elt, 0);
  2515. }
  2516. static void lsr_write_switch(GF_LASeRCodec *lsr, SVG_Element *elt)
  2517. {
  2518. SVGAllAttributes atts;
  2519. gf_svg_flatten_attributes(elt, &atts);
  2520. lsr_write_id(lsr, (GF_Node *) elt);
  2521. lsr_write_rare(lsr, (GF_Node *) elt);
  2522. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2523. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2524. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2525. lsr_write_any_attribute(lsr, elt, 1);
  2526. lsr_write_group_content(lsr, elt, 0);
  2527. }
  2528. static void lsr_write_text(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag)
  2529. {
  2530. Bool same_fill;
  2531. u32 same_type = 0;
  2532. SVGAllAttributes atts;
  2533. gf_svg_flatten_attributes(elt, &atts);
  2534. if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_text, &same_fill, NULL, 0) ) {
  2535. if (!same_fill) {
  2536. /*sametextfillType*/
  2537. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sametextfill, 6, "ch4");
  2538. lsr_write_id(lsr, (GF_Node *) elt);
  2539. lsr_write_fill(lsr, elt, &atts);
  2540. } else {
  2541. /*sametextType*/
  2542. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sametext, 6, "ch4");
  2543. lsr_write_id(lsr, (GF_Node *) elt);
  2544. }
  2545. lsr_write_coord_list(lsr, atts.text_x, "x");
  2546. lsr_write_coord_list(lsr, atts.text_y, "y");
  2547. same_type = 1;
  2548. } else {
  2549. /*textType*/
  2550. if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_text, 6, "ch4");
  2551. lsr_write_id(lsr, (GF_Node *) elt);
  2552. lsr_write_rare(lsr, (GF_Node *) elt);
  2553. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2554. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2555. GF_LSR_WRITE_INT(lsr, (atts.editable && *atts.editable) ? 1 : 0, 1, "editable");
  2556. lsr_write_float_list(lsr, atts.text_rotate, "rotate");
  2557. lsr_write_coord_list(lsr, atts.text_x, "x");
  2558. lsr_write_coord_list(lsr, atts.text_y, "y");
  2559. lsr_write_any_attribute(lsr, elt, 1);
  2560. lsr->prev_text = elt;
  2561. }
  2562. lsr_write_group_content(lsr, elt, same_type);
  2563. }
  2564. static void lsr_write_tspan(GF_LASeRCodec *lsr, SVG_Element *elt)
  2565. {
  2566. SVGAllAttributes atts;
  2567. gf_svg_flatten_attributes(elt, &atts);
  2568. lsr_write_id(lsr, (GF_Node *) elt);
  2569. lsr_write_rare(lsr, (GF_Node *) elt);
  2570. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2571. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2572. lsr_write_any_attribute(lsr, elt, 1);
  2573. lsr_write_group_content(lsr, elt, 0);
  2574. }
  2575. static void lsr_write_use(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag)
  2576. {
  2577. SVGAllAttributes atts;
  2578. Bool is_same = 0;
  2579. gf_svg_flatten_attributes(elt, &atts);
  2580. if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_use, NULL, NULL, 0)
  2581. /*TODO check overflow*/
  2582. ) {
  2583. is_same = 1;
  2584. /*sameuseType*/
  2585. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sameuse, 6, "ch4");
  2586. lsr_write_id(lsr, (GF_Node *) elt);
  2587. lsr_write_href(lsr, atts.xlink_href);
  2588. } else {
  2589. /*useType*/
  2590. if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_use, 6, "ch4");
  2591. lsr_write_id(lsr, (GF_Node *) elt);
  2592. lsr_write_rare(lsr, (GF_Node *) elt);
  2593. lsr_write_fill(lsr, (SVG_Element*)elt, &atts);
  2594. lsr_write_stroke(lsr, (SVG_Element*)elt, &atts);
  2595. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2596. GF_LSR_WRITE_INT(lsr, atts.overflow ? 1 : 0, 1, "hasOverflow");
  2597. /*one value only??*/
  2598. if (atts.overflow) GF_LSR_WRITE_INT(lsr, 0, 2, "overflow");
  2599. lsr_write_coordinate_ptr(lsr, atts.x, 1, "x");
  2600. lsr_write_coordinate_ptr(lsr, atts.y, 1, "y");
  2601. lsr_write_href(lsr, atts.xlink_href);
  2602. lsr_write_any_attribute(lsr, elt, 1);
  2603. lsr->prev_use = elt;
  2604. }
  2605. lsr_write_group_content(lsr, elt, is_same);
  2606. }
  2607. static void lsr_write_video(GF_LASeRCodec *lsr, SVG_Element *elt)
  2608. {
  2609. u32 fs_value;
  2610. SVGAllAttributes atts;
  2611. gf_svg_flatten_attributes(elt, &atts);
  2612. fs_value = 0;
  2613. if (atts.fullscreen) {
  2614. fs_value = *atts.fullscreen + 1;
  2615. atts.fullscreen = NULL;
  2616. }
  2617. lsr_write_id(lsr, (GF_Node *) elt);
  2618. lsr_write_rare(lsr, (GF_Node *) elt);
  2619. lsr_write_smil_times(lsr, atts.begin, "begin", 1);
  2620. lsr_write_duration(lsr, atts.dur, "dur");
  2621. GF_LSR_WRITE_INT(lsr, (atts.externalResourcesRequired && *atts.externalResourcesRequired) ? 1 : 0, 1, "externalResourcesRequired");
  2622. lsr_write_coordinate_ptr(lsr, atts.height, 1, "height");
  2623. GF_LSR_WRITE_INT(lsr, atts.overlay ? 1 : 0, 1, "hasOverlay");
  2624. if (atts.overlay) {
  2625. GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
  2626. GF_LSR_WRITE_INT(lsr, *atts.overlay, 1, "overlay");
  2627. }
  2628. lsr_write_preserve_aspect_ratio(lsr, atts.preserveAspectRatio);
  2629. lsr_write_anim_repeat(lsr, atts.repeatCount);
  2630. lsr_write_repeat_duration(lsr, atts.repeatDur);
  2631. lsr_write_anim_restart(lsr, atts.restart);
  2632. lsr_write_sync_behavior(lsr, atts.syncBehavior, "syncBehavior");
  2633. lsr_write_sync_tolerance(lsr, atts.syncTolerance, "syncBehavior");
  2634. lsr_write_transform_behavior(lsr, atts.transformBehavior);
  2635. lsr_write_content_type(lsr, atts.xlink_type, "type");
  2636. lsr_write_coordinate_ptr(lsr, atts.width, 1, "width");
  2637. lsr_write_coordinate_ptr(lsr, atts.x, 1, "x");
  2638. lsr_write_coordinate_ptr(lsr, atts.y, 1, "y");
  2639. lsr_write_href(lsr, atts.xlink_href);
  2640. lsr_write_clip_time(lsr, atts.clipBegin, "clipBegin");
  2641. lsr_write_clip_time(lsr, atts.clipEnd, "clipEnd");
  2642. GF_LSR_WRITE_INT(lsr, fs_value ? 1 : 0, 1, "hasFullscreen");
  2643. if (atts.fullscreen) GF_LSR_WRITE_INT(lsr, fs_value - 1, 1, "fullscreen");
  2644. GF_LSR_WRITE_INT(lsr, atts.syncReference ? 1 : 0, 1, "hasSyncReference");
  2645. if (atts.syncReference) lsr_write_any_uri(lsr, atts.syncReference, "syncReference");
  2646. lsr_write_any_attribute(lsr, elt, 1);
  2647. lsr_write_group_content(lsr, elt, 0);
  2648. }
  2649. static void lsr_write_listener(GF_LASeRCodec *lsr, SVG_Element *elt)
  2650. {
  2651. SVGAllAttributes atts;
  2652. gf_svg_flatten_attributes(elt, &atts);
  2653. lsr_write_id(lsr, (GF_Node *) elt);
  2654. lsr_write_rare(lsr, (GF_Node *) elt);
  2655. GF_LSR_WRITE_INT(lsr, atts.defaultAction ? 1 : 0, 1, "hasDefaultAction");
  2656. if (atts.defaultAction) GF_LSR_WRITE_INT(lsr, *atts.defaultAction ? 1 : 0, 1, "defaultAction");
  2657. if (atts.event) {
  2658. GF_LSR_WRITE_INT(lsr, 1, 1, "hasEvent");
  2659. lsr_write_event_type(lsr, atts.event->type, atts.event->parameter);
  2660. } else {
  2661. GF_LSR_WRITE_INT(lsr, 0, 1, "hasEvent");
  2662. }
  2663. if (atts.handler && (atts.handler->string || (atts.handler->target && gf_node_get_id((GF_Node *)atts.handler->target) ) )) {
  2664. GF_LSR_WRITE_INT(lsr, 1, 1, "hasHandler");
  2665. lsr_write_any_uri(lsr, atts.handler, "handler");
  2666. } else {
  2667. GF_LSR_WRITE_INT(lsr, 0, 1, "hasHandler");
  2668. }
  2669. if (atts.observer && atts.observer->target && gf_node_get_id((GF_Node *)atts.observer->target) ) {
  2670. GF_LSR_WRITE_INT(lsr, 1, 1, "hasObserver");
  2671. lsr_write_codec_IDREF(lsr, atts.observer, "observer");
  2672. } else {
  2673. if (atts.observer) {
  2674. GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] listener.observer %s not found in scene - skipping it\n", atts.observer->string ));
  2675. }
  2676. GF_LSR_WRITE_INT(lsr, 0, 1, "hasObserver");
  2677. }
  2678. GF_LSR_WRITE_INT(lsr, atts.phase ? 1 : 0, 1, "hasPhase");
  2679. if (atts.phase) GF_LSR_WRITE_INT(lsr, *atts.phase, 1, "phase");
  2680. GF_LSR_WRITE_INT(lsr, atts.propagate ? 1 : 0, 1, "hasPropagate");
  2681. if (atts.propagate) GF_LSR_WRITE_INT(lsr, *atts.propagate, 1, "propagate");
  2682. if (atts.listener_target && atts.listener_target->target && gf_node_get_id((GF_Node *)atts.listener_target->target) ) {
  2683. GF_LSR_WRITE_INT(lsr, 1, 1, "hasTarget");
  2684. lsr_write_codec_IDREF(lsr, atts.listener_target, "target");
  2685. } else {
  2686. GF_LSR_WRITE_INT(lsr, 0, 1, "hasTarget");
  2687. }
  2688. GF_LSR_WRITE_INT(lsr, (atts.lsr_enabled && *atts.lsr_enabled) ? 1 : 0, 1, "enabled");
  2689. lsr_write_any_attribute(lsr, elt, 1);
  2690. lsr_write_group_content(lsr, elt, 0);
  2691. }
  2692. static void lsr_write_scene_content_model(GF_LASeRCodec *lsr, SVG_Element *parent, void *node)
  2693. {
  2694. u32 tag = gf_node_get_tag((GF_Node*)node);
  2695. switch(tag) {
  2696. case TAG_SVG_a:
  2697. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_a, 6, "ch4");
  2698. lsr_write_a(lsr, node);
  2699. break;
  2700. case TAG_SVG_animate:
  2701. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animate, 6, "ch4");
  2702. lsr_write_animate(lsr, node, parent);
  2703. break;
  2704. case TAG_SVG_animateColor:
  2705. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animateColor, 6, "ch4");
  2706. lsr_write_animate(lsr, node, parent);
  2707. break;
  2708. case TAG_SVG_animateMotion:
  2709. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animateMotion, 6, "ch4");
  2710. lsr_write_animateMotion(lsr, node, parent);
  2711. break;
  2712. case TAG_SVG_animateTransform:
  2713. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animateTransform, 6, "ch4");
  2714. lsr_write_animateTransform(lsr, node, parent);
  2715. break;
  2716. case TAG_SVG_audio:
  2717. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_audio, 6, "ch4");
  2718. lsr_write_audio(lsr, node);
  2719. break;
  2720. case TAG_SVG_circle:
  2721. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_circle, 6, "ch4");
  2722. lsr_write_circle(lsr, node);
  2723. break;
  2724. case TAG_LSR_cursorManager: GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_cursorManager, 6, "ch4");
  2725. lsr_write_cursorManager(lsr, node);
  2726. break;
  2727. case TAG_SVG_defs:
  2728. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_defs, 6, "ch4");
  2729. lsr_write_defs(lsr, node);
  2730. break;
  2731. case TAG_SVG_desc:
  2732. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_desc, 6, "ch4");
  2733. lsr_write_data(lsr, node);
  2734. break;
  2735. case TAG_SVG_ellipse:
  2736. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_ellipse, 6, "ch4");
  2737. lsr_write_ellipse(lsr, node);
  2738. break;
  2739. case TAG_SVG_foreignObject:
  2740. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_foreignObject, 6, "ch4");
  2741. lsr_write_foreignObject(lsr, node);
  2742. break;
  2743. case TAG_SVG_g:
  2744. /*type is written in encoding fct for sameg handling*/
  2745. lsr_write_g(lsr, node, 0);
  2746. break;
  2747. case TAG_SVG_image:
  2748. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_image, 6, "ch4");
  2749. lsr_write_image(lsr, node);
  2750. break;
  2751. case TAG_SVG_line:
  2752. /*type is written in encoding fct for sameline handling*/
  2753. lsr_write_line(lsr, node, 0);
  2754. break;
  2755. case TAG_SVG_linearGradient:
  2756. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_linearGradient, 6, "ch4");
  2757. lsr_write_linearGradient(lsr, node);
  2758. break;
  2759. case TAG_SVG_metadata:
  2760. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_metadata, 6, "ch4");
  2761. lsr_write_data(lsr, node);
  2762. break;
  2763. case TAG_SVG_mpath:
  2764. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_mpath, 6, "ch4");
  2765. lsr_write_mpath(lsr, node);
  2766. break;
  2767. case TAG_SVG_path:
  2768. /*type is written in encoding fct for samepath handling*/
  2769. lsr_write_path(lsr, node, 0);
  2770. break;
  2771. case TAG_SVG_polygon:
  2772. /*type is written in encoding fct for samepolygon handling*/
  2773. lsr_write_polygon(lsr, node, 0, 0);
  2774. break;
  2775. case TAG_SVG_polyline:
  2776. /*type is written in encoding fct for samepolyline handling*/
  2777. lsr_write_polygon(lsr, node, 1, 0);
  2778. break;
  2779. case TAG_SVG_radialGradient:
  2780. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_radialGradient, 6, "ch4");
  2781. lsr_write_radialGradient(lsr, node);
  2782. break;
  2783. case TAG_SVG_rect:
  2784. /*type is written in encoding fct for samepolyline handling*/
  2785. lsr_write_rect(lsr, node, 0);
  2786. break;
  2787. case TAG_SVG_script:
  2788. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_script, 6, "ch4");
  2789. lsr_write_script(lsr, node);
  2790. break;
  2791. case TAG_SVG_set:
  2792. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_set, 6, "ch4");
  2793. lsr_write_set(lsr, node, parent);
  2794. break;
  2795. case TAG_SVG_stop:
  2796. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_stop, 6, "ch4");
  2797. lsr_write_stop(lsr, node);
  2798. break;
  2799. case TAG_SVG_switch:
  2800. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_switch, 6, "ch4");
  2801. lsr_write_switch(lsr, node);
  2802. break;
  2803. case TAG_SVG_text:
  2804. /*type is written in encoding fct for sametext handling*/
  2805. lsr_write_text(lsr, node, 0);
  2806. break;
  2807. case TAG_SVG_title:
  2808. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_title, 6, "ch4");
  2809. lsr_write_data(lsr, node);
  2810. break;
  2811. case TAG_SVG_tspan:
  2812. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_tspan, 6, "ch4");
  2813. lsr_write_tspan(lsr, node);
  2814. break;
  2815. case TAG_SVG_use:
  2816. /*type is written in encoding fct for sameuse handling*/
  2817. lsr_write_use(lsr, node, 0);
  2818. break;
  2819. case TAG_SVG_video:
  2820. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_video, 6, "ch4");
  2821. lsr_write_video(lsr, node);
  2822. break;
  2823. case TAG_SVG_listener:
  2824. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_listener, 6, "ch4");
  2825. lsr_write_listener(lsr, node);
  2826. break;
  2827. case TAG_LSR_conditional:
  2828. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_conditional, 6, "ch4");
  2829. lsr_write_conditional(lsr, node);
  2830. break;
  2831. case TAG_LSR_rectClip:
  2832. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_rectClip, 6, "ch4");
  2833. lsr_write_rectClip(lsr, node);
  2834. break;
  2835. case TAG_LSR_selector:
  2836. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_selector, 6, "ch4");
  2837. lsr_write_selector(lsr, node);
  2838. break;
  2839. case TAG_LSR_simpleLayout:
  2840. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_simpleLayout, 6, "ch4");
  2841. lsr_write_simpleLayout(lsr, node);
  2842. break;
  2843. #if 0
  2844. /*case privateElement*/
  2845. case TAG_SVG_extendElement:
  2846. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_privateContainer, 6, "ch4");
  2847. lsr_write_private_element_container(lsr);
  2848. break;
  2849. #endif
  2850. default:
  2851. #if 0
  2852. /*case extend*/
  2853. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_element_any, 6, "ch4");
  2854. lsr_write_extend_class(lsr, NULL, 0, node);
  2855. break;
  2856. #else
  2857. /*hack for encoding - needs cleaning*/
  2858. GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] node %s not part of LASeR children nodes - skipping\n", gf_node_get_class_name((GF_Node*)node)));
  2859. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_textContent, 6, "ch4");
  2860. lsr_write_byte_align_string(lsr, "", "textContent");
  2861. break;
  2862. #endif
  2863. }
  2864. }
  2865. static void lsr_write_update_content_model(GF_LASeRCodec *lsr, SVG_Element *parent, void *node)
  2866. {
  2867. u32 tag = gf_node_get_tag((GF_Node*)node);
  2868. if (tag==TAG_LSR_conditional) {
  2869. GF_LSR_WRITE_INT(lsr, 1, 1, "ch4");
  2870. GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_conditional, 3, "ch61");
  2871. lsr_write_conditional(lsr, node);
  2872. } else if (tag==TAG_LSR_cursorManager) {
  2873. GF_LSR_WRITE_INT(lsr, 1, 1, "ch4");
  2874. GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_cursorManager, 3, "ch61");
  2875. lsr_write_cursorManager(lsr, node);
  2876. } else if (tag==TAG_LSR_rectClip) {
  2877. GF_LSR_WRITE_INT(lsr, 1, 1, "ch4");
  2878. GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_rectClip, 3, "ch61");
  2879. lsr_write_rectClip(lsr, node);
  2880. } else if (tag==TAG_LSR_selector) {
  2881. GF_LSR_WRITE_INT(lsr, 1, 1, "ch4");
  2882. GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_selector, 3, "ch61");
  2883. lsr_write_selector(lsr, node);
  2884. } else if (tag==TAG_LSR_simpleLayout) {
  2885. GF_LSR_WRITE_INT(lsr, 1, 1, "ch4");
  2886. GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_simpleLayout, 3, "ch61");
  2887. lsr_write_simpleLayout(lsr, node);
  2888. } else {
  2889. GF_LSR_WRITE_INT(lsr, 0, 1, "ch4");
  2890. switch(tag) {
  2891. case TAG_SVG_a: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_a, 6, "ch6"); lsr_write_a(lsr, node); break;
  2892. case TAG_SVG_animate: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_animate, 6, "ch6"); lsr_write_animate(lsr, node, parent); break;
  2893. case TAG_SVG_animateColor: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_animateColor, 6, "ch6"); lsr_write_animate(lsr, node, parent); break;
  2894. case TAG_SVG_animateMotion: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_animateMotion, 6, "ch6"); lsr_write_animateMotion(lsr, node, parent); break;
  2895. case TAG_SVG_animateTransform: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_animateTransform, 6, "ch6"); lsr_write_animateTransform(lsr, node, parent); break;
  2896. case TAG_SVG_audio: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_audio, 6, "ch6"); lsr_write_audio(lsr, node); break;
  2897. case TAG_SVG_circle: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_circle, 6, "ch6"); lsr_write_circle(lsr, node); break;
  2898. case TAG_SVG_defs: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_defs, 6, "ch6"); lsr_write_defs(lsr, node); break;
  2899. case TAG_SVG_desc: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_desc, 6, "ch6"); lsr_write_data(lsr, node); break;
  2900. case TAG_SVG_ellipse: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_ellipse, 6, "ch6"); lsr_write_ellipse(lsr, node); break;
  2901. case TAG_SVG_foreignObject: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_foreignObject, 6, "ch6"); lsr_write_foreignObject(lsr, node); break;
  2902. case TAG_SVG_g: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_g, 6, "ch6"); lsr_write_g(lsr, node, 1); break;
  2903. case TAG_SVG_image: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_image, 6, "ch6"); lsr_write_image(lsr, node); break;
  2904. case TAG_SVG_line: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_line, 6, "ch6"); lsr_write_line(lsr, node, 1); break;
  2905. case TAG_SVG_linearGradient: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_linearGradient, 6, "ch6"); lsr_write_linearGradient(lsr, node); break;
  2906. case TAG_SVG_metadata: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_metadata, 6, "ch6"); lsr_write_data(lsr, node); break;
  2907. case TAG_SVG_mpath: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_mpath, 6, "ch6"); lsr_write_mpath(lsr, node); break;
  2908. case TAG_SVG_path: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_path, 6, "ch6"); lsr_write_path(lsr, node, 1); break;
  2909. case TAG_SVG_polygon: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_polygon, 6, "ch6"); lsr_write_polygon(lsr, node, 0, 1); break;
  2910. case TAG_SVG_polyline: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_polyline, 6, "ch6"); lsr_write_polygon(lsr, node, 1, 1); break;
  2911. case TAG_SVG_radialGradient: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_radialGradient, 6, "ch6"); lsr_write_radialGradient(lsr, node); break;
  2912. case TAG_SVG_rect: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_rect, 6, "ch6"); lsr_write_rect(lsr, node, 1); break;
  2913. case TAG_SVG_script: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_script, 6, "ch6"); lsr_write_script(lsr, node); break;
  2914. case TAG_SVG_set: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_set, 6, "ch6"); lsr_write_set(lsr, node, parent); break;
  2915. case TAG_SVG_stop: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_stop, 6, "ch6"); lsr_write_stop(lsr, node); break;
  2916. case TAG_SVG_svg: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_svg, 6, "ch6"); lsr_write_svg(lsr, node); break;
  2917. case TAG_SVG_switch: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_switch, 6, "ch6"); lsr_write_switch(lsr, node); break;
  2918. case TAG_SVG_text: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_text, 6, "ch6"); lsr_write_text(lsr, node, 1); break;
  2919. case TAG_SVG_title: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_title, 6, "ch6"); lsr_write_data(lsr, node); break;
  2920. case TAG_SVG_tspan: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_tspan, 6, "ch6"); lsr_write_tspan(lsr, node); break;
  2921. case TAG_SVG_use: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_use, 6, "ch6"); lsr_write_use(lsr, node, 1); break;
  2922. case TAG_SVG_video: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_video, 6, "ch6"); lsr_write_video(lsr, node); break;
  2923. case TAG_SVG_listener: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_listener, 6, "ch6"); lsr_write_listener(lsr, node); break;
  2924. }
  2925. }
  2926. }
  2927. static void lsr_write_group_content(GF_LASeRCodec *lsr, SVG_Element *elt, Bool skip_object_content)
  2928. {
  2929. GF_ChildNodeItem *l;
  2930. u32 count;
  2931. if (!skip_object_content) lsr_write_private_attributes(lsr, elt);
  2932. count = gf_node_list_get_count(elt->children);
  2933. l = elt->children;
  2934. if (!count) {
  2935. GF_LSR_WRITE_INT(lsr, 0, 1, "opt_group");
  2936. return;
  2937. }
  2938. GF_LSR_WRITE_INT(lsr, 1, 1, "opt_group");
  2939. lsr_write_vluimsbf5(lsr, count, "occ0");
  2940. while (l) {
  2941. if (gf_node_get_tag(l->node)==TAG_DOMText) {
  2942. GF_DOMText *txt = (GF_DOMText *)l->node;
  2943. GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_textContent, 6, "ch4");
  2944. lsr_write_byte_align_string(lsr, txt->textContent, "textContent");
  2945. } else {
  2946. lsr_write_scene_content_model(lsr, elt, l->node);
  2947. GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] ############## end %s ###########\n", gf_node_get_class_name((GF_Node*)l->node)));
  2948. }
  2949. l = l->next;
  2950. }
  2951. }
  2952. static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fieldType, u32 att_tag, u32 transformType, void *val, Bool is_indexed)
  2953. {
  2954. SVG_Number *n;
  2955. if (is_indexed) {
  2956. assert(gf_list_count(*(GF_List **)val));
  2957. switch (fieldType) {
  2958. case SVG_Points_datatype:/*points*/
  2959. {
  2960. GF_Point2D *pt = gf_list_get(*(GF_List **)val, 0);
  2961. lsr_write_coordinate(lsr, pt->x, 0, "x");
  2962. lsr_write_coordinate(lsr, pt->y, 0, "y");
  2963. }
  2964. break;
  2965. case SMIL_Times_datatype:/*smil_times*/
  2966. {
  2967. SMIL_Time *st = gf_list_get(*(GF_List **)val, 0);
  2968. lsr_write_smil_time(lsr, st);
  2969. }
  2970. break;
  2971. case SMIL_KeyPoints_datatype:/*0to1*/
  2972. {
  2973. Fixed *f = gf_list_get(*(GF_List **)val, 0);
  2974. lsr_write_fixed_clamp(lsr, *f, "v");
  2975. }
  2976. break;
  2977. case SMIL_KeySplines_datatype:/*float*/
  2978. {
  2979. Fixed *f = gf_list_get(*(GF_List **)val, 0);
  2980. lsr_write_fixed_16_8(lsr, *f, "v");
  2981. }
  2982. break;
  2983. case SMIL_KeyTimes_datatype:/*keyTime*/
  2984. {
  2985. Fixed *v = gf_list_get(*(GF_List **)val, 0);
  2986. Fixed f = *v;
  2987. if ((f==0) || (f==FIX_ONE)) {
  2988. GF_LSR_WRITE_INT(lsr, 1, 1, "hasShort");
  2989. GF_LSR_WRITE_INT(lsr, (f==0) ? 0 : 1, 1, "isZero");
  2990. } else {
  2991. GF_LSR_WRITE_INT(lsr, 0, 1, "hasShort");
  2992. lsr_write_fixed_clamp(lsr, f, "timevalue");
  2993. }
  2994. }
  2995. break;
  2996. case SVG_StrokeDashArray_datatype:/*float*/
  2997. case SVG_ViewBox_datatype:/*float*/
  2998. break;
  2999. case DOM_StringList_datatype:
  3000. if (att_tag==TAG_SVG_ATT_requiredFeatures) {
  3001. /*int*/
  3002. }
  3003. break;
  3004. }
  3005. } else {
  3006. switch (fieldType) {
  3007. case SVG_Boolean_datatype:
  3008. GF_LSR_WRITE_INT(lsr, *(SVG_Boolean*)val ? 1 : 0, 1, "val");
  3009. break;
  3010. case SVG_Paint_datatype:
  3011. lsr_write_paint(lsr, (SVG_Paint *)val, "val");
  3012. break;
  3013. case SVG_Transform_datatype:
  3014. lsr_write_matrix(lsr, (SVG_Transform*)val);
  3015. break;
  3016. case SVG_Transform_Scale_datatype:
  3017. lsr_write_fixed_16_8(lsr, ((SVG_Point *)val)->x, "scale_x");
  3018. lsr_write_fixed_16_8(lsr, ((SVG_Point *)val)->y, "scale_y");
  3019. break;
  3020. case LASeR_Size_datatype:
  3021. case SVG_Transform_Translate_datatype:
  3022. lsr_write_coordinate(lsr, ((SVG_Point *)val)->x, 0, "translation_x");
  3023. lsr_write_coordinate(lsr, ((SVG_Point *)val)->y, 0, "translation_y");
  3024. break;
  3025. case SVG_Transform_Rotate_datatype:
  3026. GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue");
  3027. GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag");
  3028. lsr_write_fixed_16_8(lsr, ((SVG_Point_Angle*)val)->angle, "rotate");
  3029. break;
  3030. case SVG_Number_datatype:
  3031. case SVG_FontSize_datatype:
  3032. case SVG_Length_datatype:
  3033. n = (SVG_Number*)val;
  3034. switch (att_tag) {
  3035. /*fractions*/
  3036. case TAG_SVG_ATT_audio_level:
  3037. case TAG_SVG_ATT_fill_opacity:
  3038. case TAG_SVG_ATT_offset:
  3039. case TAG_SVG_ATT_opacity:
  3040. case TAG_SVG_ATT_solid_opacity:
  3041. case TAG_SVG_ATT_stop_opacity:
  3042. case TAG_SVG_ATT_stroke_opacity:
  3043. case TAG_SVG_ATT_viewport_fill_opacity:
  3044. if (n->type==SVG_NUMBER_INHERIT) {
  3045. GF_LSR_WRITE_INT(lsr, 1, 1, "isDefaultValue");
  3046. } else {
  3047. GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue");
  3048. lsr_write_fixed_clamp(lsr, n->value, "val");
  3049. }
  3050. break;
  3051. case TAG_SVG_ATT_width:
  3052. case TAG_SVG_ATT_height:
  3053. if (elt->sgprivate->tag==TAG_SVG_svg) {
  3054. lsr_write_value_with_units(lsr, n, "val");
  3055. } else {
  3056. lsr_write_coordinate(lsr, n->value, 0, "val");
  3057. }
  3058. break;
  3059. default:
  3060. if (n->type==SVG_NUMBER_INHERIT) {
  3061. GF_LSR_WRITE_INT(lsr, 1, 1, "isDefaultValue");
  3062. } else {
  3063. GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue");
  3064. GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag");
  3065. lsr_write_fixed_16_8(lsr, n->value, "val");
  3066. }
  3067. }
  3068. break;
  3069. case SVG_Rotate_datatype:
  3070. n = (SVG_Number*)val;
  3071. if (n->type==SVG_NUMBER_INHERIT) {
  3072. GF_LSR_WRITE_INT(lsr, 1, 1, "isDefaultValue");
  3073. } else {
  3074. GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue");
  3075. if ((n->type == SVG_NUMBER_AUTO) || (n->type == SVG_NUMBER_AUTO_REVERSE)) {
  3076. GF_LSR_WRITE_INT(lsr, 1, 1, "escapeFlag");
  3077. GF_LSR_WRITE_INT(lsr, (n->type == SVG_NUMBER_AUTO) ? 0 : 1, 2, "rotate");
  3078. } else {
  3079. GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag");
  3080. lsr_write_fixed_16_8(lsr, n->value, "rotate");
  3081. }
  3082. }
  3083. break;
  3084. case SVG_Coordinate_datatype:
  3085. n = (SVG_Number*)val;
  3086. lsr_write_coordinate(lsr, n->value, 0, "val");
  3087. break;
  3088. case SVG_Coordinates_datatype:
  3089. GF_LSR_WRITE_INT(lsr, 0, 1, "isInherit");
  3090. GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag");
  3091. lsr_write_float_list(lsr, (GF_List **)val, "val");
  3092. break;
  3093. case XMLRI_datatype:
  3094. if ((att_tag==TAG_XLINK_ATT_href) || (att_tag==TAG_SVG_ATT_syncReference)) {
  3095. lsr_write_any_uri(lsr, (XMLRI*)val, "val");
  3096. } else if (((XMLRI*)val)->target) {
  3097. GF_LSR_WRITE_INT(lsr, 0, 1, "isDefault");
  3098. GF_LSR_WRITE_INT(lsr, 0, 1, "isEscape");
  3099. lsr_write_vluimsbf5(lsr, gf_node_get_id( ((XMLRI*)val)->target) - 1, "ID");
  3100. } else {
  3101. GF_LSR_WRITE_INT(lsr, 1, 1, "isDefault");
  3102. }
  3103. break;
  3104. case SVG_Focus_datatype:
  3105. if ( (((SVG_Focus*)val)->type == SVG_FOCUS_AUTO) || !((SVG_Focus*)val)->target.target) {
  3106. GF_LSR_WRITE_INT(lsr, 1, 1, "isDefault");
  3107. } else if (((SVG_Focus*)val)->type == SVG_FOCUS_SELF) {
  3108. GF_LSR_WRITE_INT(lsr, 0, 1, "isDefault");
  3109. GF_LSR_WRITE_INT(lsr, 1, 1, "isEscape");
  3110. GF_LSR_WRITE_INT(lsr, 1, 2, "escapeEnumVal");
  3111. } else {
  3112. GF_LSR_WRITE_INT(lsr, 0, 1, "isDefault");
  3113. GF_LSR_WRITE_INT(lsr, 0, 1, "isEscape");
  3114. lsr_write_vluimsbf5(lsr, gf_node_get_id( ((SVG_Focus*)val)->target.target) - 1, "ID");
  3115. }
  3116. break;
  3117. case DOM_String_datatype:
  3118. case SVG_ContentType_datatype:
  3119. case SVG_LanguageID_datatype:
  3120. lsr_write_byte_align_string(lsr, val ? *(DOM_String *)val : (char *)"", "val");
  3121. break;
  3122. case SVG_Motion_datatype:
  3123. lsr_write_coordinate(lsr, ((GF_Matrix2D *)val)->m[2], 0, "pointValueX");
  3124. lsr_write_coordinate(lsr, ((GF_Matrix2D *)val)->m[5], 0, "pointValueY");
  3125. break;
  3126. case SVG_Points_datatype:
  3127. lsr_write_point_sequence(lsr, (GF_List **)val, "val");
  3128. break;
  3129. case SVG_PathData_datatype:
  3130. lsr_write_path_type(lsr, (SVG_PathData*)val, "val");
  3131. break;
  3132. case LASeR_Choice_datatype:
  3133. {
  3134. LASeR_Choice *ch = (LASeR_Choice *)val;
  3135. GF_LSR_WRITE_INT(lsr, (ch->type==LASeR_CHOICE_ALL) ? 1 : 0, 1, "isDefaultValue");
  3136. if (ch->type!=LASeR_CHOICE_ALL) {
  3137. GF_LSR_WRITE_INT(lsr, (ch->type==LASeR_CHOICE_NONE) ? 1 : 0, 1, "escapeFlag");
  3138. if (ch->type==LASeR_CHOICE_NONE) {
  3139. GF_LSR_WRITE_INT(lsr, LASeR_CHOICE_NONE, 2, "escapeEnum");
  3140. } else {
  3141. lsr_write_vluimsbf5(lsr, ((LASeR_Choice *)val)->choice_index, "value");
  3142. }
  3143. }
  3144. }
  3145. break;
  3146. case SVG_ViewBox_datatype:
  3147. {
  3148. SVG_ViewBox *b = (SVG_ViewBox *)val;
  3149. GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue");
  3150. GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag");
  3151. lsr_write_vluimsbf5(lsr, 4, "nb1");
  3152. lsr_write_fixed_16_8(lsr, b->x, "x");
  3153. lsr_write_fixed_16_8(lsr, b->y, "y");
  3154. lsr_write_fixed_16_8(lsr, b->width, "width");
  3155. lsr_write_fixed_16_8(lsr, b->width, "height");
  3156. }
  3157. break;
  3158. case SVG_FontFamily_datatype:
  3159. {
  3160. SVG_FontFamily *ff = (SVG_FontFamily *)val;
  3161. GF_LSR_WRITE_INT(lsr, (ff->type == SVG_FONTFAMILY_INHERIT) ? 1 : 0, 1, "isDefaultValue");
  3162. if (ff->type != SVG_FONTFAMILY_INHERIT) {
  3163. s32 idx = lsr_get_font_index(lsr, ff);
  3164. if (idx==-1) {
  3165. GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] corrupted font table while encoding update value\n"));
  3166. idx=0;
  3167. }
  3168. GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag");
  3169. lsr_write_vluimsbf5(lsr, (u32) idx, "nb1");
  3170. }
  3171. }
  3172. break;
  3173. default:
  3174. if ((fieldType>=SVG_FillRule_datatype) && (fieldType<=SVG_LAST_U8_PROPERTY)) {
  3175. u8 v = *(u8 *)val;
  3176. /*TODO fixme, check inherit/default values*/
  3177. if (!v) {
  3178. GF_LSR_WRITE_INT(lsr, 1, 1, "isDefaultValue");
  3179. } else {
  3180. GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue");
  3181. lsr_write_vluimsbf5(lsr, v, "val");
  3182. }
  3183. } else {
  3184. GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] update value not implemented for type %d - please fix or report\n", fieldType));
  3185. }
  3186. }
  3187. }
  3188. }
  3189. /*FIXME - support for scale/translate/rotation*/
  3190. static GF_Err lsr_write_add_replace_insert(GF_LASeRCodec *lsr, GF_Command *com)
  3191. {
  3192. GF_CommandField *field;
  3193. u8 type = 0;
  3194. Bool is_text_node = 0;
  3195. u32 field_type, tr_type = 0;
  3196. if (com->tag==GF_SG_LSR_REPLACE) type = LSR_UPDATE_REPLACE;
  3197. else if (com->tag==GF_SG_LSR_ADD) type = LSR_UPDATE_ADD;
  3198. else if (com->tag==GF_SG_LSR_INSERT) type = LSR_UPDATE_INSERT;
  3199. else return GF_BAD_PARAM;
  3200. GF_LSR_WRITE_INT(lsr, type, 4, "ch4");
  3201. field = (GF_CommandField*)gf_list_get(com->command_fields, 0);
  3202. field_type = 0;
  3203. if (field && ( !field->new_node || (field->fieldIndex==TAG_LSR_ATT_children) ) && !field->node_list) {
  3204. s32 attType = 0;
  3205. field_type = field->fieldType;
  3206. attType = gf_lsr_anim_type_from_attribute(field->fieldIndex);
  3207. if (attType== -1) {
  3208. GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[LASeR] Attribute %s of element %s is not updatable\n", gf_svg_get_attribute_name(com->node, field->fieldIndex), gf_node_get_class_name(com->node) ));
  3209. return lsr->last_error = GF_BAD_PARAM;
  3210. }
  3211. GF_LSR_WRITE_INT(lsr, 1, 1, "has_attributeName");
  3212. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  3213. GF_LSR_WRITE_INT(lsr, attType, 8, "attributeName");
  3214. }
  3215. /*single text */
  3216. else if (field->new_node->sgprivate->tag==TAG_DOMText) {
  3217. GF_LSR_WRITE_INT(lsr, 1, 1, "has_attributeName");
  3218. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  3219. GF_LSR_WRITE_INT(lsr, LSR_UPDATE_TYPE_TEXT_CONTENT, 8, "attributeName");
  3220. is_text_node = 1;
  3221. } else {
  3222. GF_LSR_WRITE_INT(lsr, 0, 1, "has_attributeName");
  3223. }
  3224. /*if not add*/
  3225. if (type!=LSR_UPDATE_ADD) {
  3226. if (!field || field->pos<0) {
  3227. GF_LSR_WRITE_INT(lsr, 0, 1, "has_index");
  3228. } else {
  3229. GF_LSR_WRITE_INT(lsr, 1, 1, "has_index");
  3230. lsr_write_vluimsbf5(lsr, (u32) field->pos, "index");
  3231. }
  3232. }
  3233. if (type!=LSR_UPDATE_INSERT) {
  3234. if (com->fromNodeID) {
  3235. u8 opAttType;
  3236. opAttType = gf_lsr_anim_type_from_attribute(com->fromFieldIndex);
  3237. GF_LSR_WRITE_INT(lsr, 1, 1, "has_operandAttribute");
  3238. GF_LSR_WRITE_INT(lsr, opAttType, 8, "operandAttribute");
  3239. GF_LSR_WRITE_INT(lsr, 1, 1, "has_operandElementId");
  3240. lsr_write_vluimsbf5(lsr, com->fromNodeID-1, "operandElementId");
  3241. } else {
  3242. GF_LSR_WRITE_INT(lsr, 0, 1, "has_operandAttribute");
  3243. GF_LSR_WRITE_INT(lsr, 0, 1, "has_operandElementId");
  3244. }
  3245. }
  3246. lsr_write_codec_IDREF_Node(lsr, com->node, "ref");
  3247. if (field && !field->new_node && !field->node_list && !com->fromNodeID) {
  3248. GF_LSR_WRITE_INT(lsr, 1, 1, "has_value");
  3249. lsr_write_update_value(lsr, (SVG_Element *)com->node, field_type, field->fieldIndex, tr_type, field->field_ptr, (field->pos>=0) ? 1 : 0);
  3250. } else if (is_text_node) {
  3251. GF_DOMText *t = (GF_DOMText *)field->new_node;
  3252. GF_LSR_WRITE_INT(lsr, 1, 1, "has_value");
  3253. lsr_write_update_value(lsr, (SVG_Element *)com->node, DOM_String_datatype, field->fieldIndex, 0, &t->textContent, (field->pos>=0) ? 1 : 0);
  3254. } else {
  3255. GF_LSR_WRITE_INT(lsr, 0, 1, "has_value");
  3256. }
  3257. lsr_write_any_attribute(lsr, NULL, 1);
  3258. /*if not add*/
  3259. if (type!=LSR_UPDATE_ADD) {
  3260. if (field && field->node_list && !com->fromNodeID) {
  3261. GF_ChildNodeItem *l = field->node_list;
  3262. u32 count = gf_node_list_get_count(l);
  3263. GF_LSR_WRITE_INT(lsr, 1, 1, "opt_group");
  3264. if (type==LSR_UPDATE_REPLACE) lsr_write_vluimsbf5(lsr, count, "count");
  3265. while (l) {
  3266. lsr_write_update_content_model(lsr, (SVG_Element*) com->node, l->node);
  3267. l = l->next;
  3268. if (type==LSR_UPDATE_INSERT) break;
  3269. }
  3270. } else if (field && field->new_node && !is_text_node) {
  3271. GF_LSR_WRITE_INT(lsr, 1, 1, "opt_group");
  3272. if (type==LSR_UPDATE_REPLACE) lsr_write_vluimsbf5(lsr, 1, "count");
  3273. lsr_write_update_content_model(lsr, (SVG_Element*) com->node, field->new_node);
  3274. } else {
  3275. GF_LSR_WRITE_INT(lsr, 0, 1, "opt_group");
  3276. }
  3277. }
  3278. return GF_OK;
  3279. }
  3280. static GF_Err lsr_write_command_list(GF_LASeRCodec *lsr, GF_List *com_list, SVG_Element *cond, Bool first_implicit)
  3281. {
  3282. GF_CommandField *field;
  3283. u32 i, count;
  3284. u32 detail;
  3285. GF_BitStream *old_bs;
  3286. count = com_list ? gf_list_count(com_list) : 0;
  3287. old_bs = NULL;
  3288. if (cond) {
  3289. /*use temp bitstream for encoding conditional*/
  3290. old_bs = lsr->bs;
  3291. lsr->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
  3292. }
  3293. assert(count>= (u32) (first_implicit ? 1 : 0) );
  3294. lsr_write_vluimsbf5(lsr, count-first_implicit, "occ0");
  3295. if (!com_list) goto exit;
  3296. count = gf_list_count(com_list);
  3297. for (i=0; i<count; i++) {
  3298. GF_Command *com = (GF_Command *)gf_list_get(com_list, i);
  3299. switch (com->tag) {
  3300. case GF_SG_LSR_NEW_SCENE:
  3301. case GF_SG_LSR_REFRESH_SCENE:
  3302. GF_LSR_WRITE_INT(lsr, (com->tag==GF_SG_LSR_REFRESH_SCENE) ? LSR_UPDATE_REFRESH_SCENE : LSR_UPDATE_NEW_SCENE, 4, "ch4");
  3303. if (com->tag==GF_SG_LSR_REFRESH_SCENE) lsr_write_vluimsbf5(lsr, /*refresh scene time*/0, "time");
  3304. lsr_write_any_attribute(lsr, NULL, 1);
  3305. lsr_write_svg(lsr, (SVG_Element*)com->node);
  3306. break;
  3307. case GF_SG_LSR_REPLACE:
  3308. case GF_SG_LSR_ADD:
  3309. case GF_SG_LSR_INSERT:
  3310. lsr_write_add_replace_insert(lsr, com);
  3311. break;
  3312. case GF_SG_LSR_CLEAN:
  3313. break;
  3314. case GF_SG_LSR_DELETE:
  3315. GF_LSR_WRITE_INT(lsr, LSR_UPDATE_DELETE, 4, "ch4");
  3316. field = (GF_CommandField*)gf_list_get(com->command_fields, 0);
  3317. if (field && field->fieldType) {
  3318. u8 attType;
  3319. attType = gf_lsr_anim_type_from_attribute(field->fieldIndex);
  3320. GF_LSR_WRITE_INT(lsr, 1, 1, "has_attributeName");
  3321. GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
  3322. GF_LSR_WRITE_INT(lsr, attType, 8, "attributeName");
  3323. } else {
  3324. GF_LSR_WRITE_INT(lsr, 0, 1, "has_attributeName");
  3325. }
  3326. if (!field || (field->pos<0) ) {
  3327. GF_LSR_WRITE_INT(lsr, 0, 1, "has_index");
  3328. } else {
  3329. GF_LSR_WRITE_INT(lsr, 1, 1, "has_index");
  3330. lsr_write_vluimsbf5(lsr, (u32) field->pos, "index");
  3331. }
  3332. lsr_write_codec_IDREF_Node(lsr, com->node, "ref");
  3333. lsr_write_any_attribute(lsr, NULL, 1);
  3334. break;
  3335. case GF_SG_LSR_RESTORE:
  3336. return GF_NOT_SUPPORTED;
  3337. case GF_SG_LSR_SAVE:
  3338. return GF_NOT_SUPPORTED;
  3339. case GF_SG_LSR_SEND_EVENT:
  3340. GF_LSR_WRITE_INT(lsr, LSR_UPDATE_SEND_EVENT, 4, "ch4");
  3341. detail = com->send_event_integer;
  3342. switch (com->send_event_name) {
  3343. case GF_EVENT_KEYDOWN:
  3344. case GF_EVENT_LONGKEYPRESS:
  3345. case GF_EVENT_REPEAT_KEY:
  3346. case GF_EVENT_SHORT_ACCESSKEY:
  3347. detail = dom_to_lsr_key(detail);
  3348. if (detail==100) detail = 0;
  3349. break;
  3350. }
  3351. /*FIXME in the spec, way too obscur*/
  3352. lsr_write_event_type(lsr, com->send_event_name, com->send_event_integer);
  3353. if (detail && com->send_event_integer) {
  3354. GF_LSR_WRITE_INT(lsr, 1, 1, "has_intvalue");
  3355. GF_LSR_WRITE_INT(lsr, (com->send_event_integer<0) ? 1 : 0, 1, "sign");
  3356. lsr_write_vluimsbf5(lsr, ABS(com->send_event_integer), "value");
  3357. } else {
  3358. GF_LSR_WRITE_INT(lsr, 0, 1, "has_intvalue");
  3359. }
  3360. if (com->send_event_name<=GF_EVENT_MOUSEWHEEL) {
  3361. GF_LSR_WRITE_INT(lsr, 1, 1, "has_pointvalue");
  3362. lsr_write_coordinate(lsr, INT2FIX(com->send_event_x), 0, "x");
  3363. lsr_write_coordinate(lsr, INT2FIX(com->send_event_y), 0, "y");
  3364. } else {
  3365. GF_LSR_WRITE_INT(lsr, 0, 1, "has_pointvalue");
  3366. }
  3367. lsr_write_codec_IDREF_Node(lsr, com->node, "ref");
  3368. if (com->send_event_string) {
  3369. GF_LSR_WRITE_INT(lsr, 1, 1, "has_stringvalue");
  3370. lsr_write_byte_align_string(lsr, com->send_event_string, "stringvalue");
  3371. } else if (!detail && com->send_event_integer) {
  3372. GF_LSR_WRITE_INT(lsr, 1, 1, "has_stringvalue");
  3373. lsr_write_byte_align_string(lsr, (char *)gf_dom_get_key_name(com->send_event_integer), "stringvalue");
  3374. } else {
  3375. GF_LSR_WRITE_INT(lsr, 0, 1, "has_stringvalue");
  3376. }
  3377. GF_LSR_WRITE_INT(lsr, 0, 1, "has_attr_any");
  3378. return GF_OK;
  3379. case GF_SG_LSR_ACTIVATE:
  3380. case GF_SG_LSR_DEACTIVATE:
  3381. {
  3382. u32 update_size = lsr_get_IDREF_nb_bits(lsr, com->node);
  3383. GF_LSR_WRITE_INT(lsr, LSR_UPDATE_EXTEND, 4, "ch4");
  3384. GF_LSR_WRITE_INT(lsr, 2, lsr->info->cfg.extensionIDBits, "extensionID");
  3385. lsr_write_vluimsbf5(lsr, 10 + 5 /*occ2*/ + 2 /*reserved*/ + 5 /*occ3*/ + 2 /*ch5*/ + update_size, "len");
  3386. lsr_write_vluimsbf5(lsr, 87, "reserved");
  3387. lsr_write_vluimsbf5(lsr, 1, "occ2");
  3388. GF_LSR_WRITE_INT(lsr, 1, 2, "reserved");
  3389. lsr_write_vluimsbf5(lsr, 1, "occ3");
  3390. GF_LSR_WRITE_INT(lsr, (com->tag==GF_SG_LSR_ACTIVATE) ? 1 : 2, 2, "ch5");
  3391. lsr_write_codec_IDREF_Node(lsr, com->node, "ref");
  3392. }
  3393. break;
  3394. default:
  3395. return GF_BAD_PARAM;
  3396. }
  3397. /*same-coding scope is command-based (to check in the spec)*/
  3398. lsr->prev_g = NULL;
  3399. lsr->prev_line = NULL;
  3400. lsr->prev_path = NULL;
  3401. lsr->prev_polygon = NULL;
  3402. lsr->prev_rect = NULL;
  3403. lsr->prev_text = NULL;
  3404. lsr->prev_use = NULL;
  3405. if (lsr->last_error) break;
  3406. }
  3407. exit:
  3408. /*script is aligned*/
  3409. if (cond) {
  3410. char *data;
  3411. u32 data_size;
  3412. gf_bs_get_content(lsr->bs, &data, &data_size);
  3413. gf_bs_del(lsr->bs);
  3414. lsr->bs = old_bs;
  3415. lsr_write_vluimsbf5(lsr, data_size, NULL/*"encoding-length" - don't log to avoid corrupting the log order!!*/);
  3416. /*script is aligned*/
  3417. gf_bs_align(lsr->bs);
  3418. gf_bs_write_data(lsr->bs, data, data_size);
  3419. gf_free(data);
  3420. }
  3421. return lsr->last_error;
  3422. }
  3423. static void lsr_add_color(GF_LASeRCodec *lsr, SVG_Color *color)
  3424. {
  3425. lsr->col_table = (LSRCol*)gf_realloc(lsr->col_table, sizeof(LSRCol)*(lsr->nb_cols+1));
  3426. lsr->col_table[lsr->nb_cols].r = FIX2INT(color->red*lsr->color_scale);
  3427. lsr->col_table[lsr->nb_cols].g = FIX2INT(color->green*lsr->color_scale);
  3428. lsr->col_table[lsr->nb_cols].b = FIX2INT(color->blue*lsr->color_scale);
  3429. lsr->nb_cols++;
  3430. }
  3431. static void lsr_check_col_index(GF_LASeRCodec *lsr, SVG_Color *color, SVG_Paint *paint)
  3432. {
  3433. s32 idx;
  3434. if (color) {
  3435. idx = lsr_get_col_index(lsr, color);
  3436. if (idx==-2) lsr_add_color(lsr, color);
  3437. }
  3438. else if (paint && (paint->type==SVG_PAINT_COLOR) ) {
  3439. idx = lsr_get_col_index(lsr, &paint->color);
  3440. if (idx==-2) lsr_add_color(lsr, &paint->color);
  3441. }
  3442. }
  3443. static void lsr_check_font_index(GF_LASeRCodec *lsr, SVG_FontFamily *font)
  3444. {
  3445. u32 count, i;
  3446. if (font && (font->type == SVG_FONTFAMILY_VALUE) && font->value) {
  3447. Bool found = 0;
  3448. count = gf_list_count(lsr->font_table);
  3449. for (i=0; i<count; i++) {
  3450. char *ff = (char *)gf_list_get(lsr->font_table, i);
  3451. if (!strcmp(ff, font->value)) {
  3452. found = 1;
  3453. break;
  3454. }
  3455. }
  3456. if (!found) gf_list_add(lsr->font_table, gf_strdup(font->value));
  3457. }
  3458. }
  3459. static void lsr_check_font_and_color(GF_LASeRCodec *lsr, SVG_Element *elt)
  3460. {
  3461. GF_ChildNodeItem *l;
  3462. SVGAttribute *att;
  3463. u32 i, count, tag;
  3464. u32 check_anim_font, check_anim_col;
  3465. tag = gf_node_get_tag((GF_Node*)elt);
  3466. if (tag < GF_NODE_FIRST_DOM_NODE_TAG) goto check_children;
  3467. check_anim_font = check_anim_col = 0;
  3468. att = elt->attributes;
  3469. while (att) {
  3470. switch (att->data_type) {
  3471. case SVG_Paint_datatype:
  3472. lsr_check_col_index(lsr, NULL, att->data);
  3473. break;
  3474. case SVG_FontFamily_datatype:
  3475. lsr_check_font_index(lsr, att->data);
  3476. break;
  3477. case SMIL_AttributeName_datatype:
  3478. {
  3479. SMIL_AttributeName *an = (SMIL_AttributeName*)att->data;
  3480. if (an->name) {
  3481. if (!strcmp(an->name, "fill")) check_anim_col = 1; /*we're sure this is not SMIL fill, it is not animatable*/
  3482. else if (!strcmp(an->name, "stroke")) check_anim_col = 1;
  3483. else if (!strcmp(an->name, "color")) check_anim_col = 1;
  3484. else if (!strcmp(an->name, "solid-olor")) check_anim_col = 2;
  3485. else if (!strcmp(an->name, "stop-color")) check_anim_col = 2;
  3486. else if (!strcmp(an->name, "font-family")) check_anim_font = 1;
  3487. }
  3488. }
  3489. break;
  3490. }
  3491. att = att->next;
  3492. }
  3493. if (check_anim_font || check_anim_col) {
  3494. att = elt->attributes;
  3495. while (att) {
  3496. switch (att->data_type) {
  3497. case SMIL_AnimateValue_datatype:
  3498. if (check_anim_font) lsr_check_font_index(lsr, ((SMIL_AnimateValue*)att->data)->value);
  3499. else if (check_anim_col == 1) lsr_check_col_index(lsr, NULL, ((SMIL_AnimateValue*)att->data)->value);
  3500. else if (check_anim_col == 2) lsr_check_col_index(lsr, ((SMIL_AnimateValue*)att->data)->value, NULL);
  3501. break;
  3502. case SMIL_AnimateValues_datatype:
  3503. {
  3504. SMIL_AnimateValues *vals = (SMIL_AnimateValues*)att->data;
  3505. count = gf_list_count(vals->values);
  3506. for (i=0; i<count; i++) {
  3507. if (check_anim_font) lsr_check_font_index(lsr, (SVG_FontFamily*)gf_list_get(vals->values, i));
  3508. else if (check_anim_col == 1) lsr_check_col_index(lsr, NULL, (SVG_Paint*)gf_list_get(vals->values, i) );
  3509. else if (check_anim_col == 2) lsr_check_col_index(lsr, (SVG_Color*)gf_list_get(vals->values, i), NULL);
  3510. }
  3511. }
  3512. break;
  3513. }
  3514. att = att->next;
  3515. }
  3516. }
  3517. check_children:
  3518. l = elt->children;
  3519. while (l) {
  3520. if (l->node->sgprivate->tag==TAG_DOMUpdates) {
  3521. GF_DOMUpdates *up = (GF_DOMUpdates *)l->node;
  3522. count = gf_list_count(up->updates);
  3523. for (i=0; i<count; i++) {
  3524. u32 j, c2;
  3525. GF_Command *com = gf_list_get(up->updates, i);
  3526. c2 = gf_list_count(com->command_fields);
  3527. for (j=0; j<c2; j++) {
  3528. GF_CommandField *field = (GF_CommandField *)gf_list_get(com->command_fields, j);
  3529. if (field->new_node) {
  3530. lsr_check_font_and_color(lsr, (SVG_Element*)field->new_node);
  3531. }
  3532. /*replace/insert*/
  3533. else if (field->field_ptr) {
  3534. switch (field->fieldType) {
  3535. case SVG_Paint_datatype:
  3536. lsr_check_col_index(lsr, NULL, (SVG_Paint*)field->field_ptr);
  3537. break;
  3538. case SVG_Color_datatype:
  3539. lsr_check_col_index(lsr, (SVG_Color*)field->field_ptr, NULL);
  3540. break;
  3541. case SVG_FontFamily_datatype:
  3542. lsr_check_font_index(lsr, (SVG_FontFamily*)field->field_ptr);
  3543. break;
  3544. }
  3545. }
  3546. }
  3547. }
  3548. } else {
  3549. lsr_check_font_and_color(lsr, (SVG_Element*)l->node);
  3550. }
  3551. l = l->next;
  3552. }
  3553. }
  3554. static GF_Err lsr_write_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list, Bool reset_encoding_context)
  3555. {
  3556. u32 i, count, prev_col_count, prev_font_count;
  3557. /*
  3558. * 1 - laser unit header
  3559. */
  3560. if (!com_list) {
  3561. if (gf_sg_get_root_node(lsr->sg) == NULL) return GF_BAD_PARAM;
  3562. /*RAP generation, force reset encoding context*/
  3563. GF_LSR_WRITE_INT(lsr, 1, 1, "resetEncodingContext");
  3564. } else {
  3565. GF_LSR_WRITE_INT(lsr, reset_encoding_context ? 1 : 0, 1, "resetEncodingContext");
  3566. }
  3567. GF_LSR_WRITE_INT(lsr, 0, 1, "opt_group");
  3568. if (0) lsr_write_extension(lsr, NULL, 0, "ext");
  3569. /*clean all tables*/
  3570. if (reset_encoding_context) {
  3571. lsr->nb_cols = 0;
  3572. if (lsr->col_table) gf_free(lsr->col_table);
  3573. lsr->col_table = NULL;
  3574. while (gf_list_count(lsr->font_table)) {
  3575. char *ft = (char *)gf_list_last(lsr->font_table);
  3576. gf_free(ft);
  3577. gf_list_rem_last(lsr->font_table);
  3578. }
  3579. }
  3580. /*
  3581. * 2 - codecInitialisations
  3582. */
  3583. prev_col_count = lsr->nb_cols;
  3584. prev_font_count = gf_list_count(lsr->font_table);
  3585. /*RAP generation, send all fonts and colors*/
  3586. if (!com_list) {
  3587. prev_col_count = prev_font_count = 0;
  3588. lsr_check_font_and_color(lsr, (SVG_Element *)gf_sg_get_root_node(lsr->sg));
  3589. } else {
  3590. /*process all colors and fonts*/
  3591. count = gf_list_count(com_list);
  3592. for (i=0; i<count; i++) {
  3593. GF_Command *com = (GF_Command *)gf_list_get(com_list, i);
  3594. if (gf_list_count(com->command_fields)) {
  3595. GF_CommandField *field = (GF_CommandField *)gf_list_get(com->command_fields, 0);
  3596. if (field->fieldType==SVG_Paint_datatype) lsr_check_col_index(lsr, NULL, (SVG_Paint*)field->field_ptr);
  3597. else if (field->fieldType==SVG_FontFamily_datatype) lsr_check_font_index(lsr, (SVG_FontFamily*)field->field_ptr);
  3598. else if (field->new_node) lsr_check_font_and_color(lsr, (SVG_Element*)field->new_node);
  3599. else if (field->node_list) {
  3600. GF_ChildNodeItem *l = field->node_list;
  3601. while (l) {
  3602. lsr_check_font_and_color(lsr, (SVG_Element*)l->node);
  3603. l = l->next;
  3604. }
  3605. }
  3606. } else if (com->node && (com->tag!=GF_SG_LSR_DELETE) ) {
  3607. lsr_check_font_and_color(lsr, (SVG_Element *)com->node);
  3608. }
  3609. }
  3610. }
  3611. /*
  3612. * 2.a - condecInitialization.color
  3613. */
  3614. if (prev_col_count == lsr->nb_cols) {
  3615. GF_LSR_WRITE_INT(lsr, 0, 1, "colorInitialisation");
  3616. } else {
  3617. GF_LSR_WRITE_INT(lsr, 1, 1, "colorInitialisation");
  3618. lsr_write_vluimsbf5(lsr, lsr->nb_cols - prev_col_count, "count");
  3619. for (i=prev_col_count; i<lsr->nb_cols; i++) {
  3620. GF_LSR_WRITE_INT(lsr, lsr->col_table[i].r, lsr->info->cfg.colorComponentBits, "red");
  3621. GF_LSR_WRITE_INT(lsr, lsr->col_table[i].g, lsr->info->cfg.colorComponentBits, "green");
  3622. GF_LSR_WRITE_INT(lsr, lsr->col_table[i].b, lsr->info->cfg.colorComponentBits, "blue");
  3623. }
  3624. }
  3625. lsr->colorIndexBits = gf_get_bit_size(lsr->nb_cols);
  3626. /*
  3627. * 2.b - condecInitialization.fonts
  3628. */
  3629. count = gf_list_count(lsr->font_table);
  3630. if (prev_font_count == count) {
  3631. GF_LSR_WRITE_INT(lsr, 0, 1, "fontInitialisation");
  3632. } else {
  3633. GF_LSR_WRITE_INT(lsr, 1, 1, "fontInitialisation");
  3634. lsr_write_vluimsbf5(lsr, count - prev_font_count, "count");
  3635. for (i=prev_font_count; i<count; i++) {
  3636. char *ft = (char *)gf_list_get(lsr->font_table, i);
  3637. lsr_write_byte_align_string(lsr, ft, "font");
  3638. }
  3639. }
  3640. lsr->fontIndexBits = gf_get_bit_size(count);
  3641. /*
  3642. * 2.c - condecInitialization.private
  3643. */
  3644. GF_LSR_WRITE_INT(lsr, 0, 1, "privateDataIdentifierInitialisation");
  3645. /*
  3646. * 2.d - condecInitialization.anyXML
  3647. */
  3648. GF_LSR_WRITE_INT(lsr, 0, 1, "anyXMLInitialisation");
  3649. /*
  3650. * 2.e - condecInitialization.extended
  3651. */
  3652. /*FIXME - node string IDs are currently not used*/
  3653. lsr_write_vluimsbf5(lsr, 0, "countG");
  3654. /*FIXME - global streams are currently not used*/
  3655. GF_LSR_WRITE_INT(lsr, 0, 1, "hasExtension");
  3656. /*RAP generation, encode NewScene with root node*/
  3657. if (!com_list) {
  3658. lsr_write_vluimsbf5(lsr, 0, "occ0");
  3659. GF_LSR_WRITE_INT(lsr, 4, 4, "ch4");
  3660. lsr_write_any_attribute(lsr, NULL, 1);
  3661. lsr_write_svg(lsr, (SVG_Element *)gf_sg_get_root_node(lsr->sg) );
  3662. } else {
  3663. GF_Err e = lsr_write_command_list(lsr, com_list, NULL, 1);
  3664. if (e) return e;
  3665. }
  3666. GF_LSR_WRITE_INT(lsr, 0, 1, "opt_group");
  3667. if (0) lsr_write_extension(lsr, NULL, 0, "ext");
  3668. return GF_OK;
  3669. }
  3670. #endif /*GPAC_DISABLE_LASER*/