はじめに†
- Flash SWF バイナリ内の(非可逆圧縮)画像は JPEG 形式で格納される。
- SWF フォーマットの詳細はこちら > Flash/SWF/format, Flash/SWF/format/Jpeg
- JPEG を格納するフォーマットは4種類あり、以下のタグで区別する
- DefineBitsJPEG(6)(←公式にはDefineBits), DefineBitsJPEG2(21), DefineBitsJPEG3(35), DefineBitsJPEG4(90)
タグ別JPEG構造†
- DefineBitsJPEG は以下の2択
- JPEG のうち圧縮テーブル情報のセグメント(DQT,DHT)を、別タグ(JPEGTables)のブロックに分離する。
- 尚、JPEGTables は SWF ファイル内に1つしか置けないので、圧縮テーブル情報のセグメントを抜いた DefineBitsJPEG(2,3 も同様)は全て一つの JPEGTables を(共通で)参照する事になる。
- JPEG 形式をそのまま入れて、JPEGTables は空っぽ。(仕様的には微妙な使い方)
- JPEG のうち圧縮テーブル情報のセグメント(DQT,DHT)を、別タグ(JPEGTables)のブロックに分離する。
- DefineBitsJPEG2,3 は以下の二択。参考
- DefineBitsJPEG2,3 タグ内の、前半に圧縮テーブル情報を持ってきて、後半にそれ以外のセグメントを置き、各々 SOI EOI で囲む。
- この方法を取った場合、SOI, EOI マーカーが2つずつ含まれる、妙な JPEG に見え る。
- JPEG のうち圧縮テーブルのセグメントを、別タグ(JPEGTables)のブロックに入れて、それを参照する。(仕様的には微妙、DefineBitsJPEG を使うべきだけど透明度つきだと仕方ないか)
- この場合の SOI, EOI の扱いは未調査
- DefineBitsJPEG2,3 タグ内の、前半に圧縮テーブル情報を持ってきて、後半にそれ以外のセグメントを置き、各々 SOI EOI で囲む。
- DefineBitsJPEG4 の JPEG 構造は不明。恐らくは DefineBitsJPEG2,3 と同様と思われる。
付加的なデータ†
- DefineBitsJPEG3 は更に、alpha channel(透明度)データが後ろに付く。
- 透明度のデータを zlib 圧縮して埋めこまれる。
- マスクデータを指定してスプライト表示のように使う事が多い。(参考)
- DefineBitsJPEG4 は更に、スムージングフィルタ用の設定値が 2byte で付加される
- デブロッキングフィルタに渡すパラメータを 2byte で埋め込む
- それ以外は DefineBitsJPEG3 と同じと思われる
その他†
- 特殊に見える JPEG の説明はこちら。↓ (本家のサイトはアクセスできなくなっているので、cache 参考の事)
推測(歴史的経緯の)†
根拠は殆どないけど勝手に推理。(事実と又聞きと憶測が混ざってます)
- JPEG の圧縮テーブル部分は(ほぼ?)固定なので、それ用のタグを作って(複数の JPEG 画像が)共通で参照するようにすればデータ量減るよね。 > JPEGTable(圧縮テーブル) + DefineBitsJPEG(メタデータや圧縮された画像データ)
- どちらも JPEG フォーマットの一部なので、SOI, EOI でくくっておこう
- JPEGTable と DefineBitsJPEG を合成して1つのタグにしちゃっていいんじゃないか > DefineBitsJPEG2(圧縮テーブル+画像データ、情報量的には一般的な JPEG ファイルと同等)
- JPEGTable と DefineBitsJPEG はどちらも SOI, EOI でくくるので、それらを合成した DefineBitsJPEG2 は結果的に SOI, EOI が 2つずつになる。しかも一般的な JPEG ファイルは圧縮テーブルを真ん中らへんに配置するので、並びも異なる。(ので、そのままデータを取り出しても、ビューアで表示出来ない)
でも、Flash Player の実装系の中には JPEGTable の SOI,EOI と DefineBitsJPEG の SOI,EOI の両方がある前提で作られてるものが… (例えば、携帯のFlashプレイヤー)
しゃーない、JPEG フォーマットの頭に SOI,EOI を余分につけていいよ? でないと困るよね?- DefineBitsJPEG2 に JPEG 画像をそのまま入れられない?
- でも以前のフォーマットと違うよね。
- しゃーない、JPEG フォーマットの頭に EOI, SOI (SOI,EOI でない事に注意) を余分につければ、その後ろ、生 JPEG でいいよ?
って事?
調査のきっかけ†
- http://pc11.2ch.net/test/read.cgi/swf/1172599208/277-376
375 :Now_loading...774KB:2007/06/15(金) 02:45:13 ID:t9sozzWd >>345 >>374 JPEGを差し替えるだけならこんな感じ。 1)とりあえずベースとなるswfを作る。 2)DefineBitsJPEG2を探してJPEGデータを差し替える。 3)差し替えたDefineBitsJPEG2のRECORDHEADER内のLengthを書き換える。 4)SWF File HeaderのFileLengthを書き換える。 用語やフォーマットは flash_fileformat_specification.pdf を参照。
備考†
- SWFspec v8 以降、DefineBitsJPEG2,3(,4) は JPEG に限らず PNG や GIF のフォーマットを生のまま入れられる。
- DefineBitsLossless は独自画像フォーマットで、DefineBitsJPEG は JPEG ファイルをほぼそのままなので、DefineBitsJPEG2,3(,4) を選択したと思われる。
- タグ名については仕様を作った人も後悔してるらしいw
- http://blogs.adobe.com/penguinswf/2008/11/swf_and_flv_10_specs.html
revised DefineBitsJPEG2 and DefineBitsJPEG3 to mention how they can be used to store GIF and PNG data as well as JPEG (as can the new DefineBitsJPEG4 tag; yes, the tag names are a bit misleading, but they’re a bit too entrenched to be changed now)
- http://blogs.adobe.com/penguinswf/2008/11/swf_and_flv_10_specs.html
- JPEGTables はこれが元?↓
参考†
関連†
- JPEG フォーマット (JPEG)
- SWF Editor PHP extension (swfed)
- SWF フォーマット