あまつぶ

8.20 【PNGについてのこと】

 ドキュメントを読んで、PNGのことがおぼろげながらわかってきた感じ。

 まず、これまで何度か書いてきた使用可能なビット数のことについて。インデックスカラーでは1、2、4、8ビットが使用できる。これは予想通り。次にグレースケールは、1、2、4、8、16ビットが使用できる。16ビットグレースケールについては、おそらくQuickDrawでサポートされていないから気にしなくてもいいのかな……。それから、RGBそれぞれに8、16ビット割り当てたフォーマット(24ビットと48ビットになるのかな)、8、16ビットのグレースケール+αチャンネル、RGB+αチャンネルが使用できるそうな。ということは、とりあえず今サポートしているものだけ考えれば十分なのかな。

 次に、謎だったフィルタのこと。これは、圧縮前にデータをいじって圧縮効率を上げようというものらしい。一番単純な「None」は、単になにもせず、データをそのまま圧縮する。
 「Sub」は、ほぼ、1つ左のピクセルとの差をとる。フィルタはピクセルごとではなくてバイトごとに処理されるそうなので「ほぼ」。一番左のピクセルは左のピクセルが存在しないからそのまま使うと。左右の方向に同じ色が並んでいるような絵では圧縮効率が高そうな気がする。どうかな?
 「Up」は、1行上のピクセルとの差をとる。これについても一番上の行はそのまま使う。こちらは上下の方向に同じ色が並んでいると圧縮効率が高くなりそうだ。
 「Average」は、「Sub」と「Up」を組み合わせたようなフィルタで、左のピクセルと上のピクセルの平均との差をとる。左のピクセルの考え方は「Sub」と同じ。また、平均をとる時に小数点以下は切り捨てる。どういう場合に効果があるのかどうかちょっとわからないが、画像によってはこのフィルタを使うといい場合ってのもあるのかな。
 「Paeth」は単語の意味すらわからなかったが、なんでも人名らしい。Alan W.Paethっていう人が考えたんだそうな。これはちょっと複雑なので説明が大変だが、左、上のピクセルに加えて左上のピクセルも使う。それぞれを引数として、PaethPredictor()という関数を呼ぶ……わけだが、この関数をCで書くなら、

UInt8	PaethPredictor(UInt8 a, UInt8 b, UInt8 c)
{
	UInt16	p,pa,pb,pc;
	
	p=(UInt16)a+b-c;
	pa=abs(p-a);
	pb=abs(p-b);
	pc=abs(p-c);
	if (pa <= pb && pa <= pc) return a;
	else if (pb <= pc) return b;
	else return c;
}


こんな形(a、b、cはそれぞれ、左、上、左上のピクセルに対応、abs()は絶対値を求める関数。例えば#define abs(x) (x>0 ? x : -x)とか)。predictorってのは「預言者」って意味らしいけど、それはともかくとして、3つのデータa、b、cからa+b-cという値を求め、それに一番近いものを返すという関数だ。paとpbはpの値を代入して整理すればabs(b-c)、abs(a-c)となるからそれぞれbとcの差、aとcの差と同じこと。pcはabs(a+b-2c)だから、aとbの平均とcの差を2倍したものか(よけいなんだかわからんような気もしつつ)。
 もうひとつ「Adaptive」というフィルタがあったような気がするが、ドキュメントにはなかった。フィルタの中で一番「適応できる」ものを選んでくれるということかな? そうすると「Best」はなんなんだという話になるが、んー?

to August 18, 1999 ↑ to August index → to August 21, 1999