LoginSignup
3
3

More than 5 years have passed since last update.

ofxTurboJpegをiOSデバイスで使う際の注意

Last updated at Posted at 2017-04-11

ofxTurboJpegをiOSデバイスで使おうとしたところ、いろんなエラーに悩まされた末に解決した記録。

環境

  • macOS Sierra 10.12.2
  • iPhone 6
  • iOS 9.3.1
  • Xcode 8.2.1
  • openFrameworks 0.9.8(8c7ddba)
  • ofxTurboJpeg(a0b432f)

最短手順

  • ここからlibjpeg.alibturbojpeg.aをDLしてofxTurboJpeg/libs/turbo-jpeg/lib/ios/に上書きコピー
  • Build SettingsOther Linker Flagslibjpeg.aの行を$(OF_CORE_LIBS)より上に移動させる

試行錯誤の記録(再現手順)

ここから下は暇な人だけ読んで下さい

何かしらofxTurboJpegを使うコードを書いてビルドするとarm64用のシンボルが見つかりませんよ、とのリンクエラーが出る。
でない人はシミュレーターなりiPhoneなりのアーキテクチャがarmv7とかなんだと思います。

Undefined symbols for architecture arm64:
  "_tjDestroy", referenced from:
      ofxTurboJpeg::~ofxTurboJpeg() in ofxTurboJpeg.o
  "_tjInitCompress", referenced from:
      ofxTurboJpeg::ofxTurboJpeg() in ofxTurboJpeg.o
  "_tjInitDecompress", referenced from:
      ofxTurboJpeg::ofxTurboJpeg() in ofxTurboJpeg.o
  "_tjGetErrorStr", referenced from:
      ofxTurboJpeg::ofxTurboJpeg() in ofxTurboJpeg.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

ここにarm64版をいれてビルドしてくれてる人がいるのでDLして上書きコピーする。
すると、実行はできるものの、下記エラーを見ることになる。

[ error ] ofxTurboJpeg: Error in tjInitCompress():Wrong JPEG library version: library is 90, caller expects 62
[ error ] ofxTurboJpeg: Error in tjInitDeCompress():Wrong JPEG library version: library is 90, caller expects 62

ここで、エラーメッセージの通りにJPEG libraryのバージョンを合わせに行ったのが間違いだった。
長い旅の始まり。

いろいろ調べたところ、oF098のFreeImageが使っているlibjpegのバージョンが90(9a)で、libturbojpegが使っているlibjpegのバージョンが62(6b)ということらしい。

まずはlibturbojpegの方でlibjpeg9aを使えないか調べたところ、公式が否定していた。

libturbojpegのビルド時に--with-jpeg8オプションをつけるとlibjpeg80(8d)を"Emulate"したものが書き出せるという情報があったのでやってみた。
ソースをここからDLしてビルド。
ビルド自体はここの手順ほぼそのままでいけました。
シェルが${IOS_SYSROOT[0]}を展開してくれなくてそこだけ書き換えましたが。

書き出されたlibjpeg.alibtuebojpeg.aofxTurboJpeg/libs/turbo-jpeg/lib/ios以下にコピーして実行すると、下記エラーが出る。これは思惑通り。

[ error ] ofxTurboJpeg: Error in tjInitCompress():Wrong JPEG library version: library is 90, caller expects 80
[ error ] ofxTurboJpeg: Error in tjInitDeCompress():Wrong JPEG library version: library is 90, caller expects 80

そして、FreeImageをlibjpeg80を使ったものに差し替えればいけるはず、と踏んでいました。
FreeImageのChanges Logを読むと、Ver.3.16.0以降でlibjpeg9aを使っているようなのでそれより前のソースかビルド済みバイナリを探すことに。

まずはoFの過去バージョンから探す。
コミットログを辿るとoF080でFreeImage3.15.3を使っているようなのでそれをDLしてoF/libs/FreeImage以下に上書き。
すると下記エラーに遭遇する。
ここでエラーに遭遇しない人は、ソースにofImage i;と書くだけで見えるようになります。
もしこれじゃなくて50個超えのリンクエラーをみた人はBuild SettingsBuild Active Architecture OnlyYesに設定すると見えるようになります。

Undefined symbols for architecture arm64:
  "_FreeImage_Initialise", referenced from:
      ofInitFreeImage(bool) in libofxiOS_iphoneos_Debug.a(ofImage.o)
  "_FreeImage_DeInitialise", referenced from:
      ofInitFreeImage(bool) in libofxiOS_iphoneos_Debug.a(ofImage.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

エラーを素直に読んで、arm64版のFreeImageを探すか作るかします。
ここからソースをDL。
含まれるMakefile.iphoneはarmv6用の設定ファイルなので、自力で書き換えるかこれをDLしてbuild_ios.shを叩く。
ビルドエラーが出るのでSource/LibRawLite/internal/dcraw_common.cppの9158行目を以下に変更して再度ビルド("dcraw v"DCRAW_VERSOINの間にスペースを追加)。
strcpy (th->soft, "dcraw v" DCRAW_VERSION);

出来上がったlibfreeimage.aFreeImage.hoF/libs/FreeImage以下にコピー。

実行できるようになるが下記エラーが出る。

[ error ] ofxTurboJpeg: Error in tjInitCompress():JPEG parameter struct mismatch: library thinks size is 568, caller expects 584
[ error ] ofxTurboJpeg: Error in tjInitDeCompress():JPEG parameter struct mismatch: library thinks size is 624, caller expects 656

バージョンは同じはずなのになんでだ・・・?!としばらく悩んだ末に、

libturbojpegのビルド時に作られるlibjpeg.aはピュアなlibjpegではなく、libjpegと同じインターフェースを持った別物なのだ

ということに気づく。恥ずかしながらいままで知らなかった。
--with-jpeg8云々の説明にEmulateと書いてあったことの意味がここで氷解。
そしてここで起こっている問題の根本は

libturbojpegが参照するlibjpegが、turbo用にカスタマイズされたものではなくて通常の(FreeImageに含まれる)libjpegになってしまっていること

であるのだ!ということに気づく。

じゃあ、なぜそうなるのかっていうとリンク順ですよね、ということで冒頭に書いた通りにリンク順を変えて解決。
いろいろ勉強になりました。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3