1 /* ------------------------------------------------------------------------ */
3 /* slice.c -- sliding dictionary with percolating update */
5 /* Modified Nobutaka Watazaki */
7 /* Ver. 1.14d Exchanging a search algorithm 1997.01.11 T.Okamoto */
8 /* ------------------------------------------------------------------------ */
19 static int noslide = 1;
22 /* ------------------------------------------------------------------------ */
24 static unsigned long encoded_origsize;
26 /* ------------------------------------------------------------------------ */
28 static unsigned int *hash;
29 static unsigned int *prev;
31 /* static unsigned char *text; */
32 unsigned char *too_flag;
35 static struct encode_option encode_define[2] = {
36 #if defined(__STDC__) || defined(AIX)
38 {(void (*) ()) output_dyn,
39 (void (*) ()) encode_start_fix,
40 (void (*) ()) encode_end_dyn},
42 {(void (*) ()) output_st1,
43 (void (*) ()) encode_start_st1,
44 (void (*) ()) encode_end_st1}
47 {(int (*) ()) output_dyn,
48 (int (*) ()) encode_start_fix,
49 (int (*) ()) encode_end_dyn},
51 {(int (*) ()) output_st1,
52 (int (*) ()) encode_start_st1,
53 (int (*) ()) encode_end_st1}
57 static struct decode_option decode_define[] = {
59 {decode_c_dyn, decode_p_st0, decode_start_fix},
61 {decode_c_dyn, decode_p_dyn, decode_start_dyn},
63 {decode_c_st0, decode_p_st0, decode_start_st0},
65 {decode_c_st1, decode_p_st1, decode_start_st1},
67 {decode_c_st1, decode_p_st1, decode_start_st1},
69 {decode_c_st1, decode_p_st1, decode_start_st1},
71 {decode_c_st1, decode_p_st1, decode_start_st1},
73 {decode_c_lzs, decode_p_lzs, decode_start_lzs},
75 {decode_c_lz5, decode_p_lz5, decode_start_lz5}
78 static struct encode_option encode_set;
79 static struct decode_option decode_set;
82 static node pos, matchpos, avail, *position, *parent, *prev;
83 static int remainder, matchlen;
84 static unsigned char *level, *childcount;
85 static unsigned long dicsiz; /* t.okamoto */
86 static unsigned short max_hash_val;
87 static unsigned short hash1, hash2;
91 #define DICSIZ (1L << 16)
92 #define TXTSIZ (DICSIZ * 2L + MAXMATCH)
94 #define DICSIZ (((unsigned long)1) << 15)
95 #define TXTSIZ (DICSIZ * 2 + MAXMATCH)
98 #define HSHSIZ (((unsigned long)1) <<15)
100 #define LIMIT 0x100 /* chain ŤΠlimit */
102 static unsigned int txtsiz;
104 static unsigned long dicsiz;
106 static unsigned int hval;
108 static unsigned int matchpos;
109 static unsigned int pos;
110 static unsigned int remainder;
113 /* ------------------------------------------------------------------------ */
118 if (method == LZHUFF1_METHOD_NUM) { /* Changed N.Watazaki */
119 encode_set = encode_define[0];
121 dicbit = 12; /* 12 Changed N.Watazaki */
122 } else { /* method LH4(12),LH5(13),LH6(15) */
123 encode_set = encode_define[1];
125 if (method == LZHUFF7_METHOD_NUM)
126 dicbit = MAX_DICBIT; /* 16 bits */
127 else if (method == LZHUFF6_METHOD_NUM)
128 dicbit = MAX_DICBIT-1; /* 15 bits */
129 else /* LH5 LH4 is not used */
130 dicbit = MAX_DICBIT - 3; /* 13 bits */
133 dicsiz = (((unsigned long)1) << dicbit);
134 txtsiz = dicsiz*2+maxmatch;
136 if (hash) return method;
140 hash = (unsigned int*)xmalloc(HSHSIZ * sizeof(unsigned int));
141 prev = (unsigned int*)xmalloc(DICSIZ * sizeof(unsigned int));
142 text = (unsigned char*)xmalloc(TXTSIZ);
143 too_flag = (unsigned char*)xmalloc(HSHSIZ);
148 /* ------------------------------------------------------------------------ */
149 /* ¥Ý¥¤¥ó¥¿¤Î½é´ü²½ */
151 static void init_slide()
155 for (i = 0; i < HSHSIZ; i++) {
160 for (i = 0; i < DICSIZ; i++) {
166 /* ¼½ñ¤ò DICSIZ ʬ Á°¤Ë¤º¤é¤¹ */
175 memmove(&text[0], &text[dicsiz], (unsigned)(txtsiz - dicsiz));
179 i = 0; j = dicsiz; m = txtsiz-dicsiz;
181 text[i++] = text[j++];
185 n = fread_crc(&text[(unsigned)(txtsiz - dicsiz)],
186 (unsigned)dicsiz, infile);
189 encoded_origsize += n;
192 for (i = 0; i < HSHSIZ; i++) {
194 hash[i] = (j > dicsiz) ? j - dicsiz : NIL;
197 for (i = 0; i < dicsiz; i++) {
199 prev[i] = (j > dicsiz) ? j - dicsiz : NIL;
204 /* ¸½ºß¤Îʸ»úÎó¤ò¥Á¥§¡¼¥ó¤ËÄɲ乤ë */
208 prev[pos & (dicsiz - 1)] = hash[hval];
213 /* ¸½ºß¤Îʸ»úÎó¤ÈºÇĹ°ìÃפ¹¤ëʸ»úÎó¤ò¸¡º÷¤·¡¢¥Á¥§¡¼¥ó¤ËÄɲ乤ë */
215 static void match_insert()
217 unsigned int scan_pos, scan_end, len;
218 unsigned char *a, *b;
219 unsigned int chain, off, h, max;
221 max = maxmatch; /* MAXMATCH; */
222 if (matchlen < THRESHOLD - 1) matchlen = THRESHOLD - 1;
226 for (h = hval; too_flag[h] && off < maxmatch - THRESHOLD; ) {
227 h = ((h << 5) ^ text[pos + (++off) + 2]) & (unsigned)(HSHSIZ - 1);
229 if (off == maxmatch - THRESHOLD) off = 0;
233 scan_end = (pos > dicsiz) ? pos + off - dicsiz : off;
234 while (scan_pos > scan_end) {
237 if (text[scan_pos + matchlen - off] == text[pos + matchlen]) {
239 a = text + scan_pos - off; b = text + pos;
240 for (len = 0; len < max && *a++ == *b++; len++);
243 if (len > matchlen) {
244 matchpos = scan_pos - off;
245 if ((matchlen = len) == max) {
250 if (matchpos < dicsiz) {
251 printf("matchpos=%u scan_pos=%u dicsiz=%u\n"
252 ,matchpos, scan_pos, dicsiz);
258 scan_pos = prev[scan_pos & (dicsiz - 1)];
264 if (matchlen > off + 2 || off == 0)
270 prev[pos & (dicsiz - 1)] = hash[hval];
275 /* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¡¢¼½ñ¤ò¹¹¿·¤·¡¢¥Ï¥Ã¥·¥åÃͤò¹¹¿·¤¹¤ë */
277 static void get_next()
280 if (++pos >= txtsiz - maxmatch) {
286 hval = ((hval << 5) ^ text[pos + 2]) & (unsigned)(HSHSIZ - 1);
289 void encode(interface)
290 struct interfacing *interface;
293 unsigned int lastmatchoffset;
300 fout = fopen("en", "wt");
301 if (fout == NULL) exit(1);
303 infile = interface->infile;
304 outfile = interface->outfile;
305 origsize = interface->original;
306 compsize = count = 0L;
307 crc = unpackable = 0;
309 /* encode_alloc(); */ /* allocate_memory(); */
312 encode_set.encode_start();
313 memset(&text[0], ' ', (long)TXTSIZ);
315 remainder = fread_crc(&text[dicsiz], txtsiz-dicsiz, infile);
316 encoded_origsize = remainder;
317 matchlen = THRESHOLD - 1;
321 if (matchlen > remainder) matchlen = remainder;
322 hval = ((((text[dicsiz] << 5) ^ text[dicsiz + 1]) << 5)
323 ^ text[dicsiz + 2]) & (unsigned)(HSHSIZ - 1);
326 while (remainder > 0 && ! unpackable) {
327 lastmatchlen = matchlen; lastmatchoffset = pos - matchpos - 1;
329 get_next(); match_insert();
330 if (matchlen > remainder) matchlen = remainder;
331 if (matchlen > lastmatchlen || lastmatchlen < THRESHOLD) {
332 encode_set.output(text[pos - 1], 0);
334 fprintf(fout, "%u C %02X\n", addr, text[pos-1]);
339 encode_set.output(lastmatchlen + (UCHAR_MAX + 1 - THRESHOLD),
340 (lastmatchoffset) & (dicsiz-1) );
344 fprintf(fout, "%u M %u %u ", addr,
345 lastmatchoffset & (dicsiz-1), lastmatchlen+1);
346 addr += lastmatchlen +1 ;
350 for (t=0; t<lastmatchlen+1; t++) {
351 cc = text[(pos-(lastmatchoffset)) & (dicsiz-1)];
352 fprintf(fout, "%02X ", cc);
357 while (--lastmatchlen > 0) {
358 get_next(); insert();
362 matchlen = THRESHOLD - 1;
364 if (matchlen > remainder) matchlen = remainder;
367 encode_set.encode_end();
369 interface->packed = compsize;
370 interface->original = encoded_origsize;
373 /* ------------------------------------------------------------------------ */
376 struct interfacing *interface;
378 unsigned int i, j, k, c;
379 unsigned int dicsiz1, offset;
380 unsigned char *dtext;
384 fout = fopen("de", "wt");
385 if (fout == NULL) exit(1);
388 infile = interface->infile;
389 outfile = interface->outfile;
390 dicbit = interface->dicbit;
391 origsize = interface->original;
392 compsize = interface->packed;
393 decode_set = decode_define[interface->method - 1];
397 dicsiz = 1L << dicbit;
398 dtext = (unsigned char *)xmalloc(dicsiz);
399 for (i=0; i<dicsiz; i++) dtext[i] = 0x20;
400 decode_set.decode_start();
401 dicsiz1 = dicsiz - 1;
402 offset = (interface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3;
405 while (count < origsize) {
406 c = decode_set.decode_c();
407 if (c <= UCHAR_MAX) {
409 fprintf(fout, "%u C %02X\n", count, c);
413 fwrite_crc(dtext, dicsiz, outfile);
420 i = (loc - decode_set.decode_p() - 1) & dicsiz1;
422 fprintf(fout, "%u M %u %u ", count, (loc-1-i) & dicsiz1, j);
425 for (k = 0; k < j; k++) {
426 c = dtext[(i + k) & dicsiz1];
429 fprintf(fout, "%02X ", c & 0xff);
433 fwrite_crc(dtext, dicsiz, outfile);
443 fwrite_crc(dtext, loc, outfile);
449 /* Local Variables: */