PostScript
目次
概要
PostScript は Adobe が策定した印刷のためのページ記述言語である。普通に考えれば、どこに何を描くかのデータを集めただけのファイル形式に過ぎないように思えるが、実は PostScript はれっきとしたプログラミング言語の一種である。 例えば次のような中身の PostScript ファイルを作って、印刷してみてほしい。
gsave /Helvetica findfont 100 scalefont setfont newpath 100 100 moveto (1+2=) show 1 2 add =string cvs show showpage grestore
これを印刷すると、「1+2=3]と書かれた紙が出てくるが、上のファイルの中には、どこにも「3」という文字は出てこない。 ちゃんと中で「1+2」を計算し、その結果を「1+2=」という文字列に続けて表示しているのだ。
この調子でプログラムを構築していけば、人手で描くのが大変な複雑な図形も作ることができる。ただし、上の例を見てわかる通り、 よく知られているプログラミング言語とはその形態がかなり異なる。実のところ PostScript で高度なプログラムを書くのは 非常にしんどいので、あくまでも「そういうことができる」ということを知っておくのみにとどめておいた方がよいかもしれない。
PostScript プリンタの仕組
PostScript ファイルは実はプログラムであった。ということは、PostScript 対応プリンタというのは、PostScript で書かれた プログラムを実行することができる、ということだ。PostScript 対応プリンタは内部で PostScript を実行するための CPU とメモリが搭載されていて、コンピュータから PostScript ファイルを受け取ると、それを解釈実行して、 その結果を印刷するのだ。
Ghostscript
では実際に試しにプログラムを作ってみよう、というときに、プログラムをいちいちプリンタに送っていると、紙とインクがもったいないし、 プログラムに間違いがあってもプリンタはまず教えてくれないので、どうにも効率が悪い。そこで、コンピュータ上で動作する PostScript 処理系(PostScript インタプリタと呼ばれる)を使おう。 古くから知られるオープンソースのインタプリタが、Ghostscript だ。 これを使うと、単に PostScript のプログラムを実行できるだけでなく、内部状態などを確認しながら対話的に使うことができるので、 プログラムを試しに組んだりデバッグするのに役立つ。次に紹介する PostScript プログラムも、Ghostscript で実行すれば 実際に印刷することなく、その結果を観賞することができる。
おもしろプログラム
難解な PostScript コンテスト
プログラミング言語あるところ必ずこういうコンテストがあるものだが、PostScript でもやっぱりあった。
基本的には「コードを見ても何をやるプログラムだか分かりにくい」プログラムであることを競うコンテストなのだけど、 その結果を如何に面白くするかも重要な要素になっているので、実に面白いコードが並んでいる。 中でも芸術部門で見事1位に選ばれた早川たかし氏の "Tiny_RayTracing.ps" は、PostScript でレイトレーシングを行うという凄まじいもの。 優勝作の "labyrinth.ps" ともども、コードを見ても一体なんでこれがプログラムとして成立しているのか理解できないくらいに難読化されているので、 参考にしたくともできない。(labyrinth.unobfs.ps は難読化されていないのでなんとか読める)
ペントミノの解法
電気通信大学の寺田実助教授が書いたpentomino.ps は、PostScript でペントミノパズルの全解答を 計算して表示する。昔の PostScript プリンタでは、全てを印刷し終わるまで 20日くらいかかる計算らしい。
ライフゲーム
セルラーオートマトンの傑作、John Horton Conway のライフゲーム (The game of life) を PostScript で書いたのがこちら。
間違っても印刷しようとしないように。
MD5 強衝突耐性を突く
ちょっと毛色が違うが、面白いので紹介。MD5 というハッシュアルゴリズムは 2004年になって強衝突耐性を突破するアルゴリズムが見付かってしまった。 つまり同じ MD5 ハッシュ値を持つ二つのデータを短時間で作ることができるようになった訳だ。ただし、あるデータと同じ MD5 ハッシュ値を持つ別のデータを 簡単に作れるようになった(弱衝突)訳ではないので、そう簡単に悪用することはできない。それでもうまく工夫することで強衝突耐性の弱点を 悪用することができる。その例がこれだ。
ここに掲載されている二つの PostScript 文書は同じ MD5 ハッシュ値を持つが、それぞれを印刷してみると違う内容が表示される。 この二つの文書、実は基本的には同じ内容なのだが、二つの文章が内包されていて、条件次第でどちらかの文章を表示するよう プログラムされている。プログラム冒頭には両者が同じ MD5 ハッシュ値になるようダミーデータが加えられており、そのダミーデータが、 どちらの文章を表示するかを決定しているのだ。
一見単なる文書に見えるが内部はプログラムであるという、PostScript の特徴をうまく利用した例だ。
PDF との関係
Adobe が PostScript の後継として策定したのが、PDF だ。では何故 PostScript ではなく PDF が必要だったのだろうか。 これには様々な理由がある。
一つには、PostScript が完全なプログラミング言語(チューリングマシン等価)であるところに問題があった。完全なプログラミング言語には「停止問題」がつきまとうのである。「停止問題」とは、そのプログラムが有限時間内に停止するかどうかを判定することができるかどうか、という問題で、完全なプログラミング言語で書かれたプログラムの場合、それが停止するかどうかを判定することができない場合があるのだ。つまり、ある PostScript プログラムを実行して、それが本当に有限時間内に計算を終了して結果を出力できるかどうかを自動判定することはできないのである。こうした性質を持つファイルを流通させるのは問題が大きい。PDF は、PostScript から反復命令などを取り除いてプログラミング言語としての完全性を失わせることで、この問題を解決している。
また、PostScript は基本的にベクトルグラフィックを指向して設計されている。もちろんビットマップ画像も扱えるのだが、PostScript ファイルの中に非圧縮で文字列化して埋め込む形で実現されるので、ファイルサイズが非常に大きくなってしまうという問題があった。それを解決するために PDF では、JPEG や PNG 画像を直接埋め込むことができるようになっている。
ちなみに、PDF のファイルを直接バイナリエディタなどで見ると、構文などは PostScript とほぼ同じであることがわかる。