123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929 |
- --- /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)
|