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.SHAR12_OF_19
Message-ID: <880624092706.02c@Ins.MRC.AdhocNet.CA>
Date: 24 Jun 88 15:27:02 GMT
Sender: usenet@ucbvax.BERKELEY.EDU
Organization: The Internet
Lines: 278

$Part13:
$ File_is="ARCS.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