EmbCompress — compressione Husqvarna (Greg-Hus)
La compressione usata da HUS, VIP e VP3. Lo schema classico noto come
"Greg's HUS compression": due livelli — Huffman statici + RLE — implementati in
packages/core/src/embcompress.ts, port fedele di
pyembroidery/EmbCompress.py (licenza MIT).
API
// Decompressione (per leggere VIP/HUS/VP3)
expand(data: Uint8Array, count: number): Uint8Array
// Compressione (per scrivere HUS/VIP/VP3)
compress(data: Uint8Array): Uint8Array expand() prende un blocco compresso e il numero di record
attesi, restituisce i byte decompressi. compress() produce
un blocco stored (tabella Huffman letterale degenerata): chiave per non
rischiare edge case su dim. variabili.
Struttura del blocco
- Header: number of elements (4 byte, letto come MSB-first dai decoder).
- Huffman table: bitlengths per ogni simbolo.
- RLE layer: controlla ripetizioni di byte.
- Payload: sequenze codificate.
Bug noto in pyembroidery
pyembroidery.EmbCompress.compressscrive il count del blocco little-endian, mentre ogni decoder lo legge MSB-first. Funziona per puro lucky size. Il nostro writer lo scrive in decoder order — verificato controexpanddi pyembroidery per tutte le size, non solo quelle fortunate.
Test
packages/core/test/embcompress.test.ts copre:
- Round-trip
compress → expandsu fixture reali HUS/VIP/VP3. - Confronto byte-per-byte con output di pyembroidery per gli stessi input.
- Edge case: 1 record, 65535 record (gate), byte nulli, delta di ctrl.
Vedi anche Test & fixture.