加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swf文件格式(结构)

发布时间:2020-12-15 18:23:26 所属栏目:百科 来源:网络整理
导读:这个在自己开发辅助工具时很有用啊,转来学习一下 swf文件的整体结构是 header + body的组成。 文件的开始是一个[文件头] 它的结构如下: [Copy to clipboard] [ - ]CODE: 字节?????? 名称???????????? 说明 1?????????? Signature????? “F”表示非加密格式

这个在自己开发辅助工具时很有用啊,转来学习一下

swf文件的整体结构是 header + body的组成。

文件的开始是一个[文件头]
它的结构如下:

[Copy to clipboard] [ - ]CODE:
字节?????? 名称???????????? 说明
1?????????? Signature????? “F”表示非加密格式,“C”表示加密格式
1?????????? Signature????? “W”无特殊意义
1?????????? Signature????? “S”无特殊意义
1?????????? Version???????? 版本号,它表示对应播放器版本
4?????????? FileLength???? 整个文件长度,低位在前
N?????????? FrameSize???? RECT结构体,表示屏幕大小,具体结构和长度根据数据变化,分析方法另外讨论。
2?????????? FrameRate???? 帧频,默认为12,高位在前
2?????????? FrameCount?? 帧数,表明文件根下的帧数,低位在前
以上是swf中,最简单的一个tag,一个完整的swf文件是由很多独立的tag组成的。每一个tag都包括一个头和一个数据体,头有2种类型,短tag型和长tag型。

短tag型由2byte构成,前10个bit表示tag类型,后6个bit表示tag长度。

长tag型由6byte构成,前10个bit表示tag类型,后6个bit固定为全1,后4个byte代表tag长度。

tag的长度不同于文件头的长度FileLength,它是除去tag头后的长度。

(另外)只有非加密的swf文件可以直接用以上的方法解析,加密的文件需要另外增加一步处理。具体方法由于牵涉到版权问题,这里我不加说明。


这份资料可能对flash设计意义不大,但如果有人用的着,我会继续分析一下,如果有人也在做这方面的调查,欢迎和我一起讨论。


第2节

前节说明了swf文件是由1个head和1个body构成的。
并且解析了header的结构,和一个tag的header部分的简单说明。

下面余下的就是swf文件的body了。

整个文件body是由大量的tag组成的,通过分析tag的head部分,可以立刻知道这个tag的类型代码和长度。

如果你无法识别这个tag的类型,也可以利用tag的长度,直接跳过这个tag。

这种方式保证了版本的兼容性,即使出现了新的tag,老版本的播放器还是能够解析完整个swf文件而不出现错误,大不了就是不能提供新的功能而已。

以下就是swf文件结构的一个形象概念。

[Copy to clipboard] [ - ]CODE:
(文件header)(文件body)
?????????????? |
(tag 1)(tag 2)(tag 3)(……)
??? |
(tag header)(tag body)
??? |
(tag 类型代码)(tag 长度)
这样大家是否对swf文件的结构有了一个基本的认识?

下一节我会分析一下几个swf必有的tag,包括 backgroundColor tag,showFrame tag和end tag

第3节
setBackgroundColor tag

这个tag是直接跟在文件head后面的第一个tag,是文件中必然存在的。
它的结构如下:

[Copy to clipboard] [ - ]CODE:
长度(bit)??????????? 名称???????????????????????? 说明
16????????????????? header???????????????????? tag头,短tag型 类型码为9
24????????????????? BackgroundColor??????? RGB类型,右3个字节,分别表示红、绿、蓝
showFrame tag

这是文件最后第2个tag,它是必然存在的。
结构如下:

[Copy to clipboard] [ - ]CODE:
长度(bit)??????????? 名称???????????????????????? 说明
16?????????????????? header???????????????????? tag头,短tag型 类型码为1
end tag

结束tag,它的作用不用我说了,必然是文件的最后一个tag。

[Copy to clipboard] [ - ]CODE:
长度(bit)??????????? 名称???????????????????????? 说明
16?????????????????? header???????????????????? tag头,短tag型 类型码为0
下一节我将讲的是character ID 和Depth的意义和textField的基本tag组成。
(另外)感谢AOL的补充和解释。

第4节
一个textField就是一个文本框,文本框有3种,静态的,动态的,和输入型。作为tag的话,它只有2种,静态的和动态的,输入型不过是动态的一种特别形式。

这里讨论动态文本框的组成。
它由3个tag组成,2个定义tag和一个控制tag
分别是:
定义tag??? DefineFont2?? DefineEditText?? (针对player 7.0 如有不同情况请检查播放器版本)
控制tag??? PlaceObject2

DefineFont2 定义了一个字体信息, DefineEditText引用了定义的字体,并定义了显示的文字信息,而PlaceObject引用了定义的文字信息,并控制了文字的显示。

他们之间的引用就是依靠character ID进行的。

character ID就是一个从1开始的数字标示,如果中间出现缺漏,从缺漏开始的所有character ID都被忽略,而重复的话,后出现的将覆盖先出现的tag。

DefineFont2用一个character ID 来标示自己,DefineEditText和PlaceObject2也同样如此。但并不是所有的tag都有character ID。
另外,PlaceObject2虽然也有character ID,但它并不是用来标示自己的,而是用来调用的。

而深度Depth在3个tag中只有PlaceObject2拥有。

这3个tag的关系就是这样。这3个tag的结构我会在下节中说明。(抱歉,每次都说一点点!)

第5节

DefineFont2
这个tag的作用是定义一个字体,或者一组静态轮廓字,用以给DefineEditText使用。

关于文字的几乎所有信息,都可以在这个tag中进行设置,因此,这也是一个相当复杂的tag。
它的结构如下:

[Copy to clipboard] [ - ]CODE:
长度(bit)??????????????????????? 名称???????????????????????? 说明
headerLength??????????????? header????????????????? tag头,类型码为48
16??????????????????????? FontID??????????????????? character ID,唯一的标示
1????????????????????????? FontFlagsHasLayout?? 根据字面解释,判断是否有变型的标记
1????????????????????????? FontFlagsShiftJIS?????? 是否使用ShiftJIS编码
1????????????????????????? FontFlagsSmallText??? 是否使用小字体显示
1????????????????????????? FontFlagsANSI?????????? 是否使用ANSI编码
1????????????????????????? FontFlagsWideOffsets 是否使用32位偏移量
1????????????????????????? FontFlagsWideCodes?? 是否使用16位文字编码
1????????????????????????? FontFlagsItalic??????????? 文字是否是斜体
1????????????????????????? FontFlagsBold???????????? 文字是否是粗体
8????????????????????????? LanguageCode?????????? 语言编码,有相应的编码表对应
8????????????????????????? FontNameLen??????????? 文件名长度
FontNameLen*8??????????? FontName?????????????? 文件名称(使用utf8编码)?
16?????????????????????????????? NumGlyphs????????????? 轮廓字个数
32/16????????????????????????? OffsetTable????????????? 根据FontFlagsWideOffsets,为32位,否则为16位
32/16????????????????????????? CodeTableOffset????? 同上
不定*NumGlyphs?????????? GlyphShapeTable????? 轮廓字信息,为shape结构(又是一个复杂结构)
16/8??????????????????? CodeTable?????????????? 根据FontFlagsWideCodes,为16位。编码表,为固定值UCS-2
16/0??????????????????? FontAscent???????????? 根据FontFlagsHasLayout,为16位,否则没有该字段
16/0?????????????????? FontDescent??????????? 根据FontFlagsHasLayout,为16位,否则没有该字段
16/0?????????????????? FontLeading??????????? 根据FontFlagsHasLayout,为16位,否则没有该字段
16/0*NumGlyphs???????? FontAdvanceTable?? 根据FontFlagsHasLayout,为16位,否则没有该字段
RECT*NumGlyphs??????? FontBoundsTable???? 根据FontFlagsHasLayout,为16位,否则没有该字段
16/0????????????????????????? KerningCount???????? 根据FontFlagsHasLayout,为16位,否则没有该字段
KERNINGRECORD*KerningCount
???????????????????????? FontKerningTable???? 根据FontFlagsHasLayout,为16位,否则没有该字段
如果你仔细看了上面的内容,我挺佩服你的。

其实如果单纯分析动态文本的这个tag的信息,只需要分析到上面的fontName部分就足够了,其他信息只对轮廓字,也就是静态文字有效。

看到这个大家应该都明白了一点,动态文字在信息上,关键的只有一个字体名,而静态文字却包含了他的轮廓信息(包含在shape里)。
这就是动态文字和静态文字最大的不同。

下一节讲下一个tag????? DefineEditText


rect结构这个没有说清楚.它是flash存储结构的一种.

????? 属性???????? 类型???????????????????? 说明??
????? Nbits??????????? nBits = UB[5]?????????? rect结构的各个属性值的位数
????? Xmin??????????? SB[nBits]??????????? x轴方向的最小值
????? Xmax??????????? SB[nBits]??????????? x轴方向的最大值
????? Ymin??????????? SB[nBits]??????????? y轴方向的最小值
????? Ymax??????????? SB[nBits]??????????? y轴方向的最大值


这里涉及到swf文件中的一个长度单位:twip. 1 twip也就是一像素的1/20.

Nbits一般等于最大属性值的位数.比如影片有这个属性:

属性???????????? 十进制???????????  二进制
Xmin = 127 decimal =???? 2222211 binary?
Xmax = 260 decimal =??? 10000100 binary?
Ymin =?? 15 decimal =??????? 1111 binary?
Ymax = 514 decimal = 1000000010 binary


那么最大的属性值是ymax了.它为514了,它有十位,加上正负数的一个sign就十一位了.那么Nbits应该会是11.


这时:
属性???????????? 十进制???????????  ????? 二进制
Nbits =??? 11 decimal =??????? 1011
Xmin =??? 127 decimal =???? 00002222211 binary?
Xmax =?? 260 decimal =??? 00010000100 binary?
Ymin =??? 15 decimal =???? 00000001111 binary?
Ymax =?? 514 decimal =??? 01000000010 binary

用java读取就可以:

//其中readUBits是读取unsigned bit的函数
//readSBits是读取signed bit的函数
public Rectangle2D readRect()
???????? throws IOException {

???????? byteAlign();
???????? int nbits = (int)readUBits(5);
???????? int xmin = (int)readSBits(nbits);
???????? int xmax = (int)readSBits(nbits);
???????? int ymin = (int)readSBits(nbits);
???????? int ymax = (int)readSBits(nbits);
???????? return new Rectangle2D.Double(xmin/TWIPS,ymin/TWIPS,(xmax-xmin)/TWIPS,(ymax-ymin)/TWIPS);
???? }


我算是抛砖引玉吧,兄弟们有更多的内容大家一起加!

这是swf 文件的组成形式.swf文件头占21字节,尾标签(EndTag)占三个字节.其它的tag每个都有统一的组成结构,而且它们是彼此独立的.从这个tag不能访问那个tag的数据.每个tag内部的数据读取方法是根据数据的偏移量(offset)来读取.因为是独立的,所以你可以用工具来修改,添加,删除swf文件里面的tag.


// java的添加tag?
???? final TagCollection tc = new TagCollection();?????
???? tc.add(tag1);?????
???? tc.add(tag2);?????
???? ...?????
???? final TagEnumeration te = tc.close();?????

重复sansunzw兄弟的了:
tag可以分为两种,一种是定义型tag,另外一种是控制型tag.
tag按长度也可以两种,一种是长型tag,一种是短型tag.]
tag一般都由tag头开始.
短型tag的tag头有十六位,高十位为tag的类型,低六位为定义这个tag的长度.因为是6位,所以短型tag只能最多是2^6 =64字节左右大小.swf 有规定不能超过62字节大小.
长型tag的tag头有48位,16位tag类型定义+32位tag长度定义.所以长型tag最大长度能为2^32=4G字节.这可远远超过了我们平时用到的那个数量级了.

//这个java 的关于swf tag头的一个类
//很多相关的代码不列了
public class TagHeader {

???? int tagID;
???? long length;

???? public TagHeader(int tagID,long length) {
???????? this.tagID = tagID;
???????? this.length = length;
???? }
????
???? public void setTag(int tagID) {
???????? this.tagID = tagID;
???? }
????
???? public int getTag() {
???????? return tagID;
???? }
????
???? public void setLength(long length) {
???????? this.length = length;
???? }
????
???? public long getLength() {
???????? return length;
???? }
}

定义型和控制型tag(Definition and Control Tags)是swf文件tag的两种类型。定义型tag定义的swf影片的内容,像形状啊,文字啊,位图啊,声音啊等等。每个定义型tag都分配

了一个唯一的标识ID叫做角色ID.flash播放器则把这些角色放到一个存储空间里面,这个存储空间我们一般叫它字典。用定义型tag是不会绘制任何图形的,不会产生任何动画的。

因为这些事都交由控制型tag来做。控制型tag做的就是从字典里取出角色,操作这些的绘制和运动等,控制整个影片的流程。

这些tag是怎么排序存储起来的呢?总的来说,tag可以出现任何情况的排序方法,但也不是随便乱排咯。 它遵循一些规则。


1.一个tag只能依靠在它之前的tag,不能依靠在它之后的tag.
2.一个定义了角色的定义型tag必须在引用这个角色的控制型tag之前。
3.流媒体tag必须有顺序,没有顺序的流媒体播放起来也是没有顺序的
4.结尾标签(tag)应该在swf文件的最后。

(待续)

swf文件是由文件头和文件体组成,两者都不定长,文件头定义了本swf文件的版本、是否压缩、文件大小、场景大小、帧率、总帧数共6个内容,这些内容非明文,均以数字的存储方式表现出来,楼主提供的第一个表格详细指示了这些内容的相关信息,稍微补充一下,第一个字‘C’代表本swf文件是否被压缩,当你用flash6以后版本,public setting设置里会有“压缩影片”,选中后,出来的swf文件都是‘C’开头的。 压缩影片,是指从文件头中的filelength部分以后所有内容,包括文件体,都被标准压缩算法处理了。算法是zlib,压缩的好处,就是swf文件变小。
下面举例:
?? 46 57 53 05 AF 00 00 00 78 00 05 5f 00 00 0f a0
?? 00 00 0c 01 00 43 02 ff ff ff 00 06 3f 03 15 00 00 00

46 57 53 就是‘fws’的asc码,此处显示的都是16进制,大家注意了。05 代表本swf是flash5兼容格式,如果是0c,就表示本swf是flash12格式,嘿嘿,不知道将来的flash12会是什么样子。af 00 00 00就是16进制数‘af’的存储方式,af转换成10进制是175,就是本swf文件的总长度。78 00 05 5f 00 00 0f a0 00,表示了场景大小,这个长度不定,此处占用了9个byte,究竟为什么占用9个,大家可以看rect的结构指示,此处不再做介绍。00 0c 表示帧率12,c就是12,没有人反对吧。01 00表示本swf文件共1帧。文件头到此结束,以上结构是必须的,不能少任何一项。43 02 ff ff ff 是个“块”,这里罗嗦一下,文件体是由大量的块组成的,这些块内容独立,一起配合显示动画,比如有的块表示了一个矩形,有的块存储了一段音乐,有的块表示了此处为一帧,等等。??? 块,组成了文件体,但每一个块都是可以割舍的,这5个 byte的块表示了底色,红为ff,绿为ff,兰为ff,合起来就是白色啦。再罗嗦一下,块,不严格的说,就是楼主所说的tag。块是堆砌在一起的,两个块之间没有什么分割符号,因为每个块的长度都有定义,比如这个块,43 02就表示了本块占用3 byte,加上43 02,就是5个byte,所以后面的:00 06就不是本块内容啦。为什么43 02表示本块代表底色,还占3个byte呢?哎,偏题了,说到文件体了。以后再作介绍吧。最后介绍一个,00 06表示本文件保护,不允许导入到别的flash中,这也是一个块,嘿嘿,最小的块就是由2byte组成,把它去掉就不保护了,好像是废话啊,哈哈,别忘了改一下文件长度位,减少2。如果带密码,此处就不是00 06了。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读