in src/laser/lsr_enc.c [1067:1523]
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 = GF_FALSE;
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 = GF_TRUE;
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", GF_TRUE);
break;
case TAG_SVG_ATT_requiredFormats:
lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "requiredFormats", GF_FALSE);
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", GF_FALSE);
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", GF_FALSE);
break;
case TAG_SVG_ATT_min:
lsr_write_duration_ex(lsr, (SMIL_Duration*)att->data, "min", GF_FALSE);
break;
case TAG_SVG_ATT_max:
lsr_write_duration_ex(lsr, (SMIL_Duration*)att->data, "max", GF_FALSE);
break;
case TAG_SVG_ATT_transform:
lsr_write_matrix(lsr, (SVG_Transform*)att->data);
break;
}
att = att->next;
}
}