mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 22:44:27 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			930 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			930 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
--- /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 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;
 | 
						|
+	uint32_t dict_size;
 | 
						|
+};
 | 
						|
+
 | 
						|
+#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)
 |