⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader_svg_da.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / Scene Management 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 <gpac/scene_manager.h>#include <gpac/constants.h>#include <gpac/utf.h>#include <gpac/xml.h>#include <gpac/events.h>#include <gpac/internal/scenegraph_dev.h>#include <gpac/internal/laser_dev.h>#include <gpac/nodes_svg_da.h>#ifndef GPAC_DISABLE_SVGtypedef struct _st_entry{	struct _st_entry *next;	/*as refered to by xlink-href*/	char *stream_name;	/*stream id*/	u32 id;	const char *nhml_info;} SVG_SAFExternalStream;typedef struct{	GF_SceneLoader *load;	GF_Err last_error;	GF_SAXParser *sax_parser;	Bool has_root;		/* stack of SVG nodes*/	GF_List *node_stack;	GF_List *defered_hrefs;	GF_List *defered_animations;	GF_List *defered_listeners;	/*non-linear parsing*/	GF_List *peeked_nodes;	/*LASeR parsing*/	u32 command_depth;	GF_StreamContext *laser_es;	GF_AUContext *laser_au;	GF_Command *command;	/*SAF AU maps to OD AU and is used for each new media declaration*/	GF_AUContext *saf_au;	GF_StreamContext *saf_es;	SVG_SAFExternalStream *streams;} GF_SVG_Parser;typedef struct{	/*top of parsed sub-tree*/	SVG_Element *node;	/*depth of unknown elements being skipped*/	u32 unknown_depth;	/*last child added, used to speed-up parsing*/	GF_ChildNodeItem *last_child;} SVG_NodeStack;typedef struct {	/* Stage of the resolving:	    0: resolving attributes which depends on the target: from, to, by, values, type		1: resolving begin times		2: resolving end times */	u32 resolve_stage;	/* Animation element being defered */	SVG_Element *animation_elt;	/* anim parent*/	SVG_Element *anim_parent;	/* target animated element*/	SVG_Element *target;	/* id of the target element when unresolved*/	char *target_id;	/* attributes which cannot be parsed until the type of the target attribute is known */	char *type; /* only for animateTransform */	char *to;	char *from;	char *by;	char *values;} SVG_DeferedAnimation;static GF_Err svg_report(GF_SVG_Parser *parser, GF_Err e, char *format, ...){#ifndef GPAC_DISABLE_LOG	if (gf_log_get_level() && (gf_log_get_tools() & GF_LOG_PARSER)) {		char szMsg[2048];		va_list args;		va_start(args, format);		vsprintf(szMsg, format, args);		va_end(args);		GF_LOG((u32) (e ? GF_LOG_ERROR : GF_LOG_WARNING), GF_LOG_PARSER, ("[SVG Parsing] line %d - %s\n", gf_xml_sax_get_line(parser->sax_parser), szMsg));	}#endif	if (e) parser->last_error = e;	return e;}static void svg_progress(void *cbk, u32 done, u32 total){	gf_set_progress("SVG (Dynamic Attribute List) Parsing", done, total);}static SVG_SAFExternalStream *svg_saf_get_stream(GF_SVG_Parser *parser, u32 id, const char *name){	SVG_SAFExternalStream *st;	st = parser->streams;	while (st) {		if (id == st->id) return st;		if (name && !strcmp(name, st->stream_name) ) return st;		st = st->next;	}	return NULL;}static SVG_SAFExternalStream *svg_saf_get_next_available_stream(GF_SVG_Parser *parser){	/*1 reserved for base laser stream*/	u32 id = 1;	SVG_SAFExternalStream *st = parser->streams;	SVG_SAFExternalStream *prev = NULL;	while (st) {		prev = st;		id = st->id;		st = st->next;	}	GF_SAFEALLOC(st, SVG_SAFExternalStream);	if (prev) prev->next = st;	else parser->streams = st;	st->id = id+1;	return st;}static void svg_lsr_set_v2(GF_SVG_Parser *parser){	u32 i;	if (parser->load->ctx && parser->load->ctx->root_od) {		for (i=0; i<gf_list_count(parser->load->ctx->root_od->ESDescriptors); i++) {			GF_ESD *esd = gf_list_get(parser->load->ctx->root_od->ESDescriptors, i);			if (esd->decoderConfig->streamType==GF_STREAM_SCENE) {				GF_LASERConfig *cfg = (GF_LASERConfig *)esd->decoderConfig->decoderSpecificInfo;				if (cfg && (cfg->tag==GF_ODF_LASER_CFG_TAG)) {					if (!cfg->extensionIDBits) cfg->extensionIDBits = 2;				}			}		}	}}static void svg_process_media_href(GF_SVG_Parser *parser, XMLRI *iri){	SVG_SAFExternalStream *st = svg_saf_get_stream(parser, 0, iri->string+1);	if (st) {		free(iri->string);		iri->string = NULL;		iri->lsr_stream_id = st->id;		iri->type = XMLRI_STREAMID;	}}static void xsr_exec_command_list(GF_Node *node, void *par, Bool is_destroy){	GF_DOMUpdates *up = (GF_DOMUpdates *)node;	if (is_destroy || !up || (up->sgprivate->tag!=TAG_DOMUpdates)) return;	gf_sg_command_apply_list(up->sgprivate->scenegraph, up->updates, 0);}static GF_Node *svg_find_node(GF_SVG_Parser *parser, char *ID){	u32 i, count, tag;	char *node_class;	GF_Node *n = gf_sg_find_node_by_name(parser->load->scene_graph, ID);	if (n) return n;	count = gf_list_count(parser->peeked_nodes);	for (i=0; i<count; i++) {		n = (GF_Node*)gf_list_get(parser->peeked_nodes, i);		if (!strcmp(gf_node_get_name(n), ID)) return n;	}	node_class = gf_xml_sax_peek_node(parser->sax_parser, "id", ID, NULL, NULL, NULL, NULL);	if (!node_class) return NULL;	tag = gf_svg_get_element_tag(node_class);	n = gf_node_new(parser->load->scene_graph, tag);	free(node_class);	if (n) {		gf_svg_parse_element_id(n, ID, 0);		gf_list_add(parser->peeked_nodes, n);	}	return n;}static void svg_post_process_href(GF_SVG_Parser *parser, XMLRI *iri){	/*keep data when encoding*/	if ( !(parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK)) return;	/*unresolved, queue it...*/	if ((iri->type==XMLRI_ELEMENTID) && !iri->target && iri->string) {		gf_list_add(parser->defered_hrefs, iri);	}	if (iri->type != XMLRI_STRING) return;	gf_svg_store_embedded_data(iri, parser->load->localPath, parser->load->fileName);}static void svg_delete_defered_anim(SVG_DeferedAnimation *anim, GF_List *defered_animations){	if (defered_animations) gf_list_del_item(defered_animations, anim);	if (anim->target_id) free(anim->target_id);	if (anim->to) free(anim->to);	if (anim->from) free(anim->from);	if (anim->by) free(anim->by);	if (anim->values) free(anim->values);	if (anim->type) free(anim->type);	free(anim);}static Bool svg_parse_animation(GF_SVG_Parser *parser, GF_SceneGraph *sg, SVG_DeferedAnimation *anim, const char *nodeID){	GF_FieldInfo info;	u32 tag;	u8 anim_value_type = 0;	if (anim->resolve_stage==0) {		/* Stage 0: parsing the animation attribute values 					for that we need to resolve the target first */		if (!anim->target) 			anim->target = (SVG_Element *) gf_sg_find_node_by_name(sg, anim->target_id + 1);		if (!anim->target) {			/* the target is still not known stay in stage 0 */			return 0;		} else { 			XMLRI *iri;			gf_svg_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_xlink_href, 1, 0, &info);			iri = (XMLRI *)info.far_ptr;			iri->type = XMLRI_ELEMENTID;			iri->target = anim->target;			gf_svg_register_iri(sg, iri);		}		tag = gf_node_get_tag((GF_Node *)anim->animation_elt);		/* get the attribute name attribute if specified */		if (anim->type && (tag== TAG_SVG_animateTransform) ) {			gf_svg_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_transform_type, 1, 0, &info);			gf_svg_parse_attribute((GF_Node *)anim->animation_elt, &info, anim->type, 0);			switch(*(SVG_TransformType *) info.far_ptr) {			case SVG_TRANSFORM_TRANSLATE:				anim_value_type = SVG_Transform_Translate_datatype;				break;			case SVG_TRANSFORM_SCALE:				anim_value_type = SVG_Transform_Scale_datatype;				break;			case SVG_TRANSFORM_ROTATE:				anim_value_type = SVG_Transform_Rotate_datatype;				break;			case SVG_TRANSFORM_SKEWX:				anim_value_type = SVG_Transform_SkewX_datatype;				break;			case SVG_TRANSFORM_SKEWY:				anim_value_type = SVG_Transform_SkewY_datatype;				break;			case SVG_TRANSFORM_MATRIX:				anim_value_type = SVG_Transform_datatype;				break;			default:				svg_report(parser, GF_OK, "unknown datatype for animate transform");				return 0;			}		}		else if (gf_svg_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_attributeName, 0, 0, &info) == GF_OK) {			gf_svg_get_attribute_by_name((GF_Node *)anim->target, ((SMIL_AttributeName *)info.far_ptr)->name, 1, 1, &info);			anim_value_type = info.fieldType;		} else {			if (tag == TAG_SVG_animateMotion) {				anim_value_type = SVG_Motion_datatype;			} else if (tag == TAG_SVG_discard) {				/* there is no value to parse in discard, we can jump to the next stage */				anim->resolve_stage = 1;				return svg_parse_animation(parser, sg, anim, nodeID);			} else {				svg_report(parser, GF_OK, "Missing attributeName attribute on %s", gf_node_get_name((GF_Node *)anim->animation_elt));				return 0;			}		}		if (anim->to) {			gf_svg_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_to, 1, 0, &info);			gf_svg_parse_attribute((GF_Node *)anim->animation_elt, &info, anim->to, anim_value_type);			if (anim_value_type==XMLRI_datatype) 				svg_post_process_href(parser, (XMLRI*)((SMIL_AnimateValue *)info.far_ptr)->value);		} 		if (anim->from) {			gf_svg_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_from, 1, 0, &info);			gf_svg_parse_attribute((GF_Node *)anim->animation_elt, &info, anim->from, anim_value_type);			if (anim_value_type==XMLRI_datatype) 				svg_post_process_href(parser, (XMLRI*)((SMIL_AnimateValue *)info.far_ptr)->value);		} 		if (anim->by) {			gf_svg_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_by, 1, 0, &info);			gf_svg_parse_attribute((GF_Node *)anim->animation_elt, &info, anim->by, anim_value_type);			if (anim_value_type==XMLRI_datatype) 				svg_post_process_href(parser, (XMLRI*)((SMIL_AnimateValue *)info.far_ptr)->value);		} 		if (anim->values) {			gf_svg_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_values, 1, 0, &info);			gf_svg_parse_attribute((GF_Node *)anim->animation_elt, &info, anim->values, anim_value_type);			if (anim_value_type==XMLRI_datatype) {				u32 i, count;				SMIL_AnimateValues *anim_values;				anim_values = (SMIL_AnimateValues *)info.far_ptr;				count = gf_list_count(anim_values->values);				for (i=0; i<count; i++) {					XMLRI *iri = (XMLRI *)gf_list_get(anim_values->values, i);					svg_post_process_href(parser, iri);				}			}		}		anim->resolve_stage = 1;	}	if (anim->resolve_stage == 1) {		/* Stage 1: parsing the begin values 					we go into the next stage only if at least one begin value is resolved */		gf_svg_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_begin, 1, 0, &info);		if (gf_svg_resolve_smil_times(sg, anim->anim_parent, *(GF_List **)info.far_ptr, 0, nodeID)) {			anim->resolve_stage = 2;		} else {			return 0;		}	}	gf_svg_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_end, 1, 0, &info);	if (!gf_svg_resolve_smil_times(sg, anim->anim_parent, *(GF_List **)info.far_ptr, 1, nodeID)) return 0;	/*animateMotion needs its children to be parsed before it can be initialized !! */	if (gf_node_get_tag((GF_Node *)anim->animation_elt) != TAG_SVG_animateMotion)		gf_node_init((GF_Node *)anim->animation_elt);		return 1;}static void svg_resolved_refs(GF_SVG_Parser *parser, GF_SceneGraph *sg, const char *nodeID){	u32 count, i;	/*check unresolved HREF*/	count = gf_list_count(parser->defered_hrefs);	for (i=0; i<count; i++) {		GF_Node *targ;		XMLRI *iri = (XMLRI *)gf_list_get(parser->defered_hrefs, i);		if (nodeID && strcmp(iri->string + 1, nodeID)) continue;		targ = gf_sg_find_node_by_name(sg, iri->string + 1);		if (targ) {			iri->type = XMLRI_ELEMENTID;			iri->target = targ;			gf_svg_register_iri(sg, iri);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -