3.23 【「ちゃんと」読む】
センバツは25日かららしい。今年はどこを応援しようかな。
IconPartyは正式版間近でとくにいじるところもなく、Phutは原因不明の問題で行き詰まっているのでこちらもいじることがない。そこで、やろうやろうと思ってそのままになっていた、QT-QでPNGの透過色サポートをやってみることに。
いろいろいじっていたら、24bitのPNGに保存した場合に画像がおかしくなるという問題を発見。そういえば前(99.11.13)に、読み込みがうまくいかなかったということを書いたが、まさにそんな症状だ。今度こそpng_set_filler()でいけるのではないかと思ったが、これがまただめ。読み込みの時は自分で無理矢理データを補正するという方法で回避したが、書き込み前に補正しておいて書き込んだ後に元に戻す……なんていうことはあまりやりたくない。
ここはやはり、ちゃんとpng_set_filler()のことを調べてみるべきだろう。読み込みについてもひょっとしたら単なる勘違いなのかもしれないし。と、ドキュメントを読んでみたが、特に気になる記述はない。読み込みに関しては、あとでpng_read_update_info()を呼ぶ必要があることが書かれているが、保存についてはなにも書かれていない。まずは、手がかりがある読み込みからチェックかなぁ……。
読み込みルーチンを見ると、png_read_update_info()はちゃんと呼んである。が、ちょっと気掛かりなのは、png_set_filler()の前にも呼んでいたことだ。2回呼んでも問題ないような気もするが、チェックしてみるべきかな。と、あとの方だけ残して試してみると、あっさり成功。なんだ、そんな単純なことだったのか。ここはIconPartyでも同じことをしていたから、そこもあわせて修正と。
書き込みの方はなんの手がかりもないので、とりあえずデバッガで追ってみた。ソースファイル(pngtrans.c)によればpng_set_filler()を呼んだところで構造体のusr_channelsというメンバが書き換えられるはずだが、なぜか変わっていない。そこで、color_typeを見ると、「0」になっている。その前のpng_set_IHDR()で「2(=PNG_COLOR_TYPE_RGB)」になるんじゃないのか???
原因がさっぱりわからず、そのままデバッガでトレースしてみると、png_write_info()を呼んだところでcolor_typeが「2」に変わった。それだけではなく、他のメンバに関してもここで変更された。と、いうことは、このあとでpng_set_filler()を呼べばいいということなのかな? サンプルコード(example.c)を見てみると、まさにその通り。なるほど、そういうことだったのね。考えたらこんなこと、ドキュメントを「ちゃんと」読めば書いてありそうなことだな……。
今回のまとめ(笑)。png_read_update_info()は1回だけ呼ぶ。書き込みでは、png_write_info()のあとでpng_set_filler()を呼ぶ、と。
|