#include "de_compress.h" #include #include "macunpack.h" #ifdef SIT #define DECOMPRESS #endif /* SIT */ #ifdef LZC #define DECOMPRESS #endif /* LZC */ #ifdef DECOMPRESS #include "globals.h" #include "../fileio/wrfile.h" /* Written to allow for bits to be upto 16, MacCompress can use 16 bits */ #define BITS 16 #define HSIZE 69001 /* 95% occupancy */ #define INIT_BITS 9 /* initial number of bits/code */ static int n_bits; /* number of bits/code */ static int maxbits; /* user settable max # bits/code */ static int32_t maxcode; /* maximum code, given n_bits */ static int32_t maxmaxcode; /* should NEVER generate this code */ # define MAXCODE(n_bits) ((1 << (n_bits)) - 1) static int32_t htab [HSIZE]; static unsigned short codetab [HSIZE]; #define tab_prefixof(i) codetab[i] #define tab_suffixof(i) ((unsigned char *)(htab))[i] #define de_stack ((unsigned char *)&tab_suffixof(1<= 0; code--) { tab_prefixof(code) = 0; tab_suffixof(code) = (unsigned char)code; } free_ent = FIRST; finchar = oldcode = getcode(); if(oldcode == -1) { /* EOF already? */ return; /* Get out of here */ } /* first code must be 8 bits = char */ *out_ptr++ = (char)finchar; stackp = de_stack; while((code = getcode()) > -1) { if(code == CLEAR) { for(code = 255; code >= 0; code--) { tab_prefixof(code) = 0; } clear_flg = 1; free_ent = FIRST - 1; if((code = getcode()) == -1) { /* O, untimely death! */ break; } } incode = code; /* * Special case for KwKwK string. */ if(code >= free_ent) { *stackp++ = finchar; code = oldcode; } /* * Generate output characters in reverse order */ while(code >= 256) { *stackp++ = tab_suffixof(code); code = tab_prefixof(code); } *stackp++ = finchar = tab_suffixof(code); /* * And put them out in forward order */ do { *out_ptr++ = (char)*--stackp; } while(stackp > de_stack); /* * Generate the new entry. */ if((code=free_ent) < maxmaxcode) { tab_prefixof(code) = (unsigned short)oldcode; tab_suffixof(code) = finchar; free_ent = code+1; } /* * Remember previous code. */ oldcode = incode; } return; } static unsigned char rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; static int get_core_bytes; static char *core_ptr; static int file_bytes(char *buf, int length); static int core_bytes(char *buf, int length); static int32_t getcode (void) { register int32_t code; static int offset = 0, size = 0; static unsigned char buf[BITS]; register int r_off, bits; register unsigned char *bp = buf; if(clear_flg > 0 || offset >= size || free_ent > maxcode) { /* * If the next entry will be too big for the current code * size, then we must increase the size. This implies reading * a new buffer full, too. */ if(free_ent > maxcode) { n_bits++; if(n_bits == maxbits) { maxcode = maxmaxcode; /* won't get any bigger now */ } else { maxcode = MAXCODE(n_bits); } } if(clear_flg > 0) { maxcode = MAXCODE (n_bits = INIT_BITS); clear_flg = 0; } if(toread == 0) { return -1; } if(get_core_bytes) { size = core_bytes((char *)buf, (n_bits < toread ? n_bits : toread)); } else { size = file_bytes((char *)buf, (n_bits < toread ? n_bits : toread)); } toread -= size; if(size <= 0) { (void)fprintf(stderr, "Premature EOF\n"); #ifdef SCAN do_error("macunpack: Premature EOF"); #endif /* SCAN */ exit(1); } offset = 0; /* Round size down to integral number of codes */ size = (size << 3) - (n_bits - 1); } r_off = offset; bits = n_bits; /* * Get to the first byte. */ bp += (r_off >> 3); r_off &= 7; /* Get first part (low order bits) */ code = (*bp++ >> r_off); bits -= (8 - r_off); r_off = 8 - r_off; /* now, offset into code word */ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ if(bits >= 8) { code |= *bp++ << r_off; r_off += 8; bits -= 8; } /* high order bits. */ code |= (*bp & rmask[bits]) << r_off; offset += n_bits; return code; } static int file_bytes (char *buf, int length) { return fread(buf, 1, length, infp); } static int core_bytes (char *buf, int length) { int i; for(i = 0; i < length; i++) { *buf++ = *core_ptr++; } return length; } void core_compress(char* ptr) { core_ptr = ptr; get_core_bytes = ptr != NULL; } #else /* DECOMPRESS */ int decompress; /* keep lint and some compilers happy */ #endif /* DECOMPRESS */