EmbCompress — Husqvarna compression (Greg-Hus)

The compression used by HUS, VIP and VP3. The classic scheme known as "Greg's HUS compression": two layers — static Huffman + RLE — implemented in packages/core/src/embcompress.ts, a faithful port of pyembroidery/EmbCompress.py (MIT license).

API

// Decompression (for reading VIP/HUS/VP3)
expand(data: Uint8Array, count: number): Uint8Array

// Compression (for writing HUS/VIP/VP3)
compress(data: Uint8Array): Uint8Array

expand() takes a compressed block and the expected record count, and returns the decompressed bytes. compress() produces a stored block (a degenerate literal Huffman table): the key to avoiding edge cases on variable sizes.

Block structure

Known bug in pyembroidery

pyembroidery.EmbCompress.compress writes the block count little-endian, while every decoder reads it MSB-first. It only works because certain sizes happen to coincide in both byte orders. Our writer emits it in decoder order — verified against pyembroidery's expand for all sizes, not just the lucky ones.

Tests

packages/core/test/embcompress.test.ts covers:

See also Tests & fixtures.

← IR Tests →