私はこれを自分で解決できると思っていましたが、まったく前進していないようです。
わかりました、背景:
jpg ファイルの FFC4、DHT (Define Huffman Table) ヘッダーによって提供される情報からコードのハフマン ツリーを作成する必要があります。DHT ヘッダーは、ハフマン テーブルを次のように定義します。
1) 一連の 16 バイト。各バイトは、n ビットのハフマン コードを持つシンボルの数を定義します。ここで、n は一連のバイトの位置です。(それは意味がありましたか?!!) たとえば、16 進数の生データは次のとおりです。
00 01 05 01 01 01 ... 00
この意味は:
Num of bits: 1 2 3 4 5 6 7 ... 16
Num of codes: 00 01 05 01 01 01 01 ... 00
2) 16 バイトのリストの後に、実際のシンボル自体が続きます。例えば:
00 01 02 03 04 05 06 07 08 09 0A 0B
3) 2 つの部分を組み合わせると、
1 ビットの 00 コード。
2 ビットの 01 コード: リストから最初のシンボルを取得: 00
3 ビットの 05 コード: リストから次の 5 つのシンボルを取得: 01 02 03 04 05
.. など
4) 最後に、上記の情報から実際のハフマン コードを計算する必要があります。あなたが数学の天才なら、特定のビット長で新しいコードごとに適切なビット数で 2 進数をインクリメントするだけで、これらのコードを計算できることにすでに気づいているかもしれません。ビット長が増えたら、単純に 2 進数をインクリメントしてから 2 倍にして続行します。これらの二分木を手で描いてみると、誰の目にも明らかです...
5) これは、ハフマン コードを作成し、それらを配列に格納するために使用したコードです: (最初に 1 のデータを読み取り、それを配列に入れます: dhtBitnum)
int binaryCode = 0;
count = 0;
StringBuffer codeString = new StringBuffer();
//populate array with code strings
for (int numBits=1; numBits<=16; numBits++) {
//dhtBitnum contains the number of codes that have a certain number of bits
for (int i=1; i<=dhtBitnum[(numBits-1)]; i++) {
//turn the binary number into a string
codeString.append(Integer.toBinaryString(binaryCode));
//prepend 0s until the code string is the right length
for(int n=codeString.length(); n<numBits; n++) {
codeString.insert(0, "0");
}
//put the created Huffman code in an array
dhtCodes[count]=codeString.toString();
binaryCode++;
count ++;
codeString.delete(0, codeString.length());
}
binaryCode = binaryCode << 1;
}
ハフマン コードを生成して順番に保存したら、2) で参照するシンボルを順番に追加するだけです。これはそれほどエレガントではないかもしれませんが、少なくとも機能しているようで、正しいテーブルを作成します。
6) 誰かがまだこれに従っているなら、あなたはメダルに値します。
7) 問題は、配列を毎回検索するのではなく、後で jpg 画像データを効率的にデコードできるように、この情報をバイナリ ツリーに格納することです。残念ながら、上記の jpg ヘッダーで提供される情報から直接これを行うためのクリーンで効率的な方法を見つけることはできません。
私が考えることができる唯一の方法は、最初に上記のようにハフマンコードを作成し、次にコードをある種のアドレスとして使用して、必要に応じてノードを作成し、シンボルを適切な場所に保存する方法を実装することです。しかし、これは私が必要とする情報を複製しているようなラウンドアバウトな方法のように思えます.もっと良くて簡単な方法があるに違いありません.
8) 誰かが私のとりとめのないことを理解していれば、いくつかの提案に非常に感謝しています. これは非常に具体的な問題であることは承知していますが、上記の情報が誰かの役に立てば幸いです。私はまだこれに非常に慣れていないので、私の無知を許してください。理解しやすいコードは特に大歓迎です!