JPEG 2000もEmacs/Org-modeでちゃんと表示する

#はじめに

当初、JPEG 2000を使えばどんな超高解像度な画像もサクサク扱えるのをデモしたかったのですが、すみません、本年の記事は思いっきり企画倒れになってしました。タイトルに偽りは無いものの、道半ばの内容、と言いますか、むしろこれは「最新Emacsのセットアップログ」になっておりますが、どうかお付き合いください。

**(2014-12-26) myuheさんの温かいコメントにより、ビルドしなくても大丈夫だということがわかりました！「ImageMagick をシステムに入れる」と「ちゃんと表示できるかの確認」以降を読んでいただければ、JPEG 2000画像をEmacsとOrg-modeで使えます。ただし、インラインパッチを当てたい人はビルドが必要です。**

**(2017-10-30) JPEG 2000画像をバッファに出すだけならば，ビルド不要なのですが，スケールを変換して（例えば横幅を縮小指定して）表示するためには，やはり --with-imagemagick 付きのビルドが必要です．org-image-actual-width の定義を参照ください．**

# 最新Emacsをビルドする

まず始めに、最新のEmacsを入手します。今年の10月20日に、24.4がリリースされています。このバージョンに組み込まれている org-mode は 8.2.10 なので、こちらも最新版です。

今回は、JPEG 2000画像をバッファにレンダリングするのが目的です。どうやって実現するかといえば、何のことはない、ビルド時に[ImageMagick](http://www.imagemagick.org/)を組み込むだけです。ただし、実際にJPEG 2000をハンドリングしてくれるのは、[OpenJPEG](http://www.openjpeg.org/)になりますので注意が必要です。OpenJPEG は、JPEG 2000規格の参照ソフトウェアとして追加されていますので、安心してご使用ください（バグ等のレポート、ウェルカムです）。

## ダウンロード

最新版のソースコードは、ミーラーサイトからダウンロードできます。`emacs-24.4.tar.gz` をダウンロードします。

http://public.p-knowledge.co.jp/gnu-mirror/gnu/emacs/

## インラインパッチの入手（Mac向け）

Macユーザは、おなじみのインラインパッチも入手します。Gistに置いておきました。`emacs-24.4-inline.patch`としてダウンロードされたとします。

https://gist.github.com/takaxp/6a32218a148684e8b03f

## ImageMagick をシステムに入れる

### imagemagick のバージョンに関する留意点

Emacs26にチャレンジする人は，imagemagickのバージョンに注意です．imagemagick の最新バージョンは7系ですが，現状ではEmacsでは 6系のみを動作対象にしています．したがって，当面は，6系のインストールが必要です．Homebrewの場合は以下のようにします．

```text:
sudo brew install imagemagick@6 --with-openjpeg
```

ちなみに，

```zsh:
Warning: imagemagick@6: --with-jp2 was deprecated; using --with-openjpeg instead!
```

だそうです．

### Mac の場合

MacですとMacPortsやHomebrewを使用して導入できます。

```zsh:
sudo port install ImageMagick
```

念のため、openjpeg が入っているか確認します。

```zsh:
sudo port installed | grep openjpeg
```

`openjpeg @2.1.0_0 (active)` と表示されればOKです。

### Linux の場合

パッケージ管理システムで完結する場合は楽ですが、環境によっては ImageMagick のビルドも必要かもしれません。どちらにしても、まずはopenjpegをインストールします。2.0系が必要です。

```zsh:
sudo zypper in openjpeg2 openjpeg2-devel
```

パッケージ管理システムで済む場合は、

```zsh:
sudo zypper in imagemagick imagemagick-devel imagemagick-extra
```

として終わりです。上記の例は、OpenSUSE 13.2 の例で、`imagemagick-extra`を入れることで、convert コマンドが JPEG 2000 に対応するようになります。以下のコマンドで状況を確認できます。

```zsh:
convert -list format | grep JPEG
```

次のような表示があればOKです。

```text:
JP2* JP2       rw-   JPEG-2000 File Format Syntax (2.1.0)
```

自分でビルドする場合は、[公式サイト](http://www.imagemagick.org/script/download.php)からソースをダウンロードします。バージョンは、6.9.0です。

ImageMagickのビルドを最後まで通すために必要になったパッケージを記しておきます。ウィンドウシステムの違いで `libxfce4ui-devel`以外が必要になると思われます。

```zsh:
sudo zypper in libxfce4ui-devel libXpm-devel libjpeg8-devel libtiff-devel ncurses-devel
```

ImageMagick をビルドします。

```zsh:
cd ImageMagick-6.9.0-0
./configure
make -j1
sudo make install
```

`./configure` の出力に次のような内容が含まれていることを確認してください。

```
OpenJP2           --with-openjp2=yes		yes
  CFLAGS          = -I/usr/include/openjpeg-2.1 -I/usr/include/freetype2 -fopenmp -g -O2 -Wall -march=core2 -fexceptions -pthread -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16
  DELEGATES       = bzlib mpeg fontconfig freetype jng jpeg openjp2 pango png ps tiff x zlib
```

ふぅ、、、という感じ。


## 野良ビルド実施

### Mac の場合
パッチをあてて、ビルドします。以下はMacでの例なので、`--with-ns`が付いています。ImageMagickはデフォルトでONになります。`etc/NEWS`に書いてあるのですが、Mac向けでは24.4からImageMagickのサポートが正式になったようで、`pkg-config`が必要だと書いてあります。必要に応じてインストールしてください。

```zsh:
tar zxvf emacs-24.4.tar.gz
cd emacs-24.4
patch -p1 < ../emacs-24.4-inline.patch
./configure --with-ns --without-x
make bootstrap -j1
make install
```

簡単ですね。パッチを当てると、次のような出力があり、`nsterm.h`が修正されたり、`macim.m`が新しく生成されたりします。

```zsh:
patching file configure.ac
patching file lisp/term/common-win.el
patching file lisp/term/ns-win.el
patching file src/Makefile.in
patching file src/keyboard.c
patching file src/macim.m
patching file src/nsfns.m
patching file src/nsterm.h
patching file src/nsterm.m
patching file src/termhooks.h
```

`./configure`を発行した時の出力メッセージに注意して下さい。`imagemagick`が追加されていることが前提です。

```zsh:
Does Emacs use imagemagick?                             yes
```

ビルドが終わったアプリケーションは、`nextstep/Emacs.app` として保存されていますから、`/Applications`以下など、適当な場所に置きましょう。なお，ビルド後にも imagemagick が使える状態であるかを確認できます．

```text:
#+BEGIN_SRC emacs-lisp
system-configuration-features
#+END_SRC

#+RESULTS:
: JPEG RSVG IMAGEMAGICK NOTIFY ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS MODULES LCMS2
```

### Linux の場合

ImageMagickを組み込んでビルドします。gifは外します（まぁ、はずさなくても良いですけども、、、）。

```zsh:
tar zxvf emacs-24.4.tar.gz
cd emacs-24.4
./configure --without-gif
make -j1
sudo make install
```

openSUSE の場合は、`/usr/local/bin/emacs`としてインストールされます。

# ちゃんと表示できるかの確認

ImageMagickとOpenJPEGが組み込まれたことで、野良ビルドしたEmacsはJPEG 2000で圧縮された画像を表示できるようになっています。Emacsを起動して、JPEG 2000画像を訪れてみましょう。JPEG 2000画像なんて持っていない！という人は、[ここ](https://dl.dropboxusercontent.com/u/2440/emacs/lena_std.jp2)からみんな大好きレナさんをダウンロードしてください。もしくは、すでにOpenJPEGがシステムに入っていますので、自分でエンコードすることもできます。諸事情があるので詳細は割愛します。

うまくいかない時は、次を評価してみてください。`imagemagick`と戻らなければ、途中で何かセットアップがコケています。

```text:
#+BEGIN_SRC emacs-lisp
(image-type-from-file-name "~/Desktop/lena_std.jp2")
#+END_SRC

#+RESULTS:
: imagemagick
```

JPEG 2000以外にどんな画像が表示されるかは、`imagemagick-enabled-types`変数を参照するとわかります。org-mode 使いの人は、ソースブロックを評価すれば、さくっと確認できます。最近話題の[BPG Image format](http://bellard.org/bpg/)はダメですな。よく見るとPSDがあるので、フォトショップもいけます（した）。

```
#+BEGIN_SRC emacs-lisp
imagemagick-enabled-types
#+END_SRC

#+RESULTS:
| 3FR | ART | ARW | AVS | BMP | BMP2 | BMP3 | CAL | CALS | CMYK | CMYKA | CR2 | CRW | CUR | CUT | DCM | DCR | DCX | DDS | DJVU | DNG | DPX | EXR | FAX | FITS | GBR | GIF | GIF87 | GRB | HRZ | ICB | ICO | ICON | J2C | JNG | JP2 | JPC | JPEG | JPG | JPX | K25 | KDC | MIFF | MNG | MRW | MSL | MSVG | MTV | NEF | ORF | OTB | PBM | PCD | PCDS | PCL | PCT | PCX | PDB | PEF | PGM | PICT | PIX | PJPEG | PNG | PNG24 | PNG32 | PNG8 | PNM | PPM | PSD | PTIF | PWP | RAF | RAS | RBG | RGB | RGBA | RGBO | RLA | RLE | SCR | SCT | SFW | SGI | SR2 | SRF | SUN | SVG | SVGZ | TGA | TIFF | TIFF64 | TILE | TIM | TTF | UYVY | VDA | VICAR | VID | VIFF | VST | WBMP | WPG | X3F | XBM | XC | XCF | XPM | XV | XWD | YCbCr | YCbCrA | YUV |
```

# Orgバッファでも表示する

さて、以上でJPEG 2000画像をEmacsでちゃんと表示できるようになったわけですが、このままだとOrgバッファには表示されません。具体的には、`org-display-inline-images`を実行した時に、画像が展開されないのです。インライン画像として正しく展開されるようにするには、次の二つの設定が必要です（した）。

## image-file-name-extensions に値を追加する

```el:
(add-to-list 'image-file-name-extensions "jp2")
(add-to-list 'image-file-name-extensions "bmp")
(add-to-list 'image-file-name-extensions "psd")
```

これで、拡張子が`.jp2`のファイルが表示対象となります。ついでに`.bmp`や`.psd`も追加してみました。

## インライン画像の横幅を設定する

次に、インライン表示する時の画像幅を設定します。方法は2つありますが、必ずどちらかを施してください。そうしないと表示されません。

### 一律に指定する

`org-image-actual-width` を数値で設定すると、バッファ内の全ての画像は一律に同じ横幅に補正された表示されるようになります。

```el:
(setq org-image-actual-width 256)
```

でも、オススメはこのやり方ではなく次の方法です。

### 個別に指定する

アトリビュートを使用して、横幅を指定します。`#+ATTR_`で始まっていれば正規表現で勝手に解釈されますが、とりあえず`#+ATTR_HTML`を使いましょう。コロンの位置などフォーマットに気をつけてください。以下のようにすると、横幅100ピクセルでインライン表示されます。

```text:
#+ATTR_HTML: :width 100
```

もう一つ重要な設定。実は、上記のアトリビュート指定と同時に、やはり`org-image-actual-width`の設定が必要です。しかも、数値指定ではなくリスト型でないとだめです。以下のように設定すれば、アトリビュート指定がある時にはその値を優先し、無ければ`org-image-actual-width`の数値が使われます。

```el:
(setq org-image-actual-width '(256))
```

それから、若干のハマりポイントなのですが、`org-element-property`に正しく反応させないとアトリビュートが正しく解釈されないので、画像リンクの前にハイフン等が付いているとダメです（した）。

## 確認

これでめでたくorgバッファでもJPEG 2000画像がインライン表示されるようになります。Orgバッファで次のように画像へのリンク記載します。ちなみにリンク上で、`C-c C-o`すれば、別バッファにフルサイズの画像がレンダリングされます。

```text:
#+ATTR_HTML: :width 128
[[~/Desktop/lena_std.jp2]]

[[~/Desktop/lena_std.jp2]]

#+BEGIN_SRC emacs-lisp
(org-toggle-inline-images)
#+END_SRC
```

`org-toggle-inline-images`を評価します。上の例では、`org-toggle-inline-images`の行にカーソルを置いて、`C-c C-c`すればOKです。以下のように表示が切り替わると思います。大元の画像は、横幅が512ピクセルですから、アトリビュート指定で128ピクセルに、指定なし（デフォ値反映）で256ピクセルにリサイズされています。めでたし！（ところがJPEG 2000のメリットは何も使っていないっ！ひどい！）

（Macでの表示例）
![Screen Shot 2014-12-25 at 2.00.44 AM.png](https://qiita-image-store.s3.amazonaws.com/0/12232/ad4c01f2-a706-9409-dbb5-7b383131475a.png)

（Linuxでの表示例）
![Screen Shot 2014-12-25 at 4.12.57 AM.png](https://qiita-image-store.s3.amazonaws.com/0/12232/00e2b41e-e56d-1477-45e8-129a5aec0b79.png)


ちなみに、常にOrgバッファでインライン画像を展開しておくには、次のように設定しておけばOKです。

```cl:
(setq org-startup-with-inline-images t)
```

# まとめ

ImageMagickとOpenJPEGをEmacsに組み込むことで、バッファにJPEG 2000画像を表示できることについて述べました。JPEG 2000の機能面での良さを全く伝えることができませんでしたが、とにかくEmacsでも使える！ということを示せたので、良しにしたいと思います。

本来紹介したかった超高解像度画像からサクッと縮小画像を抜き出して表示するのを実現するには、`src/image.c`の`imagemagick_load_image`関数や、`lisp/image.el`の`create-image`関数を書きなおして、orgバッファで横幅を解釈する部分のインターフェイスも変えなければならぬという大規模工事が必要そうです。。。きっと、いつの日か。。。

（個人的には関東Emacsでの宿題を提出できたので、ちゃんと新年を迎えられそうです。）