カラー/マルチ X-Face について
                                            山岡克美 <yamaoka@jpl.org>

1. はじめに

  カラー X-Face や 48x48 より大きい X-Face を送受信または表示するため
  の仕様について説明します。これはまだ世の中で認知されたものではありま
  せん。他人に迷惑をかけなければ何をやっても良い :-p、という基本理念に
  基いて勝手にデッチ上げた規格であることをお断わりしておきます。

  ;;; とは言うものの、巨大な X-Face が付いたメールを送り付けられた人は
  ;;; やっぱり迷惑だろうなぁ。(^^;;)

2. きっかけ

  そもそもこんなことを始めようとした発端は、市川さんがある日の tm-ja
  メーリングリストでおっしゃった「カラーにできないか?」 という問題が頭
  の隅でくすぶっていた矢先、XEmacs の Gnus で読んでいた xemace-beta メー
  リングリストで X-Face が２つ付いたメッセージを発見したことでした。
  いつからか Gnus はヘッダに存在するすべての X-Face フィールドをデコー
  ドして、全部を横に並べて From フィールドに表示するようになっていたの
  です。

  ;;; 後でわかったことですが XEmacs 付属の highlight-headers.el では
  ;;; 以前から全部を表示するようになっていたようです。Gnus とは並べる
  ;;; 左右の順序が逆なのですが、これが苦労の種になるとは...。

  それまで X-Gif-Face などとたわけたことを考えていたのですが、ヘッダに
  複数の X-Face フィールドを付けてしまえばカラーやマルチが実現できるこ
  とに、昔々カラーテレビを設計していて赤と緑を重ねると黄色になることを
  知っていた山岡は気がついてしまったのでした。しかも逆にカラーの画像を
  赤緑青の３原色に分解したり合成するプログラムが netpbm パッケージに含
  まれていることも知っていたので、早速自分の顔写真で試してみたのです。
  できあがったものはお世辞にもきれいな絵ではありませんでしたが、赤緑青
  ３枚の２値画像を合成して得られるたった８色のカラー画像でも、肌色の雰
  囲気が再現できることがわかりました。そして、このように赤緑青に分解し
  た３つの X-Face が付いたメッセージを普通に highlight-headers や Gnus
  で表示しても、まったくわけがわからない絵が表示されてしまうわけではな
  いことも確認できました。よし、それならやってみよう。

3. compface/uncompface

  X-Face のエンコード/デコードに使う compface/uncompface のプログラム
  は対象が 48x48 サイズの２値画像に限られていますが、その圧縮率の高さ
  において右に出るものがありません。それに広く普及している X-Face とは
  別のフォーマットを作っても、相手にしてくれる人が少なくて寂しい思いを
  することは明白ですから、これはそのまま使うことにします。そしてヘッダ
  のフィールド名も X-Face のままです。

  ;;; 余談ですが、XEmacs には uncompface の機能が盛り込まれていて、普
  ;;; 通のモノクロの X-Face をデコードしていきなりイメージを表示できる
  ;;; ことは便利なのですが、せっかく libcompface.a をリンクしているの
  ;;; ですから、デコードした結果のビットマップを elisp のプログラムで
  ;;; 取得したり、逆にビットマップから X-Face にエンコードする機能も提
  ;;; 供してもらえるとうれしいのですがねぇ。

4. カラー/マルチ X-Face

  マルチ X-Face とは、サイズが 48x48 の普通の X-Face を複数個組み合わ
  せて一枚の絵にするもので、カラー X-Face もその一種です。

  さて、互いに無関係な複数の、それぞれのサイズが 48x48 の絵をエンコー
  ドしてヘッダに挿入した場合、それらをデコードして表示する場合の順序や
  配置はさほど問題になりません。しかし、もっと大きな絵を複数の X-Face
  に分割したりカラーの絵を２値の三原色に分解して伝送する場合には、それ
  ぞれをデコードした後でつなぎあわせたり合成するときの順序や配置に関す
  る情報を一緒に伝送する必要があります。そのため

  X-Face-Type:

  というフィールドを創設しました。この右側には ";" で区切って ascii 文
  字で複数の情報を並べることができ、並べる順序の決まりや大文字/小文字
  の区別はありません。現在以下の二つが予約されています。

  geometry=MxN
    M と N はそれぞれ M=横幅÷48, N=高さ÷48 で求められる自然数で、こ
    れによって表示するときのサイズを表します。

  RGB
    ２値の三原色に分解したカラー X-Face であることを示します。当然なが
    ら３の自然数倍の個数の X-Face フィールドがヘッダに含まれていなけれ
    ばなりません。これには必ず geometry の指定が伴っている必要があり、
    カラーイメージとして表示するときのサイズを表します。

  ;;; 他にプログラムの開発段階を表す status という要素を一時使ったこと
  ;;; がありますが、これはあえて予約語にはしないことにします。

  互いに無関係な複数または単一の X-Face フィールドをヘッダに挿入すると
  きは X-Face-Type フィールドを付ける必要はありません。これが必要なの
  は 48x48 より大きいものやカラー X-Face を伝送する場合で、必ず X-Face
  フィールドより前に挿入します。続く複数の X-Face フィールドは、以下の
  ような順序で並べます。これらの組合せ (例えば 2x1 のカラーと 1x3 のモ
  ノクロ X-Face、都合 9個の X-Face フィールドをヘッダに挿入する) も可
  です。

  X-Face-Type: geometry=3x1
  X-Face: (1)                   +---+---+---+
  X-Face: (2)                   | 1 | 2 | 3 |
  X-Face: (3)                   +---+---+---+

                                +---+
  X-Face-Type: geometry=1x3     | 1 |
  X-Face: (1)                   +---+
  X-Face: (2)                   | 2 |
  X-Face: (3)                   +---+
                                | 3 |
                                +---+

  X-Face-Type: geometry=3x2
  X-Face: (1)                   +---+---+---+
  X-Face: (2)                   | 1 | 2 | 3 |
  X-Face: (3)                   +---+---+---+
  X-Face: (4)                   | 4 | 5 | 6 |
  X-Face: (5)                   +---+---+---+
  X-Face: (6)


  X-Face-Type: RGB; geometry=1x1    +---+
  X-Face: (1 Red)                   | 1 |
  X-Face: (1 Green)                 +---+
  X-Face: (1 Blue)


  X-Face-Type: RGB; geometry=2x1
  X-Face: (1 Red)
  X-Face: (2 Red)                 +---+---+
  X-Face: (1 Green)               | 1 | 2 |
  X-Face: (2 Green)               +---+---+
  X-Face: (1 Blue)
  X-Face: (2 Blue)


  X-Face-Type: RGB; geometry=1x2
  X-Face: (1 Red)                   +---+
  X-Face: (2 Red)                   | 1 |
  X-Face: (1 Green)                 +---+
  X-Face: (2 Green)                 | 2 |
  X-Face: (1 Blue)                  +---+
  X-Face: (2 Blue)


  X-Face-Type: RGB; geometry=2x2
  X-Face: (1 Red)
  X-Face: (2 Red)
  X-Face: (3 Red)                 +---+---+
  X-Face: (4 Red)                 | 1 | 2 |
  X-Face: (1 Green)               +---+---+
  X-Face: (2 Green)               | 3 | 4 |
  X-Face: (3 Green)               +---+---+
  X-Face: (4 Green)
  X-Face: (1 Blue)
  X-Face: (2 Blue)
  X-Face: (3 Blue)
  X-Face: (4 Blue)

  これらの並びの順序は重要で、途中に別のフィールドが紛れ込むのは構いま
  せんが、 X-Face や X-Face-Type の順序が変わってしまうと元の絵を再現
  することができません。現在までのところ順序を入れ替えてしまう MUA/MTA
  に遭遇したことはありませんが、フィールドの並び順 (特に X- で始まるも
  の) に関する決まりは無いので、不幸にして壊れてしまったら諦めるしかあ
  りません。(;_;)

  x-face.el を使うと X-Face-Type フィールドも含めてこれらのヘッダを自
  動的に作成することができます。
