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;
81 #define TXTSIZ (MAX_DICSIZ * 2L + MAXMATCH)
82 #define HSHSIZ (((unsigned long)1) <<15)
84 #define LIMIT 0x100 /* chain ŤΠlimit */
86 static unsigned int txtsiz;
88 static unsigned long dicsiz;
90 static unsigned int hval;
92 static unsigned int matchpos;
93 static unsigned int pos;
94 static unsigned int remainder;
97 /* ------------------------------------------------------------------------ */
103 case LZHUFF1_METHOD_NUM:
104 encode_set = encode_define[0];
106 dicbit = LZHUFF1_DICBIT; /* 12 bits Changed N.Watazaki */
108 case LZHUFF5_METHOD_NUM:
109 encode_set = encode_define[1];
111 dicbit = LZHUFF5_DICBIT; /* 13 bits */
113 case LZHUFF6_METHOD_NUM:
114 encode_set = encode_define[1];
116 dicbit = LZHUFF6_DICBIT; /* 15 bits */
118 case LZHUFF7_METHOD_NUM:
119 encode_set = encode_define[1];
121 dicbit = LZHUFF7_DICBIT; /* 16 bits */
127 dicsiz = (((unsigned long)1) << dicbit);
128 txtsiz = dicsiz*2+maxmatch;
130 if (hash) return method;
134 hash = (unsigned int*)xmalloc(HSHSIZ * sizeof(unsigned int));
135 prev = (unsigned int*)xmalloc(MAX_DICSIZ * sizeof(unsigned int));
136 text = (unsigned char*)xmalloc(TXTSIZ);
137 too_flag = (unsigned char*)xmalloc(HSHSIZ);
142 /* ------------------------------------------------------------------------ */
143 /* ¥Ý¥¤¥ó¥¿¤Î½é´ü²½ */
145 static void init_slide()
149 for (i = 0; i < HSHSIZ; i++) {
154 for (i = 0; i < DICSIZ; i++) {
160 /* ¼½ñ¤ò DICSIZ ʬ Á°¤Ë¤º¤é¤¹ */
170 assert(txtsiz - dicsiz > 0);
171 memmove(&text[0], &text[dicsiz], txtsiz - dicsiz);
173 n = fread_crc(&crc, &text[txtsiz - dicsiz], dicsiz, infile);
176 encoded_origsize += n; /* total size of read bytes */
179 for (i = 0; i < HSHSIZ; i++) {
181 hash[i] = (j > dicsiz) ? j - dicsiz : NIL;
184 for (i = 0; i < dicsiz; i++) {
186 prev[i] = (j > dicsiz) ? j - dicsiz : NIL;
193 /* ¸½ºß¤Îʸ»úÎó¤ò¥Á¥§¡¼¥ó¤ËÄɲ乤ë */
197 prev[pos & (dicsiz - 1)] = hash[hval];
202 /* ¸½ºß¤Îʸ»úÎó¤ÈºÇĹ°ìÃפ¹¤ëʸ»úÎó¤ò¸¡º÷¤·¡¢¥Á¥§¡¼¥ó¤ËÄɲ乤ë */
204 static void match_insert()
206 unsigned int scan_pos, scan_end, len;
207 unsigned char *a, *b;
208 unsigned int chain, off, h, max;
210 max = maxmatch; /* MAXMATCH; */
211 if (matchlen < THRESHOLD - 1) matchlen = THRESHOLD - 1;
215 for (h = hval; too_flag[h] && off < maxmatch - THRESHOLD; ) {
216 h = ((h << 5) ^ text[pos + (++off) + 2]) & (unsigned)(HSHSIZ - 1);
218 if (off == maxmatch - THRESHOLD) off = 0;
222 scan_end = (pos > dicsiz) ? pos + off - dicsiz : off;
223 while (scan_pos > scan_end) {
226 if (text[scan_pos + matchlen - off] == text[pos + matchlen]) {
228 a = text + scan_pos - off; b = text + pos;
229 for (len = 0; len < max && *a++ == *b++; len++);
232 if (len > matchlen) {
233 matchpos = scan_pos - off;
234 if ((matchlen = len) == max) {
239 if (matchpos < dicsiz) {
240 printf("matchpos=%u scan_pos=%u dicsiz=%u\n"
241 ,matchpos, scan_pos, dicsiz);
247 scan_pos = prev[scan_pos & (dicsiz - 1)];
253 if (matchlen > off + 2 || off == 0)
259 prev[pos & (dicsiz - 1)] = hash[hval];
264 /* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¡¢¼½ñ¤ò¹¹¿·¤·¡¢¥Ï¥Ã¥·¥åÃͤò¹¹¿·¤¹¤ë */
271 if (++pos >= txtsiz - maxmatch) {
277 hval = ((hval << 5) ^ text[pos + 2]) & (unsigned)(HSHSIZ - 1);
284 struct interfacing *interface;
287 unsigned int lastmatchoffset;
295 fout = fopen("en", "wt");
296 if (fout == NULL) exit(1);
298 infile = interface->infile;
299 outfile = interface->outfile;
300 origsize = interface->original;
301 compsize = count = 0L;
306 /* encode_alloc(); */ /* allocate_memory(); */
309 encode_set.encode_start();
310 memset(&text[0], ' ', TXTSIZ);
312 remainder = fread_crc(&crc, &text[dicsiz], txtsiz-dicsiz, infile);
313 encoded_origsize = remainder;
314 matchlen = THRESHOLD - 1;
318 if (matchlen > remainder) matchlen = remainder;
319 hval = ((((text[dicsiz] << 5) ^ text[dicsiz + 1]) << 5)
320 ^ text[dicsiz + 2]) & (unsigned)(HSHSIZ - 1);
323 while (remainder > 0 && ! unpackable) {
324 lastmatchlen = matchlen; lastmatchoffset = pos - matchpos - 1;
326 crc = get_next(crc); match_insert();
327 if (matchlen > remainder) matchlen = remainder;
328 if (matchlen > lastmatchlen || lastmatchlen < THRESHOLD) {
329 encode_set.output(text[pos - 1], 0);
331 fprintf(fout, "%u C %02X\n", addr, text[pos-1]);
336 encode_set.output(lastmatchlen + (UCHAR_MAX + 1 - THRESHOLD),
337 (lastmatchoffset) & (dicsiz-1) );
341 fprintf(fout, "%u M %u %u ", addr,
342 lastmatchoffset & (dicsiz-1), lastmatchlen+1);
343 addr += lastmatchlen +1 ;
347 for (t=0; t<lastmatchlen+1; t++) {
348 cc = text[pos - lastmatchoffset - 2 + t];
349 fprintf(fout, "%02X ", cc);
354 while (--lastmatchlen > 0) {
355 crc = get_next(crc); insert();
359 matchlen = THRESHOLD - 1;
361 if (matchlen > remainder) matchlen = remainder;
364 encode_set.encode_end();
366 interface->packed = compsize;
367 interface->original = encoded_origsize;
372 /* ------------------------------------------------------------------------ */
375 struct interfacing *interface;
377 unsigned int i, j, k, c;
378 unsigned int dicsiz1, offset;
379 unsigned char *dtext;
383 fout = fopen("de", "wt");
384 if (fout == NULL) exit(1);
387 infile = interface->infile;
388 outfile = interface->outfile;
389 dicbit = interface->dicbit;
390 origsize = interface->original;
391 compsize = interface->packed;
392 decode_set = decode_define[interface->method - 1];
396 dicsiz = 1L << dicbit;
397 dtext = (unsigned char *)xmalloc(dicsiz);
398 for (i=0; i<dicsiz; i++) dtext[i] = 0x20;
399 decode_set.decode_start();
400 dicsiz1 = dicsiz - 1;
401 offset = (interface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3;
404 while (count < origsize) {
405 c = decode_set.decode_c();
406 if (c <= UCHAR_MAX) {
408 fprintf(fout, "%u C %02X\n", count, c);
412 fwrite_crc(&crc, dtext, dicsiz, outfile);
419 i = (loc - decode_set.decode_p() - 1) & dicsiz1;
421 fprintf(fout, "%u M %u %u ", count, (loc-1-i) & dicsiz1, j);
424 for (k = 0; k < j; k++) {
425 c = dtext[(i + k) & dicsiz1];
428 fprintf(fout, "%02X ", c & 0xff);
432 fwrite_crc(&crc, dtext, dicsiz, outfile);
442 fwrite_crc(&crc, dtext, loc, outfile);