|
|
@ -52,7 +52,7 @@ |
|
|
|
#include "deflate.h" |
|
|
|
#include "deflate.h" |
|
|
|
|
|
|
|
|
|
|
|
const char deflate_copyright[] = |
|
|
|
const char deflate_copyright[] = |
|
|
|
" deflate 1.2.12 Copyright 1995-2022 Jean-loup Gailly and Mark Adler "; |
|
|
|
" deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler "; |
|
|
|
/*
|
|
|
|
/*
|
|
|
|
If you use the zlib library in a product, an acknowledgment is welcome |
|
|
|
If you use the zlib library in a product, an acknowledgment is welcome |
|
|
|
in the documentation of your product. If for some reason you cannot |
|
|
|
in the documentation of your product. If for some reason you cannot |
|
|
@ -87,13 +87,7 @@ local void lm_init OF((deflate_state *s)); |
|
|
|
local void putShortMSB OF((deflate_state *s, uInt b)); |
|
|
|
local void putShortMSB OF((deflate_state *s, uInt b)); |
|
|
|
local void flush_pending OF((z_streamp strm)); |
|
|
|
local void flush_pending OF((z_streamp strm)); |
|
|
|
local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); |
|
|
|
local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); |
|
|
|
#ifdef ASMV |
|
|
|
|
|
|
|
# pragma message("Assembler code may have bugs -- use at your own risk") |
|
|
|
|
|
|
|
void match_init OF((void)); /* asm code initialization */ |
|
|
|
|
|
|
|
uInt longest_match OF((deflate_state *s, IPos cur_match)); |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
local uInt longest_match OF((deflate_state *s, IPos cur_match)); |
|
|
|
local uInt longest_match OF((deflate_state *s, IPos cur_match)); |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef ZLIB_DEBUG |
|
|
|
#ifdef ZLIB_DEBUG |
|
|
|
local void check_match OF((deflate_state *s, IPos start, IPos match, |
|
|
|
local void check_match OF((deflate_state *s, IPos start, IPos match, |
|
|
@ -160,7 +154,7 @@ local const config configuration_table[10] = { |
|
|
|
* characters, so that a running hash key can be computed from the previous |
|
|
|
* characters, so that a running hash key can be computed from the previous |
|
|
|
* key instead of complete recalculation each time. |
|
|
|
* key instead of complete recalculation each time. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) |
|
|
|
#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ===========================================================================
|
|
|
|
/* ===========================================================================
|
|
|
@ -191,9 +185,9 @@ local const config configuration_table[10] = { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
#define CLEAR_HASH(s) \ |
|
|
|
#define CLEAR_HASH(s) \ |
|
|
|
do { \
|
|
|
|
do { \
|
|
|
|
s->head[s->hash_size-1] = NIL; \
|
|
|
|
s->head[s->hash_size - 1] = NIL; \
|
|
|
|
zmemzero((Bytef *)s->head, \
|
|
|
|
zmemzero((Bytef *)s->head, \
|
|
|
|
(unsigned)(s->hash_size-1)*sizeof(*s->head)); \
|
|
|
|
(unsigned)(s->hash_size - 1)*sizeof(*s->head)); \
|
|
|
|
} while (0) |
|
|
|
} while (0) |
|
|
|
|
|
|
|
|
|
|
|
/* ===========================================================================
|
|
|
|
/* ===========================================================================
|
|
|
@ -285,6 +279,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, |
|
|
|
|
|
|
|
|
|
|
|
if (windowBits < 0) { /* suppress zlib wrapper */ |
|
|
|
if (windowBits < 0) { /* suppress zlib wrapper */ |
|
|
|
wrap = 0; |
|
|
|
wrap = 0; |
|
|
|
|
|
|
|
if (windowBits < -15) |
|
|
|
|
|
|
|
return Z_STREAM_ERROR; |
|
|
|
windowBits = -windowBits; |
|
|
|
windowBits = -windowBits; |
|
|
|
} |
|
|
|
} |
|
|
|
#ifdef GZIP |
|
|
|
#ifdef GZIP |
|
|
@ -314,7 +310,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, |
|
|
|
s->hash_bits = (uInt)memLevel + 7; |
|
|
|
s->hash_bits = (uInt)memLevel + 7; |
|
|
|
s->hash_size = 1 << s->hash_bits; |
|
|
|
s->hash_size = 1 << s->hash_bits; |
|
|
|
s->hash_mask = s->hash_size - 1; |
|
|
|
s->hash_mask = s->hash_size - 1; |
|
|
|
s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); |
|
|
|
s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH); |
|
|
|
|
|
|
|
|
|
|
|
s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); |
|
|
|
s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); |
|
|
|
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); |
|
|
|
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); |
|
|
@ -340,11 +336,11 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, |
|
|
|
* sym_buf value to read moves forward three bytes. From that symbol, up to |
|
|
|
* sym_buf value to read moves forward three bytes. From that symbol, up to |
|
|
|
* 31 bits are written to pending_buf. The closest the written pending_buf |
|
|
|
* 31 bits are written to pending_buf. The closest the written pending_buf |
|
|
|
* bits gets to the next sym_buf symbol to read is just before the last |
|
|
|
* bits gets to the next sym_buf symbol to read is just before the last |
|
|
|
* code is written. At that time, 31*(n-2) bits have been written, just |
|
|
|
* code is written. At that time, 31*(n - 2) bits have been written, just |
|
|
|
* after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at |
|
|
|
* after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at |
|
|
|
* 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 |
|
|
|
* 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1 |
|
|
|
* symbols are written.) The closest the writing gets to what is unread is |
|
|
|
* symbols are written.) The closest the writing gets to what is unread is |
|
|
|
* then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and |
|
|
|
* then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and |
|
|
|
* can range from 128 to 32768. |
|
|
|
* can range from 128 to 32768. |
|
|
|
* |
|
|
|
* |
|
|
|
* Therefore, at a minimum, there are 142 bits of space between what is |
|
|
|
* Therefore, at a minimum, there are 142 bits of space between what is |
|
|
@ -390,7 +386,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, |
|
|
|
/* =========================================================================
|
|
|
|
/* =========================================================================
|
|
|
|
* Check for a valid deflate stream state. Return 0 if ok, 1 if not. |
|
|
|
* Check for a valid deflate stream state. Return 0 if ok, 1 if not. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
local int deflateStateCheck (strm) |
|
|
|
local int deflateStateCheck(strm) |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
|
{ |
|
|
|
{ |
|
|
|
deflate_state *s; |
|
|
|
deflate_state *s; |
|
|
@ -413,7 +409,7 @@ local int deflateStateCheck (strm) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
/* ========================================================================= */ |
|
|
|
int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) |
|
|
|
int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
|
const Bytef *dictionary; |
|
|
|
const Bytef *dictionary; |
|
|
|
uInt dictLength; |
|
|
|
uInt dictLength; |
|
|
@ -482,7 +478,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
/* ========================================================================= */ |
|
|
|
int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) |
|
|
|
int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
|
Bytef *dictionary; |
|
|
|
Bytef *dictionary; |
|
|
|
uInt *dictLength; |
|
|
|
uInt *dictLength; |
|
|
@ -504,7 +500,7 @@ int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
/* ========================================================================= */ |
|
|
|
int ZEXPORT deflateResetKeep (strm) |
|
|
|
int ZEXPORT deflateResetKeep(strm) |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
|
{ |
|
|
|
{ |
|
|
|
deflate_state *s; |
|
|
|
deflate_state *s; |
|
|
@ -542,7 +538,7 @@ int ZEXPORT deflateResetKeep (strm) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
/* ========================================================================= */ |
|
|
|
int ZEXPORT deflateReset (strm) |
|
|
|
int ZEXPORT deflateReset(strm) |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
|
{ |
|
|
|
{ |
|
|
|
int ret; |
|
|
|
int ret; |
|
|
@ -554,7 +550,7 @@ int ZEXPORT deflateReset (strm) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
/* ========================================================================= */ |
|
|
|
int ZEXPORT deflateSetHeader (strm, head) |
|
|
|
int ZEXPORT deflateSetHeader(strm, head) |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
|
gz_headerp head; |
|
|
|
gz_headerp head; |
|
|
|
{ |
|
|
|
{ |
|
|
@ -565,7 +561,7 @@ int ZEXPORT deflateSetHeader (strm, head) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
/* ========================================================================= */ |
|
|
|
int ZEXPORT deflatePending (strm, pending, bits) |
|
|
|
int ZEXPORT deflatePending(strm, pending, bits) |
|
|
|
unsigned *pending; |
|
|
|
unsigned *pending; |
|
|
|
int *bits; |
|
|
|
int *bits; |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
@ -579,7 +575,7 @@ int ZEXPORT deflatePending (strm, pending, bits) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
/* ========================================================================= */ |
|
|
|
int ZEXPORT deflatePrime (strm, bits, value) |
|
|
|
int ZEXPORT deflatePrime(strm, bits, value) |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
|
int bits; |
|
|
|
int bits; |
|
|
|
int value; |
|
|
|
int value; |
|
|
@ -674,36 +670,50 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* =========================================================================
|
|
|
|
/* =========================================================================
|
|
|
|
* For the default windowBits of 15 and memLevel of 8, this function returns |
|
|
|
* For the default windowBits of 15 and memLevel of 8, this function returns a |
|
|
|
* a close to exact, as well as small, upper bound on the compressed size. |
|
|
|
* close to exact, as well as small, upper bound on the compressed size. This |
|
|
|
* They are coded as constants here for a reason--if the #define's are |
|
|
|
* is an expansion of ~0.03%, plus a small constant. |
|
|
|
* changed, then this function needs to be changed as well. The return |
|
|
|
* |
|
|
|
* value for 15 and 8 only works for those exact settings. |
|
|
|
* For any setting other than those defaults for windowBits and memLevel, one |
|
|
|
|
|
|
|
* of two worst case bounds is returned. This is at most an expansion of ~4% or |
|
|
|
|
|
|
|
* ~13%, plus a small constant. |
|
|
|
* |
|
|
|
* |
|
|
|
* For any setting other than those defaults for windowBits and memLevel, |
|
|
|
* Both the 0.03% and 4% derive from the overhead of stored blocks. The first |
|
|
|
* the value returned is a conservative worst case for the maximum expansion |
|
|
|
* one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second |
|
|
|
* resulting from using fixed blocks instead of stored blocks, which deflate |
|
|
|
* is for stored blocks of 127 bytes (the worst case memLevel == 1). The |
|
|
|
* can emit on compressed data for some combinations of the parameters. |
|
|
|
* expansion results from five bytes of header for each stored block. |
|
|
|
* |
|
|
|
* |
|
|
|
* This function could be more sophisticated to provide closer upper bounds for |
|
|
|
* The larger expansion of 13% results from a window size less than or equal to |
|
|
|
* every combination of windowBits and memLevel. But even the conservative |
|
|
|
* the symbols buffer size (windowBits <= memLevel + 7). In that case some of |
|
|
|
* upper bound of about 14% expansion does not seem onerous for output buffer |
|
|
|
* the data being compressed may have slid out of the sliding window, impeding |
|
|
|
* allocation. |
|
|
|
* a stored block from being emitted. Then the only choice is a fixed or |
|
|
|
|
|
|
|
* dynamic block, where a fixed block limits the maximum expansion to 9 bits |
|
|
|
|
|
|
|
* per 8-bit byte, plus 10 bits for every block. The smallest block size for |
|
|
|
|
|
|
|
* which this can occur is 255 (memLevel == 2). |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* Shifts are used to approximate divisions, for speed. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
uLong ZEXPORT deflateBound(strm, sourceLen) |
|
|
|
uLong ZEXPORT deflateBound(strm, sourceLen) |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
|
uLong sourceLen; |
|
|
|
uLong sourceLen; |
|
|
|
{ |
|
|
|
{ |
|
|
|
deflate_state *s; |
|
|
|
deflate_state *s; |
|
|
|
uLong complen, wraplen; |
|
|
|
uLong fixedlen, storelen, wraplen; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* upper bound for fixed blocks with 9-bit literals and length 255
|
|
|
|
|
|
|
|
(memLevel == 2, which is the lowest that may not use stored blocks) -- |
|
|
|
|
|
|
|
~13% overhead plus a small constant */ |
|
|
|
|
|
|
|
fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + |
|
|
|
|
|
|
|
(sourceLen >> 9) + 4; |
|
|
|
|
|
|
|
|
|
|
|
/* conservative upper bound for compressed data */ |
|
|
|
/* upper bound for stored blocks with length 127 (memLevel == 1) --
|
|
|
|
complen = sourceLen + |
|
|
|
~4% overhead plus a small constant */ |
|
|
|
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; |
|
|
|
storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + |
|
|
|
|
|
|
|
(sourceLen >> 11) + 7; |
|
|
|
|
|
|
|
|
|
|
|
/* if can't get parameters, return conservative bound plus zlib wrapper */ |
|
|
|
/* if can't get parameters, return larger bound plus a zlib wrapper */ |
|
|
|
if (deflateStateCheck(strm)) |
|
|
|
if (deflateStateCheck(strm)) |
|
|
|
return complen + 6; |
|
|
|
return (fixedlen > storelen ? fixedlen : storelen) + 6; |
|
|
|
|
|
|
|
|
|
|
|
/* compute wrapper length */ |
|
|
|
/* compute wrapper length */ |
|
|
|
s = strm->state; |
|
|
|
s = strm->state; |
|
|
@ -740,11 +750,12 @@ uLong ZEXPORT deflateBound(strm, sourceLen) |
|
|
|
wraplen = 6; |
|
|
|
wraplen = 6; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* if not default parameters, return conservative bound */ |
|
|
|
/* if not default parameters, return one of the conservative bounds */ |
|
|
|
if (s->w_bits != 15 || s->hash_bits != 8 + 7) |
|
|
|
if (s->w_bits != 15 || s->hash_bits != 8 + 7) |
|
|
|
return complen + wraplen; |
|
|
|
return (s->w_bits <= s->hash_bits ? fixedlen : storelen) + wraplen; |
|
|
|
|
|
|
|
|
|
|
|
/* default settings: return tight bound for that case */ |
|
|
|
/* default settings: return tight bound for that case -- ~0.03% overhead
|
|
|
|
|
|
|
|
plus a small constant */ |
|
|
|
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + |
|
|
|
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + |
|
|
|
(sourceLen >> 25) + 13 - 6 + wraplen; |
|
|
|
(sourceLen >> 25) + 13 - 6 + wraplen; |
|
|
|
} |
|
|
|
} |
|
|
@ -754,7 +765,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) |
|
|
|
* IN assertion: the stream state is correct and there is enough room in |
|
|
|
* IN assertion: the stream state is correct and there is enough room in |
|
|
|
* pending_buf. |
|
|
|
* pending_buf. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
local void putShortMSB (s, b) |
|
|
|
local void putShortMSB(s, b) |
|
|
|
deflate_state *s; |
|
|
|
deflate_state *s; |
|
|
|
uInt b; |
|
|
|
uInt b; |
|
|
|
{ |
|
|
|
{ |
|
|
@ -801,7 +812,7 @@ local void flush_pending(strm) |
|
|
|
} while (0) |
|
|
|
} while (0) |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
/* ========================================================================= */ |
|
|
|
int ZEXPORT deflate (strm, flush) |
|
|
|
int ZEXPORT deflate(strm, flush) |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
|
int flush; |
|
|
|
int flush; |
|
|
|
{ |
|
|
|
{ |
|
|
@ -856,7 +867,7 @@ int ZEXPORT deflate (strm, flush) |
|
|
|
s->status = BUSY_STATE; |
|
|
|
s->status = BUSY_STATE; |
|
|
|
if (s->status == INIT_STATE) { |
|
|
|
if (s->status == INIT_STATE) { |
|
|
|
/* zlib header */ |
|
|
|
/* zlib header */ |
|
|
|
uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; |
|
|
|
uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; |
|
|
|
uInt level_flags; |
|
|
|
uInt level_flags; |
|
|
|
|
|
|
|
|
|
|
|
if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) |
|
|
|
if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) |
|
|
@ -1116,7 +1127,7 @@ int ZEXPORT deflate (strm, flush) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ========================================================================= */ |
|
|
|
/* ========================================================================= */ |
|
|
|
int ZEXPORT deflateEnd (strm) |
|
|
|
int ZEXPORT deflateEnd(strm) |
|
|
|
z_streamp strm; |
|
|
|
z_streamp strm; |
|
|
|
{ |
|
|
|
{ |
|
|
|
int status; |
|
|
|
int status; |
|
|
@ -1142,7 +1153,7 @@ int ZEXPORT deflateEnd (strm) |
|
|
|
* To simplify the source, this is not supported for 16-bit MSDOS (which |
|
|
|
* To simplify the source, this is not supported for 16-bit MSDOS (which |
|
|
|
* doesn't have enough memory anyway to duplicate compression states). |
|
|
|
* doesn't have enough memory anyway to duplicate compression states). |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
int ZEXPORT deflateCopy (dest, source) |
|
|
|
int ZEXPORT deflateCopy(dest, source) |
|
|
|
z_streamp dest; |
|
|
|
z_streamp dest; |
|
|
|
z_streamp source; |
|
|
|
z_streamp source; |
|
|
|
{ |
|
|
|
{ |
|
|
@ -1231,7 +1242,7 @@ local unsigned read_buf(strm, buf, size) |
|
|
|
/* ===========================================================================
|
|
|
|
/* ===========================================================================
|
|
|
|
* Initialize the "longest match" routines for a new zlib stream |
|
|
|
* Initialize the "longest match" routines for a new zlib stream |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
local void lm_init (s) |
|
|
|
local void lm_init(s) |
|
|
|
deflate_state *s; |
|
|
|
deflate_state *s; |
|
|
|
{ |
|
|
|
{ |
|
|
|
s->window_size = (ulg)2L*s->w_size; |
|
|
|
s->window_size = (ulg)2L*s->w_size; |
|
|
@ -1252,11 +1263,6 @@ local void lm_init (s) |
|
|
|
s->match_length = s->prev_length = MIN_MATCH-1; |
|
|
|
s->match_length = s->prev_length = MIN_MATCH-1; |
|
|
|
s->match_available = 0; |
|
|
|
s->match_available = 0; |
|
|
|
s->ins_h = 0; |
|
|
|
s->ins_h = 0; |
|
|
|
#ifndef FASTEST |
|
|
|
|
|
|
|
#ifdef ASMV |
|
|
|
|
|
|
|
match_init(); /* initialize the asm code */ |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifndef FASTEST |
|
|
|
#ifndef FASTEST |
|
|
@ -1269,10 +1275,6 @@ local void lm_init (s) |
|
|
|
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 |
|
|
|
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 |
|
|
|
* OUT assertion: the match length is not greater than s->lookahead. |
|
|
|
* OUT assertion: the match length is not greater than s->lookahead. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
#ifndef ASMV |
|
|
|
|
|
|
|
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
|
|
|
|
|
|
|
|
* match.S. The code will be functionally equivalent. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
local uInt longest_match(s, cur_match) |
|
|
|
local uInt longest_match(s, cur_match) |
|
|
|
deflate_state *s; |
|
|
|
deflate_state *s; |
|
|
|
IPos cur_match; /* current match */ |
|
|
|
IPos cur_match; /* current match */ |
|
|
@ -1297,10 +1299,10 @@ local uInt longest_match(s, cur_match) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; |
|
|
|
register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; |
|
|
|
register ush scan_start = *(ushf*)scan; |
|
|
|
register ush scan_start = *(ushf*)scan; |
|
|
|
register ush scan_end = *(ushf*)(scan+best_len-1); |
|
|
|
register ush scan_end = *(ushf*)(scan + best_len - 1); |
|
|
|
#else |
|
|
|
#else |
|
|
|
register Bytef *strend = s->window + s->strstart + MAX_MATCH; |
|
|
|
register Bytef *strend = s->window + s->strstart + MAX_MATCH; |
|
|
|
register Byte scan_end1 = scan[best_len-1]; |
|
|
|
register Byte scan_end1 = scan[best_len - 1]; |
|
|
|
register Byte scan_end = scan[best_len]; |
|
|
|
register Byte scan_end = scan[best_len]; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
@ -1318,7 +1320,8 @@ local uInt longest_match(s, cur_match) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; |
|
|
|
if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; |
|
|
|
|
|
|
|
|
|
|
|
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); |
|
|
|
Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, |
|
|
|
|
|
|
|
"need lookahead"); |
|
|
|
|
|
|
|
|
|
|
|
do { |
|
|
|
do { |
|
|
|
Assert(cur_match < s->strstart, "no future"); |
|
|
|
Assert(cur_match < s->strstart, "no future"); |
|
|
@ -1336,43 +1339,44 @@ local uInt longest_match(s, cur_match) |
|
|
|
/* This code assumes sizeof(unsigned short) == 2. Do not use
|
|
|
|
/* This code assumes sizeof(unsigned short) == 2. Do not use
|
|
|
|
* UNALIGNED_OK if your compiler uses a different size. |
|
|
|
* UNALIGNED_OK if your compiler uses a different size. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
if (*(ushf*)(match+best_len-1) != scan_end || |
|
|
|
if (*(ushf*)(match + best_len - 1) != scan_end || |
|
|
|
*(ushf*)match != scan_start) continue; |
|
|
|
*(ushf*)match != scan_start) continue; |
|
|
|
|
|
|
|
|
|
|
|
/* It is not necessary to compare scan[2] and match[2] since they are
|
|
|
|
/* It is not necessary to compare scan[2] and match[2] since they are
|
|
|
|
* always equal when the other bytes match, given that the hash keys |
|
|
|
* always equal when the other bytes match, given that the hash keys |
|
|
|
* are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at |
|
|
|
* are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at |
|
|
|
* strstart+3, +5, ... up to strstart+257. We check for insufficient |
|
|
|
* strstart + 3, + 5, up to strstart + 257. We check for insufficient |
|
|
|
* lookahead only every 4th comparison; the 128th check will be made |
|
|
|
* lookahead only every 4th comparison; the 128th check will be made |
|
|
|
* at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is |
|
|
|
* at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is |
|
|
|
* necessary to put more guard bytes at the end of the window, or |
|
|
|
* necessary to put more guard bytes at the end of the window, or |
|
|
|
* to check more often for insufficient lookahead. |
|
|
|
* to check more often for insufficient lookahead. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Assert(scan[2] == match[2], "scan[2]?"); |
|
|
|
Assert(scan[2] == match[2], "scan[2]?"); |
|
|
|
scan++, match++; |
|
|
|
scan++, match++; |
|
|
|
do { |
|
|
|
do { |
|
|
|
} while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && |
|
|
|
} while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) && |
|
|
|
*(ushf*)(scan+=2) == *(ushf*)(match+=2) && |
|
|
|
*(ushf*)(scan += 2) == *(ushf*)(match += 2) && |
|
|
|
*(ushf*)(scan+=2) == *(ushf*)(match+=2) && |
|
|
|
*(ushf*)(scan += 2) == *(ushf*)(match += 2) && |
|
|
|
*(ushf*)(scan+=2) == *(ushf*)(match+=2) && |
|
|
|
*(ushf*)(scan += 2) == *(ushf*)(match += 2) && |
|
|
|
scan < strend); |
|
|
|
scan < strend); |
|
|
|
/* The funny "do {}" generates better code on most compilers */ |
|
|
|
/* The funny "do {}" generates better code on most compilers */ |
|
|
|
|
|
|
|
|
|
|
|
/* Here, scan <= window+strstart+257 */ |
|
|
|
/* Here, scan <= window + strstart + 257 */ |
|
|
|
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); |
|
|
|
Assert(scan <= s->window + (unsigned)(s->window_size - 1), |
|
|
|
|
|
|
|
"wild scan"); |
|
|
|
if (*scan == *match) scan++; |
|
|
|
if (*scan == *match) scan++; |
|
|
|
|
|
|
|
|
|
|
|
len = (MAX_MATCH - 1) - (int)(strend-scan); |
|
|
|
len = (MAX_MATCH - 1) - (int)(strend - scan); |
|
|
|
scan = strend - (MAX_MATCH-1); |
|
|
|
scan = strend - (MAX_MATCH-1); |
|
|
|
|
|
|
|
|
|
|
|
#else /* UNALIGNED_OK */ |
|
|
|
#else /* UNALIGNED_OK */ |
|
|
|
|
|
|
|
|
|
|
|
if (match[best_len] != scan_end || |
|
|
|
if (match[best_len] != scan_end || |
|
|
|
match[best_len-1] != scan_end1 || |
|
|
|
match[best_len - 1] != scan_end1 || |
|
|
|
*match != *scan || |
|
|
|
*match != *scan || |
|
|
|
*++match != scan[1]) continue; |
|
|
|
*++match != scan[1]) continue; |
|
|
|
|
|
|
|
|
|
|
|
/* The check at best_len-1 can be removed because it will be made
|
|
|
|
/* The check at best_len - 1 can be removed because it will be made
|
|
|
|
* again later. (This heuristic is not always a win.) |
|
|
|
* again later. (This heuristic is not always a win.) |
|
|
|
* It is not necessary to compare scan[2] and match[2] since they |
|
|
|
* It is not necessary to compare scan[2] and match[2] since they |
|
|
|
* are always equal when the other bytes match, given that |
|
|
|
* are always equal when the other bytes match, given that |
|
|
@ -1382,7 +1386,7 @@ local uInt longest_match(s, cur_match) |
|
|
|
Assert(*scan == *match, "match[2]?"); |
|
|
|
Assert(*scan == *match, "match[2]?"); |
|
|
|
|
|
|
|
|
|
|
|
/* We check for insufficient lookahead only every 8th comparison;
|
|
|
|
/* We check for insufficient lookahead only every 8th comparison;
|
|
|
|
* the 256th check will be made at strstart+258. |
|
|
|
* the 256th check will be made at strstart + 258. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
do { |
|
|
|
do { |
|
|
|
} while (*++scan == *++match && *++scan == *++match && |
|
|
|
} while (*++scan == *++match && *++scan == *++match && |
|
|
@ -1391,7 +1395,8 @@ local uInt longest_match(s, cur_match) |
|
|
|
*++scan == *++match && *++scan == *++match && |
|
|
|
*++scan == *++match && *++scan == *++match && |
|
|
|
scan < strend); |
|
|
|
scan < strend); |
|
|
|
|
|
|
|
|
|
|
|
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); |
|
|
|
Assert(scan <= s->window + (unsigned)(s->window_size - 1), |
|
|
|
|
|
|
|
"wild scan"); |
|
|
|
|
|
|
|
|
|
|
|
len = MAX_MATCH - (int)(strend - scan); |
|
|
|
len = MAX_MATCH - (int)(strend - scan); |
|
|
|
scan = strend - MAX_MATCH; |
|
|
|
scan = strend - MAX_MATCH; |
|
|
@ -1403,9 +1408,9 @@ local uInt longest_match(s, cur_match) |
|
|
|
best_len = len; |
|
|
|
best_len = len; |
|
|
|
if (len >= nice_match) break; |
|
|
|
if (len >= nice_match) break; |
|
|
|
#ifdef UNALIGNED_OK |
|
|
|
#ifdef UNALIGNED_OK |
|
|
|
scan_end = *(ushf*)(scan+best_len-1); |
|
|
|
scan_end = *(ushf*)(scan + best_len - 1); |
|
|
|
#else |
|
|
|
#else |
|
|
|
scan_end1 = scan[best_len-1]; |
|
|
|
scan_end1 = scan[best_len - 1]; |
|
|
|
scan_end = scan[best_len]; |
|
|
|
scan_end = scan[best_len]; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
@ -1415,7 +1420,6 @@ local uInt longest_match(s, cur_match) |
|
|
|
if ((uInt)best_len <= s->lookahead) return (uInt)best_len; |
|
|
|
if ((uInt)best_len <= s->lookahead) return (uInt)best_len; |
|
|
|
return s->lookahead; |
|
|
|
return s->lookahead; |
|
|
|
} |
|
|
|
} |
|
|
|
#endif /* ASMV */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#else /* FASTEST */ |
|
|
|
#else /* FASTEST */ |
|
|
|
|
|
|
|
|
|
|
@ -1436,7 +1440,8 @@ local uInt longest_match(s, cur_match) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); |
|
|
|
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); |
|
|
|
|
|
|
|
|
|
|
|
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); |
|
|
|
Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, |
|
|
|
|
|
|
|
"need lookahead"); |
|
|
|
|
|
|
|
|
|
|
|
Assert(cur_match < s->strstart, "no future"); |
|
|
|
Assert(cur_match < s->strstart, "no future"); |
|
|
|
|
|
|
|
|
|
|
@ -1446,7 +1451,7 @@ local uInt longest_match(s, cur_match) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; |
|
|
|
if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; |
|
|
|
|
|
|
|
|
|
|
|
/* The check at best_len-1 can be removed because it will be made
|
|
|
|
/* The check at best_len - 1 can be removed because it will be made
|
|
|
|
* again later. (This heuristic is not always a win.) |
|
|
|
* again later. (This heuristic is not always a win.) |
|
|
|
* It is not necessary to compare scan[2] and match[2] since they |
|
|
|
* It is not necessary to compare scan[2] and match[2] since they |
|
|
|
* are always equal when the other bytes match, given that |
|
|
|
* are always equal when the other bytes match, given that |
|
|
@ -1456,7 +1461,7 @@ local uInt longest_match(s, cur_match) |
|
|
|
Assert(*scan == *match, "match[2]?"); |
|
|
|
Assert(*scan == *match, "match[2]?"); |
|
|
|
|
|
|
|
|
|
|
|
/* We check for insufficient lookahead only every 8th comparison;
|
|
|
|
/* We check for insufficient lookahead only every 8th comparison;
|
|
|
|
* the 256th check will be made at strstart+258. |
|
|
|
* the 256th check will be made at strstart + 258. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
do { |
|
|
|
do { |
|
|
|
} while (*++scan == *++match && *++scan == *++match && |
|
|
|
} while (*++scan == *++match && *++scan == *++match && |
|
|
@ -1465,7 +1470,7 @@ local uInt longest_match(s, cur_match) |
|
|
|
*++scan == *++match && *++scan == *++match && |
|
|
|
*++scan == *++match && *++scan == *++match && |
|
|
|
scan < strend); |
|
|
|
scan < strend); |
|
|
|
|
|
|
|
|
|
|
|
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); |
|
|
|
Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); |
|
|
|
|
|
|
|
|
|
|
|
len = MAX_MATCH - (int)(strend - scan); |
|
|
|
len = MAX_MATCH - (int)(strend - scan); |
|
|
|
|
|
|
|
|
|
|
@ -1501,7 +1506,7 @@ local void check_match(s, start, match, length) |
|
|
|
z_error("invalid match"); |
|
|
|
z_error("invalid match"); |
|
|
|
} |
|
|
|
} |
|
|
|
if (z_verbose > 1) { |
|
|
|
if (z_verbose > 1) { |
|
|
|
fprintf(stderr,"\\[%d,%d]", start-match, length); |
|
|
|
fprintf(stderr,"\\[%d,%d]", start - match, length); |
|
|
|
do { putc(s->window[start++], stderr); } while (--length != 0); |
|
|
|
do { putc(s->window[start++], stderr); } while (--length != 0); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1547,9 +1552,9 @@ local void fill_window(s) |
|
|
|
/* If the window is almost full and there is insufficient lookahead,
|
|
|
|
/* If the window is almost full and there is insufficient lookahead,
|
|
|
|
* move the upper half to the lower one to make room in the upper half. |
|
|
|
* move the upper half to the lower one to make room in the upper half. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
if (s->strstart >= wsize+MAX_DIST(s)) { |
|
|
|
if (s->strstart >= wsize + MAX_DIST(s)) { |
|
|
|
|
|
|
|
|
|
|
|
zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more); |
|
|
|
zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); |
|
|
|
s->match_start -= wsize; |
|
|
|
s->match_start -= wsize; |
|
|
|
s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ |
|
|
|
s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ |
|
|
|
s->block_start -= (long) wsize; |
|
|
|
s->block_start -= (long) wsize; |
|
|
@ -1680,7 +1685,7 @@ local void fill_window(s) |
|
|
|
* |
|
|
|
* |
|
|
|
* deflate_stored() is written to minimize the number of times an input byte is |
|
|
|
* deflate_stored() is written to minimize the number of times an input byte is |
|
|
|
* copied. It is most efficient with large input and output buffers, which |
|
|
|
* copied. It is most efficient with large input and output buffers, which |
|
|
|
* maximizes the opportunites to have a single copy from next_in to next_out. |
|
|
|
* maximizes the opportunities to have a single copy from next_in to next_out. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
local block_state deflate_stored(s, flush) |
|
|
|
local block_state deflate_stored(s, flush) |
|
|
|
deflate_state *s; |
|
|
|
deflate_state *s; |
|
|
@ -1890,7 +1895,7 @@ local block_state deflate_fast(s, flush) |
|
|
|
if (s->lookahead == 0) break; /* flush the current block */ |
|
|
|
if (s->lookahead == 0) break; /* flush the current block */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Insert the string window[strstart .. strstart+2] in the
|
|
|
|
/* Insert the string window[strstart .. strstart + 2] in the
|
|
|
|
* dictionary, and set hash_head to the head of the hash chain: |
|
|
|
* dictionary, and set hash_head to the head of the hash chain: |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
hash_head = NIL; |
|
|
|
hash_head = NIL; |
|
|
@ -1938,7 +1943,7 @@ local block_state deflate_fast(s, flush) |
|
|
|
s->strstart += s->match_length; |
|
|
|
s->strstart += s->match_length; |
|
|
|
s->match_length = 0; |
|
|
|
s->match_length = 0; |
|
|
|
s->ins_h = s->window[s->strstart]; |
|
|
|
s->ins_h = s->window[s->strstart]; |
|
|
|
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); |
|
|
|
UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); |
|
|
|
#if MIN_MATCH != 3 |
|
|
|
#if MIN_MATCH != 3 |
|
|
|
Call UPDATE_HASH() MIN_MATCH-3 more times |
|
|
|
Call UPDATE_HASH() MIN_MATCH-3 more times |
|
|
|
#endif |
|
|
|
#endif |
|
|
@ -1949,7 +1954,7 @@ local block_state deflate_fast(s, flush) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
/* No match, output a literal byte */ |
|
|
|
/* No match, output a literal byte */ |
|
|
|
Tracevv((stderr,"%c", s->window[s->strstart])); |
|
|
|
Tracevv((stderr,"%c", s->window[s->strstart])); |
|
|
|
_tr_tally_lit (s, s->window[s->strstart], bflush); |
|
|
|
_tr_tally_lit(s, s->window[s->strstart], bflush); |
|
|
|
s->lookahead--; |
|
|
|
s->lookahead--; |
|
|
|
s->strstart++; |
|
|
|
s->strstart++; |
|
|
|
} |
|
|
|
} |
|
|
@ -1993,7 +1998,7 @@ local block_state deflate_slow(s, flush) |
|
|
|
if (s->lookahead == 0) break; /* flush the current block */ |
|
|
|
if (s->lookahead == 0) break; /* flush the current block */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Insert the string window[strstart .. strstart+2] in the
|
|
|
|
/* Insert the string window[strstart .. strstart + 2] in the
|
|
|
|
* dictionary, and set hash_head to the head of the hash chain: |
|
|
|
* dictionary, and set hash_head to the head of the hash chain: |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
hash_head = NIL; |
|
|
|
hash_head = NIL; |
|
|
@ -2035,17 +2040,17 @@ local block_state deflate_slow(s, flush) |
|
|
|
uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; |
|
|
|
uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; |
|
|
|
/* Do not insert strings in hash table beyond this. */ |
|
|
|
/* Do not insert strings in hash table beyond this. */ |
|
|
|
|
|
|
|
|
|
|
|
check_match(s, s->strstart-1, s->prev_match, s->prev_length); |
|
|
|
check_match(s, s->strstart - 1, s->prev_match, s->prev_length); |
|
|
|
|
|
|
|
|
|
|
|
_tr_tally_dist(s, s->strstart -1 - s->prev_match, |
|
|
|
_tr_tally_dist(s, s->strstart - 1 - s->prev_match, |
|
|
|
s->prev_length - MIN_MATCH, bflush); |
|
|
|
s->prev_length - MIN_MATCH, bflush); |
|
|
|
|
|
|
|
|
|
|
|
/* Insert in hash table all strings up to the end of the match.
|
|
|
|
/* Insert in hash table all strings up to the end of the match.
|
|
|
|
* strstart-1 and strstart are already inserted. If there is not |
|
|
|
* strstart - 1 and strstart are already inserted. If there is not |
|
|
|
* enough lookahead, the last two strings are not inserted in |
|
|
|
* enough lookahead, the last two strings are not inserted in |
|
|
|
* the hash table. |
|
|
|
* the hash table. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
s->lookahead -= s->prev_length-1; |
|
|
|
s->lookahead -= s->prev_length - 1; |
|
|
|
s->prev_length -= 2; |
|
|
|
s->prev_length -= 2; |
|
|
|
do { |
|
|
|
do { |
|
|
|
if (++s->strstart <= max_insert) { |
|
|
|
if (++s->strstart <= max_insert) { |
|
|
@ -2063,8 +2068,8 @@ local block_state deflate_slow(s, flush) |
|
|
|
* single literal. If there was a match but the current match |
|
|
|
* single literal. If there was a match but the current match |
|
|
|
* is longer, truncate the previous match to a single literal. |
|
|
|
* is longer, truncate the previous match to a single literal. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Tracevv((stderr,"%c", s->window[s->strstart-1])); |
|
|
|
Tracevv((stderr,"%c", s->window[s->strstart - 1])); |
|
|
|
_tr_tally_lit(s, s->window[s->strstart-1], bflush); |
|
|
|
_tr_tally_lit(s, s->window[s->strstart - 1], bflush); |
|
|
|
if (bflush) { |
|
|
|
if (bflush) { |
|
|
|
FLUSH_BLOCK_ONLY(s, 0); |
|
|
|
FLUSH_BLOCK_ONLY(s, 0); |
|
|
|
} |
|
|
|
} |
|
|
@ -2082,8 +2087,8 @@ local block_state deflate_slow(s, flush) |
|
|
|
} |
|
|
|
} |
|
|
|
Assert (flush != Z_NO_FLUSH, "no flush?"); |
|
|
|
Assert (flush != Z_NO_FLUSH, "no flush?"); |
|
|
|
if (s->match_available) { |
|
|
|
if (s->match_available) { |
|
|
|
Tracevv((stderr,"%c", s->window[s->strstart-1])); |
|
|
|
Tracevv((stderr,"%c", s->window[s->strstart - 1])); |
|
|
|
_tr_tally_lit(s, s->window[s->strstart-1], bflush); |
|
|
|
_tr_tally_lit(s, s->window[s->strstart - 1], bflush); |
|
|
|
s->match_available = 0; |
|
|
|
s->match_available = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; |
|
|
|
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; |
|
|
@ -2140,7 +2145,8 @@ local block_state deflate_rle(s, flush) |
|
|
|
if (s->match_length > s->lookahead) |
|
|
|
if (s->match_length > s->lookahead) |
|
|
|
s->match_length = s->lookahead; |
|
|
|
s->match_length = s->lookahead; |
|
|
|
} |
|
|
|
} |
|
|
|
Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); |
|
|
|
Assert(scan <= s->window + (uInt)(s->window_size - 1), |
|
|
|
|
|
|
|
"wild scan"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Emit match if have run of MIN_MATCH or longer, else emit literal */ |
|
|
|
/* Emit match if have run of MIN_MATCH or longer, else emit literal */ |
|
|
@ -2155,7 +2161,7 @@ local block_state deflate_rle(s, flush) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
/* No match, output a literal byte */ |
|
|
|
/* No match, output a literal byte */ |
|
|
|
Tracevv((stderr,"%c", s->window[s->strstart])); |
|
|
|
Tracevv((stderr,"%c", s->window[s->strstart])); |
|
|
|
_tr_tally_lit (s, s->window[s->strstart], bflush); |
|
|
|
_tr_tally_lit(s, s->window[s->strstart], bflush); |
|
|
|
s->lookahead--; |
|
|
|
s->lookahead--; |
|
|
|
s->strstart++; |
|
|
|
s->strstart++; |
|
|
|
} |
|
|
|
} |
|
|
@ -2195,7 +2201,7 @@ local block_state deflate_huff(s, flush) |
|
|
|
/* Output a literal byte */ |
|
|
|
/* Output a literal byte */ |
|
|
|
s->match_length = 0; |
|
|
|
s->match_length = 0; |
|
|
|
Tracevv((stderr,"%c", s->window[s->strstart])); |
|
|
|
Tracevv((stderr,"%c", s->window[s->strstart])); |
|
|
|
_tr_tally_lit (s, s->window[s->strstart], bflush); |
|
|
|
_tr_tally_lit(s, s->window[s->strstart], bflush); |
|
|
|
s->lookahead--; |
|
|
|
s->lookahead--; |
|
|
|
s->strstart++; |
|
|
|
s->strstart++; |
|
|
|
if (bflush) FLUSH_BLOCK(s, 0); |
|
|
|
if (bflush) FLUSH_BLOCK(s, 0); |
|
|
|