玄関コンピュータの部屋各種解説コーナーデータ圧縮法概説

5.3 LZ77符号化の手順

LZ77符号化の手順は以下のとおりです。

  1. 参照部Nバイト、符号化部Fバイトの大きさのスライド窓を用意する。

    通常、Nは1024〜4096バイト、Fは16〜256バイト程度が用いられます。 例えばN=4096、F=256としますと、最大(F−1=255)バイトまでの最長一致系列を処理することができ、[最長一致系列の参照部の先頭からのオフセット値]12ビット、[最長一致系列の記号数]8ビット、[一致しない最初の記号」8ビットの、計28ビットの固定長で符号化することになります。

    LZ77符号化1
  2. 元データの先頭からFバイトを符号化部にコピーする。
    LZ77符号化2
  3. 最初の記号はそのまま出力する。

    最初は参照部にデータがありませんから、最初の記号は必ず「00<最初の記号>」と符号化されます。 このため、最初の記号だけは00を付けずに記号だけ出力します。

    LZ77符号化3
  4. スライド窓を1バイト右にスライドする。
    LZ77符号化4
  5. 符号化部の先頭から始る記号列に対する最長一致系列を参照部から探し、[最長一致系列の参照部の先頭からのオフセット値][最長一致系列の記号数][一致しない最初の記号」という形式で符号化し、それを出力する。

    例えばオフセットmから始るpバイトが最長一致系列であり、一致しない最初の記号がxだとしますと、「mpx」という符号を出力し、一致する記号がない時は「00<符号化部の最初の記号>」という符号を出力します。

    LZ77符号化5

    最長一致系列は最大(F−1)バイトであり、符号化部のFバイト全体が一致する場合でも最長符号系列を(F−1)バイトとし、最後の記号を一致しない最初の記号として扱います。 また最長一致系列の先頭は参照部にある必要がありますが、末尾は符号化部にまで入ってもかまいません。 例えば下図のような場合、最長一致系列はオフセット(N-3)から始る5バイトが最長一致系列となり、一致しない最初の文字はdとなります。 したがって0≦m≦(N−1)、0≦p≦(F−1)ということになります。

    LZ77符号化6
  6. スライド窓を符号化した(p+1)バイトだけ右にスライドする。
    LZ77符号化7
  7. 元データが終了するまで5.と6.を繰り返す。

    下図のように、最後に不一致記号がない場合は「mp」だけを出力します。

    LZ77符号化7

5.4 LZ77符号化の実例

例として3章5節のハフマン符号の例と同じ「aabbccccddddeeeeeeeeffff」という元データを、前節の手順に従って符号化してみましょう。

  1. 元データが短いため、参照部8バイト、符号化部8バイトの大きさのスライド窓を用意する。
    LZ77符号化例1
  2. 元データの先頭から8バイトを符号化部にコピーする。
    LZ77符号化例2
  3. 最初の記号はそのまま出力する。
    LZ77符号化例3
    符号化データ:a
  4. スライド窓を1バイト右にスライドする。
    LZ77符号化例4
  5. 最長一致系列が「a」なので「71b」を出力する。
    LZ77符号化例5
    最長一致系列のオフセット値m=7 バイト数p=1 最初の不一致記号:b
    符号化データ:a71b
  6. スライド窓を2バイト右にスライドする。
    LZ77符号化例6
  7. 最長一致系列が「b」なので「71c」を出力する。
    LZ77符号化例7
    最長一致系列のオフセット値m=7 バイト数p=1 最初の不一致記号:c
    符号化データ:a71b71c
  8. スライド窓を2バイト右にスライドする。
    LZ77符号化例8
  9. 最長一致系列が「ccc」なので「73d」を出力する。
    LZ77符号化例9
    最長一致系列のオフセット値m=7 バイト数p=3 最初の不一致記号:d
    符号化データ:a71b71c73d
  10. スライド窓を4バイト右にスライドする。
    LZ77符号化例10
  11. 最長一致系列が「ddd」なので「73e」を出力する。
    LZ77符号化例11
    最長一致系列のオフセット値m=7 バイト数p=3 最初の不一致記号:e
    符号化データ:a71b71c73d73e
  12. スライド窓を4バイト右にスライドする。
    LZ77符号化例12
  13. 最長一致系列が「eeeeeee」なので「77f」を出力する。
    LZ77符号化例13
    最長一致系列のオフセット値m=7 バイト数p=7 最初の不一致記号:f
    符号化データ:a71b71c73d73e77f
  14. スライド窓を8バイト右にスライドする。
    LZ77符号化例14
  15. 最長一致系列が「fff」なので「73」を出力し、符号化終了。
    LZ77符号化例15
    最長一致系列のオフセット値m=7 バイト数p=3 最初の不一致記号:なし
    符号化データ:a71b71c73d73e77f73

このデータでは最長一致系列のオフセット値とバイト数はどちらも7であり、ともに3ビットで符号化することができます。 したがって符号化後のデータは、

a71b71c73d73e77f73:8×6+(3+3)×6=48+36=84ビット

となり、この時の圧縮率と平均符号長は次のようになります。

圧縮率=84
───
24×8
84
───
192
=0.4375(43.75%)
平均符号長=84
──
24
=3.5ビット

またこのデータの場合、記号は6種類しかありませんから、

a:000 b:001 c:010 d:011 e:100 f:101

と3ビットで符号化することも可能です。 不一致記号としてこの符号を用い、記号と符号の対応表を符号化後のデータに追加することにすれば、符号化後のデータは、

a71b71c73d73e77f73:3×6+6×6=18+36=54ビット

となり、ハフマン符号よりも6ビット短くすることができます。 ただしオーバーヘッドのビット数まで考慮しますと、圧縮率は記号を通常の8ビットで表す単純な方法が一番良く、ハフマン符号が一番悪くなります。