Files
skills/docs/foundation/bitpacker/bitpacker-compressed/src/rle/rle.md
2026-05-29 08:20:56 +01:00

3.8 KiB

Run-length encoding (compressRle / decompressRle)

(no submodules)

- rle.schema — Zod schema for the per-call `Compressi…
  • rle.schema — Zod schema for the per-call CompressionOptions accepted by compressRle / decompressRle. The RLE codec is byte-onl…

  • rle.schema — Zod schema for the per-call `Compressi…

  • rle.schema — Zod schema for the per-call CompressionOptions accepted by compressRle / decompressRle. The RLE codec is byte-onl…

  • rle.schema — Zod schema for the per-call `Compressi…

  • rle.schema — Zod schema for the per-call CompressionOptions accepted by compressRle / decompressRle. The RLE codec is byte-onl…

  • rle.schema — Zod schema for the per-call `Compressi…

  • rle.schema — Zod schema for the per-call CompressionOptions accepted by compressRle / decompressRle. The RLE codec is byte-onl…

  • rle.schema — Zod schema for the per-call CompressionOptions accepted by compressRle / decompressRle. The RLE codec is byte-onl…

Purpose

compressRle / decompressRle are byte-level run-length encoding helpers shipped as a separate module within @suaveplan/bitpacker-compressed so embedded / no-streams environments can import them without pulling in CompressionStream-using gzip/deflate adapters or the CompressedBitPacker class. They are not part of the CompressionRegistry framing — bytes produced by compressRle are NOT the same shape as bytes produced by the registry's "none"/"gzip"/"deflate" adapters, which include the CompressedBitPacker header. If you need framed RLE, write a thin RleCompressionAdapter that internally calls these helpers.

Features

  • Bytes-only fast path; no streams required.
  • Single-byte runs longer than 3 are emitted as [byte][0][count]; everything else passes through verbatim.
  • Symmetric round-trip with decompressRle.
  • Zero allocation overhead beyond the output Uint8Array.

Usage: Basic Example

import { compressRle, decompressRle } from "@suaveplan/bitpacker-compressed";

const data = new Uint8Array([1, 1, 1, 1, 1, 2, 3]);
const compressed = compressRle(data);  // [1, 0, 5, 2, 3]
const restored = decompressRle(compressed);  // back to original

Usage: Advanced Example

import {
  compressRle,
  decompressRle,
  type CompressionAdapter,
} from "@suaveplan/bitpacker-compressed";

// Wrap RLE in a CompressionAdapter shape so it plugs into the registry.
class RleAdapter implements CompressionAdapter {
  readonly name = "rle";
  async compress(data: Uint8Array) { return compressRle(data); }
  async decompress(data: Uint8Array) { return decompressRle(data); }
}

API Reference

compressRle(data: Uint8Array): Uint8Array

  • Encodes runs of >3 identical bytes as [byte][0][count].
  • Returns a fresh Uint8Array; input is not mutated.

decompressRle(data: Uint8Array): Uint8Array

  • Reverses compressRle. Looks ahead for [0][count] markers after each byte.
  • Returns a fresh Uint8Array.

CompressionOptions

Type alias for { readonly level?: number } — accepted but ignored by the bytes-only RLE path; included so adapter authors can re-export the canonical compression-options shape.

Implementation Notes

  • The marker byte is 0, which would collide with a literal 0 in input data; the encoder handles this by always emitting the run-length form when byte === 0 runs.
  • This is not the most aggressive RLE possible — it does not pack runs of distinct bytes into literal blocks. The intent is "smaller than verbatim with a single linear pass", not "competitive with gzip on text".
  • Use this when you have known byte-pattern data (e.g. graphics with large flat regions, sparse network frames). For general-purpose data, use the gzip / deflate adapters.