home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 157.lha / Arc_Src / arcusq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-27  |  2.7 KB  |  94 lines

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