Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libz/sfdclzw.c
1808 views
1
#pragma prototyped
2
3
/*
4
* compress/zcat discipline snarfed from BSD zopen by
5
* Glenn Fowler
6
* AT&T Research
7
* 1999-06-23
8
*/
9
10
/*-
11
* Copyright (c) 1985, 1986, 1992, 1993
12
* The Regents of the University of California. All rights reserved.
13
*
14
* This code is derived from software contributed to Berkeley by
15
* Diomidis Spinellis and James A. Woods, derived from original
16
* work by Spencer Thomas and Joseph Orost.
17
*
18
* Redistribution and use in source and binary forms, with or without
19
* modification, are permitted provided that the following conditions
20
* are met:
21
* 1. Redistributions of source code must retain the above copyright
22
* notice, this list of conditions and the following disclaimer.
23
* 2. Redistributions in binary form must reproduce the above copyright
24
* notice, this list of conditions and the following disclaimer in the
25
* documentation and/or other materials provided with the distribution.
26
* 3. Neither the name of the University nor the names of its contributors
27
* may be used to endorse or promote products derived from this software
28
* without specific prior written permission.
29
*
30
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40
* SUCH DAMAGE.
41
*/
42
43
/*-
44
* fcompress.c - File compression ala IEEE Computer, June 1984.
45
*
46
* Compress authors:
47
* Spencer W. Thomas (decvax!utah-cs!thomas)
48
* Jim McKie (decvax!mcvax!jim)
49
* Steve Davies (decvax!vax135!petsd!peora!srd)
50
* Ken Turkowski (decvax!decwrl!turtlevax!ken)
51
* James A. Woods (decvax!ihnp4!ames!jaw)
52
* Joe Orost (decvax!vax135!petsd!joe)
53
*
54
* Cleaned up and converted to library returning I/O streams by
55
* Diomidis Spinellis <[email protected]>.
56
*/
57
58
#include <sfio_t.h>
59
#include <ast.h>
60
#include <sfdcgzip.h>
61
62
#define BITS 16 /* Default bits. */
63
#define HSIZE 69001 /* 95% occupancy */
64
65
/* A code_int must be able to hold 2**BITS values of type int, and also -1. */
66
typedef long code_int;
67
typedef long count_int;
68
69
typedef u_char char_type;
70
static char_type magic_header[] =
71
{ 0x1f, 0x9d };
72
73
#define BIT_MASK 0x1f /* Defines for third byte of header. */
74
#define BLOCK_MASK 0x80
75
76
/*
77
* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
78
* a fourth header byte (for expansion).
79
*/
80
#define INIT_BITS 9 /* Initial number of bits/code. */
81
82
#define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
83
84
typedef struct s_zstate {
85
Sfdisc_t disc; /* sfio discipline */
86
enum {
87
S_START, S_MIDDLE, S_EOF
88
} zs_state; /* State of computation */
89
int zs_n_bits; /* Number of bits/code. */
90
int zs_maxbits; /* User settable max # bits/code. */
91
code_int zs_maxcode; /* Maximum code, given n_bits. */
92
code_int zs_maxmaxcode; /* Should NEVER generate this code. */
93
count_int zs_htab [HSIZE];
94
u_short zs_codetab [HSIZE];
95
code_int zs_hsize; /* For dynamic table sizing. */
96
code_int zs_free_ent; /* First unused entry. */
97
/*
98
* Block compression parameters -- after all codes are used up,
99
* and compression rate changes, start over.
100
*/
101
int zs_block_compress;
102
int zs_clear_flg;
103
long zs_ratio;
104
count_int zs_checkpoint;
105
int zs_offset;
106
long zs_in_count; /* Length of input. */
107
long zs_bytes_out; /* Length of compressed output. */
108
long zs_out_count; /* # of codes output (for debugging). */
109
char_type zs_buf[BITS];
110
union {
111
struct {
112
long zs_fcode;
113
code_int zs_ent;
114
code_int zs_hsize_reg;
115
int zs_hshift;
116
} w; /* Write paramenters */
117
struct {
118
char_type *zs_stackp;
119
int zs_finchar;
120
code_int zs_code, zs_oldcode, zs_incode;
121
int zs_roffset, zs_size;
122
char_type zs_gbuf[BITS];
123
} r; /* Read parameters */
124
} u;
125
} LZW_t;
126
127
/* Definitions to retain old variable names */
128
#define state zs->zs_state
129
#define n_bits zs->zs_n_bits
130
#define maxbits zs->zs_maxbits
131
#define maxcode zs->zs_maxcode
132
#define maxmaxcode zs->zs_maxmaxcode
133
#define htab zs->zs_htab
134
#define codetab zs->zs_codetab
135
#define hsize zs->zs_hsize
136
#define free_ent zs->zs_free_ent
137
#define block_compress zs->zs_block_compress
138
#define clear_flg zs->zs_clear_flg
139
#define ratio zs->zs_ratio
140
#define checkpoint zs->zs_checkpoint
141
#define offset zs->zs_offset
142
#define in_count zs->zs_in_count
143
#define bytes_out zs->zs_bytes_out
144
#define out_count zs->zs_out_count
145
#define buf zs->zs_buf
146
#define fcode zs->u.w.zs_fcode
147
#define hsize_reg zs->u.w.zs_hsize_reg
148
#define ent zs->u.w.zs_ent
149
#define hshift zs->u.w.zs_hshift
150
#define stackp zs->u.r.zs_stackp
151
#define finchar zs->u.r.zs_finchar
152
#define code zs->u.r.zs_code
153
#define oldcode zs->u.r.zs_oldcode
154
#define incode zs->u.r.zs_incode
155
#define roffset zs->u.r.zs_roffset
156
#define size zs->u.r.zs_size
157
#define gbuf zs->u.r.zs_gbuf
158
159
/*
160
* To save much memory, we overlay the table used by compress() with those
161
* used by decompress(). The tab_prefix table is the same size and type as
162
* the codetab. The tab_suffix table needs 2**BITS characters. We get this
163
* from the beginning of htab. The output stack uses the rest of htab, and
164
* contains characters. There is plenty of room for any possible stack
165
* (stack used to be 8000 characters).
166
*/
167
168
#define htabof(i) htab[i]
169
#define codetabof(i) codetab[i]
170
171
#define tab_prefixof(i) codetabof(i)
172
#define tab_suffixof(i) ((char_type *)(htab))[i]
173
#define de_stack ((char_type *)&tab_suffixof(1 << BITS))
174
175
#define CHECK_GAP 10000 /* Ratio check interval. */
176
177
/*
178
* the next two codes should not be changed lightly, as they must not
179
* lie within the contiguous general code space.
180
*/
181
#define FIRST 257 /* First free entry. */
182
#define CLEAR 256 /* Table clear output code. */
183
184
/*-
185
* Algorithm from "A Technique for High Performance Data Compression",
186
* Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
187
*
188
* Algorithm:
189
* Modified Lempel-Ziv method (LZW). Basically finds common
190
* substrings and replaces them with a variable size code. This is
191
* deterministic, and can be done on the fly. Thus, the decompression
192
* procedure needs no input table, but tracks the way the table was built.
193
*/
194
195
/*-
196
* Output the given code.
197
* Inputs:
198
* code: A n_bits-bit integer. If == -1, then EOF. This assumes
199
* that n_bits =< (long)wordsize - 1.
200
* Outputs:
201
* Outputs code to the file.
202
* Assumptions:
203
* Chars are 8 bits long.
204
* Algorithm:
205
* Maintain a BITS character long buffer (so that 8 codes will
206
* fit in it exactly). Use the VAX insv instruction to insert each
207
* code in turn. When the buffer fills up empty it and start over.
208
*/
209
210
static char_type lmask[9] =
211
{0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
212
static char_type rmask[9] =
213
{0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
214
215
static int
216
output(LZW_t* zs, Sfio_t* f, code_int ocode, Sfdisc_t* dp)
217
{
218
register int bits, r_off;
219
register char_type *bp;
220
221
r_off = offset;
222
bits = n_bits;
223
bp = buf;
224
if (ocode >= 0) {
225
/* Get to the first byte. */
226
bp += (r_off >> 3);
227
r_off &= 7;
228
/*
229
* Since ocode is always >= 8 bits, only need to mask the first
230
* hunk on the left.
231
*/
232
*bp = (*bp & rmask[r_off]) | ((ocode << r_off) & lmask[r_off]);
233
bp++;
234
bits -= (8 - r_off);
235
ocode >>= 8 - r_off;
236
/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
237
if (bits >= 8) {
238
*bp++ = ocode;
239
ocode >>= 8;
240
bits -= 8;
241
}
242
/* Last bits. */
243
if (bits)
244
*bp = ocode;
245
offset += n_bits;
246
if (offset == (n_bits << 3)) {
247
bp = buf;
248
bits = n_bits;
249
bytes_out += bits;
250
if (sfwr(f, bp, bits, dp) != bits)
251
return (-1);
252
bp += bits;
253
bits = 0;
254
offset = 0;
255
}
256
/*
257
* If the next entry is going to be too big for the ocode size,
258
* then increase it, if possible.
259
*/
260
if (free_ent > maxcode || (clear_flg > 0)) {
261
/*
262
* Write the whole buffer, because the input side won't
263
* discover the size increase until after it has read it.
264
*/
265
if (offset > 0) {
266
if (sfwr(f, buf, n_bits, dp) != n_bits)
267
return (-1);
268
bytes_out += n_bits;
269
}
270
offset = 0;
271
272
if (clear_flg) {
273
maxcode = MAXCODE(n_bits = INIT_BITS);
274
clear_flg = 0;
275
} else {
276
n_bits++;
277
if (n_bits == maxbits)
278
maxcode = maxmaxcode;
279
else
280
maxcode = MAXCODE(n_bits);
281
}
282
}
283
} else {
284
/* At EOF, write the rest of the buffer. */
285
if (offset > 0) {
286
offset = (offset + 7) / 8;
287
if (sfwr(f, buf, offset, dp) != offset)
288
return (-1);
289
bytes_out += offset;
290
}
291
offset = 0;
292
}
293
return (0);
294
}
295
296
/*-
297
* Read one code from the standard input. If EOF, return -1.
298
* Inputs:
299
* stdin
300
* Outputs:
301
* code or -1 is returned.
302
*/
303
static code_int
304
getcode(LZW_t* zs, Sfio_t* f, Sfdisc_t* dp)
305
{
306
register code_int gcode;
307
register int r_off, bits;
308
register char_type *bp;
309
310
bp = gbuf;
311
if (clear_flg > 0 || roffset >= size || free_ent > maxcode) {
312
/*
313
* If the next entry will be too big for the current gcode
314
* size, then we must increase the size. This implies reading
315
* a new buffer full, too.
316
*/
317
if (free_ent > maxcode) {
318
n_bits++;
319
if (n_bits == maxbits) /* Won't get any bigger now. */
320
maxcode = maxmaxcode;
321
else
322
maxcode = MAXCODE(n_bits);
323
}
324
if (clear_flg > 0) {
325
maxcode = MAXCODE(n_bits = INIT_BITS);
326
clear_flg = 0;
327
}
328
size = sfrd(f, gbuf, n_bits, dp);
329
if (size <= 0) /* End of file. */
330
return (-1);
331
roffset = 0;
332
/* Round size down to integral number of codes. */
333
size = (size << 3) - (n_bits - 1);
334
}
335
r_off = roffset;
336
bits = n_bits;
337
338
/* Get to the first byte. */
339
bp += (r_off >> 3);
340
r_off &= 7;
341
342
/* Get first part (low order bits). */
343
gcode = (*bp++ >> r_off);
344
bits -= (8 - r_off);
345
r_off = 8 - r_off; /* Now, roffset into gcode word. */
346
347
/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
348
if (bits >= 8) {
349
gcode |= *bp++ << r_off;
350
r_off += 8;
351
bits -= 8;
352
}
353
354
/* High order bits. */
355
gcode |= (*bp & rmask[bits]) << r_off;
356
roffset += n_bits;
357
358
return (gcode);
359
}
360
361
static void
362
cl_hash(LZW_t* zs, register count_int cl_hsize) /* Reset code table. */
363
{
364
register count_int *htab_p;
365
register long i, m1;
366
367
m1 = -1;
368
htab_p = htab + cl_hsize;
369
i = cl_hsize - 16;
370
do { /* Might use Sys V memset(3) here. */
371
*(htab_p - 16) = m1;
372
*(htab_p - 15) = m1;
373
*(htab_p - 14) = m1;
374
*(htab_p - 13) = m1;
375
*(htab_p - 12) = m1;
376
*(htab_p - 11) = m1;
377
*(htab_p - 10) = m1;
378
*(htab_p - 9) = m1;
379
*(htab_p - 8) = m1;
380
*(htab_p - 7) = m1;
381
*(htab_p - 6) = m1;
382
*(htab_p - 5) = m1;
383
*(htab_p - 4) = m1;
384
*(htab_p - 3) = m1;
385
*(htab_p - 2) = m1;
386
*(htab_p - 1) = m1;
387
htab_p -= 16;
388
} while ((i -= 16) >= 0);
389
for (i += 16; i > 0; i--)
390
*--htab_p = m1;
391
}
392
393
static int
394
cl_block(LZW_t* zs, Sfio_t* f, Sfdisc_t* dp)/* Table clear for block compress. */
395
{
396
register long rat;
397
398
checkpoint = in_count + CHECK_GAP;
399
400
if (in_count > 0x007fffff) { /* Shift will overflow. */
401
rat = bytes_out >> 8;
402
if (rat == 0) /* Don't divide by zero. */
403
rat = 0x7fffffff;
404
else
405
rat = in_count / rat;
406
} else
407
rat = (in_count << 8) / bytes_out; /* 8 fractional bits. */
408
if (rat > ratio)
409
ratio = rat;
410
else {
411
ratio = 0;
412
cl_hash(zs, (count_int) hsize);
413
free_ent = FIRST;
414
clear_flg = 1;
415
if (output(zs, f, (code_int) CLEAR, dp) == -1)
416
return (-1);
417
}
418
return (0);
419
}
420
421
/*
422
* lzw sync/flush/getpos
423
* only sync is implemented right now
424
* see sfdcgzip() for full implementation
425
*/
426
427
static Sfoff_t
428
lzw_sync(LZW_t* zs, Sfio_t* f, Sfoff_t off, Sfdisc_t* dp)
429
{
430
#if 1
431
static int nosync;
432
433
if (off == -1)
434
{
435
if (!nosync)
436
nosync = getenv("SFDCLZW_nosync") ? 1 : -1;
437
if (nosync > 0)
438
return 0;
439
}
440
#endif
441
if (zs->disc.writef && cl_block(zs, f, dp))
442
return -1;
443
if (off == -1)
444
return 0;
445
return -1;
446
}
447
448
/*
449
* lzw exception handler
450
* free on close
451
*/
452
453
static int
454
lzw_except(Sfio_t* f, int op, void* val, Sfdisc_t* dp)
455
{
456
register LZW_t* zs = (LZW_t*)dp;
457
int flags;
458
int r;
459
460
NoP(f);
461
switch (op)
462
{
463
case SF_ATEXIT:
464
sfdisc(f, SF_POPDISC);
465
return 0;
466
case SF_CLOSING:
467
case SF_DPOP:
468
case SF_FINAL:
469
r = 0;
470
if (dp->writef)
471
{
472
SFDCNEXT(f, flags);
473
if (output(zs, f, (code_int) ent, dp) == -1)
474
r = -1;
475
else
476
{
477
out_count++;
478
if (output(zs, f, (code_int) -1, dp) == -1)
479
r = -1;
480
}
481
SFDCPREV(f, flags);
482
}
483
if (op != SF_CLOSING)
484
free(dp);
485
return r;
486
case SF_DBUFFER:
487
return 1;
488
case SF_READ:
489
case SF_WRITE:
490
return *((ssize_t*)val) < 0 ? -1 : 0;
491
case SF_SYNC:
492
return val ? 0 : lzw_sync(zs, f, -1, dp) == -1 ? -1 : 0;
493
case SFGZ_HANDLE:
494
return (*((LZW_t**)val) = zs) ? 1 : -1;
495
case SFGZ_GETPOS:
496
return (*((Sfoff_t*)val) = lzw_sync(zs, f, -1, dp)) == -1 ? -1 : 0;
497
case SFGZ_SETPOS:
498
return lzw_sync(zs, f, *((Sfoff_t*)val), dp) == -1 ? -1 : 0;
499
}
500
return 0;
501
}
502
503
/*-
504
* compress write
505
*
506
* Algorithm: use open addressing double hashing (no chaining) on the
507
* prefix code / next character combination. We do a variant of Knuth's
508
* algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
509
* secondary probe. Here, the modular division first probe is gives way
510
* to a faster exclusive-or manipulation. Also do block compression with
511
* an adaptive reset, whereby the code table is cleared when the compression
512
* ratio decreases, but after the table fills. The variable-length output
513
* codes are re-sized at this point, and a special CLEAR code is generated
514
* for the decompressor. Late addition: construct the table according to
515
* file size for noticeable speed improvement on small files. Please direct
516
* questions about this implementation to ames!jaw.
517
*/
518
519
static ssize_t
520
lzw_write(Sfio_t* f, const Void_t* wbp, size_t num, Sfdisc_t* dp)
521
{
522
register code_int i;
523
register int c, disp;
524
LZW_t *zs;
525
const u_char *bp;
526
u_char tmp;
527
int count;
528
529
if (num == 0)
530
return (0);
531
532
zs = (LZW_t*)dp;
533
count = num;
534
bp = (u_char *)wbp;
535
if (state == S_MIDDLE)
536
goto middle;
537
state = S_MIDDLE;
538
539
maxmaxcode = 1L << maxbits;
540
if (sfwr(f, magic_header, sizeof(magic_header), dp) != sizeof(magic_header))
541
return (-1);
542
tmp = (u_char)((maxbits) | block_compress);
543
if (sfwr(f, &tmp, sizeof(tmp), dp) != sizeof(tmp))
544
return (-1);
545
546
offset = 0;
547
bytes_out = 3; /* Includes 3-byte header mojo. */
548
out_count = 0;
549
clear_flg = 0;
550
ratio = 0;
551
in_count = 1;
552
checkpoint = CHECK_GAP;
553
maxcode = MAXCODE(n_bits = INIT_BITS);
554
free_ent = ((block_compress) ? FIRST : 256);
555
556
ent = *bp++;
557
--count;
558
559
hshift = 0;
560
for (fcode = (long)hsize; fcode < 65536L; fcode *= 2L)
561
hshift++;
562
hshift = 8 - hshift; /* Set hash code range bound. */
563
564
hsize_reg = hsize;
565
cl_hash(zs, (count_int)hsize_reg); /* Clear hash table. */
566
567
middle: for (i = 0; count--;) {
568
c = *bp++;
569
in_count++;
570
fcode = (long)(((long)c << maxbits) + ent);
571
i = ((c << hshift) ^ ent); /* Xor hashing. */
572
573
if (htabof(i) == fcode) {
574
ent = codetabof(i);
575
continue;
576
} else if ((long)htabof(i) < 0) /* Empty slot. */
577
goto nomatch;
578
disp = hsize_reg - i; /* Secondary hash (after G. Knott). */
579
if (i == 0)
580
disp = 1;
581
probe: if ((i -= disp) < 0)
582
i += hsize_reg;
583
584
if (htabof(i) == fcode) {
585
ent = codetabof(i);
586
continue;
587
}
588
if ((long)htabof(i) >= 0)
589
goto probe;
590
nomatch: if (output(zs, f, (code_int) ent, dp) == -1)
591
return (-1);
592
out_count++;
593
ent = c;
594
if (free_ent < maxmaxcode) {
595
codetabof(i) = free_ent++; /* code -> hashtable */
596
htabof(i) = fcode;
597
} else if ((count_int)in_count >=
598
checkpoint && block_compress) {
599
if (cl_block(zs, f, dp) == -1)
600
return (-1);
601
}
602
}
603
return (num);
604
}
605
606
/*
607
* Decompress read. This routine adapts to the codes in the file building
608
* the "string" table on-the-fly; requiring no table to be stored in the
609
* compressed file. The tables used herein are shared with those of the
610
* compress() routine. See the definitions above.
611
*/
612
static ssize_t
613
lzw_read(Sfio_t* f, Void_t* rbp, size_t num, Sfdisc_t* dp)
614
{
615
register u_int count;
616
LZW_t *zs;
617
u_char *bp, header[3];
618
619
if (num == 0)
620
return (0);
621
622
zs = (LZW_t*)dp;
623
count = num;
624
bp = (u_char *)rbp;
625
switch (state) {
626
case S_START:
627
state = S_MIDDLE;
628
break;
629
case S_MIDDLE:
630
goto middle;
631
case S_EOF:
632
goto eof;
633
}
634
635
/* Check the magic number */
636
if (sfrd(f, header, sizeof(header), dp) != sizeof(header) ||
637
memcmp(header, magic_header, sizeof(magic_header)) != 0)
638
return (-1);
639
maxbits = header[2]; /* Set -b from file. */
640
block_compress = maxbits & BLOCK_MASK;
641
maxbits &= BIT_MASK;
642
maxmaxcode = 1L << maxbits;
643
if (maxbits > BITS)
644
return (-1);
645
/* As above, initialize the first 256 entries in the table. */
646
maxcode = MAXCODE(n_bits = INIT_BITS);
647
for (code = 255; code >= 0; code--) {
648
tab_prefixof(code) = 0;
649
tab_suffixof(code) = (char_type) code;
650
}
651
free_ent = block_compress ? FIRST : 256;
652
653
finchar = oldcode = getcode(zs, f, dp);
654
if (oldcode == -1) /* EOF already? */
655
return (0); /* Get out of here */
656
657
/* First code must be 8 bits = char. */
658
*bp++ = (u_char)finchar;
659
count--;
660
stackp = de_stack;
661
662
while ((code = getcode(zs, f, dp)) > -1) {
663
664
if ((code == CLEAR) && block_compress) {
665
for (code = 255; code >= 0; code--)
666
tab_prefixof(code) = 0;
667
clear_flg = 1;
668
free_ent = FIRST - 1;
669
if ((code = getcode(zs, f, dp)) == -1) /* O, untimely death! */
670
break;
671
}
672
incode = code;
673
674
/* Special case for KwKwK string. */
675
if (code >= free_ent) {
676
*stackp++ = finchar;
677
code = oldcode;
678
}
679
680
/* Generate output characters in reverse order. */
681
while (code >= 256) {
682
*stackp++ = tab_suffixof(code);
683
code = tab_prefixof(code);
684
}
685
*stackp++ = finchar = tab_suffixof(code);
686
687
/* And put them out in forward order. */
688
middle: do {
689
if (count-- == 0)
690
return (num);
691
*bp++ = *--stackp;
692
} while (stackp > de_stack);
693
694
/* Generate the new entry. */
695
if ((code = free_ent) < maxmaxcode) {
696
tab_prefixof(code) = (u_short) oldcode;
697
tab_suffixof(code) = finchar;
698
free_ent = code + 1;
699
}
700
701
/* Remember previous code. */
702
oldcode = incode;
703
}
704
state = S_EOF;
705
eof: return (num - count);
706
}
707
708
/*
709
* create and push the sfio lzw discipline
710
* for SF_READ streams only
711
*
712
* (flags&SFGZ_VERIFY) return
713
* >0 is an lzw file
714
* 0 not an lzw file
715
* <0 error
716
* otherwise return
717
* >0 discipline pushed (gzip or lzw)
718
* 0 discipline not needed
719
* <0 error
720
*/
721
722
int
723
sfdclzw(Sfio_t* f, int flags)
724
{
725
LZW_t* zs;
726
727
if (sfset(f, 0, 0) & SF_READ)
728
{
729
register unsigned char* s;
730
register int n;
731
732
/*
733
* peek the first 2 bytes to verify the magic
734
*
735
* 0x1f8b sfdcgzip gzip
736
* 0x1f9d sfdclzw compress
737
*/
738
739
if (!(n = sfset(f, 0, 0) & SF_SHARE))
740
sfset(f, SF_SHARE, 1);
741
s = (unsigned char*)sfreserve(f, 2, 1);
742
if (!n)
743
sfset(f, SF_SHARE, 0);
744
if (!s)
745
return -1;
746
if (*s != 0x1f)
747
n = -1;
748
else if (*(s + 1) == 0x8b)
749
n = 1;
750
else if (*(s + 1) == 0x9d)
751
n = 0;
752
else
753
n = -1;
754
sfread(f, s, 0);
755
if (n < 0)
756
return 0;
757
if (flags & SFGZ_VERIFY)
758
return n >= 0;
759
if (n > 0)
760
return sfdcgzip(f, flags);
761
}
762
if (!(zs = newof(0, LZW_t, 1, 0)))
763
return -1;
764
zs->disc.exceptf = lzw_except;
765
if (sfset(f, 0, 0) & SF_READ)
766
zs->disc.readf = lzw_read;
767
else
768
zs->disc.writef = lzw_write;
769
770
maxbits = BITS; /* fixed max # bits/code. */
771
maxmaxcode = 1L << maxbits; /* Should NEVER generate this code. */
772
hsize = HSIZE; /* For dynamic table sizing. */
773
free_ent = 0; /* First unused entry. */
774
block_compress = BLOCK_MASK;
775
clear_flg = 0;
776
ratio = 0;
777
checkpoint = CHECK_GAP;
778
in_count = 1; /* Length of input. */
779
out_count = 0; /* # of codes output (for debugging). */
780
state = S_START;
781
roffset = 0;
782
size = 0;
783
784
sfset(f, SF_SHARE|SF_PUBLIC, 0);
785
if (sfdisc(f, &zs->disc) != &zs->disc)
786
{
787
free(zs);
788
return -1;
789
}
790
return 1;
791
}
792
793