10. デコードアルゴリズム (Decoding Algorithm)
10. デコードアルゴリズム (Decoding Algorithm)
非圧縮データを生成するデコードアルゴリズム (Decoding Algorithm) は次のとおりです:
ウィンドウサイズを読み取る
do
ISLAST ビットを読み取る
if ISLAST
ISLASTEMPTY ビットを読み取る
if ISLASTEMPTY
ループから抜ける
MNIBBLES を読み取る
if MNIBBLES がゼロ
予約ビットがゼロであることを確認
MSKIPLEN を読み取る
次のバイト境界までのビットをスキップ
MSKIPLEN バイトをスキップ
次のメタブロックに続行
else
MLEN を読み取る
if not ISLAST
ISUNCOMPRESSED ビットを読み取る
if ISUNCOMPRESSED
次のバイト境界までのビットをスキップ
MLEN バイトの圧縮データをリテラルとしてコピー
次のメタブロックに続行
3 つのブロックカテゴリそれぞれでループ (i = L, I, D)
NBLTYPESi を読み取る
if NBLTYPESi >= 2
ブロックタイプのプレフィックスコード HTREE_BTYPE_i を読み取る
ブロックカウントのプレフィックスコード HTREE_BLEN_i を読み取る
ブロックカウント BLEN_i を読み取る
ブロックタイプ BTYPE_i を 0 に設定
最後から 2 番目と最後のブロックタイプを 0 と 1 に初期化
else
ブロックタイプ BTYPE_i を 0 に設定
ブロックカウント BLEN_i を 16777216 に設定
NPOSTFIX と NDIRECT を読み取る
リテラルコンテキストモード配列 CMODE[] を読み取る
NTREESL を読み取る
if NTREESL >= 2
リテラルコンテキストマップ CMAPL[] を読み取る
else
CMAPL[] をゼロで埋める
NTREESD を読み取る
if NTREESD >= 2
距離コンテキストマップ CMAPD[] を読み取る
else
CMAPD[] をゼロで埋める
リテラルプレフィックスコード配列 HTREEL[] を読み取る
挿入コピー長プレフィックスコード配列 HTREEI[] を読み取る
距離プレフィックスコード配列 HTREED[] を読み取る
do
if BLEN_I がゼロ
HTREE_BTYPE_I を使用してブロックタイプを読み取り、BTYPE_I を設定
前のブロックタイプを保存
HTREE_BLEN_I を使用してブロックカウントを読み取り、BLEN_I を設定
BLEN_I をデクリメント
HTREEI[BTYPE_I] を使用して挿入コピー長シンボルを読み取る
挿入長 ILEN とコピー長 CLEN を計算
ILEN の間ループ
if BLEN_L がゼロ
HTREE_BTYPE_L を使用してブロックタイプを読み取り、BTYPE_L を設定
前のブロックタイプを保存
HTREE_BLEN_L を使用してブロックカウントを読み取り、BLEN_L を設定
BLEN_L をデクリメント
コンテキストモード CMODE[BTYPE_L] を検索
最後の 2 つの非圧縮バイトからコンテキスト ID CIDL を計算
HTREEL[CMAPL[64*BTYPE_L + CIDL]] を使用してリテラルを読み取る
リテラルを非圧縮ストリームに書き込む
if このメタブロックのループで生成された非圧縮バイト数が MLEN なら
ループから抜ける (この場合、コピー長は無視され、任意の値を
持つことができます)
if 挿入コピーコードからの距離コードが暗黙のゼロ
後方距離を最後の距離に設定
else
if BLEN_D がゼロ
HTREE_BTYPE_D を使用してブロックタイプを読み取り、BTYPE_D を設定
前のブロックタイプを保存
HTREE_BLEN_D を使用してブロックカウントを読み取り、BLEN_D を設定
BLEN_D をデクリメント
CLEN からコンテキスト ID CIDD を計算
HTREED[CMAPD[4*BTYPE_D + CIDD]] を使用して距離コードを読み取る
距離ショートコード置換により距離を計算
if 距離コードがゼロでなく、
距離が静的辞書参照でない場合、
距離を最後の距離のリングバッファにプッシュ
if 距離が最大許容距離 + 1 未満
非圧縮データで後方に距離バイト移動し、
この位置から CLEN バイトを非圧縮ストリームにコピー
else
静的辞書単語を検索し、指示に従って単語を変換し、
結果を非圧縮ストリームにコピー
while このメタブロックの非圧縮バイト数 < MLEN
while not ISLAST
最後のメタブロックが完了する前にストリームが終了した場合、ストリームは無効として拒否されるべきです。
重複文字列参照は、前のメタブロック内の文字列を参照する場合があることに注意してください。つまり、後方距離は 1 つ以上のメタブロック境界を越える場合があります。ただし、後方コピー距離は、非圧縮ストリームの始まりまたはウィンドウサイズより過去を参照することはありません。そのような距離は、静的辞書単語への参照として解釈されます。また、参照される文字列は現在の位置とオーバーラップする場合があることに注意してください。たとえば、デコードされた最後の 2 バイトの値が X と Y である場合、<length = 5, distance = 2> の文字列参照は、非圧縮ストリームに X,Y,X,Y,X を追加します。
出典 (Source): RFC 7932, Section 10
公式テキスト (Official Text): https://www.rfc-editor.org/rfc/rfc7932.txt