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

📄 svg_loader.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *					GPAC Multimedia Framework * *			Authors: Cyril Concolato - Jean le Feuvre *				Copyright (c) 2005-200X ENST *					All rights reserved * *  This file is part of GPAC / SVG Loader module * *  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/internal/terminal_dev.h>#include "svg_parser.h"#ifndef GPAC_DISABLE_SVG#include <zlib.h>/************************************************************************* *																	 	 * * Functions implementing the Basic Decoder and Scene Decoder interfaces * *																		 * *************************************************************************/static GF_Err LSR_ProcessDocument(GF_SceneDecoder *plug, unsigned char *inBuffer, u32 inBufferLength, 								u16 ES_ID, u32 stream_time, u32 mmlevel){	GF_Err e;	SVGParser *parser = plug->privateStack;	parser->stream_time = stream_time;	e = SVGParser_ParseLASeR(parser);	if (!e && parser->needs_attachement) {		parser->needs_attachement = 0;		gf_sg_set_scene_size_info(parser->graph, parser->svg_w, parser->svg_h, 1);		gf_is_attach_to_renderer(parser->inline_scene);	}	return e;}/* Only in case of reading from file (cached or not) of an XML file (i.e. not AU framed)   The buffer is empty but the filename has been given in a previous step: SVG_AttachStream */static GF_Err SVG_ProcessProgressiveDocument(GF_SceneDecoder *plug, unsigned char *inBuffer, u32 inBufferLength, 								u16 ES_ID, u32 stream_time, u32 mmlevel){	GF_Err e = GF_OK;	SVGParser *parser = plug->privateStack;	if (parser->loader_status == 4) return GF_BAD_PARAM;	if (parser->loader_status == 0) {		e = SVGParser_InitProgressiveFileChunk(parser);		if (e) {			parser->loader_status = 4;			return e;		} 		parser->loader_status = 1;	}	e = SVGParser_ParseProgressiveFileChunk(parser);	if (parser->loader_status == 2) 	{ /* the SVG root element has been encountered */		gf_sg_set_scene_size_info(parser->graph, parser->svg_w, parser->svg_h, 1);		/*attach graph to renderer*/		gf_is_attach_to_renderer(parser->inline_scene);		parser->loader_status = 3;	}	return e;}/* Only in case of reading from file (cached or not) of an XML file (i.e. not AU framed)   The buffer is empty but the filename has been given in a previous step: SVG_AttachStream */static GF_Err SVG_ProcessFullDocument(GF_SceneDecoder *plug, unsigned char *inBuffer, u32 inBufferLength, 								u16 ES_ID, u32 stream_time, u32 mmlevel){	GF_Err e = GF_EOS;	SVGParser *parser = plug->privateStack;	if (parser->loader_status == 0) {		/*needs full doc for DOM parsing*/		if (!SVG_CheckDownload(parser)) return GF_OK;		parser->loader_status = 1;		e = SVGParser_ParseFullDoc(parser);		if (!e) {			gf_sg_set_scene_size_info(parser->graph, parser->svg_w, parser->svg_h, 1);			/*attach graph to renderer*/			gf_is_attach_to_renderer(parser->inline_scene);		} else {			parser->loader_status = 0;		}	} 	return e;}/* Only in case of streaming or reading from MP4 file or framed container   The buffer contains the actual piece of SVG to read */static GF_Err SVG_ProcessAU(GF_SceneDecoder *plug, unsigned char *inBuffer, u32 inBufferLength, 								u16 ES_ID, u32 stream_time, u32 mmlevel){	GF_Err e = GF_OK;	SVGParser *parser = plug->privateStack;	if (parser->loader_status == 0) {		parser->loader_status = 1;		e = SVGParser_ParseMemoryFirstChunk(parser, inBuffer, inBufferLength);				if (!e) {			gf_sg_set_scene_size_info(parser->graph, parser->svg_w, parser->svg_h, 1);			/*attach graph to renderer*/			gf_is_attach_to_renderer(parser->inline_scene);		} else {			parser->loader_status = 0;		}	} else {		e = SVGParser_ParseMemoryNextChunk(parser, inBuffer, inBufferLength);		if (e == GF_EOS) return GF_OK;	}	return e;}static GF_Err SVG_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBufferLength, 								u16 ES_ID, u32 stream_time, u32 mmlevel){	SVGParser *parser = plug->privateStack;	switch (parser->oti) {	case SVGLOADER_OTI_SVG:		/*DOM parsing*/		if (parser->load_type==SVG_LOAD_DOM) {			return SVG_ProcessFullDocument(plug, inBuffer, inBufferLength, ES_ID, stream_time, mmlevel);		}		/*SAX parsing*/		else {			return SVG_ProcessProgressiveDocument(plug, inBuffer, inBufferLength, ES_ID, stream_time, mmlevel);		}	case SVGLOADER_OTI_STREAMING_SVG:		return SVG_ProcessAU(plug, inBuffer, inBufferLength, ES_ID, stream_time, mmlevel);	case SVGLOADER_OTI_STREAMING_SVG_GZ:	{		char svg_data[2049];		GF_Err e = GF_OK;		int err;		u32 done = 0;		z_stream d_stream;		d_stream.zalloc = (alloc_func)0;		d_stream.zfree = (free_func)0;		d_stream.opaque = (voidpf)0;		d_stream.next_in  = inBuffer;		d_stream.avail_in = inBufferLength;		d_stream.next_out = svg_data;		d_stream.avail_out = 2048;		err = inflateInit(&d_stream);		if (err == Z_OK) {			while (d_stream.total_in < inBufferLength) {				err = inflate(&d_stream, Z_NO_FLUSH);				if (err < Z_OK) {					e = GF_NON_COMPLIANT_BITSTREAM;					break;				}				svg_data[d_stream.total_out - done] = 0;				e = SVG_ProcessAU(plug, svg_data, d_stream.total_out - done, ES_ID, stream_time, mmlevel);				if (e || (err== Z_STREAM_END)) break;				done = d_stream.total_out;				d_stream.avail_out = 2048;				d_stream.next_out = svg_data;			}			inflateEnd(&d_stream);		}		return e;	}	case SVGLOADER_OTI_LASERML:		return LSR_ProcessDocument(plug, inBuffer, inBufferLength, ES_ID, stream_time, mmlevel);	default:		return GF_BAD_PARAM;	}}static GF_Err SVG_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_scene_decoder){	SVGParser *parser = plug->privateStack;	parser->inline_scene = scene;	parser->graph = scene->graph;	parser->temp_dir = (char *) gf_modules_get_option((GF_BaseInterface *)plug, "General", "CacheDirectory");	return GF_OK;}static GF_Err SVG_ReleaseScene(GF_SceneDecoder *plug){	return GF_OK;}static GF_Err SVG_AttachStream(GF_BaseDecoder *plug, 									 u16 ES_ID, 									 char *decSpecInfo, 									 u32 decSpecInfoSize, 									 u16 DependsOnES_ID,									 u32 objectTypeIndication, 									 Bool Upstream){	const char *sOpt;	GF_BitStream *bs;	SVGParser *parser = plug->privateStack;	if (Upstream) return GF_NOT_SUPPORTED;	/* decSpecInfo is not null only when reading from an SVG file (local or distant, cached or not) */	switch (objectTypeIndication) {	case SVGLOADER_OTI_STREAMING_SVG:	case SVGLOADER_OTI_STREAMING_SVG_GZ:		/*no decSpecInfo defined for streaming svg yet*/		break;	default:		if (!decSpecInfo) return GF_NON_COMPLIANT_BITSTREAM;		bs = gf_bs_new(decSpecInfo, decSpecInfoSize, GF_BITSTREAM_READ);		parser->file_size = gf_bs_read_u32(bs);		gf_bs_del(bs);		parser->file_name = (char *) malloc(sizeof(char)*(1 + decSpecInfoSize - sizeof(u32)) );		memcpy(parser->file_name, decSpecInfo + sizeof(u32), decSpecInfoSize - sizeof(u32) );		parser->file_name[decSpecInfoSize - sizeof(u32)] = 0;		break;	}	parser->oti = objectTypeIndication;	parser->sax_max_duration = 30;	sOpt = gf_modules_get_option((GF_BaseInterface *)plug, "SAXLoader", "MaxDuration");	if (sOpt) parser->sax_max_duration = atoi(sOpt);	parser->load_type = SVG_LOAD_DOM;	sOpt = gf_modules_get_option((GF_BaseInterface *)plug, "SAXLoader", "Progressive");	if (sOpt && !strcmp(sOpt, "yes") ) parser->load_type = SVG_LOAD_SAX_PROGRESSIVE;	else if (sOpt && !strcmp(sOpt, "DOM") ) parser->load_type = SVG_LOAD_DOM;	else parser->load_type = SVG_LOAD_SAX;	/*if DOM parsing is requested and file size is not available, the server didn't send	a proper content length, force SAX parsing*/	if (!parser->file_size && (parser->load_type==SVG_LOAD_DOM)) {		parser->load_type = SVG_LOAD_SAX;	}	return GF_OK;}static GF_Err SVG_DetachStream(GF_BaseDecoder *plug, u16 ES_ID){	return GF_OK;}const char *SVG_GetName(struct _basedecoder *plug){	SVGParser *parser = plug->privateStack;	if (parser->oti==SVGLOADER_OTI_SVG) return (parser->load_type==SVG_LOAD_DOM) ? "GPAC SVG DOM Parser" : (parser->load_type==SVG_LOAD_SAX) ? "GPAC SVG SAX Parser" : "GPAC SVG Progressive Parser";	if (parser->oti==SVGLOADER_OTI_STREAMING_SVG) return "GPAC Streaming SVG + libXML Parser";	if (parser->oti==SVGLOADER_OTI_STREAMING_SVG_GZ) return "GPAC Streaming SVGZ + libXML Parser";	if (parser->oti==SVGLOADER_OTI_LASERML) return "GPAC LASeRML Parser";	return "INTERNAL ERROR";}Bool SVG_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, u32 ObjectType, char *decSpecInfo, u32 decSpecInfoSize, u32 PL){	if (StreamType==GF_STREAM_PRIVATE_SCENE) {		if (ObjectType==SVGLOADER_OTI_SVG) return 1;		//if (ObjectType==SVGLOADER_OTI_LASERML) return 1;		return 0;	} else if (StreamType==GF_STREAM_SCENE) {		if (ObjectType==SVGLOADER_OTI_STREAMING_SVG) return 1;		if (ObjectType==SVGLOADER_OTI_STREAMING_SVG_GZ) return 1;		return 0;	}	return 0;}static GF_Err SVG_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *cap){	cap->cap.valueInt = 0;	if (cap->CapCode==GF_CODEC_PADDING_BYTES) {		/* Adding one byte of padding for \r\n problems*/		cap->cap.valueInt = 1;		return GF_OK;	}	return GF_NOT_SUPPORTED;}static GF_Err SVG_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapability capability){	return GF_OK;}/*interface create*/GF_BaseInterface *LoadInterface(u32 InterfaceType){	SVGParser *parser;	GF_SceneDecoder *sdec;	if (InterfaceType != GF_SCENE_DECODER_INTERFACE) return NULL;		GF_SAFEALLOC(sdec, GF_SceneDecoder)	GF_REGISTER_MODULE_INTERFACE(sdec, GF_SCENE_DECODER_INTERFACE, "GPAC SVG Parser", "gpac distribution");	parser = NewSVGParser();	sdec->privateStack = parser;	sdec->AttachStream = SVG_AttachStream;	sdec->CanHandleStream = SVG_CanHandleStream;	sdec->DetachStream = SVG_DetachStream;	sdec->AttachScene = SVG_AttachScene;	sdec->ReleaseScene = SVG_ReleaseScene;	sdec->ProcessData = SVG_ProcessData;	sdec->GetName = SVG_GetName;	sdec->SetCapabilities = SVG_SetCapabilities;	sdec->GetCapabilities = SVG_GetCapabilities;	return (GF_BaseInterface *)sdec;}/*interface destroy*/void ShutdownInterface(GF_BaseInterface *ifce){	GF_SceneDecoder *sdec = (GF_SceneDecoder *)ifce;	SVGParser *parser = (SVGParser *) sdec->privateStack;	if (sdec->InterfaceType != GF_SCENE_DECODER_INTERFACE) return;	SVGParser_Terminate(parser);	free(sdec);}/*interface query*/Bool QueryInterface(u32 InterfaceType){	if (InterfaceType == GF_SCENE_DECODER_INTERFACE) return 1;	return 0;}#else/*interface create*/GF_BaseInterface *LoadInterface(u32 InterfaceType){	return NULL;}/*interface destroy*/void ShutdownInterface(GF_BaseInterface *ifce){}/*interface query*/Bool QueryInterface(u32 InterfaceType){	return 0;}#endif

⌨️ 快捷键说明

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