DHT (0xFFC4) ハフマンテーブル定義 Back
DHTはJPEGファイルのハフマン圧縮、復元時に使用するデータが記録されています。

DHTはひとつのセグメントで複数のハフマンテーブルを定義出来ます。
テーブルは可変長でテーブル番号が4種類(0〜3)、テーブルクラス(DCとAC)が2種類、計8種類あります。

SOSセグメントで参照され、該当のテーブルが無ければ画像は表示出来ません。

・ベースライン形式ではHT2とHT3は使用しません。
・ロスレス形式ではAC成分のハフマンテーブルは使用しません。

解析例

DHT :Define Huffman Table 【汎用ハフマンテーブル】
 000000B1 HT0-DC 汎用輝度HT-DC
 000000CE HT0-AC 汎用輝度HT-AC
 00000181 HT1-DC 汎用色差HT-DC
 0000019E HT1-AC 汎用色差HT-AC


1行目にはDHTの項目表示、セグメントデータが登録されていれば【括弧】内に内容を表示します。
2行目以降は1テーブル1行でテーブルの開始位置、ハフマンテーブルの種類、ハフマンテーブルのCRC値またはハフマンテーブル名が表示されます。

テーブル名は
JpegTBL.iniに登録されれいるものが表示されます。
DHTは余り種類は多くなく、汎用のものとアドビ社のオリジナルテーブル(各成分4〜5種類)のみ区別出来ます。
それ以外はほとんどの場合、最適化されたテーブルです。

DHTの構造

図の下の16進数値は テーブルがひとつだけ、DC成分HT0のDHT例
名称 サイズ 内容
Lh 2バイト セグメント長
以降はテーブル毎にあります
Tcn 4ビット(上位) ハフマンテーブルクラス 0=DC成分 1=AC成分
Thn 4ビット(下位) ハフマンテーブル番号 0から3までのいずれか
L1〜L16 16バイト ハフマンテーフルビット配分数
V1-n〜V16-n L1〜L16の合計x1バイト ハフマンテーブル定義データ
DC成分 データービット数
AC成分 上位4bit ランレングス数
    下位4bit データービット数

補足説明

難解なので補足しておきます。興味なければ読み飛ばして下さい。
※以降、ダブルクォーテションマークで囲っている数値は2進表現です。


L1〜L16のLの後の数はハフマンコードのビット数を表しています。
上の図の16進値の例では1bitのコードが0個、2bitのコードが1個、3bitのコードが5個、16bitのコードがn個になっています。

続くVのデータは1バイトが1つのハフマンコードに割り当たっており、L1からL16までを足した数がそのテーブルで定義されたハフマンコード数、Vのバイト数となります。

ハフマンコードのコードパターンは指定出来ず、ビットの少ない順から割り当てて行きます。
16進値の例からハフマンコードを割り当てていくと下記の通りになります。

1bitのコードは有りませんのでパスします。
2bitのコードは1個ですから、2bitの"00"を割り当てます。
3bitのコードは5個です。
この場合上の2bitの次のコード"01"に1bitの"0"を付け足して"010"から始めます。

この繰り上がり時のルールは、先頭ビットから一致するハフマンコードが無いか調べる事になるので、"001"などとしてしまうと、2bitの"00"か3bitの"001"か判らなくなってしまうからです。

結果、3bitのコードは"010","011","100","101","110"の5個を割り当てます。

同様に最後まで割り当てて行き、テーブルを完成させます。

コード解読時は、一致するハフマンコードのVの値を出します。
DC成分ならVで指定するビット数のデータを数値に変換します。
AC成分ならVの上位ビット、ランの数だけ値0のバイトを用意し、Vの下位ビット、データビット数だけデータを読み取り値に変換します。

次にDC成分のVの値、データビットの数値変換について説明します。
AC成分もデータビットの部分は考え方は同じです。

V=0の場合続きのデータビットは有りません。
表現出来る数は1個で0が割り当たります。

V=1の場合、表現出来る数は2個、2進値で"0"と"1"です。これを"0"=-1、"1"=1に割り当てます。
V=2の場合、表現出来る数は4個、"00"=-3、"01"=-2、"10"=2、"11"=3と割り当てます。

V=3の場合、表現出来る数は8個、"000"=-7、"001"=-6、"010"=-5、"011"=-4、"100"=4、"101"=5、"110"=6、"111"=7と割り当てます。

ここまで書くと大体判ると思いますが、数は2のV乗個扱え、数の先頭ビットが1ならそのまま2進表現のプラスの数、先頭のビットが0ならビットを反転させ符号を変えたマイナスの数になります。

図の例で、−4から+4までの数をハフマンコードで表現すると以下の通りになります。(赤がハフマンビット、黒がデータビット)
−4="
100011"
−3="
01100"
−2="
01101"
−1="
0100"
 0="
00"
+1="
0101"
+2="
01110"
+3="
01111"
+4="
100100"

ハフマンコードとVの値の対応次第でファイルが大きくなったり小さくなったりします。
ハフマンコードの最適化とは、ここの対応を変えてファイルを最も小さくする訳です。

図の例でV2-1=0x03,V3-1=0x02,V3-2=0x01,V3-3=0x00に変わったとして、同様に−4から+4までの数をハフマンコードで表現すると以下の通りになります。
(赤がハフマンビット、黒がデータビット)
−4="
00011"
−3="
01000"
−2="
01001"
−1="
0110"
 0="
100"
+1="
0111"
+2="
01010"
+3="
01011"
+4="
00100"

表現するビットが増えたり減ったりしています。
ハフマンコードの最適化では、ハフマンコードビットとデータビットの対応を変えて、ファイルサイズが最も小さくなるようにしています。