/************************************************************** LZSS.C -- A Data Compression Program (tab = 4 spaces) *************************************************************** 4/6/1989 Haruhiko Okumura Use, distribute, and modify this program freely. Please send me your improved versions. PC-VAN SCIENCE NIFTY-Serve PAF01022 CompuServe 74050,1022 **************************************************************/ #include #include #define N 4096 /* size of ring buffer */ #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 */ #define EOF -1 #define getc(file) ((src < srcend) ? *src++ : EOF) #define putc(c, file) (dst < dstend) ? (*dst++ = (c)) : 0; grub_size_t grub_decompress_lzss (grub_uint8_t *dst, grub_uint8_t *dstend, grub_uint8_t *src, grub_uint8_t *srcend) { int i, j, k, r, c; unsigned int flags; static unsigned char text_buf[N + F - 1]; grub_uint8_t *dst0 = dst; for (i = 0; i < N - F; i++) text_buf[i] = ' '; r = N - F; flags = 0; for ( ; ; ) { if (((flags >>= 1) & 256) == 0) { if ((c = getc(infile)) == EOF) break; flags = c | 0xff00; /* uses higher byte cleverly */ } /* to count eight */ if (flags & 1) { if ((c = getc(infile)) == EOF) break; putc(c, outfile); text_buf[r++] = c; r &= (N - 1); } else { if ((i = getc(infile)) == EOF) break; if ((j = getc(infile)) == EOF) break; i |= ((j & 0xf0) << 4); j = (j & 0x0f) + THRESHOLD; for (k = 0; k <= j; k++) { c = text_buf[(i + k) & (N - 1)]; putc(c, outfile); text_buf[r++] = c; r &= (N - 1); } } } return dst - dst0; }