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

📄 svg_in.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *					GPAC Multimedia Framework * *			Authors: 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 <gpac/scene_manager.h>#include <gpac/constants.h>#include <zlib.h>#ifndef GPAC_DISABLE_SVGenum {	/*defined by dummy_in plugin*/	SVG_IN_OTI_SVG = 2,	/*defined by dummy_in plugin*/	SVG_IN_OTI_LASERML = 3,	/*defined by ourselves - streamType 3 (scene description) for SVG streaming*/	SVG_IN_OTI_STREAMING_SVG	  = 10,	/*defined by ourselves - streamType 3 (scene description) for SVG streaming*/	SVG_IN_OTI_STREAMING_SVG_GZ	  = 11};typedef struct{	GF_SceneLoader loader;	GF_InlineScene *inline_scene;	u8 oti;	char *file_name;	u32 file_size;	u32 sax_max_duration;	u16 base_es_id;	u32 file_pos;	gzFile src;} SVGIn;static Bool svg_check_download(SVGIn *svgin){	u32 size;	FILE *f = fopen(svgin->file_name, "rb");	fseek(f, 0, SEEK_END);	size = ftell(f);	fclose(f);	if (size==svgin->file_size) return 1;	return 0;}#define SVG_PROGRESSIVE_BUFFER_SIZE		4096static GF_Err SVG_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBufferLength, 								u16 ES_ID, u32 stream_time, u32 mmlevel){	GF_Err e = GF_OK;	SVGIn *svgin = (SVGIn *)plug->privateStack;	switch (svgin->oti) {	case SVG_IN_OTI_SVG:		/*full doc parsing*/		if ((svgin->sax_max_duration==(u32) -1) && svgin->file_size) {			/*init step*/			if (!svgin->loader.fileName) {				/*not done yet*/				if (!svg_check_download(svgin)) return GF_OK;				svgin->loader.fileName = svgin->file_name;				e = gf_sm_load_init(&svgin->loader);			} else {				/*should not be needed since SVG parser loads the entire file for now*/				e = /*gf_sm_load_run(&svgin->loader)*/GF_EOS;			}		}		/*chunk parsing*/		else {			u32 entry_time;			char file_buf[SVG_PROGRESSIVE_BUFFER_SIZE+2];			/*initial load*/			if (!svgin->src && !svgin->file_pos) {				svgin->src = gzopen(svgin->file_name, "rb");				if (!svgin->src) return GF_URL_ERROR;				svgin->loader.fileName = svgin->file_name;			}			e = GF_OK;			entry_time = gf_sys_clock();						while (1) {				u32 diff, nb_read;				nb_read = gzread(svgin->src, file_buf, SVG_PROGRESSIVE_BUFFER_SIZE);				file_buf[nb_read] = file_buf[nb_read+1] = 0;				if (!nb_read) {					if (gzeof(svgin->src)) {						gf_set_progress("SVG Parsing", svgin->file_pos, svgin->file_size);						gzclose(svgin->src);						svgin->src = NULL;						e = GF_EOS;						goto exit;					}					break;				}				e = gf_sm_load_string(&svgin->loader, file_buf, 0);				svgin->file_pos += nb_read;				/*handle decompression*/				if (svgin->file_pos > svgin->file_size) svgin->file_size = svgin->file_pos + 1;				if (e) break;				diff = gf_sys_clock() - entry_time;				gf_set_progress("SVG Parsing", svgin->file_pos, svgin->file_size);				if (diff > svgin->sax_max_duration) break;			}		}		break;	case SVG_IN_OTI_STREAMING_SVG:		e = gf_sm_load_string(&svgin->loader, inBuffer, 0);		break;	case SVG_IN_OTI_STREAMING_SVG_GZ:	{		char svg_data[2049];		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  = (Bytef*)inBuffer;		d_stream.avail_in = inBufferLength;		d_stream.next_out = (Bytef*)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 = gf_sm_load_string(&svgin->loader, svg_data, 0);				if (e || (err== Z_STREAM_END)) break;				done = d_stream.total_out;				d_stream.avail_out = 2048;				d_stream.next_out = (Bytef*)svg_data;			}			inflateEnd(&d_stream);		}	}		break;	case SVG_IN_OTI_LASERML: return GF_NOT_SUPPORTED;	default: return GF_BAD_PARAM;	}exit:	if ((svgin->inline_scene->graph_attached!=1) && (gf_sg_get_root_node(svgin->loader.scene_graph)!=NULL) ) {		gf_is_attach_to_renderer(svgin->inline_scene);	}	/*prepare for next playback*/	if (e==GF_EOS) {		gf_sm_load_done(&svgin->loader);		svgin->loader.fileName = NULL;	}	return e;}static GF_Err SVG_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_scene_decoder){	SVGIn *svgin = (SVGIn *)plug->privateStack;	memset(&svgin->loader, 0, sizeof(GF_SceneLoader));	svgin->inline_scene = scene;	svgin->loader.scene_graph = scene->graph;	svgin->loader.localPath = gf_modules_get_option((GF_BaseInterface *)plug, "General", "CacheDirectory");	/*Warning: svgin->loader.type may be overriden in attach stream */	svgin->loader.type = GF_SM_LOAD_SVG_DA;	svgin->loader.flags = GF_SM_LOAD_FOR_PLAYBACK;	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;	SVGIn *svgin = (SVGIn *)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 SVG_IN_OTI_STREAMING_SVG:	case SVG_IN_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);		svgin->file_size = gf_bs_read_u32(bs);		svgin->file_pos = 0;		gf_bs_del(bs);		svgin->file_name =  (char *) malloc(sizeof(char)*(1 + decSpecInfoSize - sizeof(u32)) );		memcpy(svgin->file_name, decSpecInfo + sizeof(u32), decSpecInfoSize - sizeof(u32) );		svgin->file_name[decSpecInfoSize - sizeof(u32) ] = 0;		break;	}	svgin->oti = objectTypeIndication;	if (!DependsOnES_ID) svgin->base_es_id = ES_ID;	sOpt = gf_modules_get_option((GF_BaseInterface *)plug, "SAXLoader", "Progressive");	if (sOpt && !strcmp(sOpt, "yes")) {		svgin->sax_max_duration = 30;		sOpt = gf_modules_get_option((GF_BaseInterface *)plug, "SAXLoader", "MaxDuration");		if (sOpt) svgin->sax_max_duration = atoi(sOpt);	} else {		svgin->sax_max_duration = (u32) -1;	}	svgin->loader.type = GF_SM_LOAD_SVG_DA;	sOpt = gf_modules_get_option((GF_BaseInterface *)plug, "SVGLoader", "Version");#ifdef GPAC_ENABLE_SVG_SA	if (sOpt && !strcmp(sOpt, "static_allocation")) {		svgin->loader.type = GF_SM_LOAD_SVG_SA;		fprintf(stdout, "Using SVG Scene Graph with static allocation of attributes\n");	}#endif#ifdef GPAC_ENABLE_SVG_SANI	if (sOpt && !strcmp(sOpt, "no_inheritance")) {		svgin->loader.type = GF_SM_LOAD_SVG_SANI;		fprintf(stdout, "Using SVG Scene Graph with static allocation of attributes and no inheritance\n");	} #endif	if (svgin->loader.type == GF_SM_LOAD_SVG_DA) {		fprintf(stdout, "Using SVG Scene Graph with dynamic allocation of attributes\n");	}		return GF_OK;}static GF_Err SVG_DetachStream(GF_BaseDecoder *plug, u16 ES_ID){	SVGIn *svgin = (SVGIn *)plug->privateStack;	if (svgin->file_name) free(svgin->file_name);	svgin->file_name = NULL;	gf_sm_load_done(&svgin->loader);	return GF_OK;}const char *SVG_GetName(struct _basedecoder *plug){	SVGIn *svgin = (SVGIn *)plug->privateStack;	if (svgin->oti==SVG_IN_OTI_SVG) return ((svgin->sax_max_duration==(u32)-1) && svgin->file_size) ? "GPAC SVG SAX Parser" : "GPAC SVG Progressive Parser";	if (svgin->oti==SVG_IN_OTI_STREAMING_SVG) return "GPAC Streaming SVG Parser";	if (svgin->oti==SVG_IN_OTI_STREAMING_SVG_GZ) return "GPAC Streaming SVGZ Parser";	if (svgin->oti==SVG_IN_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==SVG_IN_OTI_SVG) return 1;		//if (ObjectType==SVG_IN_OTI_LASERML) return 1;		return 0;	} else if (StreamType==GF_STREAM_SCENE) {		if (ObjectType==SVG_IN_OTI_STREAMING_SVG) return 1;		if (ObjectType==SVG_IN_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_EXPORTGF_BaseInterface *LoadInterface(u32 InterfaceType){	SVGIn *svgin;	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");	GF_SAFEALLOC(svgin, SVGIn);	sdec->privateStack = svgin;	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*/GF_EXPORTvoid ShutdownInterface(GF_BaseInterface *ifce){	GF_SceneDecoder *sdec = (GF_SceneDecoder *)ifce;	SVGIn *svgin = (SVGIn *) sdec->privateStack;	if (sdec->InterfaceType != GF_SCENE_DECODER_INTERFACE) return;	free(svgin);	free(sdec);}/*interface query*/GF_EXPORTBool QueryInterface(u32 InterfaceType){	if (InterfaceType == GF_SCENE_DECODER_INTERFACE) return 1;	return 0;}#else/*interface create*/GF_EXPORTGF_BaseInterface *LoadInterface(u32 InterfaceType){	return NULL;}/*interface destroy*/GF_EXPORTvoid ShutdownInterface(GF_BaseInterface *ifce){}/*interface query*/GF_EXPORTBool QueryInterface(u32 InterfaceType){	return 0;}#endif

⌨️ 快捷键说明

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