複天一流:どんな手を使ってでも問題解決を図るブログ

宮本武蔵の五輪書の教えに従い、どんな手を使ってでも問題解決を図るブログです(特に、科学、数学、工学の問題についてですが)

Imagemagickが使えなくなる....

Imagemagickのmontageが使えなくなる....

昨晩、久しぶりに天体観測を行った。メインターゲットは土星である。土星の環は約15年周期でその傾きが変化する(13年周期の場合もあるらしい)。2011年から撮りためてきた土星の観測写真をそろそろまとめてみようと思い、Imagemagickに付属するmontageコマンドで合成しようとしたとき、問題が発生した。

montage: no decode delegate for this image format `JPEG' @ error/constitute.c/ReadImage/509.
montage: unable to load module '/usr/local/Cellar/imagemagick/7.0.4-6/lib/ImageMagick//modules-Q16HDRI/coders/jpeg.la': file not found

JPEGを処理するライブラリjpeg.laが存在しないという。しかし、このコマンドは先月までちゃんと動いていた。もしかすると、この間インストールした新しいアプリが悪さをしたのではないか?ls -lコマンドでjpeg.laがあるかどうか確認すると、ちゃんと存在する。つまりこれは何らかのファイルリンクに関連した問題が発生しているということになる。

同様の問題はpngの処理でも発生した。ありとあらゆる画像処理用のライブラリが(Imagemagickからは)読めない状態になっているようだ。

gimpを使って当面の作業は切り抜けられるとしても、montageの高機能が使えないとなると、複天一流の「道具を残らず役に立てたきもの」という精神が著しく損なわれる。ここはなんとかして復旧させなければなるまい。

徹底的な「ググり」検索へ

いつものことだが、このような問題は先人が人柱となって必ず脱出方法をどこぞに書き残してくれているものである。さっそく「ググりサーチ」を開始した。キーワードはエラーメッセージそのものにした。

最初の情報

まずでてきたのがgithubでの議論板である。彼らはpngの処理で困っているらしい。macOSのアプリ管理システムであるHomebrewを使ったやり方について色々とやりとりが続いていた。私が利用しているのもmacOSなので期待が持てそうである。長い議論を読み進めていくと、使えそうな手段は議論の最後に書いてあったコマンドであった。

The following worked for me:

  > brew unlink libpng && brew link --overwrite libpng

この命令の意味を考えれば、やはりhomebrewシステムにおけるファイルリンクの掛け間違いを疑っていたようだ。期待してこのコマンドを打ってみた。

Unlinking /usr/local/Cellar/libpng/1.6.37... 18 symlinks removed.
Linking /usr/local/Cellar/libpng/1.6.37... 18 symlinks created.

同様にlibjpegに関してもやってみた。

> brew unlink libjpeg && brew link --overwrite libjpeg

Unlinking /usr/local/Cellar/jpeg/9d... 18 symlinks removed.
Linking /usr/local/Cellar/jpeg/9d... 18 symlinks created.

なんとなくうまくいきそうに見えた......が、残念ながら私の場合はうまくいかなかった。

unable to load module '/usr/local/Cellar/imagemagick/7.0.4-6/lib/ImageMagick//modules-Q16HDRI/coders/jpeg.la': file not found @ error/module.c/OpenModule/1279.

これは最初とまったく同じエラーメッセージである。ふりだしに戻ってしまった。

2つ目の情報

次に参考したのがこちらの文章である。WindowsバージョンのImagemagickの問題のようだが、症状はほぼ同じで「以前は使えていたのに突然使えなくなった」というものである。

They worked properly before, so I don't know what I have done that they stopped working.

この相談者は再インストールを試みるが、同じエラーメッセージが出てしまうという。つまり、再インストールするだけでは解決できなさそう、ということである。この文章の後半でもやはりファイルリンクの問題を解決した後、うまく作動するようになったとあるが、macOSを使っている私の場合、直接のヘルプにはならない。

日本語の情報

日本語の情報に目を向けてみることにした。「最新版がうまくいかないなら、バージョンを下げてみたらどうだろう」と思ったのがきっかけである。こんな文書が見つかった。

この人が使っているのはmacOSなので、ここで見つかった解決法ならば直接使えるはず!と期待が高まる。しかし、この文書が扱っていたのは「問題が全く生じない場合」であった。「最新版がhomebrewで一発インストールできた!」などと書いてあるため、あまり参考にならない可能性もある。「最新版のインストールがうまくいった」の部分は読み飛ばし、古いバージョン(Imagemagick ver.6)のインストール方法だけを参考にする。

brew install imagemagick@6
brew link --force imagemagick@6

とやると一発でうまくいくそうだが....私の場合は駄目であった。落胆である。

駄目でもともと作戦(再インストールを試す)

検索しても解決法が見つからず、行き詰まってしまった。こうなったら「駄目でもともと」作戦に出るほかはない。ということで、

brew reinstall imagemagick

を試すことにした。すると、予想外のエラーメッセージが出た。

brew reinstall imagemagick
==> Downloading https://homebrew.bintray.com/bottles/glib-2.66.4_1.mojave.bottle.1.tar.gz

curl: (51) SSL: no alternative certificate subject name matches target host name 'homebrew.bintray.com'
Error: Failed to download resource "glib"

curl: (60) SSL certificate problem: certificate has expired

ファイルをダウンロードする際の認証に使う証明書(SSL認証)らしきものが「古すぎて駄目」だという。Imagemagickのみならず、glibすらインストールできないとは....。これは一大事である。

確かに私が利用しているmacOSは古い。Mojaveなど今時誰がつかっているだろうか?といった感じである。しかし、このmacOSのバージョンが「自由にアプリをインストールできる最後のmacOS」なのである(Appleが導入したGatekeeperシステムについてはこちらの文書が詳しい。この文書によると、うまくやればなんとかGatekeeperを回避できる方法もあるらしいが、Mojaveに愛着がありすぎてなかなか新しいOSへのアップデートができていない)。なんとかして使い続けたいものである。

とはいえ、homebrewもMojaveユーザーにはいい加減愛想をつかしてしまったらしく、この後、しつこく「OSのバージョンを上げると解決できる可能性が高まります」というメッセージを見ることになった。

macOSをアップデートせずになんとかするしかない、となればHomebrewをアップデートするしかない。ということで、自分の判断でhomebrewのアップデートを試みることにしたのである。しかし、そこにはさらなる難関があったのである。

homebrewをアップデートする

Homebrew自体のアップデートのためのコマンドは

brew update

と、かつては非常に簡単であった。しかし、このコマンドは古びてしまったようで、今実行するとエラーになってしまうのである。代わりに次のコマンドを叩けと言ってきた。

To `brew update`, first run:
  git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
  git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow

These commands may take a few minutes to run due to the large size of the repositories. This restriction has been made on GitHub's request because updating shallow clones is an extremely expensive operation due to the tree layout and traffic of Homebrew/homebrew-core and Homebrew/homebrew-cask. We don't do this for you automatically to avoid repeatedly performing an expensive unshallow operation in CI systems (which should instead be fixed to not use shallow clones). Sorry for the inconvenience!

"shallow clone"というのがよくわからないが、インストールすべきアプリのデータベースのようなものであろうか。「GitHubからの要望でshallow cloneをあまり頻繁に作らせないように言われてしまった」と書いてある。shallow cloneというのは、どうもかなり長いファイルになるらしく、その生成にあたってGitHubのリソースがかなり喰われてしまうことが推察される。

ちなみに、Shallow cloneについて検索をかけてみたら、読んでもわけのわからない文書が出てきた。

github.blog

次の解説を読んだ後に、上の「わけのわからない」解説文を読んでみると、最初の時よりは少しだけわかるようになっていて驚いた。

tech-blog.rakus.co.jp

今現在自分にわかるところだけをかき集めて説明を試みてみる。結論からすると、だいたい予想通りだと感じる。つまり、複数のプログラム相関をもつアプリがあったとして、それをネットワーク経由でインストールする際に必要となる多数のライブラリやサブプログラムについての「関連性情報データ」(ファイル間の結合関係のデータベース)が存在し、このデータに基づいて必要なファイルやライブラリをかき集め「リポジトリ」と呼ばれるファイル群を自身のローカル環境に構築することを「クローン」と呼ぶらしい。もちろん、さっき読んだばかりなので誤解に基づく曲解が入っているとは思うが、「第0近似としては、まあいいのではないか」というところであろう。これはgitHubで採用されている技術らしいが、ネットワークプログラム技術としては有名なものらしい。クローンを構築してから、それを使ってインストールを行うわけである。そこには関連性を指示するデータベースもあるはずである。

「警告文」には「may take a few minuites」とあるが、実際にやってみると数時間かかってしまった。やはりリポジトリは年々複雑化長大化しているのであろう。

Homebrewのアップデートが終了

shallow cloneの作成途中のメッセージをみると、今までにインストールした全てのアプリのアップデートをやっているような感じである。たくさんのファイルをダウンロードし、展開し、コンパイルし、インストールを延々と行っている。mojaveに関しての「嫌なメッセージ」もたくさん出ている。

Warning: You are using macOS 10.14.

We (and Apple) do not provide support for this old version.It is expected behaviour that some formulae will fail to build in this old version.It is expected behaviour that Homebrew will be buggy and slow.Do not create any issues about this on Homebrew's GitHub repositories.Do not create any issues even if you think this message is unrelated.Any opened issues will be immediately closed without response.Do not ask for help from Homebrew or its maintainers on social media.You may ask for help in Homebrew's discussions but are unlikely to receive a response.Try to figure out the problem yourself and submit a fix as a pull request.We will review it but may or may not accept it.

「責任は取らないし解決法も提供しない。全てを自己責任、自己能力の許す範囲内でやってくれ」などとつれない言葉が続いている。

とはいえ、プロセスは色々な問題を回避しながら進んでいく。「もしかしたら最後までいけるのではないか?」と淡い期待が出てきた。

そうこうしているうちにlibpngのダウンロードの箇所に来た!緊張しながら見守っていると、なんとうまくダウンロードできたようである。

==> Fetching libpng
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-core/9debb24aaa764a45a351ad5e3f26381717dc0dc0/Formula/lib/libpng.rb
==> Downloading https://downloads.sourceforge.net/project/libpng/libpng16/1.6.40/libpng-1.6.40.tar.xz

....と思ったらぬか喜びであった。やはりcurlの認証のところでエラーが出てしまい、ダウンロードができないというメッセージが出てしまった。

curl: (60) SSL certificate problem: certificate has expired
More details here: https://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs).

ただ、このgitというコマンドは、失敗してもその部分に固執することなく次のターゲットへ作業を移す仕様になっていた。つまりエラーが出て止まってしまうということにはならなかったのである。どうやらlibpngが収められているsourceforge.netのファイルサーバーはよく落ちるらしく、「curlの認証の問題だ」とエラーメッセージにはあるものの、サーバー自体が動いていないが故のトラブルであることも度々あるらしいのである。きっとそういうことも考慮して、このgitコマンドは時間をおいてから再びダウンロードを試してみるというアルゴリズムが組み込まれているようである。

実際、この日、下のようなメッセージが何度となく繰り返されたので、根気強くlibpngをダウンロードしようと試みたのであろう。

Trying a mirror...
==> Downloading https://sourceforge.mirrorservice.org/l/li/libpng/libpng16/1.6.40/libpng-1.6.40.tar.xz
Warning: Transient problem: timeout Will retry in 1 seconds. 3 retries left.
Warning: Transient problem: timeout Will retry in 2 seconds. 2 retries left.
Warning: Transient problem: timeout Will retry in 4 seconds. 1 retries left.

curl: (6) Could not resolve host: sourceforge.mirrorservice.org
Error: libpng: Failed to download resource "libpng"

エラーメッセージを眺めていても解決できないものはできない。少し疲れたこともあって、この後、うたた寝してしまった。後で見返してみると、「macOSが古い」というエラーメッセージと「libpngがダウンロードできない」というエラーメッセージが無数に繰り返され、その合間にダウンロードできた他のアプリに関する作業が行われていた。そしてなぜかどこかで妥協点を見出したらしく、あるところでlibpngのダウンロードが放棄され、最終段階へと作業は入っていたのであった。

==> Upgrading 87 outdated packages:
libtiff 4.2.0 -> 4.6.0
libtool 2.4.6_2 -> 2.4.7
gmp 6.2.1 -> 6.3.0
.
.
.

homebrewで今までにインストールしたアプリのうち、87のアプリがバージョンアップされるのだという。しかし、libpngもImagemagickもこのリストには入っていなかった。どうやら諦めたようである。

するとおもむろに、ダウンロードしたファイルの展開が始まり、様々なファイルのmakeが始まったのである。これにかなりの時間を要したようにみえる。configure, make, make install, make test....すべてのアプリにこれが繰り返されていく。

そしてついに最後の段階を迎え、最初のgitコマンドが終了した。

==> No outdated dependents to upgrade!
==> Checking for dependents of upgraded formulae...
Disable this behaviour by setting HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> No broken dependents to reinstall!
Error: Cask 'adobe-reader' definition is invalid: invalid 'depends_on macos' value: unknown or unsupported macOS version: :mavericks

なにやらadobe-readerのところでエラーが発生しているようだが、もうこれは無視することにした。

続けて2つ目のgitコマンドを叩く(今度はcaskの方だが、やる内容は最初のgitコマンドとほぼ同じ)。ちなみに、homebrewのCaskパッケージというのは、macOSで使うGUIプログラムの集合のことである。コマンドライン系のアプリはHomebrewに含まれ、webブラウザなどのGUI系のアプリはHomebrew Caskに含まれている。

Imagemagickのインストールに再挑戦

さて、居眠りしている間に2つのgitコマンドはなんとなく終了した。うまくいったアプリはちゃんとアップグレードされている。しかし、libpngやImagemagickなど失敗したものはインストールすらされていなかった。

とはいえ、homebrewがアップグレードされ、新しいシステムに書き換えられたのは事実である。

そこで駄目でもともと、もう一度

brew install imagemagick

を試したのである。しかし、予想通り、結果は前と同じで失敗に終わった。ただ、失敗しているのがpython3.11のインストールであった。どうやらXcodeが古いのが原因らしい。XcodeはやたらにいじるとMojave自体のバランスが崩れてしまい、起動しなくなる恐れもある。Imagemagick ver.7は必要ではあるが、Python3.11のインストールをごり押ししてOS全体が動かなくなるのも怖いので、このやり方はここで諦めることにした。

では、古いバージョンのインストールならばどうであろうか?これなら古いpythonのまま動いてくれるのではないだろうか?当然新しいXcodeも必要ない。とはいえ、こちらもダメでもともと、という気分でコマンドを叩いてみた。

brew install imagemagick@6

なんと、今度は動いたのである!どんどん必要なファイルがダウンロードされていく。しばらく待っていると、ダウンロードは終了し、ファイルの展開、そしてコンパイルが始まった。そして次々にImagemagickが必要とするライブラリやアプリがインストールされていく。驚きであった。そして全てが終了した。

==> Summary
🍺  /usr/local/Cellar/imagemagick@6/6.9.12-98: 767 files, 22.7MB, built in 3 minutes 56 seconds
==> Running `brew cleanup imagemagick@6`...

この状態でconvertとかmontageとかコマンドを打ってみてもpathが通っておらず、起動できない。次のコマンドを叩いて、 関連するリンクを整える必要があったのを思い出す。

 brew link --force imagemagick@6

反応はなかったが、どうやらこれで古いバージョンのImagemagick ver.6がインストールできたようである。半信半疑ではあったが、コマンドを叩いてみた。

> montage -version

Version: ImageMagick 6.9.12-98 Q16 x86_64 18038 https://legacy.imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC Modules 
Delegates (built-in): bzlib fontconfig freetype jng jp2 jpeg lcms ltdl lzma png tiff webp xml zlib

やったー!古いバージョンではあるが、なんとかMojaveにImagemagickを復活させることに成功したのである。

最初の一枚

さっそく、直近3年間の土星観測の画像データを張り合わせてみた。

montage -tile 3x1 -geometry +1+1 -resize x500 saturn2021.jpg saturn2022.jpg saturn2023.jpg tmp.png

結果が下の図である。

2021-2023までの土星の観測写真:Imagemagickで合成

お辞儀していた土星の環が次第に細くなっていくのが、なんとなくわかるであろう。そして土星の本体がしだいに環から頭を出していく様子もわかると思う。環が完全に一直線になってしまうのは2年後だという。これは土星にとっての「春分秋分」のようなものでEquinoxと呼ばれるらしい。

ちなみに使用した望遠鏡はVixen A80Mfである。10年ほど前にamazon.comで購入した時は3.5万円ほどだったと思うが、今見ると5万円を超えている。インフレであると実感する。撮影したのはCanon EOS M、最初のミラーレス一眼である。こちらはレンズ無しの中古をソフマップで5万円ほどで購入した記憶がある。別売りのリモコン(数千円?)を買わないと手ぶれのため、まともな天体写真とはならないから要注意だ。

光学系はVixenの拡大筒を使った「拡大撮影」である。接眼レンズとデジカメのレンズを筒で繋いで焦点を合わせるやり方だ。撮影感度は3枚ともiso400。シャッター速度は環が傾いていた2021年のときは1/15秒と短めめにしたが、環が水平になって暗くなってきた今年は1/13秒に増やしてみた。切り抜きはgimpで行い、合成はImagemagickのmontageで行なった。

やはりImagemagickは必須のツール

やはりImagemagickは画像系処理にはどうしても欠かせない必須ツールであることを再認識した。もちろん、gimpでやれることもたくさんあるし、そちらの技も習熟すべきであるというのが複天一流の極意である。どんな手を使ってでも、みやすい天体観測の画像データを生成するべきなのである!