📄 lzhuf.c
字号:
if (putc(putbuf >> 8, outfile) == EOF) { Error(wterr); } if ((putlen -= 8) >= 8) { if (putc(putbuf, outfile) == EOF) { Error(wterr); }#ifdef VERBOSE codesize += 2;#endif putlen -= 8; putbuf = c << (l - putlen); } else { putbuf <<= 8;#ifdef VERBOSE codesize++;#endif } }}#endif/* initialization of tree */#if defined(ENCODE) || defined(DECODE)static void StartHuff(void){ int i, j; for (i = 0; i < N_CHAR; i++) { freq[i] = 1; son[i] = i + T; prnt[i + T] = i; } i = 0; j = N_CHAR; while (j <= R) { freq[j] = freq[i] + freq[i + 1]; son[j] = i; prnt[i] = prnt[i + 1] = j; i += 2; j++; } freq[T] = 0xffff; prnt[R] = 0;}/* reconstruction of tree */static void reconst(void){ int i, j, k; unsigned f, l; /* collect leaf nodes in the first half of the table */ /* and replace the freq by (freq + 1) / 2. */ j = 0; for (i = 0; i < T; i++) { if (son[i] >= T) { freq[j] = (freq[i] + 1) / 2; son[j] = son[i]; j++; } } /* begin constructing tree by connecting sons */ for (i = 0, j = N_CHAR; j < T; i += 2, j++) { k = i + 1; f = freq[j] = freq[i] + freq[k]; for (k = j - 1; f < freq[k]; k--); k++; l = (j - k) * 2; memmove(&freq[k + 1], &freq[k], l); freq[k] = f; memmove(&son[k + 1], &son[k], l); son[k] = i; } /* connect prnt */ for (i = 0; i < T; i++) { if ((k = son[i]) >= T) { prnt[k] = i; } else { prnt[k] = prnt[k + 1] = i; } }}/* increment frequency of given code by one, and update tree */static void update(int c){ int i, j, k, l; if (freq[R] == MAX_FREQ) { reconst(); } c = prnt[c + T]; do { k = ++freq[c]; /* if the order is disturbed, exchange nodes */ if (k > freq[l = c + 1]) { while (k > freq[++l]); l--; freq[c] = freq[l]; freq[l] = k; i = son[c]; prnt[i] = l; if (i < T) prnt[i + 1] = l; j = son[l]; son[l] = i; prnt[j] = c; if (j < T) prnt[j + 1] = c; son[c] = j; c = l; } } while ((c = prnt[c]) != 0); /* repeat up to root */}#endif#ifdef ENCODE#if 0static unsigned code, len;#endifstatic void EncodeChar(unsigned c){ unsigned i; int j, k; i = 0; j = 0; k = prnt[c + T]; /* travel from leaf to root */ do { i >>= 1; /* if node's address is odd-numbered, choose bigger brother node */ if (k & 1) i += 0x8000; j++; } while ((k = prnt[k]) != R); Putcode(j, i);#if 0 code = i; len = j;#endif update(c);}static void EncodePosition(unsigned c){ unsigned i; /* output upper 6 bits by table lookup */ i = c >> 6; Putcode(p_len[i], (unsigned)p_code[i] << 8); /* output lower 6 bits verbatim */ Putcode(6, (c & 0x3f) << 10);}static void EncodeEnd(void){ if (putlen) { if (putc(putbuf >> 8, outfile) == EOF) { Error(wterr); }#ifdef VERBOSE codesize++;#endif }}#endif#ifdef DECODEstatic int DecodeChar(void){ unsigned c; c = son[R]; /* travel from root to leaf, */ /* choosing the smaller child node (son[]) if the read bit is 0, */ /* the bigger (son[]+1} if 1 */ while (c < T) { c += GetBit(); c = son[c]; } c -= T; update(c); return c;}static int DecodePosition(void){ unsigned i, j, c; /* recover upper 6 bits from table */ i = GetByte(); c = (unsigned)d_code[i] << 6; j = d_len[i]; /* read lower 6 bits verbatim */ j -= 2; while (j--) { i = (i << 1) + GetBit(); } return c | (i & 0x3f);}#endif#ifdef ENCODE/* compression */void Encode(void) /* compression */{ int i, c, len, r, s, last_match_length; unsigned long tw; fseek(infile, 0L, 2); textsize = ftell(infile);#ifdef VERBOSE if ((signed long)textsize < 0) Fprintf((stderr, "Errno: %d", errno));#endif tw = host_to_i86ul(textsize); if (fwrite(&tw, sizeof tw, 1, outfile) < 1) Error(wterr); /* output size of text */ if (textsize == 0) return; rewind(infile); textsize = 0; /* rewind and re-read */ StartHuff(); InitTree(); s = 0; r = N - F; for (i = s; i < r; i++) text_buf[i] = ' '; for (len = 0; len < F && (c = getc(infile)) != EOF; len++) text_buf[r + len] = c; textsize = len; for (i = 1; i <= F; i++) InsertNode(r - i); InsertNode(r); do { if (match_length > len) match_length = len; if (match_length <= THRESHOLD) { match_length = 1; EncodeChar(text_buf[r]); } else { EncodeChar(255 - THRESHOLD + match_length); EncodePosition(match_position); } last_match_length = match_length; for (i = 0; i < last_match_length && (c = getc(infile)) != EOF; i++) { DeleteNode(s); text_buf[s] = c; if (s < F - 1) text_buf[s + N] = c; s = (s + 1) & (N - 1); r = (r + 1) & (N - 1); InsertNode(r); } if ((textsize += i) > printcount) {#if defined(VERBOSE) && defined(EXTRAVERBOSE) Fprintf((stderr, "%12ld\r", textsize));#endif printcount += 1024; } while (i++ < last_match_length) { DeleteNode(s); s = (s + 1) & (N - 1); r = (r + 1) & (N - 1); if (--len) InsertNode(r); } } while (len > 0); EncodeEnd();#ifdef LONG_REPORT Fprintf((stderr, "input size %ld bytes\n", codesize)); Fprintf((stderr, "output size %ld bytes\n", textsize)); Fprintf((stderr, "input/output %.3f\n", (double)codesize / textsize));#else Fprintf((stderr, "input/output = %ld/%ld = %.3f\n", codesize, textsize, (double)codesize / textsize));#endif}#endif#ifdef DECODEvoid Decode(void) /* recover */{ int i, j, k, r, c; unsigned long int count; unsigned long tw; if (fread(&tw, sizeof tw, 1, infile) < 1) Error("Can't read"); /* read size of text */ textsize = i86ul_to_host(tw); if (textsize == 0) return; StartHuff(); for (i = 0; i < N - F; i++) text_buf[i] = ' '; r = N - F; for (count = 0; count < textsize; ) { c = DecodeChar(); if (c < 256) { if (putc(c, outfile) == EOF) { Error(wterr); } text_buf[r++] = c; r &= (N - 1); count++; } else { i = (r - DecodePosition() - 1) & (N - 1); j = c - 255 + THRESHOLD; for (k = 0; k < j; k++) { c = text_buf[(i + k) & (N - 1)]; if (putc(c, outfile) == EOF) { Error(wterr); } text_buf[r++] = c; r &= (N - 1); count++; } } if (count > printcount) {#if defined(VERBOSE) && defined(EXTRAVERBOSE) Fprintf((stderr, "%12ld\r", count));#endif printcount += 1024; } } Fprintf((stderr, "%12ld\n", count));}#endif#ifdef MAINint main(int argc, char *argv[]){ char *s; FILE *f; int c; if (argc == 2) { outfile = stdout; if ((f = tmpfile()) == NULL) { perror("tmpfile"); return EXIT_FAILURE; } while ((c = getchar()) != EOF) fputc(c, f); rewind(infile = f); } else if (argc != 4) { Fprintf((stderr, "'lzhuf e file1 file2' encodes file1 into file2.\n" "'lzhuf d file2 file1' decodes file2 into file1.\n")); return EXIT_FAILURE; } if (argc == 4) { if ((s = argv[1], s[1] || strpbrk(s, "DEde") == NULL) || (s = argv[2], (infile = fopen(s, "rb")) == NULL) || (s = argv[3], (outfile = fopen(s, "wb")) == NULL)) { Fprintf((stderr, "??? %s\n", s)); return EXIT_FAILURE; } } if (toupper(*argv[1]) == 'E') Encode(); else Decode(); fclose(infile); fclose(outfile); return EXIT_SUCCESS;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -