http://hi.baidu.com/zoujun1314/blog/item/42f09bfa01c8509c58ee907a.html
前言:
最近很想用AIR开发一个游戏里自动生成SWF素材包的工具,所以需要了解清楚SWF文件的格式和结构。网上找了一下只有官方的英文文档,找不到比较完善一点的中文资料。所以索性自己翻译了一份,放出来跟大家一起分享。目前只翻译了Introduction、SWF File Format9、SWF File Format8三部分。官方的原文比较长,中间的SWF File Format 7、SWF File Format 6打算略过,后面会放上Basic Data Types的部分。文中的对于标签的讲述可能会视情况而定了。
作者:闪刀浪子 http://www.iflashigame.com http://hi.baidu.com/mr_ziqiang
原文:swf_file_format_spec_v9.pdf
Swf文件格式规范参考:http://blog.csdn.net/alenwelkin/archive/2008/02/12/2088719.aspx 作者kk
介绍章节其他部分参考:http://blog.csdn.net/flashvan/archive/2004/09/30/121482.aspx 作者:AOL
介绍
SWF文件格式规范
SWF格式(念"swiff")主要用于在互联网上传递矢量图、文本、视频和声音,且能被Adobe Flash Player软件支持。它被设计为一种高效的传输格式,而不是用于图形和图形编辑器的交换格式。以下是它的设计目标:
适合屏幕显示——需要适合屏幕显示同时支持抗锯齿。能够快速渲染各种颜色格式的位图、动画和交互按钮。(ps:比如ARGB、RGBA等)
易于扩展——使用标签格式,让他能够很容易保证与Flash Player之前的版本兼容同时又能够随意扩展新的特性。
方便网络传输——要能够在有限或者不确定的带宽下传输。文件使用压缩来减少尺寸同时支持流式渲染。采用的是二进制格式的标签而不是像HTML一样的可读性标签,同时使用了bit-pack(ps:相当于内置一些编译好的二进制)和标记位结构(structures with optional fields)的技巧来让文件跟小。
(ps:标记位结构表示用一个字节中的某几个位来作为标记,比如:某字节的二进制位:10001010,最高位的为1表示某个标记位true,如果为0表示某个标记位false)
简单——这种格式需要尽量简单以使他的播放器小一点容易实现。同时他还必须尽量少依赖操作系统的特性,方便跨平台。
文件独立——这种文件的现实不要依赖像字体这样外部的资源
可伸缩性——在有限硬件条件下能够运行,同时在硬件条件好的情况下能够充分发挥硬件优势。这一点很重要因为计算机有不同的显示分辨率和处理能力。
迅速——高速、高质量的渲染。
脚本实现——这种格式包含各种标签,标签提供堆栈机解释需要的字节码。字节码支持ActionScript 语言。Flash Player 提供运行时的ActionScript 对象模型允许Flash Player的图元、服务交互。
SWF文件使用.swf作为扩展名,application/x-shockwave-flash为MIME类型。
SWF格式经历了几个版本。直到SWF5才真正明确了SWF标签设置。SWF6及后面的版本改变很小,一些新的特性部分或者全部在ActionScript脚本层实现。(ps:底层不怎么变了)从SWF9开始,AS3使用了新的虚拟机。任何打算使用新特性来生成swf文件内容都需要熟悉Flash Player公开的ActionScript 对象模型(ActionScript object model)。更多的信息请参考“ActionScript3.0编程”,“ActionScript 3.0语言参考”和Adobe Action Script 虚拟机2的概览。(www.adobe.com/go/avm2overview/ )
SWF文件头
所有的SWF文件都由文件头开始。数据类型定义请阅读后面的“基本数据类型”章节。
(类型中U表示无符号,I表示整型。下面的UI8表示占8位二进制的无符号整型)
SWF文件头 | ||
字段 | 类型 | 说明 |
标志 | UI8 | 标志字节: 如果是“F”表示未压缩,如果是“C”表示压缩(SWF6之后才有 |
标志 | UI8 | 始终为"W" |
标志 | UI8 | 始终为"S" |
版本号 | UI8 | 一个字节的版本号(如0x06表示SWF6) |
文件长度 | UI32 | 完成文件的长度有多少字节 |
显示尺寸 | RECT结构 | 以twips为单位的显示尺寸,20twips=1px,Rect结构请阅读后面的基本数据类型章节。 |
帧速 | UI16 | 每秒的帧速,通过一个8.8小数方式显示。(整数和小数各占8位) |
帧总数 | UI16 | 文件中帧的总数。 |
文件头都是由三个字节开始的0x46,0x57,0x53(“FWS”);或者0x43,0x57,0x53(“CWS”)。FWS表示文件没有压缩,CWS表示第8个字节后面是经过ZLIB开放标准压缩的(文件长度字段后面)。SWF6之后的版本才开始使用压缩。
版本号占一个字节紧跟在标志之后。版本数字不是一个ASCII字符而是一个8位的数字。例如SWF4,版本号字节为0x04,而不是ASCII字符“4”(0x35)。
文件长度字段记录SWF文件的总长度,包括文件头。对于未压缩的swf文件(标志位FWS),文件长度字段的数值跟该文件长度一致。而对于压缩的swf文件(标志为CWS),文件长度字段的长度表示第8个字节之后的数据解压缩之后的长度。(ZLIB标准)
显示尺寸字段定义了屏幕显示的宽度和高度。这个字段使用一个RECT结构来存储(一种可变长度的存储结构,详细信息看基本数据结构中对于RECT的介绍),这表示它的占位长度会根据bits的描述来随时改变。显示尺寸字段的RECT结构的Xmin和Ymin通常为0;Xmax和Ymax定义宽度和高度。
帧速字段定义了每秒的播放速率。这个速率无法绝对保证,比如CPU忙的时候或者慢的时候。
帧总数定义了SWF文件的总帧数。(ps:注意到没有?只有16位,那么帧总数的极限只能是65535帧了)
SWF文件结构
文件头之后是一系列的标记的数据块(ps:一般成为标签Tag)。所有的标签(Tag)都使用公用的格式,所以程序在分析SWF文件的时候都可以跳过一些不明确的数据块。数据块里面的数据可以定位到内部的偏移位置,但是不能定位到其他块中的偏移位置。(ps:主要是保证Tag间相互独立,记得flash的设计灵感是来自乐高积木的。不同的Tag相当于不同的积木块。)这样的方式使我们可以在处理SWF文件的时候通过工具移除、插入、编辑标签。
SWF文件结构图
FileAttributes 标签在SWF8之后才需要。
标签格式
每一个标签的开始都是标签的类型和长度。标签头可以是短标签头类型也可以是长标签头类型。短标签头类型用于数据在62字节之内的标签。如果标签的数据长度不超过62个字节使用短标签。而长标签头类型可以用于数据在4G之内的任何标签。
标签头记录(短类型) | ||
字段 | 类型 | 说明 |
TagCodeAndLength | UI16 | 高10位表示标签类型 低6位表示标签长度 |
注意事项 | TagCodeAndLength字段是一个两个字节的字,而不是一个10位的字段跟随一个6位字段。SWF使用低位在前(little-endian)造成上述两种情况是不同的。 (ps:如果TagCodeAndLength字段的十六进制是 43 02 那么实际上的值是0234 二进制为 00000010 01000011 前10位的值是9 表示这是一个SetBackgroundColor标签) |
标签的长度不包括标签头记录自己的长度,仅表示其后面数据的长度。
如果标签为63字节或者更长,它将存储为一个长标签头的类型。长标签头可以看成一个标签长度为0x3f的短标签跟着一个32位的长度。(ps:这表示只要TagCodeAndLength中的后6位的值为0x3f,那么肯定是一个长标签头类型。)
标签头记录(短类型) | ||
字段 | 类型 | 说明 |
TagCodeAndLength | UI16 | 高10位表示标签类型 低6位始终为0x3F |
Length | SI32 | 标签的长度 |
定义型标签和控制型标签
Swf文件有两类标签:定义型和控制型
定义型标签定义SWF文件的内容如Shapes、文本、位图、声音等等。每一个标签会为定义的内容分配一个唯一的编号称做角色编号(character ID)。之后Flash Player 将角色(character)存储在称作字典(dictionary)的仓库。定义型标签本身不产生渲染。
控制型标签创建和操作已渲染的字典中角色的实例,同时控制文件流程。
SWF文件中标签(Tag)的排序
一般来讲,SWF中的标签(Tag)可以随意排序。但是必须遵循以下规则:
1、如果是SWF8之后的版本则FileAttributes 标签必须为第一个标签
2、标签仅依赖之前的标签,而不依赖后面的标签。(ps:我的理解是后面需要用到的内容始终会在前面先定义,跟下一条控制型标签的规则类似)
3、角色的定义标签必须出现在引用他的控制型标签之前。
4、声音流标签必须有序。无序的声音标签会导致播放时也无序。
5、结束标签始终在SWF文件的最后