/branches/gl-inet/tools/squashfs4/patches/160-expose_lzma_xz_options.patch |
@@ -0,0 +1,929 @@ |
--- /dev/null |
+++ b/squashfs-tools/lzma_xz_options.h |
@@ -0,0 +1,115 @@ |
+#ifndef LZMA_XZ_OPTIONS_H |
+#define LZMA_XZ_OPTIONS_H |
+/* |
+ * Copyright (c) 2011 |
+ * Jonas Gorski <jonas.gorski@gmail.com> |
+ * |
+ * This program is free software; you can redistribute it and/or |
+ * modify it under the terms of the GNU General Public License |
+ * as published by the Free Software Foundation; either version 2, |
+ * or (at your option) any later version. |
+ * |
+ * This program is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with this program; if not, write to the Free Software |
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
+ * |
+ * lzma_options.h |
+ */ |
+ |
+#include <stdint.h> |
+ |
+#ifndef linux |
+#ifdef __FreeBSD__ |
+#include <machine/endian.h> |
+#endif |
+#define __BYTE_ORDER BYTE_ORDER |
+#define __BIG_ENDIAN BIG_ENDIAN |
+#define __LITTLE_ENDIAN LITTLE_ENDIAN |
+#else |
+#include <endian.h> |
+#endif |
+ |
+ |
+ |
+struct lzma_opts { |
+ uint32_t dict_size; |
+ uint32_t flags; |
+#define LZMA_OPT_FLT_MASK 0xffff |
+#define LZMA_OPT_PRE_OFF 16 |
+#define LZMA_OPT_PRE_MASK (0xf << LZMA_OPT_PRE_OFF) |
+#define LZMA_OPT_EXTREME 20 |
+ uint16_t bit_opts; |
+#define LZMA_OPT_LC_OFF 0 |
+#define LZMA_OPT_LC_MASK (0x7 << LZMA_OPT_LC_OFF) |
+#define LZMA_OPT_LP_OFF 3 |
+#define LZMA_OPT_LP_MASK (0x7 << LZMA_OPT_LP_OFF) |
+#define LZMA_OPT_PB_OFF 6 |
+#define LZMA_OPT_PB_MASK (0x7 << LZMA_OPT_PB_OFF) |
+ uint16_t fb; |
+}; |
+ |
+#if __BYTE_ORDER == __BIG_ENDIAN |
+extern unsigned int inswap_le32(unsigned int); |
+ |
+#define SQUASHFS_INSWAP_LZMA_COMP_OPTS(s) { \ |
+ (s)->flags = inswap_le32((s)->flags); \ |
+ (s)->bit_opts = inswap_le16((s)->bit_opts); \ |
+ (s)->fb = inswap_le16((s)->fb); \ |
+ (s)->dict_size = inswap_le32((s)->dict_size); \ |
+} |
+#else |
+#define SQUASHFS_INSWAP_LZMA_COMP_OPTS(s) |
+#endif |
+ |
+#define MEMLIMIT (32 * 1024 * 1024) |
+ |
+#define LZMA_OPT_LC_MIN 0 |
+#define LZMA_OPT_LC_MAX 4 |
+#define LZMA_OPT_LC_DEFAULT 3 |
+ |
+#define LZMA_OPT_LP_MIN 0 |
+#define LZMA_OPT_LP_MAX 4 |
+#define LZMA_OPT_LP_DEFAULT 0 |
+ |
+#define LZMA_OPT_PB_MIN 0 |
+#define LZMA_OPT_PB_MAX 4 |
+#define LZMA_OPT_PB_DEFAULT 2 |
+ |
+#define LZMA_OPT_FB_MIN 5 |
+#define LZMA_OPT_FB_MAX 273 |
+#define LZMA_OPT_FB_DEFAULT 64 |
+ |
+enum { |
+ LZMA_OPT_LZMA = 1, |
+ LZMA_OPT_XZ |
+}; |
+ |
+struct lzma_xz_options { |
+ int preset; |
+ int extreme; |
+ int lc; |
+ int lp; |
+ int pb; |
+ int fb; |
+ int dict_size; |
+ int flags; |
+}; |
+ |
+struct lzma_xz_options *lzma_xz_get_options(void); |
+ |
+int lzma_xz_options(char *argv[], int argc, int lzmaver); |
+ |
+int lzma_xz_options_post(int block_size, int lzmaver); |
+ |
+void *lzma_xz_dump_options(int block_size, int *size, int flags); |
+ |
+int lzma_xz_extract_options(int block_size, void *buffer, int size, int lzmaver); |
+ |
+void lzma_xz_usage(int lzmaver); |
+ |
+#endif |
--- /dev/null |
+++ b/squashfs-tools/lzma_xz_options.c |
@@ -0,0 +1,365 @@ |
+/* |
+ * Copyright (c) 2011 |
+ * Jonas Gorski <jonas.gorski@gmail.com> |
+ * |
+ * This program is free software; you can redistribute it and/or |
+ * modify it under the terms of the GNU General Public License |
+ * as published by the Free Software Foundation; either version 2, |
+ * or (at your option) any later version. |
+ * |
+ * This program is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with this program; if not, write to the Free Software |
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
+ * |
+ * lzma_options.c |
+ * |
+ * Common options for LZMA1 and 2 compressors. Based on xz_wrapper.c |
+ */ |
+ |
+#include <stdio.h> |
+#include <string.h> |
+#include <stdlib.h> |
+ |
+#include <lzma.h> |
+ |
+#include "lzma_xz_options.h" |
+ |
+static const char const *lzmaver_str[] = { "", "lzma", "xz" }; |
+ |
+static struct lzma_xz_options options = { |
+ .flags = 0, |
+ .preset = 6, |
+ .extreme = 0, |
+ .lc = LZMA_OPT_LC_DEFAULT, |
+ .lp = LZMA_OPT_LP_DEFAULT, |
+ .pb = LZMA_OPT_PB_DEFAULT, |
+ .fb = LZMA_OPT_FB_DEFAULT, |
+ .dict_size = 0, |
+}; |
+ |
+static float lzma_dict_percent = 0; |
+ |
+struct lzma_xz_options *lzma_xz_get_options(void) |
+{ |
+ return &options; |
+} |
+ |
+ |
+int lzma_xz_options(char *argv[], int argc, int lzmaver) |
+{ |
+ const char *comp_name = lzmaver_str[lzmaver]; |
+ |
+ if(strcmp(argv[0], "-Xpreset") == 0) { |
+ int preset; |
+ |
+ if(argc < 2) { |
+ fprintf(stderr, "%s: -Xpreset missing preset\n", comp_name); |
+ goto failed; |
+ } |
+ |
+ preset = atoi(argv[1]); |
+ |
+ if (preset < 0 || preset > 9) { |
+ fprintf(stderr, "%s: -Xpreset invalid value\n", comp_name); |
+ goto failed; |
+ } |
+ options.preset = preset; |
+ return 1; |
+ } else if(strcmp(argv[0], "-Xe") == 0) { |
+ options.extreme = 1; |
+ return 0; |
+ } else if(strcmp(argv[0], "-Xlc") == 0) { |
+ int lc; |
+ |
+ if(argc < 2) { |
+ fprintf(stderr, "%s: -Xlc missing lc\n", comp_name); |
+ goto failed; |
+ } |
+ |
+ lc = atoi(argv[1]); |
+ |
+ if (lc < LZMA_OPT_LC_MIN || lc > LZMA_OPT_LC_MAX) { |
+ fprintf(stderr, "%s: -Xlc invalid value\n", comp_name); |
+ goto failed; |
+ } |
+ options.lc = lc; |
+ return 1; |
+ } else if(strcmp(argv[0], "-Xlp") == 0) { |
+ int lp; |
+ |
+ if(argc < 2) { |
+ fprintf(stderr, "%s: -Xlp missing lp\n", comp_name); |
+ goto failed; |
+ } |
+ |
+ lp = atoi(argv[1]); |
+ |
+ if (lp < LZMA_OPT_LP_MIN || lp > LZMA_OPT_LP_MAX) { |
+ fprintf(stderr, "%s: -Xlp invalid value\n", comp_name); |
+ goto failed; |
+ } |
+ options.lp = lp; |
+ return 1; |
+ } else if(strcmp(argv[0], "-Xpb") == 0) { |
+ int pb; |
+ |
+ if(argc < 2) { |
+ fprintf(stderr, "%s: -Xpb missing pb\n", comp_name); |
+ goto failed; |
+ } |
+ |
+ pb = atoi(argv[1]); |
+ |
+ if (pb < LZMA_OPT_PB_MIN || pb > LZMA_OPT_PB_MAX) { |
+ fprintf(stderr, "%s: -Xbp invalid value\n", comp_name); |
+ goto failed; |
+ } |
+ options.pb = pb; |
+ return 1; |
+ } else if(strcmp(argv[0], "-Xfb") == 0) { |
+ int fb; |
+ |
+ if(argc < 2) { |
+ fprintf(stderr, "%s: -Xfb missing fb\n", comp_name); |
+ goto failed; |
+ } |
+ |
+ fb = atoi(argv[1]); |
+ |
+ if (fb < LZMA_OPT_FB_MIN || fb > LZMA_OPT_FB_MAX) { |
+ fprintf(stderr, "%s: -Xfb invalid value\n", comp_name); |
+ goto failed; |
+ } |
+ options.fb = fb; |
+ return 1; |
+ } else if(strcmp(argv[0], "-Xdict-size") == 0) { |
+ char *b; |
+ float size; |
+ |
+ if(argc < 2) { |
+ fprintf(stderr, "%s: -Xdict-size missing dict-size\n", comp_name); |
+ goto failed; |
+ } |
+ |
+ size = strtof(argv[1], &b); |
+ if(*b == '%') { |
+ if(size <= 0 || size > 100) { |
+ fprintf(stderr, "%s: -Xdict-size percentage " |
+ "should be 0 < dict-size <= 100\n", comp_name); |
+ goto failed; |
+ } |
+ |
+ lzma_dict_percent = size; |
+ options.dict_size = 0; |
+ } else { |
+ if((float) ((int) size) != size) { |
+ fprintf(stderr, "%s: -Xdict-size can't be " |
+ "fractional unless a percentage of the" |
+ " block size\n", comp_name); |
+ goto failed; |
+ } |
+ |
+ lzma_dict_percent = 0; |
+ options.dict_size = (int) size; |
+ |
+ if(*b == 'k' || *b == 'K') |
+ options.dict_size *= 1024; |
+ else if(*b == 'm' || *b == 'M') |
+ options.dict_size *= 1024 * 1024; |
+ else if(*b != '\0') { |
+ fprintf(stderr, "%s: -Xdict-size invalid " |
+ "dict-size\n", comp_name); |
+ goto failed; |
+ } |
+ } |
+ |
+ return 1; |
+ } |
+ |
+ return -1; |
+ |
+failed: |
+ return -2; |
+ |
+} |
+ |
+int lzma_xz_options_post(int block_size, int lzmaver) |
+{ |
+ const char *comp_name = lzmaver_str[lzmaver]; |
+ /* |
+ * if -Xdict-size has been specified use this to compute the datablock |
+ * dictionary size |
+ */ |
+ if(options.dict_size || lzma_dict_percent) { |
+ int dict_size_min = (lzmaver == 1 ? 4096 : 8192); |
+ int n; |
+ |
+ if(options.dict_size) { |
+ if(options.dict_size > block_size) { |
+ fprintf(stderr, "%s: -Xdict-size is larger than" |
+ " block_size\n", comp_name); |
+ goto failed; |
+ } |
+ } else |
+ options.dict_size = block_size * lzma_dict_percent / 100; |
+ |
+ if(options.dict_size < dict_size_min) { |
+ fprintf(stderr, "%s: -Xdict-size should be %i bytes " |
+ "or larger\n", comp_name, dict_size_min); |
+ goto failed; |
+ } |
+ |
+ /* |
+ * dictionary_size must be storable in xz header as either |
+ * 2^n or as 2^n+2^(n+1) |
+ */ |
+ n = ffs(options.dict_size) - 1; |
+ if(options.dict_size != (1 << n) && |
+ options.dict_size != ((1 << n) + (1 << (n + 1)))) { |
+ fprintf(stderr, "%s: -Xdict-size is an unsupported " |
+ "value, dict-size must be storable in %s " |
+ "header\n", comp_name, comp_name); |
+ fprintf(stderr, "as either 2^n or as 2^n+2^(n+1). " |
+ "Example dict-sizes are 75%%, 50%%, 37.5%%, " |
+ "25%%,\n"); |
+ fprintf(stderr, "or 32K, 16K, 8K etc.\n"); |
+ goto failed; |
+ } |
+ |
+ } else |
+ /* No -Xdict-size specified, use defaults */ |
+ options.dict_size = block_size; |
+ |
+ return 0; |
+ |
+failed: |
+ return -1; |
+} |
+ |
+static struct lzma_opts lzma_comp_opts; |
+ |
+void *lzma_xz_dump_options(int block_size, int *size, int flags) |
+{ |
+ /* No need to store default options */ |
+ if (options.preset == 6 && |
+ options.extreme == 0 && |
+ options.lc == LZMA_OPT_LC_DEFAULT && |
+ options.lp == LZMA_OPT_LC_DEFAULT && |
+ options.pb == LZMA_OPT_PB_DEFAULT && |
+ options.fb == 0 && |
+ options.dict_size == block_size && |
+ flags == 0) |
+ return NULL; |
+ |
+ *size = sizeof(struct lzma_opts); |
+ |
+ lzma_comp_opts.flags |= flags; |
+ |
+ if (options.extreme) |
+ lzma_comp_opts.flags |= LZMA_OPT_EXTREME; |
+ |
+ lzma_comp_opts.flags |= ((options.preset << LZMA_OPT_PRE_OFF) & LZMA_OPT_PRE_MASK); |
+ |
+ lzma_comp_opts.bit_opts = |
+ ((options.lc << LZMA_OPT_LC_OFF) & LZMA_OPT_LC_MASK) | |
+ ((options.lp << LZMA_OPT_LP_OFF) & LZMA_OPT_LP_MASK) | |
+ ((options.pb << LZMA_OPT_PB_OFF) & LZMA_OPT_PB_MASK); |
+ lzma_comp_opts.fb = options.fb; |
+ lzma_comp_opts.dict_size = options.dict_size; |
+ |
+ SQUASHFS_INSWAP_LZMA_COMP_OPTS(&lzma_comp_opts); |
+ |
+ return &lzma_comp_opts; |
+} |
+ |
+int lzma_xz_extract_options(int block_size, void *buffer, int size, int lzmaver) |
+{ |
+ if (size == 0) { |
+ /* default options */ |
+ options.preset = 6; |
+ options.extreme = 0; |
+ options.lc = LZMA_OPT_LC_DEFAULT; |
+ options.lp = LZMA_OPT_LC_DEFAULT; |
+ options.pb = LZMA_OPT_PB_DEFAULT; |
+ options.fb = LZMA_OPT_FB_DEFAULT; |
+ options.dict_size = block_size; |
+ options.flags = 0; |
+ } else { |
+ struct lzma_opts *comp_opts = buffer; |
+ int n; |
+ |
+ if (size != sizeof(struct lzma_opts)) |
+ goto failed; |
+ |
+ SQUASHFS_INSWAP_LZMA_COMP_OPTS(comp_opts); |
+ |
+ options.flags = comp_opts->flags & LZMA_OPT_FLT_MASK; |
+ options.preset = (comp_opts->flags & LZMA_OPT_PRE_MASK) >> LZMA_OPT_PRE_OFF; |
+ options.extreme = !!(comp_opts->flags & LZMA_OPT_EXTREME); |
+ |
+ options.lc = (comp_opts->bit_opts & LZMA_OPT_LC_MASK) >> LZMA_OPT_LC_OFF; |
+ options.lp = (comp_opts->bit_opts & LZMA_OPT_LP_MASK) >> LZMA_OPT_LP_OFF; |
+ options.pb = (comp_opts->bit_opts & LZMA_OPT_PB_MASK) >> LZMA_OPT_PB_OFF; |
+ options.fb = comp_opts->fb; |
+ options.dict_size = comp_opts->dict_size; |
+ |
+ /* check that the LZMA bit options are in range */ |
+ if (options.lc < LZMA_OPT_LC_MIN || options.lc > LZMA_OPT_LC_MAX || |
+ options.lp < LZMA_OPT_LP_MIN || options.lp > LZMA_OPT_LP_MAX || |
+ options.pb < LZMA_OPT_PB_MIN || options.pb > LZMA_OPT_PB_MAX || |
+ options.fb < LZMA_OPT_FB_MIN || options.fb > LZMA_OPT_FB_MAX) |
+ goto failed; |
+ |
+ /* |
+ * check that the dictionary size seems correct - the dictionary |
+ * size should 2^n or 2^n+2^(n+1) |
+ */ |
+ n = ffs(options.dict_size) - 1; |
+ if(options.dict_size != (1 << n) && |
+ options.dict_size != ((1 << n) + (1 << (n + 1)))) |
+ goto failed; |
+ |
+ } |
+ |
+ return 0; |
+ |
+failed: |
+ fprintf(stderr, "%s: error reading stored compressor options from " |
+ "filesystem!\n", lzmaver_str[lzmaver]); |
+ return -1; |
+} |
+ |
+void lzma_xz_usage(int lzmaver) |
+{ |
+ fprintf(stderr, "\t -Xpreset <preset>\n"); |
+ fprintf(stderr, "\t\tcompression preset (0-9, default 6)\n"); |
+ fprintf(stderr, "\t -Xe\n"); |
+ fprintf(stderr, "\t\tTry to improve compression ratio by using more "); |
+ fprintf(stderr, "CPU time.\n"); |
+ fprintf(stderr, "\t -Xlc <lc>\n"); |
+ fprintf(stderr, "\t\tNumber of literal context bits (0-4, default 3)\n"); |
+ fprintf(stderr, "\t -Xlp <lp>\n"); |
+ fprintf(stderr, "\t\tNumber of literal position bits (0-4, default 0)\n"); |
+ fprintf(stderr, "\t -Xpb <pb>\n"); |
+ fprintf(stderr, "\t\tNumber of position bits (0-4, default 2)\n"); |
+ fprintf(stderr, "\t -Xnice <nice>\n"); |
+ fprintf(stderr, "\t\tNice length of a match (5-273, default 64)\n"); |
+ fprintf(stderr, "\t -Xdict-size <dict-size>\n"); |
+ fprintf(stderr, "\t\tUse <dict-size> as the %s dictionary size. The", |
+ lzmaver == LZMA_OPT_LZMA ? "LZMA" : "XZ"); |
+ fprintf(stderr, " dictionary size\n\t\tcan be specified as a"); |
+ fprintf(stderr, " percentage of the block size, or as an\n\t\t"); |
+ fprintf(stderr, "absolute value. The dictionary size must be less"); |
+ fprintf(stderr, " than or equal\n\t\tto the block size and %d bytes", |
+ lzmaver == LZMA_OPT_LZMA ? 4096 : 8192); |
+ fprintf(stderr, " or larger. It must also be\n\t\tstorable in the lzma"); |
+ fprintf(stderr, " header as either 2^n or as 2^n+2^(n+1).\n\t\t"); |
+ fprintf(stderr, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or"); |
+ fprintf(stderr, " 32K, 16K, 8K\n\t\tetc.\n"); |
+ |
+} |
--- a/squashfs-tools/lzma_xz_wrapper.c |
+++ b/squashfs-tools/lzma_xz_wrapper.c |
@@ -27,6 +27,7 @@ |
|
#include "squashfs_fs.h" |
#include "compressor.h" |
+#include "lzma_xz_options.h" |
|
#define LZMA_PROPS_SIZE 5 |
#define LZMA_UNCOMP_SIZE 8 |
@@ -38,13 +39,27 @@ |
static int lzma_compress(void *dummy, void *dest, void *src, int size, |
int block_size, int *error) |
{ |
+ uint32_t preset; |
unsigned char *d = (unsigned char *) dest; |
+ struct lzma_xz_options *opts = lzma_xz_get_options(); |
+ |
lzma_options_lzma opt; |
lzma_stream strm = LZMA_STREAM_INIT; |
int res; |
|
- lzma_lzma_preset(&opt, LZMA_OPTIONS); |
- opt.dict_size = block_size; |
+ preset = opts->preset; |
+ |
+ if (opts->extreme) |
+ preset |= LZMA_PRESET_EXTREME; |
+ |
+ lzma_lzma_preset(&opt, opts->preset); |
+ opt.lc = opts->lc; |
+ opt.lp = opts->lp; |
+ opt.pb = opts->pb; |
+ if (opts->fb) |
+ opt.nice_len = opts->fb; |
+ |
+ opt.dict_size = opts->dict_size; |
|
res = lzma_alone_encoder(&strm, &opt); |
if(res != LZMA_OK) { |
@@ -143,13 +158,45 @@ failed: |
return -1; |
} |
|
+static int lzma_options(char *argv[], int argc) |
+{ |
+ return lzma_xz_options(argv, argc, LZMA_OPT_LZMA); |
+} |
+ |
+ |
+static int lzma_options_post(int block_size) |
+{ |
+ return lzma_xz_options_post(block_size, LZMA_OPT_LZMA); |
+} |
+ |
+ |
+static void *lzma_dump_options(int block_size, int *size) |
+{ |
+ return lzma_xz_dump_options(block_size, size, 0); |
+} |
+ |
+ |
+static int lzma_extract_options(int block_size, void *buffer, int size) |
+{ |
+ return lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_LZMA); |
+} |
+ |
+ |
+void lzma_usage() |
+{ |
+ lzma_xz_usage(LZMA_OPT_LZMA); |
+} |
+ |
|
struct compressor lzma_comp_ops = { |
.init = NULL, |
.compress = lzma_compress, |
.uncompress = lzma_uncompress, |
- .options = NULL, |
- .usage = NULL, |
+ .options = lzma_options, |
+ .options_post = lzma_options_post, |
+ .dump_options = lzma_dump_options, |
+ .extract_options = lzma_extract_options, |
+ .usage = lzma_usage, |
.id = LZMA_COMPRESSION, |
.name = "lzma", |
.supported = 1 |
--- a/squashfs-tools/xz_wrapper.h |
+++ b/squashfs-tools/xz_wrapper.h |
@@ -24,25 +24,6 @@ |
* |
*/ |
|
-#ifndef linux |
-#define __BYTE_ORDER BYTE_ORDER |
-#define __BIG_ENDIAN BIG_ENDIAN |
-#define __LITTLE_ENDIAN LITTLE_ENDIAN |
-#else |
-#include <endian.h> |
-#endif |
- |
-#if __BYTE_ORDER == __BIG_ENDIAN |
-extern unsigned int inswap_le32(unsigned int); |
- |
-#define SQUASHFS_INSWAP_COMP_OPTS(s) { \ |
- (s)->dictionary_size = inswap_le32((s)->dictionary_size); \ |
- (s)->flags = inswap_le32((s)->flags); \ |
-} |
-#else |
-#define SQUASHFS_INSWAP_COMP_OPTS(s) |
-#endif |
- |
#define MEMLIMIT (32 * 1024 * 1024) |
|
struct bcj { |
--- a/squashfs-tools/xz_wrapper.c |
+++ b/squashfs-tools/xz_wrapper.c |
@@ -30,6 +30,7 @@ |
#include "squashfs_fs.h" |
#include "xz_wrapper.h" |
#include "compressor.h" |
+#include "lzma_xz_options.h" |
|
static struct bcj bcj[] = { |
{ "x86", LZMA_FILTER_X86, 0 }, |
@@ -41,22 +42,18 @@ static struct bcj bcj[] = { |
{ NULL, LZMA_VLI_UNKNOWN, 0 } |
}; |
|
-static struct comp_opts comp_opts; |
- |
static int filter_count = 1; |
-static int dictionary_size = 0; |
-static float dictionary_percent = 0; |
|
|
static int xz_options(char *argv[], int argc) |
{ |
- int i; |
- char *name; |
- |
if(strcmp(argv[0], "-Xbcj") == 0) { |
+ int i; |
+ char *name; |
+ |
if(argc < 2) { |
fprintf(stderr, "xz: -Xbcj missing filter\n"); |
- goto failed; |
+ return -2; |
} |
|
name = argv[1]; |
@@ -76,190 +73,50 @@ static int xz_options(char *argv[], int |
} |
if(bcj[i].name == NULL) { |
fprintf(stderr, "xz: -Xbcj unrecognised " |
- "filter\n"); |
- goto failed; |
- } |
- } |
- |
- return 1; |
- } else if(strcmp(argv[0], "-Xdict-size") == 0) { |
- char *b; |
- float size; |
- |
- if(argc < 2) { |
- fprintf(stderr, "xz: -Xdict-size missing dict-size\n"); |
- goto failed; |
- } |
- |
- size = strtof(argv[1], &b); |
- if(*b == '%') { |
- if(size <= 0 || size > 100) { |
- fprintf(stderr, "xz: -Xdict-size percentage " |
- "should be 0 < dict-size <= 100\n"); |
- goto failed; |
- } |
- |
- dictionary_percent = size; |
- dictionary_size = 0; |
- } else { |
- if((float) ((int) size) != size) { |
- fprintf(stderr, "xz: -Xdict-size can't be " |
- "fractional unless a percentage of the" |
- " block size\n"); |
- goto failed; |
- } |
- |
- dictionary_percent = 0; |
- dictionary_size = (int) size; |
- |
- if(*b == 'k' || *b == 'K') |
- dictionary_size *= 1024; |
- else if(*b == 'm' || *b == 'M') |
- dictionary_size *= 1024 * 1024; |
- else if(*b != '\0') { |
- fprintf(stderr, "xz: -Xdict-size invalid " |
- "dict-size\n"); |
- goto failed; |
+ "filter\n"); |
+ return -2; |
} |
} |
- |
return 1; |
+ } else { |
+ return lzma_xz_options(argv, argc, LZMA_OPT_XZ); |
} |
- |
- return -1; |
- |
-failed: |
- return -2; |
} |
|
|
static int xz_options_post(int block_size) |
{ |
- /* |
- * if -Xdict-size has been specified use this to compute the datablock |
- * dictionary size |
- */ |
- if(dictionary_size || dictionary_percent) { |
- int n; |
- |
- if(dictionary_size) { |
- if(dictionary_size > block_size) { |
- fprintf(stderr, "xz: -Xdict-size is larger than" |
- " block_size\n"); |
- goto failed; |
- } |
- } else |
- dictionary_size = block_size * dictionary_percent / 100; |
- |
- if(dictionary_size < 8192) { |
- fprintf(stderr, "xz: -Xdict-size should be 8192 bytes " |
- "or larger\n"); |
- goto failed; |
- } |
- |
- /* |
- * dictionary_size must be storable in xz header as either |
- * 2^n or as 2^n+2^(n+1) |
- */ |
- n = ffs(dictionary_size) - 1; |
- if(dictionary_size != (1 << n) && |
- dictionary_size != ((1 << n) + (1 << (n + 1)))) { |
- fprintf(stderr, "xz: -Xdict-size is an unsupported " |
- "value, dict-size must be storable in xz " |
- "header\n"); |
- fprintf(stderr, "as either 2^n or as 2^n+2^(n+1). " |
- "Example dict-sizes are 75%%, 50%%, 37.5%%, " |
- "25%%,\n"); |
- fprintf(stderr, "or 32K, 16K, 8K etc.\n"); |
- goto failed; |
- } |
- |
- } else |
- /* No -Xdict-size specified, use defaults */ |
- dictionary_size = block_size; |
- |
- return 0; |
- |
-failed: |
- return -1; |
+ return lzma_xz_options_post(block_size, LZMA_OPT_XZ); |
} |
|
|
static void *xz_dump_options(int block_size, int *size) |
{ |
- int flags = 0, i; |
- |
- /* |
- * don't store compressor specific options in file system if the |
- * default options are being used - no compressor options in the |
- * file system means the default options are always assumed |
- * |
- * Defaults are: |
- * metadata dictionary size: SQUASHFS_METADATA_SIZE |
- * datablock dictionary size: block_size |
- * 1 filter |
- */ |
- if(dictionary_size == block_size && filter_count == 1) |
- return NULL; |
+ int i, flags = 0; |
|
for(i = 0; bcj[i].name; i++) |
flags |= bcj[i].selected << i; |
|
- comp_opts.dictionary_size = dictionary_size; |
- comp_opts.flags = flags; |
- |
- SQUASHFS_INSWAP_COMP_OPTS(&comp_opts); |
- |
- *size = sizeof(comp_opts); |
- return &comp_opts; |
+ return lzma_xz_dump_options(block_size, size, flags); |
} |
|
|
static int xz_extract_options(int block_size, void *buffer, int size) |
{ |
- struct comp_opts *comp_opts = buffer; |
- int flags, i, n; |
- |
- if(size == 0) { |
- /* set defaults */ |
- dictionary_size = block_size; |
- flags = 0; |
- } else { |
- /* check passed comp opts struct is of the correct length */ |
- if(size != sizeof(struct comp_opts)) |
- goto failed; |
- |
- SQUASHFS_INSWAP_COMP_OPTS(comp_opts); |
- |
- dictionary_size = comp_opts->dictionary_size; |
- flags = comp_opts->flags; |
- |
- /* |
- * check that the dictionary size seems correct - the dictionary |
- * size should 2^n or 2^n+2^(n+1) |
- */ |
- n = ffs(dictionary_size) - 1; |
- if(dictionary_size != (1 << n) && |
- dictionary_size != ((1 << n) + (1 << (n + 1)))) |
- goto failed; |
- } |
+ int ret = lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_XZ); |
|
- filter_count = 1; |
- for(i = 0; bcj[i].name; i++) { |
- if((flags >> i) & 1) { |
- bcj[i].selected = 1; |
- filter_count ++; |
- } else |
- bcj[i].selected = 0; |
+ if (!ret) { |
+ int i; |
+ struct lzma_xz_options *opts = lzma_xz_get_options(); |
+ for(i = 0; bcj[i].name; i++) { |
+ if((opts->flags >> i) & 1) { |
+ bcj[i].selected = 1; |
+ filter_count ++; |
+ } else |
+ bcj[i].selected = 0; |
+ } |
} |
- |
- return 0; |
- |
-failed: |
- fprintf(stderr, "xz: error reading stored compressor options from " |
- "filesystem!\n"); |
- |
- return -1; |
+ return ret; |
} |
|
|
@@ -268,6 +125,7 @@ static int xz_init(void **strm, int bloc |
int i, j, filters = datablock ? filter_count : 1; |
struct filter *filter = malloc(filters * sizeof(struct filter)); |
struct xz_stream *stream; |
+ struct lzma_xz_options *opts = lzma_xz_get_options(); |
|
if(filter == NULL) |
goto failed; |
@@ -281,7 +139,7 @@ static int xz_init(void **strm, int bloc |
|
memset(filter, 0, filters * sizeof(struct filter)); |
|
- stream->dictionary_size = datablock ? dictionary_size : |
+ stream->dictionary_size = datablock ? opts->dict_size : |
SQUASHFS_METADATA_SIZE; |
|
filter[0].filter[0].id = LZMA_FILTER_LZMA2; |
@@ -323,14 +181,25 @@ static int xz_compress(void *strm, void |
lzma_ret res = 0; |
struct xz_stream *stream = strm; |
struct filter *selected = NULL; |
+ struct lzma_xz_options *opts = lzma_xz_get_options(); |
|
stream->filter[0].buffer = dest; |
|
for(i = 0; i < stream->filters; i++) { |
+ uint32_t preset = opts->preset; |
struct filter *filter = &stream->filter[i]; |
|
- if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT)) |
- goto failed; |
+ if (opts->extreme) |
+ preset |= LZMA_PRESET_EXTREME; |
+ |
+ if(lzma_lzma_preset(&stream->opt, preset)) |
+ goto failed; |
+ |
+ stream->opt.lc = opts->lc; |
+ stream->opt.lp = opts->lp; |
+ stream->opt.pb = opts->pb; |
+ if (opts->fb) |
+ stream->opt.nice_len = opts->fb; |
|
stream->opt.dict_size = stream->dictionary_size; |
|
@@ -384,22 +253,13 @@ static int xz_uncompress(void *dest, voi |
|
void xz_usage() |
{ |
+ lzma_xz_usage(LZMA_OPT_XZ); |
fprintf(stderr, "\t -Xbcj filter1,filter2,...,filterN\n"); |
fprintf(stderr, "\t\tCompress using filter1,filter2,...,filterN in"); |
fprintf(stderr, " turn\n\t\t(in addition to no filter), and choose"); |
fprintf(stderr, " the best compression.\n"); |
fprintf(stderr, "\t\tAvailable filters: x86, arm, armthumb,"); |
fprintf(stderr, " powerpc, sparc, ia64\n"); |
- fprintf(stderr, "\t -Xdict-size <dict-size>\n"); |
- fprintf(stderr, "\t\tUse <dict-size> as the XZ dictionary size. The"); |
- fprintf(stderr, " dictionary size\n\t\tcan be specified as a"); |
- fprintf(stderr, " percentage of the block size, or as an\n\t\t"); |
- fprintf(stderr, "absolute value. The dictionary size must be less"); |
- fprintf(stderr, " than or equal\n\t\tto the block size and 8192 bytes"); |
- fprintf(stderr, " or larger. It must also be\n\t\tstorable in the xz"); |
- fprintf(stderr, " header as either 2^n or as 2^n+2^(n+1).\n\t\t"); |
- fprintf(stderr, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or"); |
- fprintf(stderr, " 32K, 16K, 8K\n\t\tetc.\n"); |
} |
|
|
--- a/squashfs-tools/Makefile |
+++ b/squashfs-tools/Makefile |
@@ -140,6 +140,8 @@ COMPRESSORS += xz |
endif |
|
ifneq ($(LZMA_XZ_SUPPORT)$(XZ_SUPPORT),) |
+MKSQUASHFS_OBJS += lzma_xz_options.o |
+UNSQUASHFS_OBJS += lzma_xz_options.o |
ifneq ($(LZMA_LIB),) |
MKSQUASHFS_OBJS += $(LZMA_LIB) |
UNSQUASHFS_OBJS += $(LZMA_LIB) |