Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/codexlib/lzh/lzh.c
1810 views
1
#pragma prototyped
2
3
/*
4
* lzh decoder
5
*/
6
7
#include <codex.h>
8
9
#define WINBIT_MIN 10
10
#define WINBIT_MAX 16
11
12
#define WINDOW_MIN (1<<WINBIT_MIN)
13
#define WINDOW_MAX (1<<WINBIT_MAX)
14
15
#define MATCH_MAX 256 /* formerly F (not more than UCHAR_MAX + 1) */
16
#define THRESHOLD 3 /* choose optimal value */
17
18
#define NC (UCHAR_MAX+MATCH_MAX-THRESHOLD+2) /* alphbet 0..NC-1 */
19
#define CBIT 9 /* $\lfloor \log_2 NC \rfloor + 1$ */
20
#define USHRT_BIT 16 /* (CHAR_BIT * sizeof(ui2)) */
21
#define NP (WINBIT_MAX + 1)
22
#define NT (USHRT_BIT + 3)
23
#define PBIT 5 /* smallest int s.t. (1<<PBIT))>(WINBIT_MAX+1) */
24
#define TBIT 5 /* smallest int s.t. (1<<TBIT)>NT */
25
#define NPT 0x80
26
#define N1 286 /* alphabet size */
27
#define N2 (2*N1-1) /* # of nodes in Huffman tree */
28
#define EXTRABITS 8 /* >= log2(F-THRESHOLD+258-N1) */
29
#define BUFBITS 16 /* >= log2(MAXBUF) */
30
#define LENFIELD 4 /* bit size of length field for tree output */
31
#define SNP (8*1024/64)
32
#define SNP2 (SNP*2-1)
33
#define N_CHAR (256+60-THRESHOLD+1)
34
#define TREESIZE_C (N_CHAR*2)
35
#define TREESIZE_P (128*2)
36
#define TREESIZE (TREESIZE_C+TREESIZE_P)
37
#define ROOT_C 0
38
#define ROOT_P TREESIZE_C
39
#define MAGIC0 18
40
#define MAGIC5 19
41
42
struct State_s; typedef struct State_s State_t;
43
44
typedef int (*Decode_f)(State_t*);
45
46
typedef uint8_t ui1;
47
typedef uint16_t ui2;
48
typedef uint32_t ui4;
49
50
struct State_s
51
{
52
Codex_t* codex;
53
54
Decode_f init_c;
55
Decode_f init_p;
56
Decode_f decode_c;
57
Decode_f decode_p;
58
59
int method;
60
61
ui1 buf[SF_BUFSIZE];
62
ui1* ip;
63
ui1* ie;
64
65
ui4 window;
66
ui4 count;
67
ui4 nxt;
68
ui4 loc;
69
ui4 cpylen;
70
ui4 cpy;
71
ui4 bitbuf;
72
73
ui2 maxmatch;
74
ui2 bitcount;
75
ui2 blocksize;
76
77
ui1 c_len[NC];
78
ui1 p_len[NPT];
79
ui2 left[2 * NC - 1];
80
ui2 right[2 * NC - 1];
81
ui2 c_table[4096];
82
ui2 p_table[256];
83
84
ui4 n_max;
85
short child[TREESIZE];
86
short parent[TREESIZE];
87
short block[TREESIZE];
88
short edge[TREESIZE];
89
short stock[TREESIZE];
90
short node[TREESIZE / 2];
91
ui2 freq[TREESIZE];
92
ui2 total_p;
93
int avail;
94
int eof;
95
int n1;
96
int most_p;
97
ui4 nextcount;
98
ui4 snp;
99
int flag;
100
int flagcnt;
101
int matchpos;
102
int offset;
103
ui4 pbit;
104
105
ui1 text[1L<<WINBIT_MAX];
106
};
107
108
#define GETCHAR(p) ((p)->ip < (p)->ie ? (int)*(p)->ip++ : fill(p))
109
110
static int
111
fill(State_t* state)
112
{
113
ssize_t r;
114
115
if (state->eof)
116
return 0;
117
if ((r = sfrd(state->codex->sp, state->buf, sizeof(state->buf), &state->codex->sfdisc)) <= 0)
118
{
119
state->eof = 1;
120
return 0;
121
}
122
state->ie = (state->ip = state->buf) + r;
123
return *state->ip++;
124
}
125
126
#define GETBITS(p,n) ((n)<=(p)->bitcount ? ((((p)->bitbuf)>>((p)->bitcount-=(n)))&((1L<<(n))-1)) : getbits(p,n,0))
127
#define PEEKBITS(p,n) ((n)<=(p)->bitcount ? ((((p)->bitbuf)>>((p)->bitcount-(n)))&((1L<<(n))-1)) : getbits(p,n,1))
128
#define SKIPBITS(p,n) ((p)->bitcount-=(n))
129
130
static int
131
getbits(register State_t* state, int n, int peek)
132
{
133
while (state->bitcount < n)
134
{
135
state->bitbuf <<= 8;
136
state->bitbuf |= GETCHAR(state);
137
state->bitcount += 8;
138
}
139
if (peek)
140
{
141
state->eof = 0;
142
return PEEKBITS(state, n);
143
}
144
return GETBITS(state, n);
145
}
146
147
static int
148
make_table(State_t* state, int nchar, ui1* bitlen, int tablebits, ui2* table, ui4 tablesize)
149
{
150
#if 1
151
ui2 count[17]; /* count of bitlen */
152
ui2 weight[17]; /* 0x10000ul >> bitlen */
153
ui2 start[17]; /* first code of bitlen */
154
ui2 total;
155
int i;
156
int j;
157
int k;
158
int l;
159
int m;
160
int n;
161
int available;
162
ui2* p;
163
164
if (state->eof)
165
return -1;
166
available = nchar;
167
168
/* initialize */
169
170
for (i = 1; i <= 16; i++)
171
{
172
count[i] = 0;
173
weight[i] = 1 << (16 - i);
174
}
175
176
/* count */
177
178
for (i = 0; i < nchar; i++)
179
count[bitlen[i]]++;
180
181
/* calculate first code */
182
183
total = 0;
184
for (i = 1; i <= 16; i++)
185
{
186
start[i] = total;
187
total += weight[i] * count[i];
188
}
189
if (total)
190
{
191
if (state->codex->disc->errorf)
192
(*state->codex->disc->errorf)(NiL, state->codex->disc, 2, "%s: invalid compression table", state->codex->meth->name);
193
return -1;
194
}
195
196
/* shift data for make table. */
197
198
m = 16 - tablebits;
199
for (i = 1; i <= tablebits; i++)
200
{
201
start[i] >>= m;
202
weight[i] >>= m;
203
}
204
205
/* initialize */
206
207
j = start[tablebits + 1] >> m;
208
k = 1 << tablebits;
209
if (j != 0)
210
for (i = j; i < k; i++)
211
table[i] = 0;
212
213
/* create table and tree */
214
215
for (j = 0; j < nchar; j++)
216
{
217
k = bitlen[j];
218
if (k == 0)
219
continue;
220
i = start[k];
221
l = i + weight[k];
222
if (k <= tablebits)
223
{
224
if (l > tablesize)
225
{
226
if (state->codex->disc->errorf)
227
(*state->codex->disc->errorf)(NiL, state->codex->disc, 2, "%s: compression table overflow", state->codex->meth->name);
228
return -1;
229
}
230
231
/* code in table */
232
233
while (i < l)
234
table[i++] = j;
235
}
236
else
237
{
238
/* code not in table */
239
240
p = &table[i >> m];
241
i <<= tablebits;
242
n = k - tablebits;
243
244
/* make tree (n length) */
245
246
while (--n >= 0)
247
{
248
if (*p == 0)
249
{
250
state->right[available] = state->left[available] = 0;
251
*p = available++;
252
}
253
if (i & 0x8000)
254
p = &state->right[*p];
255
else
256
p = &state->left[*p];
257
i <<= 1;
258
}
259
*p = j;
260
}
261
start[k] = l;
262
}
263
#else
264
ui2 count[17], weight[17], start[18], *p;
265
ui4 i, k, len, ch, jutbits, avail, nextcode, mask;
266
267
for (i = 1; i <= 16; i++) count[i] = 0;
268
for (i = 0; i < nchar; i++) count[bitlen[i]]++;
269
270
start[1] = 0;
271
for (i = 1; i <= 16; i++)
272
start[i + 1] = start[i] + (count[i] << (16 - i));
273
if (start[17] != (ushort)((unsigned) 1 << 16))
274
{
275
if (state->codex->disc->errorf)
276
(*state->codex->disc->errorf)(NiL, state->codex->disc, 2, "%s: invalid compression table", state->codex->meth->name);
277
return -1;
278
}
279
280
jutbits = 16 - tablebits;
281
for (i = 1; i <= tablebits; i++) {
282
start[i] >>= jutbits;
283
weight[i] = (unsigned) 1 << (tablebits - i);
284
}
285
while (i <= 16) {
286
weight[i] = (unsigned) 1 << (16 - i);
287
i++;
288
}
289
290
i = start[tablebits + 1] >> jutbits;
291
if (i != (ushort)((unsigned) 1 << 16)) {
292
k = 1 << tablebits;
293
while (i != k) table[i++] = 0;
294
}
295
296
avail = nchar;
297
mask = (unsigned) 1 << (15 - tablebits);
298
for (ch = 0; ch < nchar; ch++) {
299
if ((len = bitlen[ch]) == 0) continue;
300
nextcode = start[len] + weight[len];
301
if (len <= tablebits) {
302
if (nextcode > tablesize)
303
{
304
if (state->codex->disc->errorf)
305
(*state->codex->disc->errorf)(NiL, state->codex->disc, 2, "%s: compression table overflow", state->codex->meth->name);
306
return -1;
307
}
308
for (i = start[len]; i < nextcode; i++) table[i] = ch;
309
} else {
310
k = start[len];
311
p = &table[k >> jutbits];
312
i = len - tablebits;
313
while (i != 0) {
314
if (*p == 0) {
315
state->right[avail] = state->left[avail] = 0;
316
*p = avail++;
317
}
318
if (k & mask) p = &state->right[*p];
319
else p = &state->left[*p];
320
k <<= 1; i--;
321
}
322
*p = ch;
323
}
324
start[len] = nextcode;
325
}
326
#endif
327
return 0;
328
}
329
330
static int
331
get_p_len(State_t* state, int k, int nbit, int i_special)
332
{
333
int i;
334
int c;
335
int n;
336
337
if (!(n = GETBITS(state, nbit)))
338
{
339
c = GETBITS(state, nbit);
340
for (i = 0; i < elementsof(state->p_table); i++)
341
state->p_table[i] = c;
342
for (i = 0; i < k; i++)
343
state->p_len[i] = 0;
344
}
345
else
346
{
347
i = 0;
348
while (i < n)
349
{
350
if ((c = GETBITS(state, 3)) == 7)
351
while (GETBITS(state, 1))
352
c++;
353
state->p_len[i++] = c;
354
if (i == i_special)
355
{
356
c = GETBITS(state, 2);
357
while (--c >= 0)
358
state->p_len[i++] = 0;
359
}
360
}
361
while (i < k)
362
state->p_len[i++] = 0;
363
if (make_table(state, k, state->p_len, 8, state->p_table, elementsof(state->p_table)))
364
return -1;
365
}
366
return 0;
367
}
368
369
static int
370
get_c_len(State_t* state)
371
{
372
int i;
373
int c;
374
int n;
375
ui2 b;
376
377
n = GETBITS(state, CBIT);
378
if (state->eof)
379
return -1;
380
if (n == 0)
381
{
382
c = GETBITS(state, CBIT);
383
for (i = 0; i < elementsof(state->c_table); i++)
384
state->c_table[i] = c;
385
for (i = 0; i < elementsof(state->c_len); i++)
386
state->c_len[i] = 0;
387
}
388
else
389
{
390
i = 0;
391
while (i < n)
392
{
393
b = PEEKBITS(state, 16);
394
c = state->p_table[b >> 8];
395
while (c >= NT)
396
c = ((b <<= 1) & 0x100) ? state->right[c] : state->left[c];
397
SKIPBITS(state, state->p_len[c]);
398
if (c <= 2)
399
{
400
if (c == 0)
401
c = 1;
402
else if (c == 1)
403
c = GETBITS(state, 4) + 3;
404
else
405
c = GETBITS(state, CBIT) + 20;
406
while (--c >= 0)
407
state->c_len[i++] = 0;
408
}
409
else
410
state->c_len[i++] = c - 2;
411
}
412
while (i < NC)
413
state->c_len[i++] = 0;
414
if (make_table(state, NC, state->c_len, 12, state->c_table, elementsof(state->c_table)))
415
return -1;
416
}
417
return 0;
418
}
419
420
static void
421
reconst(State_t* state, int start, int end)
422
{
423
int i;
424
int j;
425
int k;
426
int l;
427
int b;
428
ui4 f;
429
ui4 g;
430
431
b = 0;
432
for (i = j = start; i < end; i++)
433
{
434
if ((k = state->child[i]) < 0)
435
{
436
state->freq[j] = (state->freq[i] + 1) / 2;
437
state->child[j] = k;
438
j++;
439
}
440
if (state->edge[b = state->block[i]] == i)
441
state->stock[--state->avail] = b;
442
}
443
j--;
444
i = end - 1;
445
l = end - 2;
446
while (i >= start)
447
{
448
while (i >= l)
449
{
450
state->freq[i] = state->freq[j];
451
state->child[i] = state->child[j];
452
i--;
453
j--;
454
}
455
f = state->freq[l] + state->freq[l + 1];
456
for (k = start; f < state->freq[k]; k++)
457
;
458
while (j >= k)
459
{
460
state->freq[i] = state->freq[j];
461
state->child[i] = state->child[j];
462
i--;
463
j--;
464
}
465
state->freq[i] = f;
466
state->child[i] = l + 1;
467
i--;
468
l -= 2;
469
}
470
f = 0;
471
for (i = start; i < end; i++)
472
{
473
if ((j = state->child[i]) < 0)
474
state->node[~j] = i;
475
else
476
state->parent[j] = state->parent[j - 1] = i;
477
if ((g = state->freq[i]) == f)
478
state->block[i] = b;
479
else
480
{
481
state->edge[b = state->block[i] = state->stock[state->avail++]] = i;
482
f = g;
483
}
484
}
485
}
486
487
static int
488
swap_inc(State_t* state, int p)
489
{
490
int b;
491
int q;
492
int r;
493
int s;
494
495
b = state->block[p];
496
if ((q = state->edge[b]) != p)
497
{
498
r = state->child[p];
499
s = state->child[q];
500
state->child[p] = s;
501
state->child[q] = r;
502
if (r >= 0)
503
state->parent[r] = state->parent[r - 1] = q;
504
else
505
state->node[~r] = q;
506
if (s >= 0)
507
state->parent[s] = state->parent[s - 1] = p;
508
else
509
state->node[~s] = p;
510
p = q;
511
}
512
else if (b != state->block[p + 1])
513
{
514
if (++state->freq[p] == state->freq[p - 1])
515
{
516
state->stock[--state->avail] = b;
517
state->block[p] = state->block[p - 1];
518
}
519
return state->parent[p];
520
}
521
state->edge[b]++;
522
if (++state->freq[p] == state->freq[p - 1])
523
state->block[p] = state->block[p - 1];
524
else
525
state->edge[state->block[p] = state->stock[state->avail++]] = p;
526
return state->parent[p];
527
}
528
529
static void
530
update_c(State_t* state, int p)
531
{
532
int q;
533
534
if (state->freq[ROOT_C] == 0x8000)
535
reconst(state, 0, state->n_max * 2 - 1);
536
state->freq[ROOT_C]++;
537
q = state->node[p];
538
do
539
{
540
q = swap_inc(state, q);
541
} while (q != ROOT_C);
542
}
543
544
static void
545
update_p(State_t* state, int p)
546
{
547
int q;
548
549
if (state->total_p == 0x8000)
550
{
551
reconst(state, ROOT_P, state->most_p + 1);
552
state->total_p = state->freq[ROOT_P];
553
state->freq[ROOT_P] = 0xffff;
554
}
555
q = state->node[p + N_CHAR];
556
while (q != ROOT_P)
557
{
558
q = swap_inc(state, q);
559
}
560
state->total_p++;
561
}
562
563
static void
564
make_new_node(State_t* state, int p)
565
{
566
int q;
567
int r;
568
569
r = state->most_p + 1;
570
q = r + 1;
571
state->node[~(state->child[r] = state->child[state->most_p])] = r;
572
state->child[q] = ~(p + N_CHAR);
573
state->child[state->most_p] = q;
574
state->freq[r] = state->freq[state->most_p];
575
state->freq[q] = 0;
576
state->block[r] = state->block[state->most_p];
577
if (state->most_p == ROOT_P)
578
{
579
state->freq[ROOT_P] = 0xffff;
580
state->edge[state->block[ROOT_P]]++;
581
}
582
state->parent[r] = state->parent[q] = state->most_p;
583
state->edge[state->block[q] = state->stock[state->avail++]]
584
= state->node[p + N_CHAR] = state->most_p = q;
585
update_p(state, p);
586
}
587
588
static void
589
ready_made(State_t* state, ui1* tbl)
590
{
591
int i;
592
int j;
593
ui4 code;
594
ui4 weight;
595
596
j = *tbl++;
597
weight = 1 << (16 - j);
598
code = 0;
599
for (i = 0; i < state->snp; i++)
600
{
601
while (*tbl == i)
602
{
603
j++;
604
tbl++;
605
weight >>= 1;
606
}
607
state->p_len[i] = j;
608
code += weight;
609
}
610
}
611
612
static int
613
read_tree_c(State_t* state)
614
{
615
int i;
616
int c;
617
618
i = 0;
619
while (i < N1)
620
{
621
if (GETBITS(state, 1))
622
state->c_len[i] = GETBITS(state, LENFIELD) + 1;
623
else
624
state->c_len[i] = 0;
625
if (++i == 3 && state->c_len[0] == 1 && state->c_len[1] == 1 && state->c_len[2] == 1)
626
{
627
c = GETBITS(state, CBIT);
628
for (i = 0; i < N1; i++)
629
state->c_len[i] = 0;
630
for (i = 0; i < 4096; i++)
631
state->c_table[i] = c;
632
return 0;
633
}
634
}
635
return make_table(state, N1, state->c_len, 12, state->c_table, elementsof(state->c_table));
636
}
637
638
static void
639
read_tree_p(State_t* state)
640
{
641
int i;
642
int c;
643
644
i = 0;
645
while (i < SNP)
646
{
647
state->p_len[i] = GETBITS(state, LENFIELD);
648
if (++i == 3 && state->p_len[0] == 1 && state->p_len[1] == 1 && state->p_len[2] == 1)
649
{
650
c = GETBITS(state, WINBIT_MAX - 6);
651
for (i = 0; i < SNP; i++)
652
state->c_len[i] = 0;
653
for (i = 0; i < 256; i++)
654
state->c_table[i] = c;
655
return;
656
}
657
}
658
}
659
660
static int
661
set_c_d0(State_t* state, ui4 n_max, ui4 maxmatch, ui4 snp)
662
{
663
int i;
664
int j;
665
int f;
666
667
state->n_max = n_max;
668
state->maxmatch = maxmatch;
669
state->snp = snp;
670
state->n1 = (state->n_max >= 256 + state->maxmatch - THRESHOLD + 1)
671
? 512 : state->n_max - 1;
672
for (i = 0; i < TREESIZE_C; i++)
673
{
674
state->stock[i] = i;
675
state->block[i] = 0;
676
}
677
for (i = 0, j = state->n_max * 2 - 2; i < state->n_max; i++, j--)
678
{
679
state->freq[j] = 1;
680
state->child[j] = ~i;
681
state->node[i] = j;
682
state->block[j] = 1;
683
}
684
state->avail = 2;
685
state->edge[1] = state->n_max - 1;
686
i = state->n_max * 2 - 2;
687
while (j >= 0)
688
{
689
f = state->freq[j] = state->freq[i] + state->freq[i - 1];
690
state->child[j] = i;
691
state->parent[i] = state->parent[i - 1] = j;
692
if (f == state->freq[j + 1])
693
state->edge[state->block[j] = state->block[j + 1]] = j;
694
else
695
state->edge[state->block[j] = state->stock[state->avail++]] = j;
696
i -= 2;
697
j--;
698
}
699
return 0;
700
}
701
702
static ui1 table_fix[16] =
703
{
704
3, 0x01, 0x04, 0x0c, 0x18, 0x30
705
};
706
707
static int
708
init_c_d0(State_t* state)
709
{
710
set_c_d0(state, 314, 60, 1 << (12 - 6));
711
ready_made(state, table_fix);
712
return make_table(state, state->snp, state->p_len, 8, state->p_table, elementsof(state->p_table));
713
}
714
715
static int
716
decode_c_d0(State_t* state)
717
{
718
int c;
719
720
c = state->child[ROOT_C];
721
while (c)
722
c = state->child[c - GETBITS(state, 1)];
723
c = ~c;
724
update_c(state, c);
725
if (c == state->n1)
726
c += GETBITS(state, 8);
727
return c;
728
}
729
730
static int
731
init_p_d0(State_t* state)
732
{
733
state->freq[ROOT_P] = 1;
734
state->child[ROOT_P] = ~(N_CHAR);
735
state->node[N_CHAR] = ROOT_P;
736
state->edge[state->block[ROOT_P] = state->stock[state->avail++]] = ROOT_P;
737
state->most_p = ROOT_P;
738
state->total_p = 0;
739
state->nextcount = 64;
740
return 0;
741
}
742
743
static int
744
decode_p_d0(State_t* state)
745
{
746
int c;
747
748
while (state->count > state->nextcount)
749
{
750
make_new_node(state, (int)(state->nextcount / 64));
751
if ((state->nextcount += 64) >= state->window)
752
state->nextcount = 0xffffffff;
753
}
754
c = state->child[ROOT_P];
755
while (c)
756
c = state->child[c - GETBITS(state, 1)];
757
c = (~c) - N_CHAR;
758
update_p(state, c);
759
return (c << 6) + GETBITS(state, 6);
760
}
761
762
static int
763
init_c_d1(State_t* state)
764
{
765
return set_c_d0(state, 286, MATCH_MAX, 1 << (12 - 6));
766
}
767
768
static int
769
decode_start_fix(State_t* state)
770
{
771
state->n_max = 314;
772
state->maxmatch = 60;
773
state->snp = 1 << (12 - 6);
774
#if 0
775
start_c_dyn(state);
776
#endif
777
ready_made(state, table_fix);
778
return make_table(state, state->snp, state->p_len, 8, state->p_table, elementsof(state->p_table));
779
}
780
781
static int
782
init_c_s0(State_t* state)
783
{
784
state->n_max = 286;
785
state->maxmatch = MATCH_MAX;
786
state->snp = 1 << (WINBIT_MAX - 6);
787
state->blocksize = 0;
788
return 0;
789
}
790
791
static ui1 table_s0[16] =
792
{
793
2, 0x01, 0x01, 0x03, 0x06, 0x0D, 0x1F, 0x4E
794
};
795
796
static int
797
decode_c_s0(State_t* state)
798
{
799
int j;
800
801
if (state->blocksize == 0) /* read block head */
802
{
803
/* read block blocksize */
804
state->blocksize = GETBITS(state, BUFBITS);
805
if (read_tree_c(state))
806
return -1;
807
if (GETBITS(state, 1))
808
read_tree_p(state);
809
else
810
ready_made(state, table_s0);
811
if (make_table(state, SNP, state->p_len, 8, state->p_table, elementsof(state->p_table)))
812
return 0;
813
}
814
state->blocksize--;
815
j = state->c_table[GETBITS(state, 4)];
816
while (j >= N1)
817
{
818
if (GETBITS(state, 1))
819
j = state->right[j];
820
else
821
j = state->left [j];
822
}
823
if (j == N1 - 1)
824
j += GETBITS(state, EXTRABITS);
825
return j;
826
}
827
828
static int
829
init_p_s0(State_t* state)
830
{
831
return 0;
832
}
833
834
static int
835
decode_p_s0(State_t* state)
836
{
837
int j;
838
839
j = state->p_table[GETBITS(state, 8)];
840
if (j >= state->snp)
841
{
842
do
843
{
844
if (GETBITS(state, 1))
845
j = state->right[j];
846
else
847
j = state->left[j];
848
} while (j >= state->snp);
849
}
850
return (j << 6) + GETBITS(state, 6);
851
}
852
853
static int
854
init_c_s1(State_t* state)
855
{
856
if (state->window <= (14 * 1024))
857
{
858
state->snp = 14;
859
state->pbit = 4;
860
}
861
else
862
{
863
state->snp = 16;
864
state->pbit = 5;
865
}
866
state->blocksize = 0;
867
return 0;
868
}
869
870
static int
871
decode_c_s1(State_t* state)
872
{
873
ui4 j;
874
ui2 b;
875
876
if (!state->blocksize && (!(state->blocksize = GETBITS(state, 16)) || get_p_len(state, NT, TBIT, 3) || get_c_len(state) || get_p_len(state, state->snp, state->pbit, -1)))
877
return -1;
878
state->blocksize--;
879
b = PEEKBITS(state, 16);
880
j = state->c_table[b >> 4];
881
while (j >= NC)
882
j = ((b <<= 1) & 0x10) ? state->right[j] : state->left[j];
883
SKIPBITS(state, state->c_len[j]);
884
return state->eof ? -1 : j;
885
}
886
887
static int
888
init_p_s1(State_t* state)
889
{
890
return 0;
891
}
892
893
static int
894
decode_p_s1(State_t* state)
895
{
896
ui4 j;
897
ui2 b;
898
899
b = PEEKBITS(state, 16);
900
j = state->p_table[b >> 8];
901
while (j >= state->snp)
902
j = ((b <<= 1) & 0x100) ? state->right[j] : state->left[j];
903
SKIPBITS(state, state->p_len[j]);
904
if (j)
905
j = (1 << (j - 1)) + GETBITS(state, j - 1);
906
return j;
907
}
908
909
static int
910
init_c_s2(State_t* state)
911
{
912
state->offset = 0x100 - 2;
913
return 0;
914
}
915
916
static int
917
decode_c_s2(State_t* state)
918
{
919
if (GETBITS(state, 1))
920
return GETBITS(state, 8);
921
state->matchpos = GETBITS(state, 11);
922
return GETBITS(state, 4) + 0x100;
923
}
924
925
static int
926
init_p_s2(State_t* state)
927
{
928
return 0;
929
}
930
931
static int
932
decode_p_s2(State_t* state)
933
{
934
return (state->loc - state->matchpos - MAGIC0) & 0x7ff;
935
}
936
937
static int
938
init_c_s3(State_t* state)
939
{
940
int i;
941
942
state->flagcnt = 0;
943
for (i = 0; i < 256; i++)
944
memset(&state->text[i * 13 + 18], i, 13);
945
for (i = 0; i < 256; i++)
946
state->text[256 * 13 + 18 + i] = i;
947
for (i = 0; i < 256; i++)
948
state->text[256 * 13 + 256 + 18 + i] = 255 - i;
949
memset(&state->text[256 * 13 + 512 + 18], 0, 128);
950
memset(&state->text[256 * 13 + 512 + 128 + 18], ' ', 128 - 18);
951
return 0;
952
}
953
954
static int
955
decode_c_s3(State_t* state)
956
{
957
int c;
958
959
if (state->flagcnt == 0)
960
{
961
state->flagcnt = 8;
962
state->flag = GETCHAR(state);
963
}
964
state->flagcnt--;
965
c = GETCHAR(state);
966
if ((state->flag & 1) == 0)
967
{
968
state->matchpos = c;
969
c = GETCHAR(state);
970
state->matchpos += (c & 0xf0) << 4;
971
c &= 0x0f;
972
c += 0x100;
973
}
974
state->flag >>= 1;
975
return c;
976
}
977
978
static int
979
init_p_s3(State_t* state)
980
{
981
return 0;
982
}
983
984
static int
985
decode_p_s3(State_t* state)
986
{
987
return (state->loc - state->matchpos - MAGIC5) & 0xfff;
988
}
989
990
#define N_D 2
991
#define N_S 4
992
993
static Decode_f decoders[] =
994
{
995
init_c_d0, decode_c_d0,
996
init_c_d1, decode_c_d0,
997
init_c_s0, decode_c_s0,
998
init_c_s1, decode_c_s1,
999
init_c_s2, decode_c_s2,
1000
init_c_s3, decode_c_s3,
1001
1002
init_p_d0, decode_p_d0,
1003
init_p_d0, decode_p_d0,
1004
init_p_s0, decode_p_s0,
1005
init_p_s1, decode_p_s1,
1006
init_p_s2, decode_p_s2,
1007
init_p_s3, decode_p_s3,
1008
};
1009
1010
static int
1011
lzh_decoder(char* s, int p, Codexdisc_t* disc)
1012
{
1013
register int i;
1014
register int n;
1015
1016
if (!(n = *s++))
1017
{
1018
if (disc->errorf)
1019
(*disc->errorf)(NiL, disc, 2, "decoder name expected");
1020
return -1;
1021
}
1022
if (n == 'd')
1023
i = 0;
1024
else if (n == 's')
1025
i = 2 * N_D;
1026
else
1027
{
1028
if (disc->errorf)
1029
(*disc->errorf)(NiL, disc, 2, "%s: d[ynamic] or s[tatic] decoder name expected", s - 1);
1030
return -1;
1031
}
1032
i += 2 * (int)strtol(s, &s, 10);
1033
if (i < 0 || i >= (elementsof(decoders) / 2))
1034
{
1035
if (disc->errorf)
1036
(*disc->errorf)(NiL, disc, 2, "%c%d: unknown decoder name", n, i);
1037
return -1;
1038
}
1039
if (p)
1040
i += 2 * (N_D + N_S);
1041
return i;
1042
}
1043
1044
static char* const arc[][4] =
1045
{
1046
{ "lh0" },
1047
{ "lh1", "4k", "d0", "s0" },
1048
{ "lh2", "8k", "d1" },
1049
{ "lh3", "8k", "s0" },
1050
{ "lh4", "4k", "s1" },
1051
{ "lh5", "8k", "s1" },
1052
{ "lhd" },
1053
{ "lhj", "26624","s1" },
1054
{ "lz4" },
1055
{ "lz5", "4k", "s3" },
1056
{ "lz6", "32k", "s1" },
1057
{ "lz7", "64k", "s1" },
1058
{ "lzs", "2k", "s2" },
1059
};
1060
1061
static int
1062
lzh_options(Codexmeth_t* meth, Sfio_t* sp)
1063
{
1064
register int i;
1065
register int j;
1066
1067
for (i = 0; i < elementsof(arc); i++)
1068
{
1069
sfprintf(sp, "[+%s?Equivalent to \b", arc[i][0]);
1070
if (!arc[i][1])
1071
sfprintf(sp, "copy");
1072
else
1073
{
1074
sfprintf(sp, "lzh");
1075
for (j = 1; j < elementsof(arc[i]) && arc[i][j]; j++)
1076
sfprintf(sp, "-%s", arc[i][j]);
1077
}
1078
sfprintf(sp, "\b.]");
1079
}
1080
return 0;
1081
}
1082
1083
static int
1084
lzh_open(Codex_t* p, char* const args[], Codexnum_t flags)
1085
{
1086
register State_t* state;
1087
const char* name;
1088
char* s;
1089
int i;
1090
int j;
1091
int w;
1092
1093
name = args[0];
1094
args += 2;
1095
if (!args[0])
1096
{
1097
if (p->disc->errorf)
1098
(*p->disc->errorf)(NiL, p->disc, 2, "%s: method parameter expected", name);
1099
return -1;
1100
}
1101
if (!args[1])
1102
{
1103
for (i = 0;; i++)
1104
{
1105
if (i >= elementsof(arc))
1106
{
1107
if (p->disc->errorf)
1108
(*p->disc->errorf)(NiL, p->disc, 2, "%s: unknown method", name);
1109
return 0;
1110
}
1111
if (streq(args[0], arc[i][0]))
1112
{
1113
args = arc[i] + 1;
1114
break;
1115
}
1116
}
1117
if (!args[0])
1118
{
1119
p->meth = 0;
1120
return 0;
1121
}
1122
}
1123
if ((w = strton(args[0], &s, NiL, 0)) < WINDOW_MIN || w > WINDOW_MAX || *s)
1124
{
1125
if (p->disc->errorf)
1126
(*p->disc->errorf)(NiL, p->disc, 2, "%s: window size must be in [%d..%d]", args[0], WINDOW_MIN, WINDOW_MAX);
1127
return -1;
1128
}
1129
if (!args[1])
1130
{
1131
if (p->disc->errorf)
1132
(*p->disc->errorf)(NiL, p->disc, 2, "%s: at least one coder must be specified", name);
1133
return -1;
1134
}
1135
if ((i = lzh_decoder(args[1], 0, p->disc)) < 0 || (j = lzh_decoder(args[2] ? args[2] : args[1], 1, p->disc)) < 0)
1136
return -1;
1137
if (!(state = newof(0, State_t, 1, w - 1)))
1138
{
1139
if (p->disc->errorf)
1140
(*p->disc->errorf)(NiL, p->disc, 2, "out of space");
1141
return -1;
1142
}
1143
state->window = w;
1144
state->init_c = decoders[i];
1145
state->decode_c = decoders[i + 1];
1146
state->init_p = decoders[j];
1147
state->decode_p = decoders[j + 1];
1148
state->codex = p;
1149
p->data = state;
1150
return 0;
1151
}
1152
1153
static int
1154
lzh_init(Codex_t* p)
1155
{
1156
register State_t* state = (State_t*)p->data;
1157
1158
memset(&state->count, 0, sizeof(*state) - offsetof(State_t, count));
1159
state->ip = state->ie = 0;
1160
state->bitcount = 0;
1161
state->cpylen = 0;
1162
state->eof = 0;
1163
state->offset = 0x100 - 3;
1164
return ((*state->init_c)(state) || (*state->init_p)(state)) ? -1 : 0;
1165
}
1166
1167
static ssize_t
1168
lzh_read(Sfio_t* sp, void* buf, size_t n, Sfdisc_t* disc)
1169
{
1170
register State_t* state = (State_t*)CODEX(disc)->data;
1171
register char* s = (char*)buf;
1172
register char* e = s + n;
1173
int c;
1174
int i;
1175
ui4 j;
1176
1177
if (n == 0 || state->eof)
1178
return 0;
1179
while (state->cpylen)
1180
{
1181
*s++ = state->text[state->loc++] = state->text[state->cpy++];
1182
if (state->loc >= state->window)
1183
state->loc = 0;
1184
if (state->cpy >= state->window)
1185
state->cpy = 0;
1186
state->cpylen--;
1187
if (s >= e)
1188
return s - (char*)buf;
1189
}
1190
for (;;)
1191
{
1192
c = (*state->decode_c)(state);
1193
if (c < 0)
1194
break;
1195
else if (c <= UCHAR_MAX)
1196
{
1197
state->count++;
1198
*s++ = state->text[state->loc++] = c;
1199
if (state->loc >= state->window)
1200
state->loc = 0;
1201
if (s >= e)
1202
break;
1203
}
1204
else
1205
{
1206
j = c - state->offset;
1207
i = state->loc - (*state->decode_p)(state) - 1;
1208
if (i < 0)
1209
i += state->window;
1210
state->count += j;
1211
while (j--)
1212
{
1213
*s++ = state->text[state->loc++] = state->text[i++];
1214
if (i >= state->window)
1215
i = 0;
1216
if (state->loc >= state->window)
1217
state->loc = 0;
1218
if (s >= e)
1219
{
1220
if (state->cpylen = j)
1221
state->cpy = i;
1222
return s - (char*)buf;
1223
}
1224
}
1225
}
1226
}
1227
return (n = s - (char*)buf) ? n : -1;
1228
}
1229
1230
Codexmeth_t codex_lzh =
1231
{
1232
"lzh",
1233
"lzh compression. The options are ordered. A single option alias"
1234
" (example \blzh-lh5\b) or \awindow-ccode\a[-\apcode\a]"
1235
" (example \blzh-4k-d0-s0\b) are accepted. \apcode\a defaults to"
1236
" \accode\a if omitted.",
1237
"[+window?Window size <= 64k.]:[size]"
1238
"[+coding?\accode\a or \apcode\a coding method { d0 s0 s1 s2 s3 }.]"
1239
"[+(version)?codex-lzh 1998-11-11]",
1240
CODEX_DECODE|CODEX_COMPRESS,
1241
lzh_options,
1242
0,
1243
lzh_open,
1244
0,
1245
lzh_init,
1246
0,
1247
lzh_read,
1248
0,
1249
0,
1250
0,
1251
0,
1252
0,
1253
0,
1254
CODEXNEXT(lzh)
1255
};
1256
1257
CODEXLIB(lzh)
1258
1259