|
@@ -1,929 +0,0 @@
|
|
|
---- /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 <[email protected]>
|
|
|
-+ *
|
|
|
-+ * 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 <[email protected]>
|
|
|
-+ *
|
|
|
-+ * 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)
|