[comp.sources.misc] v17i068: freeze - Freeze/Melt compression package, Part02/02

leo@s514.ipmce.su (Leonid A. Broukhis) (03/25/91)

Submitted-by: Leonid A. Broukhis <leo@s514.ipmce.su>
Posting-number: Volume 17, Issue 68
Archive-name: freeze/part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents:  Contents debug.c decode.c default.c freeze.h huf.h lz.c
#   lz.h makefile
# Wrapped by kent@sparky on Sun Mar 24 20:41:08 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 2 (of 2)."'
if test -f 'Contents' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Contents'\"
else
  echo shar: Extracting \"'Contents'\" \(706 characters\)
  sed "s/^X//" >'Contents' <<'END_OF_FILE'
X       This package contalns:
X-rw-------   1    6234 Mar 21 21:44 README
X-rw-------   1    1650 Mar 20 12:49 bitio.c
X-rw-------   1    1567 Mar 20 12:49 debug.c
X-rw-------   1    1023 Mar 20 12:50 decode.c
X-rw-rw-r--   1    1155 Mar 20 12:49 default.c
X-rw-------   1    3800 Mar 20 13:02 encode.c
X-rw-r--r--   1    5973 Mar 21 21:56 freeze.1
X-rw-------   1   16740 Mar 21 21:56 freeze.c
X-rw-------   1    2495 Mar 20 12:49 freeze.h
X-rw-------   1    8291 Mar 20 12:58 huf.c
X-rw-------   1     201 Mar 20 12:50 huf.h
X-rw-------   1    2451 Mar 20 12:49 lz.c
X-rw-------   1    1547 Mar 20 12:50 lz.h
X-rw-rw-r--   1    1248 Mar 20 12:50 makefile
X-rw-------   1    4475 Mar 20 12:50 statist.c
XTotal: 15 files.
END_OF_FILE
  if test 706 -ne `wc -c <'Contents'`; then
    echo shar: \"'Contents'\" unpacked with wrong size!
  fi
  # end of 'Contents'
fi
if test -f 'debug.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'debug.c'\"
else
  echo shar: Extracting \"'debug.c'\" \(1567 characters\)
  sed "s/^X//" >'debug.c' <<'END_OF_FILE'
X#ifdef DEBUG
X#include "freeze.h"
X
X		  /*---------------------------*/
X		  /*      DEBUG      MODULE    */
X		  /*---------------------------*/
X
Xprintcodes()
X{
X    /*
X     * Just print out codes from input file.  For debugging.
X     */
X    register short k, c, col = 0;
X#ifdef COMPAT
X    if(new_flg)
X#endif
X	if(read_header() == EOF) {
X		fprintf(stderr, "Bad header\n");
X		return;
X	}
X    StartHuff();
X    for (;;) {
X#ifdef COMPAT
X	    c = new_flg ? DecodeChar() : DecodeCOld();
X#else
X	    c = DecodeChar();
X#endif
X	    if (c == ENDOF)
X		    break;
X	    if (c < 256) {
X		fprintf(stderr, "%5d%c", c,
X			(col+=8) >= 74 ? (col = 0, '\n') : '\t' );
X	    } else {
X		c = c - 256 + THRESHOLD;
X#ifdef COMPAT
X		k = new_flg ? DecodePosition() : DecodePOld();
X#else
X		k = DecodePosition();
X#endif
X		fprintf(stderr, "%2d-%d%c", c, k,
X			(col+=8) >= 74 ? (col = 0, '\n') : '\t' );
X	    }
X    }
X    putc( '\n', stderr );
X    exit( 0 );
X}
X
X/* for pretty char printing */
X
Xchar *
Xpr_char(c)
X	register uchar c;
X{
X	static char buf[5];
X	register i = 4;
X	buf[4] = '\0';
X	if ( (isascii((int)c) && isprint((int)c) && c != '\\') || c == ' ' ) {
X	    buf[--i] = c;
X	} else {
X	    switch( c ) {
X	    case '\n': buf[--i] = 'n'; break;
X	    case '\t': buf[--i] = 't'; break;
X	    case '\b': buf[--i] = 'b'; break;
X	    case '\f': buf[--i] = 'f'; break;
X	    case '\r': buf[--i] = 'r'; break;
X	    case '\\': buf[--i] = '\\'; break;
X	    default:
X		buf[--i] = '0' + c % 8;
X		buf[--i] = '0' + (c / 8) % 8;
X		buf[--i] = '0' + c / 64;
X		break;
X	    }
X	    buf[--i] = '\\';
X	}
X	return &buf[i];
X}
X#endif
END_OF_FILE
  if test 1567 -ne `wc -c <'debug.c'`; then
    echo shar: \"'debug.c'\" unpacked with wrong size!
  fi
  # end of 'debug.c'
fi
if test -f 'decode.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'decode.c'\"
else
  echo shar: Extracting \"'decode.c'\" \(1023 characters\)
  sed "s/^X//" >'decode.c' <<'END_OF_FILE'
X#include "freeze.h"
X
X/*
X * Melt stdin to stdout.
X */
X
Xmelt ()
X{
X	register short    i, j, k, n, r, c;
X#ifdef COMPAT
X	if(new_flg)
X#endif
X	if(read_header() == EOF)
X		return;
X
X	StartHuff();
X	n = N;
X	for (i = 0; i < n - F; i++)
X		text_buf[i] = ' ';
X	r = n - F;
X	n --;   /* array size --> mask */
X	for (in_count = 0;; ) {
X		c =
X#ifdef COMPAT
X		new_flg ? DecodeChar() : DecodeCOld();
X#else
X		DecodeChar();
X#endif
X		if (c == ENDOF)
X			break;
X		if (c < 256) {
X			putchar (c);
X			text_buf[r++] = c;
X			r &= n;
X			in_count++;
X		} else {
X			i = (r -
X#ifdef COMPAT
X				(new_flg ? DecodePosition() : DecodePOld())
X#else
X				DecodePosition()
X#endif
X				- 1) & n;
X			j = c - 256 + THRESHOLD;
X			for (k = 0; k < j; k++) {
X				c = text_buf[(i + k) & n];
X				putchar (c);
X				text_buf[r++] = c;
X				r &= n;
X				in_count++;
X			}
X		}
X
X		if (!quiet && (in_count > indicator_count)) {
X			fprintf(stderr, "%5dK\b\b\b\b\b\b", in_count / 1024);
X			fflush (stderr);
X			indicator_count += indicator_threshold;
X			indicator_threshold += 1024;
X		}
X	}
X}
END_OF_FILE
  if test 1023 -ne `wc -c <'decode.c'`; then
    echo shar: \"'decode.c'\" unpacked with wrong size!
  fi
  # end of 'decode.c'
fi
if test -f 'default.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'default.c'\"
else
  echo shar: Extracting \"'default.c'\" \(1155 characters\)
  sed "s/^X//" >'default.c' <<'END_OF_FILE'
X#include <stdio.h>
X
X#define OK      0
X#define FAIL    NULL
X#define NOFILE  ((FILE *) 0)
X#define MAXLINE 128
X
Xextern int      errno;
Xchar            *strchr();
Xstatic FILE     *defd = NOFILE;  /* defaults file stream */
X
Xint     defopen(fname)          /* open | reopen | close defaults file */
X	char    *fname;
X{
X	register FILE   *fd;
X
X	if (!fname) {
X		if (defd)
X			fclose(defd);
X		defd = NOFILE;
X		return OK;
X	}
X
X	if (!(fd = fopen(fname, "r")))
X		return errno;                   /* problems opening file */
X
X	defd = fd;
X	return OK;
X}
X
Xstatic char     defline[MAXLINE + 1];
X
Xchar    *defread(pattern)
X	register char   *pattern;
X{
X	register        sz_patt;
X	register char   *cp;
X
X	if (!defd)
X		return FAIL;            /* defaults file not opened */
X
X	rewind(defd);
X	sz_patt = strlen(pattern);
X
X	while (fgets(defline, MAXLINE, defd)) {
X		if (!(cp = strchr(defline, '\n')))
X			return FAIL;     /* line too long  */
X		if (cp - defline < sz_patt)
X			continue;       /* line too short */
X		*cp = '\0';
X		if (!strncmp(pattern, defline, sz_patt))
X			return defline + sz_patt;       /* match found */
X	}
X
X	return FAIL;                    /* no matching lines */
X}
END_OF_FILE
  if test 1155 -ne `wc -c <'default.c'`; then
    echo shar: \"'default.c'\" unpacked with wrong size!
  fi
  # end of 'default.c'
fi
if test -f 'freeze.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'freeze.h'\"
else
  echo shar: Extracting \"'freeze.h'\" \(2495 characters\)
  sed "s/^X//" >'freeze.h' <<'END_OF_FILE'
X
X#include <stdio.h>
X
X/* for GCC */
X
X#ifdef SUN4
X#include <sys/stdtypes.h>
X#else
X  typedef int mode_t; /* for GCC */
X# ifndef getc
X#   define getc(p)         (--(p)->_cnt < 0 ? _filbuf(p) : (int) *(p)->_ptr++)
X# endif
X# ifndef putc
X#   define putc(x, p)      (--(p)->_cnt < 0 ? _flsbuf((unsigned char) (x), (p)) : (int) (*(p)->_ptr++ = (unsigned char) (x)))
X# endif
X  typedef unsigned short u_short;
X#endif
X
X/* end (for GCC) */
X
X#include <ctype.h>
X#include <signal.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#ifdef DEBUG
X#include <assert.h>
X#endif
X
X#ifdef __TURBOC__
X#define MSDOS
X#include <io.h>
X#endif
X
X#ifdef MSDOS
X#include <stdlib.h>
X#endif
X
Xtypedef unsigned char uchar;
X
X#if defined(BITS) && BITS > 14
Xtypedef unsigned long hash_t;
X#else
Xtypedef u_short hash_t;
X#endif
X
X#ifdef  lint
X#define N               256
X#else
X#define N               8192    /* buffer size */
X#endif
X
X#define F               256     /* pre-sence buffer size */
X#define THRESHOLD	2
X
X#define _NCHAR         (256 - THRESHOLD + _F + 1) /* {code : 0 .. N_CHAR-1} */
X
X#define _T              (_NCHAR * 2 - 1)        /* size of table */
X#define _R              (_T - 1)                 /* root position */
X#define _NN             8092
X#define _F              256
X
X#ifndef COMPAT
X#define N_CHAR          _NCHAR
X#define T               _T
X#define R               _R
X#else
X#define _FO             60
X#define _NO             4096
X#define _NCHARO        (256 - THRESHOLD + _FO + 1)
X#define _TO             (_NCHARO * 2 - 1)
X#define _RO             (_TO - 1)
X#define N_CHAR          (new_flg ? _NCHAR : _NCHARO)
X#define T               (new_flg ? _T : _TO)
X#define R               (new_flg ? _R : _RO)
X#endif
X
X#define ENDOF           256
X
Xextern uchar   Table[];
X
Xextern long in_count, bytes_out;
X
Xextern uchar    text_buf[];
Xextern u_short   match_position, match_length;
X
Xextern short quiet;
X
X/* Note indicator_threshold is triangle number of Kbytes */
X
Xextern unsigned long indicator_threshold, indicator_count;
X
Xextern short do_melt, topipe;
X
Xextern uchar magic_header[];
X
Xextern int exit_stat;
X
Xextern short new_flg;
X
X#ifdef DEBUG
Xextern short debug;
Xextern short verbose;
Xextern char * pr_char();
Xextern long symbols_out, refers_out;
X#endif /* DEBUG */
X
X#ifdef GATHER_STAT
Xextern long node_steps, node_matches;
X#endif
X
Xextern short DecodeChar(), DecodePosition(),
X	     GetByte(), GetNBits();
X
X#ifdef COMPAT
Xextern short DecodeCOld(), DecodePOld();
X#endif
X
X#if defined(BSD42) && !defined(BSD4_2)
X#define BSD4_2
X#endif
END_OF_FILE
  if test 2495 -ne `wc -c <'freeze.h'`; then
    echo shar: \"'freeze.h'\" unpacked with wrong size!
  fi
  # end of 'freeze.h'
fi
if test -f 'huf.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'huf.h'\"
else
  echo shar: Extracting \"'huf.h'\" \(201 characters\)
  sed "s/^X//" >'huf.h' <<'END_OF_FILE'
Xextern u_short getbuf;
Xextern uchar    getlen;
X
Xextern uchar corrupt_flag;
X
Xextern u_short putbuf;
Xextern uchar putlen;
X
X#define MAX_FREQ        (u_short)0x8000 /* tree update timing from frequency */
END_OF_FILE
  if test 201 -ne `wc -c <'huf.h'`; then
    echo shar: \"'huf.h'\" unpacked with wrong size!
  fi
  # end of 'huf.h'
fi
if test -f 'lz.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lz.c'\"
else
  echo shar: Extracting \"'lz.c'\" \(2451 characters\)
  sed "s/^X//" >'lz.c' <<'END_OF_FILE'
X#include "freeze.h"
X#include "lz.h"
X
X/*----------------------------------------------------------------------*/
X/*									*/
X/*                          LZSS ENCODING                               */
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#define NIL		N	/* term of tree */
X
Xuchar    text_buf[N + _F - 1];
Xu_short   match_position, match_length;
X
X/* next[N+1..] is used as hash table,
X	the rest of next is a link down,
X	prev is a link up.
X*/
X
Xhash_t             prev[N + 1];
X#ifndef __XENIX__
Xu_short            next[array_size];
X#else
X#if parts == 2
Xu_short next0[32768], next1[8193];
X#elif parts == 3
Xu_short next0[32768], next1[32768], next2[8193];
X#elif parts == 5
Xu_short next0[32768], next1[32768], next2[32768], next3[32768], next4[8193];
X#else
Xu_short next0[32768], next1[32768], next2[32768], next3[32768], next4[32768],
X	next5[32768], next6[32768], next7[32768], next8[8193];
X#endif
X
Xu_short *next[parts] = {
Xnext0, next1
X#if parts > 2
X,next2
X#if parts > 3
X,next3, next4
X#if parts > 5
X,next5, next6,
Xnext7, next8
X#endif
X#endif
X#endif
X};
X#endif
X
X
X#ifdef GATHER_STAT
Xlong node_steps, node_matches;
X#endif
X
X/* Initialize Tree */
XInitTree ()
X{
X	long i;
X#ifdef GATHER_STAT
X	node_steps = node_matches = 0;
X#endif
X
X	for (i = N + 1; i < array_size; i++ )
X		nextof(i) = NIL;
X	for (i = 0; i < sizeof(prev)/sizeof(*prev); i++ )
X		prev[i] = NIL;
X}
X
X/* Get next match */
XGet_Next_Match (r)
X	u_short r;
X{
X	register uchar  *key;
X	register u_short        m, i, p;
X#ifdef GATHER_STAT
X	node_matches++;
X#endif
X	key = &text_buf[p = r];
X	m = 0;
X	while (m < _F) {
X		if ((p = nextof(p)) == NIL) {
X			match_length = m;
X			return;
X		}
X
X/* This statement is due to ideas of Boyer and Moore: */
X
X		if(key[m] != text_buf[p + m])
X			continue;
X
X/* This statement is due to my ideas: :-) */
X/* It gives up to 8% speedup on files with big redundancy (text, etc.) */
X
X		if(key[m >> 1] != text_buf[p + (m >> 1)])
X			continue;
X
X#ifdef GATHER_STAT
X		node_steps++;
X#endif
X
X/* This statement doesn't take a lot of execution time -
X	about 20% (in profiling we trust)
X*/
X		for (i = 0; i < _F && key[i] == text_buf[p + i];  i++);
X
X		if (i > m) {
X			match_position = ((r - p) & (N - 1)) - 1;
X			m = i;
X		}
X	}
X#ifdef DEBUG
X	if (verbose)
X		fprintf(stderr, "Replacing node: %d -> %d\n", p, r);
X#endif
X	nextof(prev[p]) = nextof(p);
X	prev[nextof(p)] = prev[p];
X	prev[p] = NIL;  /* remove p, it is further than r */
X	match_length = _F;
X}
END_OF_FILE
  if test 2451 -ne `wc -c <'lz.c'`; then
    echo shar: \"'lz.c'\" unpacked with wrong size!
  fi
  # end of 'lz.c'
fi
if test -f 'lz.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lz.h'\"
else
  echo shar: Extracting \"'lz.h'\" \(1547 characters\)
  sed "s/^X//" >'lz.h' <<'END_OF_FILE'
X#ifndef BITS
X#define BITS    14      /* for 16-bits machines */
X#endif
X
X#if BITS < 13
X#undef BITS
X#define BITS    13      /* 1:1 hash */
X#endif
X
X#if BITS > 21
X#undef BITS
X#define BITS    21      /* 4 MB hash table, if sizeof(u_short) == 2 */
X#endif
X
X#define LEN0    (BITS/3 + (BITS%3 != 0))
X#define LEN1    (BITS/3 + (BITS%3 == 2))
X#define LEN2    (BITS/3)
X
X#define MASK0   ((1 << LEN0) - 1)
X#define MASK1   ((1 << LEN1) - 1)
X#define MASK2   ((1 << LEN2) - 1)
X
X#define NIL     N
X
X#if defined(M_XENIX) && defined(I_286) && (BITS > 14)
X#define __XENIX__
X#if BITS > 18
X#undef BITS
X#define BITS 18
X#endif
X#endif
X
X#define array_size      (N + 1 + (1 << BITS))
X
X#ifndef __XENIX__
X#define nextof(i)       next[i]
X#else
X#define parts (array_size/32768 + 1)
X#define nextof(i)       next[(i) >> 15][(i) & 0x7fff]
X#endif
X
X/* To eliminate function-call overhead */
X
X#define DeleteNode(n) \
X{\
X       nextof(prev[n]) = NIL;\
X       prev[n] = NIL;\
X}
X
X#define InsertNode(r)\
X{\
X	register hash_t p, first_son;\
X	register uchar  *key;\
X	key = &text_buf[r];\
X	p = N + 1 + (key[0] & MASK0) |\
X		    ((key[1] & MASK1) << LEN0) |\
X		    ((key[2] & MASK2) << (LEN0 + LEN1));\
X	first_son = nextof(p);\
X	nextof(r) = first_son;\
X	nextof(p) = r;\
X	prev[r] = p;\
X	prev[first_son] = r;\
X}
X
X#define Next_Char()\
Xif ((c = getchar()) != EOF) {\
X	text_buf[s] = c;\
X	if (s < _F - 1)\
X		text_buf[s + N] = c;\
X	s = (s + 1) & (N - 1);\
X	r = (r + 1) & (N - 1);\
X	InsertNode(r);\
X	in_count++;\
X} else {\
X	s = (s + 1) & (N - 1);\
X	r = (r + 1) & (N - 1);\
X	if (--len) InsertNode(r);\
X}
END_OF_FILE
  if test 1547 -ne `wc -c <'lz.h'`; then
    echo shar: \"'lz.h'\" unpacked with wrong size!
  fi
  # end of 'lz.h'
fi
if test -f 'makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile'\"
else
  echo shar: Extracting \"'makefile'\" \(1248 characters\)
  sed "s/^X//" >'makefile' <<'END_OF_FILE'
XDEST          = /usr/local/bin
XEXTHDRS	      =
XHDRS          = freeze.h\
X		lz.h\
X		huf.h
XLDFLAGS       =
XLIBS          = -lc_s   # shared library
X
XCC            = gcc 
X
XCFLAGS        = -DBITS=18 -O -DCOMPAT #-DBSD42 -DSUN4
X
XLINTFLAGS     = -DBITS=15 -DCOMPAT -DDEBUG -DGATHER_STAT
X
XMAKEFILE      = makefile
X
XOBJS          = bitio.o\
X		debug.o\
X		decode.o\
X		encode.o\
X		default.o\
X		freeze.o\
X		huf.o\
X		lz.o
X
XPROGRAM       = freeze
X
XSRCS          = bitio.c\
X		debug.c\
X		decode.c\
X		default.c\
X		encode.c\
X		freeze.c\
X		huf.c\
X		lz.c
X
Xall:            $(PROGRAM) statist freeze.man
X
Xlint:           $(SRCS)
X		lint $(LINTFLAGS) $(SRCS) $(LIBS)
X
X$(PROGRAM):     $(OBJS) 
X		$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM)
X
Xstatist: statist.c freeze.h lz.h huf.h
X		$(CC) $(CFLAGS) -UCOMPAT $(LDFLAGS) -o statist statist.c $(LIBS)
X
Xclean:;         rm -f *.o *.b .,* core a.out $(PROGRAM) statist
X
Xinstall:	$(PROGRAM)
X		install -s -c $(PROGRAM) $(DEST)
X		ln -f $(DEST)/freeze $(DEST)/melt
X		ln -f $(DEST)/freeze $(DEST)/fcat
X
Xfreeze.man:     freeze.1
X		nroff -man < freeze.1 > freeze.man
X
X###
Xbitio.o: freeze.h huf.h
Xdebug.o: freeze.h
Xdecode.o: freeze.h
Xencode.o: freeze.h lz.h
Xfreeze.o: freeze.h lz.h huf.h
Xhuf.o: freeze.h huf.h
Xlz.o: freeze.h
END_OF_FILE
  if test 1248 -ne `wc -c <'makefile'`; then
    echo shar: \"'makefile'\" unpacked with wrong size!
  fi
  # end of 'makefile'
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0
exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.