dnjiro’s 9VAe blog

誰でもアニメが作れる無料ソフト9VAeきゅうべえ開発者のブログ

9VAeきゅうべえiPad版 64bitの問題を解決し、アニメGIF出力できるようになった。

9vaeきゅうべえ開発記録

今日は、アニメGIF出力を作ることにする。

 

アニメGIF作成のメインルーチンは備わっているので、要は、iOSで描画した画像をアニメGIF作成ルーチンに送る部分を作成すればよいはずであった。

 

64ビットの問題が発生

とりあえず、リンクしてから実行させて見ると、アニメGIFはできた。しかし、色が違うし、左右に同じ絵が2つできてる。これは、Linux版を64bitでビルドしたときに発生した現象で、アニメGIF出力が立体視みたいに左右2つ同じ絵ができてしまう。その時の結論は、アニメGIF出力ルーチンが32bitを前提にしたプログラムになっており、64ビットだとちゃんと動かない。ポインタを順番に動かしてデータを取得しているときに、本来32ビットずつ動くはずが、64ビットずつ動くので、2倍速く動いてしまい、結果として2つ絵が出るということが起こっているようだ。

 

iOSアプリ64bit版に対応する | admage blog ―技術者目線のアドテク知識発信ブログ―

 

アニメGIF出力は、とても複雑なので、そのまま動かしたい。ということで、16ビットのデータは、int16_t、uint16_t、32ビットのデータは、int32_t、uint32_t、と記述し直すことにする。

#include <stdint.h>

error: unknown type name ‘uint16_t’ · Issue #336 · antirez/redis · GitHub

 

そうして、画像取得の部分のポインタの書き方を変更すると、左右に2つの絵が出るのは無くなった。しかし絵が上下に反転。色もおかしい。これはカラーパレットの作成が怪しい。ポインタやシフト演算が多く使われている。

 

デバッグの方法

アニメGIF出力ルーチンは、高速化のためにポインタやビット演算が多用されている。64ビットになると、これらがみんな怪しくなる。一応、インクルードファイルの修正で簡単に変更できるデータは、int16_t などに変更したが、関数内部には、longとかshortとか、int といった記述が残っているので、どこかがおかしいのだろう。このデバッグは、次のようにした。

  • いくつかアニメGIF出力を行なって、どういう状態なのかを推測。まず、画面全体が1色だけだと正しく出力されるようだ。
  • ところが、2色になると、どちらかの色になってしまう。カラーパレットがおかしい可能性大。
  • 色以外はちゃんと動作してる。上下反転を除けば。

ここまで確認してから、iPad版と、Windows版の動作を同じデータを使って比較することにした。

  • 同じデータを、iPad版と、Windows版でアニメGIF出力し、バイナリーエディタで比較。ところどころ違いが見られたが、かなり正しく動作してるようだ。
  • 次に、両方のバージョンをデバッガで動作させ、途中の変数の値を比較しながら、違いを探した。

その結果、カラーテーブルの作成は正しいが、カラーテーブルの中から一番近い色を選ぶ処理に間違いを発見。

 

原因は、unsigned char の引き算 

  • 2つの色の距離の計算をするときに、unsigned char と、unsigned char の引き算を行なっていた。その結果を int に代入していたのだが、負の値がとても大きな値になっていた。今までのコンパイラーでは、計算途中で 勝手に int に変換され、ちゃんと計算できていたのだが、今回のコンパイラーでは、unsignedの引き算結果は、unsigned になるようだ。(int)にキャストしてから引き算しないといけない。そのため、近い色を正しく取得できず1色だけなら正しく表示されるということになっていたようだ。なるほど。これは、64ビットのせいではなかった。

これを修正した結果、以下のようにアニメGIFが作成できるようになった。上下が逆転してるが、これは、画像データの読み出し部分を反転させればクリアできそうだ。

 

f:id:dnjiro:20170915191227g:plain

9VAe iPad版で作成したアニメGIF。「てすと」という手書き文字が上下反転してる。RGBの色と半透明もちゃんと出力できてる。