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