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

📄 swf_parse.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 5 页
字号:
			pts[ptj] = path->pts[pti];			pts[ptj+1] = path->pts[pti-1];			pti-=2;			ptj+=2;			break;		case 1:			assert(ptj<=path->nbPts-1);			pts[ptj] = path->pts[pti];			pti--;			ptj++;			break;		case 0:			assert(ptj<=path->nbPts-1);			pts[ptj] = path->pts[pti];			pti--;			ptj++;			break;		}		j++;	}	free(path->pts);	path->pts = pts;	free(path->types);	path->types = types;}void swf_free_shape_rec(SWFShapeRec *ptr){	if (ptr->grad_col) free(ptr->grad_col);	if (ptr->grad_ratio) free(ptr->grad_ratio);	if (ptr->path) {		if (ptr->path->pts) free(ptr->path->pts);		if (ptr->path->types) free(ptr->path->types);		free(ptr->path);	}	free(ptr);}void swf_free_rec_list(GF_List *recs){	while (gf_list_count(recs)) {		SWFShapeRec *tmp = (SWFShapeRec *)gf_list_get(recs, 0);		gf_list_rem(recs, 0);		swf_free_shape_rec(tmp);	}	gf_list_del(recs);}void swf_append_path(SWFPath *a, SWFPath *b){	if (b->nbType<=1) return;	a->pts = (SFVec2f*)realloc(a->pts, sizeof(SFVec2f) * (a->nbPts + b->nbPts));	memcpy(&a->pts[a->nbPts], b->pts, sizeof(SFVec2f)*b->nbPts);	a->nbPts += b->nbPts;	a->types = (u32*)realloc(a->types, sizeof(u32)*(a->nbType+ b->nbType));	memcpy(&a->types[a->nbType], b->types, sizeof(u32)*b->nbType);	a->nbType += b->nbType;}void swf_path_add_type(SWFPath *path, u32 val){	path->types = (u32*)realloc(path->types, sizeof(u32) * (path->nbType + 1));	path->types[path->nbType] = val;	path->nbType++;}void swf_resort_path(SWFPath *a, SWFReader *read){	u32 idx, i, j;	GF_List *paths;	SWFPath *sorted, *p, *np;	if (!a->nbType) return;	paths = gf_list_new();	GF_SAFEALLOC(sorted, SWFPath);	swf_path_realloc_pts(sorted, 1);	sorted->pts[sorted->nbPts] = a->pts[0];	sorted->nbPts++;	swf_path_add_type(sorted, 0);	gf_list_add(paths, sorted);	/*1- split all paths*/	idx = 1;	for (i=1; i<a->nbType; i++) {		switch (a->types[i]) {		case 2:			swf_path_realloc_pts(sorted, 2);			sorted->pts[sorted->nbPts] = a->pts[idx];			sorted->pts[sorted->nbPts+1] = a->pts[idx+1];			sorted->nbPts+=2;			swf_path_add_type(sorted, 2);			idx += 2;			break;		case 1:			swf_path_realloc_pts(sorted, 1);			sorted->pts[sorted->nbPts] = a->pts[idx];			sorted->nbPts+=1;			swf_path_add_type(sorted, 1);			idx += 1;			break;		case 0:			GF_SAFEALLOC(sorted , SWFPath);			swf_path_realloc_pts(sorted, 1);			sorted->pts[sorted->nbPts] = a->pts[idx];			sorted->nbPts++;			swf_path_add_type(sorted, 0);			gf_list_add(paths, sorted);			idx += 1;			break;		}	}restart:	for (i=0; i<gf_list_count(paths); i++) {		p = (SWFPath*)gf_list_get(paths, i);		j=i+1;		for (j=i+1; j < gf_list_count(paths); j++) {			np = (SWFPath*)gf_list_get(paths, j);				/*check if any next subpath ends at the same place we're starting*/			if ((np->pts[np->nbPts-1].x == p->pts[0].x) && (np->pts[np->nbPts-1].y == p->pts[0].y)) {				u32 k;				idx = 1;				for (k=1; k<p->nbType; k++) {					switch (p->types[k]) {					case 2:						swf_path_realloc_pts(np, 2);						np->pts[np->nbPts] = p->pts[idx];						np->pts[np->nbPts+1] = p->pts[idx+1];						np->nbPts+=2;						swf_path_add_type(np, 2);						idx += 2;						break;					case 1:						swf_path_realloc_pts(np, 1);						np->pts[np->nbPts] = p->pts[idx];						np->nbPts+=1;						swf_path_add_type(np, 1);						idx += 1;						break;					default:						assert(0);						break;					}				}				free(p->pts);				free(p->types);				free(p);				gf_list_rem(paths, i);				goto restart;			}			/*check if any next subpath starts at the same place we're ending*/			else if ((p->pts[p->nbPts-1].x == np->pts[0].x) && (p->pts[p->nbPts-1].y == np->pts[0].y)) {				u32 k;				idx = 1;				for (k=1; k<np->nbType; k++) {					switch (np->types[k]) {					case 2:						swf_path_realloc_pts(p, 2);						p->pts[p->nbPts] = np->pts[idx];						p->pts[p->nbPts+1] = np->pts[idx+1];						p->nbPts+=2;						swf_path_add_type(p, 2);						idx += 2;						break;					case 1:						swf_path_realloc_pts(p, 1);						p->pts[p->nbPts] = np->pts[idx];						p->nbPts+=1;						swf_path_add_type(p, 1);						idx += 1;						break;					default:						assert(0);						break;					}				}				free(np->pts);				free(np->types);				free(np);				gf_list_rem(paths, j);				j--;			}		}	}	/*reassemble path*/	free(a->pts);	free(a->types);	memset(a, 0, sizeof(SWFPath));	while (gf_list_count(paths)) {		sorted = (SWFPath*)gf_list_get(paths, 0);		if (read->flat_limit==0) {			swf_append_path(a, sorted);		} else {			Bool prev_is_line_to = 0;			idx = 0;			for (i=0; i<sorted->nbType; i++) {				switch (sorted->types[i]) {				case 2:					swf_path_realloc_pts(a, 2);					a->pts[a->nbPts] = sorted->pts[idx];					a->pts[a->nbPts+1] = sorted->pts[idx+1];					a->nbPts+=2;					swf_path_add_type(a, 2);					idx += 2;					prev_is_line_to = 0;					break;				case 1:					if (prev_is_line_to) {						Fixed angle;						Bool flatten = 0;						SFVec2f v1, v2;						v1.x = a->pts[a->nbPts-1].x - a->pts[a->nbPts-2].x;						v1.y = a->pts[a->nbPts-1].y - a->pts[a->nbPts-2].y;						v2.x = a->pts[a->nbPts-1].x - sorted->pts[idx].x;						v2.y = a->pts[a->nbPts-1].y - sorted->pts[idx].y;						angle = gf_mulfix(v1.x,v2.x) + gf_mulfix(v1.y,v2.y);						/*get magnitudes*/						v1.x = gf_v2d_len(&v1);						v2.x = gf_v2d_len(&v2);						if (!v1.x || !v2.x) flatten = 1;						else {							Fixed h_pi = GF_PI / 2;							angle = gf_divfix(angle, gf_mulfix(v1.x, v2.x));							if (angle + FIX_EPSILON >= FIX_ONE) angle = 0;							else if (angle - FIX_EPSILON <= -FIX_ONE) angle = GF_PI;							else angle = gf_acos(angle);							if (angle<0) angle += h_pi;							angle = ABSDIFF(angle, h_pi);							if (angle < read->flat_limit) flatten = 1;						}						if (flatten) {							a->pts[a->nbPts-1] = sorted->pts[idx];							idx++;							read->flatten_points++;							break;						}					}					swf_path_realloc_pts(a, 1);					a->pts[a->nbPts] = sorted->pts[idx];					a->nbPts+=1;					swf_path_add_type(a, 1);					idx += 1;					prev_is_line_to = 1;					break;				case 0:					swf_path_realloc_pts(a, 1);					a->pts[a->nbPts] = sorted->pts[idx];					a->nbPts+=1;					swf_path_add_type(a, 0);					idx += 1;					prev_is_line_to = 0;					break;				}			}		}		free(sorted->pts);		free(sorted->types);		free(sorted);		gf_list_rem(paths, 0);	}	gf_list_del(paths);}/*	Notes on SWF->BIFS conversion - some ideas taken from libswfdec 	A single fillStyle has 2 associated path, one used for left fill, one for right fill	This is then a 4 step process:	1- blindly parse swf shape, and add point/lines to the proper left/right path	2- for each fillStyles, revert the right path so that it becomes a left path	3- concatenate left and right paths	4- resort all subelements of the final path, making sure moveTo introduced by the SWF coding (due to style changes)	are removed. 		Ex: if path is 			A->C, B->A, C->B = moveTo(A), lineTo(C), moveTo(B), lineTo (A), moveTo(C), lineTo(B)		we restort and remove unneeded moves to get			A->C->B = moveTo(A), lineTo(C), lineTo(B), lineTo(A)*/GF_Node *swf_parse_shape_def(SWFReader *read, Bool has_styles, u32 revision){	u32 ID, nbBits, comType, i, count;	s32 x, y;	SFVec2f orig, ctrl, end;	Bool flag;	u32 fill0, fill1, strike;	SWFRec rc;	u32 bits_fill, bits_line;	SWFShape shape;	Bool is_empty;	GF_Node *n;	u32 fill_base, line_base;	SWFShapeRec *sf0, *sf1, *sl;	memset(&shape, 0, sizeof(SWFShape));	shape.fill_left = gf_list_new();	shape.fill_right = gf_list_new();	shape.lines = gf_list_new();	ctrl.x = ctrl.y = 0;	swf_align(read);	ID = 0;	/*get initial styles*/	if (has_styles) {		ID = swf_get_16(read);		/*don't care about that...*/		swf_get_rec(read, &rc);		swf_parse_styles(read, revision, &shape, &bits_fill, &bits_line);	} else {		bits_fill = swf_read_int(read, 4);		bits_line = swf_read_int(read, 4);		/*fonts are usually defined without styles*/		if ((read->tag == SWF_DEFINEFONT) || (read->tag==SWF_DEFINEFONT2)) {			sf0 = swf_new_shape_rec();			gf_list_add(shape.fill_right, sf0);			sf0 = swf_new_shape_rec();			gf_list_add(shape.fill_left, sf0);			sf0->solid_col = 0xFF000000;			sf0->type = 0;		}	}	fill_base = line_base = 0;		is_empty = 1;	comType = 0;	/*parse all points*/	fill0 = fill1 = strike = 0;	sf0 = sf1 = sl = NULL;	x = y = 0;	while (1) {		flag = swf_read_int(read, 1);		if (!flag) {			Bool new_style = swf_read_int(read, 1);			Bool set_strike = swf_read_int(read, 1);			Bool set_fill1 = swf_read_int(read, 1);			Bool set_fill0 = swf_read_int(read, 1);			Bool move_to = swf_read_int(read, 1);			/*end of shape*/			if (!new_style && !set_strike && !set_fill0 && !set_fill1 && !move_to) break;			is_empty = 0;			if (move_to) {				nbBits = swf_read_int(read, 5);				x = swf_read_sint(read, nbBits);				y = swf_read_sint(read, nbBits);			}			if (set_fill0) fill0 = fill_base + swf_read_int(read, bits_fill);			if (set_fill1) fill1 = fill_base + swf_read_int(read, bits_fill);			if (set_strike) strike = line_base + swf_read_int(read, bits_line);			/*looks like newStyle does not append styles but define a new set - old styles can no 			longer be referenced*/			if (new_style) {				fill_base += gf_list_count(shape.fill_left);				line_base += gf_list_count(shape.lines);				swf_parse_styles(read, revision, &shape, &bits_fill, &bits_line);			}			if (read->flags & GF_SM_SWF_NO_LINE) strike = 0;			/*moveto*/			comType = 0;			orig.x = FLT2FIX( x * SWF_TWIP_SCALE );			orig.y = FLT2FIX( y * SWF_TWIP_SCALE );			end = orig;			sf0 = fill0 ? (SWFShapeRec*)gf_list_get(shape.fill_left, fill0 - 1) : NULL;			sf1 = fill1 ? (SWFShapeRec*)gf_list_get(shape.fill_right, fill1 - 1) : NULL;			sl = strike ? (SWFShapeRec*)gf_list_get(shape.lines, strike - 1) : NULL;			if (move_to) {				swf_path_add_com(sf0, end, ctrl, 0);				swf_path_add_com(sf1, end, ctrl, 0);				swf_path_add_com(sl, end, ctrl, 0);			} else {				if (set_fill0) swf_path_add_com(sf0, end, ctrl, 0);				if (set_fill1) swf_path_add_com(sf1, end, ctrl, 0);				if (set_strike) swf_path_add_com(sl, end, ctrl, 0);			}		} else {			flag = swf_read_int(read, 1);			/*quadratic curve*/			if (!flag) {				nbBits = 2 + swf_read_int(read, 4);				x += swf_read_sint(read, nbBits);				y += swf_read_sint(read, nbBits);				ctrl.x = FLT2FIX( x * SWF_TWIP_SCALE );				ctrl.y = FLT2FIX( y * SWF_TWIP_SCALE );				x += swf_read_sint(read, nbBits);				y += swf_read_sint(read, nbBits);				end.x = FLT2FIX( x * SWF_TWIP_SCALE );				end.y = FLT2FIX( y * SWF_TWIP_SCALE );				/*curveTo*/				comType = 2;			} 			/*straight line*/			else {				nbBits = 2 + swf_read_int(read, 4);				flag = swf_read_int(read, 1);				if (flag) {					x += swf_read_sint(read, nbBits);					y += swf_read_sint(read, nbBits);				} else {					flag = swf_read_int(read, 1);					if (flag) {						y += swf_read_sint(read, nbBits);					} else {						x += swf_read_sint(read, nbBits);					}				}				/*lineTo*/				comType = 1;				end.x = FLT2FIX( x * SWF_TWIP_SCALE );				end.y = FLT2FIX( y * SWF_TWIP_SCALE );			}			swf_path_add_com(sf0, end, ctrl, comType);			swf_path_add_com(sf1, end, ctrl, comType);			swf_path_add_com(sl, end, ctrl, comType);		}	}	if (is_empty) {		swf_free_rec_list(shape.fill_left);		swf_free_rec_list(shape.fill_right);		swf_free_rec_list(shape.lines);		return NULL;	}	swf_align(read);	count = gf_list_count(shape.fill_left);	for (i=0; i<count; i++) {		sf0 = (SWFShapeRec*)gf_list_get(shape.fill_left, i);		sf1 = (SWFShapeRec*)gf_list_get(shape.fill_right, i);		/*reverse right path*/		swf_referse_path(sf1->path);		/*concatenate with left path*/		swf_append_path(sf0->path, sf1->path);		/*resort all path curves*/		swf_resort_path(sf0->path, read);	}	/*remove dummy fill_left*/	for (i=0; i<gf_list_count(shape.fill_left); i++) {		sf0 = (SWFShapeRec*)gf_list_get(shape.fill_left, i);		if (sf0->path->nbType<=1) {			gf_list_rem(shape.fill_left, i);			swf_free_shape_rec(sf0);			i--;		}	}	/*remove dummy lines*/	for (i=0; i<gf_list_count(shape.lines); i++) {		sl = (SWFShapeRec*)gf_list_get(shape.lines, i);		if (sl->path->nbType<1) {			gf_list_rem(shape.lines, i);			swf_free_shape_rec(sl);			i--;		} else {			swf_resort_path(sl->path, read);		}	}	/*now translate a flash shape record into BIFS*/	shape.ID = ID;	n = SWFShapeToBIFS(read, &shape);	/*delete shape*/	swf_free_rec_list(shape.fill_left);	swf_free_rec_list(shape.fill_right);

⌨️ 快捷键说明

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