You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
alee-forth/msp430/lzss.h

75 lines
1.8 KiB
C

/* LZSS encoder-decoder (Haruhiko Okumura; public domain) */
/* Modified by Clyne Sullivan to focus on streamed decompression. */
#ifndef EOF
#define EOF (-1)
#endif
#define EI 8 /* typically 10..13 */
#define EJ 3 /* typically 4..5 */
#define N (1 << EI) /* buffer size */
#define F ((1 << EJ) + 1) /* lookahead buffer size */
static unsigned char buffer[N * 2];
static const unsigned char *inbuffer;
static unsigned int insize, inidx;
static int buf, mask;
/* Prepares decode() to decompress the given data. */
void lzssinit(const unsigned char *inb, unsigned int ins)
{
inbuffer = inb;
insize = ins;
inidx = 0;
buf = 0;
mask = 0;
}
int getbit(int n) /* get n bits */
{
int i, x;
x = 0;
for (i = 0; i < n; i++) {
if (mask == 0) {
if (inidx >= insize)
return EOF;
buf = inbuffer[inidx++];
mask = 128;
}
x <<= 1;
if (buf & mask) x++;
mask >>= 1;
}
return x;
}
/* handleoutput() receives each decompressed byte, return zero if want more. */
int decode(int (*handleoutput)(int))
{
int i, j, k, r, c, ret;
for (i = 0; i < N - F; i++) buffer[i] = ' ';
r = N - F;
while ((c = getbit(1)) != EOF) {
if (c) {
if ((c = getbit(8)) == EOF) break;
if ((ret = handleoutput(c)))
return ret;
buffer[r++] =(unsigned char) c; r &= (N - 1);
} else {
if ((i = getbit(EI)) == EOF) break;
if ((j = getbit(EJ)) == EOF) break;
for (k = 0; k <= j + 1; k++) {
c = buffer[(i + k) & (N - 1)];
if ((ret = handleoutput(c)))
return ret;
buffer[r++] = (unsigned char)c; r &= (N - 1);
}
}
}
return EOF;
}