summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/gzip/deflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/gzip/deflate.c')
-rw-r--r--gnu/usr.bin/gzip/deflate.c87
1 files changed, 60 insertions, 27 deletions
diff --git a/gnu/usr.bin/gzip/deflate.c b/gnu/usr.bin/gzip/deflate.c
index 0b3af93..eaad69a 100644
--- a/gnu/usr.bin/gzip/deflate.c
+++ b/gnu/usr.bin/gzip/deflate.c
@@ -68,7 +68,7 @@
#include "lzw.h" /* just for consistency checking */
#ifndef lint
-static char rcsid[] = "$Id: deflate.c,v 0.13 1993/05/25 16:25:40 jloup Exp $";
+static char rcsid[] = "$Id: deflate.c,v 0.14 1993/06/12 20:11:10 jloup Exp $";
#endif
/* ===========================================================================
@@ -187,8 +187,17 @@ unsigned near max_chain_length;
local unsigned int max_lazy_match;
/* Attempt to find a better match only when the current match is strictly
- * smaller than this value.
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
*/
+#define max_insert_length max_lazy_match
+/* Insert new strings in the hash table only if the match length
+ * is not greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+local int compr_level;
+/* compression level (1..9) */
int near good_match;
/* Use a faster search when the previous match is longer than this */
@@ -216,18 +225,20 @@ typedef struct config {
local config configuration_table[10] = {
/* good lazy nice chain */
/* 0 */ {0, 0, 0, 0}, /* store only */
-/* 1 */ {4, 4, 16, 16}, /* maximum speed */
-/* 2 */ {6, 8, 16, 16},
-/* 3 */ {8, 16, 32, 32},
-/* 4 */ {8, 16, 64, 64},
-/* 5 */ {8, 16, 128, 128},
-/* 6 */ {8, 32, 128, 256},
-/* 7 */ {8, 64, 128, 512},
+/* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8},
+/* 3 */ {4, 6, 32, 32},
+
+/* 4 */ {4, 4, 16, 16}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32},
+/* 6 */ {8, 16, 128, 128},
+/* 7 */ {8, 32, 128, 256},
/* 8 */ {32, 128, 258, 1024},
/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */
-/* Note: the current code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * but these restrictions can easily be removed at a small cost.
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
*/
#define EQUAL 0
@@ -237,6 +248,8 @@ local config configuration_table[10] = {
* Prototypes for local functions.
*/
local void fill_window OF((void));
+local ulg deflate_fast OF((void));
+
int longest_match OF((IPos cur_match));
#ifdef ASMV
void match_init OF((void)); /* asm code initialization */
@@ -277,6 +290,7 @@ void lm_init (pack_level, flags)
register unsigned j;
if (pack_level < 1 || pack_level > 9) error("bad pack level");
+ compr_level = pack_level;
/* Initialize the hash table. */
#if defined(MAXSEG_64K) && HASH_BITS == 15
@@ -558,10 +572,12 @@ local void fill_window()
(char*)NULL, (long)strstart - block_start, (eof))
/* ===========================================================================
- * Processes a new input file and return its compressed length.
+ * Processes a new input file and return its compressed length. This
+ * function does not perform lazy evaluationof matches and inserts
+ * new strings in the dictionary only for unmatched strings. It is used
+ * only for the fast compression options.
*/
-#ifdef NO_LAZY
-ulg deflate()
+local ulg deflate_fast()
{
IPos hash_head; /* head of the hash chain */
int flush; /* set if current block must be flushed */
@@ -592,22 +608,38 @@ ulg deflate()
flush = ct_tally(strstart-match_start, match_length - MIN_MATCH);
lookahead -= match_length;
- match_length--; /* string at strstart already in hash table */
- do {
- strstart++;
- INSERT_STRING(strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
- * these bytes are garbage, but it does not matter since the
- * next lookahead bytes will always be emitted as literals.
- */
- } while (--match_length != 0);
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+ if (match_length <= max_insert_length) {
+ match_length--; /* string at strstart already in hash table */
+ do {
+ strstart++;
+ INSERT_STRING(strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
+ * these bytes are garbage, but it does not matter since
+ * the next lookahead bytes will be emitted as literals.
+ */
+ } while (--match_length != 0);
+ strstart++;
+ } else {
+ strstart += match_length;
+ match_length = 0;
+ ins_h = window[strstart];
+ UPDATE_HASH(ins_h, window[strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ }
} else {
/* No match, output a literal byte */
+ Tracevv((stderr,"%c",window[strstart]));
flush = ct_tally (0, window[strstart]);
lookahead--;
+ strstart++;
}
- strstart++;
if (flush) FLUSH_BLOCK(0), block_start = strstart;
/* Make sure that we always have enough lookahead, except
@@ -620,7 +652,7 @@ ulg deflate()
}
return FLUSH_BLOCK(1); /* eof */
}
-#else /* LAZY */
+
/* ===========================================================================
* Same as above, but achieves better compression. We use a lazy
* evaluation for matches: a match is finally adopted only if there is
@@ -637,6 +669,8 @@ ulg deflate()
extern long isize; /* byte length of input file, for debug only */
#endif
+ if (compr_level <= 3) return deflate_fast(); /* optimized for speed */
+
/* Process the input block. */
while (lookahead != 0) {
/* Insert the string window[strstart .. strstart+2] in the
@@ -727,4 +761,3 @@ ulg deflate()
return FLUSH_BLOCK(1); /* eof */
}
-#endif /* LAZY */
OpenPOWER on IntegriCloud