aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Edgecumbe <git@esotericnonsense.com>2019-09-02 22:05:26 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2019-09-05 13:26:58 +0200
commitca5d86d52c979cef05a614fb725870c10be9b265 (patch)
tree0af03859c7ddd974d6b71834dd0fee10665a74cc
parentde82f0b764de4720fed3378f2e5f938a3f4b9d18 (diff)
downloadbusybox-w32-ca5d86d52c979cef05a614fb725870c10be9b265.tar.gz
busybox-w32-ca5d86d52c979cef05a614fb725870c10be9b265.tar.bz2
busybox-w32-ca5d86d52c979cef05a614fb725870c10be9b265.zip
gzip: set compression flags correctly as per standard
With this change and CONFIG_GZIP_FAST=2, CONFIG_FEATURE_GZIP_LEVELS=y, GNU gzip and BusyBox gzip now produce identical output at each compression level (excluding 1..3, as BusyBox does not implement these levels). Signed-off-by: Daniel Edgecumbe <git@esotericnonsense.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--archival/gzip.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/archival/gzip.c b/archival/gzip.c
index 37db347b8..a543d8c36 100644
--- a/archival/gzip.c
+++ b/archival/gzip.c
@@ -259,6 +259,7 @@ enum {
259 259
260#if !ENABLE_FEATURE_GZIP_LEVELS 260#if !ENABLE_FEATURE_GZIP_LEVELS
261 261
262 comp_level = 9,
262 max_chain_length = 4096, 263 max_chain_length = 4096,
263/* To speed up deflation, hash chains are never searched beyond this length. 264/* To speed up deflation, hash chains are never searched beyond this length.
264 * A higher limit improves compression ratio but degrades the speed. 265 * A higher limit improves compression ratio but degrades the speed.
@@ -334,14 +335,16 @@ struct globals {
334#define head (G1.prev + WSIZE) /* hash head (see deflate.c) */ 335#define head (G1.prev + WSIZE) /* hash head (see deflate.c) */
335 336
336#if ENABLE_FEATURE_GZIP_LEVELS 337#if ENABLE_FEATURE_GZIP_LEVELS
338 unsigned comp_level;
337 unsigned max_chain_length; 339 unsigned max_chain_length;
338 unsigned max_lazy_match; 340 unsigned max_lazy_match;
339 unsigned good_match; 341 unsigned good_match;
340 unsigned nice_match; 342 unsigned nice_match;
343#define comp_level (G1.comp_level)
341#define max_chain_length (G1.max_chain_length) 344#define max_chain_length (G1.max_chain_length)
342#define max_lazy_match (G1.max_lazy_match) 345#define max_lazy_match (G1.max_lazy_match)
343#define good_match (G1.good_match) 346#define good_match (G1.good_match)
344#define nice_match (G1.nice_match) 347#define nice_match (G1.nice_match)
345#endif 348#endif
346 349
347/* =========================================================================== */ 350/* =========================================================================== */
@@ -1919,7 +1922,7 @@ static void bi_init(void)
1919/* =========================================================================== 1922/* ===========================================================================
1920 * Initialize the "longest match" routines for a new file 1923 * Initialize the "longest match" routines for a new file
1921 */ 1924 */
1922static void lm_init(unsigned *flags16p) 1925static void lm_init(void)
1923{ 1926{
1924 unsigned j; 1927 unsigned j;
1925 1928
@@ -1927,8 +1930,6 @@ static void lm_init(unsigned *flags16p)
1927 memset(head, 0, HASH_SIZE * sizeof(*head)); 1930 memset(head, 0, HASH_SIZE * sizeof(*head));
1928 /* prev will be initialized on the fly */ 1931 /* prev will be initialized on the fly */
1929 1932
1930 /* speed options for the general purpose bit flag */
1931 *flags16p |= 2; /* FAST 4, SLOW 2 */
1932 /* ??? reduce max_chain_length for binary files */ 1933 /* ??? reduce max_chain_length for binary files */
1933 1934
1934 //G1.strstart = 0; // globals are zeroed in pack_gzip() 1935 //G1.strstart = 0; // globals are zeroed in pack_gzip()
@@ -2076,10 +2077,16 @@ static void zip(void)
2076 2077
2077 bi_init(); 2078 bi_init();
2078 ct_init(); 2079 ct_init();
2079 deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ 2080 lm_init();
2080 lm_init(&deflate_flags);
2081 2081
2082 put_16bit(deflate_flags | 0x300); /* extra flags. OS id = 3 (Unix) */ 2082 deflate_flags = 0x300; /* extra flags. OS id = 3 (Unix) */
2083#if ENABLE_FEATURE_GZIP_LEVELS
2084 /* Note that comp_level < 4 do not exist in this version of gzip */
2085 if (comp_level == 9) {
2086 deflate_flags |= 0x02; /* SLOW flag */
2087 }
2088#endif
2089 put_16bit(deflate_flags);
2083 2090
2084 /* The above 32-bit misaligns outbuf (10 bytes are stored), flush it */ 2091 /* The above 32-bit misaligns outbuf (10 bytes are stored), flush it */
2085 flush_outbuf_if_32bit_optimized(); 2092 flush_outbuf_if_32bit_optimized();
@@ -2224,6 +2231,9 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
2224 if (opt == 0) 2231 if (opt == 0)
2225 opt = 1 << 5; /* default: 6 */ 2232 opt = 1 << 5; /* default: 6 */
2226 opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */ 2233 opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */
2234
2235 comp_level = opt + 4;
2236
2227 max_chain_length = 1 << gzip_level_config[opt].chain_shift; 2237 max_chain_length = 1 << gzip_level_config[opt].chain_shift;
2228 good_match = gzip_level_config[opt].good; 2238 good_match = gzip_level_config[opt].good;
2229 max_lazy_match = gzip_level_config[opt].lazy2 * 2; 2239 max_lazy_match = gzip_level_config[opt].lazy2 * 2;