Listing 3 Zigler's compression technique

  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 */