typedef struct
{
int cnt ; /* count nodes to root */
DWORD path ; /* bit-encoded path to root */
} HPATH ;
/**** Module Semiglobals ****/
static DWORD Cnt[512] , /* Huffman tree node counts */
OutSize , /* track size of compressed file */
ByteCtr ; /* length of input file */
static char Out8 ; /* code byte to compressed file */
static int Cnt8 ; /* code bit counter */
static HPATH * Hp ; /* ptr to HPATH base */
HTREE * Ht ; /* ptr to Huffman tree base */
static int pascal encode( void )
{
register int c , /* chars from input file */
h ; /* follows path through tree */
int ncnt ; /* count nodes to root */
child ; /* child of current node */
HPATH * php ; /* pointer to HPATH array */
DWORD acc = 0L ; /* accumulator for code bits */
for ( c = 0; c < 256 ; c++ ) /* get Huffman codes */
{
if ( Cnt[c] > 0 ) /* if char found in input */
{
php = Hp + c; /* php->Hp[c] */
h = c;
ncnt = 0;
acc = 0L;
do
{
ncnt++;
acc <<== 1;
child = h; /* child = current node */
h = Ht[h].parent; /* go to parent node */
if ( child == Ht[h].left ) /* "look back" at child node */
(int)acc <<= 1; /* encode left child node */
}
while( Ht[h].parent != -1 );
php-cnt = ncnt; /* save node count */
php-path = acc; /* save encoded path */
}
}
while ( (c = getc(fi)) != EOF && OutSize < ByteCtr )
{
php = Hp + c;
ncnt = php-cnt;
acc = php-path;
while ( ncnt-- )
{
emit( (int)acc & 1 );
acc >>= 1;
}
} /* while(getc()) */
if ( --BytesFree 0 ) /* if out of disk space */
longjmp( JumpBuf, ErrWrite );
if ( ++OutSize < ByteCtr )
{
OutBuffer[pBuf++] = Out8 << ( 8 - Cnt8 ); /* pad last byte */
_write( OutHandle, OutBuffer, pBuf );
}
return ( OutSize >= ByteCtr );
} /**** encode() ****/
static void pascal emit( register int bit )
{
if (Cnt8 == 8 )
{
if ( --BytesFree <= 0 ) /* if out of disk space */
longjmp( JumpBuf, ErrWrite );
else if ( pBuf >= OUTBUFFSIZE ) /* if buffer full */
{
_write( OutHandle, OutBuffer, pBuf ); /* write to output */
pBuf = 0;
}
OutBuffer[pBuf++] = Out8;
OutSize++;
Cnt8 = 0;
}
Out8 = ( Out8 << 1 ) | bit;
Cnt8++;
}
/* End of File */