home *** CD-ROM | disk | FTP | other *** search
- From: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
- Newsgroups: alt.sources
- Subject: zoo 2.1 source part 03/15
- Message-ID: <12769@bsu-cs.bsu.edu>
- Date: 10 Jul 91 09:03:42 GMT
-
- Checksum: 733558324 (verify with "brik -cv")
- Submitted-by: dhesi@bsu-cs.bsu.edu
- Archive-name: zoo210/part03
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # This is part 03 of zoo210
- # ============= generic.c ==============
- if test -f 'generic.c' -a X"$1" != X"-c"; then
- echo 'x - skipping generic.c (File already exists)'
- else
- echo 'x - extracting generic.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'generic.c' &&
- #ifndef LINT
- static char genericid[]="@(#) generic.c 2.2 88/01/24 12:44:03";
- #endif /* LINT */
- X
- /*
- Generic template for machine-dependent functions.
- X
- The contents of this file are hereby released to the public domain
- X
- X -- Rahul Dhesi 1991/07/05
- */
- X
- /****************
- Date and time functions are assumed to be standard **IX-style functions.
- */
- X
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <time.h>
- X
- /* Function isadir() returns 1 if the supplied handle is a directory,
- else it returns 0.
- */
- X
- int isadir (file)
- ZOOFILE file;
- {
- X int handle = fileno(file);
- X struct stat buf; /* buffer to hold file information */
- X if (fstat (handle, &buf) == -1) {
- X return (0); /* inaccessible -- assume not dir */
- X } else {
- X if (buf.st_mode & S_IFDIR)
- X return (1);
- X else
- X return (0);
- X }
- }
- X
- /****************
- Function fixfname() converts the supplied filename to a syntax
- legal for the host system. It is used during extraction.
- */
- X
- char *fixfname(fname)
- char *fname;
- {
- X fname[FNLIMIT] = '\0'; /* Just truncate at filename size limit */
- X return fname;
- }
- X
- /* The function gettz() returns the offset from GMT in seconds, taking
- into account the local timezone and any daylight savings time. */
- X
- /* This version of gettz should be portable to all Unices, although it
- can't be described as elegant. Users immediately west of the International
- Date Line (Polynesia, Soviet Far East) may get times out by 24 hours.
- Contributed by: Ian Phillipps <igp@camcon.co.uk> */
- X
- long gettz()
- {
- #define NOONOFFSET 43200
- #define SEC_IN_DAY (24L * 60L * 60L)
- #define INV_VALUE (SEC_IN_DAY + 1L)
- X static long retval = INV_VALUE; /* cache, init to impossible value */
- X extern long time();
- X extern struct tm *localtime();
- X long now;
- X long noon;
- X struct tm *noontm;
- X if (retval != INV_VALUE) /* if have cached value, return it */
- X return retval;
- X now = time((long *) 0);
- X /* Find local time for GMT noon today */
- X noon = now - now % SEC_IN_DAY + NOONOFFSET ;
- X noontm = localtime( &noon );
- X retval = NOONOFFSET - 60 * ( 60 * noontm->tm_hour - noontm->tm_min );
- X return retval;
- #undef NOONOFFSET
- }
- X
- /* Standard UNIX-compatible time functions */
- #include "nixtime.i"
- X
- /* Standard UNIX-specific file attribute routines */
- #include "nixmode.i"
- X
- /* Assume no file truncate system call. Ok to be a no-op. */
- /*ARGSUSED*/
- int zootrunc(f) FILE *f; { return 0; }
- X
- SHAR_EOF
- chmod 0644 generic.c ||
- echo 'restore of generic.c failed'
- Wc_c="`wc -c < 'generic.c'`"
- test 2422 -eq "$Wc_c" ||
- echo 'generic.c: original size 2422, current size' "$Wc_c"
- fi
- # ============= getfile.c ==============
- if test -f 'getfile.c' -a X"$1" != X"-c"; then
- echo 'x - skipping getfile.c (File already exists)'
- else
- echo 'x - extracting getfile.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'getfile.c' &&
- #ifndef LINT
- static char sccsid[]="@(#) getfile.c 2.7 88/01/24 12:44:23";
- #endif /* LINT */
- X
- /*
- Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- (C) Copyright 1988 Rahul Dhesi -- All rights reserved
- */
- X
- #include "options.h"
- /*
- This function copies n characters from the source file to the destination
- X
- Input: out_f: destination file
- X in_f: source file
- X count: count of characters to copy
- X docrc: 0 if crc not wanted
- X
- If count is -1, copying is done until eof is encountered.
- X
- The source file is transferred to the current file pointer position in the
- destination file, using the handles provided. Function return value is 0
- if no error, 2 if write error, and 3 if read error.
- X
- If docrc is not 0, the global variable crccode is updated via addbfcrc().
- This is done even if the output is to the null device.
- X
- If UNBUF_IO is defined, and if more than UNBUF_LIMIT bytes are
- being transferred or copying is to end of file, the data transfer
- is done using low-level read() and write() functions, which must
- be defined elsewhere. File descriptors are obtained for this
- purpose using the fileno() macro, which must be provided elsewhere
- too. This is meant to provide greater efficiency on some systems.
- The files of type ZOOFILE are synchronized with their file
- descriptors by doing a reasonable number of seeks and other
- miscellaneous operations before and after the transfer. Such
- simultaneous use of buffered and unbuffered files is not
- portable and should not be used without extensive testing.
- */
- X
- #ifdef UNBUF_IO
- int read PARMS ((int, VOIDPTR, unsigned));
- int write PARMS ((int, VOIDPTR, unsigned));
- long lseek PARMS ((int, long, int));
- long tell PARMS ((int));
- #endif /* UNBUF_IO */
- X
- #include "zoo.h" /* satisfy declarations in zooio.h */
- #include "zooio.h"
- #include "various.h"
- #include "zoofns.h"
- #include "zoomem.h"
- X
- int getfile (in_f, out_f, count, docrc)
- ZOOFILE in_f, out_f;
- long count;
- int docrc;
- {
- X register int how_much;
- #ifdef UNBUF_IO
- X int in_d, out_d; /* file descriptors for unbuffered I/O */
- #endif /* UNBUF_IO */
- X
- #ifdef UNBUF_IO
- X if (out_f != NULLFILE && (count == -1 || count > UNBUF_LIMIT)) {
- X in_d = fileno (in_f); /* get .. */
- X out_d = fileno (out_f); /* ... file descriptors */
- X
- X /* Synchronize buffered and unbuffered files */
- X zooseek (in_f, zootell (in_f), 0);
- X zooseek (out_f, zootell (out_f), 0);
- X
- #if 0
- X lseek (in_d, zootell (in_f), 0);
- X lseek (out_d, zootell (out_f), 0);
- #endif
- X
- X if (count == -1) {
- X while ((how_much = read (in_d, out_buf_adr, MEM_BLOCK_SIZE)) > 0) {
- X if (how_much == -1 ||
- X write (out_d, out_buf_adr, how_much) != how_much)
- X return (2);
- X if (docrc)
- X addbfcrc (out_buf_adr,how_much);
- X }
- X zooseek (in_f, tell (in_d), 0); /* resynch */
- X zooseek (out_f, tell (out_d), 0); /* resynch */
- X
- #ifndef NDEBUG
- X if (ftell (in_f) != tell (in_d) || ftell (out_f) != tell (out_d)) {
- X prterror ('w', "seek mismatch in copy to EOF\n");
- X printf ("in_f =%6ld, in_d =%6ld\n", ftell (in_f), tell (in_d));
- X printf ("out_f=%6ld, out_d=%6ld\n", ftell (out_f), tell (out_d));
- X }
- #endif /* NDEBUG */
- X
- X return (0);
- X }
- X
- X while (count > 0) {
- X if (count > MEM_BLOCK_SIZE)
- X how_much = MEM_BLOCK_SIZE;
- X else
- X how_much = (int) count;
- X count -= how_much;
- X if (read (in_d, out_buf_adr, how_much) != how_much)
- X return (3);
- X if (docrc)
- X addbfcrc (out_buf_adr, how_much);
- X if (write (out_d, out_buf_adr, how_much) != how_much)
- X return (2);
- X }
- X zooseek (in_f, tell (in_d), 0); /* resynch */
- X zooseek (out_f, tell (out_d), 0); /* resynch */
- #ifndef NDEBUG
- X if (ftell (in_f) != tell (in_d) || ftell (out_f) != tell (out_d))
- X prterror ('w', "seek mismatch in fixed length copy\n");
- #endif /* NDEBUG */
- X return (0);
- X }
- #endif /* UNBUF_IO */
- X
- X if (count == -1) {
- X while ((how_much = zooread (in_f, out_buf_adr, MEM_BLOCK_SIZE)) > 0) {
- X if (how_much == -1 ||
- X zoowrite (out_f, out_buf_adr, how_much) != how_much)
- X return (2);
- X if (docrc)
- X addbfcrc (out_buf_adr,how_much);
- X }
- X return (0);
- X }
- X
- X while (count > 0) {
- X if (count > MEM_BLOCK_SIZE)
- X how_much = MEM_BLOCK_SIZE;
- X else
- X how_much = (int) count;
- X count -= how_much;
- X if (zooread (in_f, out_buf_adr, how_much) != how_much)
- X return (3);
- X if (docrc)
- X addbfcrc (out_buf_adr, how_much);
- X if (zoowrite (out_f, out_buf_adr, how_much) != how_much)
- X return (2);
- X }
- X return (0);
- }
- SHAR_EOF
- chmod 0644 getfile.c ||
- echo 'restore of getfile.c failed'
- Wc_c="`wc -c < 'getfile.c'`"
- test 4549 -eq "$Wc_c" ||
- echo 'getfile.c: original size 4549, current size' "$Wc_c"
- fi
- # ============= huf.c ==============
- if test -f 'huf.c' -a X"$1" != X"-c"; then
- echo 'x - skipping huf.c (File already exists)'
- else
- echo 'x - extracting huf.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'huf.c' &&
- /*$Source: /usr/home/dhesi/zoo/RCS/huf.c,v $*/
- /*$Id: huf.c,v 1.9 91/07/09 01:39:55 dhesi Exp $*/
- /***********************************************************
- X huf.c -- static Huffman
- X
- Adapted from "ar" archiver written by Haruhiko Okumura.
- ***********************************************************/
- #include "options.h"
- #include "zoo.h"
- #include "ar.h"
- #include "lzh.h"
- #include "errors.i"
- X
- extern void prterror();
- X
- #ifdef ANSI_HDRS
- # include <stdlib.h>
- #endif
- X
- #define NP (DICBIT + 1)
- #define NT (CODE_BIT + 3)
- #define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */
- #define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */
- #if NT > NP
- # define NPT NT
- #else
- # define NPT NP
- #endif
- X
- int decoded; /* for use in decode.c */
- X
- ushort left[2 * NC - 1], right[2 * NC - 1];
- static uchar *buf, c_len[NC], pt_len[NPT];
- static uint bufsiz = 0, blocksize;
- static ushort c_freq[2 * NC - 1], c_table[4096], c_code[NC],
- X p_freq[2 * NP - 1], pt_table[256], pt_code[NPT],
- X t_freq[2 * NT - 1];
- X
- /***** encoding *****/
- X
- static void count_t_freq()
- {
- X int i, k, n, count;
- X
- X for (i = 0; i < NT; i++) t_freq[i] = 0;
- X n = NC;
- X while (n > 0 && c_len[n - 1] == 0) n--;
- X i = 0;
- X while (i < n) {
- X k = c_len[i++];
- X if (k == 0) {
- X count = 1;
- X while (i < n && c_len[i] == 0) { i++; count++; }
- X if (count <= 2) t_freq[0] += count;
- X else if (count <= 18) t_freq[1]++;
- X else if (count == 19) { t_freq[0]++; t_freq[1]++; }
- X else t_freq[2]++;
- X } else t_freq[k + 2]++;
- X }
- }
- X
- static void write_pt_len(n, nbit, i_special)
- int n;
- int nbit;
- int i_special;
- {
- X int i, k;
- X
- X while (n > 0 && pt_len[n - 1] == 0) n--;
- X putbits(nbit, (uint) n);
- X i = 0;
- X while (i < n) {
- X k = pt_len[i++];
- X if (k <= 6) putbits(3, (uint) k);
- X else putbits(k - 3, (uint) (((unsigned) 1 << (k - 3)) - 2));
- X if (i == i_special) {
- X while (i < 6 && pt_len[i] == 0) i++;
- X putbits(2, (uint) ((i - 3) & 3));
- X }
- X }
- }
- X
- static void write_c_len()
- {
- X int i, k, n, count;
- X
- X n = NC;
- X while (n > 0 && c_len[n - 1] == 0) n--;
- X putbits(CBIT, (uint) n);
- X i = 0;
- X while (i < n) {
- X k = c_len[i++];
- X if (k == 0) {
- X count = 1;
- X while (i < n && c_len[i] == 0) { i++; count++; }
- X if (count <= 2) {
- X for (k = 0; k < count; k++)
- X putbits((int) pt_len[0], (uint) pt_code[0]);
- X } else if (count <= 18) {
- X putbits((int) pt_len[1], (uint) pt_code[1]);
- X putbits(4, (uint) (count - 3));
- X } else if (count == 19) {
- X putbits((int) pt_len[0], (uint) pt_code[0]);
- X putbits((int) pt_len[1], (uint) pt_code[1]);
- X putbits(4, 15);
- X } else {
- X putbits((int) pt_len[2], (uint) pt_code[2]);
- X putbits(CBIT, (uint) (count - 20));
- X }
- X } else putbits((int) pt_len[k + 2], (uint) pt_code[k + 2]);
- X }
- }
- X
- static void encode_c(c)
- int c;
- {
- X putbits((int) c_len[c], (uint) c_code[c]);
- }
- X
- static void encode_p(p)
- uint p;
- {
- X uint c, q;
- X
- X c = 0; q = p; while (q) { q >>= 1; c++; }
- X putbits((int) pt_len[c], (uint) pt_code[c]);
- X if (c > 1) putbits((int) (c - 1), (uint) (p & ((unsigned) 0xFFFF >> (17 - c))));
- }
- X
- static void send_block()
- {
- X uint i, k, flags, root, pos, size;
- X
- X root = make_tree(NC, c_freq, c_len, c_code);
- X size = c_freq[root];
- #if 0
- X /*debug*/ (void) fprintf(stderr, "\nsize = %u\n", size);
- #endif
- X putbits(16, size);
- X if (root >= NC) {
- X count_t_freq();
- X root = make_tree(NT, t_freq, pt_len, pt_code);
- X if (root >= NT) {
- X write_pt_len(NT, TBIT, 3);
- X } else {
- X putbits(TBIT, 0); putbits(TBIT, root);
- X }
- X write_c_len();
- X } else {
- X putbits(TBIT, 0); putbits(TBIT, 0);
- X putbits(CBIT, 0); putbits(CBIT, root);
- X }
- X root = make_tree(NP, p_freq, pt_len, pt_code);
- X if (root >= NP) {
- X write_pt_len(NP, PBIT, -1);
- X } else {
- X putbits(PBIT, 0); putbits(PBIT, root);
- X }
- X pos = 0;
- X for (i = 0; i < size; i++) {
- X if (i % CHAR_BIT == 0) flags = buf[pos++]; else flags <<= 1;
- X if (flags & ((unsigned) 1 << (CHAR_BIT - 1))) {
- X encode_c((int) (buf[pos++] + ((unsigned) 1 << CHAR_BIT)));
- X k = buf[pos++] << CHAR_BIT; k += buf[pos++];
- X encode_p(k);
- X } else encode_c((int) buf[pos++]);
- X if (unpackable) return;
- X }
- X for (i = 0; i < NC; i++) c_freq[i] = 0;
- X for (i = 0; i < NP; i++) p_freq[i] = 0;
- }
- X
- static uint output_pos, output_mask;
- X
- void output(c, p)
- uint c;
- uint p;
- {
- X static uint cpos;
- X
- X if ((output_mask >>= 1) == 0) {
- X output_mask = (unsigned) 1 << (CHAR_BIT - 1);
- X if (output_pos >= bufsiz - 3 * CHAR_BIT) {
- X send_block();
- X if (unpackable) return;
- X output_pos = 0;
- X }
- X cpos = output_pos++; buf[cpos] = 0;
- X }
- X buf[output_pos++] = (uchar) c; c_freq[c]++;
- X if (c >= ((unsigned) 1 << CHAR_BIT)) {
- X buf[cpos] |= output_mask;
- X buf[output_pos++] = (uchar)(p >> CHAR_BIT);
- X buf[output_pos++] = (uchar) p;
- X c = 0; while (p) { p >>= 1; c++; }
- X p_freq[c]++;
- X }
- }
- X
- void huf_encode_start()
- {
- X int i;
- X
- X if (bufsiz == 0) {
- X bufsiz = 16 * (unsigned) 1024;
- X while ((buf = (uchar *) malloc(bufsiz)) == NULL) {
- X bufsiz = (bufsiz / (unsigned) 10) * (unsigned) 9;
- X if (bufsiz < 4 * (unsigned) 1024)
- X prterror('f', no_memory);
- X }
- X }
- X buf[0] = 0;
- X for (i = 0; i < NC; i++) c_freq[i] = 0;
- X for (i = 0; i < NP; i++) p_freq[i] = 0;
- X output_pos = output_mask = 0;
- X init_putbits();
- }
- X
- void huf_encode_end()
- {
- X if (! unpackable) {
- X send_block();
- X putbits(CHAR_BIT - 1, 0); /* flush remaining bits */
- X putbits(16, 0); /* EOF marker */
- X }
- }
- X
- /***** decoding *****/
- X
- static void read_pt_len(nn, nbit, i_special)
- int nn;
- int nbit;
- int i_special;
- {
- X int i, c, n;
- X uint mask;
- X
- X n = getbits(nbit);
- X if (n == 0) {
- X c = getbits(nbit);
- X for (i = 0; i < nn; i++) pt_len[i] = 0;
- X for (i = 0; i < 256; i++) pt_table[i] = c;
- X } else {
- X i = 0;
- X while (i < n) {
- X c = bitbuf >> (BITBUFSIZ - 3);
- X if (c == 7) {
- X mask = (unsigned) 1 << (BITBUFSIZ - 1 - 3);
- X while (mask & bitbuf) { mask >>= 1; c++; }
- X }
- X fillbuf((c < 7) ? 3 : c - 3);
- X pt_len[i++] = c;
- X if (i == i_special) {
- X c = getbits(2);
- X while (--c >= 0) pt_len[i++] = 0;
- X }
- X }
- X while (i < nn) pt_len[i++] = 0;
- X make_table(nn, pt_len, 8, pt_table);
- X }
- }
- X
- static void read_c_len()
- {
- X int i, c, n;
- X uint mask;
- X
- X n = getbits(CBIT);
- X if (n == 0) {
- X c = getbits(CBIT);
- X for (i = 0; i < NC; i++) c_len[i] = 0;
- X for (i = 0; i < 4096; i++) c_table[i] = c;
- X } else {
- X i = 0;
- X while (i < n) {
- X c = pt_table[bitbuf >> (BITBUFSIZ - 8)];
- X if (c >= NT) {
- X mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
- X do {
- X if (bitbuf & mask) c = right[c];
- X else c = left [c];
- X mask >>= 1;
- X } while (c >= NT);
- X }
- X fillbuf((int) pt_len[c]);
- X if (c <= 2) {
- X if (c == 0) c = 1;
- X else if (c == 1) c = getbits(4) + 3;
- X else c = getbits(CBIT) + 20;
- X while (--c >= 0) c_len[i++] = 0;
- X } else c_len[i++] = c - 2;
- X }
- X while (i < NC) c_len[i++] = 0;
- X make_table(NC, c_len, 12, c_table);
- X }
- }
- X
- uint decode_c()
- {
- X uint j, mask;
- X
- X if (blocksize == 0) {
- X blocksize = getbits(16);
- X if (blocksize == 0) {
- #if 0
- X (void) fprintf(stderr, "block size = 0, decoded\n"); /* debug */
- #endif
- X decoded = 1;
- X return 0;
- X }
- X read_pt_len(NT, TBIT, 3);
- X read_c_len();
- X read_pt_len(NP, PBIT, -1);
- X }
- X blocksize--;
- X j = c_table[bitbuf >> (BITBUFSIZ - 12)];
- X if (j >= NC) {
- X mask = (unsigned) 1 << (BITBUFSIZ - 1 - 12);
- X do {
- X if (bitbuf & mask) j = right[j];
- X else j = left [j];
- X mask >>= 1;
- X } while (j >= NC);
- X }
- X fillbuf((int) c_len[j]);
- X return j;
- }
- X
- uint decode_p()
- {
- X uint j, mask;
- X
- X j = pt_table[bitbuf >> (BITBUFSIZ - 8)];
- X if (j >= NP) {
- X mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
- X do {
- X if (bitbuf & mask) j = right[j];
- X else j = left [j];
- X mask >>= 1;
- X } while (j >= NP);
- X }
- X fillbuf((int) pt_len[j]);
- X if (j != 0) j = ((unsigned) 1 << (j - 1)) + getbits((int) (j - 1));
- X return j;
- }
- X
- void huf_decode_start()
- {
- X init_getbits(); blocksize = 0;
- }
- SHAR_EOF
- chmod 0644 huf.c ||
- echo 'restore of huf.c failed'
- Wc_c="`wc -c < 'huf.c'`"
- test 7757 -eq "$Wc_c" ||
- echo 'huf.c: original size 7757, current size' "$Wc_c"
- fi
- # ============= io.c ==============
- if test -f 'io.c' -a X"$1" != X"-c"; then
- echo 'x - skipping io.c (File already exists)'
- else
- echo 'x - extracting io.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'io.c' &&
- /*$Source: /usr/home/dhesi/zoo/RCS/io.c,v $*/
- /*$Id: io.c,v 1.14 91/07/09 01:39:54 dhesi Exp $*/
- /***********************************************************
- X io.c -- input/output
- X
- Adapted from "ar" archiver written by Haruhiko Okumura.
- ***********************************************************/
- #ifdef ANSI_HDRS
- # include <stdlib.h>
- # include <string.h>
- #endif
- X
- #include "options.h"
- #include "zoo.h"
- #include "ar.h"
- #include "lzh.h"
- #include "zooio.h" /* for NULLFILE */
- #include "portable.h"
- X
- extern void prterror();
- X
- #include "errors.i"
- X
- #define JUST_LZH /* for stand-alone compression */
- X
- #if 0
- # define CRCPOLY 0xA001 /* ANSI CRC-16 */ /* CCITT: 0x8408 */
- # define UPDATE_CRC(c) \
- X crc = crctable[(crc ^ (c)) & 0xFF] ^ (crc >> CHAR_BIT)
- static ushort crctable[UCHAR_MAX + 1];
- t_uint16 crc;
- #endif
- X
- extern FILE *arcfile, *lzh_outfile;
- t_uint16 bitbuf;
- int unpackable;
- X
- ulong compsize, origsize;
- X
- static uint subbitbuf;
- static int bitcount;
- X
- #if 0
- void make_crctable()
- {
- X uint i, j, r;
- X
- X for (i = 0; i <= UCHAR_MAX; i++) {
- X r = i;
- X for (j = 0; j < CHAR_BIT; j++)
- X if (r & 1) r = (r >> 1) ^ CRCPOLY;
- X else r >>= 1;
- X crctable[i] = r;
- X }
- }
- #endif
- X
- void fillbuf(n) /* Shift bitbuf n bits left, read n bits */
- int n;
- {
- X bitbuf <<= n;
- X while (n > bitcount) {
- X bitbuf |= subbitbuf << (n -= bitcount);
- #ifdef JUST_LZH
- X if (feof(arcfile))
- X subbitbuf = 0;
- X else
- X subbitbuf = (uchar) zgetc(arcfile);
- #else
- X if (compsize != 0) {
- X compsize--; subbitbuf = (uchar) zgetc(arcfile);
- X } else subbitbuf = 0;
- #endif /* JUST_LZH */
- X bitcount = CHAR_BIT;
- X }
- X bitbuf |= subbitbuf >> (bitcount -= n);
- }
- X
- uint getbits(n)
- int n;
- {
- X uint x;
- X
- X x = bitbuf >> (BITBUFSIZ - n); fillbuf(n);
- X return x;
- }
- X
- void putbits(n, x) /* Write rightmost n bits of x */
- int n;
- uint x;
- {
- X if (n < bitcount) {
- X subbitbuf |= x << (bitcount -= n);
- X } else {
- #ifdef JUST_LZH
- X (void) putc((int) (subbitbuf | (x >> (n -= bitcount))), lzh_outfile);
- X compsize++;
- #else
- X if (compsize < origsize) {
- X (void) zputc((int) (subbitbuf | (x >> (n -= bitcount))), lzh_outfile);
- X compsize++;
- X } else unpackable = 1;
- #endif /* JUST_LZH */
- X
- X if (n < CHAR_BIT) {
- X subbitbuf = x << (bitcount = CHAR_BIT - n);
- X } else {
- #ifdef JUST_LZH
- X (void) putc((int) (x >> (n - CHAR_BIT)), lzh_outfile);
- X compsize++;
- #else
- X if (compsize < origsize) {
- X (void) zputc((int) (x >> (n - CHAR_BIT)), lzh_outfile);
- X compsize++;
- X } else unpackable = 1;
- #endif /* JUST_LZH */
- X subbitbuf = x << (bitcount = 2 * CHAR_BIT - n);
- X }
- X }
- }
- X
- extern void addbfcrc();
- X
- int fread_crc(p, n, f)
- uchar *p;
- int n;
- FILE *f;
- {
- X int i;
- X
- X i = n = fread((char *) p, 1, n, f); origsize += n;
- X addbfcrc(p, i);
- X return n;
- }
- X
- void fwrite_crc(p, n, f)
- uchar *p;
- int n;
- FILE *f;
- {
- X if (f != NULLFILE) {
- X if (fwrite((char *) p, 1, n, f) < n)
- X prterror('f', disk_full);
- X }
- X addbfcrc(p, n);
- }
- X
- void init_getbits()
- {
- X bitbuf = 0; subbitbuf = 0; bitcount = 0;
- X fillbuf(BITBUFSIZ);
- }
- X
- void init_putbits()
- {
- X bitcount = CHAR_BIT; subbitbuf = 0;
- }
- SHAR_EOF
- chmod 0644 io.c ||
- echo 'restore of io.c failed'
- Wc_c="`wc -c < 'io.c'`"
- test 3003 -eq "$Wc_c" ||
- echo 'io.c: original size 3003, current size' "$Wc_c"
- fi
- # ============= lzc.asm ==============
- if test -f 'lzc.asm' -a X"$1" != X"-c"; then
- echo 'x - skipping lzc.asm (File already exists)'
- else
- echo 'x - extracting lzc.asm (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'lzc.asm' &&
- title Lempel-Ziv Compressor
- ; $Source: /usr/home/dhesi/zoo/RCS/lzc.asm,v $
- ; $Id: lzc.asm,v 1.4 91/07/07 09:36:18 dhesi Exp $
- X
- ;Derived from Tom Pfau's public domain assembly code.
- ;The contents of this file are hereby released to the public domain.
- ; -- Rahul Dhesi 1988/08/24
- X
- UNBUF_IO equ 1 ;use unbuffered I/O
- X
- public _lzc
- X
- X include asmconst.ai
- X include macros.ai
- X
- check_gap equ 4000 ;Check ratio every so many bits
- scale_limit equ 32000 ;scale down if bitsout > scale_limit
- rat_thresh equ 0ffffh ;don't reset if rat > rat_thresh
- X
- ;Hash table entry
- hash_rec struc
- first dw ? ; First entry with this value
- next dw ? ; Next entry along chain
- char db ? ; Suffix char
- hash_rec ends
- X
- extrn docrc:near ;Procedure for block CRC in lzd.asm
- X
- ifdef UNBUF_IO
- extrn _read:near
- extrn _blockwrite:near
- else
- extrn _zooread:near
- extrn _zoowrite:near
- endif
- X
- ;Declare Segments
- _text segment byte public 'code'
- _text ends
- X
- dgroup group _data
- X assume ds:dgroup,es:dgroup
- _data segment word public 'data'
- extrn _out_buf_adr:word ;address of C output buffer
- extrn _in_buf_adr:word ;address of C input buffer
- X
- extrn memflag:byte ;got memory? flag
- X
- save_sp dw ?
- X
- bytesin dw ? ;count of bytes read
- bitsout dw ? ;count of bits written
- ratio dw ? ;recent ratio
- ratflag db ? ;flag to remind us to check ratio
- bit_interval dw ? ;interval at which to test ratio
- X
- input_handle dw ?
- output_handle dw ?
- hash_seg dw ?
- prefix_code dw ?
- free_code dw ?
- max_code dw ?
- nbits dw ?
- k db ?
- bit_offset dw ?
- input_offset dw 0
- input_size dw 0
- _data ends
- X
- memory segment para public 'memory'
- hash label hash_rec
- memory ends
- X
- add_code macro
- X local ac1,ac2,ac3
- X mov bx,free_code ;Get code to use
- X push ds ;point to hash table
- X mov ds,hash_seg
- X or di,di ;First use of this prefix?
- X jz ac1 ;zero means yes
- X mov [si].next,bx ;point last use to new entry
- X jmp short ac2
- ac1: mov [si].first,bx ;Point first use to new entry
- ac2: cmp bx,maxmax ;Have we reached code limit?
- X je ac3 ;equal means yes, just return
- X
- X ;call index ;get address of new entry
- X call_index ;macro for speed
- X
- X mov [si].first,-1 ;initialize pointers
- X mov [si].next,-1
- X mov [si].char,al ;save suffix char
- X inc es:free_code ;adjust next code
- ac3: pop ds ;restore seg reg
- X endm
- X
- read_char macro ;Macro for speed
- X local m$1,m$2,m$3,m$4
- X inc [bytesin] ;Maintain input byte count for ratio
- X mov di,input_offset ;Anything left in buffer?
- X cmp di,input_size
- X jb m$1 ;less means yes
- X
- X mov cx,inbufsiz
- X call doread ;read block
- X
- X cmp ax,-1
- X jnz m$3
- X jmp IO_err ;input error
- m$3:
- X mov dx,_in_buf_adr ;for docrc
- X call docrc
- X or ax,ax ;Anything left?
- X jz m$2 ;zero means no, finished
- X mov input_size,ax ;Save bytes read
- X mov input_offset,0 ;Point to beginning of buffer
- X mov di,0
- m$1:
- X mov si,_in_buf_adr
- X add si,di
- X lodsb ;Read it in
- X inc input_offset ;Adjust pointer
- X clc ;Success
- X jmp short m$4
- m$2: stc ;Nothing left
- m$4:
- X endm
- X
- ;Start writing code
- _text segment
- X assume cs:_text,ds:dgroup,es:dgroup,ss:nothing
- X
- _lzc proc near
- X push bp ;Standard C entry code
- X mov bp,sp
- X push di
- X push si
- X
- X push ds ;Save ds to be sure
- X mov bx,ds
- X mov es,bx
- X
- ;Get two parameters, both integers, that are input file handle and
- ;output file handle
- X mov ax,[bp+4]
- X mov [input_handle],ax
- X mov ax,[bp+6]
- X mov [output_handle],ax
- X
- X call compress ;Compress file
- X ;Status received back in AX
- X pop ds
- X pop si ;Standard C return code
- X pop di
- X mov sp,bp
- X pop bp
- X ret
- X
- _lzc endp
- X
- compress proc near
- X mov [save_sp],sp ;Save SP in case of error return
- X
- ;Initialize variables for serial re-entrancy
- X mov [bit_offset],0
- X mov [input_offset],0
- X mov [input_size],0
- X
- X test memflag,0ffH ;Memory allocated?
- X jnz gotmem ;If allocated, continue
- X malloc <((maxmax * 5) / 16 + 20)> ;allocate it
- X jnc here1
- X jmp MALLOC_err1
- here1:
- X mov hash_seg,ax ;Save segment address of mem block
- X mov memflag,0ffh ;Set flag to remind us later
- gotmem:
- X
- l1: call init_table ;Initialize the table and some vars
- X mov ax,clear ;Write a clear code
- X call write_code
- X ;call read_char ;Read first char
- X read_char ;macro for speed
- l4:
- X
- ;new code to check compression ratio
- X test [ratflag],0FFH ;Time to check ratio?
- X jz rd$1 ;Skip checking if zero
- X call check_ratio
- rd$1:
- X xor ah,ah ;Turn char into code
- l4a: mov prefix_code,ax ;Set prefix code
- X ;call read_char ;Read next char
- X read_char ;macro for speed
- X jc l17 ;Carry means eof
- X mov k,al ;Save char in k
- X mov bx,prefix_code ;Get prefix code
- X
- X call lookup_code ;See if this pair in table
- X
- X jnc l4a ;nc means yes, new code in ax
- X ;call add_code ;Add pair to table
- X add_code ;Macro for speed
- X push bx ;Save new code
- X mov ax,prefix_code ;Write old prefix code
- X call write_code
- X pop bx
- X mov al,k ;Get last char
- X cmp bx,max_code ;Exceed code size?
- X
- X jnb l4$
- X jmp l4
- l4$:
- X cmp nbits,maxbits ;Currently less than maxbits?
- X jb l14 ;yes
- X mov ax,clear ;Write a clear code
- X call write_code
- X call init_table ;Reinit table
- X mov al,k ;get last char
- X jmp l4 ;Start over
- l14: inc nbits ;Increase number of bits
- X shl max_code,1 ;Double max code size
- X jmp l4 ;Get next char
- l17: mov ax,prefix_code ;Write last code
- X call write_code
- X mov ax,eof ;Write eof code
- X call write_code
- X mov ax,bit_offset ;Make sure buffer is flushed to file
- X cmp ax,0
- X je OK_ret
- X mov dx,ax ;dx <- ax
- X shr ax,1
- X shr ax,1
- X shr ax,1 ;ax <- ax div 8
- X and dx,07 ;dx <- ax mod 8
- X ;If extra bits, make sure they get
- X je l17a ;written
- X inc ax
- l17a: call flush
- OK_ret:
- X xor ax,ax ;Normal return -- compressed
- X ret
- IO_err:
- X mov ax,2 ;I/O error return
- X mov sp,[save_sp] ;Restore stack pointer
- X ret
- X
- MALLOC_err1: ;hash table alloc error
- X mov ax,1 ;Malloc error return
- X mov sp,[save_sp] ;Restore stack pointer
- X ret
- compress endp
- X
- init_table proc near
- X mov [bytesin],0 ;Input byte count
- X mov [bitsout],0 ;Output bit count
- X mov [ratio],0
- X mov [ratflag],0
- X mov [bit_interval],check_gap
- X
- X mov nbits,9 ;Set code size to 9
- X mov max_code,512 ;Set max code to 512
- X push es ;Save seg reg
- X mov es,hash_seg ;Address hash table
- X mov ax,-1 ;Unused flag
- X mov cx,640 ;Clear first 256 entries
- X mov di,offset hash ;Point to first entry
- rep stosw ;Clear it out
- X pop es ;Restore seg reg
- X mov free_code,first_free ;Set next code to use
- X ret ;done
- init_table endp
- X
- write_code proc near
- X push ax ;Save code
- X mov cx,nbits
- X add [bitsout],cx ;Maintain output bit count for ratio
- X sub [bit_interval],cx
- X jg rd$2 ;OK if not reached interval
- X mov [ratflag],1 ;else set flag -- check ratio soon
- rd$2:
- X mov ax,bit_offset ;Get bit offset
- X mov cx,nbits ;Adjust bit offset by code size
- X add bit_offset,cx
- X
- X mov dx,ax ;dx <- ax
- X shr ax,1
- X shr ax,1
- X shr ax,1 ;ax <- ax div 8
- X and dx,07 ;dx <- ax mod 8
- X
- X ;Now ax contains byte offset and
- X ;dx contains bit offset within that byte (I think)
- X
- X cmp ax,outbufsiz-4 ;Approaching end of buffer?
- X jb wc1 ;less means no
- X call flush ;Write the buffer
- X
- X push dx ;dx contains offset within byte
- X add dx,nbits ;adjust by code size
- X mov bit_offset,dx ;new bit offset
- X pop dx ;restore dx
- X
- ;ax is an index into output buffer. Next, ax <- address of buffer[ax]
- X add ax,[_out_buf_adr]
- X mov si,ax ;put in si
- X mov al,byte ptr [si] ;move byte to first position
- X
- ;put value of al into first byte of output buffer
- X push bx
- X mov bx,[_out_buf_adr]
- X mov [bx],al
- X pop bx
- X xor ax,ax ;Byte offset of zero
- wc1: add ax,[_out_buf_adr] ;Point into buffer
- X mov di,ax ;Destination
- X pop ax ;Restore code
- X mov cx,dx ;offset within byte
- X xor dx,dx ;dx will catch bits rotated out
- X jcxz wc3 ;If offset in byte is zero, skip shift
- wc2: shl ax,1 ;Rotate code
- X rcl dx,1
- X loop wc2
- X or al,byte ptr [di] ;Grab bits currently in buffer
- wc3: stosw ;Save data
- X mov al,dl ;Grab extra bits
- X stosb ;and save
- X ret
- write_code endp
- X
- flush proc near
- X push ax ;Save all registers
- X push bx ;AX contains number of bytes to write
- X push cx
- X push dx
- X
- X push si ;may not be necessary to save si & di
- X push di
- X
- X push ax ;save byte count
- X
- X push ax ;byte count
- X push _out_buf_adr ;buffer address
- X push output_handle ;zoofile
- ifdef UNBUF_IO
- X call _blockwrite
- else
- X call _zoowrite
- endif
- X add sp,6
- X
- X pop cx ;recover byte count
- X
- X cmp ax,cx
- X
- X jz here2
- X jmp IO_err ;I/O error
- X
- here2:
- X pop di
- X pop si
- X
- X pop dx
- X pop cx
- X pop bx
- X pop ax
- X ret
- flush endp
- X
- lookup_code proc near
- X push ds ;Save seg reg
- X mov ds,hash_seg ;point to hash table
- X
- X ;call index ;convert code to address
- X call_index ;macro for speed
- X
- X mov di,0 ;flag
- X mov bx,[si].first
- X cmp bx,-1 ;Has this code been used?
- X je gc4 ;equal means no
- X inc di ;set flag
- gc2:
- X ;call index ;convert code to address
- X call_index ;macro for speed
- X
- X cmp [si].char,al ;is char the same?
- X jne gc3 ;ne means no
- X clc ;success
- X mov ax,bx ;put found code in ax
- X pop ds ;restore seg reg
- X ret ;done
- gc3:
- X mov bx,[si].next
- X cmp bx,-1 ;More left with this prefix?
- X je gc4 ;equal means no
- X jmp gc2 ;try again
- gc4: stc ;not found
- X pop ds ;restore seg reg
- X ret ;done
- lookup_code endp
- X
- comment #
- index proc near
- X mov si,bx ;si = bx * 5 (5 byte hash entries)
- X shl si,1 ;si = bx * 2 * 2 + bx
- X shl si,1
- X add si,bx
- X ret
- index endp
- # end comment
- X
- check_ratio proc near
- X push ax
- X
- ; mov dl,'*' ;'*' printed means checking ratio
- ; call sendout
- X
- X ;Getting ready to check ratios. If bitsout is over scale_limit,
- X ;then we scale down both bitsout and bytesin by a factor
- X ;of 4. This will avoid overflow.
- X mov cx,[bitsout]
- X cmp cx,scale_limit
- X jb scale_ok
- X
- X mov cl,2
- X shr [bytesin],cl
- X shr [bitsout],cl
- X
- scale_ok:
- X ;Note MASM bug: "mov ah,high [bytesin]" and
- X ;"mov al,low [bytesin]" don't work.
- X mov ah,byte ptr [bytesin]
- X mov dl,byte ptr [bytesin+1]
- X
- X sub al,al
- X sub dh,dh ;dx:ax = 8 * bitsin = 256 * bytesin
- X mov cx,[bitsout] ;cx <- bitsout
- X or cx,cx ;Division by zero?
- X jnz candivide ;No -- go ahead divide
- X mov ax,0FFFFH ;yes -- assume max poss value
- X jmp short divided
- candivide:
- X ;Calculate cx as (bytesin * 256) / bitsout = bitsin * 8 / bitsout
- X div cx ;ax <- rat <- dx:ax / cx
- X shl ax,1
- X shl ax,1 ;rat <- 4 * bytes_in / bytes_out
- divided:
- X ;Enter here with ax = rat = bitsin / bitsout.
- X
- ; call print_data ;print info for debugging
- X
- X ;If rat > rat_thresh then ratio is good; do not reset table
- ; cmp ax,rat_thresh
- ; ja ratdone
- X
- X ;Compare rat against ratio
- X mov bx,ax ;save rat in bx
- X cmp ax,[ratio] ;cmp rat,ratio
- X jb ratless ;trouble if ratio is now smaller
- X mov ax,[ratio]
- X call mul7 ;ax <- 7 * ratio
- X add ax,bx ;ax = 7 * ratio + rat
- X shr ax,1
- X shr ax,1
- X shr ax,1 ;ax = (7 * ratio + rat) / 8
- X mov [ratio],ax ;ratio = (7 * ratio + rat) / 8
- X jmp short ratdone
- ratless: ;ratio is going down, so...
- X mov [bytesin],0
- X mov [bitsout],0
- X
- ; mov dl,'#' ;'#' printed means table reset
- ; call sendout
- X
- X mov ax,clear ;Write a clear code
- X call write_code
- X call init_table ;Reinit table
- ratdone:
- X mov [ratflag],0
- X mov [bit_interval],check_gap
- X pop ax
- X ret
- check_ratio endp
- X
- comment #
- sendout proc near ;char in dl send to console
- X push ax
- X mov ah,02
- X int 21H
- X pop ax
- X ret
- sendout endp
- # end comment
- X
- mul7 proc near ;multiply ax by 7
- X push dx
- X mov dx,7
- X mul dx ;dx:ax <- 7 * ax
- X pop dx
- X ret
- mul7 endp
- X
- comment #
- mul3 proc near ;multiply ax by 3
- X push dx
- X mov dx,3
- X mul dx ;dx:ax <- 3 * ax
- X pop dx
- X ret
- mul3 endp
- # end comment
- X
- comment #
- mul1_125 proc near ;multiply ax by 1.125
- X push bx
- X mov bx,ax
- X shr bx,1
- X shr bx,1
- X shr bx,1 ;bx = n / 8
- X add ax,bx ;ax <- n + n / 8
- X pop bx
- X ret
- mul1_125 endp
- # end comment
- X
- comment #
- print_data proc near
- X ;Debugging -- print bytesin, bitsout, rat, and ratio
- X push ax
- X push bx
- X push cx
- X push dx
- X
- X push ax ;print rat
- X call _prtint
- X add sp,2
- X
- X push [ratio] ;print ratio
- X call _prtint
- X add sp,2
- X
- X push [bytesin]
- X call _prtint
- X add sp,2
- X
- X push [bitsout]
- X call _prtint
- X add sp,2
- X
- X pop dx
- X pop cx
- X pop bx
- X pop ax
- X ret
- print_data endp
- # end comment
- X
- ;doread reads cx characters and stores them in input buffer
- ;return value from zooread is returned in ax
- doread proc near ;reads block
- X push bx
- X push cx
- X push dx
- X push si
- X push di
- X
- X push cx ;byte count
- X push _in_buf_adr ;buffer address
- X push input_handle ;zoofile
- ifdef UNBUF_IO
- X call _read
- else
- X call _zooread
- endif
- X add sp,6
- X
- X pop di
- X pop si
- X pop dx
- X pop cx
- X pop bx
- X ret
- doread endp
- X
- _text ends
- X
- end
- X
- SHAR_EOF
- chmod 0644 lzc.asm ||
- echo 'restore of lzc.asm failed'
- Wc_c="`wc -c < 'lzc.asm'`"
- test 12283 -eq "$Wc_c" ||
- echo 'lzc.asm: original size 12283, current size' "$Wc_c"
- fi
- # ============= lzc.c ==============
- if test -f 'lzc.c' -a X"$1" != X"-c"; then
- echo 'x - skipping lzc.c (File already exists)'
- else
- echo 'x - extracting lzc.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'lzc.c' &&
- #ifndef LINT
- static char sccsid[]="@(#) lzc.c 2.6 88/01/30 18:39:15";
- #endif /* LINT */
- X
- /*
- Lempel-Ziv compression. Mostly based on Tom Pfau's assembly language
- code.
- X
- The contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1986/12/31
- */
- X
- #include "options.h"
- #include "zoo.h"
- #include "zooio.h"
- #include "various.h"
- #include "zoofns.h" /* function definitions */
- /* zoomem.h defines IN_BUF_SIZE & OUT_BUF_SIZE */
- #include "zoomem.h"
- #include "debug.h"
- #include "assert.h"
- /* lzconst.h contains constants for lzd() and lzc() */
- #include "lzconst.h"
- X
- void init_ctab PARMS((void));
- void wr_ccode PARMS((int));
- int rd_cch PARMS((void));
- int lukup_ccode PARMS((int, int, int *));
- void ad_ccode PARMS((int, int, int));
- void check_ratio PARMS((void));
- void flush_c PARMS((int));
- X
- /* interval at which to check ratio */
- #define CHECKGAP 4000
- #define NEXT_USE 1
- #define FIRST_USE 2
- #define FOUND 0
- X
- struct tabentry {
- X int first;
- X int next;
- X char z_ch;
- };
- X
- extern char *out_buf_adr;
- extern char *in_buf_adr;
- extern char memflag; /* memory allocated? */
- struct tabentry *table; /* this table also used by lzd.c */
- static unsigned int free_code;
- static int nbits;
- static unsigned int max_code;
- static unsigned int bitsout;
- static int bit_interval;
- static unsigned int bytesin, ratio, ratflag;
- static unsigned int in_offset, in_size;
- static unsigned int bit_offset;
- X
- #ifdef UNBUF_IO
- #define BLOCKFILE int
- #define BLOCKREAD read
- #define BLOCKWRITE write
- int read PARMS ((int, VOIDPTR, unsigned));
- int write PARMS ((int, VOIDPTR, unsigned));
- #else
- #define BLOCKFILE ZOOFILE
- #define BLOCKREAD zooread
- #define BLOCKWRITE zoowrite
- #endif /* UNBUF_IO */
- X
- static BLOCKFILE in_f, out_f;
- X
- int lzc (input_f, output_f)
- BLOCKFILE input_f, output_f;
- {
- X int nextch, prefix_code, k;
- X int status;
- X int where;
- X
- X in_f = input_f;
- X out_f = output_f;
- X
- X bit_offset = in_offset = in_size = 0;
- X
- X if (memflag == 0) {
- X table = (struct tabentry *) ealloc((MAXMAX+10) * sizeof(struct tabentry));
- X memflag++;
- X }
- X
- X init_ctab();
- X wr_ccode(CLEAR);
- X nextch = rd_cch();
- X if (nextch == EOF) { /* note real EOF, not Z_EOF */
- X wr_ccode (Z_EOF);
- X flush_c ((int) ((bit_offset + 7) / 8));
- X return (0); /* normal return from compress */
- X }
- X
- X /* compression loop begins here with nextch holding the next input char */
- loop1:
- X if (ratflag != 0)
- X check_ratio();
- X nextch &= 0xff; /* turn character to code */
- X assert(nextch < 256);
- loop2:
- X prefix_code = nextch;
- X nextch = rd_cch();
- X if (nextch == EOF) { /* note real EOF, not Z_EOF */
- X wr_ccode (prefix_code);
- X wr_ccode (Z_EOF);
- X flush_c ((int) ((bit_offset + 7) / 8));
- X return (0); /* normal return from compress */
- X }
- X nextch &= 0xff; /* force to 8 bits */
- X assert(nextch < 256);
- X
- X k = nextch;
- X status = lukup_ccode (prefix_code, nextch, &where);
- X if (status == FOUND) {
- X nextch = where; /* where found */
- X goto loop2;
- X }
- X assert(status == FIRST_USE || status == NEXT_USE);
- X
- X /* reach here with status = FIRST_USE or NEXT_USE */
- X ad_ccode (status, nextch, where);
- X
- X wr_ccode (prefix_code);
- X nextch = k;
- X
- X if (free_code <= max_code)
- X goto loop1;
- X assert(nbits >= 9 && nbits <= MAXBITS);
- X if (nbits >= MAXBITS) {
- X /* To continue using table after it is full, remove next two lines */
- X wr_ccode (CLEAR);
- X init_ctab();
- X
- X goto loop1;
- X }
- X
- X nbits++;
- X assert(nbits >= 9 && nbits <= MAXBITS);
- X max_code = max_code << 1;
- X goto loop1;
- } /* end lzc() */
- X
- void wr_ccode (code)
- int code;
- {
- X unsigned int ofs_inbyte, hibits;
- X int byte_offset;
- X
- #ifdef DEBUG
- if (code == CLEAR)
- X printf(" CLEAR\n");
- #endif
- X
- X assert(nbits >= 9 && nbits <= MAXBITS);
- X bitsout += nbits; /* total number of bits written */
- X bit_interval -= nbits;
- X if (bit_interval < 0)
- X ratflag = 1; /* time to check ratio */
- X
- X byte_offset = bit_offset / 8;
- X ofs_inbyte = bit_offset % 8; /* offset within byte */
- X bit_offset += nbits; /* allowing for new code */
- X
- X if (byte_offset >= OUTBUFSIZ - 4) {
- X flush_c (byte_offset);
- X bit_offset = ofs_inbyte + nbits;
- X out_buf_adr[0] = out_buf_adr [byte_offset];
- X byte_offset = 0;
- X }
- X
- X code = code & 0xffff; /* force to 16 bits */
- X
- X if (ofs_inbyte == 0)
- X out_buf_adr[byte_offset] = code & 0xff;
- X else
- X out_buf_adr[byte_offset] |= (code << ofs_inbyte) & 0xff;
- X
- X hibits = ((unsigned int) code) >> (8 - ofs_inbyte);
- X out_buf_adr[byte_offset+1] = hibits & 0xff;
- X out_buf_adr[byte_offset+2] = (((unsigned int) hibits) >> 8) & 0xff;
- X
- X assert(nbits >= 9 && nbits <= MAXBITS);
- } /* end wr_ccode() */
- X
- void init_ctab()
- {
- X int i;
- X bytesin = bitsout = ratio = ratflag = 0;
- X bit_interval = CHECKGAP;
- X nbits = 9;
- X max_code = 512;
- #ifdef COMMENT
- X for (i = 0; i < 256; i++) {
- #endif
- X for (i = 0; i < MAXMAX+1; i++) {
- X table[i].z_ch = table[i].first = table[i].next = -1;
- X }
- #ifdef COMMENT
- X /*DEBUG*/ table[MAXMAX].first = table[MAXMAX].next = -1;
- X /*DEBUG*/ table[MAXMAX-1].first = table[MAXMAX-1].next = -1;
- #endif
- X free_code = FIRST_FREE;
- } /* end init_ctab() */
- X
- int rd_cch()
- {
- X int count;
- X bytesin++;
- X if (in_offset == in_size) {
- X count = BLOCKREAD (in_f, in_buf_adr, INBUFSIZ);
- X if (count == -1)
- X prterror ('f', "Error reading input file during compression.\n");
- X addbfcrc (in_buf_adr, count);
- X if (count == 0) {
- X debug((printf("\nEOF on input\n")))
- X return (EOF); /* real EOF, not Z_EOF */
- X }
- X in_size = count;
- X debug((printf("\ninput %d chars\n", count)))
- X in_offset = 0;
- X }
- X in_offset++;
- X return (in_buf_adr[in_offset-1] & 0xff);
- } /* end rd_cch () */
- X
- void check_ratio()
- {
- #ifdef COMMENT
- X int rat;
- X if (bitsout > 16383) { /* avoid overflow */
- X bitsout /= 4;
- X bytesin /= 4;
- X }
- X rat = (2 * bitsout) / bytesin;
- X if (1.1 * rat < ratio) {
- X printf("#");
- X wr_ccode (CLEAR);
- X init_ctab();
- X bit_interval = CHECKGAP;
- X bitsout = 0;
- X bytesin = 0;
- X ratio = 0;
- X } else
- X ratio = ((ratio << 2) + ((2 * bitsout) / bytesin)) / 5;
- #else
- X bit_interval = CHECKGAP;
- X bitsout = 0;
- X bytesin = 0;
- #endif
- } /* end check_ratio() */
- X
- void ad_ccode (status, ch, index)
- int status, index, ch;
- {
- X assert(status == FIRST_USE || status == NEXT_USE);
- #ifdef COMMENT
- X if (free_code >= MAXMAX) /* to fix apparent bug in original */
- X return;
- #endif
- #ifdef COMMENT
- X if (status == NEXT_USE)
- X table[index].next = free_code;
- X else /* else must be FIRST_USE */
- X table[index].first = free_code;
- #endif
- X if (status == NEXT_USE)
- X table[index].next = (free_code >= MAXMAX ? -1 : free_code);
- X else /* else must be FIRST_USE */
- X table[index].first = (free_code >= MAXMAX ? -1 : free_code);
- X
- #ifdef COMMENT
- X if (free_code < MAXMAX) {
- #endif
- X if (free_code <= MAXMAX) {
- X table[free_code].first = table[free_code].next = -1;
- X table[free_code].z_ch = ch & 0xff;
- X free_code++;
- X }
- } /* end ad_ccode() */
- X
- int lukup_ccode (index, ch, where)
- int index; /* where to start looking */
- int ch; /* char to look for */
- int *where; /* last entry looked at */
- {
- X *where = index;
- X index = table[index].first;
- X if (index == -1) {
- X return (FIRST_USE); /* not found, first use */
- X } else {
- X while (1) {
- X if ((table[index].z_ch & 0xff) == (ch & 0xff)) {
- X *where = index;
- X return (FOUND);
- X }
- X *where = index;
- X index = table[index].next;
- X if (index == -1) {
- X return (NEXT_USE);
- X }
- X } /* end while */
- X } /* end else */
- } /* end lukup_ccode() */
- X
- void flush_c (count)
- int count;
- {
- X int status;
- #ifdef DEBUG
- printf(" <flushed %d bytes> ", count);
- #endif
- X
- #ifdef CHECK_BREAK
- X check_break();
- #endif
- X
- X if (count != 0) {
- X status = BLOCKWRITE (out_f, out_buf_adr, count);
- X if (status == -1)
- X prterror ('f', "Error writing during compression.\n");
- X }
- }
- SHAR_EOF
- chmod 0644 lzc.c ||
- echo 'restore of lzc.c failed'
- Wc_c="`wc -c < 'lzc.c'`"
- test 8393 -eq "$Wc_c" ||
- echo 'lzc.c: original size 8393, current size' "$Wc_c"
- fi
- # ============= lzconst.h ==============
- if test -f 'lzconst.h' -a X"$1" != X"-c"; then
- echo 'x - skipping lzconst.h (File already exists)'
- else
- echo 'x - extracting lzconst.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'lzconst.h' &&
- /* @(#) lzconst.h 2.1 87/12/25 12:22:30 */
- X
- /*
- The contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1986/12/31
- */
- X
- #define INBUFSIZ (IN_BUF_SIZE - 10) /* avoid obo errors */
- #define OUTBUFSIZ (OUT_BUF_SIZE - 10)
- #define MEMERR 2
- #define IOERR 1
- #define MAXBITS 13
- #define CLEAR 256 /* clear code */
- #define Z_EOF 257 /* end of file marker */
- #define FIRST_FREE 258 /* first free code */
- #define MAXMAX 8192 /* max code + 1 */
- SHAR_EOF
- chmod 0644 lzconst.h ||
- echo 'restore of lzconst.h failed'
- Wc_c="`wc -c < 'lzconst.h'`"
- test 574 -eq "$Wc_c" ||
- echo 'lzconst.h: original size 574, current size' "$Wc_c"
- fi
- true || echo 'restore of lzd.asm failed'
- echo End of part 3, continue with part 4
- exit 0
-