にせねこメモ

はてなダイアリーがUTF-8じゃないので移ってきました。

JPEGのヘッダからクロマサブサンプリングを調べる

JPEGはクロマサブサンプリングに対応しているわけだが、画像ビューアや画像編集ソフトで開いてもその辺りの情報が得られなかったりする。
なので、JPEGのバイナリを読んでクロマサブサンプリングがどうなっているか理解できる様にしたい。

JPEGに記録されたクロマサブサンプリング情報

まず、imagemagickでクロマサブサンプリングを次のように設定して書き出した。
そしてそれをバイナリエディタで開き、対応するSOF0タグ内の構成要素のサンプリング値を調べた。ここで、数字は16進数である。

設定 Y Cb Cr
4:4:4 11 11 11
4:4:0 12 11 11
4:2:2 21 11 11
4:2:0 22 11 11
4:1:1 41 11 11
4:1:0 42 11 11

Y, Cb, Crについて、上位4ビットが水平方向、下位4ビットが垂直方向のサンプリング値を示す。
要するに、4:4:4であればY, Cb, Crそれぞれの1x1のブロック同士が対応する。4:2:0であればYの2x2ブロックとCb, Crの1x1ブロックが対応する、などといったことだろう。


JPEGのバイナリを開いて、9E番地から始まるSOF0が

FF C0 00 11 08 02 D0 05 00 03 01 22 00 02 11 01 03 11 01

となっていれば、赤がチャンネル数(3=YCbCr)、太字が各チャンネルのサンプリング値であるので、ここからYCbCr 4:2:0だとわかる。

J:a:b表記について

ところで4:2:0みたいな表記をずっと分かりづらいなと思っていたのだが、次のような事情があるらしい。

これはもともとは水平方向のY:Cr:Cbのサブサンプリングの比率を表していて、垂直方向のサブサンプリングは考慮されていなかった。そのため、人間の目の空間的な解像度が、青/黄色の方が赤/緑より小さいのを利用して、4:2:1みたいなクロマサブサンプリングも存在しているらしい(今ではほとんど使われていない)。

この後、縦方向のサブサンプリングを考慮するようになり、縦方向の色成分の解像度を半分にする場合、表記として、三番目の数字に0を指定するようになった。現在のこの書き方をJ:a:b notationという。縦方向解像度を0で示すようにしたのは、おそらくそれまでの表記法との互換性を保つためだろう。縦方向にクロマサブサンプリングをしない場合に4:2:2や4:1:1と書くのも過去の表記との整合性を考慮してのことで、過去の表記法でも現在の表記法でも同じクロマサブサンプリングを示すことになる。