SWF 内の JPEG のマーカー

上記では、ファイルからオープンした jpeg データの先頭に
[0xff, 0xd9, 0xff, 0xd8].pack(”C*”) の4Byteの文字列を付加していますが、
これは SWF File Format Specification にも記載されている接頭子(マーカー)になります


僕の知る限りでは、

  • JPEG フォーマットは先頭に SOI(Start of Image = FFD8)、末尾に EOI(End of Image = FFD9)のマーカーがつく (前提知識)
  • SWF は元々、JPEG ファイル中の圧縮用テーブルだけ JPEGTables に分離して、画像毎のメタデータや画像データを DefineBitsJPEG に置いていた。多分、容量節約の為。
  • JPEGTables も DefineBitsJPEG も JPEGのデータを SOI と EOI でくくる
  • でも、現在主流の DefineBitsJPEG2 は、JPEGTables と DefineBitsJPEG のデータを連結したデータ構造を持つ
  • 結果的に DefineBitsJPEG2 は SOI とEOI が2つずつあり、かつ、通常の JPEG ファイルとセグメントの並びが異なった JPEG データを持つ
  • なので、DefineBitsJPEG2 から抜き出したJPEGデータは、そのままだとビューアで表示できない
  • JPEG データをそのまま DefineBitsJPEG2 の中に差し挟んでも、携帯だと表示できなかったりする
  • この辺の話のまとめ) http://pwiki.awm.jp/~yoya/?Flash/JPEG


という事情がありまして、頭に EOI, SOI(順番逆だし)をつければ良い訳ないじゃん。
頭に SOI, EOI をつければ携帯flashでも表示できていたけど、たまたまだよね!

と思って、早速、仕様をチェックしました。

The data in this tag begins with the JPEG SOI marker 0xFF, 0xD8 and
ends with the EOI marker 0xFF, 0xD9.
Before version 8 of the SWF file format, SWF files could contain an
erroneous header of 0xFF, 0xD9, 0xFF, 0xD8 before the JPEG SOI marker.

うぁぁ… (´Д`;)

SWF v8 からですが、仕様に確かに明記されてます…

↑これでは、JPEG セグメント並び変えを真面目にやってるのですが、
それをサボるモードを作ってみようかしら。
JPEG をセグメント分割するにはバイト単位で scan する必要があるので、
結構重たいんです。

SWF内のJPEG構造が変な理由を推測

DefineBit2JPEG2のJPEG完取り込みパターンはなぜこんな仕様かー。

との声がありましたので、自分なりに推測してみました。

事実と又聞きと憶測が入り混じってます。

…といいますか、事情知ってる人いたら教えてw