home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / macutils.lzh / MACUTILS / MACUNPACK / de_compress.c < prev    next >
C/C++ Source or Header  |  1995-09-18  |  5KB  |  226 lines

  1. #include "macunpack.h"
  2. #ifdef SIT
  3. #define DECOMPRESS
  4. #endif /* SIT */
  5. #ifdef LZC
  6. #define DECOMPRESS
  7. #endif /* LZC */
  8. #ifdef DECOMPRESS
  9. #include "globals.h"
  10. #include "../fileio/wrfile.h"
  11.  
  12. /* Written to allow for bits to be upto 16, MacCompress can use 16 bits */
  13.  
  14. #define    BITS    16
  15. #define HSIZE    69001        /* 95% occupancy */
  16.  
  17. #define INIT_BITS 9            /* initial number of bits/code */
  18.  
  19. static int n_bits;                /* number of bits/code */
  20. static int maxbits;            /* user settable max # bits/code */
  21. static long maxcode;            /* maximum code, given n_bits */
  22. static long maxmaxcode;            /* should NEVER generate this code */
  23. # define MAXCODE(n_bits)    ((1 << (n_bits)) - 1)
  24.  
  25. static long htab [HSIZE];
  26. static unsigned short codetab [HSIZE];
  27.  
  28. #define tab_prefixof(i) codetab[i]
  29. #define tab_suffixof(i)    ((unsigned char *)(htab))[i]
  30. #define de_stack    ((unsigned char *)&tab_suffixof(1<<BITS))
  31.  
  32. static long free_ent = 0;            /* first unused entry */
  33.  
  34. static long getcode();
  35.  
  36. static int clear_flg = 0;
  37.  
  38. /*
  39.  * the next two codes should not be changed lightly, as they must not
  40.  * lie within the contiguous general code space.
  41.  */
  42. #define FIRST    257    /* first free entry */
  43. #define    CLEAR    256    /* table clear output code */
  44.  
  45. static int toread;
  46.  
  47. void de_compress(ibytes, mb)
  48. unsigned long ibytes;
  49. int mb;
  50. {
  51.     register unsigned char *stackp;
  52.     register int finchar;
  53.     register long code, oldcode, incode;
  54.  
  55.     toread = ibytes;
  56.     maxbits = mb;
  57.     maxmaxcode = 1 << maxbits;
  58.     maxcode = MAXCODE(n_bits = INIT_BITS);
  59.     for(code = 255; code >= 0; code--) {
  60.     tab_prefixof(code) = 0;
  61.     tab_suffixof(code) = (unsigned char)code;
  62.     }
  63.     free_ent = FIRST;
  64.     finchar = oldcode = getcode();
  65.     if(oldcode == -1) {    /* EOF already? */
  66.     return;            /* Get out of here */
  67.     }
  68.     /* first code must be 8 bits = char */
  69.     *out_ptr++ = (char)finchar;
  70.     stackp = de_stack;
  71.     while((code = getcode()) > -1) {
  72.     if(code == CLEAR) {
  73.         for(code = 255; code >= 0; code--) {
  74.         tab_prefixof(code) = 0;
  75.         }
  76.         clear_flg = 1;
  77.         free_ent = FIRST - 1;
  78.         if((code = getcode()) == -1) {    /* O, untimely death! */
  79.         break;
  80.         }
  81.     }
  82.     incode = code;
  83.     /*
  84.      * Special case for KwKwK string.
  85.      */
  86.     if(code >= free_ent) {
  87.         *stackp++ = finchar;
  88.         code = oldcode;
  89.     }
  90.     /*
  91.      * Generate output characters in reverse order
  92.      */
  93.     while(code >= 256) {
  94.         *stackp++ = tab_suffixof(code);
  95.         code = tab_prefixof(code);
  96.     }
  97.     *stackp++ = finchar = tab_suffixof(code);
  98.     /*
  99.      * And put them out in forward order
  100.      */
  101.     do {
  102.         *out_ptr++ = (char)*--stackp;
  103.     } while(stackp > de_stack);
  104.     /*
  105.      * Generate the new entry.
  106.      */
  107.     if((code=free_ent) < maxmaxcode) {
  108.         tab_prefixof(code) = (unsigned short)oldcode;
  109.         tab_suffixof(code) = finchar;
  110.         free_ent = code+1;
  111.     }
  112.     /*
  113.      * Remember previous code.
  114.      */
  115.     oldcode = incode;
  116.     }
  117.     return;
  118. }
  119.  
  120. static unsigned char rmask[9] =
  121.     {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
  122.  
  123. static int get_core_bytes;
  124. static char *core_ptr;
  125. static int file_bytes();
  126. static int core_bytes();
  127.  
  128. static long getcode()
  129. {
  130.     register long code;
  131.     static int offset = 0, size = 0;
  132.     static unsigned char buf[BITS];
  133.     register int r_off, bits;
  134.     register unsigned char *bp = buf;
  135.  
  136.     if(clear_flg > 0 || offset >= size || free_ent > maxcode) {
  137.     /*
  138.      * If the next entry will be too big for the current code
  139.      * size, then we must increase the size.  This implies reading
  140.      * a new buffer full, too.
  141.      */
  142.     if(free_ent > maxcode) {
  143.         n_bits++;
  144.         if(n_bits == maxbits) {
  145.         maxcode = maxmaxcode;    /* won't get any bigger now */
  146.         } else {
  147.         maxcode = MAXCODE(n_bits);
  148.         }
  149.     }
  150.     if(clear_flg > 0) {
  151.         maxcode = MAXCODE (n_bits = INIT_BITS);
  152.         clear_flg = 0;
  153.     }
  154.     if(toread == 0) {
  155.         return -1;
  156.     }
  157.     if(get_core_bytes) {
  158.         size = core_bytes((char *)buf, (n_bits < toread ? n_bits : toread));
  159.     } else {
  160.         size = file_bytes((char *)buf, (n_bits < toread ? n_bits : toread));
  161.     }
  162.     toread -= size;
  163.     if(size <= 0) {
  164.         (void)fprintf(stderr, "Premature EOF\n");
  165. #ifdef SCAN
  166.         do_error("macunpack: Premature EOF");
  167. #endif /* SCAN */
  168.         exit(1);
  169.     }
  170.     offset = 0;
  171.     /* Round size down to integral number of codes */
  172.     size = (size << 3) - (n_bits - 1);
  173.     }
  174.     r_off = offset;
  175.     bits = n_bits;
  176.     /*
  177.      * Get to the first byte.
  178.      */
  179.     bp += (r_off >> 3);
  180.     r_off &= 7;
  181.     /* Get first part (low order bits) */
  182.     code = (*bp++ >> r_off);
  183.     bits -= (8 - r_off);
  184.     r_off = 8 - r_off;        /* now, offset into code word */
  185.     /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
  186.     if(bits >= 8) {
  187.     code |= *bp++ << r_off;
  188.     r_off += 8;
  189.     bits -= 8;
  190.     }
  191.     /* high order bits. */
  192.     code |= (*bp & rmask[bits]) << r_off;
  193.     offset += n_bits;
  194.     return code;
  195. }
  196.  
  197. static int file_bytes(buf, length)
  198. char *buf;
  199. int length;
  200. {
  201.     return fread(buf, 1, length, infp);
  202. }
  203.  
  204. static int core_bytes(buf, length)
  205. char *buf;
  206. int length;
  207. {
  208.     int i;
  209.  
  210.     for(i = 0; i < length; i++) {
  211.     *buf++ = *core_ptr++;
  212.     }
  213.     return length;
  214. }
  215.  
  216. void core_compress(ptr)
  217. char *ptr;
  218. {
  219.     core_ptr = ptr;
  220.     get_core_bytes = ptr != NULL;
  221. }
  222. #else /* DECOMPRESS */
  223. int decompress; /* keep lint and some compilers happy */
  224. #endif /* DECOMPRESS */
  225.  
  226.