Mac で sng (PNGのマークアップ言語SNG用コンパイラ) をビルドする

sng とは http://sourceforge.net/projects/sng/ これのこと。試験用に補助チャンクをごにょごにょしてPNGファイルをつくる必要があってこれをつかうことにしたんだけど、なんかビルドがうまくいかなかったので忘れないようにメモっておく。

まず、 sng-1.0.5.tar.gz を展開して configure したら以下のように libpng がない、とか X color database (なんだそりゃ?) がないと怒られた。

$ cd sng-1.0.5/
$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
(中略)
checking for pow in -lm... yes
checking for png_get_io_ptr in -lpng... no
checking "for X color database"... configure: error:  isn't there.


オプションに以下を指定したら configure はうまくいった。

$ ./configure --with-png-inc=/usr/X11/include/libpng15/ --with-png-lib=/usr/X11/lib --with-rgbtxt=/usr/X11/share/X11/rgb.txt

でも make でこけたorz

$ make
make  all-am
gcc -DHAVE_CONFIG_H -D_GNU_SOURCE -I.     -g -O2 -I/usr/X11/include/libpng15 -MT sngc.o -MD -MP -MF .deps/sngc.Tpo -c -o sngc.o sngc.c
sngc.c: In function ‘collect_data’:
sngc.c:534: error: dereferencing pointer to incomplete type
sngc.c:534: error: dereferencing pointer to incomplete type
sngc.c:545: error: dereferencing pointer to incomplete type
sngc.c:545: error: dereferencing pointer to incomplete type
(以下略)


さんざん悩んだあげく、libpng 1.5.x が原因だとわかった。(png.h で定義されている構造体が変更されていて、メンバ変数にアクセスできない)

libpng 1.2.50 を使ったらうまくいった。なお Mac 用にビルドするには以下のようにする。

$ cd libpng-1.2.50/
$ cp scripts/makefile.darwin makefile
$ make


あらためて ./configure してみる。

$ cd sng-1.0.5/
$ ./configure --with-png=../libpng-1.2.50 --with-rgbtxt=/usr/X11/share/X11/rgb.txt

これで、make したら sng ができた!

$ make
make  all-am
gcc -DHAVE_CONFIG_H -I.     -g -O2 -I../libpng-1.2.50 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -DHAVE_CONFIG_H -I.     -g -O2 -I../libpng-1.2.50 -MT sngd.o -MD -MP -MF .deps/sngd.Tpo -c -o sngd.o sngd.c
mv -f .deps/sngd.Tpo .deps/sngd.Po
gcc  -g -O2 -I../libpng-1.2.50  -L../libpng-1.2.50 -o sng main.o sngc.o sngd.o  -lpng -lm -lz

$ ls sng
sng*


ちなみに、補助チャンクの tEXt (非圧縮のテキストを保持) はPNGの仕様上長さの制限がないのに、BUFSIZを超えたらfatalになるので困った。で、以下のように変更して再ビルドしたらうまくいった。でも、めちゃ長いテキストをつっこんでちゃんと動作するかは知らない。

$ diff -u sngc.c sngc.c.new 
--- sngc.c      2012-12-26 21:24:57.000000000 +0900
+++ sngc.c.new  2012-12-26 21:24:50.000000000 +0900
@@ -275,8 +275,10 @@
                break;
            else if (c == '\n' && !literal)
                fatal("runaway string");
+/*
            else if (tp >= token_buffer + sizeof(token_buffer) - 1)
                fatal("string token too long");
+*/
            else
            {
                if (literal)

あと、tEXt は keyword を変えてやれば複数書けるみたいだ。こんな感じ。

tEXt {
    keyword "key1";
    text "ABCD";
}
tEXt {
    keyword "key2";
    text "EFGH";
}


余談だけど X color database ってのは色名(white とか red みたいなやつ)とRGB値の対応表のことらしい。
こんな内容。

$ head /usr/X11/share/X11/rgb.txt
255 250 250             snow
248 248 255             ghost white
248 248 255             GhostWhite
245 245 245             white smoke
245 245 245             WhiteSmoke
220 220 220             gainsboro
255 250 240             floral white
255 250 240             FloralWhite
253 245 230             old lace
253 245 230             OldLace


参考にしたサイト