さて、何か値が与えられた時に、
その値の2進表現の何桁が有効桁かを判断したり、
対応するハフマンコードをその都度ツリーを辿って探し出したり、
そもそも与えられた値が負だったら1の補数表現に直したり・・・
なんてコトをイチイチ処理していたら時間がかかる。
日の短い時分には日が暮れちまう、温気の時分には腐っちまうので
これらの変換の対応を取ったルックアップ・テーブル(LUT)を作ってしまおう。
なお、LUTに作るべきデータは本来なら可変ビット長なのだが、
さすがに可変ビット長では扱いようがない。
で、一旦16bitデータ形式の中に可変ビットデータを「左寄せ」で詰め込み
開いた右側はゼロで埋めたものを16進数表現で羅列したtxtファイルと、
その16bitデータ中の何bitを左から取り出すかの数値を羅列したtxtファイルを作る。
例によって、例のごとくExcel VBAを使って・・・
まずはデータ値を可変ビットに変換するLUT(負の場合は1の補数表現に直す)。
Sub DataBitsToFile()
Dim DB, N As Integer
Dim Data(4094) As String
Dim Num(4094) As Integer
DataFile$ = "E:\DB_Data.txt" ' 変換データのファイル
NumFile$ = "E:\DB_Num.txt" ' 有効Bit数のファイル
For N = -2047 To 2047
If N < 0 Then
DB = -N
Data(N + 2047) = Right("0000000000000000" _
& Application.WorksheetFunction.Dec2Bin(Not (DB \ 256)) _
& Right("00000000" _
& Application.WorksheetFunction.Dec2Bin(Not (DB Mod 256)), 8), 16)
Else
DB = N
Data(N + 2047) = Right("0000000000000000" _
& Application.WorksheetFunction.Dec2Bin(DB \ 256) _
& Right("00000000" _
& Application.WorksheetFunction.Dec2Bin(DB Mod 256), 8), 16)
End If
If N = 0 Then
Num(2047) = 0
Else
Num(N + 2047) = Int(0.0001 + Log(DB) / Log(2)) + 1
End If
Data(N + 2047) = Left(Right(Data(N + 2047), Num(N + 2047)) _
& "0000000000000000", 16)
Data(N + 2047) = Application.WorksheetFunction.Bin2Hex(Left(Data(N + 2047), 4)) _
& Application.WorksheetFunction.Bin2Hex(Mid(Data(N + 2047), 5, 4)) _
& Application.WorksheetFunction.Bin2Hex(Mid(Data(N + 2047), 9, 4)) _
& Application.WorksheetFunction.Bin2Hex(Mid(Data(N + 2047), 13, 4))
Next N
Open DataFile$ For Output As #1
For N = 0 To 4094
If N Mod 8 <> 7 Then
Print #1, "0x" & Data(N) & ", ";
Else
Print #1, "0x" & Data(N) & ", "
End If
Next N
Close #1
Open NumFile$ For Output As #2
For N = 0 To 4094
If N Mod 16 <> 15 Then
Print #2, Num(N) & ", ";
Else
Print #2, Num(N) & ", "
End If
Next N
Close #2
End Sub
を実行すると、中身が
0x0000, 0x0020, 0x0040,・・・(大幅に中略)・・・, 0xFFA0, 0xFFC0, 0xFFE0,
と
11, 11, 11, ・・・(これまた大幅に中略)・・・, 11, 11, 11,
となっている2つのtxtファイルが出来上がる。
双方とも一番最後の「,」(コンマ)はいらないのでテキストエディタで削除する。
いずれも-2047~+2047範囲のデータに対応するものになっている。
なお、ゼロ値は「値0x0000」で「bit長0」として記述している。
データ値ゼロは前回述べたようにJpegハフマンでは記述しないが
処理を統一するためこのようにしておく。
コレをソースファイルのInitialize Variable Arrayセクションにコピペして
static unsigned short L_Dc[4095] = {
// LUT for Data Code -2047~+2047
0x0000, 0x0020, 0x0040,・・・(大幅に中略)・・・, 0xFFA0, 0xFFC0, 0xFFE0
};
と
static char L_Db[4095] = {
// LUT for Data Bits -2047~+2047
11, 11, 11, ・・・(これまた大幅に中略)・・・, 11, 11, 11
};
・・・とでもして配列に初期化する。
これでデータ値Nをハフマン変換処理用の可変ビット長変換したビット列は
L_Dc[N]の16bitのビット列の左からL_Db[N]個のビットを抜き出せば良い。
(厳密には、データ範囲は-2047~+2047なのでNを+2047オフセットさせて
配列から取り出す)
- つづく -