home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / OS2ARC_S.ZIP / ARCUSQ.C < prev    next >
C/C++ Source or Header  |  1987-10-14  |  3KB  |  100 lines

  1. /*  ARC - Archive utility - ARCUSQ
  2.  
  3. $define(tag,$$segment(@1,$$index(@1,=)+1))#
  4. $define(version,Version $tag(
  5. TED_VERSION DB =3.13), created on $tag(
  6. TED_DATE DB =01/30/86) at $tag(
  7. TED_TIME DB =20:11:42))#
  8. $undefine(tag)#
  9.     $version
  10.  
  11. (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  12.  
  13.     By:  Thom Henderson
  14.  
  15.     Description:
  16.          This file contains the routines used to expand a file
  17.          which was packed using Huffman squeezing.
  18.  
  19.          Most of this code is taken from an USQ program by Richard
  20.          Greenlaw, which was adapted to CI-C86 by Robert J. Beilstein.
  21.  
  22.     Language:
  23.          Computer Innovations Optimizing C86
  24. */
  25. #include <stdio.h>
  26. #include "arc.h"
  27.  
  28. /* stuff for Huffman unsqueezing */
  29.  
  30. #define ERROR (-1)
  31.  
  32. #define SPEOF 256                      /* special endfile token */
  33. #define NUMVALS 257                    /* 256 data values plus SPEOF */
  34.  
  35. extern struct nd                       /* decoding tree */
  36. {   int child[2];                      /* left, right */
  37. }   node[NUMVALS];                     /* use large buffer */
  38.  
  39. static int bpos;                       /* last bit position read */
  40. static int curin;                      /* last byte value read */
  41. static int numnodes;                   /* number of nodes in decode tree */
  42.  
  43. static int get_int(f)                  /* get an integer */
  44. FILE *f;                               /* file to get it from */
  45. {
  46.     return getc_unp(f) | (getc_unp(f)<<8);
  47. }
  48.  
  49. init_usq(f)                            /* initialize Huffman unsqueezing */
  50. FILE *f;                               /* file containing squeezed data */
  51. {
  52.     int i;                             /* node index */
  53.  
  54.     bpos = 99;                         /* force initial read */
  55.  
  56.     numnodes = get_int(f);
  57.  
  58.     if(numnodes<0 || numnodes>=NUMVALS)
  59.          abort("File has an invalid decode tree");
  60.  
  61.     /* initialize for possible empty tree (SPEOF only) */
  62.  
  63.     node[0].child[0] = -(SPEOF + 1);
  64.     node[0].child[1] = -(SPEOF + 1);
  65.  
  66.     for(i=0; i<numnodes; ++i)          /* get decoding tree from file */
  67.     {    node[i].child[0] = get_int(f);
  68.          node[i].child[1] = get_int(f);
  69.     }
  70. }
  71.  
  72. int getc_usq(f)                        /* get byte from squeezed file */
  73. FILE *f;                               /* file containing squeezed data */
  74. {
  75.     int i;                             /* tree index */
  76.  
  77.     /* follow bit stream in tree to a leaf */
  78.  
  79.     for(i=0; i>=0; )                   /* work down(up?) from root */
  80.     {    if(++bpos>7)
  81.          {    if((curin=getc_unp(f)) == ERROR)
  82.                    return(ERROR);
  83.               bpos = 0;
  84.  
  85.               /* move a level deeper in tree */
  86.               i = node[i].child[1&curin];
  87.          }
  88.          else i = node[i].child[1 & (curin >>= 1)];
  89.     }
  90.  
  91.     /* decode fake node index to original data value */
  92.  
  93.     i = -(i + 1);
  94.  
  95.     /* decode special endfile token to normal EOF */
  96.  
  97.     i = (i==SPEOF) ? EOF : i;
  98.     return i;
  99. }
  100.