/src/laser/lsr_enc.c
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
- /*
- * GPAC - Multimedia Framework C SDK
- *
- * Authors: Jean Le Feuvre
- * Copyright (c) Telecom ParisTech 2005-2012
- * All rights reserved
- *
- * This file is part of GPAC / LASeR codec sub-project
- *
- * GPAC is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * GPAC is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
- #include "../../include/gpac/internal/laser_dev.h"
- #include "../../include/gpac/internal/scenegraph_dev.h"
- #include "../../include/gpac/bitstream.h"
- #include "../../include/gpac/math.h"
- #ifndef GPAC_DISABLE_LASER
- #include "../../include/gpac/events.h"
- #define GF_LSR_WRITE_INT(_codec, _val, _nbBits, _str) {\
- gf_bs_write_int(_codec->bs, _val, _nbBits); \
- GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", _str, _nbBits, _val)); \
- }\
- static void lsr_write_group_content(GF_LASeRCodec *lsr, SVG_Element *elt, Bool skip_object_content);
- static GF_Err lsr_write_command_list(GF_LASeRCodec *lsr, GF_List *comList, SVG_Element *script, Bool first_implicit);
- static GF_Err lsr_write_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list, Bool reset_encoding_context);
- static void lsr_write_point_sequence(GF_LASeRCodec *lsr, GF_List **pts, const char *name);
- static void lsr_write_path_type(GF_LASeRCodec *lsr, SVG_PathData *path, const char *name);
- GF_LASeRCodec *gf_laser_encoder_new(GF_SceneGraph *graph)
- {
- GF_LASeRCodec *tmp;
- GF_SAFEALLOC(tmp, GF_LASeRCodec);
- if (!tmp) return NULL;
- tmp->streamInfo = gf_list_new();
- tmp->font_table = gf_list_new();
- tmp->sg = graph;
- return tmp;
- }
- void gf_laser_encoder_del(GF_LASeRCodec *codec)
- {
- /*destroy all config*/
- while (gf_list_count(codec->streamInfo)) {
- LASeRStreamInfo *p = (LASeRStreamInfo *)gf_list_last(codec->streamInfo);
- gf_free(p);
- gf_list_rem_last(codec->streamInfo);
- }
- gf_list_del(codec->streamInfo);
- if (codec->col_table) gf_free(codec->col_table);
- while (gf_list_count(codec->font_table)) {
- char *ft = (char *)gf_list_last(codec->font_table);
- gf_free(ft);
- gf_list_rem_last(codec->font_table);
- }
- gf_list_del(codec->font_table);
- gf_free(codec);
- }
- static LASeRStreamInfo *lsr_get_stream(GF_LASeRCodec *codec, u16 ESID)
- {
- LASeRStreamInfo *ptr;
- u32 i = 0;
- while ((ptr = (LASeRStreamInfo *)gf_list_enum(codec->streamInfo, &i))) {
- if(ptr->ESID==ESID) return ptr;
- }
- return NULL;
- }
- GF_Err gf_laser_encoder_new_stream(GF_LASeRCodec *codec, u16 ESID, GF_LASERConfig *cfg)
- {
- LASeRStreamInfo *pInfo;
- if (lsr_get_stream(codec, ESID) != NULL) return GF_BAD_PARAM;
- GF_SAFEALLOC(pInfo, LASeRStreamInfo);
- pInfo->ESID = ESID;
- memcpy(&pInfo->cfg, cfg, sizeof(GF_LASERConfig));
- if (!pInfo->cfg.time_resolution) pInfo->cfg.time_resolution = 1000;
- if (!pInfo->cfg.colorComponentBits) pInfo->cfg.colorComponentBits = 8;
- if (!pInfo->cfg.coord_bits) pInfo->cfg.coord_bits = 12;
- if (pInfo->cfg.resolution<-8) pInfo->cfg.resolution = (s8) -8;
- else if (pInfo->cfg.resolution>7) pInfo->cfg.resolution=7;
- gf_list_add(codec->streamInfo, pInfo);
- return GF_OK;
- }
- GF_Err gf_laser_encoder_get_config(GF_LASeRCodec *codec, u16 ESID, char **out_data, u32 *out_data_length)
- {
- GF_BitStream *bs;
- if (!codec || !out_data || !out_data_length) return GF_BAD_PARAM;
- codec->info = lsr_get_stream(codec, ESID);
- if (!codec->info) return GF_BAD_PARAM;
- bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
- gf_bs_write_int(bs, codec->info->cfg.profile, 8);
- gf_bs_write_int(bs, codec->info->cfg.level, 8);
- gf_bs_write_int(bs, 0 /*codec->info->cfg.reserved*/, 3);
- gf_bs_write_int(bs, codec->info->cfg.pointsCodec, 2);
- gf_bs_write_int(bs, codec->info->cfg.pathComponents, 4);
- gf_bs_write_int(bs, codec->info->cfg.fullRequestHost, 1);
- if (codec->info->cfg.time_resolution != 1000) {
- gf_bs_write_int(bs, 1, 1);
- gf_bs_write_int(bs, codec->info->cfg.time_resolution , 16);
- } else {
- gf_bs_write_int(bs, 0, 1);
- }
- gf_bs_write_int(bs, codec->info->cfg.colorComponentBits - 1, 4);
- if (codec->info->cfg.resolution<0)
- gf_bs_write_int(bs, 16 + codec->info->cfg.resolution, 4);
- else
- gf_bs_write_int(bs, codec->info->cfg.resolution, 4);
- gf_bs_write_int(bs, codec->info->cfg.coord_bits, 5);
- gf_bs_write_int(bs, codec->info->cfg.scale_bits_minus_coord_bits, 4);
- gf_bs_write_int(bs, codec->info->cfg.newSceneIndicator ? 1 : 0, 1);
- gf_bs_write_int(bs, 0, 3);
- gf_bs_write_int(bs, codec->info->cfg.extensionIDBits, 4);
- /*no extConfig*/
- gf_bs_write_int(bs, 0, 1);
- /*no extensions*/
- gf_bs_write_int(bs, 0, 1);
- gf_bs_align(bs);
- gf_bs_get_content(bs, out_data, out_data_length);
- gf_bs_del(bs);
- return GF_OK;
- }
- 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)
- {
- GF_Err e;
- if (!codec || !command_list || !out_data || !out_data_length) return GF_BAD_PARAM;
- codec->info = lsr_get_stream(codec, ESID);
- if (!codec->info) return GF_BAD_PARAM;
- codec->coord_bits = codec->info->cfg.coord_bits;
- codec->scale_bits = codec->info->cfg.scale_bits_minus_coord_bits;
- codec->time_resolution = codec->info->cfg.time_resolution;
- codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1;
- if (codec->info->cfg.resolution>=0)
- codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1<<codec->info->cfg.resolution) );
- else
- codec->res_factor = INT2FIX(1 << (-codec->info->cfg.resolution));
- codec->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
- e = lsr_write_laser_unit(codec, command_list, reset_context);
- if (!e) {
- gf_bs_align(codec->bs);
- gf_bs_get_content(codec->bs, out_data, out_data_length);
- }
- gf_bs_del(codec->bs);
- codec->bs = NULL;
- return e;
- }
- GF_Err gf_laser_encoder_get_rap(GF_LASeRCodec *codec, char **out_data, u32 *out_data_length)
- {
- GF_Err e;
- if (!codec->info) codec->info = (LASeRStreamInfo*)gf_list_get(codec->streamInfo, 0);
- codec->coord_bits = codec->info->cfg.coord_bits;
- codec->scale_bits = codec->info->cfg.scale_bits_minus_coord_bits;
- codec->time_resolution = codec->info->cfg.time_resolution;
- codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1;
- if (codec->info->cfg.resolution>=0)
- codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1<<codec->info->cfg.resolution) );
- else
- codec->res_factor = INT2FIX(1 << (-codec->info->cfg.resolution));
- codec->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
- e = lsr_write_laser_unit(codec, NULL, 0);
- if (e == GF_OK) gf_bs_get_content(codec->bs, out_data, out_data_length);
- gf_bs_del(codec->bs);
- codec->bs = NULL;
- return e;
- }
- static void lsr_write_vluimsbf5(GF_LASeRCodec *lsr, u32 val, const char *name)
- {
- u32 nb_words;
- u32 nb_bits = val ? gf_get_bit_size(val) : 1;
- nb_words = nb_bits / 4;
- if (nb_bits%4) nb_words++;
- assert(nb_words * 4 >= nb_bits);
- nb_bits = 4*nb_words;
- while (nb_words) {
- nb_words--;
- gf_bs_write_int(lsr->bs, nb_words ? 1 : 0, 1);
- }
- gf_bs_write_int(lsr->bs, val, nb_bits);
- GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_bits + (nb_bits/4), val));
- }
- static void lsr_write_vluimsbf5_ex(GF_LASeRCodec *lsr, u32 val, u32 extra_words, const char *name)
- {
- u32 nb_words;
- u32 nb_bits = val ? gf_get_bit_size(val) : 1;
- nb_words = nb_bits / 4;
- if (nb_bits%4) nb_words++;
- nb_words += extra_words;
- assert(nb_words * 4 >= nb_bits);
- nb_bits = 4*nb_words;
- while (nb_words) {
- nb_words--;
- gf_bs_write_int(lsr->bs, nb_words ? 1 : 0, 1);
- }
- gf_bs_write_int(lsr->bs, val, nb_bits);
- GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_bits + (nb_bits/4), val));
- }
- static u32 lsr_get_vluimsbf5_size(u32 val, u32 extra_words)
- {
- u32 nb_words;
- u32 nb_bits = val ? gf_get_bit_size(val) : 1;
- nb_words = nb_bits / 4;
- if (nb_bits%4) nb_words++;
- nb_words += extra_words;
- return 4*nb_words + nb_words;
- }
- static void lsr_write_vluimsbf8(GF_LASeRCodec *lsr, u32 val, const char *name)
- {
- u32 nb_words;
- u32 nb_tot, nb_bits = val ? gf_get_bit_size(val) : 1;
- nb_words = nb_bits / 7;
- if (nb_bits%7) nb_words++;
- assert(nb_words * 7 >= nb_bits);
- nb_bits = nb_words * 7;
- nb_tot = nb_words+nb_bits;
- while (nb_words) {
- nb_words--;
- gf_bs_write_int(lsr->bs, nb_words ? 1 : 0, 1);
- }
- gf_bs_write_int(lsr->bs, val, nb_bits);
- GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%d\n", name, nb_tot, val));
- }
- static void lsr_write_extension(GF_LASeRCodec *lsr, char *data, u32 len, const char *name)
- {
- if (!len) len = (u32) strlen(name);
- lsr_write_vluimsbf5(lsr, len, name);
- gf_bs_write_data(lsr->bs, data, len);
- }
- static void lsr_write_codec_IDREF(GF_LASeRCodec *lsr, XMLRI *href, const char *name)
- {
- u32 nID = 0;
- if (href && href->target) nID = gf_node_get_id((GF_Node *)href->target);
- else if (name[0]=='#') {
- GF_Node *n = gf_sg_find_node_by_name(lsr->sg, (char *) name + 1);
- if (n) nID = gf_node_get_id((GF_Node *)href->target);
- }
- else nID = 1+href->lsr_stream_id;
- assert(nID);
- lsr_write_vluimsbf5(lsr, nID-1, name);
- GF_LSR_WRITE_INT(lsr, 0, 1, "reserved");
- }
- static void lsr_write_codec_IDREF_Node(GF_LASeRCodec *lsr, GF_Node *href, const char *name)
- {
- u32 nID = gf_node_get_id(href);
- assert(nID);
- lsr_write_vluimsbf5(lsr, nID-1, name);
- GF_LSR_WRITE_INT(lsr, 0, 1, "reserved");
- }
- static u32 lsr_get_IDREF_nb_bits(GF_LASeRCodec *lsr, GF_Node *href)
- {
- u32 nb_bits, nb_words, nID;
- nID = gf_node_get_id(href);
- assert(nID);
- nb_bits = nID ? gf_get_bit_size(nID) : 1;
- nb_words = nb_bits / 4;
- if (nb_bits%4) nb_words++;
- assert(nb_words * 4 >= nb_bits);
- nb_bits = nb_words * 4;
- return nb_words+nb_bits /*IDREF part*/ + 1 /*reserevd bit*/;
- }
- static void lsr_write_fixed_16_8(GF_LASeRCodec *lsr, Fixed fix, const char *name)
- {
- u32 val;
- if (fix<0) {
- #ifdef GPAC_FIXED_POINT
- val = (1<<24) + fix / 256;
- #else
- val = (1<<24) + FIX2INT(fix * 256);
- #endif
- } else {
- #ifdef GPAC_FIXED_POINT
- val = fix/256;
- #else
- val = FIX2INT(fix*256);
- #endif
- }
- val &= 0x00FFFFFF;
- GF_LSR_WRITE_INT(lsr, val, 24, name);
- }
- static void lsr_write_fixed_16_8i(GF_LASeRCodec *lsr, SVG_Number *n, const char *name)
- {
- if (n->type==SVG_NUMBER_INHERIT) {
- GF_LSR_WRITE_INT(lsr, 1, 1, name);
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, name);
- lsr_write_fixed_16_8(lsr, n->value, name);
- }
- }
- static s32 lsr_get_font_index(GF_LASeRCodec *lsr, SVG_FontFamily *font)
- {
- u32 i, count;
- if ((font->type!=SVG_FONTFAMILY_VALUE) || !font->value) return -1;
- count = gf_list_count(lsr->font_table);
- for (i=0; i<count; i++) {
- char *n = (char *)gf_list_get(lsr->font_table, i);
- if (!strcmp(n, font->value)) return (s32) i;
- }
- return -2;
- }
- static s32 lsr_get_col_index(GF_LASeRCodec *lsr, SVG_Color *color)
- {
- u16 r, g, b;
- u32 i;
- if (color->type!=SVG_COLOR_RGBCOLOR) return -1;
- r = FIX2INT(color->red*lsr->color_scale);
- g = FIX2INT(color->green*lsr->color_scale);
- b = FIX2INT(color->blue*lsr->color_scale);
- for (i=0; i<lsr->nb_cols; i++) {
- LSRCol *c = &lsr->col_table[i];
- if ((c->r == r) && (c->g == g) && (c->b == b)) return (s32) i;
- }
- return -2;
- }
- static void lsr_write_line_increment_type(GF_LASeRCodec *lsr, SVG_Number *li, const char *name)
- {
- if (li->type==SVG_NUMBER_INHERIT) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
- GF_LSR_WRITE_INT(lsr, 1, 1, "inherit");
- } else if (li->type==SVG_NUMBER_AUTO) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
- GF_LSR_WRITE_INT(lsr, 0, 1, "auto");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
- lsr_write_fixed_16_8(lsr, li->value, "line-increment-value");
- }
- }
- static void lsr_write_byte_align_string(GF_LASeRCodec *lsr, char *str, const char *name)
- {
- u32 len = str ? (u32) strlen(str) : 0;
- gf_bs_align(lsr->bs);
- lsr_write_vluimsbf8(lsr, len, "len");
- if (len) gf_bs_write_data(lsr->bs, str, len);
- GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[LASeR] %s\t\t%d\t\t%s\n", name, 8*len, str ? str : ""));
- }
- static void lsr_write_byte_align_string_list(GF_LASeRCodec *lsr, GF_List *l, const char *name, Bool is_iri)
- {
- char text[4096];
- u32 i, count = gf_list_count(l);
- text[0] = 0;
- for (i=0; i<count; i++) {
- char *str;
- if (is_iri) {
- XMLRI *iri = (XMLRI *)gf_list_get(l, i);
- str = iri->string;
- } else {
- str = (char*)gf_list_get(l, i);
- }
- strcat(text, str);
- if (i+1<count) strcat(text, ";");
- }
- lsr_write_byte_align_string(lsr, text, name);
- }
- static void lsr_write_any_uri(GF_LASeRCodec *lsr, XMLRI *iri, const char *name)
- {
- Bool is_iri = 0;
- if (iri->type==XMLRI_STRING) {
- is_iri = 1;
- if (iri->string[0]=='#') {
- iri->target = (SVG_Element*)gf_sg_find_node_by_name(lsr->sg, iri->string+1);
- if (iri->target) {
- is_iri = 0;
- iri->type = XMLRI_ELEMENTID;
- }
- }
- }
- GF_LSR_WRITE_INT(lsr, is_iri, 1, "hasUri");
- if (is_iri) {
- if (!iri->string || strnicmp(iri->string, "data:", 5)) {
- lsr_write_byte_align_string(lsr, iri->string, "uri");
- GF_LSR_WRITE_INT(lsr, 0, 1, "hasData");
- } else {
- u32 len;
- char *sep = strchr(iri->string, ',');
- sep[0] = 0;
- lsr_write_byte_align_string(lsr, iri->string, "uri");
- sep[0] = ',';
- len = (u32) strlen(sep+1);
- GF_LSR_WRITE_INT(lsr, 1, 1, "hasData");
- lsr_write_vluimsbf5(lsr, len, "len");
- gf_bs_write_data(lsr->bs, sep+1, len);
- }
- }
- GF_LSR_WRITE_INT(lsr, (iri->type==XMLRI_ELEMENTID) ? 1 : 0, 1, "hasID");
- if (iri->type==XMLRI_ELEMENTID) lsr_write_codec_IDREF(lsr, iri, "idref");
- GF_LSR_WRITE_INT(lsr, (iri->type==XMLRI_STREAMID) ? 1 : 0, 1, "hasID");
- if (iri->type==XMLRI_STREAMID)
- lsr_write_codec_IDREF(lsr, iri, "ref");
- }
- static void lsr_write_paint(GF_LASeRCodec *lsr, SVG_Paint *paint, const char *name)
- {
- if ((paint->type==SVG_PAINT_COLOR) && (paint->color.type==SVG_COLOR_RGBCOLOR)) {
- s32 idx;
- GF_LSR_WRITE_INT(lsr, 1, 1, "hasIndex");
- idx = lsr_get_col_index(lsr, &paint->color);
- if (idx<0) {
- idx = 0;
- GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[LASeR] color not in colorTable\n"));
- }
- GF_LSR_WRITE_INT(lsr, (u32) idx, lsr->colorIndexBits, name);
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "hasIndex");
- switch (paint->type) {
- case SVG_PAINT_INHERIT:
- GF_LSR_WRITE_INT(lsr, 0, 2, "enum");
- GF_LSR_WRITE_INT(lsr, 0, 2, "choice");
- break;
- case SVG_PAINT_NONE:
- GF_LSR_WRITE_INT(lsr, 0, 2, "enum");
- GF_LSR_WRITE_INT(lsr, 2, 2, "choice");
- break;
- case SVG_PAINT_COLOR:
- if (paint->color.type == SVG_COLOR_CURRENTCOLOR) {
- GF_LSR_WRITE_INT(lsr, 0, 2, "enum");
- GF_LSR_WRITE_INT(lsr, 1, 2, "choice");
- } else {
- GF_LSR_WRITE_INT(lsr, 2, 2, "enum");
- lsr_write_byte_align_string(lsr, (char*)gf_svg_get_system_paint_server_name(paint->color.type), "systemsPaint");
- }
- break;
- case SVG_PAINT_URI:
- GF_LSR_WRITE_INT(lsr, 1, 2, "enum");
- lsr_write_any_uri(lsr, &paint->iri, "uri");
- break;
- default:
- GF_LSR_WRITE_INT(lsr, 3, 2, "enum");
- lsr_write_extension(lsr, "ERROR", 5, "colorExType0");
- break;
- }
- }
- }
- #ifdef GPAC_UNUSED_FUNC
- static void lsr_write_private_element_container(GF_LASeRCodec *lsr)
- {
- /*NO PRIVATE DATA ON ENCODING YET*/
- assert(0);
- }
- static void lsr_write_private_att_class(GF_LASeRCodec *lsr)
- {
- /*NO PRIVATE DATA ON ENCODING YET*/
- assert(0);
- }
- static void lsr_write_extend_class(GF_LASeRCodec *lsr, char *data, u32 len, const char *name)
- {
- u32 i=0;
- GF_LSR_WRITE_INT(lsr, 0, lsr->info->cfg.extensionIDBits, "reserved");
- lsr_write_vluimsbf5(lsr, len, "len");
- while (i<len) {
- gf_bs_write_int(lsr->bs, data[i], 8);
- i++;
- }
- }
- static void lsr_write_private_attr_container(GF_LASeRCodec *lsr, u32 index, const char *name)
- {
- assert(0);
- }
- static Bool lsr_float_list_equal(GF_List *l1, GF_List *l2)
- {
- u32 i, count = gf_list_count(l1);
- if (count != gf_list_count(l2)) return 0;
- for (i=0;i<count;i++) {
- Fixed *v1 = (Fixed *)gf_list_get(l1, i);
- Fixed *v2 = (Fixed *)gf_list_get(l2, i);
- if (*v1 != *v2) return 0;
- }
- return 1;
- }
- #endif /*GPAC_UNUSED_FUNC*/
- static void lsr_write_any_attribute(GF_LASeRCodec *lsr, SVG_Element *node, Bool skippable)
- {
- if (1) {
- if (skippable) GF_LSR_WRITE_INT(lsr, 0, 1, "has_attrs");
- } else {
- if (skippable) GF_LSR_WRITE_INT(lsr, 1, 1, "has_attrs");
- /*
- do () {
- GF_LSR_WRITE_INT(lsr, 0, lsr->info->cfg.extensionIDBits, "reserved");
- lsr_write_vluimsbf5(lsr, 0, "len");//len in BITS
- GF_LSR_WRITE_INT(lsr, 0, 0, "reserved_val");
- } while ()
- */
- }
- }
- static void lsr_write_private_attributes(GF_LASeRCodec *lsr, SVG_Element *elt)
- {
- if (1) {
- GF_LSR_WRITE_INT(lsr, 0, 1, "has_private_attr");
- } else {
- GF_LSR_WRITE_INT(lsr, 1, 1, "has_private_attr");
- #ifdef GPAC_UNUSED_FUNC
- lsr_write_private_att_class(lsr);
- #endif /*GPAC_UNUSED_FUNC*/
- }
- }
- static void lsr_write_string_attribute(GF_LASeRCodec *lsr, char *class_attr, char *name)
- {
- if (class_attr) {
- GF_LSR_WRITE_INT(lsr, 1, 1, name);
- lsr_write_byte_align_string(lsr, class_attr, name);
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, name);
- }
- }
- static void lsr_write_id(GF_LASeRCodec *lsr, GF_Node *n)
- {
- u32 id = gf_node_get_id(n);
- if (id) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "has_id");
- lsr_write_vluimsbf5(lsr, id-1, "ID");
- #if TODO_LASER_EXTENSIONS
- if (0) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "reserved");
- lsr_write_vluimsbf5(lsr, reserved_len, "len");
- GF_LSR_WRITE_INT(lsr, 0, reserved_len, "reserved");
- } else
- #endif
- GF_LSR_WRITE_INT(lsr, 0, 1, "reserved");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "has_id");
- }
- }
- static u32 lsr_translate_coords(GF_LASeRCodec *lsr, Fixed x, u32 nb_bits)
- {
- s32 res, max;
- res = FIX2INT( gf_divfix(x, lsr->res_factor) );
- /*don't loose too much*/
- if (!res && x) {
- 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) ));
- res = (x>0) ? 1 : -1;
- }
- max = (1<<(nb_bits-1)) - 1;
- if (res>=0) {
- if (res > max) {
- 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) ));
- res = max;
- }
- assert( ! (res & (1<<(nb_bits-1)) ));
- return (u32) res;
- }
- res += 1<<(nb_bits);
- if (res<=max){
- 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) ));
- res = max+1;
- }
- assert( res & (1<<(nb_bits-1)) );
- return res;
- }
- static u32 lsr_translate_scale(GF_LASeRCodec *lsr, Fixed v)
- {
- s32 res;
- /*always 8 bits for fractional part*/
- if (ABS(v) * 256 < 1) v = 0;
- v = v*256;
- if (v<0) {
- res = FIX2INT(v) + (1<<lsr->coord_bits);
- 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));
- return res;
- }
- res = FIX2INT(v);
- if (res & (1<<(lsr->coord_bits-1)) ) {
- 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));
- }
- return res;
- }
- static void lsr_write_matrix(GF_LASeRCodec *lsr, SVG_Transform *mx)
- {
- u32 res;
- if (mx->is_ref) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "isNotMatrix");
- GF_LSR_WRITE_INT(lsr, 1, 1, "isRef");
- GF_LSR_WRITE_INT(lsr, 1, 1, "hasXY");
- lsr_write_fixed_16_8(lsr, mx->mat.m[2], "valueX");
- lsr_write_fixed_16_8(lsr, mx->mat.m[5], "valueY");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "isNotMatrix");
- lsr->coord_bits += lsr->scale_bits;
- if ((mx->mat.m[0]!=FIX_ONE) || (mx->mat.m[4]!=FIX_ONE)) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "xx_yy_present");
- res = lsr_translate_scale(lsr, mx->mat.m[0]);
- GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "xx");
- res = lsr_translate_scale(lsr, mx->mat.m[4]);
- GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "yy");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "xx_yy_present");
- }
- if (mx->mat.m[1] || mx->mat.m[3]) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "xy_yx_present");
- res = lsr_translate_scale(lsr, mx->mat.m[1]);
- GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "xy");
- res = lsr_translate_scale(lsr, mx->mat.m[3]);
- GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "yx");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "xy_yx_present");
- }
- if (mx->mat.m[2] || mx->mat.m[5]) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "xz_yz_present");
- res = lsr_translate_coords(lsr, mx->mat.m[2], lsr->coord_bits);
- GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "xz");
- res = lsr_translate_coords(lsr, mx->mat.m[5], lsr->coord_bits);
- GF_LSR_WRITE_INT(lsr, res, lsr->coord_bits, "yz");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "xz_yz_present");
- }
- lsr->coord_bits -= lsr->scale_bits;
- }
- }
- static void lsr_write_fixed_clamp(GF_LASeRCodec *lsr, Fixed f, const char *name)
- {
- #ifdef GPAC_FIXED_POINT
- s32 val = f >> 8;
- #else
- s32 val = (u32) (255 * f);
- #endif
- if (val<0) val = 0;
- else if (val>255) val = 255;
- GF_LSR_WRITE_INT(lsr, (u32) val, 8, name);
- }
- u32 dom_to_lsr_key(u32 dom_k)
- {
- switch (dom_k) {
- case GF_KEY_STAR: return 0;
- case GF_KEY_0: return 1;
- case GF_KEY_1: return 2;
- case GF_KEY_2: return 3;
- case GF_KEY_3: return 4;
- case GF_KEY_4: return 5;
- case GF_KEY_5: return 6;
- case GF_KEY_6: return 7;
- case GF_KEY_7: return 8;
- case GF_KEY_8: return 9;
- case GF_KEY_9: return 10;
- case GF_KEY_DOWN: return 12;
- case GF_KEY_LEFT: return 14;
- case GF_KEY_RIGHT: return 16;
- case GF_KEY_UP: return 20;
- /*WHAT IS ANY_KEY (11) ??*/
- case GF_KEY_ENTER:
- case GF_KEY_EXECUTE:
- return 13;
- case GF_KEY_ESCAPE:
- return 15;
- case GF_KEY_NUMBER:
- return 17;
- case GF_KEY_CELL_SOFT1:
- return 18;
- case GF_KEY_CELL_SOFT2:
- return 19;
- default:
- return 100;
- }
- }
- static void lsr_write_event_type(GF_LASeRCodec *lsr, u32 evtType, u32 evtParam)
- {
- Bool force_string = 0;
- switch (evtType) {
- case GF_EVENT_KEYDOWN:
- case GF_EVENT_LONGKEYPRESS:
- case GF_EVENT_REPEAT_KEY:
- case GF_EVENT_SHORT_ACCESSKEY:
- if (dom_to_lsr_key(evtParam)==100) force_string = 2;
- break;
- case GF_EVENT_BEGIN:
- case GF_EVENT_END:
- force_string = 1;
- break;
- case GF_EVENT_REPEAT:
- force_string = 1;
- break;
- }
- if (force_string) {
- char szName[1024];
- GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
- if (evtParam) {
- if (force_string==2) {
- sprintf(szName, "%s(%s)", gf_dom_event_get_name(evtType), gf_dom_get_key_name(evtParam) );
- } else {
- sprintf(szName, "%s(%d)", gf_dom_event_get_name(evtType), evtParam);
- }
- } else {
- sprintf(szName, "%s", gf_dom_event_get_name(evtType));
- }
- lsr_write_byte_align_string(lsr, szName, "evtString");
- } else {
- GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
- switch (evtType) {
- case GF_EVENT_ABORT:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_abort, 6, "event"); break;
- case GF_EVENT_ACTIVATE:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_activate, 6, "event"); break;
- case GF_EVENT_ACTIVATED:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_activatedEvent, 6, "event"); break;
- case GF_EVENT_BEGIN:/*SPEC IS BROKEN, CANNOT ENCODE elt.begin !! */
- case GF_EVENT_BEGIN_EVENT:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_beginEvent, 6, "event"); break;
- case GF_EVENT_CLICK:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_click, 6, "event"); break;
- case GF_EVENT_DEACTIVATED:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_deactivatedEvent, 6, "event"); break;
- case GF_EVENT_END:/*SPEC IS BROKEN, CANNOT ENCODE elt.end !! */
- case GF_EVENT_END_EVENT:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_endEvent, 6, "event"); break;
- case GF_EVENT_ERROR:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_error, 6, "event"); break;
- case GF_EVENT_EXECUTION_TIME:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_executionTime, 6, "event"); break;
- case GF_EVENT_FOCUSIN:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_focusin, 6, "event"); break;
- case GF_EVENT_FOCUSOUT:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_focusout, 6, "event"); break;
- case GF_EVENT_KEYDOWN:
- /*encode as accessKey() if param*/
- GF_LSR_WRITE_INT(lsr, evtParam ? LSR_EVT_accessKey : LSR_EVT_keydown, 6, "event");
- break;
- case GF_EVENT_KEYUP:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_keyup, 6, "event"); break;
- case GF_EVENT_LOAD:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_load, 6, "event"); break;
- case GF_EVENT_LONGKEYPRESS:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_longAccessKey, 6, "event"); break;
- case GF_EVENT_MOUSEDOWN:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_mousedown, 6, "event"); break;
- case GF_EVENT_MOUSEMOVE:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_mousemove, 6, "event"); break;
- case GF_EVENT_MOUSEOUT:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_mouseout, 6, "event"); break;
- case GF_EVENT_MOUSEOVER:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_mouseover, 6, "event"); break;
- case GF_EVENT_MOUSEUP:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_mouseup, 6, "event"); break;
- case GF_EVENT_PAUSE:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_pause, 6, "event"); break;
- case GF_EVENT_PAUSED_EVENT:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_pausedEvent, 6, "event"); break;
- case GF_EVENT_PLAY:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_play, 6, "event"); break;
- case GF_EVENT_REPEAT_EVENT:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_repeatEvent, 6, "event"); break;
- case GF_EVENT_REPEAT_KEY:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_repeatKey, 6, "event"); break;
- case GF_EVENT_RESIZE:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_resize, 6, "event"); break;
- case GF_EVENT_RESUME_EVENT:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_resumedEvent, 6, "event"); break;
- case GF_EVENT_SCROLL:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_scroll, 6, "event"); break;
- case GF_EVENT_SHORT_ACCESSKEY:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_shortAccessKey, 6, "event"); break;
- case GF_EVENT_TEXTINPUT:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_textinput, 6, "event"); break;
- case GF_EVENT_UNLOAD:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_unload, 6, "event"); break;
- case GF_EVENT_ZOOM:
- GF_LSR_WRITE_INT(lsr, LSR_EVT_zoom, 6, "event"); break;
- default:
- GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] Unsupported LASER event %d\n", evtType) );
- GF_LSR_WRITE_INT(lsr, 0, 6, "event"); break;
- return;
- }
- switch (evtType) {
- case GF_EVENT_KEYDOWN:
- if (!evtParam) break;
- case GF_EVENT_LONGKEYPRESS:
- case GF_EVENT_REPEAT_KEY:
- case GF_EVENT_SHORT_ACCESSKEY:
- lsr_write_vluimsbf5(lsr, dom_to_lsr_key(evtParam), "keyCode");
- break;
- }
- }
- }
- static void lsr_write_smil_time(GF_LASeRCodec *lsr, SMIL_Time *t)
- {
- s32 now;
- if (t->type==GF_SMIL_TIME_EVENT) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "hasEvent");
- if (t->element && gf_node_get_id((GF_Node*)t->element) ) {
- XMLRI iri;
- GF_LSR_WRITE_INT(lsr, 1, 1, "hasIdentifier");
- iri.string = NULL;
- iri.type = XMLRI_ELEMENTID;
- iri.target = t->element;
- lsr_write_codec_IDREF(lsr, &iri, "idref");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "hasIdentifier");
- }
- lsr_write_event_type(lsr, t->event.type, t->event.parameter);
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "hasEvent");
- }
- if (!t->clock) {
- GF_LSR_WRITE_INT(lsr, 0, 1, "hasClock");
- return;
- }
- GF_LSR_WRITE_INT(lsr, 1, 1, "hasClock");
- now = (s32) (t->clock * lsr->time_resolution);
- if (now<0) {
- now = -now;
- GF_LSR_WRITE_INT(lsr, 1, 1, "sign");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "sign");
- }
- lsr_write_vluimsbf5(lsr, now, "value");
- }
- static void lsr_write_smil_times(GF_LASeRCodec *lsr, GF_List **l, const char *name, Bool skipable)
- {
- SMIL_Time *v;
- u32 r_count, i, count;
- Bool indef = 0;
- count = l ? gf_list_count(*l) : 0;
- r_count = 0;
- for (i=0; i<count; i++) {
- v = (SMIL_Time*)gf_list_get(*l, i);
- if (v->type==GF_SMIL_TIME_INDEFINITE) {
- indef = 1;
- break;
- }
- else if (v->type!=GF_SMIL_TIME_EVENT_RESOLVED) r_count++;
- }
- if (skipable && !r_count && !indef) {
- GF_LSR_WRITE_INT(lsr, 0, 1, name);
- return;
- }
- if (skipable) GF_LSR_WRITE_INT(lsr, 1, 1, name);
- GF_LSR_WRITE_INT(lsr, indef, 1, "choice");
- if (indef) return;
- lsr_write_vluimsbf5(lsr, r_count, "count");
- for (i=0; i<count; i++) {
- v = (SMIL_Time*)gf_list_get(*l, i);
- lsr_write_smil_time(lsr, v);
- }
- }
- static void lsr_write_duration_ex(GF_LASeRCodec *lsr, SMIL_Duration *v, const char *name, Bool skipable)
- {
- if (skipable) {
- if (!v || !v->type) {
- GF_LSR_WRITE_INT(lsr, 0, 1, name);
- return;
- }
- GF_LSR_WRITE_INT(lsr, 1, 1, name);
- }
- if (v->type==SMIL_DURATION_DEFINED) {
- s32 now = (s32) (v->clock_value * lsr->time_resolution);
- GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
- GF_LSR_WRITE_INT(lsr, (now<0) ? 1 : 0, 1, "sign");
- if (now<0) now = -now;
- lsr_write_vluimsbf5(lsr, now, "value");
- } else {
- GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
- GF_LSR_WRITE_INT(lsr, v->type, 2, "time");
- }
- }
- #define lsr_write_duration(a, b, c) lsr_write_duration_ex(a, b, c, 1)
- static void lsr_write_focus(GF_LASeRCodec *lsr, SVG_Focus *foc, const char *name)
- {
- if (foc->type==SVG_FOCUS_IRI) {
- GF_LSR_WRITE_INT(lsr, 0, 1, "isEnum");
- lsr_write_codec_IDREF(lsr, &foc->target, "id");
- } else {
- GF_LSR_WRITE_INT(lsr, 1, 1, "isEnum");
- GF_LSR_WRITE_INT(lsr, foc->type, 1, "enum");
- }
- }
- 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)
- {
- SVGAllAttributes base_atts;
- GF_FieldInfo info, base_info;
- if (same_stroke) *same_stroke = 0;
- if (same_fill) *same_fill = 0;
- if (!base) return 0;
- gf_svg_flatten_attributes(base, &base_atts);
- if (atts->externalResourcesRequired != base_atts.externalResourcesRequired) return 0;
- info.fieldType = base_info.fieldType = SVG_Paint_datatype;
- info.far_ptr = atts->stroke;
- base_info.far_ptr = base_atts.stroke;
- /*check stroke color*/
- if (!gf_svg_attributes_equal(&info, &base_info)) {
- if (!no_stroke_check) return 0;
- } else {
- if (same_stroke) *same_stroke = 1;
- }
- if (same_fill) {
- info.fieldType = base_info.fieldType = SVG_Paint_datatype;
- info.far_ptr = atts->fill;
- base_info.far_ptr = base_atts.fill;
- /*check stroke color*/
- *same_fill = gf_svg_attributes_equal(&info, &base_info) ? 1 : 0;
- }
- switch (gf_node_get_tag((GF_Node*) base)) {
- /*check path length*/
- case TAG_SVG_path:
- info.fieldType = base_info.fieldType = SVG_Number_datatype;
- info.far_ptr = atts->pathLength;
- base_info.far_ptr = base_atts.pathLength;
- if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
- break;
- /*check rx and ry for rect*/
- case TAG_SVG_rect:
- info.fieldType = base_info.fieldType = SVG_Length_datatype;
- info.far_ptr = atts->rx;
- base_info.far_ptr = base_atts.rx;
- if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
- info.fieldType = base_info.fieldType = SVG_Length_datatype;
- info.far_ptr = atts->ry;
- base_info.far_ptr = base_atts.ry;
- if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
- break;
- /*check x and y for use*/
- case TAG_SVG_use:
- info.fieldType = base_info.fieldType = SVG_Coordinate_datatype;
- info.far_ptr = atts->x;
- base_info.far_ptr = base_atts.x;
- if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
- info.fieldType = base_info.fieldType = SVG_Coordinate_datatype;
- info.far_ptr = atts->y;
- base_info.far_ptr = base_atts.y;
- if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
- break;
- /*check editable and rotate for text*/
- case TAG_SVG_text:
- info.fieldType = base_info.fieldType = SVG_Boolean_datatype;
- info.far_ptr = atts->editable;
- base_info.far_ptr = base_atts.editable;
- if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
- info.fieldType = base_info.fieldType = SVG_Numbers_datatype;
- info.far_ptr = atts->text_rotate;
- base_info.far_ptr = base_atts.text_rotate;
- if (!gf_svg_attributes_equal(&info, &base_info)) return 0;
- break;
- }
- return gf_lsr_same_rare(atts, &base_atts);
- }
- static void lsr_write_rare(GF_LASeRCodec *lsr, GF_Node *n)
- {
- u32 i, nb_rare;
- s32 field_rare;
- SVGAttribute *att;
- nb_rare = 0;
- att = ((SVG_Element*)n)->attributes;
- while (att) {
- field_rare = gf_lsr_rare_type_from_attribute(att->tag);
- if (field_rare>=0) nb_rare++;
- att = att->next;
- }
- GF_LSR_WRITE_INT(lsr, nb_rare ? 1 : 0, 1, "has_rare");
- if (!nb_rare) return;
- GF_LSR_WRITE_INT(lsr, nb_rare, 6, "nbOfAttributes");
- att = ((SVG_Element*)n)->attributes;
- while (att) {
- field_rare = gf_lsr_rare_type_from_attribute(att->tag);
- if (field_rare==-1) {
- att = att->next;
- continue;
- }
- /*RARE extension*/
- if (field_rare==49) {
- Bool is_string = 0;
- u32 size, cur_bits;
- u32 len = 2+3;
- switch (att->tag) {
- case TAG_SVG_ATT_syncMaster: len +=1; break;
- case TAG_SVG_ATT_requiredFonts:
- len += 8 * (u32) strlen(*(SVG_String*)att->data);
- /*get vluimsbf5 field size with one extra word (4 bits, enough to code string alignment)*/
- size = lsr_get_vluimsbf5_size(len, 1);
- cur_bits = gf_bs_get_bit_position(lsr->bs) + lsr->info->cfg.extensionIDBits + size + 5;
- /*count string alignment*/
- while (cur_bits%8) {
- len++;
- cur_bits++;
- }
- is_string = 1;
- break;
- default: len +=2; break;
- }
- GF_LSR_WRITE_INT(lsr, 49, 6, "attributeRARE");
- GF_LSR_WRITE_INT(lsr, 2, lsr->info->cfg.extensionIDBits, "extensionID");
- if (is_string) {
- lsr_write_vluimsbf5_ex(lsr, len, 1, "len");
- } else {
- lsr_write_vluimsbf5(lsr, len, "len");
- }
- GF_LSR_WRITE_INT(lsr, 1, 2, "nbOfAttributes");
- switch (att->tag) {
- case TAG_SVG_ATT_syncMaster:
- GF_LSR_WRITE_INT(lsr, 0, 3, "attributeRARE");
- GF_LSR_WRITE_INT(lsr, *(SVG_Boolean *)att->data ? 1 : 0, 1, "syncMaster");
- break;
- case TAG_SVG_ATT_focusHighlight:
- GF_LSR_WRITE_INT(lsr, 1, 3, "attributeRARE");
- GF_LSR_WRITE_INT(lsr, *(SVG_FocusHighlight*)att->data, 2, "focusHighlight");
- break;
- case TAG_SVG_ATT_initialVisibility:
- GF_LSR_WRITE_INT(lsr, 2, 3, "attributeRARE");
- GF_LSR_WRITE_INT(lsr, *(SVG_InitialVisibility*)att->data, 2, "initialVisibility");
- break;
- case TAG_SVG_ATT_fullscreen:
- GF_LSR_WRITE_INT(lsr, 3, 3, "attributeRARE");
- GF_LSR_WRITE_INT(lsr, *(SVG_Boolean *)att->data ? 1 : 0, 2, "fullscreen");
- break;
- case TAG_SVG_ATT_requiredFonts:
- GF_LSR_WRITE_INT(lsr, 4, 3, "attributeRARE");
- lsr_write_byte_align_string(lsr, *(SVG_String*)att->data, "requiredFonts");
- break;
- }
- GF_LSR_WRITE_INT(lsr, 0, 1, "hasNextExtension");
- att = att->next;
- continue;
- }
- GF_LSR_WRITE_INT(lsr, (u32)field_rare, 6, "attributeRARE");
- switch (att->tag) {
- case TAG_SVG_ATT__class: lsr_write_byte_align_string(lsr, *(SVG_String *)att->data, "class"); break;
- case TAG_SVG_ATT_audio_level: lsr_write_fixed_clamp(lsr, ((SVG_Number *) att->data)->value, "audio-level"); break;
- case TAG_SVG_ATT_color: lsr_write_paint(lsr, (SVG_Paint*) att->data, "color"); break;
- case TAG_SVG_ATT_color_rendering: GF_LSR_WRITE_INT(lsr, *(SVG_RenderingHint*)att->data, 2, "color-rendering"); break;
- case TAG_SVG_ATT_display: GF_LSR_WRITE_INT(lsr, *(SVG_Display*)att->data, 5, "display"); break;
- case TAG_SVG_ATT_display_align: GF_LSR_WRITE_INT(lsr, *(SVG_DisplayAlign*)att->data, 3, "display-align"); break;
- case TAG_SVG_ATT_fill_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "fill-opacity"); break;
- case TAG_SVG_ATT_fill_rule: GF_LSR_WRITE_INT(lsr, *(SVG_FillRule*)att->data, 2, "fill-rule"); break;
- case TAG_SVG_ATT_image_rendering: GF_LSR_WRITE_INT(lsr, *(SVG_RenderingHint*)att->data, 2, "image-rendering"); break;
- case TAG_SVG_ATT_line_increment: lsr_write_line_increment_type(lsr, (SVG_Number*)att->data, "lineIncrement"); break;
- case TAG_SVG_ATT_pointer_events: GF_LSR_WRITE_INT(lsr, *(SVG_PointerEvents*)att->data, 4, "pointer-events"); break;
- case TAG_SVG_ATT_shape_rendering: GF_LSR_WRITE_INT(lsr, *(SVG_RenderingHint*)att->data, 3, "shape-rendering"); break;
- case TAG_SVG_ATT_solid_color: lsr_write_paint(lsr, (SVG_Paint*)att->data, "solid-color"); break;
- case TAG_SVG_ATT_solid_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "solid-opacity"); break;
- case TAG_SVG_ATT_stop_color: lsr_write_paint(lsr, (SVG_Paint*)att->data, "stop-color"); break;
- case TAG_SVG_ATT_stop_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "stop-opacity"); break;
- case TAG_SVG_ATT_stroke_dasharray:
- {
- u32 j;
- SVG_StrokeDashArray *da = (SVG_StrokeDashArray*)att->data;
- if (da->type==SVG_STROKEDASHARRAY_INHERIT) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "dashArray");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "dashArray");
- lsr_write_vluimsbf5(lsr, da->array.count, "len");
- for (j=0; j<da->array.count; j++) {
- lsr_write_fixed_16_8(lsr, da->array.vals[j], "dash");
- }
- }
- }
- break;
- case TAG_SVG_ATT_stroke_dashoffset:
- lsr_write_fixed_16_8i(lsr, (SVG_Number*)att->data, "dashOffset"); break;
- case TAG_SVG_ATT_stroke_linecap: GF_LSR_WRITE_INT(lsr, *(SVG_StrokeLineCap*)att->data, 2, "stroke-linecap"); break;
- case TAG_SVG_ATT_stroke_linejoin: GF_LSR_WRITE_INT(lsr, *(SVG_StrokeLineJoin*)att->data, 2, "stroke-linejoin"); break;
- case TAG_SVG_ATT_stroke_miterlimit: lsr_write_fixed_16_8i(lsr, (SVG_Number*)att->data, "miterLimit"); break;
- case TAG_SVG_ATT_stroke_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "stroke-opacity"); break;
- case TAG_SVG_ATT_stroke_width: lsr_write_fixed_16_8i(lsr, (SVG_Number*)att->data, "strokeWidth"); break;
- case TAG_SVG_ATT_text_anchor: GF_LSR_WRITE_INT(lsr, *(SVG_TextAnchor*)att->data, 2, "text-achor"); break;
- case TAG_SVG_ATT_text_rendering: GF_LSR_WRITE_INT(lsr, *(SVG_RenderingHint*)att->data, 3, "text-rendering"); break;
- case TAG_SVG_ATT_viewport_fill: lsr_write_paint(lsr, (SVG_Paint*)att->data, "viewport-fill"); break;
- case TAG_SVG_ATT_viewport_fill_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "viewport-fill-opacity"); break;
- case TAG_SVG_ATT_vector_effect: GF_LSR_WRITE_INT(lsr, *(SVG_VectorEffect*)att->data, 4, "vector-effect"); break;
- case TAG_SVG_ATT_visibility: GF_LSR_WRITE_INT(lsr, *(SVG_PointerEvents*)att->data, 2, "visibility"); break;
- case TAG_SVG_ATT_requiredExtensions: lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "requiredExtensions", 1); break;
- case TAG_SVG_ATT_requiredFormats: lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "requiredFormats", 0); break;
- case TAG_SVG_ATT_requiredFeatures:
- {
- GF_List *l = *(GF_List **)att->data;
- u32 j, tot_count, count = gf_list_count(l);
- u8 *vals = (u8*)gf_malloc(sizeof(u8)*count);
- tot_count = 0;
- for (i=0; i<count; i++) {
- char *ext;
- XMLRI *iri = (XMLRI*)gf_list_get(l, i);
- if (iri->type != XMLRI_STRING) continue;
- ext = strchr(iri->string, '#');
- if (!ext) continue;
- if (!stricmp(ext, "Animation")) { vals[tot_count] = 0; tot_count++; }
- else if (!stricmp(ext, "Audio")) { vals[tot_count] = 1; tot_count++; }
- else if (!stricmp(ext, "ComposedVideo")) { vals[tot_count] = 2; tot_count++; }
- else if (!stricmp(ext, "ConditionalProcessing")) { vals[tot_count] = 3; tot_count++; }
- else if (!stricmp(ext, "ConditionalProcessingAttribute")) { vals[tot_count] = 4; tot_count++; }
- else if (!stricmp(ext, "CoreAttribute")) { vals[tot_count] = 5; tot_count++; }
- else if (!stricmp(ext, "Extensibility")) { vals[tot_count] = 6; tot_count++; }
- else if (!stricmp(ext, "ExternalResourcesRequired")) { vals[tot_count] = 7; tot_count++; }
- else if (!stricmp(ext, "Font")) { vals[tot_count] = 8; tot_count++; }
- else if (!stricmp(ext, "Gradient")) { vals[tot_count] = 9; tot_count++; }
- else if (!stricmp(ext, "GraphicsAttribute")) { vals[tot_count] = 10; tot_count++; }
- else if (!stricmp(ext, "Handler")) { vals[tot_count] = 11; tot_count++; }
- else if (!stricmp(ext, "Hyperlinking")) { vals[tot_count] = 12; tot_count++; }
- else if (!stricmp(ext, "Image")) { vals[tot_count] = 13; tot_count++; }
- else if (!stricmp(ext, "OpacityAttribute")) { vals[tot_count] = 14; tot_count++; }
- else if (!stricmp(ext, "PaintAttribute")) { vals[tot_count] = 15; tot_count++; }
- else if (!stricmp(ext, "Prefetch")) { vals[tot_count] = 16; tot_count++; }
- else if (!stricmp(ext, "SVG")) { vals[tot_count] = 17; tot_count++; }
- else if (!stricmp(ext, "SVG-animation")) { vals[tot_count] = 18; tot_count++; }
- else if (!stricmp(ext, "SVG-dynamic")) { vals[tot_count] = 19; tot_count++; }
- else if (!stricmp(ext, "SVG-static")) { vals[tot_count] = 20; tot_count++; }
- else if (!stricmp(ext, "SVGDOM")) { vals[tot_count] = 21; tot_count++; }
- else if (!stricmp(ext, "SVGDOM-animation")) { vals[tot_count] = 22; tot_count++; }
- else if (!stricmp(ext, "SVGDOM-dynamic")) { vals[tot_count] = 23; tot_count++; }
- else if (!stricmp(ext, "SVGDOM-static")) { vals[tot_count] = 24; tot_count++; }
- else if (!stricmp(ext, "Script")) { vals[tot_count] = 25; tot_count++; }
- else if (!stricmp(ext, "Shape")) { vals[tot_count] = 26; tot_count++; }
- else if (!stricmp(ext, "SolidColor")) { vals[tot_count] = 27; tot_count++; }
- else if (!stricmp(ext, "Structure")) { vals[tot_count] = 28; tot_count++; }
- else if (!stricmp(ext, "Text")) { vals[tot_count] = 29; tot_count++; }
- else if (!stricmp(ext, "TimedAnimation")) { vals[tot_count] = 30; tot_count++; }
- else if (!stricmp(ext, "TransformedVideo")) { vals[tot_count] = 31; tot_count++; }
- else if (!stricmp(ext, "Video")) { vals[tot_count] = 32; tot_count++; }
- else if (!stricmp(ext, "XlinkAttribute")) { vals[tot_count] = 33; tot_count++; }
- }
- lsr_write_vluimsbf5(lsr, tot_count, "len");
- for (j=0; j<tot_count; j++) {
- GF_LSR_WRITE_INT(lsr, vals[j], 6, "feature");
- }
- gf_free(vals);
- }
- break;
- case TAG_SVG_ATT_systemLanguage:
- lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "systemLanguage", 0);
- break;
- case TAG_XML_ATT_base: lsr_write_byte_align_string(lsr, ((XMLRI*)att->data)->string, "xml:base"); break;
- case TAG_XML_ATT_lang: lsr_write_byte_align_string(lsr, *(SVG_String *)att->data, "xml:lang"); break;
- case TAG_XML_ATT_space: GF_LSR_WRITE_INT(lsr, *(XML_Space *)att->data, 1, "xml:space"); break;
- case TAG_SVG_ATT_nav_next: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusNext"); break;
- case TAG_SVG_ATT_nav_up: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusNorth"); break;
- case TAG_SVG_ATT_nav_up_left: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusNorthEast"); break;
- case TAG_SVG_ATT_nav_up_right: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusNorthWest"); break;
- case TAG_SVG_ATT_nav_prev: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusPrev"); break;
- case TAG_SVG_ATT_nav_down: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusSouth"); break;
- case TAG_SVG_ATT_nav_down_left: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusSouthEast"); break;
- case TAG_SVG_ATT_nav_down_right: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusSouthWest"); break;
- case TAG_SVG_ATT_nav_right: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusWest"); break;
- case TAG_SVG_ATT_nav_left: lsr_write_focus(lsr, (SVG_Focus*)att->data, "focusEast"); break;
- case TAG_SVG_ATT_font_variant: GF_LSR_WRITE_INT(lsr, *(SVG_FontVariant *)att->data, 2, "font-variant"); break;
- case TAG_SVG_ATT_font_family:
- {
- s32 idx = lsr_get_font_index(lsr, (SVG_FontFamily*)att->data);
- if (idx<0) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "isInherit");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "isInherit");
- GF_LSR_WRITE_INT(lsr, idx, lsr->fontIndexBits, "fontIndex");
- }
- }
- break;
- case TAG_SVG_ATT_font_size: lsr_write_fixed_16_8i(lsr, (SVG_Number*)att->data, "fontSize"); break;
- case TAG_SVG_ATT_font_style: GF_LSR_WRITE_INT(lsr, *((SVG_FontStyle *)att->data), 3, "fontStyle"); break;
- case TAG_SVG_ATT_font_weight: GF_LSR_WRITE_INT(lsr, *((SVG_FontWeight *)att->data), 4, "fontWeight"); break;
- case TAG_XLINK_ATT_title: lsr_write_byte_align_string(lsr, *(SVG_String *)att->data, "xlink:title"); break;
- /*TODO FIXME*/
- case TAG_XLINK_ATT_type: GF_LSR_WRITE_INT(lsr, 0, 3, "xlink:type"); break;
- case TAG_XLINK_ATT_role: lsr_write_any_uri(lsr, (XMLRI*)att->data, "xlink:role"); break;
- case TAG_XLINK_ATT_arcrole: lsr_write_any_uri(lsr, (XMLRI*)att->data, "xlink:arcrole"); break;
- /*TODO FIXME*/
- case TAG_XLINK_ATT_actuate: GF_LSR_WRITE_INT(lsr, 0, 2, "xlink:actuate"); break;
- case TAG_XLINK_ATT_show: GF_LSR_WRITE_INT(lsr, 0, 3, "xlink:show"); break;
- case TAG_SVG_ATT_end: lsr_write_smil_times(lsr, (GF_List **)att->data, "end", 0); break;
- case TAG_SVG_ATT_min: lsr_write_duration_ex(lsr, (SMIL_Duration*)att->data, "min", 0); break;
- case TAG_SVG_ATT_max: lsr_write_duration_ex(lsr, (SMIL_Duration*)att->data, "max", 0); break;
- case TAG_SVG_ATT_transform: lsr_write_matrix(lsr, (SVG_Transform*)att->data); break;
- }
- att = att->next;
- }
- }
- static void lsr_write_fill(GF_LASeRCodec *lsr, SVG_Element *n, SVGAllAttributes *atts)
- {
- if (atts->fill) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "fill");
- lsr_write_paint(lsr, atts->fill, "fill");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "fill");
- }
- }
- static void lsr_write_stroke(GF_LASeRCodec *lsr, SVG_Element *n, SVGAllAttributes *atts)
- {
- if (atts->stroke) {
- GF_LSR_WRITE_INT(lsr, 1, 1, "has_stroke");
- lsr_write_paint(lsr, atts->stroke, "stroke");
- } else {
- GF_LSR_WRITE_INT(lsr, 0, 1, "has_stroke");
- }
- }
- static void lsr_write_href(GF_LASeRCodec *lsr, XMLRI *iri)
- {
- Bool has_href = iri ? 1 : 0;
- if (iri) {
- if (iri->type==XMLRI_ELEMENTID) {
- if (!iri->target && iri->string) iri->target = (SVG_Element *)gf_sg_find_node_by_name(lsr->sg, iri->string+1);
- if (!iri->target || !gf_node_get_id((GF_Node *)iri->target)) has_href = 0;
- }
- else if (iri->type==XMLRI_STREAMID) {
- if (!iri->lsr_stream_id) has_href = 0;
- }
- else if (!iri->string) has_href = 0;
- }
- GF_LSR_WRITE_INT(lsr, has_href, 1, "has_href");
- if (has_href) lsr_write_any_uri(lsr, iri, "href");
- }
- static void lsr_write_accumulate(GF_LASeRCodec *lsr, SMIL_Accumulate *accum_type)
- {
- GF_LSR_WRITE_INT(lsr, accum_type ? 1 : 0, 1, "has_accumulate");
- if (accum_type) GF_LSR_WRITE_INT(lsr, *accum_type, 1, "accumulate");
- }
- static void lsr_write_additive(GF_LASeRCodec *lsr, SMIL_Additive *add_type)
- {
- GF_LSR_WRITE_INT(lsr, add_type ? 1 : 0, 1, "has_additive");
- if (add_type) GF_LSR_WRITE_INT(lsr, *add_type, 1, "additive");
- }
- static void lsr_write_calc_mode(GF_LASeRCodec *lsr, u8 *calc_mode)
- {
- /*SMIL_CALCMODE_LINEAR is default and 0 in our code*/
- GF_LSR_WRITE_INT(lsr, (!calc_mode || (*calc_mode==SMIL_CALCMODE_LINEAR)) ? 0 : 1, 1, "has_calcMode");
- if (calc_mode && (*calc_mode!=SMIL_CALCMODE_LINEAR)) {
- GF_LSR_WRITE_INT(lsr, *calc_mode, 2, "calcMode");
- }
- }
- static void lsr_write_animatable(GF_LASeRCodec *lsr, SMIL_AttributeName *anim_type, XMLRI *iri, const char *name)
- {
- s32 a_type = -1;
- if (!anim_type || !iri || !iri->target) {
- GF_LSR_WRITE_INT(lsr, 0, 1, "hasAttributeName");
- return;
- }
- /*locate field - checkme, this may not work since anim is not setup...*/
- assert(anim_type->name || anim_type->tag);
- if (!anim_type->tag) anim_type->tag = gf_xml_get_attribute_tag((GF_Node*)iri->target, anim_type->name, 0);
- if (!anim_type->type) anim_type->type = gf_xml_get_attribute_type(anim_type->tag);
- a_type = gf_lsr_anim_type_from_attribute(anim_type->tag);
- if (a_type<0) {
- GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] Unsupported attributeName %s\n", anim_type->name));
- }
- GF_LSR_WRITE_INT(lsr, 1, 1, "hasAttributeName");
- GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
- GF_LSR_WRITE_INT(lsr, (u8) a_type, 8, "attributeType");
- }
- static void lsr_write_anim_fill(GF_LASeRCodec *lsr, u8 *animFreeze)
- {
- GF_LSR_WRITE_INT(lsr, animFreeze ? 1 : 0, 1, "has_smil_fill");
- if (animFreeze) GF_LSR_WRITE_INT(lsr, *animFreeze, 1, "smil_fill");
- }
- static void lsr_write_anim_repeat(GF_LASeRCodec *lsr, SMIL_RepeatCount *repeat)
- {
- GF_LSR_WRITE_INT(lsr, repeat ? 1 : 0, 1, "has_repeatCount");
- if (!repeat) return;
- if (repeat->type==SMIL_REPEATCOUNT_DEFINED) {
- GF_LSR_WRITE_INT(lsr, 0, 1, "repeatCount");
- lsr_write_fixed_16_8(lsr, repeat->count, "repeatCount");
- } else {
- GF_LSR_WRITE_INT(lsr, 1, 1, "repeatCount");
- /*enumeration indefinite{0}*/
- }
- }
- static void lsr_write_repeat_duration(GF_LASeRCodec *lsr, SMIL_Duration *smil)
- {
- GF_LSR_WRITE_INT(lsr, smil ? 1 : 0, 1, "has_repeatDur");
- if (!smil) return;
- if (smil->type==SMIL_DURATION_DEFINED) {
- u32 now = (u32) (smil->clock_value * lsr->time_resolution);
- GF_LSR_WRITE_INT(lsr, 0, 1, "choice");
- lsr_write_vluimsbf5(lsr, now, "value");
- } else {
- GF_LSR_WRITE_INT(lsr, 1, 1, "choice");
- /*enumeration indefinite{0}*/
- }
- }
- static void lsr_write_anim_restart(GF_LASeRCodec *lsr, u8 *animRestart)
- {
- GF_LSR_WRITE_INT(lsr, animRestart ? 1 : 0, 1, "has_restart");
- /*enumeration always{0} never{1} whenNotActive{2}*/
- if (animRestart) GF_LSR_WRITE_INT(lsr, *animRestart, 2, "restart");
- }
- static u32 svg_type_to_lsr_anim(u32 svg_type, u32 transform_type, GF_List *vals, void *a_val)
- {
- switch (svg_type) {
- /*all string types*/
- case DOM_String_datatype:
- return 0;
- /*all length types*/
- case SVG_Number_datatype:
- case SVG_FontSize_datatype:
- case SVG_Length_datatype:
- case SVG_Coordinate_datatype:
- return 1;
- case SVG_PathData_datatype:
- return 2;
- /*list of points*/
- case SMIL_KeyPoints_datatype:
- case SVG_Points_datatype:
- return 3;
- /*all 0 - 1 types*/
- /*
- case SVG_Opacity_datatype:
- return 4;
- */
- case SVG_Paint_datatype:
- return 5;
- /*all enums (u8) types*/
- case SVG_FillRule_datatype:
- case SVG_StrokeLineJoin_datatype:
- case SVG_StrokeLineCap_datatype:
- case SVG_FontStyle_datatype:
- case SVG_FontWeight_datatype:
- case SVG_FontVariant_datatype:
- case SVG_TextAnchor_datatype:
- case SVG_TransformType_datatype:
- case SVG_Display_datatype:
- case SVG_Visibility_datatype:
- case SVG_Overflow_datatype:
- case SVG_ZoomAndPan_datatype:
- case SVG_DisplayAlign_datatype:
- case SVG_TextAlign_datatype:
- case SVG_PointerEvents_datatype:
- case SVG_RenderingHint_datatype:
- case SVG_VectorEffect_datatype:
- case SVG_PlaybackOrder_datatype:
- case SVG_TimelineBegin_datatype:
- return 6;
- /*all list-of-int types*/ //return 7;
- /*all list-of-float types*/
- case SVG_StrokeDashArray_datatype:
- case SVG_ViewBox_datatype:
- case SVG_Coordinates_datatype:
- return 8;
- /*ID (u32) ty…
Large files files are truncated, but you can click here to view the full file