home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / ARC521-2.ZIP / ARCUSQ.C < prev    next >
C/C++ Source or Header  |  1989-12-29  |  3KB  |  107 lines

  1. /*
  2.  * $Header: arcusq.c,v 1.2 88/06/02 16:27:44 hyc Locked $
  3.  */
  4.  
  5. /*
  6.  * ARC - Archive utility - ARCUSQ
  7.  *
  8.  * Version 3.14, created on 07/25/86 at 13:04:19
  9.  *
  10.  * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  11.  *
  12.  * By:  Thom Henderson
  13.  *
  14.  * Description: This file contains the routines used to expand a file which was
  15.  * packed using Huffman squeezing.
  16.  *
  17.  * Most of this code is taken from an USQ program by Richard Greenlaw, which was
  18.  * adapted to CI-C86 by Robert J. Beilstein.
  19.  *
  20.  * Language: Computer Innovations Optimizing C86
  21.  */
  22. #include <stdio.h>
  23. #include "arc.h"
  24.  
  25. void    abort();
  26. int    getc_unp();
  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          short
  44. get_int(f)            /* get a 16bit integer */
  45.     FILE           *f;    /* file to get it from */
  46. {
  47.     int    i,j;
  48.     i = getc_unp(f);
  49.     j = getc_unp(f) << 8;
  50.     return (i | j) & 0xFFFF;
  51. }
  52.  
  53. void
  54. init_usq(f)            /* initialize Huffman unsqueezing */
  55.     FILE           *f;    /* file containing squeezed data */
  56. {
  57.     int             i;    /* node index */
  58.  
  59.     bpos = 99;        /* force initial read */
  60.  
  61.     numnodes = get_int(f);
  62.  
  63.     if (numnodes < 0 || numnodes >= NUMVALS)
  64.         abort("File has an invalid decode tree");
  65.  
  66.     /* initialize for possible empty tree (SPEOF only) */
  67.  
  68.     node[0].child[0] = -(SPEOF + 1);
  69.     node[0].child[1] = -(SPEOF + 1);
  70.  
  71.     for (i = 0; i < numnodes; ++i) {    /* get decoding tree from
  72.                          * file */
  73.         node[i].child[0] = get_int(f);
  74.         node[i].child[1] = get_int(f);
  75.     }
  76. }
  77.  
  78. int
  79. getc_usq(f)            /* get byte from squeezed file */
  80.     FILE           *f;    /* file containing squeezed data */
  81. {
  82.     int             i;    /* tree index */
  83.  
  84.     /* follow bit stream in tree to a leaf */
  85.  
  86.     for (i = 0; i >= 0;) {    /* work down(up?) from root */
  87.         if (++bpos > 7) {
  88.             if ((curin = getc_unp(f)) == ERROR)
  89.                 return (ERROR);
  90.             bpos = 0;
  91.  
  92.             /* move a level deeper in tree */
  93.             i = node[i].child[1 & curin];
  94.         } else
  95.             i = node[i].child[1 & (curin >>= 1)];
  96.     }
  97.  
  98.     /* decode fake node index to original data value */
  99.  
  100.     i = -(i + 1);
  101.  
  102.     /* decode special endfile token to normal EOF */
  103.  
  104.     i = (i == SPEOF) ? EOF : i;
  105.     return i;
  106. }
  107.