TITLE:Flash SWF フォーマット
#contents
----
- ネタ元: http://www.m2osw.com/en/swf_alexref.html
* はじめに [#first]
- {header}+{header_movie}+{tag block}+{tag block}+.... といった形式
- {header}が固定長。{header_movie}が描画領域フィールドだけ可変長
- {tag block} は { tag | length | contents.... } # いわゆる TLC構造
- 複数バイトで表現する値が LittleEndian なのと、一部、ビット単位でフィールドが詰まっている事が分かれば、後は素直な形式なので楽に分解できる。
- block の中身(contents)も興味があるものだけ解析すればOKなので、中身を入れ替える場合は、入れ替えた {tag block}の length と {header}にある file_length の2箇所を更新すれば大抵のブロックは入れ替えられる。
* header [#swf_header]
// #header は自動生成されるので
+--------------------------------+
| magic | ver | file_length |
+--------------------------------+
<-3 bytes-><1 byte><-- 4 bytes -->
** magic: offset = 0 [#magic]
- FWS or CWS の 3文字 + SWF version (1 byte)
- CWS の時は、file_length の後ろ(=header_movie 以降全て)のデータが zlib 圧縮される
+-----------------------------------------------------------------+
| FWS\0 | ver | file_length | header_movie | tag_block list |
+-----------------------------------------------------------------+
<-3 bytes-><1 byte><-- 4 bytes -->
↓zlib compress↓
+--------------------------------------------------+
| CWS\0 | ver | file_length | (compressed) |
+--------------------------------------------------+
↑ compressed
header_movie & tag_block list
** file_length: offset = 4 [#file_length]
- Little Endian 4 byte
- SWF ファイル全体の byte 数
* header_movie [#header_movie]
char align (byte境界に合わせる)
|
+-------------------------------------------------------
| size | x_min | x_max | y_min | y_max | ..
+-------------------------------------------------------
<5 bits><size bits><size bits><size bits><size bits>
-------------------------------------+
.. | frame_rate | frame_rate_count |
-------------------------------------+
<-- 2 bytes --> <-- 2 bytes -->
** size: offset = 8 [#size]
- 先頭 5 bits は、この後に続く {x,y}_{min_max} のフィールドサイズ(つまり可変長)
** {x,y}_{min,max}: offset = 8 + 5(bits) + n*size(bits) (n は 0 数え) [#zabe493c]
- 表示フレームの左上と右下の座標値 (単位は [[TWIPS]])
- 負の値もとりうる事に注意。
** frame_rate: offset = 8 + 5(bits) + 4*size(bits) [#frame_rate]
- frame_rate
- little endian の 8.8固定小数点なので、0x100 倍相当の値が byte swap して入っている
** frame_rate_count: offset = 8 + 5(bits) + 4*size(bits) + 2 [#frame_rate_count]
- frame_rate_count: frame 数
* tag block [#tag_block]
- header + header_movie の後ろに TLC(Type|Length|Contents)形式で並ぶ
+----------------------------------------------------+
| header | header_movie | tag_block | tag_block| ... |
+----------------------------------------------------+
<-8bytes-> <- 可変長 -> <- 可変長 -- 数も可変 --
- tag block は contents の長さ(length)によって二種類のフォーマットに分かれる
** tag block の構造 (1) length < 0x3f [#tag_format1]
+-------------------------------------+
| tag | length | contents |
+-------------------------------------+
<-10bits-><-6bits-><-- length bytes -->
<- Little Endian ->
- tag & length は Little Endian なので
+--------------+------------+
| tag | length | tag |
| 1 0 | 543210 | 98765432 |
+---------------------------+
-- bit 構成的には↑こんな感じ。(ややこしい)
** tag block の構造 (1) 0x3f <= length or something[#tag_format2]
+------------------------------------------------------+
| tag | 0x3f | length | contents |
+------------------------------------------------------+
<-10bits-><-6bits-><-- 4 bytes --> <-- length bytes -->
<- Little Endian ->
- DefineBitJpeg* のように length の値に関係なく(0x3f 以下でも)このフォーマットを使う tag があるので注意。
** tag contents の構造 [#tag_contents]
*** (0) End [#tag0]
- SWF ファイルの末尾に来る tag は必ずこれ
+--------------+
| tag | length |
| 0 | 0 |
+--------------+
<- 2 bytes ->
*** (6, 21, 35, 90) DefineBitsJPEG* [#jpeg]
- [[Flash/SWF/format/Jpeg]]
*** (8) JPEGTables [#jpegtables]
- [[Flash/SWF/format/Jpeg]]
*** (20, 36) DefineBitsLossless* [#lossless]
- [[Flash/SWF/format/Lossless]]
*** (37) DefineEditText [#edittext]
- [[Flash/SWF/format/EditText]]
*** (39) DefineSprite [#sprite]
- [[Flash/SWF/format/Sprite]]
*** (2, 22, 32, 46, 83, 84) DefineShape* [#shape]
- [[Flash/SWF/format/Shape]]
*** (12, 59) Do*Action [#action]
- [[Flash/SWF/format/Action]]