Swf渲染之——文件结构

上一节我们下载了Swf文件,现在我们来尝试阅读它,使用ffd(JPEXS Free Flash Decompiler)来打开这个文件,我们可以看到Swf文件的结构如下:

Swf文件结构

其中有

对于大部分开发者来说,这样理解足够了,但是我们为了解读swf,必须换一个角度,点击右上角的16进制转储

Swf文件16进制转储

我们可以看到这样的画面

Swf文件标签序列

文件头

可以发现,swf文件内部首先是几条header信息,被称为文件头,但是在具体的读取的时候,需要注意文件头是被分割的,format,version,file_length被我称为SwfFileInfo,frame_size,frame_rate,frame_count被我称为SwfHeader,如图

Swf文件头

其中

标签

之后就是元信息标签和一系列定义标签,这些标签都继承于Tag,符合Tag的基本格式。

在官方定义中,Tag是一个基类,每个Tag都有一个Header,定义如下

Tag基类

要注意,虽然TagTagCodeAndLength看起来像两个字段,但是存储方式是UI16,必须一次读完然后移位操作,这是因为swf使用小端序,在硬盘中低位在前

聪明的小伙伴肯定会想:这6位的TagLength也太短了,最多也就63,tag一大不就无法描述了么?

所以!SWF的Tag Header还有另一种格式!如下:

LongTag

这种长类型有一个专门的Length字段,UI32,能存储整整2GB的标签长度。

🤔 别吵,我在烧烤
解析的时候怎么判断是哪一种?
—— 根据TagLength的值是否为极限值来判断,如果TagLength的值是63,则认为是长Tag,需要进一步读取Length字段作为真正的长度

SetBackgroundColorTag

让我们来实战演练一下吧,让我们看看第二个2Tag在16进制下长什么样子:

ABCT_Hex

一串16进制数字, 43 02 99 99 99

其中 43 02 是 Header部分,由于swf用的是小端序,所以真实的值为 02 43

换算成二进制就是 0000 0010 0100 0011

高10位换算回10进制是9,也就是SetBackgroundColorTag的枚举值

低十位换算成10进制是3,3 < 63,也就是说后面还有3个字节

于是我们就确定了这个Tag的具体类型为SetBackgroundColorTag,先看看官方定义:

SetBackgroundColorTag

很明显,这个Tag很简单。除了TagHeader只有一个固定的RGB3值,其长度正好与之前读到的3相等。那么剩下的99 99 99也就很好理解了:

一个RGB(0x99, 0x99, 0x99)的结构体。换算成10进制,就是RGB(153, 153, 153)

看一眼FFD的结果:

FFD结果

果然,分毫不差!


1

RECT是一个变长结构体,定义如下 RECT结构体

其中

2

之所以不用FileAttributesTag是因为这个Tag在动画渲染方面用处不大且太复杂

3

RGB是一种颜色的存储方式,用红绿蓝三个通道表示颜色,不支持透明度,在swf中定义如下 RGB结构体 每个通道一个字节,范围0~255,共3字节,24bit。