|
|
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.