summaryrefslogtreecommitdiff
path: root/deflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'deflate.c')
-rw-r--r--deflate.c93
1 files changed, 85 insertions, 8 deletions
diff --git a/deflate.c b/deflate.c
index e9c14d7..dc60299 100644
--- a/deflate.c
+++ b/deflate.c
@@ -52,7 +52,7 @@
52#include "deflate.h" 52#include "deflate.h"
53 53
54const char deflate_copyright[] = 54const char deflate_copyright[] =
55 " deflate 1.0.9 Copyright 1995-1998 Jean-loup Gailly "; 55 " deflate 1.1.0 Copyright 1995-1998 Jean-loup Gailly ";
56/* 56/*
57 If you use the zlib library in a product, an acknowledgment is welcome 57 If you use the zlib library in a product, an acknowledgment is welcome
58 in the documentation of your product. If for some reason you cannot 58 in the documentation of your product. If for some reason you cannot
@@ -160,14 +160,23 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
160 * Insert string str in the dictionary and set match_head to the previous head 160 * Insert string str in the dictionary and set match_head to the previous head
161 * of the hash chain (the most recent string with same hash key). Return 161 * of the hash chain (the most recent string with same hash key). Return
162 * the previous length of the hash chain. 162 * the previous length of the hash chain.
163 * If this file is compiled with -DFASTEST, the compression level is forced
164 * to 1, and no hash chains are maintained.
163 * IN assertion: all calls to to INSERT_STRING are made with consecutive 165 * IN assertion: all calls to to INSERT_STRING are made with consecutive
164 * input characters and the first MIN_MATCH bytes of str are valid 166 * input characters and the first MIN_MATCH bytes of str are valid
165 * (except for the last MIN_MATCH-1 bytes of the input file). 167 * (except for the last MIN_MATCH-1 bytes of the input file).
166 */ 168 */
169#ifdef FASTEST
170#define INSERT_STRING(s, str, match_head) \
171 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
172 match_head = s->head[s->ins_h], \
173 s->head[s->ins_h] = (Pos)(str))
174#else
167#define INSERT_STRING(s, str, match_head) \ 175#define INSERT_STRING(s, str, match_head) \
168 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ 176 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
169 s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ 177 s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
170 s->head[s->ins_h] = (Pos)(str)) 178 s->head[s->ins_h] = (Pos)(str))
179#endif
171 180
172/* =========================================================================== 181/* ===========================================================================
173 * Initialize the hash table (avoiding 64K overflow for 16 bit systems). 182 * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
@@ -224,6 +233,9 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
224 if (strm->zfree == Z_NULL) strm->zfree = zcfree; 233 if (strm->zfree == Z_NULL) strm->zfree = zcfree;
225 234
226 if (level == Z_DEFAULT_COMPRESSION) level = 6; 235 if (level == Z_DEFAULT_COMPRESSION) level = 6;
236#ifdef FASTEST
237 level = 1;
238#endif
227 239
228 if (windowBits < 0) { /* undocumented feature: suppress zlib header */ 240 if (windowBits < 0) { /* undocumented feature: suppress zlib header */
229 noheader = 1; 241 noheader = 1;
@@ -708,6 +720,7 @@ local void lm_init (s)
708/* For 80x86 and 680x0, an optimized version will be provided in match.asm or 720/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
709 * match.S. The code will be functionally equivalent. 721 * match.S. The code will be functionally equivalent.
710 */ 722 */
723#ifndef FASTEST
711local uInt longest_match(s, cur_match) 724local uInt longest_match(s, cur_match)
712 deflate_state *s; 725 deflate_state *s;
713 IPos cur_match; /* current match */ 726 IPos cur_match; /* current match */
@@ -845,6 +858,64 @@ local uInt longest_match(s, cur_match)
845 if ((uInt)best_len <= s->lookahead) return (uInt)best_len; 858 if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
846 return s->lookahead; 859 return s->lookahead;
847} 860}
861
862#else /* FASTEST */
863/* ---------------------------------------------------------------------------
864 * Optimized version for level == 1 only
865 */
866local uInt longest_match(s, cur_match)
867 deflate_state *s;
868 IPos cur_match; /* current match */
869{
870 register Bytef *scan = s->window + s->strstart; /* current string */
871 register Bytef *match; /* matched string */
872 register int len; /* length of current match */
873 register Bytef *strend = s->window + s->strstart + MAX_MATCH;
874
875 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
876 * It is easy to get rid of this optimization if necessary.
877 */
878 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
879
880 Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
881
882 Assert(cur_match < s->strstart, "no future");
883
884 match = s->window + cur_match;
885
886 /* Return failure if the match length is less than 2:
887 */
888 if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
889
890 /* The check at best_len-1 can be removed because it will be made
891 * again later. (This heuristic is not always a win.)
892 * It is not necessary to compare scan[2] and match[2] since they
893 * are always equal when the other bytes match, given that
894 * the hash keys are equal and that HASH_BITS >= 8.
895 */
896 scan += 2, match += 2;
897 Assert(*scan == *match, "match[2]?");
898
899 /* We check for insufficient lookahead only every 8th comparison;
900 * the 256th check will be made at strstart+258.
901 */
902 do {
903 } while (*++scan == *++match && *++scan == *++match &&
904 *++scan == *++match && *++scan == *++match &&
905 *++scan == *++match && *++scan == *++match &&
906 *++scan == *++match && *++scan == *++match &&
907 scan < strend);
908
909 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
910
911 len = MAX_MATCH - (int)(strend - scan);
912
913 if (len < MIN_MATCH) return MIN_MATCH - 1;
914
915 s->match_start = cur_match;
916 return len <= s->lookahead ? len : s->lookahead;
917}
918#endif /* FASTEST */
848#endif /* ASMV */ 919#endif /* ASMV */
849 920
850#ifdef DEBUG 921#ifdef DEBUG
@@ -930,6 +1001,7 @@ local void fill_window(s)
930 } while (--n); 1001 } while (--n);
931 1002
932 n = wsize; 1003 n = wsize;
1004#ifndef FASTEST
933 p = &s->prev[n]; 1005 p = &s->prev[n];
934 do { 1006 do {
935 m = *--p; 1007 m = *--p;
@@ -938,6 +1010,7 @@ local void fill_window(s)
938 * its value will never be used. 1010 * its value will never be used.
939 */ 1011 */
940 } while (--n); 1012 } while (--n);
1013#endif
941 more += wsize; 1014 more += wsize;
942 } 1015 }
943 if (s->strm->avail_in == 0) return; 1016 if (s->strm->avail_in == 0) return;
@@ -1105,14 +1178,15 @@ local block_state deflate_fast(s, flush)
1105 if (s->match_length >= MIN_MATCH) { 1178 if (s->match_length >= MIN_MATCH) {
1106 check_match(s, s->strstart, s->match_start, s->match_length); 1179 check_match(s, s->strstart, s->match_start, s->match_length);
1107 1180
1108 bflush = _tr_tally(s, s->strstart - s->match_start, 1181 _tr_tally_dist(s, s->strstart - s->match_start,
1109 s->match_length - MIN_MATCH); 1182 s->match_length - MIN_MATCH, bflush);
1110 1183
1111 s->lookahead -= s->match_length; 1184 s->lookahead -= s->match_length;
1112 1185
1113 /* Insert new strings in the hash table only if the match length 1186 /* Insert new strings in the hash table only if the match length
1114 * is not too large. This saves time but degrades compression. 1187 * is not too large. This saves time but degrades compression.
1115 */ 1188 */
1189#ifndef FASTEST
1116 if (s->match_length <= s->max_insert_length && 1190 if (s->match_length <= s->max_insert_length &&
1117 s->lookahead >= MIN_MATCH) { 1191 s->lookahead >= MIN_MATCH) {
1118 s->match_length--; /* string at strstart already in hash table */ 1192 s->match_length--; /* string at strstart already in hash table */
@@ -1124,7 +1198,9 @@ local block_state deflate_fast(s, flush)
1124 */ 1198 */
1125 } while (--s->match_length != 0); 1199 } while (--s->match_length != 0);
1126 s->strstart++; 1200 s->strstart++;
1127 } else { 1201 } else
1202#endif
1203 {
1128 s->strstart += s->match_length; 1204 s->strstart += s->match_length;
1129 s->match_length = 0; 1205 s->match_length = 0;
1130 s->ins_h = s->window[s->strstart]; 1206 s->ins_h = s->window[s->strstart];
@@ -1139,7 +1215,7 @@ local block_state deflate_fast(s, flush)
1139 } else { 1215 } else {
1140 /* No match, output a literal byte */ 1216 /* No match, output a literal byte */
1141 Tracevv((stderr,"%c", s->window[s->strstart])); 1217 Tracevv((stderr,"%c", s->window[s->strstart]));
1142 bflush = _tr_tally (s, 0, s->window[s->strstart]); 1218 _tr_tally_lit (s, s->window[s->strstart], bflush);
1143 s->lookahead--; 1219 s->lookahead--;
1144 s->strstart++; 1220 s->strstart++;
1145 } 1221 }
@@ -1219,7 +1295,7 @@ local block_state deflate_slow(s, flush)
1219 check_match(s, s->strstart-1, s->prev_match, s->prev_length); 1295 check_match(s, s->strstart-1, s->prev_match, s->prev_length);
1220 1296
1221 bflush = _tr_tally(s, s->strstart -1 - s->prev_match, 1297 bflush = _tr_tally(s, s->strstart -1 - s->prev_match,
1222 s->prev_length - MIN_MATCH); 1298 s->prev_length - MIN_MATCH);
1223 1299
1224 /* Insert in hash table all strings up to the end of the match. 1300 /* Insert in hash table all strings up to the end of the match.
1225 * strstart-1 and strstart are already inserted. If there is not 1301 * strstart-1 and strstart are already inserted. If there is not
@@ -1245,7 +1321,8 @@ local block_state deflate_slow(s, flush)
1245 * is longer, truncate the previous match to a single literal. 1321 * is longer, truncate the previous match to a single literal.
1246 */ 1322 */
1247 Tracevv((stderr,"%c", s->window[s->strstart-1])); 1323 Tracevv((stderr,"%c", s->window[s->strstart-1]));
1248 if (_tr_tally (s, 0, s->window[s->strstart-1])) { 1324 _tr_tally_lit(s, s->window[s->strstart-1], bflush);
1325 if (bflush) {
1249 FLUSH_BLOCK_ONLY(s, 0); 1326 FLUSH_BLOCK_ONLY(s, 0);
1250 } 1327 }
1251 s->strstart++; 1328 s->strstart++;
@@ -1263,7 +1340,7 @@ local block_state deflate_slow(s, flush)
1263 Assert (flush != Z_NO_FLUSH, "no flush?"); 1340 Assert (flush != Z_NO_FLUSH, "no flush?");
1264 if (s->match_available) { 1341 if (s->match_available) {
1265 Tracevv((stderr,"%c", s->window[s->strstart-1])); 1342 Tracevv((stderr,"%c", s->window[s->strstart-1]));
1266 _tr_tally (s, 0, s->window[s->strstart-1]); 1343 _tr_tally_lit(s, s->window[s->strstart-1], bflush);
1267 s->match_available = 0; 1344 s->match_available = 0;
1268 } 1345 }
1269 FLUSH_BLOCK(s, flush == Z_FINISH); 1346 FLUSH_BLOCK(s, flush == Z_FINISH);