ps2img

ps2img なる画像変換ツールを Cygwin 上で使ってみようとした記録。

ps2img は Encapsulated PoscScript(EPS)ファイルを GIF/PNG/BMP に 適宜拡大縮小しつつ変換するツールです。 (中略) LaTeXの記述をダイレクトに画像ファイルにする機能もあります。

必要なもの

  • Perl 5( 他のバージョン未検証)
  • ちゃんと設定されたghostscript
  • ちゃんと設定されたplatex(LaTeXを使う場合)
  • ちゃんと設定されたdvips(LaTeXを使う場合)
  • ppm, pnm を操作するライブラリ
    (ppmquant, pgmtoppm, pnmscale, ppmtogif, ppmtobmp, pnmtopng)

    (本家より抜粋)

cygwin ではどれもこれもがネットインストールできる。すばらしい。"ppm, pnm を操作するライブラリ" なるものは netpbm をインストールすればよろしい。

インストールとか

本家ページを見るよろし。簡単に言うと

ps2img と psimglib.pl (どっちも perl script) を落としてきて実行権限与えて適当なところへ起き ps2img にシンボリックリンクを張ってそれを実行する。なんでわざわざシンボリックリンクを張る仕様なのだろう。

    $ ln -s ps2img ps2gif      # ps を gif にするもの
    $ ln -s ps2img ps2png      # ps を png にするもの
    $ ln -s ps2img ps2bmp      # ps を bmp にするもの
    $ ln -s ps2img tex2gif     # TeX コマンドの実行結果を gif にするもの
    $ ln -s ps2img tex2png     # TeX コマンドの実行結果を png にするもの
    $ ln -s ps2img tex2bmp     # TeX コマンドの実行結果を bmp にするもの
    $ ln -s ps2img eqn2gif     # TeX の数式を gif にするもの
    $ ln -s ps2img eqn2png     # TeX の数式を png にするもの
    $ ln -s ps2img eqn2bmp     # 疲れた。

問題点

例えば次のコマンドを実行すると (test.eps は適当に用意)

    $ ps2gif -d test.eps test.gif

    ps2img: Debug mode
    Offset: (28,28)  Size: 552x694
    Output resolution: 552 x 694
    gs -sDEVICE=ppmraw -sOutputFile=/tmp/debug_ps2img.tmp2 -g552x694 -dNOPAUSE -dBATCH -q /tmp/debug_ps2img.tmp
    cat /tmp/debug_ps2img.tmp2| /usr/bin/ppmquant 256 2>/dev/null | /usr/bin/ppmtogif > test.gif
    ppmtogif: Error reading magic number from Netpbm image stream.  Most often, this means your input file is empty.
    size: 552x694

となる。だめじゃん。原因を究明すべくコマンドを分解。問題は ppmquant 。ppmquant は perl script で pnmquant を呼び出している。pnmquant も perl script で pnmcolormap や pnm なんとかを呼び出してppm (画像フォーマット) ファイルの減色をしている。 /tmp/debug_ps2img.tmp2 は ppm 形式になっている。 gif は 256 色までだからね。

    $ cat /tmp/debug_ps2img.tmp2 | /usr/bin/pnmscale 0.5| /usr/bin/ppmquant 256

    seek back to zero on input file failed. at /usr/local/bin/pnmquant line 246

これが悪玉。その前までのファイルはうまくできている。それを証拠に

    cygwin $ cat /tmp/debug_ps2img.tmp2 | /usr/bin/pnmscale 0.5 > test.ppm
    cygwin $ scp test.ppm debian:./
    debian $ /usr/bin/ppmquant 256 test > test2.ppm
    debian $ scp test2.ppm cygwin:./
    cygwin $ cat test2.ppm | /usr/bin/ppmtogif > test.gif

とやるとちゃんと絵が作れる。なんでやねん!(えせ関西弁)

seek back ... のエラーを吐いている箇所を見ると

    seek(STDIN, 0, $SEEK_SET) 
      or die("seek back to zero on input file failed.");

とあるのでどうやら、seek() がうまくいってないらしい。

    #!/usr/bin/perl

    open(PASSWD, "/etc/passwd") || die "die!\n" ;
    while($line=<PASSWD>) {
       if ($line=~/^SYSTEM:/) { print "$line---\n";}
    }
    seek(PASSWD,0,0) or die "die!!!!!!\n";
    while(<PASSWD>) {
       print if /^SYSTEM:/;
    }

という perl script を書いて(パクって)以下を実行すると

    $ ./hoge.pl < /etc/passwd

    SYSTEM:*: ...
    ---
    SYSTEM:*: ...

となってうまく seek されているが、

    #!/usr/bin/perl

    #open(PASSWD, "/etc/passwd") || die "die!\n" ;
    while($line=<STDIN>) {
       if ($line=~/^SYSTEM:/) { print "$line---\n";}
    }
    seek(STDIN,0,0) or die "die!!!!!!\n";
    while(<STDIN>) {
       print if /^SYSTEM:/;
    }

とやって以下を実行すると

    $ ./hoge.pl < /etc/passwd

    SYSTEM:*: ...
    ---
    die!!!!!!

が変じゃん!ということらしい。もうお手上げ。これは私の環境だけで起こる減少でしょうか?解決策を知っている方がいたらご教示ください m(__)m

"烏丸通的電算処 Perl:パイプを使ったときのseek()が上手くいかない"というのも発見したが…。

pngbmp では

    $ ps2png test.eps test.png

    sh: line 1:  1644 Broken pipe             cat /tmp/debug_ps2img.tmp2
    312 Segmentation fault (core dumped) | /usr/bin/pnmtopng >test.png

せぐめんてーしょんふぉーるとぉ! (png は減色する必要がないので ppmquant を通さない。)

    $ ps2bmp test.eps test.bmp

うまくいく!( bmp も減色する必要がないので ppmquant を通さない。)

蛇足

因みに http://sourceforge.net/project/showfiles.php?group_id=5128 から netpbm-1.6.tgz と netpbm-1.32.tgz を取ってきて cygwin 上で展開、コンパイル、インストールをしたが当然ながら変化なし。