2008年01月24日

swfmillでFlash Lite 1のswfを扱えるようにしてみた

はてなブックマークに登録

Flashに関連するオープンソースなツールのひとつに、swfmillがあります。swfmillは、swfファイルを解析してxmlファイルに変換したり、逆にxmlからswfファイルを生成することができるツールです。swfmillの使い方についてはいろいろなところで紹介されているので、ここではFlash Lite 1.xのswfファイルをswfmillで扱うときの問題点について紹介したいと思います。

日本語を含むFlash Lite 1.xのswfファイルをswfmill swf2xmlしてみたところ、"error : xmlEncodeEntitiesReentrant : input not UTF-8"というエラーメッセージがでて、xmlファイルの出力が途中で止まりました。この問題を調べてみたところ、以下のようなことがわかりました。

swf内の文字コード

FlashはVersion 6からUnicodeに対応しました。Unicode対応前と対応後でswfファイル内の文字エンコードが異なり、対応前はcp932(日本語の場合)、対応後はUTF-8になります。

そして、Flash LiteとFlashのバージョン間対応ですが、Flash Lite 1.xはFlash 4がベースになっており、Flash Lite 2.xはFlash 7がベースになっています。なので、Flash Lite 1.xで日本語swfの中の文字コードはcp932、Flash Lite 2.x以降のswf内文字コードはUTF-8となります。

swfmillとlibxml2

swfmillは、xmlの生成やパースにlibxml2を利用しています。そして、libxml2のDOM Document Treeでは、文字列は必ずUTF-8を利用することになっており、xmlの生成やパースの段階でエンコーディング変換を行うようになっています。

しかし、swfmillはswf内の文字列をそのままDOM Document Treeに格納しています。そのため、Flash Lite 1.xの日本語swfを読み込ませると、Document Tree内にcp932の文字列が入り込み、libxml2がxmlの生成に失敗してしまいます。

対策

swf内の文字列をDOM Document Treeに登録する際に、cp932からUTF-8への文字コード変換を行うように修正すると、問題なくFlash Lite 1.1のswfファイルを扱えるようになりました。また、XMLから文字列を読み込むときにUTF-8からcp932に変換すると、xml2swfで元の文字列がきちんと再現されたswfファイルが生成されました。

せっかくなので、コマンドラインオプションで"-e cp932"のようにswf内文字コードを指定できるようにしてswfmillのメーリングリストにパッチを送ってみたところ、今は次のリリースに向けた作業で忙しいけど後で時間のあるときにレビューするよと返事がありました。そのパッチをここにも載せておきますので、興味のある方はお試し下さい。上手く動かないの等問題があれば、フィードバックを頂けると幸いです。

swfmillのswf内テキストエンコーディング指定オプション追加パッチ

パッチ適用とビルドの仕方

swfmill-0.2.12のソースコードをダウンロード&展開

$ wget http://swfmill.org/releases/swfmill-0.2.12.tar.gz
$ tar xzf swfmill-0.2.12.tar.gz
$ cd swfmill-0.2.12

patchをダウンロードして適用

$ wget http://lab.klab.org/files/flash/encoding.patch
$ patch -p1 < encoding.patch

ビルドとインストール。適切なconfigureのprefixオプション等は
環境に合わせて適切に設定してください。

$ configure
$ make
$ make install
klab_gijutsu2 at 19:12│Comments(15)TrackBack(0)flash 

トラックバックURL

この記事へのコメント

1. Posted by わたなべ   2008年02月18日 01:05
5 ども。
トラックバックが弾かれちゃうので、コメントしてみました
2. Posted by nos   2008年08月12日 11:40
Windowsで、ビルドとインストールするにはどうしたらいいのでしょうか?
まだこの手のことに関しては初心者です。失礼ながら教えてもらえないでしょうか?
3. Posted by methane   2008年08月12日 20:39
>nos様
コメントありがとうございます。
swfmillは、zlib, libpng, libjpeg, libfreetype, libiconv, libxml2, libxsltと、多くのライブラリに依存しています。
これらのライブラリを一つ一つVisual C++でビルドして行くのは大変なので、Unix系と似た開発環境をMinGW+MSYSかCygwinで用意するのが近道になります。

こちらでも試しにCygwinでビルドして見たところ、上の方で渡辺さんが紹介されているようにiconv引数の修正が必要になりますが、割と簡単にビルドすることができました。
コンパイル済みのバイナリと、依存するcygwinのdllをまとめたものを置いておきます。(とりあえず実行できる事は確認していますが、動作に関してはまったく確認していません)
http://lab.klab.org/files/flash/swfmill_cygwin.zip
4. Posted by nos   2008年08月13日 21:38
5 ご返事ありがとうございます!
頂いたcygwinのdllを使用し、ビルドすることができました。swfmillもちゃんと動いています。
困っていたところだったので、本当に助かりました。ありがとうございました。
5. Posted by いおた   2009年09月25日 13:27
4 Solaris 10 でコンパイルしたら、
--
gSWFParseXML.cpp:31: error: invalid conversion from 'char**' to 'const char**'
gSWFParseXML.cpp:31: error: initializing argument 2 of 'size_t iconv(_iconv_info*, const char**, size_t*, char**, size_t*)'
--
となってエラーになってしまいました。

で、エラーになった箇所を下記のように修正して無事コンパイルできました。
--
const char **pin = (const char**)&from_str;
char *pout = dst;
bool expandbuf = false;

while (inbytesleft > 0) {
size_t r = iconv(cd, pin, &inbytesleft, &pout, &outbytesleft);
--
※修正したのは上記の1行目と最終行です。
※patchの中では、295〜300行目にあたります。
6. Posted by methane   2009年09月29日 19:36
いおたさん、報告ありがとうございます。
iconvって、引数が環境によって const char ** だったり char ** だったりするんですよね。
できれば統一してもらいたいものです。
7. Posted by bowwow   2009年12月15日 12:34
自分もこれにはまりました。

makeで以下のエラーがでましたが、いおたさんのコメントどおりの対応でできました

gSWFWriteXML.cpp:31: error: invalid conversion from 'char**' to 'const char**'
gSWFWriteXML.cpp:31: error: initializing argument 2 of 'size_t libiconv(void*, const char**, size_t*, char**, size_t*)'

8. Posted by sin   2010年01月25日 17:07
お世話になります。
こちらの以下バージョンのパッチなどありましたら、ご教示いただけますと幸いです。

swfmill 0.3.0


何卒、よろしくお願いいたします。
9. Posted by methane   2010年01月25日 18:13
>sinさん
コメントありがとうございます。
swfmill 0.3.0 がリリースされた後に、このパッチがメインラインに取り込まれました。
なので、 0.3.1 がリリースされるのを待つか、 Bazaar を使って
bzr export swfmill lp:swfmill
をしてソースコードを取得して下さい。
10. Posted by sin   2010年01月25日 18:50
ご返信ありがとうございます!

承知しました。
Bazaarを使って、取得してみたいと思います。
11. Posted by q   2010年03月28日 16:23
windowsでswfmillを使用しているのですが、
keypressイベントにswitch文で10パターンほど
getURLを記述しています。

そのうち、初めの4つのみ動く状態です。
ネット上にもkeypressが動かないような症状が
ちらほら見受けられるのですが、
これってパッチとかあるのでしょうか?
12. Posted by methane   2010年03月29日 19:18
>q さん
コメントありがとうございます。
知らない症状だったので検索して見たところ、ParaFlaに関する話題で同じ症状が報告されているのを見つけました。
paraflaを利用してボタンを作って実験して見たところ、paraflaがボタンタグ内のアクションを記述する部分の手前が冗長なために、swfmillから合成した時に1バイト位置がずれるようです。

なので、swf2xmlで作成したxmlの中から該当する <DefineButton2 を見つけ、その中で buttonSize="21" のようになっている部分の数字を一つ減らして buttonSize="20" と書き換えてから、swfに変換しなおすと良いと思います。
13. Posted by ももた   2010年04月12日 16:07
4 パッチ重宝してます。
最近気がついたのですが、埋め込みフォントで静止テキストを表示させるとき、全角スペースが入っていると以降の文字が抜け落ちる問題を発見しました。
「レベル 2Up」 と記述した演出文字が
「レベル 」
という感じです。

これはパッチなりで対策がとれるものなのでしょうか?
14. Posted by methane   2010年04月26日 20:41
ももたさん

コメントありがとうございます。
残念ながら、私はswfmillで埋め込みフォントを利用したことが無いので、その現象を見たことがありません。
swfmillのMLでも話題になった記憶が無いです。

可能でしたら、Lauhcnpadにバグ報告とテストデータをいただければ、時間がある時に調査してみます。
16. Posted by Mon   2010年08月30日 13:10
自分も気になりました

全角スペースの他に
半角文字と全角文字が1行に含まれるとそれ以降の文字が飛びますね

abcdefgテストhijk

abcdefg

一つのオブジェクト内ですべての文字が、半角または全角に統一されている場合は問題なくビルドされます。

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント