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 = LH7_DICBIT; /* 16 bits */
127 else if (method == LZHUFF6_METHOD_NUM)
128 dicbit = LH6_DICBIT; /* 15 bits */
129 else /* LH5 LH4 is not used */
130 dicbit = LH5_DICBIT; /* 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 ʬ Á°¤Ë¤º¤é¤¹ */
176 memmove(&text[0], &text[dicsiz], (unsigned)(txtsiz - dicsiz));
180 i = 0; j = dicsiz; m = txtsiz-dicsiz;
182 text[i++] = text[j++];
186 n = fread_crc(&crc, &text[(unsigned)(txtsiz - dicsiz)],
187 (unsigned)dicsiz, infile);
190 encoded_origsize += n;
193 for (i = 0; i < HSHSIZ; i++) {
195 hash[i] = (j > dicsiz) ? j - dicsiz : NIL;
198 for (i = 0; i < dicsiz; i++) {
200 prev[i] = (j > dicsiz) ? j - dicsiz : NIL;
207 /* ¸½ºß¤Îʸ»úÎó¤ò¥Á¥§¡¼¥ó¤ËÄɲ乤ë */
211 prev[pos & (dicsiz - 1)] = hash[hval];
216 /* ¸½ºß¤Îʸ»úÎó¤ÈºÇĹ°ìÃפ¹¤ëʸ»úÎó¤ò¸¡º÷¤·¡¢¥Á¥§¡¼¥ó¤ËÄɲ乤ë */
218 static void match_insert()
220 unsigned int scan_pos, scan_end, len;
221 unsigned char *a, *b;
222 unsigned int chain, off, h, max;
224 max = maxmatch; /* MAXMATCH; */
225 if (matchlen < THRESHOLD - 1) matchlen = THRESHOLD - 1;
229 for (h = hval; too_flag[h] && off < maxmatch - THRESHOLD; ) {
230 h = ((h << 5) ^ text[pos + (++off) + 2]) & (unsigned)(HSHSIZ - 1);
232 if (off == maxmatch - THRESHOLD) off = 0;
236 scan_end = (pos > dicsiz) ? pos + off - dicsiz : off;
237 while (scan_pos > scan_end) {
240 if (text[scan_pos + matchlen - off] == text[pos + matchlen]) {
242 a = text + scan_pos - off; b = text + pos;
243 for (len = 0; len < max && *a++ == *b++; len++);
246 if (len > matchlen) {
247 matchpos = scan_pos - off;
248 if ((matchlen = len) == max) {
253 if (matchpos < dicsiz) {
254 printf("matchpos=%u scan_pos=%u dicsiz=%u\n"
255 ,matchpos, scan_pos, dicsiz);
261 scan_pos = prev[scan_pos & (dicsiz - 1)];
267 if (matchlen > off + 2 || off == 0)
273 prev[pos & (dicsiz - 1)] = hash[hval];
278 /* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¡¢¼½ñ¤ò¹¹¿·¤·¡¢¥Ï¥Ã¥·¥åÃͤò¹¹¿·¤¹¤ë */
285 if (++pos >= txtsiz - maxmatch) {
291 hval = ((hval << 5) ^ text[pos + 2]) & (unsigned)(HSHSIZ - 1);
298 struct interfacing *interface;
301 unsigned int lastmatchoffset;
309 fout = fopen("en", "wt");
310 if (fout == NULL) exit(1);
312 infile = interface->infile;
313 outfile = interface->outfile;
314 origsize = interface->original;
315 compsize = count = 0L;
320 /* encode_alloc(); */ /* allocate_memory(); */
323 encode_set.encode_start();
324 memset(&text[0], ' ', (long)TXTSIZ);
326 remainder = fread_crc(&crc, &text[dicsiz], txtsiz-dicsiz, infile);
327 encoded_origsize = remainder;
328 matchlen = THRESHOLD - 1;
332 if (matchlen > remainder) matchlen = remainder;
333 hval = ((((text[dicsiz] << 5) ^ text[dicsiz + 1]) << 5)
334 ^ text[dicsiz + 2]) & (unsigned)(HSHSIZ - 1);
337 while (remainder > 0 && ! unpackable) {
338 lastmatchlen = matchlen; lastmatchoffset = pos - matchpos - 1;
340 crc = get_next(crc); match_insert();
341 if (matchlen > remainder) matchlen = remainder;
342 if (matchlen > lastmatchlen || lastmatchlen < THRESHOLD) {
343 encode_set.output(text[pos - 1], 0);
345 fprintf(fout, "%u C %02X\n", addr, text[pos-1]);
350 encode_set.output(lastmatchlen + (UCHAR_MAX + 1 - THRESHOLD),
351 (lastmatchoffset) & (dicsiz-1) );
355 fprintf(fout, "%u M %u %u ", addr,
356 lastmatchoffset & (dicsiz-1), lastmatchlen+1);
357 addr += lastmatchlen +1 ;
361 for (t=0; t<lastmatchlen+1; t++) {
362 cc = text[pos - lastmatchoffset - 2 + t];
363 fprintf(fout, "%02X ", cc);
368 while (--lastmatchlen > 0) {
369 crc = get_next(crc); insert();
373 matchlen = THRESHOLD - 1;
375 if (matchlen > remainder) matchlen = remainder;
378 encode_set.encode_end();
380 interface->packed = compsize;
381 interface->original = encoded_origsize;
386 /* ------------------------------------------------------------------------ */
389 struct interfacing *interface;
391 unsigned int i, j, k, c;
392 unsigned int dicsiz1, offset;
393 unsigned char *dtext;
397 fout = fopen("de", "wt");
398 if (fout == NULL) exit(1);
401 infile = interface->infile;
402 outfile = interface->outfile;
403 dicbit = interface->dicbit;
404 origsize = interface->original;
405 compsize = interface->packed;
406 decode_set = decode_define[interface->method - 1];
410 dicsiz = 1L << dicbit;
411 dtext = (unsigned char *)xmalloc(dicsiz);
412 for (i=0; i<dicsiz; i++) dtext[i] = 0x20;
413 decode_set.decode_start();
414 dicsiz1 = dicsiz - 1;
415 offset = (interface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3;
418 while (count < origsize) {
419 c = decode_set.decode_c();
420 if (c <= UCHAR_MAX) {
422 fprintf(fout, "%u C %02X\n", count, c);
426 fwrite_crc(&crc, dtext, dicsiz, outfile);
433 i = (loc - decode_set.decode_p() - 1) & dicsiz1;
435 fprintf(fout, "%u M %u %u ", count, (loc-1-i) & dicsiz1, j);
438 for (k = 0; k < j; k++) {
439 c = dtext[(i + k) & dicsiz1];
442 fprintf(fout, "%02X ", c & 0xff);
446 fwrite_crc(&crc, dtext, dicsiz, outfile);
456 fwrite_crc(&crc, dtext, loc, outfile);
463 /* Local Variables: */
467 /* vi: set tabstop=4: */