static void lsr_write_rare()

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;
	}
}