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

📄 swf.c

📁 Flush解码源程序
💻 C
字号:
#include <zlib.h>#include <math.h>#include "swfdec_internal.h"static void dumpbits(bits_t *b);int swf_parse_header1(SwfdecDecoder *s);int swf_inflate_init(SwfdecDecoder *s);int swf_parse_header2(SwfdecDecoder *s);#ifdef __GNUC__#define weak_alias(name, aliasname) \extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)))weak_alias(swfdec_decoder_new, swf_init);weak_alias(swfdec_decoder_addbits, swf_addbits);weak_alias(swfdec_decoder_parse, swf_parse);#elseSwfdecDecoder *swf_init(void){	return swfdec_decoder_new();}int swf_addbits(SwfdecDecoder *s, unsigned char *bits, int len){	return swfdec_decoder_addbits(s,bits,len);}int swf_parse(SwfdecDecoder *s){	return swfdec_decoder_parse(s);}#endifSwfdecDecoder *swfdec_decoder_new(void){	SwfdecDecoder *s;	s = g_new0(SwfdecDecoder,1);	s->bg_color = SWF_COLOR_COMBINE(0xff,0xff,0xff,0xff);	s->debug = 2;	art_affine_identity(s->transform);	s->main_sprite = swfdec_sprite_new();	s->render = swfdec_render_new();	s->flatness = 0.5;	//s->subpixel = TRUE;	s->subpixel = FALSE;	return s;}int swfdec_decoder_addbits(SwfdecDecoder *s, unsigned char *bits, int len){	int offset;	int ret;	if(s->compressed){		s->z->next_in = bits;		s->z->avail_in = len;		ret = inflate(s->z,Z_SYNC_FLUSH);		if(ret<0){			return SWF_ERROR;		}		s->parse.end = s->input_data + s->z->total_out;	}else{		if(s->parse.ptr){			offset = (void *)s->parse.ptr - (void *)s->input_data;		}else{			offset = 0;		}		s->input_data = realloc(s->input_data, s->input_data_len + len);		memcpy(s->input_data + s->input_data_len, bits, len);		s->input_data_len += len;		s->parse.ptr = s->input_data + offset;		s->parse.end = s->input_data + s->input_data_len;	}	return SWF_OK;}int swfdec_decoder_parse(SwfdecDecoder *s){	int ret = SWF_OK;	unsigned char *endptr;	while(ret==SWF_OK){		s->b = s->parse;		switch(s->state){		case SWF_STATE_INIT1:			/* need to initialize */			ret = swf_parse_header1(s);			if(ret != SWF_OK) break;			s->parse = s->b;			if(s->compressed){				swf_inflate_init(s);			}			s->state = SWF_STATE_INIT2;			ret = SWF_OK;			break;		case SWF_STATE_INIT2:			ret = swf_parse_header2(s);			if(ret == SWF_OK){				syncbits(&s->b);				s->parse = s->b;				s->state = SWF_STATE_PARSETAG;				{					ArtIRect rect;					rect.x0 = 0;					rect.y0 = 0;					rect.x1 = s->width;					rect.y1 = s->height;					swf_invalidate_irect(s,&rect);				}				ret = SWF_CHANGE;				break;			}			break;		case SWF_STATE_PARSETAG:			/* we're parsing tags */			ret = swf_parse_tag(s);			if(ret != SWF_OK)break;			if(bits_needbits(&s->b, s->tag_len)){				ret = SWF_NEEDBITS;				break;			}			endptr = s->b.ptr + s->tag_len;				s->parse_sprite = s->main_sprite;			ret = s->func(s);			s->parse_sprite = NULL;			//if(ret != SWF_OK)break;			syncbits(&s->b);			if(s->b.ptr < endptr){				SWF_DEBUG(3,"early parse finish (%d bytes)\n",					endptr - s->b.ptr);				dumpbits(&s->b);			}			if(s->b.ptr > endptr){				SWF_DEBUG(3,"parse overrun (%d bytes)\n",					s->b.ptr - endptr);			}			s->parse.ptr = endptr;			if(s->tag==0){				s->state = SWF_STATE_EOF;			}				break;		case SWF_STATE_EOF:			ret = SWF_EOF;			break;		}	}	return ret;}int swfdec_decoder_free(SwfdecDecoder *s){	GList *g;	for(g=g_list_first(s->objects);g;g=g_list_next(g)){		swfdec_object_free((SwfdecObject *)g->data);	}	g_list_free(s->objects);	if(s->stream_sound_obj){		swfdec_object_free(s->stream_sound_obj);	}	if(s->buffer)g_free(s->buffer);	if(s->input_data)g_free(s->input_data);	swfdec_sprite_free(s->main_sprite);	swfdec_render_free(s->render);	/* FIXME */	/* free stream->z */	if(s->jpegtables){		g_free(s->jpegtables);	}	if(s->tmp_scanline){		g_free(s->tmp_scanline);	}	for(g=g_list_first(s->sound_buffers);g;g=g_list_next(g)){		g_free(g->data);	}	g_list_free(s->sound_buffers);	g_free(s);	return SWF_OK;}int swfdec_decoder_get_n_frames(SwfdecDecoder *s, int *n_frames){	if(s->state == SWF_STATE_INIT1 || s->state == SWF_STATE_INIT2){		return SWF_ERROR;	}	if(n_frames) *n_frames = s->n_frames;	return SWF_OK;}int swfdec_decoder_get_rate(SwfdecDecoder *s, double *rate){	if(s->state == SWF_STATE_INIT1 || s->state == SWF_STATE_INIT2){		return SWF_ERROR;	}	if(rate) *rate = s->rate;	return SWF_OK;}int swfdec_decoder_get_image(SwfdecDecoder *s, unsigned char **image){	if(s->buffer == NULL){		return SWF_ERROR;	}	if(image) *image = s->buffer;	s->buffer = NULL;	return SWF_OK;}int swfdec_decoder_peek_image(SwfdecDecoder *s, unsigned char **image){	if(s->buffer == NULL){		return SWF_ERROR;	}	if(image) *image = s->buffer;	return SWF_OK;}int swfdec_decoder_get_image_size(SwfdecDecoder *s, int *width, int *height){	if(s->state == SWF_STATE_INIT1 || s->state == SWF_STATE_INIT2){		return SWF_ERROR;	}	if(width) *width = s->width;	if(height) *height = s->height;	return SWF_OK;}int swfdec_decoder_set_image_size(SwfdecDecoder *s, int width, int height){	if(s->state != SWF_STATE_INIT1){		return SWF_ERROR;	}	s->width = width;	s->height = height;	return SWF_OK;}int swfdec_decoder_set_colorspace(SwfdecDecoder *s, int colorspace){	if(s->state != SWF_STATE_INIT1){		return SWF_ERROR;	}	if(colorspace != SWF_COLORSPACE_RGB888 &&	   colorspace != SWF_COLORSPACE_RGB565){		return SWF_ERROR;	}	s->colorspace = colorspace;	return SWF_OK;}int swfdec_decoder_set_debug_level(SwfdecDecoder *s, int level){	s->debug = level;	return SWF_OK;}void swfdec_decoder_enable_render(SwfdecDecoder *s){	s->disable_render = FALSE;}void swfdec_decoder_disable_render(SwfdecDecoder *s){	s->disable_render = TRUE;}void *swfdec_decoder_get_sound_chunk(SwfdecDecoder *s, int *length){	GList *g;	SwfdecSoundBuffer *buffer;	void *data;	g = g_list_first(s->sound_buffers);	if(!g)return NULL;	buffer = (SwfdecSoundBuffer *)g->data;	s->sound_buffers = g_list_delete_link(s->sound_buffers,g);		data = buffer->data;	if(length) *length = buffer->len;	free(buffer);	return data;}static void *zalloc(void *opaque, unsigned int items, unsigned int size){	return malloc(items*size);}static void zfree(void *opaque, void *addr){	free(addr);}static void dumpbits(bits_t *b){	int i;	printf("    ");	for(i=0;i<16;i++){		printf("%02x ",get_u8(b));	}	printf("\n");}int swf_parse_header1(SwfdecDecoder *s){	int sig1,sig2,sig3;	if(bits_needbits(&s->b, 8))return SWF_NEEDBITS;	sig1 = get_u8(&s->b);	sig2 = get_u8(&s->b);	sig3 = get_u8(&s->b);	if((sig1 != 'F' && sig1 != 'C') || sig2 != 'W' || sig3 != 'S')		return SWF_ERROR;		s->compressed = (sig1 == 'C');	s->version = get_u8(&s->b);	s->length = get_u32(&s->b);	return SWF_OK;}int swf_inflate_init(SwfdecDecoder *s){	z_stream *z;	char *compressed_data;	int compressed_len;	char *data;	int ret;	z = g_new0(z_stream,1);	s->z = z;	z->zalloc = zalloc;	z->zfree = zfree;	compressed_data = s->parse.ptr;	compressed_len = s->input_data_len -		((void *)s->parse.ptr - (void *)s->input_data);	z->next_in = compressed_data;	z->avail_in = compressed_len;	z->opaque = NULL;	data = malloc(s->length);	z->next_out = data;	z->avail_out = s->length;	ret = inflateInit(z);	//printf("inflateInit returned %d\n",ret);	ret = inflate(z,Z_SYNC_FLUSH);	//printf("inflate returned %d\n",ret);	//printf("total out %d\n",(int)z->total_out);	//printf("total in %d\n",(int)z->total_in);	free(s->input_data);	s->input_data = data;	s->input_data_len = z->total_in;	s->parse.ptr = data;	return SWF_OK;}int swf_parse_header2(SwfdecDecoder *s){	int rect[4];	double width, height;	if(bits_needbits(&s->b, 32))return SWF_NEEDBITS;	get_rect(&s->b, rect);	width = rect[1]*SWF_SCALE_FACTOR;	height = rect[3]*SWF_SCALE_FACTOR;	if(s->width==0){		s->width = floor(width);		s->height = floor(height);		s->scale_factor = 1.0;		art_affine_identity(s->transform);	}else{		double sw, sh;		sw = s->width / width;		sh = s->height / height;		s->scale_factor = (sw<sh) ? sw : sh;		s->transform[0] = s->scale_factor;		s->transform[1] = 0;		s->transform[2] = 0;		s->transform[3] = s->scale_factor;		s->transform[4] = 0.5*(s->width - width*s->scale_factor);		s->transform[5] = 0.5*(s->height - height*s->scale_factor);	}	s->irect.x0 = 0;	s->irect.y0 = 0;	s->irect.x1 = s->width;	s->irect.y1 = s->height;	syncbits(&s->b);	s->rate = get_u16(&s->b)/256.0;	SWF_DEBUG(0,"rate = %g\n",s->rate);	s->n_frames = get_u16(&s->b);	SWF_DEBUG(0,"n_frames = %d\n",s->n_frames);	s->main_sprite->n_frames = s->n_frames;	return SWF_OK;}struct tag_func_struct {	char *name;	int (*func)(SwfdecDecoder *s);	int flag;};struct tag_func_struct tag_funcs[] = {	[ ST_END		] = { "End",		tag_func_zero,	0 },	[ ST_SHOWFRAME		] = { "ShowFrame",	art_show_frame,	0 },	[ ST_DEFINESHAPE	] = { "DefineShape",	art_define_shape,	0 },	[ ST_FREECHARACTER	] = { "FreeCharacter",	NULL,	0 },	[ ST_PLACEOBJECT	] = { "PlaceObject",	NULL,	0 },	[ ST_REMOVEOBJECT	] = { "RemoveObject",	swfdec_spriteseg_remove_object,	0 },//	[ ST_DEFINEBITS		] = { "DefineBits",	NULL,	0 },	[ ST_DEFINEBITSJPEG	] = { "DefineBitsJPEG",	tag_func_define_bits_jpeg,	0 },	[ ST_DEFINEBUTTON	] = { "DefineButton",	NULL,	0 },	[ ST_JPEGTABLES		] = { "JPEGTables",	swfdec_image_jpegtables, 0 },	[ ST_SETBACKGROUNDCOLOR	] = { "SetBackgroundColor",	tag_func_set_background_color,	0 },	[ ST_DEFINEFONT		] = { "DefineFont",	tag_func_define_font,	0 },	[ ST_DEFINETEXT		] = { "DefineText",	tag_func_define_text,	0 },	[ ST_DOACTION		] = { "DoAction",	tag_func_do_action,	0 },	[ ST_DEFINEFONTINFO	] = { "DefineFontInfo",	tag_func_ignore_quiet,	0 },	[ ST_DEFINESOUND	] = { "DefineSound",	tag_func_define_sound,	0 },	[ ST_STARTSOUND		] = { "StartSound",	tag_func_start_sound,	0 },	[ ST_DEFINEBUTTONSOUND	] = { "DefineButtonSound",	tag_func_define_button_sound,	0 },	[ ST_SOUNDSTREAMHEAD	] = { "SoundStreamHead",	tag_func_sound_stream_head,	0 },	[ ST_SOUNDSTREAMBLOCK	] = { "SoundStreamBlock",	tag_func_sound_stream_block,	0 },	[ ST_DEFINEBITSLOSSLESS	] = { "DefineBitsLossless",	tag_func_define_bits_lossless,	0 },	[ ST_DEFINEBITSJPEG2	] = { "DefineBitsJPEG2",	tag_func_define_bits_jpeg_2,	0 },	[ ST_DEFINESHAPE2	] = { "DefineShape2",	art_define_shape_2,	0 },	[ ST_DEFINEBUTTONCXFORM	] = { "DefineButtonCXForm",	NULL,	0 },	[ ST_PROTECT		] = { "Protect",	tag_func_zero,	0 },	[ ST_PLACEOBJECT2	] = { "PlaceObject2",	swfdec_spriteseg_place_object_2,	0 },	[ ST_REMOVEOBJECT2	] = { "RemoveObject2",	swfdec_spriteseg_remove_object_2,	0 },	[ ST_DEFINESHAPE3	] = { "DefineShape3",	art_define_shape_3,	0 },	[ ST_DEFINETEXT2	] = { "DefineText2",	tag_func_define_text_2,	0 },	[ ST_DEFINEBUTTON2	] = { "DefineButton2",	tag_func_define_button_2,	0 },	[ ST_DEFINEBITSJPEG3	] = { "DefineBitsJPEG3",	tag_func_define_bits_jpeg_3,	0 },	[ ST_DEFINEBITSLOSSLESS2] = { "DefineBitsLossless2",	tag_func_define_bits_lossless_2,	0 },	[ ST_DEFINEEDITTEXT	] = { "DefineEditText",	NULL,	0 },	[ ST_DEFINEMOVIE	] = { "DefineMovie",	NULL,	0 },	[ ST_DEFINESPRITE	] = { "DefineSprite",	tag_func_define_sprite,	0 },	[ ST_NAMECHARACTER	] = { "NameCharacter",	NULL,	0 },	[ ST_SERIALNUMBER	] = { "SerialNumber",	NULL,	0 },	[ ST_GENERATORTEXT	] = { "GeneratorText",	NULL,	0 },	[ ST_FRAMELABEL		] = { "FrameLabel",	tag_func_frame_label,	0 },	[ ST_SOUNDSTREAMHEAD2	] = { "SoundStreamHead2",	NULL,	0 },	[ ST_DEFINEMORPHSHAPE	] = { "DefineMorphShape",	NULL,	0 },	[ ST_DEFINEFONT2	] = { "DefineFont2",	tag_func_define_font_2,	0 },	[ ST_TEMPLATECOMMAND	] = { "TemplateCommand",	NULL,	0 },	[ ST_GENERATOR3		] = { "Generator3",	NULL,	0 },	[ ST_EXTERNALFONT	] = { "ExternalFont",	NULL,	0 },	[ ST_EXPORTASSETS	] = { "ExportAssets",	NULL,	0 },	[ ST_IMPORTASSETS	] = { "ImportAssets",	NULL,	0 },	[ ST_ENABLEDEBUGGER	] = { "EnableDebugger",	NULL,	0 },	[ ST_MX0		] = { "MX0",	NULL,	0 },	[ ST_MX1		] = { "MX1",	NULL,	0 },	[ ST_MX2		] = { "MX2",	NULL,	0 },	[ ST_MX3		] = { "MX3",	NULL,	0 },	[ ST_MX4		] = { "MX4",	NULL,	0 },//	[ ST_REFLEX		] = { "Reflex",	NULL,	0 },};static const int n_tag_funcs = sizeof(tag_funcs)/sizeof(tag_funcs[0]);int swf_parse_tag(SwfdecDecoder *s){	unsigned int x;	bits_t *b = &s->b;	char *name;	if(bits_needbits(&s->b, 2))return SWF_NEEDBITS;	x = get_u16(b);	s->tag = (x>>6)&0x3ff;	s->tag_len = x&0x3f;	if(s->tag_len==0x3f){		if(bits_needbits(&s->b, 4))return SWF_NEEDBITS;		s->tag_len = get_u32(b);	}	s->func = NULL;	name = "";	if(s->tag >=0 && s->tag < n_tag_funcs){		s->func = tag_funcs[s->tag].func;		name = tag_funcs[s->tag].name;	}	if(!s->func){		s->func = tag_func_ignore;	}	SWF_DEBUG(0,"tag=%d len=%d name=\"%s\"\n", s->tag, s->tag_len, name);	return SWF_OK;}int tag_func_zero(SwfdecDecoder *s){	return SWF_OK;}int tag_func_ignore_quiet(SwfdecDecoder *s){	s->b.ptr += s->tag_len;	return SWF_OK;}int tag_func_ignore(SwfdecDecoder *s){	char *name = "";	if(s->tag >=0 && s->tag < n_tag_funcs){		name = tag_funcs[s->tag].name;	}	SWF_DEBUG(3,"tag \"%s\" (%d) ignored\n", name, s->tag);	s->b.ptr += s->tag_len;	return SWF_OK;}int tag_func_dumpbits(SwfdecDecoder *s){	bits_t *b = &s->b;	int i;	printf("    ");	for(i=0;i<16;i++){		printf("%02x ",get_u8(b));	}	printf("\n");	return SWF_OK;}int tag_func_frame_label(SwfdecDecoder *s){	free(get_string(&s->b));	return SWF_OK;}void swf_debug(SwfdecDecoder *s, int n, char *format, ...){	va_list args;	int offset;	char *name = "unknown";	if(n<s->debug)return;	offset = (void *)s->parse.ptr - (void *)s->input_data;	if(s->tag >=0 && s->tag < n_tag_funcs){		name = tag_funcs[s->tag].name;	}	fprintf(stderr,"DEBUG: [%d,%s] ", offset, name);	va_start(args, format);	vfprintf(stderr,format,args);	va_end(args);}

⌨️ 快捷键说明

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