// copypasted from https://web.archive.org/web/20151202051931/http://www.opensource.apple.com/source/boot/boot-132/i386/boot2/lzss.c #include #include #include #define N 4096 /* size of ring buffer - must be power of 2 */ #define F 18 /* upper limit for match_length */ #define THRESHOLD 2 /* encode string into position and length if match_length is greater than this */ #define NIL N /* index for root of binary search trees */ int decompress_lzss(uint8_t *dst, uint8_t *src, uint32_t srclen) { /* ring buffer of size N, with extra F-1 bytes to aid string comparison */ uint8_t *dststart = dst; uint8_t *srcend = src + srclen; int i, j, k, r, c; unsigned int flags; uint8_t text_buf[N + F - 1]; dst = dststart; srcend = src + srclen; for (i = 0; i < N - F; i++) text_buf[i] = ' '; r = N - F; flags = 0; for ( ; ; ) { if (((flags >>= 1) & 0x100) == 0) { if (src < srcend) c = *src++; else break; flags = c | 0xFF00; /* uses higher byte cleverly */ } /* to count eight */ if (flags & 1) { if (src < srcend) c = *src++; else break; *dst++ = c; text_buf[r++] = c; r &= (N - 1); } else { if (src < srcend) i = *src++; else break; if (src < srcend) j = *src++; else break; i |= ((j & 0xF0) << 4); j = (j & 0x0F) + THRESHOLD; for (k = 0; k <= j; k++) { c = text_buf[(i + k) & (N - 1)]; *dst++ = c; text_buf[r++] = c; r &= (N - 1); } } } return dst - dststart; } #include int main() { #define COMPRESSED_LEN 16 uint8_t input[COMPRESSED_LEN]; uint8_t plain[24]; uint32_t size=COMPRESSED_LEN; decompress_lzss(plain, "\xff" "Buffalo \x13" "bu" "\xf0\xf2\xed\xf5", size); printf ("%s\n", plain); return 0; }