diff options
Diffstat (limited to 'trees.c')
-rw-r--r-- | trees.c | 50 |
1 files changed, 14 insertions, 36 deletions
@@ -416,7 +416,7 @@ local void init_block(s) | |||
416 | 416 | ||
417 | s->dyn_ltree[END_BLOCK].Freq = 1; | 417 | s->dyn_ltree[END_BLOCK].Freq = 1; |
418 | s->opt_len = s->static_len = 0L; | 418 | s->opt_len = s->static_len = 0L; |
419 | s->last_lit = s->matches = 0; | 419 | s->sym_next = s->matches = 0; |
420 | } | 420 | } |
421 | 421 | ||
422 | #define SMALLEST 1 | 422 | #define SMALLEST 1 |
@@ -948,7 +948,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) | |||
948 | 948 | ||
949 | Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", | 949 | Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", |
950 | opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, | 950 | opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, |
951 | s->last_lit)); | 951 | s->sym_next / 3)); |
952 | 952 | ||
953 | if (static_lenb <= opt_lenb) opt_lenb = static_lenb; | 953 | if (static_lenb <= opt_lenb) opt_lenb = static_lenb; |
954 | 954 | ||
@@ -1017,8 +1017,9 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc) | |||
1017 | unsigned dist; /* distance of matched string */ | 1017 | unsigned dist; /* distance of matched string */ |
1018 | unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ | 1018 | unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ |
1019 | { | 1019 | { |
1020 | s->d_buf[s->last_lit] = (ush)dist; | 1020 | s->sym_buf[s->sym_next++] = dist; |
1021 | s->l_buf[s->last_lit++] = (uch)lc; | 1021 | s->sym_buf[s->sym_next++] = dist >> 8; |
1022 | s->sym_buf[s->sym_next++] = lc; | ||
1022 | if (dist == 0) { | 1023 | if (dist == 0) { |
1023 | /* lc is the unmatched char */ | 1024 | /* lc is the unmatched char */ |
1024 | s->dyn_ltree[lc].Freq++; | 1025 | s->dyn_ltree[lc].Freq++; |
@@ -1033,30 +1034,7 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc) | |||
1033 | s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; | 1034 | s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; |
1034 | s->dyn_dtree[d_code(dist)].Freq++; | 1035 | s->dyn_dtree[d_code(dist)].Freq++; |
1035 | } | 1036 | } |
1036 | 1037 | return (s->sym_next == s->sym_end); | |
1037 | #ifdef TRUNCATE_BLOCK | ||
1038 | /* Try to guess if it is profitable to stop the current block here */ | ||
1039 | if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { | ||
1040 | /* Compute an upper bound for the compressed length */ | ||
1041 | ulg out_length = (ulg)s->last_lit*8L; | ||
1042 | ulg in_length = (ulg)((long)s->strstart - s->block_start); | ||
1043 | int dcode; | ||
1044 | for (dcode = 0; dcode < D_CODES; dcode++) { | ||
1045 | out_length += (ulg)s->dyn_dtree[dcode].Freq * | ||
1046 | (5L+extra_dbits[dcode]); | ||
1047 | } | ||
1048 | out_length >>= 3; | ||
1049 | Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", | ||
1050 | s->last_lit, in_length, out_length, | ||
1051 | 100L - out_length*100L/in_length)); | ||
1052 | if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; | ||
1053 | } | ||
1054 | #endif | ||
1055 | return (s->last_lit == s->lit_bufsize-1); | ||
1056 | /* We avoid equality with lit_bufsize because of wraparound at 64K | ||
1057 | * on 16 bit machines and because stored blocks are restricted to | ||
1058 | * 64K-1 bytes. | ||
1059 | */ | ||
1060 | } | 1038 | } |
1061 | 1039 | ||
1062 | /* =========================================================================== | 1040 | /* =========================================================================== |
@@ -1069,13 +1047,14 @@ local void compress_block(s, ltree, dtree) | |||
1069 | { | 1047 | { |
1070 | unsigned dist; /* distance of matched string */ | 1048 | unsigned dist; /* distance of matched string */ |
1071 | int lc; /* match length or unmatched char (if dist == 0) */ | 1049 | int lc; /* match length or unmatched char (if dist == 0) */ |
1072 | unsigned lx = 0; /* running index in l_buf */ | 1050 | unsigned sx = 0; /* running index in sym_buf */ |
1073 | unsigned code; /* the code to send */ | 1051 | unsigned code; /* the code to send */ |
1074 | int extra; /* number of extra bits to send */ | 1052 | int extra; /* number of extra bits to send */ |
1075 | 1053 | ||
1076 | if (s->last_lit != 0) do { | 1054 | if (s->sym_next != 0) do { |
1077 | dist = s->d_buf[lx]; | 1055 | dist = s->sym_buf[sx++] & 0xff; |
1078 | lc = s->l_buf[lx++]; | 1056 | dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; |
1057 | lc = s->sym_buf[sx++]; | ||
1079 | if (dist == 0) { | 1058 | if (dist == 0) { |
1080 | send_code(s, lc, ltree); /* send a literal byte */ | 1059 | send_code(s, lc, ltree); /* send a literal byte */ |
1081 | Tracecv(isgraph(lc), (stderr," '%c' ", lc)); | 1060 | Tracecv(isgraph(lc), (stderr," '%c' ", lc)); |
@@ -1100,11 +1079,10 @@ local void compress_block(s, ltree, dtree) | |||
1100 | } | 1079 | } |
1101 | } /* literal or match pair ? */ | 1080 | } /* literal or match pair ? */ |
1102 | 1081 | ||
1103 | /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ | 1082 | /* Check that the overlay between pending_buf and sym_buf is ok: */ |
1104 | Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, | 1083 | Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); |
1105 | "pendingBuf overflow"); | ||
1106 | 1084 | ||
1107 | } while (lx < s->last_lit); | 1085 | } while (sx < s->sym_next); |
1108 | 1086 | ||
1109 | send_code(s, END_BLOCK, ltree); | 1087 | send_code(s, END_BLOCK, ltree); |
1110 | } | 1088 | } |