diff options
author | Daniel Edgecumbe <git@esotericnonsense.com> | 2019-09-02 22:05:26 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2019-09-05 13:26:58 +0200 |
commit | ca5d86d52c979cef05a614fb725870c10be9b265 (patch) | |
tree | 0af03859c7ddd974d6b71834dd0fee10665a74cc | |
parent | de82f0b764de4720fed3378f2e5f938a3f4b9d18 (diff) | |
download | busybox-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.c | 26 |
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 | */ |
1922 | static void lm_init(unsigned *flags16p) | 1925 | static 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; |