home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Workbench / Archivers / PPCxDMS.lha / PPCxDMS / source.lha / src / u_heavy.c < prev    next >
C/C++ Source or Header  |  1998-02-28  |  3KB  |  184 lines

  1.  
  2. /*
  3.  *     xDMS  v1.1  -  Portable DMS archive unpacker  -  Public Domain
  4.  *     Written by     Andre R. de la Rocha  <adlroc@usa.net>
  5.  *
  6.  *     Lempel-Ziv-Huffman decompression functions used in Heavy 1 & 2 
  7.  *     compression modes. Based on LZH decompression functions from
  8.  *     UNIX LHA made by Masaru Oki
  9.  *
  10.  */
  11.  
  12.  
  13. #include "cdata.h"
  14. #include "u_heavy.h"
  15. #include "getbits.h"
  16. #include "maketbl.h"
  17.  
  18.  
  19. #define NC 510
  20. #define NPT 20
  21. #define N1 510
  22. #define OFFSET 253
  23.  
  24. USHORT left[2 * NC - 1], right[2 * NC - 1 + 9];
  25. static UCHAR c_len[NC], pt_len[NPT];
  26. static USHORT c_table[4096], pt_table[256];
  27. static USHORT lastlen, np, heavy_text_loc;
  28.  
  29.  
  30. static USHORT read_tree_c(void);
  31. static USHORT read_tree_p(void);
  32. INLINE USHORT decode_c(void);
  33. INLINE USHORT decode_p(void);
  34.  
  35.  
  36.  
  37. void Init_HEAVY(void){
  38.     heavy_text_loc = 0;
  39. }
  40.  
  41.  
  42.  
  43. USHORT Unpack_HEAVY(UCHAR *in, UCHAR *out, UCHAR flags, USHORT origsize){
  44.     USHORT j, i, c, bitmask;
  45.     UCHAR *outend;
  46.  
  47.     /*  Heavy 1 uses a 4Kb dictionary,  Heavy 2 uses 8Kb  */
  48.  
  49.     if (flags & 8) {
  50.         np = 15;
  51.         bitmask = 0x1fff;
  52.     } else {
  53.         np = 14;
  54.         bitmask = 0x0fff;
  55.     }
  56.  
  57.     initbitbuf(in);
  58.  
  59.     if (flags & 2) {
  60.         if (read_tree_c()) return 1;
  61.         if (read_tree_p()) return 2;
  62.     }
  63.  
  64.     outend = out+origsize;
  65.  
  66.     while (out<outend) {
  67.         c = decode_c();
  68.         if (c < 256) {
  69.             *out++ = text[heavy_text_loc++ & bitmask] = (UCHAR)c;
  70.         } else {
  71.             j = (USHORT) (c - OFFSET);
  72.             i = (USHORT) (heavy_text_loc - decode_p() - 1);
  73.             while(j--) *out++ = text[heavy_text_loc++ & bitmask] = text[i++ & bitmask];
  74.         }
  75.     }
  76.  
  77.     if (!(flags & 1)) Init_HEAVY();
  78.  
  79.     return 0;
  80.  
  81. }
  82.  
  83.  
  84.  
  85. INLINE USHORT decode_c(void){
  86.     USHORT i, j, m;
  87.  
  88.     j = c_table[GETBITS(12)];
  89.     if (j < N1) {
  90.         DROPBITS(c_len[j]);
  91.     } else {
  92.         DROPBITS(12);
  93.         i = GETBITS(16);
  94.         m = 0x8000;
  95.         do {
  96.             if (i & m) j = right[j];
  97.             else              j = left [j];
  98.             m >>= 1;
  99.         } while (j >= N1);
  100.         DROPBITS(c_len[j] - 12);
  101.     }
  102.     return j;
  103. }
  104.  
  105.  
  106.  
  107. INLINE USHORT decode_p(void){
  108.     USHORT i, j, m;
  109.  
  110.     j = pt_table[GETBITS(8)];
  111.     if (j < np) {
  112.         DROPBITS(pt_len[j]);
  113.     } else {
  114.         DROPBITS(8);
  115.         i = GETBITS(16);
  116.         m = 0x8000;
  117.         do {
  118.             if (i & m) j = right[j];
  119.             else             j = left [j];
  120.             m >>= 1;
  121.         } while (j >= np);
  122.         DROPBITS(pt_len[j] - 8);
  123.     }
  124.  
  125.     if (j != np-1) {
  126.         if (j > 0) {
  127.             j = (USHORT)(GETBITS(i=(USHORT)(j-1)) | (1U << (j-1)));
  128.             DROPBITS(i);
  129.         }
  130.         lastlen=j;
  131.     }
  132.  
  133.     return lastlen;
  134.  
  135. }
  136.  
  137.  
  138.  
  139. static USHORT read_tree_c(void){
  140.     USHORT i,n;
  141.  
  142.     n = GETBITS(9);
  143.     DROPBITS(9);
  144.     if (n>0){
  145.         for (i=0; i<n; i++) {
  146.             c_len[i] = (UCHAR)GETBITS(5);
  147.             DROPBITS(5);
  148.         }
  149.         for (i=n; i<510; i++) c_len[i] = 0;
  150.         if (make_table(510,c_len,12,c_table)) return 1;
  151.     } else {
  152.         n = GETBITS(9);
  153.         DROPBITS(9);
  154.         for (i=0; i<510; i++) c_len[i] = 0;
  155.         for (i=0; i<4096; i++) c_table[i] = n;
  156.     }
  157.     return 0;
  158. }
  159.  
  160.  
  161.  
  162. static USHORT read_tree_p(void){
  163.     USHORT i,n;
  164.  
  165.     n = GETBITS(5);
  166.     DROPBITS(5);
  167.     if (n>0){
  168.         for (i=0; i<n; i++) {
  169.             pt_len[i] = (UCHAR)GETBITS(4);
  170.             DROPBITS(4);
  171.         }
  172.         for (i=n; i<np; i++) pt_len[i] = 0;
  173.         if (make_table(np,pt_len,8,pt_table)) return 1;
  174.     } else {
  175.         n = GETBITS(5);
  176.         DROPBITS(5);
  177.         for (i=0; i<np; i++) pt_len[i] = 0;
  178.         for (i=0; i<256; i++) pt_table[i] = n;
  179.     }
  180.     return 0;
  181. }
  182.  
  183.  
  184.