Skip to content

Commit 1dfca16

Browse files
committed
Adding lzss.c as provided in the public domain by Haruhiko Okumura
1 parent 761e1e6 commit 1dfca16

File tree

1 file changed

+180
-0
lines changed
  • libraries/SSU/extras/SSUBoot

1 file changed

+180
-0
lines changed

libraries/SSU/extras/SSUBoot/lzss.c

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/* LZSS encoder-decoder (Haruhiko Okumura; public domain) */
2+
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
6+
#define EI 11 /* typically 10..13 */
7+
#define EJ 4 /* typically 4..5 */
8+
#define P 1 /* If match length <= P then output one character */
9+
#define N (1 << EI) /* buffer size */
10+
#define F ((1 << EJ) + 1) /* lookahead buffer size */
11+
12+
int bit_buffer = 0, bit_mask = 128;
13+
unsigned long codecount = 0, textcount = 0;
14+
unsigned char buffer[N * 2];
15+
FILE *infile, *outfile;
16+
17+
void error(void)
18+
{
19+
printf("Output error\n"); exit(1);
20+
}
21+
22+
void putbit1(void)
23+
{
24+
bit_buffer |= bit_mask;
25+
if ((bit_mask >>= 1) == 0) {
26+
if (fputc(bit_buffer, outfile) == EOF) error();
27+
bit_buffer = 0; bit_mask = 128; codecount++;
28+
}
29+
}
30+
31+
void putbit0(void)
32+
{
33+
if ((bit_mask >>= 1) == 0) {
34+
if (fputc(bit_buffer, outfile) == EOF) error();
35+
bit_buffer = 0; bit_mask = 128; codecount++;
36+
}
37+
}
38+
39+
void flush_bit_buffer(void)
40+
{
41+
if (bit_mask != 128) {
42+
if (fputc(bit_buffer, outfile) == EOF) error();
43+
codecount++;
44+
}
45+
}
46+
47+
void output1(int c)
48+
{
49+
int mask;
50+
51+
putbit1();
52+
mask = 256;
53+
while (mask >>= 1) {
54+
if (c & mask) putbit1();
55+
else putbit0();
56+
}
57+
}
58+
59+
void output2(int x, int y)
60+
{
61+
int mask;
62+
63+
putbit0();
64+
mask = N;
65+
while (mask >>= 1) {
66+
if (x & mask) putbit1();
67+
else putbit0();
68+
}
69+
mask = (1 << EJ);
70+
while (mask >>= 1) {
71+
if (y & mask) putbit1();
72+
else putbit0();
73+
}
74+
}
75+
76+
void encode(void)
77+
{
78+
int i, j, f1, x, y, r, s, bufferend, c;
79+
80+
for (i = 0; i < N - F; i++) buffer[i] = ' ';
81+
for (i = N - F; i < N * 2; i++) {
82+
if ((c = fgetc(infile)) == EOF) break;
83+
buffer[i] = c; textcount++;
84+
}
85+
bufferend = i; r = N - F; s = 0;
86+
while (r < bufferend) {
87+
f1 = (F <= bufferend - r) ? F : bufferend - r;
88+
x = 0; y = 1; c = buffer[r];
89+
for (i = r - 1; i >= s; i--)
90+
if (buffer[i] == c) {
91+
for (j = 1; j < f1; j++)
92+
if (buffer[i + j] != buffer[r + j]) break;
93+
if (j > y) {
94+
x = i; y = j;
95+
}
96+
}
97+
if (y <= P) { y = 1; output1(c); }
98+
else output2(x & (N - 1), y - 2);
99+
r += y; s += y;
100+
if (r >= N * 2 - F) {
101+
for (i = 0; i < N; i++) buffer[i] = buffer[i + N];
102+
bufferend -= N; r -= N; s -= N;
103+
while (bufferend < N * 2) {
104+
if ((c = fgetc(infile)) == EOF) break;
105+
buffer[bufferend++] = c; textcount++;
106+
}
107+
}
108+
}
109+
flush_bit_buffer();
110+
printf("text: %ld bytes\n", textcount);
111+
printf("code: %ld bytes (%ld%%)\n",
112+
codecount, (codecount * 100) / textcount);
113+
}
114+
115+
int getbit(int n) /* get n bits */
116+
{
117+
int i, x;
118+
static int buf, mask = 0;
119+
120+
x = 0;
121+
for (i = 0; i < n; i++) {
122+
if (mask == 0) {
123+
if ((buf = fgetc(infile)) == EOF) return EOF;
124+
mask = 128;
125+
}
126+
x <<= 1;
127+
if (buf & mask) x++;
128+
mask >>= 1;
129+
}
130+
return x;
131+
}
132+
133+
void decode(void)
134+
{
135+
int i, j, k, r, c;
136+
137+
for (i = 0; i < N - F; i++) buffer[i] = ' ';
138+
r = N - F;
139+
while ((c = getbit(1)) != EOF) {
140+
if (c) {
141+
if ((c = getbit(8)) == EOF) break;
142+
fputc(c, outfile);
143+
buffer[r++] = c; r &= (N - 1);
144+
} else {
145+
if ((i = getbit(EI)) == EOF) break;
146+
if ((j = getbit(EJ)) == EOF) break;
147+
for (k = 0; k <= j + 1; k++) {
148+
c = buffer[(i + k) & (N - 1)];
149+
fputc(c, outfile);
150+
buffer[r++] = c; r &= (N - 1);
151+
}
152+
}
153+
}
154+
}
155+
156+
int main(int argc, char *argv[])
157+
{
158+
int enc;
159+
char *s;
160+
161+
if (argc != 4) {
162+
printf("Usage: lzss e/d infile outfile\n\te = encode\td = decode\n");
163+
return 1;
164+
}
165+
s = argv[1];
166+
if (s[1] == 0 && (*s == 'd' || *s == 'D' || *s == 'e' || *s == 'E'))
167+
enc = (*s == 'e' || *s == 'E');
168+
else {
169+
printf("? %s\n", s); return 1;
170+
}
171+
if ((infile = fopen(argv[2], "rb")) == NULL) {
172+
printf("? %s\n", argv[2]); return 1;
173+
}
174+
if ((outfile = fopen(argv[3], "wb")) == NULL) {
175+
printf("? %s\n", argv[3]); return 1;
176+
}
177+
if (enc) encode(); else decode();
178+
fclose(infile); fclose(outfile);
179+
return 0;
180+
}

0 commit comments

Comments
 (0)