SWF内における基本的なデータ構造について
DATA STRUCTURE
SWF内では数多くのデータ型が定義されていますが、データ量を最小にするために、可変長ビットフィールドを用いることがあります。その実例として、RECT型をみてみましょう。RECT型
フィールド | 型 | 説明 |
---|---|---|
Nbits | UB[5] | RECT型のそれぞれのフィールドのビット長。 |
Xmin | SB[Nbits] | 矩形の中でのx座標の最小値(単位はtwip) |
Xmax | SB[Nbits] | 矩形の中でのx座標の最大値(単位はtwip) |
Ymin | SB[Nbits] | 矩形の中でのy座標の最小値(単位はtwip) |
Ymax | SB[Nbits] | 矩形の中でのy座標の最大値(単位はtwip) |
NBitsフィールドについてですが、これは例をみると分かりやすいので、例をあげてみます。例えば、
Xmin | = | 127 [10進数] | = | 1111111 [2進数] |
Xmax | = | 260 [10進数] | = | 100000100 [2進数] |
Ymin | = | 15 [10進数] | = | 1111 [2進数] |
Ymax | = | 514 [10進数] | = | 1000000010 [2進数] |
のうち、もっとも桁数が多いのはYmaxの514でこれを表現するには11ビット必要(符号付きなので、01000000010)です。よって、可変長ビットフィールドの長さは11ビットあれば十分ということになるので、Nbitsには11が入ります。従って、このRECT型のデータを図式で表せば、
フィールド | 型 | 説明 |
---|---|---|
Nbits | UB[5]=1011 | RECT型のそれぞれのフィールドのビット長。 |
Xmin | SB[Nbits]=00001111111 | x座標の最小値(127twip) |
Xmax | SB[Nbits]=00100000100 | x座標の最大値(260twip) |
Ymin | SB[Nbits]=00000001111 | y座標の最小値(15twip) |
Ymax | SB[Nbits]=01000000010 | y座標の最大値(514twip) |
STRING型
フィールド | 型 | 説明 |
---|---|---|
String | UI8[0以上] | SWF6以上ではUTF-8でエンコードされている。 |
StringEnd | UI8 = 0x00 | null文字 |
Stringの終了はC等でのASCII文字の取扱いと同様、0x00(null文字)で表します。
SWFファイル構造概要
この文章はAdobe®のSWF File Format Specification Version 9(SWFファイル形式仕様書(for SWF Player 9))に基づいて書かれていますが、この文章の和訳ではありません。正確な情報が得たい場合はSWF File Format Specification Version 9の原文を読むことを強く推奨します。
SWFの構成
SWF("swiff"と発音)ファイルの構造は以下の図式に示すような構造を持つ。ヘッダー | ファイル属性タグ | タグ | タグ | …… | タグ | 終了タグ |
ヘッダーの構成
フィールド | 型 | 説明 |
---|---|---|
拡張子 | UI8 | C(=0x43)またはF(=0x46)。Cはバージョン6以上の圧縮されたSWFを表す。 |
拡張子 | UI8 | W(=0x57)。常に。 |
拡張子 | UI8 | S(=0x53)。常に。 |
バージョン | UI8 | ASCIIキャラクターでなくUI8の数字が入る。バージョン6なら0x06。 |
ファイル長 | UI32 | ヘッダーを含めたファイルの大きさ(バイト単位)。 |
SWFの大きさ | RECT | RECT型(後述)。SWFの大きさをtwip単位(1/20px)で表す。 |
フレームレート | UI16 | 8.8固定小数点型でフレームレートを表す |
総フレーム数 | UI16 | フレーム数を表す。 |
- UI8は(8ビットの非負整数)、UI16は(16ビット非負整数)、UI32は(32ビット非負整数)を表します。SWFファイル内でのデータの格納方法は、リトルエンディアン方式でバイトを格納し、ビッグエンディアン方式でビットをバイト内で格納します。少し分かりにくいですが、これはつまり、32ビットの整数データ0x456e7120があったとき、20 71 6e 45と格納するということです。
- 8.8固定小数点型についてですが、3.5を16進数で表記すると、0x03.80なので、80 03というように格納されています。
- ファイル長についての注意ですが、SWCつまり圧縮されたSWFの場合、ファイル長に記録されている数値と実際のファイルサイズがことなることがあります。
- RECT型。Xminフィールド、Yminフィールドは共に0になる。単位はtwipと呼ばれるもので、1twip = 1/20pxである。
さてヘッダーについての解説は大体以上ですが、SWFファイルにおいて、ヘッダーの次に来るのはタグのブロック達です。タグは共通の形式であるため、SWFをパースするどんなプログラムも不明な命令のタグはスキップできるように作られています。またタグのブロック内のデータがタグの外のデータを指したりすることはないので、タグのブロック単位を取り除いたり、付け加えたりということができるようになっています。ファイル属性タグというのはバージョン8(以下SWF8と略記)以降から取り入れられたものですが、これについては後述。
タグの構成
ヘッダー
それぞれのタグはタグの番号と長さを記録するフィールドから始まります。このヘッダーには短いものと長いものの二つがありますが、短いヘッダーは62バイト以下のタグのブロック用に、長いヘッダーは(今のところ実用的なサイズをはるかに上回る)最大4GBまでのタグブロック用に用いられます。タグの番号についてはタグ一覧を参照。以下が短いヘッダーの構成です。RECORDHEADER型と呼ばれます。
フィールド | 型 | 説明 |
---|---|---|
タグヘッダー | UI16 | 上位10ビットにタグの番号、下位6ビットにタグの長さを格納 |
- 注意すべきはこのタグヘッダーのフィールドは2バイトのフィールドであり、10ビットのフィールドに6ビットのフィールドが続いているものではないということです。
- タグの長さにはヘッダーを含めません。
長いヘッダーの構成は以下のようになります。
フィールド | 型 | 説明 |
---|---|---|
タグヘッダー | RECORDHEADER | 長さのフィールドが0x3Fになっている短いヘッダー |
長さ | SI32 | タグの長さ |
- 上の表のタグヘッダーはつまり、上位10ビットにタグの種類、下位6ビットは全て1が格納されている111111(=0x3f)ということです。
タグ一覧
番号 | タグ名 |
---|---|
0 | End |
1 | ShowFrame |
2 | DefineShape |
4 | PlaceObject |
5 | RemoveObject |
6 | DefineBits |
7 | DefineButton |
8 | JPEGTables |
9 | SetBackgroundColor |
10 | DefineFont |
11 | DefineText |
12 | DoAction |
13 | DefineFontInfo |
14 | DefineSound |
15 | StartSound |
17 | DefineButtonSound |
18 | SoundStreamHead |
19 | SoundStreamBlock |
20 | DefineBitsLossless |
21 | DefineBitsJPEG2 |
22 | DefineShape2 |
23 | DefineButtonCxform |
24 | Protect |
26 | PlaceObject2 |
28 | RemoveObject2 |
32 | DefineShape3 |
33 | DefineText2 |
34 | DefineButton2 |
35 | DefineBitsJPEG3 |
36 | DefineBitsLossless2 |
37 | DefineEditText |
39 | DefineSprite |
43 | FrameLabel |
45 | SoundStreamHead2 |
46 | DefineMorphShape |
48 | DefineFont2 |
56 | ExportAssets |
57 | ImportAssets |
58 | EnableDebugger |
59 | DoInitAction |
60 | DefineVideoStream |
61 | VideoFrame |
62 | DefineFontInfo2 |
64 | EnableDebugger2 |
65 | ScriptLimits |
66 | SetTabIndex |
69 | FileAttributes |
70 | PlaceObject3 |
71 | ImportAssets2 |
73 | DefineFontAlignZones |
74 | CSMTextSettings |
75 | DefineFont3 |
76 | SymbolClass |
77 | Metadata |
78 | DefineScalingGrid |
82 | DoABC |
83 | DefineShape4 |
84 | DefineMorphShape2 |
86 | DefineSceneAndFrameLabelData |
87 | DefineBinaryData |
88 | DefineFontName |
89 | StartSound2 |
タグの種類
タグは定義タグとコントロールタグの二つに分類されます。定義タグはSWFファイル内のコンテンツ(シェイプ、テキスト、ビットマップ、音等)を定義するタグです。定義タグはそれぞれのコンテンツに対しユニークなcharacter IDと呼ばれるIDを振ります。Flash Playerはcharacterを辞書とよばれる領域に格納します。また、定義タグ自身は描画を引き起こしません。つまり、ただ定義するだけです。
コントロールタグは辞書内に保存されたcharacterのインスタンスを生成したり操作したり、ファイルの処理の流れをコントロールしたりします。
タグの順序についての注意
一般的にSWFファイル内においてタグの順序はどのような順序で合っても構いませんが、以下のルールがあります。- ファイル属性タグ(SWF8以降)は最初に来なければならない。
- タグはそれ以前のタグにしか依存しない。つまり、それ以前に登場したタグ内での内容しか見えていないということです。
- これは上にも通じますが、character Aを定義する定義タグはcharacter Aを参照しようとするどのコントロールタグよりも前に来なければならない。
- サウンドのストリーミングは正しい順番で現れなければならない。
- 終了タグは常にSWFの最後に来なければならない。
辞書
辞書とはcharacterを保存する倉庫のようなものであって、コントロールタグで使用することができる。辞書の構築と使い方は以下のような手順になる。- 定義タグが、シェイプやフォント、ビットマップや音といったコンテンツを定義する。
- 定義タグはそのコンテンツに対しユニークなcharacter IDを割り振る。
- コンテンツはcharacter IDと一対一に辞書に保管される。
- コントロールタグはcharacter IDによってコンテンツを辞書から取り出し、例えば、シェイプを表示したり、音を再生したりといったふうに、何かしらのアクションを行う。
character IDはユニークであり、重複してはならない。典型的には1,2,3と順に番号を振って行く。0にはnull characterという特殊なcharacterとして認識される。
辞書によってcharacterを参照するのはコントロールタグだけではなく定義タグもさらにより複雑なコンテンツを定義するために既に辞書に登録されているcharacterを参照して使用することができる。例えば、DefineButtonやDefineSpriteといったコントロールタグ等がそうであり、DefineTextタグもテキストに異なるフォントを使うためにfontのcharacterを参照することができる。
要約
- SWFファイルはヘッダーとそれに続く沢山のタグから構成される。
- タグには2種類あり、それは定義タグとコントロールタグである。
- 定義タグはオブジェクトをcharacterとして定義し辞書に保管する。
- コントロールタグはcharacterを操作したり、ファイルの処理の流れをコントロールしたりする。