1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
#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 long maxcode; /* maximum code, given n_bits */
static long maxmaxcode; /* should NEVER generate this code */
# define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
static long 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<<BITS))
static long free_ent = 0; /* first unused entry */
static long getcode();
static int clear_flg = 0;
/*
* the next two codes should not be changed lightly, as they must not
* lie within the contiguous general code space.
*/
#define FIRST 257 /* first free entry */
#define CLEAR 256 /* table clear output code */
static int toread;
void de_compress(ibytes, mb)
unsigned long ibytes;
int mb;
{
register unsigned char *stackp;
register int finchar;
register long code, oldcode, incode;
toread = ibytes;
maxbits = mb;
maxmaxcode = 1 << maxbits;
maxcode = MAXCODE(n_bits = INIT_BITS);
for(code = 255; code >= 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();
static int core_bytes();
static long getcode()
{
register long 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(buf, length)
char *buf;
int length;
{
return fread(buf, 1, length, infp);
}
static int core_bytes(buf, length)
char *buf;
int length;
{
int i;
for(i = 0; i < length; i++) {
*buf++ = *core_ptr++;
}
return length;
}
void core_compress(ptr)
char *ptr;
{
core_ptr = ptr;
get_core_bytes = ptr != NULL;
}
#else /* DECOMPRESS */
int decompress; /* keep lint and some compilers happy */
#endif /* DECOMPRESS */
|