LZW

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

LZWは、辞書式圧縮である Lempel-Ziv法 (LZ78) を、スペリー社のテリー・ウェルチが改良したアルゴリズム。

開発者の Lempel、Ziv、Welch の頭文字を取ってLZWと呼ばれる。

圧縮効率と高速化の両面を追求している為、LZSSハフマン符号化を組み合わせたDeflateアルゴリズム(LZHZIPなどが採用)と比べると30%ほど圧縮効率が悪い。GIFTIFFなどの圧縮で利用されている。UNIX Compressで使える。

実装[編集]

以下、Groovyでの実装。まず、ビット列を扱うストリームを用意する。

class BitStream {
  BitSet bs = new BitSet(); int len = 0, pos = 0;
  void write(int v, int bits) {
    for (int i in 0..<bits) { bs[len++] = ((v >>> i) & 1) != 0 }
  }
  int read(int bits) {
    int v = 0; for (int i in 0..<bits) { if (bs[pos++]) { v |= 1 << i } }
    return v
  }
  String toString() { "length = $len, {" + (0..<len).findAll({ bs[it] }).join(", ") + "}" }
}

圧縮は以下の通り。

BitStream compress(byte[] data) {
  BitStream bs = new BitStream(); List str = []; int maxCode = 255, maxCodeBits = 8;
  Map table = [:]; for (int i in 0..maxCode) { table[[(byte) i]] = i }
 
  for (byte c in data) {
    str << c
    if (!table.containsKey(str)) {
      bs.write(table[str[0..(str.size() - 2)]], maxCodeBits)
      table[str] = ++maxCode
      if (maxCode == (1 << maxCodeBits)) maxCodeBits++
      str = [c]
    }
  }
  bs.write(table[str], maxCodeBits)
  return bs
}

解凍は以下の通り。

byte[] decompress(BitStream bs) {
  List bytes = []; int maxCode = 255, maxCodeBits = 8, prevCode; byte c;
  List table = []; for (byte v in 0..maxCode) { table << [v] }
 
  bs.pos = 0
  bytes << (c = prevCode = bs.read(maxCodeBits))
  while (bs.pos < bs.len) {
    if (++maxCode == (1 << maxCodeBits)) maxCodeBits++
    int code = bs.read(maxCodeBits)
    List str = (code == maxCode) ? table[prevCode] + c : table[code]
    bytes.addAll(str)
    table << table[prevCode] + (c = str[0])
    prevCode = code
  }
  return bytes as byte[]
}

特許[編集]

LZWは1984年に発表された。当初スペリー社が特許を保有していた。のちスペリー社はバロース社と合併し1986年ユニシス社となり、本アルゴリズムの特許権もユニシス社に引き継がれた。

前述の通りGIF画像の圧縮に用いられており、その特許料に関するユニシス社の姿勢が問題となった。詳細はGIF特許問題を参照。

日本では1984年6月20日に特許が出願され、2004年6月20日に期限切れとなった。以下、日本の特許庁産業財産権情報より:

  • 発明の名称:圧縮装置および圧縮方法
  • 出願日:1984年6月20日
    • 出願番号:特許出願平7-341868
  • 公開日:1996年9月13日
    • 公開番号:特許公開平8-237138