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