This introduces GZIP_DEFAULT_LEVEL macro so that builders can easily
change it by overriding (e.g. "-DGZIP_DEFAULT_LEVEL=8").

Currently, this patch is ugly. I apologize. (Because I utilize a lot
of preprocessor tricks in order to implement a build-time constant
table lookup.)

This is how I proposed letting the user change the compression level
when GZIP_LEVELS is turned off, when discussing about gzip default
compression level. This patch is a proof of concept of that.
<http://lists.busybox.net/pipermail/busybox/2019-September/087442.html>

Signed-off-by: Kang-Che Sung <explore...@gmail.com>
---
 archival/gzip.c | 50 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/archival/gzip.c b/archival/gzip.c
index 3966a06b4..10cf2f884 100644
--- a/archival/gzip.c
+++ b/archival/gzip.c
@@ -251,6 +251,17 @@ typedef unsigned IPos;
  * save space in the various tables. IPos is used only for parameter passing.
  */
 
+#define LEVEL_CONFIG_LIST \
+       /*             (level, good, chain_shift, lazy, nice) */ \
+       LEVEL_CONFIG_DEFINE(4,    4,           4,    4,   16) \
+       LEVEL_CONFIG_DEFINE(5,    8,           5,   16,   32) \
+       LEVEL_CONFIG_DEFINE(6,    8,           7,   16,  128) \
+       LEVEL_CONFIG_DEFINE(7,    8,           8,   32,  128) \
+       LEVEL_CONFIG_DEFINE(8,   32,          10,  128,  258) \
+       LEVEL_CONFIG_DEFINE(9,   32,          12,  258,  258)
+
+#define GZIP_DEFAULT_LEVEL 6
+
 enum {
        WINDOW_SIZE = 2 * WSIZE,
 /* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
@@ -258,14 +269,25 @@ enum {
  */
 
 #if !ENABLE_FEATURE_GZIP_LEVELS
+# define LEVEL_CONFIG_DEFINE(level, good, chain_shift, lazy, nice) \
+       l##level##_chain = (1 << (chain_shift)), \
+       l##level##_lazy = (lazy), \
+       l##level##_good = (good), \
+       l##level##_nice = (nice),
+
+       LEVEL_CONFIG_LIST
+
+# define LEVEL_CONFIG_(level, suffix) l##level##suffix
+# define LEVEL_CONFIG(level, name) LEVEL_CONFIG_(level, _##name)
+
+       comp_level_minus4 = (GZIP_DEFAULT_LEVEL - 4),
 
-       comp_level_minus4 = 6 - 4,
-       max_chain_length = 128,
+       max_chain_length = LEVEL_CONFIG(GZIP_DEFAULT_LEVEL, chain),
 /* To speed up deflation, hash chains are never searched beyond this length.
  * A higher limit improves compression ratio but degrades the speed.
  */
 
-       max_lazy_match = 16,
+       max_lazy_match = LEVEL_CONFIG(GZIP_DEFAULT_LEVEL, lazy),
 /* Attempt to find a better match only when the current match is strictly
  * smaller than this value. This mechanism is used only for compression
  * levels >= 4.
@@ -277,7 +299,7 @@ enum {
  * max_insert_length is used only for compression levels <= 3.
  */
 
-       good_match = 8,
+       good_match = LEVEL_CONFIG(GZIP_DEFAULT_LEVEL, good),
 /* Use a faster search when the previous match is longer than this */
 
 /* Values for max_lazy_match, good_match and max_chain_length, depending on
@@ -286,12 +308,16 @@ enum {
  * found for specific files.
  */
 
-       nice_match = 128,       /* Stop searching when current match exceeds 
this */
+       nice_match = LEVEL_CONFIG(GZIP_DEFAULT_LEVEL, nice)
+/* Stop searching when current match exceeds this */
 /* 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.
  */
-#endif /* ENABLE_FEATURE_GZIP_LEVELS */
+# undef LEVEL_CONFIG_DEFINE
+# undef LEVEL_CONFIG_
+# undef LEVEL_CONFIG
+#endif /* !ENABLE_FEATURE_GZIP_LEVELS */
 };
 
 struct globals {
@@ -2204,12 +2230,10 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
                uint8_t lazy2;
                uint8_t nice2;
        } gzip_level_config[6] = {
-               {4,   4,   4/2,  16/2}, /* Level 4 */
-               {8,   5,  16/2,  32/2}, /* Level 5 */
-               {8,   7,  16/2, 128/2}, /* Level 6 */
-               {8,   8,  32/2, 128/2}, /* Level 7 */
-               {32, 10, 128/2, 258/2}, /* Level 8 */
-               {32, 12, 258/2, 258/2}, /* Level 9 */
+# define LEVEL_CONFIG_DEFINE(level, good, chain_shift, lazy, nice) \
+               {(good), (chain_shift), (lazy)/2, (nice)/2},
+               LEVEL_CONFIG_LIST
+# undef LEVEL_CONFIG_DEFINE
        };
 #endif
 
@@ -2229,7 +2253,7 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
 #if ENABLE_FEATURE_GZIP_LEVELS
        opt >>= (BBUNPK_OPTSTRLEN IF_FEATURE_GZIP_DECOMPRESS(+ 2) + 1); /* drop 
cfkvq[dt]n bits */
        if (opt == 0)
-               opt = 1 << 5; /* default: 6 */
+               opt = 1 << (GZIP_DEFAULT_LEVEL - 1);
        opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */
 
        comp_level_minus4 = opt;
-- 
2.18.0

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to