Compression in practice

LZ77: exploiting repetitions

Another source of redundancy

Huffman exploits symbol frequencies. But real files contain another kind of redundancy: repeated sequences. In a text, words recur; in an image, patterns repeat. The LZ77 algorithm (Lempel-Ziv, 1977) exploits precisely these repetitions, and it is the core of formats like ZIP, PNG and gzip.

The idea: replace a repetition with a reference

When a sequence has already been seen recently, instead of writing it out again, LZ77 inserts a reference: "copy so many characters, located so many positions back." A long repetition is thus replaced by a small pair (distance, length).

Sliding window over the text "abcabcabc":

[               ] abcabcabc      (window empty at the start)
[a              ] bcabcabc       (write 'a' as is)
[ab             ] cabcabc        (write 'b')
[abc            ] abcabc         (write 'c')
[abc  ] abc <---- abc            ('abcabc' already seen! -> reference)

     -> the run "abcabc" is replaced by (distance=3, length=6)
(distance = how far to go back, length = how many characters to copy)

The sliding window

LZ77 does not search for repetitions in the whole file (too costly), but in a window of recent characters that slides along the text. A larger window finds more distant repetitions (better compression) but costs more memory and search time.

The best of both worlds

In practice, modern formats combine both approaches: LZ77 first replaces repetitions with references, then Huffman encodes the result. This is exactly what DEFLATE does, the algorithm behind gzip and ZIP: two complementary ideas attacking two different kinds of redundancy.

Classic pitfall

LZ77 gains nothing on data without repetition, such as an already compressed file or random data: there is then no sequence to reference. Worse, encoding useless references can make the file slightly larger. Each algorithm targets a specific redundancy; where it is absent, it works no miracles.