|
|
1.1 ! root 1: /* LZH.C */ ! 2: ! 3: /* Digital Dynamics conversion of 1988 LZH (LHarc) encoding functions */ ! 4: /* Based on Japanese version 29-NOV-1988 */ ! 5: /* LZSS coded by Haruhiko Okumura */ ! 6: /* Adaptive Huffman Coding coded by Haruyasu Yoshizaki */ ! 7: ! 8: ! 9: #include <stdio.h> ! 10: #include <stdlib.h> ! 11: #include <string.h> ! 12: #include <ctype.h> ! 13: #ifndef __WATCOMC__ ! 14: #include <alloc.h> ! 15: #endif ! 16: ! 17: /****************************************************************************/ ! 18: /* Memory allocation macros for various compilers and environments */ ! 19: /* MALLOC is used for allocations of 64k or less */ ! 20: /* FREE is used to free buffers allocated with MALLOC */ ! 21: /* LMALLOC is used for allocations of possibly larger than 64k */ ! 22: /* LFREE is used to free buffers allocated with LMALLOC */ ! 23: /* REALLOC is used to re-size a previously MALLOCed or LMALLOCed buffer */ ! 24: /****************************************************************************/ ! 25: #if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) ! 26: #if defined(__TURBOC__) ! 27: #define REALLOC(x,y) farrealloc(x,y) ! 28: #define LMALLOC(x) farmalloc(x) ! 29: #define MALLOC(x) farmalloc(x) ! 30: #define LFREE(x) farfree(x) ! 31: #define FREE(x) farfree(x) ! 32: #elif defined(__WATCOMC__) ! 33: #define REALLOC realloc ! 34: #define LMALLOC(x) halloc(x,1) /* far heap, but slow */ ! 35: #define MALLOC malloc /* far heap, but 64k max */ ! 36: #define LFREE hfree ! 37: #define FREE free ! 38: #else /* Other 16-bit Compiler */ ! 39: #define REALLOC realloc ! 40: #define LMALLOC malloc ! 41: #define MALLOC malloc ! 42: #define LFREE free ! 43: #define FREE free ! 44: #endif ! 45: #else /* 32-bit Compiler or Small Memory Model */ ! 46: #define REALLOC realloc ! 47: #define LMALLOC malloc ! 48: #define MALLOC malloc ! 49: #define LFREE free ! 50: #define FREE free ! 51: #endif ! 52: ! 53: ! 54: ! 55: typedef unsigned char uchar; ! 56: ! 57: /* LZSS Parameters */ ! 58: ! 59: #define LZH_N 4096 /* Size of string buffer */ ! 60: #define LZH_F 60 /* Size of look-ahead buffer */ ! 61: #define LZH_THRESHOLD 2 ! 62: #define LZH_NIL LZH_N /* End of tree's node */ ! 63: ! 64: #ifdef LZH_DYNAMIC_BUF ! 65: ! 66: unsigned char *lzh_text_buf; ! 67: short int lzh_match_position, lzh_match_length, ! 68: *lzh_lson, *lzh_rson, *lzh_dad; ! 69: ! 70: #else ! 71: ! 72: unsigned char lzh_text_buf[LZH_N + LZH_F - 1]; ! 73: short int lzh_match_position, lzh_match_length, ! 74: lzh_lson[LZH_N + 1], lzh_rson[LZH_N + 257], lzh_dad[LZH_N + 1]; ! 75: ! 76: #endif ! 77: ! 78: ! 79: void lzh_init_tree(void) /* Initializing tree */ ! 80: { ! 81: short int i; ! 82: ! 83: for (i = LZH_N + 1; i <= LZH_N + 256; i++) ! 84: lzh_rson[i] = LZH_NIL; /* root */ ! 85: for (i = 0; i < LZH_N; i++) ! 86: lzh_dad[i] = LZH_NIL; /* node */ ! 87: } ! 88: ! 89: /******************************/ ! 90: /* Inserting node to the tree */ ! 91: /* Only used during encoding */ ! 92: /******************************/ ! 93: void lzh_insert_node(short int r) ! 94: { ! 95: short int i, p, cmp; ! 96: unsigned char *key; ! 97: unsigned c; ! 98: ! 99: cmp = 1; ! 100: key = lzh_text_buf+r; ! 101: p = LZH_N + 1 + key[0]; ! 102: lzh_rson[r] = lzh_lson[r] = LZH_NIL; ! 103: lzh_match_length = 0; ! 104: for ( ; ; ) { ! 105: if (cmp >= 0) { ! 106: if (lzh_rson[p] != LZH_NIL) ! 107: p = lzh_rson[p]; ! 108: else { ! 109: lzh_rson[p] = r; ! 110: lzh_dad[r] = p; ! 111: return; ! 112: } ! 113: } else { ! 114: if (lzh_lson[p] != LZH_NIL) ! 115: p = lzh_lson[p]; ! 116: else { ! 117: lzh_lson[p] = r; ! 118: lzh_dad[r] = p; ! 119: return; ! 120: } ! 121: } ! 122: for (i = 1; i < LZH_F; i++) ! 123: if ((cmp = key[i] - lzh_text_buf[p + i]) != 0) ! 124: break; ! 125: if (i > LZH_THRESHOLD) { ! 126: if (i > lzh_match_length) { ! 127: lzh_match_position = ((r - p) & (LZH_N - 1)) - 1; ! 128: if ((lzh_match_length = i) >= LZH_F) ! 129: break; ! 130: } ! 131: if (i == lzh_match_length) { ! 132: if ((c = ((r - p) & (LZH_N - 1)) - 1) < lzh_match_position) { ! 133: lzh_match_position = c; ! 134: } ! 135: } ! 136: } ! 137: } ! 138: lzh_dad[r] = lzh_dad[p]; ! 139: lzh_lson[r] = lzh_lson[p]; ! 140: lzh_rson[r] = lzh_rson[p]; ! 141: lzh_dad[lzh_lson[p]] = r; ! 142: lzh_dad[lzh_rson[p]] = r; ! 143: if (lzh_rson[lzh_dad[p]] == p) ! 144: lzh_rson[lzh_dad[p]] = r; ! 145: else ! 146: lzh_lson[lzh_dad[p]] = r; ! 147: lzh_dad[p] = LZH_NIL; /* remove p */ ! 148: } ! 149: ! 150: void lzh_delete_node(short int p) /* Deleting node from the tree */ ! 151: { ! 152: short int q; ! 153: ! 154: if (lzh_dad[p] == LZH_NIL) ! 155: return; /* unregistered */ ! 156: if (lzh_rson[p] == LZH_NIL) ! 157: q = lzh_lson[p]; ! 158: else ! 159: if (lzh_lson[p] == LZH_NIL) ! 160: q = lzh_rson[p]; ! 161: else { ! 162: q = lzh_lson[p]; ! 163: if (lzh_rson[q] != LZH_NIL) { ! 164: do { ! 165: q = lzh_rson[q]; ! 166: } while (lzh_rson[q] != LZH_NIL); ! 167: lzh_rson[lzh_dad[q]] = lzh_lson[q]; ! 168: lzh_dad[lzh_lson[q]] = lzh_dad[q]; ! 169: lzh_lson[q] = lzh_lson[p]; ! 170: lzh_dad[lzh_lson[p]] = q; ! 171: } ! 172: lzh_rson[q] = lzh_rson[p]; ! 173: lzh_dad[lzh_rson[p]] = q; ! 174: } ! 175: lzh_dad[q] = lzh_dad[p]; ! 176: if (lzh_rson[lzh_dad[p]] == p) ! 177: lzh_rson[lzh_dad[p]] = q; ! 178: else ! 179: lzh_lson[lzh_dad[p]] = q; ! 180: lzh_dad[p] = LZH_NIL; ! 181: } ! 182: ! 183: /* Huffman coding parameters */ ! 184: ! 185: #define LZH_N_CHAR (256 - LZH_THRESHOLD + LZH_F) ! 186: /* character code (= 0..LZH_N_CHAR-1) */ ! 187: #define LZH_T (LZH_N_CHAR * 2 - 1) /* Size of table */ ! 188: #define LZH_R (LZH_T - 1) /* root position */ ! 189: #define MAX_FREQ 0x8000 ! 190: /* update when cumulative frequency */ ! 191: /* reaches to this value */ ! 192: ! 193: /* ! 194: * Tables for encoding/decoding upper 6 bits of ! 195: * sliding dictionary pointer ! 196: */ ! 197: /* encoder table */ ! 198: uchar lzh_p_len[64] = { ! 199: 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, ! 200: 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, ! 201: 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, ! 202: 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ! 203: 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ! 204: 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ! 205: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, ! 206: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 ! 207: }; ! 208: ! 209: uchar lzh_p_code[64] = { ! 210: 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68, ! 211: 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C, ! 212: 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, ! 213: 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, ! 214: 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, ! 215: 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, ! 216: 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, ! 217: 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF ! 218: }; ! 219: ! 220: /* decoder table */ ! 221: uchar lzh_d_code[256] = { ! 222: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 223: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 224: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 225: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ! 226: 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, ! 227: 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, ! 228: 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ! 229: 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ! 230: 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, ! 231: 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, ! 232: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, ! 233: 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, ! 234: 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, ! 235: 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ! 236: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, ! 237: 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, ! 238: 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, ! 239: 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, ! 240: 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, ! 241: 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, ! 242: 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, ! 243: 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, ! 244: 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, ! 245: 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, ! 246: 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, ! 247: 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, ! 248: 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, ! 249: 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, ! 250: 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, ! 251: 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, ! 252: 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, ! 253: 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, ! 254: }; ! 255: ! 256: uchar lzh_d_len[256] = { ! 257: 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, ! 258: 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, ! 259: 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, ! 260: 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, ! 261: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, ! 262: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, ! 263: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, ! 264: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, ! 265: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, ! 266: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, ! 267: 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, ! 268: 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, ! 269: 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, ! 270: 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, ! 271: 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, ! 272: 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, ! 273: 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, ! 274: 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, ! 275: 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, ! 276: 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, ! 277: 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, ! 278: 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, ! 279: 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, ! 280: 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, ! 281: 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ! 282: 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ! 283: 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ! 284: 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ! 285: 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ! 286: 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ! 287: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, ! 288: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, ! 289: }; ! 290: ! 291: #ifdef LZH_DYNAMIC_BUF ! 292: ! 293: unsigned short *lzh_freq=NULL; /* cumulative freq table */ ! 294: ! 295: /* ! 296: * pointing parent nodes. ! 297: * area [LZH_T..(LZH_T + LZH_N_CHAR - 1)] are pointers for leaves ! 298: */ ! 299: short int *lzh_prnt=NULL; ! 300: ! 301: /* pointing children nodes (son[], son[] + 1)*/ ! 302: short int *lzh_son=NULL; ! 303: ! 304: #else /* STATIC */ ! 305: ! 306: unsigned short lzh_freq[LZH_T + 1]; /* cumulative freq table */ ! 307: short int lzh_prnt[LZH_T + LZH_N_CHAR]; ! 308: short int lzh_son[LZH_T + 1]; /* bug fixed by Digital Dynamics */ ! 309: ! 310: #endif ! 311: ! 312: ! 313: unsigned short lzh_getbuf = 0; /* Was just "unsigned" fixed 04/12/95 */ ! 314: uchar lzh_getlen = 0; ! 315: ! 316: int lzh_getbit(uchar *inbuf, long *incnt, long inlen) /* get one bit */ ! 317: { ! 318: short int i; ! 319: ! 320: while (lzh_getlen <= 8) { ! 321: if((*incnt)>=inlen) ! 322: i=0; ! 323: else ! 324: i=inbuf[(*incnt)++]; ! 325: lzh_getbuf |= i << (8 - lzh_getlen); ! 326: lzh_getlen += 8; ! 327: } ! 328: i = lzh_getbuf; ! 329: lzh_getbuf <<= 1; ! 330: lzh_getlen--; ! 331: return (i < 0); ! 332: } ! 333: ! 334: short int lzh_getbyte(uchar *inbuf, long *incnt, long inlen) /* get a byte */ ! 335: { ! 336: unsigned short i; ! 337: ! 338: while (lzh_getlen <= 8) { ! 339: if((*incnt)>=inlen) ! 340: i=0; ! 341: else ! 342: i=inbuf[(*incnt)++]; ! 343: lzh_getbuf |= i << (8 - lzh_getlen); ! 344: lzh_getlen += 8; ! 345: } ! 346: i = lzh_getbuf; ! 347: lzh_getbuf <<= 8; ! 348: lzh_getlen -= 8; ! 349: return i >> 8; ! 350: } ! 351: ! 352: unsigned lzh_putbuf = 0; ! 353: uchar lzh_putlen = 0; ! 354: ! 355: /* output c bits */ ! 356: void lzh_putcode(short int l, unsigned short c, uchar *outbuf, long *outlen) ! 357: { ! 358: lzh_putbuf |= c >> lzh_putlen; ! 359: if ((lzh_putlen += l) >= 8) { ! 360: outbuf[(*outlen)++]=(lzh_putbuf >> 8); ! 361: if ((lzh_putlen -= 8) >= 8) { ! 362: outbuf[(*outlen)++]=lzh_putbuf; ! 363: lzh_putlen -= 8; ! 364: lzh_putbuf = c << (l - lzh_putlen); ! 365: } else { ! 366: lzh_putbuf <<= 8; ! 367: } ! 368: } ! 369: } ! 370: ! 371: ! 372: /* initialize freq tree */ ! 373: ! 374: void lzh_start_huff() ! 375: { ! 376: short int i, j; ! 377: ! 378: lzh_getbuf = 0; /* Added by Digital Dynamics for repeating operations */ ! 379: lzh_getlen = 0; ! 380: lzh_putbuf = 0; ! 381: lzh_putlen = 0; ! 382: ! 383: for (i = 0; i < LZH_N_CHAR; i++) { ! 384: lzh_freq[i] = 1; ! 385: lzh_son[i] = i + LZH_T; ! 386: lzh_prnt[i + LZH_T] = i; ! 387: } ! 388: i = 0; j = LZH_N_CHAR; ! 389: while (j <= LZH_R) { ! 390: lzh_freq[j] = lzh_freq[i] + lzh_freq[i + 1]; ! 391: lzh_son[j] = i; ! 392: lzh_prnt[i] = lzh_prnt[i + 1] = j; ! 393: i += 2; j++; ! 394: } ! 395: lzh_freq[LZH_T] = 0xffff; ! 396: lzh_prnt[LZH_R] = 0; ! 397: } ! 398: ! 399: ! 400: /* reconstruct freq tree */ ! 401: ! 402: void lzh_reconst() ! 403: { ! 404: short int i, j, k; ! 405: unsigned short f, l; ! 406: ! 407: /* halven cumulative freq for leaf nodes */ ! 408: j = 0; ! 409: for (i = 0; i < LZH_T; i++) { ! 410: if (lzh_son[i] >= LZH_T) { ! 411: lzh_freq[j] = (lzh_freq[i] + 1) / 2; ! 412: lzh_son[j] = lzh_son[i]; ! 413: j++; ! 414: } ! 415: } ! 416: /* make a tree : first, connect children nodes */ ! 417: for (i = 0, j = LZH_N_CHAR; j < LZH_T; i += 2, j++) { ! 418: k = i + 1; ! 419: f = lzh_freq[j] = lzh_freq[i] + lzh_freq[k]; ! 420: for (k = j - 1; f < lzh_freq[k]; k--); ! 421: k++; ! 422: l = (j - k) * 2; ! 423: ! 424: /* movmem() is Turbo-C dependent ! 425: rewritten to memmove() by Kenji */ ! 426: ! 427: /* movmem(&lzh_freq[k], &lzh_freq[k + 1], l); */ ! 428: (void)memmove(lzh_freq+k+1,lzh_freq+k, l); ! 429: lzh_freq[k] = f; ! 430: /* movmem(&lzh_son[k], &lzh_son[k + 1], l); */ ! 431: (void)memmove(lzh_son+k+1,lzh_son+k, l); ! 432: lzh_son[k] = i; ! 433: } ! 434: /* connect parent nodes */ ! 435: for (i = 0; i < LZH_T; i++) { ! 436: if ((k = lzh_son[i]) >= LZH_T) { ! 437: lzh_prnt[k] = i; ! 438: } else { ! 439: lzh_prnt[k] = lzh_prnt[k + 1] = i; ! 440: } ! 441: } ! 442: } ! 443: ! 444: /* update freq tree */ ! 445: ! 446: void lzh_update(short int c) ! 447: { ! 448: short int i, j, k, l; ! 449: ! 450: if (lzh_freq[LZH_R] == MAX_FREQ) { ! 451: lzh_reconst(); ! 452: } ! 453: c = lzh_prnt[c + LZH_T]; ! 454: do { ! 455: k = ++lzh_freq[c]; ! 456: ! 457: /* swap nodes to keep the tree freq-ordered */ ! 458: if (k > lzh_freq[l = c + 1]) { ! 459: while (k > lzh_freq[++l]); ! 460: l--; ! 461: lzh_freq[c] = lzh_freq[l]; ! 462: lzh_freq[l] = k; ! 463: ! 464: i = lzh_son[c]; ! 465: lzh_prnt[i] = l; ! 466: if (i < LZH_T) lzh_prnt[i + 1] = l; ! 467: ! 468: j = lzh_son[l]; ! 469: lzh_son[l] = i; ! 470: ! 471: lzh_prnt[j] = c; ! 472: if (j < LZH_T) lzh_prnt[j + 1] = c; ! 473: lzh_son[c] = j; ! 474: ! 475: c = l; ! 476: } ! 477: } while ((c = lzh_prnt[c]) != 0); /* do it until reaching the root */ ! 478: } ! 479: ! 480: unsigned short lzh_code, lzh_len; ! 481: ! 482: void lzh_encode_char(unsigned short c, uchar *outbuf, long *outlen) ! 483: { ! 484: unsigned short i; ! 485: short int j, k; ! 486: ! 487: i = 0; ! 488: j = 0; ! 489: k = lzh_prnt[c + LZH_T]; ! 490: ! 491: /* search connections from leaf node to the root */ ! 492: do { ! 493: i >>= 1; ! 494: ! 495: /* ! 496: if node's address is odd, output 1 ! 497: else output 0 ! 498: */ ! 499: if (k & 1) i += 0x8000; ! 500: ! 501: j++; ! 502: } while ((k = lzh_prnt[k]) != LZH_R); ! 503: lzh_putcode(j, i, outbuf, outlen); ! 504: lzh_code = i; ! 505: lzh_len = j; ! 506: lzh_update(c); ! 507: } ! 508: ! 509: void lzh_encode_position(unsigned short c, uchar *outbuf, long *outlen) ! 510: { ! 511: unsigned short i; ! 512: ! 513: /* output upper 6 bits with encoding */ ! 514: i = c >> 6; ! 515: lzh_putcode(lzh_p_len[i], (unsigned)lzh_p_code[i] << 8, outbuf, outlen); ! 516: ! 517: /* output lower 6 bits directly */ ! 518: lzh_putcode(6, (c & 0x3f) << 10, outbuf, outlen); ! 519: } ! 520: ! 521: void lzh_encode_end(uchar *outbuf, long *outlen) ! 522: { ! 523: if (lzh_putlen) { ! 524: outbuf[(*outlen)++]=(lzh_putbuf >> 8); ! 525: } ! 526: } ! 527: ! 528: short int lzh_decode_char(uchar *inbuf, long *incnt, long inlen) ! 529: { ! 530: unsigned short c; ! 531: ! 532: c = lzh_son[LZH_R]; ! 533: ! 534: /* ! 535: * start searching tree from the root to leaves. ! 536: * choose node #(lzh_son[]) if input bit == 0 ! 537: * else choose #(lzh_son[]+1) (input bit == 1) ! 538: */ ! 539: while (c < LZH_T) { ! 540: c += lzh_getbit(inbuf,incnt,inlen); ! 541: c = lzh_son[c]; ! 542: } ! 543: c -= LZH_T; ! 544: lzh_update(c); ! 545: return c; ! 546: } ! 547: ! 548: short int lzh_decode_position(uchar *inbuf, long *incnt, long inlen) ! 549: { ! 550: unsigned short i, j, c; ! 551: ! 552: /* decode upper 6 bits from given table */ ! 553: i = lzh_getbyte(inbuf,incnt,inlen); ! 554: c = (unsigned)lzh_d_code[i] << 6; ! 555: j = lzh_d_len[i]; ! 556: ! 557: /* input lower 6 bits directly */ ! 558: j -= 2; ! 559: while (j--) { ! 560: i = (i << 1) + lzh_getbit(inbuf,incnt,inlen); ! 561: } ! 562: return c | i & 0x3f; ! 563: } ! 564: ! 565: /* Compression */ ! 566: ! 567: /* Encoding/Compressing */ ! 568: /* Returns length of outbuf */ ! 569: long lzh_encode(uchar *inbuf, long inlen, uchar *outbuf) ! 570: { ! 571: short int i, c, len, r, s, last_match_length; ! 572: long incnt,outlen; /* textsize=0; */ ! 573: ! 574: #ifdef LZH_DYNAMIC_BUF ! 575: ! 576: if((lzh_text_buf=(uchar *)MALLOC(LZH_N + LZH_F - 1))==NULL) ! 577: return(-1); ! 578: if((lzh_freq=(unsigned short*)MALLOC((LZH_T + 1)*sizeof(unsigned short)))==NULL) { ! 579: FREE(lzh_text_buf); ! 580: return(-1); } ! 581: if((lzh_prnt=(short *)MALLOC((LZH_T + LZH_N_CHAR)*sizeof(short)))==NULL) { ! 582: FREE(lzh_text_buf); ! 583: FREE(lzh_freq); ! 584: return(-1); } ! 585: if((lzh_son=(short *)MALLOC((LZH_T + 1) * sizeof(short)))==NULL) { ! 586: FREE(lzh_text_buf); ! 587: FREE(lzh_prnt); ! 588: FREE(lzh_freq); ! 589: return(-1); } ! 590: if((lzh_lson=(short *)MALLOC((LZH_N + 1)*sizeof(short)))==NULL) { ! 591: FREE(lzh_text_buf); ! 592: FREE(lzh_prnt); ! 593: FREE(lzh_freq); ! 594: FREE(lzh_son); ! 595: return(-1); } ! 596: if((lzh_rson=(short *)MALLOC((LZH_N + 257)*sizeof(short)))==NULL) { ! 597: FREE(lzh_text_buf); ! 598: FREE(lzh_prnt); ! 599: FREE(lzh_freq); ! 600: FREE(lzh_son); ! 601: FREE(lzh_lson); ! 602: return(-1); } ! 603: if((lzh_dad=(short *)MALLOC((LZH_N + 1)*sizeof(short)))==NULL) { ! 604: FREE(lzh_text_buf); ! 605: FREE(lzh_prnt); ! 606: FREE(lzh_freq); ! 607: FREE(lzh_son); ! 608: FREE(lzh_lson); ! 609: FREE(lzh_rson); ! 610: return(-1); } ! 611: #endif ! 612: ! 613: incnt=0; ! 614: memcpy(outbuf,&inlen,sizeof(inlen)); ! 615: outlen=sizeof(inlen); ! 616: if(!inlen) { ! 617: #ifdef LZH_DYNAMIC_BUF ! 618: FREE(lzh_text_buf); ! 619: FREE(lzh_prnt); ! 620: FREE(lzh_freq); ! 621: FREE(lzh_son); ! 622: FREE(lzh_lson); ! 623: FREE(lzh_rson); ! 624: FREE(lzh_dad); ! 625: #endif ! 626: return(outlen); } ! 627: lzh_start_huff(); ! 628: lzh_init_tree(); ! 629: s = 0; ! 630: r = LZH_N - LZH_F; ! 631: for (i = s; i < r; i++) ! 632: lzh_text_buf[i] = ' '; ! 633: for (len = 0; len < LZH_F && incnt<inlen; len++) ! 634: lzh_text_buf[r + len] = inbuf[incnt++]; ! 635: /* textsize = len; */ ! 636: for (i = 1; i <= LZH_F; i++) ! 637: lzh_insert_node(r - i); ! 638: lzh_insert_node(r); ! 639: do { ! 640: if (lzh_match_length > len) ! 641: lzh_match_length = len; ! 642: if (lzh_match_length <= LZH_THRESHOLD) { ! 643: lzh_match_length = 1; ! 644: lzh_encode_char(lzh_text_buf[r],outbuf,&outlen); ! 645: } else { ! 646: lzh_encode_char(255 - LZH_THRESHOLD + lzh_match_length ! 647: ,outbuf,&outlen); ! 648: lzh_encode_position(lzh_match_position ! 649: ,outbuf,&outlen); ! 650: } ! 651: last_match_length = lzh_match_length; ! 652: for (i = 0; i < last_match_length && incnt<inlen; i++) { ! 653: lzh_delete_node(s); ! 654: c=inbuf[incnt++]; ! 655: lzh_text_buf[s] = c; ! 656: if (s < LZH_F - 1) ! 657: lzh_text_buf[s + LZH_N] = c; ! 658: s = (s + 1) & (LZH_N - 1); ! 659: r = (r + 1) & (LZH_N - 1); ! 660: lzh_insert_node(r); ! 661: } ! 662: /*** ! 663: if ((textsize += i) > printcount) { ! 664: printf("%12ld\r", textsize); ! 665: printcount += 1024; ! 666: } ! 667: ***/ ! 668: while (i++ < last_match_length) { ! 669: lzh_delete_node(s); ! 670: s = (s + 1) & (LZH_N - 1); ! 671: r = (r + 1) & (LZH_N - 1); ! 672: if (--len) lzh_insert_node(r); ! 673: } ! 674: } while (len > 0); ! 675: lzh_encode_end(outbuf,&outlen); ! 676: /* ! 677: printf("input: %ld (%ld) bytes\n", inlen,textsize); ! 678: printf("output: %ld bytes\n", outlen); ! 679: printf("output/input: %.3f\n", (double)outlen / inlen); ! 680: */ ! 681: ! 682: #ifdef LZH_DYNAMIC_BUF ! 683: FREE(lzh_text_buf); ! 684: FREE(lzh_prnt); ! 685: FREE(lzh_freq); ! 686: FREE(lzh_son); ! 687: FREE(lzh_lson); ! 688: FREE(lzh_rson); ! 689: FREE(lzh_dad); ! 690: #endif ! 691: ! 692: return(outlen); ! 693: } ! 694: ! 695: /* Decoding/Uncompressing */ ! 696: /* Returns length of outbuf */ ! 697: long lzh_decode(uchar *inbuf, long inlen, uchar *outbuf) ! 698: { ! 699: short int i, j, k, r, c; ! 700: unsigned long int count; ! 701: long incnt,textsize; ! 702: ! 703: #ifdef LZH_DYNAMIC_BUF ! 704: ! 705: if((lzh_text_buf=(uchar *)MALLOC((LZH_N + LZH_F - 1)*2))==NULL) ! 706: return(-1); ! 707: if((lzh_freq=(unsigned short *)MALLOC((LZH_T + 1)*sizeof(unsigned short))) ! 708: ==NULL) { ! 709: FREE(lzh_text_buf); ! 710: return(-1); } ! 711: if((lzh_prnt=(short *)MALLOC((LZH_T + LZH_N_CHAR)*sizeof(short)))==NULL) { ! 712: FREE(lzh_text_buf); ! 713: FREE(lzh_freq); ! 714: return(-1); } ! 715: if((lzh_son=(short *)MALLOC((LZH_T + 1) * sizeof(short)))==NULL) { ! 716: FREE(lzh_text_buf); ! 717: FREE(lzh_prnt); ! 718: FREE(lzh_freq); ! 719: return(-1); } ! 720: ! 721: #endif ! 722: ! 723: incnt=0; ! 724: memcpy(&textsize,inbuf,sizeof(textsize)); ! 725: incnt+=sizeof(textsize); ! 726: if (textsize == 0) { ! 727: #ifdef LZH_DYNAMIC_BUF ! 728: FREE(lzh_text_buf); ! 729: FREE(lzh_prnt); ! 730: FREE(lzh_freq); ! 731: FREE(lzh_son); ! 732: #endif ! 733: return(textsize); } ! 734: lzh_start_huff(); ! 735: for (i = 0; i < LZH_N - LZH_F; i++) ! 736: *(lzh_text_buf+i) = ' '; ! 737: r = LZH_N - LZH_F; ! 738: for (count = 0; count < textsize; ) { ! 739: c = lzh_decode_char(inbuf,&incnt,inlen); ! 740: if (c < 256) { ! 741: outbuf[count]=c; ! 742: #if 0 ! 743: if(r>(LZH_N + LZH_F - 1) || r<0) { ! 744: printf("Overflow! (%d)\n",r); ! 745: getch(); ! 746: exit(-1); } ! 747: #endif ! 748: *(lzh_text_buf+r) = c; ! 749: r++; ! 750: r &= (LZH_N - 1); ! 751: count++; ! 752: } else { ! 753: i = (r - lzh_decode_position(inbuf,&incnt,inlen) - 1) ! 754: & (LZH_N - 1); ! 755: j = c - 255 + LZH_THRESHOLD; ! 756: for (k = 0; k < j && count<textsize; k++) { ! 757: c = lzh_text_buf[(i + k) & (LZH_N - 1)]; ! 758: outbuf[count]=c; ! 759: #if 0 ! 760: if(r>(LZH_N + LZH_F - 1) || r<0) { ! 761: printf("Overflow! (%d)\n",r); ! 762: exit(-1); } ! 763: #endif ! 764: *(lzh_text_buf+r) = c; ! 765: r++; ! 766: r &= (LZH_N - 1); ! 767: count++; ! 768: } ! 769: } ! 770: } ! 771: /*** ! 772: printf("%12ld\n", count); ! 773: ***/ ! 774: ! 775: #ifdef LZH_DYNAMIC_BUF ! 776: FREE(lzh_text_buf); ! 777: FREE(lzh_prnt); ! 778: FREE(lzh_freq); ! 779: FREE(lzh_son); ! 780: #endif ! 781: ! 782: return(count); ! 783: } ! 784: ! 785:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.