home *** CD-ROM | disk | FTP | other *** search
- #include "macunpack.h"
- #ifdef SIT
- #define DELZAH
- #endif /* SIT */
- #ifdef LZH
- #define DELZAH
- #endif /* LZH */
- #ifdef DELZAH
- #include "globals.h"
- #include "../util/masks.h"
- #include "../fileio/wrfile.h"
-
- /* Note: compare with LZSS decoding in lharc! */
-
- #define N 314
- #define T (2*N-1)
-
- /* Huffman table used for first 6 bits of offset:
- #bits codes
- 3 0x000
- 4 0x040-0x080
- 5 0x100-0x2c0
- 6 0x300-0x5c0
- 7 0x600-0xbc0
- 8 0xc00-0xfc0
- */
-
- static unsigned short HuffCode[] = {
- 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
- 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
- 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
- 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
- 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040,
- 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040,
- 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080,
- 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080,
- 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0,
- 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0, 0x0c0,
- 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100,
- 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140,
- 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180,
- 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0,
- 0x200, 0x200, 0x200, 0x200, 0x200, 0x200, 0x200, 0x200,
- 0x240, 0x240, 0x240, 0x240, 0x240, 0x240, 0x240, 0x240,
- 0x280, 0x280, 0x280, 0x280, 0x280, 0x280, 0x280, 0x280,
- 0x2c0, 0x2c0, 0x2c0, 0x2c0, 0x2c0, 0x2c0, 0x2c0, 0x2c0,
- 0x300, 0x300, 0x300, 0x300, 0x340, 0x340, 0x340, 0x340,
- 0x380, 0x380, 0x380, 0x380, 0x3c0, 0x3c0, 0x3c0, 0x3c0,
- 0x400, 0x400, 0x400, 0x400, 0x440, 0x440, 0x440, 0x440,
- 0x480, 0x480, 0x480, 0x480, 0x4c0, 0x4c0, 0x4c0, 0x4c0,
- 0x500, 0x500, 0x500, 0x500, 0x540, 0x540, 0x540, 0x540,
- 0x580, 0x580, 0x580, 0x580, 0x5c0, 0x5c0, 0x5c0, 0x5c0,
- 0x600, 0x600, 0x640, 0x640, 0x680, 0x680, 0x6c0, 0x6c0,
- 0x700, 0x700, 0x740, 0x740, 0x780, 0x780, 0x7c0, 0x7c0,
- 0x800, 0x800, 0x840, 0x840, 0x880, 0x880, 0x8c0, 0x8c0,
- 0x900, 0x900, 0x940, 0x940, 0x980, 0x980, 0x9c0, 0x9c0,
- 0xa00, 0xa00, 0xa40, 0xa40, 0xa80, 0xa80, 0xac0, 0xac0,
- 0xb00, 0xb00, 0xb40, 0xb40, 0xb80, 0xb80, 0xbc0, 0xbc0,
- 0xc00, 0xc40, 0xc80, 0xcc0, 0xd00, 0xd40, 0xd80, 0xdc0,
- 0xe00, 0xe40, 0xe80, 0xec0, 0xf00, 0xf40, 0xf80, 0xfc0};
-
- static short HuffLength[] = {
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
-
- unsigned char (*lzah_getbyte)();
-
- static void lzah_inithuf();
- static void lzah_reorder();
- static void lzah_move();
- static void lzah_getbit();
- static void lzah_outchar();
-
- static char lzah_buf[4096];
- static int lzah_bufptr;
- static int lzah_bitsavail;
- static int lzah_bits;
- static int Frequ[1000];
- static int ForwTree[1000];
- static int BackTree[1000];
-
- void de_lzah(obytes)
- unsigned long obytes;
- {
- int i, i1, j, ch, byte, offs, skip;
-
- lzah_inithuf();
- lzah_bitsavail = 0;
- for(i = 0; i < 4036; i++) {
- lzah_buf[i] = ' ';
- }
- lzah_bufptr = 4036;
- while(obytes != 0) {
- ch = ForwTree[T - 1];
- while(ch < T) {
- lzah_getbit();
- if(lzah_bits & 0x80) {
- ch = ch + 1;
- }
- ch = ForwTree[ch];
- }
- ch -= T;
- if(Frequ[T - 1] >= 0x8000) {
- lzah_reorder();
- }
-
- i = BackTree[ch + T];
- do {
- j = ++Frequ[i];
- i1 = i + 1;
- if(Frequ[i1] < j) {
- while(Frequ[++i1] < j) ;
- i1--;
- Frequ[i] = Frequ[i1];
- Frequ[i1] = j;
-
- j = ForwTree[i];
- BackTree[j] = i1;
- if(j < T) {
- BackTree[j + 1] = i1;
- }
- ForwTree[i] = ForwTree[i1];
- ForwTree[i1] = j;
- j = ForwTree[i];
- BackTree[j] = i;
- if(j < T) {
- BackTree[j + 1] = i;
- }
- i = i1;
- }
- i = BackTree[i];
- } while(i != 0);
-
- if(ch < 256) {
- lzah_outchar((char)ch);
- obytes--;
- } else {
- if(lzah_bitsavail != 0) {
- byte = (lzah_bits << 1) & BYTEMASK;
- lzah_bits = (*lzah_getbyte)() & BYTEMASK;
- byte |= (lzah_bits >> lzah_bitsavail);
- lzah_bits = lzah_bits << (7 - lzah_bitsavail);
- } else {
- byte = (*lzah_getbyte)() & BYTEMASK;
- }
- offs = HuffCode[byte];
- skip = HuffLength[byte] - 2;
- while(skip-- != 0) {
- byte = byte + byte;
- lzah_getbit();
- if(lzah_bits & 0x80) {
- byte++;
- }
- }
- offs |= (byte & 0x3f);
- offs = ((lzah_bufptr - offs - 1) & 0xfff);
- ch = ch - 253;
- while(ch-- > 0) {
- lzah_outchar(lzah_buf[offs++ & 0xfff]);
- obytes--;
- if(obytes == 0) {
- break;
- }
- }
- }
- }
- }
-
- static void lzah_inithuf()
- {
- int i, j;
-
- for(i = 0; i < N; i++) {
- Frequ[i] = 1;
- ForwTree[i] = i + T;
- BackTree[i + T] = i;
- }
- for(i = 0, j = N; j < T; i += 2, j++) {
- Frequ[j] = Frequ[i] + Frequ[i + 1];
- ForwTree[j] = i;
- BackTree[i] = j;
- BackTree[i + 1] = j;
- }
- Frequ[T] = 0xffff;
- BackTree[T - 1] = 0;
- }
-
- static void lzah_reorder()
- {
- int i, j, k, l;
-
- j = 0;
- for(i = 0; i < T; i++) {
- if(ForwTree[i] >= T) {
- Frequ[j] = ((Frequ[i] + 1) >> 1);
- ForwTree[j] = ForwTree[i];
- j++;
- }
- }
- for(i = 0, j = N; i < T; i += 2, j++) {
- k = i + 1;
- l = Frequ[i] + Frequ[k];
- Frequ[j] = l;
- k = j - 1;
- while(l < Frequ[k]) {
- k--;
- }
- k = k + 1;
- lzah_move(Frequ + k, Frequ + k + 1, j - k);
- Frequ[k] = l;
- lzah_move(ForwTree + k, ForwTree + k + 1, j - k);
- ForwTree[k] = i;
- }
- for(i = 0; i < T; i++) {
- k = ForwTree[i];
- if(k >= T) {
- BackTree[k] = i;
- } else {
- BackTree[k] = i;
- BackTree[k + 1] = i;
- }
- }
- }
-
- static void lzah_move(p, q, n)
- int *p, *q, n;
- {
- if(p > q) {
- while(n-- > 0) {
- *q++ = *p++;
- }
- } else {
- p += n;
- q += n;
- while(n-- > 0) {
- *--q = *--p;
- }
- }
- }
-
- static void lzah_getbit()
- {
- if(lzah_bitsavail != 0) {
- lzah_bits = lzah_bits + lzah_bits;
- lzah_bitsavail--;
- } else {
- lzah_bits = (*lzah_getbyte)() & BYTEMASK;
- lzah_bitsavail = 7;
- }
- }
-
- static void lzah_outchar(ch)
- char ch;
- {
- *out_ptr++ = ch;
- lzah_buf[lzah_bufptr++] = ch;
- lzah_bufptr &= 0xfff;
- }
- #else /* DELZAH */
- int delzah; /* keep lint and some compilers happy */
- #endif /* DELZAH */
-
-