RFR: 8920687: Deflater.setLevel does not work as expected
Xueming Shen
xueming.shen at oracle.com
Fri Sep 13 19:44:18 UTC 2013
Hi,
This is change to clarify the java doc to match the existing behavior.
If there is a "pending" level/strategy change (via setLevel/Stragety()) when
deflate(...) is invoked, the implementation goes down to zlib's
deflateParams()
for deflating operation, which clearly specifies its behavior in zlib.h as
----------------------------------------------------------------
Dynamically update the compression level and compression strategy. The
interpretation of level and strategy is as in deflateInit2. This can be
used to switch between compression and straight copy of the input
data, or
to switch to a different kind of input data requiring a different
strategy.
If the compression level is changed, the input available so far is
compressed with the old level (and may be flushed); the new level
will take
effect only at the next call of deflate().
-----------------------------------------------------------------
and its corresponding implementation does exactly that.
Note, the zlib.h doc does not explicitly mention the "strategy", but
it's implementation
treat the strategy and level the same way. The code looks like
-----------------------------------------------------------------
int ZEXPORT deflateParams(strm, level, strategy)
z_streamp strm;
int level;
int strategy;
{
deflate_state *s;
compress_func func;
int err = Z_OK;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
s = strm->state;
#ifdef FASTEST
if (level != 0) level = 1;
#else
if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR;
}
func = configuration_table[s->level].func;
if ((strategy != s->strategy || func !=
configuration_table[level].func) &&
strm->total_in != 0) {
/* Flush the last buffer: */
err = deflate(strm, Z_BLOCK);
}
if (s->level != level) {
s->level = level;
s->max_lazy_match = configuration_table[level].max_lazy;
s->good_match = configuration_table[level].good_length;
s->nice_match = configuration_table[level].nice_length;
s->max_chain_length = configuration_table[level].max_chain;
}
s->strategy = strategy;
return err;
}
-------------------------------------------------------------------
The proposed change here is to add some words to clarify the expected
behavior,
in which the next deflate() invocation after the setLevel/Strategy()
will just finish
any left input (and may flush the buffer out). The new level/strategy
will take
effect after that.
http://cr.openjdk.java.net/~sherman/8020687/webrev/
Thanks,
-Sherman
More information about the core-libs-dev
mailing list