Path: utzoo!attcan!uunet!lll-winken!lll-tis!helios.ee.lbl.gov!pasteur!ucbvax!CORNELLC.CCS.CORNELL.EDU.BITNET!ewilts%Ins.MRC.AdhocNet.CA%Stasis.MRC.AdhocNet.CA%UNCAEDU.
From: ewilts%Ins.MRC.AdhocNet.CA%Stasis.MRC.AdhocNet.CA%UNCAEDU.@CORNELLC.CCS.CORNELL.EDU.BITNET (Ed Wilts)
Newsgroups: comp.os.vms
Subject: ARC_C.SHAR14_OF_19
Message-ID: <880624092809.02e@Ins.MRC.AdhocNet.CA>
Date: 24 Jun 88 15:28:06 GMT
Sender: usenet@ucbvax.BERKELEY.EDU
Organization: The Internet
Lines: 278
$Part15:
$ File_is="ARCSQ.C"
$ Check_Sum_is=290919933
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
Xstatic char *RCSid = "$Header: arcsq.c,v 1.2 86/07/15 07:54:05 turner Exp $";
X
X/*
X * $Log:`009arcsq.c,v $
X * Hack-attack 1.3 86/12/20 01:23:45 wilhite@usceast.uucp
X * `009Bludgeoned into submission for VAX 11/780 BSD4.2
X *`009(ugly code, but fewer core dumps)
X *
X * Revision 1.2 86/07/15 07:54:05 turner
X *
X *
X * Revision 1.1 86/06/26 15:00:48 turner
X * initial version
X *
X *
X */
X
X/* ARC - Archive utility - ARCSQ
X
X$define(tag,$$segment(@1,$$index(@1,=)+1))#
X$define(version,Version $tag(
XTED_VERSION DB =3.10), created on $tag(
XTED_DATE DB =01/30/86) at $tag(
XTED_TIME DB =20:10:46))#
X$undefine(tag)#
X $version
X
X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
X
X By: Thom Henderson
X
X Description:
X This file contains the routines used to squeeze a file
X when placing it in an archive.
X
X Language:
X Computer Innovations Optimizing C86
X
X Programming notes:
X Most of the routines used for the Huffman squeezing algorithm
X were lifted from the SQ program by Dick Greenlaw, as adapted
X to CI-C86 by Robert J. Beilstein.
X*/
X#include
X#include "arc.h"
X
X/* stuff for Huffman squeezing */
X
X#define TRUE 1
X#define FALSE 0
X#define ERROR (-1)
X#define SPEOF 256 /* special endfile token */
X#define NOCHILD (-1) /* marks end of path through tree */
X#define NUMVALS 257 /* 256 data values plus SPEOF*/
X#define NUMNODES (NUMVALS+NUMVALS-1) /* number of nodes */
X#define MAXCOUNT (unsigned INT) 65535 /* biggest unsigned integer */
X
X/* The following array of structures are the nodes of the
X binary trees. The first NUMVALS nodes become the leaves of the
X final tree and represent the values of the data bytes being
X encoded and the special endfile, SPEOF.
X The remaining nodes become the internal nodes of the final tree.
X*/
X
Xstruct nd /* shared by unsqueezer */
X{ unsigned INT weight; /* number of appearances */
X INT tdepth; /* length on longest path in tree */
X INT lchild, rchild; /* indices to next level */
X} node[NUMNODES]; /* use large buffer */
X
Xstatic INT dctreehd; /* index to head of final tree */
X
X/* This is the encoding table:
X The bit strings have first bit in low bit.
X Note that counts were scaled so code fits unsigned integer.
X*/
X
Xstatic INT codelen[NUMVALS]; /* number of bits in code */
Xstatic unsigned INT code[NUMVALS]; /* code itself, right adjusted */
Xstatic unsigned INT tcode; /* temporary code value */
Xstatic long valcount[NUMVALS]; /* actual count of times seen */
X
X/* Variables used by encoding process */
X
Xstatic INT curin; /* value currently being encoded */
Xstatic INT cbitsrem; /* # of code string bits left */
Xstatic unsigned INT ccode; /* current code right justified */
X
XINT init_sq() /* prepare for scanning pass */
X{
X INT i; /* node index */
X
X /* Initialize all nodes to single element binary trees
X with zero weight and depth.
X */
X
X for(i=0; i 16 bits long.
X */
X } while(buildenc(0,dctreehd) == ERROR);
X
X /* Initialize encoding variables */
X
X cbitsrem = 0; /* force initial read */
X curin = 0; /* anything but endfile */
X
X for(i=0; i (ceil-sum))
X ++ovflw;
X sum += node[i].weight;
X }
X
X divisor = ovflw + 1;
X
X /* Ensure no non-zero values are lost */
X
X increased = FALSE;
X for(i=0; i1)
X for(i=0; i=0; --i)
X adjust(list,i,length-1);
X}
X
X/* Make a heap from a heap with a new top */
X
Xstatic INT adjust(list,top,bottom)
XINT list[], top, bottom;
X{
X register INT k, temp;
X INT cmptrees();
X
X k = 2 * top + 1; /* left child of top */
X temp = list[top]; /* remember root node of top tree */
X
X if(k<=bottom)
X { if(k