| --- /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/xz_wrapper_extended.c |
| +++ b/squashfs-tools/xz_wrapper_extended.c |
| @@ -32,6 +32,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 }, |
| @@ -44,12 +45,6 @@ static struct bcj bcj[] = { |
| }; |
| |
| static int filter_count = 1; |
| -static int dictionary_size = 0; |
| -static float dictionary_percent = 0; |
| -static int preset = LZMA_PRESET_DEFAULT; |
| -static int lc = -1; |
| -static int lp = -1; |
| -static int pb = -1; |
| |
| /* |
| * This function is called by the options parsing code in mksquashfs.c |
| @@ -77,13 +72,13 @@ static int pb = -1; |
| */ |
| 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]; |
| @@ -104,138 +99,14 @@ static int xz_options(char *argv[], int argc) |
| 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; |
| + return -2; |
| } |
| - |
| - 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; |
| - } |
| - } |
| - |
| - return 1; |
| - } else if(strcmp(argv[0], "-Xpreset") == 0) { |
| - char *b; |
| - long val; |
| - |
| - if(argc < 2) { |
| - fprintf(stderr, "xz: -Xpreset missing preset-level " |
| - "(valid value 0-9)\n"); |
| - goto failed; |
| - } |
| - |
| - val = strtol(argv[1], &b, 10); |
| - if (*b != '\0' || (int) val < 0 || (int) val & ~LZMA_PRESET_LEVEL_MASK) { |
| - fprintf(stderr, "xz: -Xpreset can't be " |
| - "negative or more than the max preset\n"); |
| - goto failed; |
| - } |
| - |
| - preset &= ~LZMA_PRESET_LEVEL_MASK; |
| - preset |= (int) val; |
| - |
| - return 1; |
| - } else if(strcmp(argv[0], "-Xe") == 0) { |
| - preset |= LZMA_PRESET_EXTREME; |
| - |
| - return 0; |
| - } else if(strcmp(argv[0], "-Xlc") == 0) { |
| - char *b; |
| - long val; |
| - |
| - if(argc < 2) { |
| - fprintf(stderr, "xz: -Xlc missing value\n"); |
| - goto failed; |
| - } |
| - |
| - val = strtol(argv[1], &b, 10); |
| - if (*b != '\0' || (int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) { |
| - fprintf(stderr, "xz: -Xlc invalid value\n"); |
| - goto failed; |
| - } |
| - |
| - lc = (int) val; |
| - |
| - return 1; |
| - } else if(strcmp(argv[0], "-Xlp") == 0) { |
| - char *b; |
| - long val; |
| - |
| - if(argc < 2) { |
| - fprintf(stderr, "xz: -Xlp missing value\n"); |
| - goto failed; |
| - } |
| - |
| - val = strtol(argv[1], &b, 10); |
| - if (*b != '\0' || (int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) { |
| - fprintf(stderr, "xz: -Xlp invalid value\n"); |
| - goto failed; |
| - } |
| - |
| - lp = (int) val; |
| - |
| - return 1; |
| - } else if(strcmp(argv[0], "-Xpb") == 0) { |
| - char *b; |
| - long val; |
| - |
| - if(argc < 2) { |
| - fprintf(stderr, "xz: -Xpb missing value\n"); |
| - goto failed; |
| - } |
| - |
| - val = strtol(argv[1], &b, 10); |
| - if (*b != '\0' || (int) val < LZMA_PB_MIN || (int) val > LZMA_PB_MAX) { |
| - fprintf(stderr, "xz: -Xpb invalid value\n"); |
| - goto failed; |
| } |
| |
| - pb = (int) val; |
| - |
| return 1; |
| + } else { |
| + return lzma_xz_options(argv, argc, LZMA_OPT_XZ); |
| } |
| - |
| - return -1; |
| - |
| -failed: |
| - return -2; |
| } |
| |
| |
| @@ -252,53 +123,7 @@ failed: |
| */ |
| 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); |
| } |
| |
| |
| @@ -314,32 +139,12 @@ failed: |
| */ |
| static void *xz_dump_options(int block_size, int *size) |
| { |
| - static struct comp_opts comp_opts; |
| 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; |
| - |
| 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); |
| } |
| |
| |
| @@ -365,49 +170,20 @@ static void *xz_dump_options(int block_size, int *size) |
| */ |
| 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; |
| - } |
| - |
| - 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; |
| + int ret = lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_XZ); |
| + |
| + 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; |
| } |
| |
| |
| @@ -474,6 +250,7 @@ static int xz_init(void **strm, int block_size, int datablock) |
| 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; |
| @@ -487,7 +264,7 @@ static int xz_init(void **strm, int block_size, int datablock) |
| |
| 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; |
| @@ -529,25 +306,27 @@ static int xz_compress(void *strm, void *dest, void *src, int size, |
| 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 (opts->extreme) |
| + preset |= LZMA_PRESET_EXTREME; |
| + |
| if(lzma_lzma_preset(&stream->opt, preset)) |
| goto failed; |
| |
| - stream->opt.dict_size = stream->dictionary_size; |
| + stream->opt.lc = opts->lc; |
| + stream->opt.lp = opts->lp; |
| + stream->opt.pb = opts->pb; |
| + if (opts->fb) |
| + stream->opt.nice_len = opts->fb; |
| |
| - if (lc >= 0) |
| - stream->opt.lc = lc; |
| - |
| - if (lp >= 0) |
| - stream->opt.lp = lp; |
| - |
| - if (pb >= 0) |
| - stream->opt.pb = pb; |
| + stream->opt.dict_size = stream->dictionary_size; |
| |
| filter->length = 0; |
| res = lzma_stream_buffer_encode(filter->filter, |
| @@ -603,32 +382,13 @@ static int xz_uncompress(void *dest, void *src, int size, int outsize, |
| |
| static void xz_usage(FILE *stream) |
| { |
| + lzma_xz_usage(LZMA_OPT_XZ); |
| fprintf(stream, "\t -Xbcj filter1,filter2,...,filterN\n"); |
| fprintf(stream, "\t\tCompress using filter1,filter2,...,filterN in"); |
| fprintf(stream, " turn\n\t\t(in addition to no filter), and choose"); |
| fprintf(stream, " the best compression.\n"); |
| fprintf(stream, "\t\tAvailable filters: x86, arm, armthumb,"); |
| fprintf(stream, " powerpc, sparc, ia64\n"); |
| - fprintf(stream, "\t -Xdict-size <dict-size>\n"); |
| - fprintf(stream, "\t\tUse <dict-size> as the XZ dictionary size. The"); |
| - fprintf(stream, " dictionary size\n\t\tcan be specified as a"); |
| - fprintf(stream, " percentage of the block size, or as an\n\t\t"); |
| - fprintf(stream, "absolute value. The dictionary size must be less"); |
| - fprintf(stream, " than or equal\n\t\tto the block size and 8192 bytes"); |
| - fprintf(stream, " or larger. It must also be\n\t\tstorable in the xz"); |
| - fprintf(stream, " header as either 2^n or as 2^n+2^(n+1).\n\t\t"); |
| - fprintf(stream, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or"); |
| - fprintf(stream, " 32K, 16K, 8K\n\t\tetc.\n"); |
| - fprintf(stream, "\t -Xpreset <preset-level>\n"); |
| - fprintf(stream, "\t\tUse <preset-value> as the custom preset to use"); |
| - fprintf(stream, " on compress.\n\t\t<preset-level> should be 0 .. 9"); |
| - fprintf(stream, " (default 6)\n"); |
| - fprintf(stream, "\t -Xe\n"); |
| - fprintf(stream, "\t\tEnable additional compression settings by passing"); |
| - fprintf(stream, " the EXTREME\n\t\tflag to the compression flags.\n"); |
| - fprintf(stream, "\t -Xlc <value>\n"); |
| - fprintf(stream, "\t -Xlp <value>\n"); |
| - fprintf(stream, "\t -Xpb <value>\n"); |
| } |
| |
| |
| --- a/squashfs-tools/Makefile |
| +++ b/squashfs-tools/Makefile |
| @@ -263,6 +263,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) |