SWF内における基本的なデータ構造について

DATA STRUCTURE

SWF内では数多くのデータ型が定義されていますが、データ量を最小にするために、可変長ビットフィールドを用いることがあります。その実例として、RECT型をみてみましょう。

RECT型






フィールド説明
NbitsUB[5]RECT型のそれぞれのフィールドのビット長。
XminSB[Nbits]矩形の中でのx座標の最小値(単位はtwip)
XmaxSB[Nbits]矩形の中でのx座標の最大値(単位はtwip)
YminSB[Nbits]矩形の中でのy座標の最小値(単位はtwip)
YmaxSB[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型のデータを図式で表せば、








フィールド説明
NbitsUB[5]=1011RECT型のそれぞれのフィールドのビット長。
XminSB[Nbits]=00001111111x座標の最小値(127twip)
XmaxSB[Nbits]=00100000100x座標の最大値(260twip)
YminSB[Nbits]=00000001111y座標の最小値(15twip)
YmaxSB[Nbits]=01000000010y座標の最大値(514twip)



STRING型



フィールド説明
StringUI8[0以上]SWF6以上ではUTF-8エンコードされている。
StringEndUI8 = 0x00null文字


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"と発音)ファイルの構造は以下の図式に示すような構造を持つ。

ヘッダーファイル属性タグタグタグ ……タグ終了タグ



ヘッダーの構成

フィールド説明
拡張子UI8C(=0x43)またはF(=0x46)。Cはバージョン6以上の圧縮されたSWFを表す。
拡張子UI8W(=0x57)。常に。
拡張子UI8S(=0x53)。常に。
バージョンUI8ASCIIキャラクターでなくUI8の数字が入る。バージョン6なら0x06。
ファイル長UI32ヘッダーを含めたファイルの大きさ(バイト単位)。
SWFの大きさRECTRECT型(後述)。SWFの大きさをtwip単位(1/20px)で表す。
フレームレートUI168.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)ということです。


タグ一覧

番号タグ名
0End
1ShowFrame
2DefineShape
4PlaceObject
5RemoveObject
6DefineBits
7DefineButton
8JPEGTables
9SetBackgroundColor
10DefineFont
11DefineText
12DoAction
13DefineFontInfo
14DefineSound
15StartSound
17DefineButtonSound
18SoundStreamHead
19SoundStreamBlock
20DefineBitsLossless
21DefineBitsJPEG2
22DefineShape2
23DefineButtonCxform
24Protect
26PlaceObject2
28RemoveObject2
32DefineShape3
33DefineText2
34DefineButton2
35DefineBitsJPEG3
36DefineBitsLossless2
37DefineEditText
39DefineSprite
43FrameLabel
45SoundStreamHead2
46DefineMorphShape
48DefineFont2
56ExportAssets
57ImportAssets
58EnableDebugger
59DoInitAction
60DefineVideoStream
61VideoFrame
62DefineFontInfo2
64EnableDebugger2
65ScriptLimits
66SetTabIndex
69FileAttributes
70PlaceObject3
71ImportAssets2
73DefineFontAlignZones
74CSMTextSettings
75DefineFont3
76SymbolClass
77Metadata
78DefineScalingGrid
82DoABC
83DefineShape4
84DefineMorphShape2
86DefineSceneAndFrameLabelData
87DefineBinaryData
88DefineFontName
89StartSound2


タグの種類

タグは定義タグコントロールタグの二つに分類されます。
定義タグはSWFファイル内のコンテンツ(シェイプ、テキスト、ビットマップ、音等)を定義するタグです。定義タグはそれぞれのコンテンツに対しユニークなcharacter IDと呼ばれるIDを振ります。Flash Playerはcharacterを辞書とよばれる領域に格納します。また、定義タグ自身は描画を引き起こしません。つまり、ただ定義するだけです。
コントロールタグは辞書内に保存されたcharacterのインスタンスを生成したり操作したり、ファイルの処理の流れをコントロールしたりします。


タグの順序についての注意

一般的にSWFファイル内においてタグの順序はどのような順序で合っても構いませんが、以下のルールがあります。

  • ファイル属性タグ(SWF8以降)は最初に来なければならない。
  • タグはそれ以前のタグにしか依存しない。つまり、それ以前に登場したタグ内での内容しか見えていないということです。
  • これは上にも通じますが、character Aを定義する定義タグはcharacter Aを参照しようとするどのコントロールタグよりも前に来なければならない。
  • サウンドのストリーミングは正しい順番で現れなければならない。
  • 終了タグは常にSWFの最後に来なければならない。


辞書

辞書とはcharacterを保存する倉庫のようなものであって、コントロールタグで使用することができる。辞書の構築と使い方は以下のような手順になる。

  1. 定義タグが、シェイプやフォント、ビットマップや音といったコンテンツを定義する。
  2. 定義タグはそのコンテンツに対しユニークなcharacter IDを割り振る。
  3. コンテンツはcharacter IDと一対一に辞書に保管される。
  4. コントロールタグはcharacter IDによってコンテンツを辞書から取り出し、例えば、シェイプを表示したり、音を再生したりといったふうに、何かしらのアクションを行う。

character IDはユニークであり、重複してはならない。典型的には1,2,3と順に番号を振って行く。0にはnull characterという特殊なcharacterとして認識される。
辞書によってcharacterを参照するのはコントロールタグだけではなく定義タグもさらにより複雑なコンテンツを定義するために既に辞書に登録されているcharacterを参照して使用することができる。例えば、DefineButtonやDefineSpriteといったコントロールタグ等がそうであり、DefineTextタグもテキストに異なるフォントを使うためにfontのcharacterを参照することができる。


要約

  • SWFファイルはヘッダーとそれに続く沢山のタグから構成される。
  • タグには2種類あり、それは定義タグとコントロールタグである。
  • 定義タグはオブジェクトをcharacterとして定義し辞書に保管する。
  • コントロールタグはcharacterを操作したり、ファイルの処理の流れをコントロールしたりする。