libcompression provides multiple lossless string codecs:
- RLE for repeated character runs
- Huffman coding for frequency-based bit packing
- LZW for dictionary-based phrase compression
The default compress() and decompress() functions keep using RLE for backward compatibility.
The implementation is split internally across compression-rle, compression-huffman, and compression-lzw, while compression remains the public facade.
Codec-specific docs:
Benchmark sample:
samples/compression-benchmark.oak
compression := import('compression')
{
compress: compress
decompress: decompress
huffmanCompress: huffmanCompress
lzwCompress: lzwCompress
} := import('compression')
Compresses input with the requested codec.
Supported algorithms:
:rleor'rle':huffmanor'huffman':lzwor'lzw'
If algorithm is omitted, RLE is used.
compression.compress('aaaaabbbb')
compression.compress('BANANA BANDANA', :huffman)
compression.compress('TOBEORNOTTOBEORTOBEORNOT', :lzw)
Decompresses content previously produced by the selected codec.
If algorithm is omitted, RLE is used.
Returns :error for malformed data or unknown algorithms.
compressed := compression.compress('aaaaabbbb')
compression.decompress(compressed)
compressed := compression.compress('BANANA BANDANA', :huffman)
compression.decompress(compressed, :huffman)
Checks whether a value appears to be compressed by a supported codec.
- Without
algorithm, returns true for any supported format. - With
algorithm, checks only that codec.
compression.compressed?(value)
compression.compressed?(value, :huffman)
compression.compressed?(value, :lzw)
RLE is the default codec and remains compatible with the original API.
Marker := '\x1d'
RunPrefix := '#'
RunSep := ':'
Encodes repeated runs using an escape-safe token format.
Rules:
- Literal characters are emitted as-is.
Markeris escaped asMarker + Marker.- Runs may be emitted as
Marker + '#' + <count> + ':' + <char>. - Runs are used only when shorter than the literal form.
Decodes an RLE stream. Returns :error for malformed tokens.
Checks whether a string contains the RLE marker form.
packed := compression.rleCompress('aaaaabbbbcc')
restored := compression.rleDecompress(packed)
Huffman compression builds a character frequency table, derives a binary tree, and stores the resulting bitstream as a text-safe payload.
HuffmanMagic := 'HUF1:'
Compresses input using a Huffman tree derived from the input character frequencies.
Implementation notes:
- The output stores a serialized frequency header followed by
|and the encoded bitstring. - Header entries are encoded as
<hex-codepoint>:<count>and joined with commas. - Small inputs may grow due to the header cost.
Decompresses Huffman data created by huffmanCompress().
Returns :error for invalid packets, malformed frequency headers, or malformed bitstreams.
Returns true when the payload starts with HuffmanMagic.
source := 'BANANA BANDANA BANANA BANDANA'
packed := compression.huffmanCompress(source)
restored := compression.huffmanDecompress(packed)
LZW compression builds a dictionary of repeated phrases and emits integer codes.
LZWMagic := 'LZW1:'
Compresses input using an LZW dictionary.
Implementation notes:
- The output stores a serialized alphabet header followed by
|and a comma-separated integer code list. - Alphabet entries are encoded as hexadecimal codepoints.
- Returns
:errorif the dictionary would exceed 65535 entries.
Decompresses data created by lzwCompress().
Returns :error for malformed packets, invalid headers, invalid code streams, or unsupported dictionary growth.
Returns true when the payload starts with LZWMagic.
source := 'TOBEORNOTTOBEORTOBEORNOT'
packed := compression.lzwCompress(source)
restored := compression.lzwDecompress(packed)
compression := import('compression')
source := 'BANANA BANDANA BANANA BANDANA'
rle := compression.compress(source)
huffman := compression.compress(source, :huffman)
lzw := compression.compress(source, :lzw)
println(len(rle))
println(len(huffman))
println(len(lzw))
compression := import('compression')
fn decodePacket(packet, codec) if codec {
:rle -> compression.decompress(packet, :rle)
:huffman -> compression.decompress(packet, :huffman)
:lzw -> compression.decompress(packet, :lzw)
_ -> :error
}
- All codecs are lossless.
- RLE is best for repeated character runs.
- Huffman is best when the data has a skewed character distribution.
- LZW is best when the data contains recurring phrases or substrings.
- Huffman and LZW output formats are self-framed with magic prefixes plus explicit text-safe payload sections.