Run-Length Encoding
Simple compression
Run-length encoding compressed data by storing repeated values as count-value pairs, dramatically reducing storage for graphics with large uniform areas.
Overview
Why store “AAAAAABBBBCC” when you can store “6A4B2C”? Run-length encoding replaced sequences of identical values with a count and single value. For graphics with large uniform areas—backgrounds, simple sprites, text screens—RLE achieved significant compression with minimal decoding overhead.
The algorithm
| Original | Encoded |
|---|---|
| AAAAAAA | 7A |
| BBBBB | 5B |
| CC | 2C |
| AAAAAABBBBBC | 6A5B1C |
Implementation
Encoding:
- Read input byte
- Count consecutive identical bytes
- Output count, then byte value
- Repeat until end
Decoding:
- Read count
- Read value
- Output value 'count' times
- Repeat until end
Ideal use cases
| Content | Compression ratio |
|---|---|
| Solid backgrounds | Excellent (90%+) |
| Simple sprites | Good (50-70%) |
| Text screens | Very good (70-80%) |
| Detailed images | Poor (may expand) |
Variations
| Variant | Feature |
|---|---|
| PackBits | Escape byte for literals |
| PCX format | RLE for image rows |
| ILBM | Amiga bitmap format |
| Vertical RLE | Column-wise encoding |
Platform examples
ZX Spectrum
Screen loading with RLE:
- 6912 bytes uncompressed
- Often 2-4KB compressed
- Fast decompression
C64
Character/colour data:
- Screen memory (1000 bytes)
- Colour memory (1000 bytes)
- Significant savings
NES
Tile and nametable compression:
- ROM space critical
- Simple decoder in 6502
Limitations
| Issue | Cause |
|---|---|
| Random data expands | No runs to compress |
| Overhead | Count byte per run |
| Fixed ratio | No adaptive compression |
| Horizontal bias | Works best row-by-row |