PageRenderTime 206ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 3ms

/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

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

  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) ty…

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