デフレート圧縮(LZ77圧縮)処理の概要。

PNG画像を生成するのに欠かせないデフレート圧縮(LZ77圧縮)について解説します。

デフレート圧縮とは。

デフレート圧縮は、LZ77圧縮アルゴリズムを応用したもので、圧縮技術としてはかなり旧くからあるもので、GZIP(ZLib)やZIPファイル圧縮技術などに用いられております。

デフレート圧縮は枯れた技術であり、特許問題も無い技術として知られており、この為PNG画像の基幹技術としても採用されたのです。

技術的な解説。

LZ77圧縮とは。

LZ77圧縮とは、ヤコブ=ジフ(J. Ziv)とアブラハム=ランペル(A. Lampel)両氏が西暦1977年(昭和52年)に考案した圧縮アルゴリズムで、平たく言えば「既に出てきている文字の並び(単語)が再度出てきたら、それをより短い符号に置換えてしまう」と言うものです。

以下、一般常識とはちょっと懸け離れた意味で使われる用語を解説しておきます。

文字

ここで言う文字とは、 1オクテット( 8ビット)で表される 1データの事を指します。

単語

単語とは、複数個の文字(オクテット)で構成されるデータの塊を指します。

尚、デフレート圧縮では単語は 3文字以上258文字以内とします。

ここでは、説明を分かり易くするため、具体的に"ABCDEFGABCDEF"というアスキィ文字列で考えて見ましょう。

  1. 8文字目以降の"ABCDEF"という長さ 6文字の単語はその 7文字前に既に出てきております。
  2. そこで、これを「 6文字の単語で 7文字前にある」と言う意味の(6,7)という符号で表します。
  3. 結局、この文字列は"ABCDEFG"(6,7)というデータとなります。

この様な原理から、同じ文字列が何度も出てくればより圧縮効率が高まると言う事になります。

更に言えば、単語が長ければ長い程、より効率よく圧縮出来る事になります。

圧縮されたデータの具体的な表現。

単語データの表現法。

LZ77圧縮を施す事で、(文字)と(単語の長さ,単語の位置)という二種類のデータが発生します。

つまり、デコーダは最初のデータが文字データ( 0〜255)ならそのまま出力して、257〜285なら単語という事でこの後に付随するデータを読込んで単語を決定します。256ならそこで処理を終了させます。

ハフマン符号による圧縮データ表現。

上述の通り、 8ビットの文字列を圧縮した際に 8ビットを越える符号データが発生します。

また、付随するデータには 8ビットに満たないものもあります。

そうすると、ビット長が不定のデータ列をどのようにして構築出来るかと言う問題が発生します。

この答えとして、デフレート圧縮ではハフマン符号が使われます。

ハフマン符号プレフィックス符号と呼ばれる二進数での符号の一種です。

プレフィックス符号の大きな特徴は、一つ一つのデータの大きさが不定だという事です。しかしながら、予め決めておいたデータの形式により、問題無く頭から順に一つづつデータを切出す事ができる様になっております。

このプレフィックス符号を依り効率の良いものにした符号がハフマン符号と呼ばれるものです。

デフレート圧縮では、予め仕様にてハフマン符号を定義してある固定ハフマン符号と、ハフマン符号を再定義してより効率よく符号化を行う独自ハフマン符号が利用できます。

実際のデフレート圧縮データでは、最初に読込むデータ( 0〜285)に対してハフマン符号を当て、単語においては単語の位置を表す0〜29のデータにも別系統のハフマン符号を当てます。

デフレート圧縮におけるLZ77圧縮の拡張(?)。

LZ77圧縮の原理を考えると、圧縮された符号(単語の長さと同じ単語がある位置の組)に関して、単語の位置と単語の長さにはある関係があると考えられます。

すなわち、(l,d)=(単語の長さ,単語の位置)としたときに、ld となっている筈だという事です。

これを否定する l > d と言う関係、例えば圧縮データが「"ABCDEFG"(7,3)」となっているとしたら(7,3)という符号は「 7文字の単語が 3文字前にある」となりますが、これだと"EFG"という 3文字しか取出せず、 7文字の単語を取出す事ができません。

しかしながら、デフレート圧縮の仕様書ではこの様なデータの存在を明確に認めております

l > d と言う関係を持つ符号では、単語の字数を満たすように取出せた文字列を繰返し並べると言う決まりになっているのです。

先ほどの「"ABCDEFG"(7,3)」の場合、(7,3)符号では 7文字になるまで"EFG"と言う3文字を繰返す事になっており、つまり"EFGEFGE"となります。

結局「"ABCDEFG"(7,3)」="ABCDEFGEFGEFGE"と言うデータとなる訳です。

この決まり事は、PNG画像には特に有効でしょう。

画像の場合、同じ色のピクセルが連続して並ぶと言う事はよくある事です。

単一のピクセルとまで行かなくても、複数のピクセルの列が規則正しく並ぶと言う事も珍しくありません。

この様な「同じデータが連続する」事が多い画像には、有効な圧縮手段を提供された事になります。

デフレート圧縮でのハフマン符号の扱い。

デフレート圧縮では、ハフマン符号に以下の規則を追加しております。

分かり易く言えば、二進数での 0及び 1を文字に見立てて辞書的な決まりに従って符号を決めて行くと言う事です。

具体例を挙げてみましょう。

  1. 一番小さい符号が2ビットの場合、「00」「01」「10」「11」の順に割当てていきます。
  2. 2ビットの符号が「00」「01」の2個しかなく、次の符号が3ビットの場合、次の符号は辞書的に「01」の次となる「10」に数字が続く「100」から始まります。
  3. 同様に3ビットの符号が「110」で終わっていて、次の符号が5ビットの場合は、次の符号は辞書的に「110」の次となる「111」に数字が続く「11100」から始まります。

デフレート圧縮で独自ハフマン符号を用いる場合、圧縮される文字/文字列長及び距離に対して、一つ一つにビット長を指定した形の符号表を提示します。

更にこれらの符号表自身もハフマン符号で圧縮され、その為のハフマン符号表は当然これらの符号表より前に定義されるものとなります。

具体的には、以下の順にデータが並ぶ事となります。

  1. HLIT…実際に利用される文字/文字列長データの個数から257を引いた値。独自ハフマン符号では不要なデータには符号を当てない事で更に効率を上げます( 5ビット)。
  2. HDIST…実際に利用される距離データの個数から 1を引いた値( 5ビット)。
  3. HCLEN…文字/文字列長及び距離データのハフマン符号表を圧縮するためのハフマン符号の数から4を引いた値( 4ビット)。
  4. (※1)文字/文字列長及び距離データのハフマン符号表を圧縮するための、ハフマン符号表。HCLEN+4個のデータが並ぶ。各データは 3ビットと固定されている。

  5. (※2)文字/文字列長データのハフマン符号表。HLIT+257個のデータが(※1)の符号表でハフマン符号化されて並ぶ。
  6. (※2)距離データのハフマン符号表。HDIST+1個のデータが(※1)の符号表でハフマン符号化されて並ぶ。
  7. 実際の圧縮データ。(※2)の二つの符号表でハフマン符号化されて並ぶ。

尚、固定ハフマン符号ではハフマン符号が既に仕様で定義済みなので実際の圧縮データのみが並ぶ事になります。

圧縮データのフォーマット。

圧縮データは、既に述べた通り、任意の区間ごとに無圧縮, 固定ハフマン符号によるエンコード及び独自ハフマン符号によるエンコードの三種類から撰べます。

このため、各区間の先頭に3ビットからなるフラグが付与されます。

先頭の 1ビットは最後の圧縮区間の場合に 1になります。

後続の2ビットは「無圧縮, 固定ハフマン符号によるエンコード及び独自ハフマン符号によるエンコード」のいずれかを明示します。

GZIPフォーマット。

ところで、デフレート圧縮の決まりに従って圧縮しても、そのままのデータでは取扱えません。

最後に、GZIPフォーマットに合せて出力することになります。

GZIPフォーマットは、PNGで採用されているデフレート圧縮データのフォーマットです。

具体的には圧縮されたデータの先頭に 2オクテットのデータ(圧縮方式とフラグ)、末尾に圧縮前のデータに関する 4オクテットのチェックディジットがそれぞれ附加されます。

デフレート圧縮の原理を考えると、圧縮されたデータは文字ないし単語の列と言う形になる訳ですが、圧縮ルーティンのバグが原因で間違ったデータを出力していた場合、形式的に不正で無い限り、デコーダはその間違いを見出す術がありません。

このため、圧縮前のデータを基にチェックディジットを計算しておく事で、展開されたデータに対して同様にチェックディジットを計算して比較する事で圧縮データの誤りを見出せるようになる訳です。

参考文献。

デフレート圧縮仕様書(英語)

一応和訳版もありますが、表組みが崩れていたり、文章が分かり難い箇所もあります。

英語が分かる方は、英語版をご覧になった方が分かり易いでしょう。

ハフマン符号については詳しい解説がありますが、LZ77圧縮については解説があまり詳しく無いので予備知識が無いと理解出来ないかも知れません。

LZ77符号

LZ77圧縮に関しては、宇都宮大学に分かり易い文書があったのですが、現在はサーヴァごと?削除されて見られません。

この文書はインターネット・アーカイヴに保存されている当該文書です(日本語)。

GZIP仕様書(英語)

GZIPフォーマットの仕様書です。

デフレート圧縮をしても、このフォーマットに従わなければ読込んでもらえません。


ページ外へのご案内。