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