一番単純な圧縮法で、前章で説明しましたように同じ記号がたくさん続く場合にしか圧縮効果がありませんので、主として画像データの圧縮に利用されています。
この手法の実用例としては、MacintoshのPICTファイルでモノクロのビットマップデータを圧縮するのに用いられているPackBitsが有名です。
- 元データは8ビットの固定長符号であると仮定し、8ビット単位で符号化する。
-
「abcd」のように繰り返しのない一連の記号は、1バイト目に(記号数−1)という1バイト整数を、2バイト以後に一連の記号を並べた(記号数+1)バイトで符号化する。
1バイト目の整数は0から127の範囲、つまり記号数にすると1個から128個とし、一連の記号が129個以上続く場合は2つ以上に分割して符号化する。
例えば元データが「abcd」の場合、「3abcd」と符号化される。
-
「aaaa」のように同じ記号が複数個連続して続く場合は、1バイト目に(−記号の繰り返し数+1)という負の1バイト整数を、2バイト目に記号そのものを並べた2バイトで符号化する。
1バイト目の整数は-1から-127の範囲、つまり繰り返し数にすると2個から128個とし、同じ記号が129個以上続く場合は2つ以上に分割して符号化する。
例えば元データが「aaaa」の場合、「-3a」と符号化される。
-
2.のようなデータを「リテラル(文字列)グループ」、3.のようなデータを「反復グループ」といい、これらは1バイト目が正の整数か負の整数かによって区別される。
「a」のように記号が1つだけの場合、どちらの方法で符号化しても「0a」となる。
-
一連の記号をリテラルとして保存するための一時記憶場所を確保し、リテラル数mを0にする。
同時に反復グループ用に前記号を保存するための一時記憶場所を確保し、繰り返し数nを0にする。
- 元データから最初の1記号(8ビット固定長符号)を入力し、入力記号を前記号として記憶し、nを1にする。
- 元データから次の1記号を入力する。
-
入力記号が前記号と異なる場合は、
もし前記号の繰り返し数nが2以上ならば、
反復グループとして「-(n-1)<前記号>」を出力。
あるいは前記号の繰り返し数nが2未満ならば、
もしリテラル数mが128未満ならば、
mを1増加して、前記号をリテラルのm文字目として保存。
あるいはリテラル数mが128以上ならば、
リテラルグループとして「(m-1)<リテラル>」を出力。
リテラルをクリアし、リテラル数mを0にする。
入力記号を前記号として記憶し、nを1にする。
3.に戻る。
-
入力記号が前記号と同じ場合は、
もしリテラル数mが1以上ならば、
リテラルグループとして「(m-1)<リテラル>」を出力。
リテラルをクリアし、リテラル数mを0にする。
もし前記号の繰り返し数nが128未満ならば、
繰り返し数nを1増加する。
あるいは前記号の繰り返し数nが128以上ならば、
反復グループとして「-(n-1)<前記号>」を出力。
前記号はそのままで、nを1にする。
3.に戻る。
-
元データが終了した場合、
もし前記号の繰り返し数nが1未満(1記号も入力せず)ならば、
何もしない。
あるいは前記号の繰り返し数nが1ならば、
mを1増加して、前記号をリテラルのm文字目として保存。
リテラルグループとして「(m-1)<リテラル>」を出力。
あるいは前記号の繰り返し数nが2以上ならば、
もしリテラル数mが1以上ならば、
リテラルグループとして「(m-1)<リテラル>」を出力。
反復グループとして「-(n-1)<前記号>」を出力。
-
リテラル記憶場所確保、m=0。
前記号記憶場所確保、n=0。
-
1記号目の「a」を入力。
前記号=a、n=1
-
「b」入力。
入力記号b≠前記号a
前コードの繰り返し数n=1<2
リテラルの繰り返し数m=0<128
m=1、リテラル=a
前記号=b、n=1
-
「b」入力。
入力記号b=前記号b
リテラル数m=1≧1
「0a」を出力
リテラルをクリア、m=0
前記号の繰り返し数n=1<128
n=2
-
「b」入力。
入力記号b=前記号b
リテラル数m=0
前記号の繰り返し数n=2<128
n=3
-
「c」入力。
入力記号c≠前記号b
前記号の繰り返し数n=3≧2
「(-2)b」を出力。
前記号=c、n=1
-
「c」入力。
入力記号c=前記号c
前記号の繰り返し数n=1<128
n=2
-
「c」入力。
入力記号c=前記号c
前記号の繰り返し数n=2<128
n=3
-
「c」入力。
入力記号c=前記号c
前記号の繰り返し数n=3<128
n=4
-
「d」入力。
入力記号d≠前記号c
前記号の繰り返し数n=4≧2
「(-3)c」を出力。
前記号=d、n=1
-
「e」入力。
入力記号e≠前記号d
前記号の繰り返し数n=1<2
リテラルの繰り返し数m=0<128
m=1、リテラル=d
前記号=e、n=1
-
元データ終了。
前記号の繰り返し数n=1
m=2、リテラル=de
「1de」を出力
実際にプログラムを組んだりデータを圧縮してみたりするとわかりますが、このWindows方式はPackBits方式よりも効率が悪く、あまり合理的な方法とは言えません。