tools/squashfs4: update to version 4.2 (adds support for xz compression)
Based on a patch by Jonas Gorski SVN-Revision: 26422
This commit is contained in:
		| @@ -42,6 +42,14 @@ ifneq ($(CONFIG_JFFS2_LZMA),y) | ||||
|   JFFS2OPTS += -x lzma | ||||
| endif | ||||
|  | ||||
| LZMA_XZ_OPTIONS := -Xpreset 9 -Xe -Xlc 0 -Xlp 2 -Xpb 2 | ||||
| ifeq ($(CONFIG_SQUASHFS_LZMA),y) | ||||
|   SQUASHFSCOMP := lzma $(LZMA_XZ_OPTIONS) | ||||
| endif | ||||
| ifeq ($(CONFIG_SQUASHFS_XZ),y) | ||||
|   SQUASHFSCOMP := xz $(LZMA_XZ_OPTIONS) | ||||
| endif | ||||
|  | ||||
| JFFS2_BLOCKSIZE ?= 64k 128k | ||||
|  | ||||
| define add_jffs2_mark | ||||
| @@ -86,7 +94,7 @@ else | ||||
|   ifneq ($(CONFIG_TARGET_ROOTFS_SQUASHFS),) | ||||
|     define Image/mkfs/squashfs | ||||
| 		@mkdir -p $(TARGET_DIR)/overlay | ||||
| 		$(STAGING_DIR_HOST)/bin/mksquashfs4 $(TARGET_DIR) $(KDIR)/root.squashfs -nopad -noappend -root-owned -comp lzma -processors 1 | ||||
| 		$(STAGING_DIR_HOST)/bin/mksquashfs4 $(TARGET_DIR) $(KDIR)/root.squashfs -nopad -noappend -root-owned -comp $(SQUASHFSCOMP) -processors 1 | ||||
| 		$(call Image/Build,squashfs) | ||||
|     endef | ||||
|   endif | ||||
|   | ||||
| @@ -38,7 +38,7 @@ $(curdir)/bison/compile := $(curdir)/flex/install | ||||
| $(curdir)/pkg-config/compile := $(curdir)/sed/install | ||||
| $(curdir)/libtool/compile := $(curdir)/sed/install | ||||
| $(curdir)/squashfs/compile := $(curdir)/lzma-old/install | ||||
| $(curdir)/squashfs4/compile := $(curdir)/lzma/install | ||||
| $(curdir)/squashfs4/compile := $(curdir)/xz/install | ||||
| $(curdir)/quilt/compile := $(curdir)/sed/install $(curdir)/autoconf/install | ||||
| $(curdir)/dtc/compile := $(curdir)/bison/install | ||||
| $(curdir)/autoconf/compile := $(curdir)/m4/install $(curdir)/libtool/install | ||||
|   | ||||
| @@ -26,10 +26,8 @@ define Host/Compile | ||||
| endef | ||||
|  | ||||
| define Host/Install | ||||
| 	$(INSTALL_DIR) $(STAGING_DIR_HOST)/lib $(STAGING_DIR_HOST)/include $(STAGING_DIR_HOST)/bin | ||||
| 	$(INSTALL_DIR) $(STAGING_DIR_HOST)/bin | ||||
| 	$(INSTALL_BIN) $(HOST_BUILD_DIR)/CPP/7zip/Compress/LZMA_Alone/lzma_alone $(STAGING_DIR_HOST)/bin/lzma | ||||
| 	$(CP) $(HOST_BUILD_DIR)/C/*.h $(STAGING_DIR_HOST)/include/ | ||||
| 	$(CP) $(UTIL_DIR)/liblzma.a $(STAGING_DIR_HOST)/lib/ | ||||
| endef | ||||
|  | ||||
| define Host/Clean | ||||
|   | ||||
| @@ -7,11 +7,11 @@ | ||||
| include $(TOPDIR)/rules.mk | ||||
|  | ||||
| PKG_NAME:=squashfs4 | ||||
| PKG_VERSION:=4.0 | ||||
| PKG_VERSION:=4.2 | ||||
|  | ||||
| PKG_SOURCE:=squashfs$(PKG_VERSION).tar.gz | ||||
| PKG_SOURCE_URL:=@SF/squashfs | ||||
| PKG_MD5SUM:=a3c23391da4ebab0ac4a75021ddabf96 | ||||
| PKG_MD5SUM:=1b7a781fb4cf8938842279bd3e8ee852 | ||||
| PKG_CAT:=zcat | ||||
|  | ||||
| HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/squashfs$(PKG_VERSION) | ||||
| @@ -20,9 +20,11 @@ include $(INCLUDE_DIR)/host-build.mk | ||||
|  | ||||
| define Host/Compile | ||||
| 	$(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \ | ||||
| 		USE_LZMA=1 \ | ||||
| 		LZMA_CFLAGS="-I$(STAGING_DIR_HOST)/include -DUSE_LZMA" \ | ||||
| 		XZ_SUPPORT=1 \ | ||||
| 		LZMA_XZ_SUPPORT=1 \ | ||||
| 		XATTR_SUPPORT= \ | ||||
| 		LZMA_LIB="$(STAGING_DIR_HOST)/lib/liblzma.a" \ | ||||
| 		EXTRA_CFLAGS="-I$(STAGING_DIR_HOST)/include" \ | ||||
| 		mksquashfs unsquashfs | ||||
| endef | ||||
|  | ||||
|   | ||||
| @@ -1,17 +1,19 @@ | ||||
| --- a/squashfs-tools/global.h | ||||
| +++ b/squashfs-tools/global.h | ||||
| @@ -44,4 +44,8 @@ typedef long long squashfs_fragment_inde | ||||
|  typedef squashfs_inode_t squashfs_inode; | ||||
|  typedef squashfs_block_t squashfs_block; | ||||
| --- a/squashfs-tools/mksquashfs.c | ||||
| +++ b/squashfs-tools/mksquashfs.c | ||||
| @@ -60,6 +60,10 @@ | ||||
|  #include <sys/sysinfo.h> | ||||
|  #endif | ||||
|   | ||||
| +#ifndef FNM_EXTMATCH | ||||
| +#define FNM_EXTMATCH 0 | ||||
| +#endif | ||||
| + | ||||
|  #endif | ||||
|  #ifdef SQUASHFS_TRACE | ||||
|  #define TRACE(s, args...) \ | ||||
|  		do { \ | ||||
| --- a/squashfs-tools/unsquashfs.h | ||||
| +++ b/squashfs-tools/unsquashfs.h | ||||
| @@ -49,8 +49,10 @@ | ||||
| @@ -49,8 +49,14 @@ | ||||
|  #define __BYTE_ORDER BYTE_ORDER | ||||
|  #define __BIG_ENDIAN BIG_ENDIAN | ||||
|  #define __LITTLE_ENDIAN LITTLE_ENDIAN | ||||
| @@ -19,6 +21,20 @@ | ||||
|  #else | ||||
|  #include <endian.h> | ||||
| +#include <sys/sysinfo.h> | ||||
| +#endif | ||||
| + | ||||
| +#ifndef FNM_EXTMATCH | ||||
| +#define FNM_EXTMATCH 0 | ||||
|  #endif | ||||
|   | ||||
|  #include "squashfs_fs.h" | ||||
| --- a/squashfs-tools/unsquashfs.c | ||||
| +++ b/squashfs-tools/unsquashfs.c | ||||
| @@ -29,7 +29,6 @@ | ||||
|  #include "compressor.h" | ||||
|  #include "xattr.h" | ||||
|   | ||||
| -#include <sys/sysinfo.h> | ||||
|  #include <sys/types.h> | ||||
|   | ||||
|  struct cache *fragment_cache, *data_cache; | ||||
|   | ||||
							
								
								
									
										30
									
								
								tools/squashfs4/patches/110-allow_static_liblzma.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								tools/squashfs4/patches/110-allow_static_liblzma.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| --- a/squashfs-tools/Makefile | ||||
| +++ b/squashfs-tools/Makefile | ||||
| @@ -129,7 +129,6 @@ ifeq ($(LZMA_XZ_SUPPORT),1) | ||||
|  CFLAGS += -DLZMA_SUPPORT | ||||
|  MKSQUASHFS_OBJS += lzma_xz_wrapper.o | ||||
|  UNSQUASHFS_OBJS += lzma_xz_wrapper.o | ||||
| -LIBS += -llzma | ||||
|  COMPRESSORS += lzma | ||||
|  endif | ||||
|   | ||||
| @@ -137,10 +136,18 @@ ifeq ($(XZ_SUPPORT),1) | ||||
|  CFLAGS += -DXZ_SUPPORT | ||||
|  MKSQUASHFS_OBJS += xz_wrapper.o | ||||
|  UNSQUASHFS_OBJS += xz_wrapper.o | ||||
| -LIBS += -llzma | ||||
|  COMPRESSORS += xz | ||||
|  endif | ||||
|   | ||||
| +ifneq ($(LZMA_XZ_SUPPORT)$(XZ_SUPPORT),) | ||||
| +ifneq ($(LZMA_LIB),) | ||||
| +MKSQUASHFS_OBJS += $(LZMA_LIB) | ||||
| +UNSQUASHFS_OBJS += $(LZMA_LIB) | ||||
| +else | ||||
| +LIBS += -llzma | ||||
| +endif | ||||
| +endif | ||||
| + | ||||
|  ifeq ($(LZO_SUPPORT),1) | ||||
|  CFLAGS += -DLZO_SUPPORT | ||||
|  ifdef LZO_DIR | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,20 +1,6 @@ | ||||
| --- a/squashfs-tools/global.h | ||||
| +++ b/squashfs-tools/global.h | ||||
| @@ -44,6 +44,11 @@ typedef long long squashfs_fragment_inde | ||||
|  typedef squashfs_inode_t squashfs_inode; | ||||
|  typedef squashfs_block_t squashfs_block; | ||||
|   | ||||
| +#ifdef __CYGWIN__ | ||||
| +#include <sys/termios.h> | ||||
| +#define FNM_EXTMATCH  (1 << 5) | ||||
| +#endif | ||||
| + | ||||
|  #ifndef FNM_EXTMATCH | ||||
|  #define FNM_EXTMATCH 0 | ||||
|  #endif | ||||
| --- a/squashfs-tools/mksquashfs.c | ||||
| +++ b/squashfs-tools/mksquashfs.c | ||||
| @@ -49,10 +49,12 @@ | ||||
| @@ -51,15 +51,22 @@ | ||||
|  #include <sys/wait.h> | ||||
|   | ||||
|  #ifndef linux | ||||
| @@ -27,7 +13,17 @@ | ||||
|  #else | ||||
|  #include <endian.h> | ||||
|  #include <sys/sysinfo.h> | ||||
| @@ -817,6 +819,7 @@ void sigusr1_handler() | ||||
|  #endif | ||||
|   | ||||
| +#ifdef __CYGWIN__ | ||||
| +#include <sys/termios.h> | ||||
| +#define FNM_EXTMATCH  (1 << 5) | ||||
| +#endif | ||||
| + | ||||
|  #ifndef FNM_EXTMATCH | ||||
|  #define FNM_EXTMATCH 0 | ||||
|  #endif | ||||
| @@ -844,6 +851,7 @@ void sigusr1_handler() | ||||
|   | ||||
|  void sigwinch_handler() | ||||
|  { | ||||
| @@ -35,7 +31,7 @@ | ||||
|  	struct winsize winsize; | ||||
|   | ||||
|  	if(ioctl(1, TIOCGWINSZ, &winsize) == -1) { | ||||
| @@ -826,6 +829,9 @@ void sigwinch_handler() | ||||
| @@ -853,6 +861,9 @@ void sigwinch_handler() | ||||
|  		columns = 80; | ||||
|  	} else | ||||
|  		columns = winsize.ws_col; | ||||
| @@ -45,28 +41,27 @@ | ||||
|  } | ||||
|   | ||||
|   | ||||
| @@ -3853,7 +3859,9 @@ void initialise_threads() | ||||
|  		BAD_ERROR("Failed to set signal mask in intialise_threads\n"); | ||||
| @@ -4066,6 +4077,9 @@ void initialise_threads(int readb_mbytes | ||||
|   | ||||
|  	signal(SIGUSR1, sigusr1_handler); | ||||
| - | ||||
|   | ||||
| +#ifdef __CYGWIN__ | ||||
| +	processors = atoi(getenv("NUMBER_OF_PROCESSORS")); | ||||
| +#else | ||||
|  	if(processors == -1) { | ||||
|  #ifndef linux | ||||
|  		int mib[2]; | ||||
| @@ -3875,6 +3883,7 @@ void initialise_threads() | ||||
|  		processors = get_nprocs(); | ||||
| @@ -4087,6 +4101,7 @@ void initialise_threads(int readb_mbytes | ||||
|  		processors = sysconf(_SC_NPROCESSORS_ONLN); | ||||
|  #endif | ||||
|  	} | ||||
| +#endif /* __CYGWIN__ */ | ||||
|   | ||||
|  	if((thread = malloc((2 + processors * 2) * sizeof(pthread_t))) == NULL) | ||||
|  		BAD_ERROR("Out of memory allocating thread descriptors\n"); | ||||
|  	thread = malloc((2 + processors * 2) * sizeof(pthread_t)); | ||||
|  	if(thread == NULL) | ||||
| --- a/squashfs-tools/read_fs.c | ||||
| +++ b/squashfs-tools/read_fs.c | ||||
| @@ -39,9 +39,11 @@ extern unsigned int get_guid(unsigned in | ||||
| @@ -33,9 +33,11 @@ | ||||
|  #include <sys/mman.h> | ||||
|   | ||||
|  #ifndef linux | ||||
| @@ -94,7 +89,7 @@ | ||||
|  #endif | ||||
| --- a/squashfs-tools/unsquashfs.c | ||||
| +++ b/squashfs-tools/unsquashfs.c | ||||
| @@ -112,6 +112,7 @@ void update_progress_bar(); | ||||
| @@ -117,6 +117,7 @@ void update_progress_bar(); | ||||
|   | ||||
|  void sigwinch_handler() | ||||
|  { | ||||
| @@ -102,7 +97,7 @@ | ||||
|  	struct winsize winsize; | ||||
|   | ||||
|  	if(ioctl(1, TIOCGWINSZ, &winsize) == -1) { | ||||
| @@ -121,6 +122,9 @@ void sigwinch_handler() | ||||
| @@ -126,6 +127,9 @@ void sigwinch_handler() | ||||
|  		columns = 80; | ||||
|  	} else | ||||
|  		columns = winsize.ws_col; | ||||
| @@ -112,7 +107,7 @@ | ||||
|  } | ||||
|   | ||||
|   | ||||
| @@ -1787,7 +1791,9 @@ void initialise_threads(int fragment_buf | ||||
| @@ -1807,7 +1811,9 @@ void initialise_threads(int fragment_buf | ||||
|  	if(sigprocmask(SIG_BLOCK, &sigmask, &old_mask) == -1) | ||||
|  		EXIT_UNSQUASH("Failed to set signal mask in intialise_threads" | ||||
|  			"\n"); | ||||
| @@ -123,17 +118,17 @@ | ||||
|  	if(processors == -1) { | ||||
|  #ifndef linux | ||||
|  		int mib[2]; | ||||
| @@ -1809,6 +1815,7 @@ void initialise_threads(int fragment_buf | ||||
|  		processors = get_nprocs(); | ||||
| @@ -1829,6 +1835,7 @@ void initialise_threads(int fragment_buf | ||||
|  		processors = sysconf(_SC_NPROCESSORS_ONLN); | ||||
|  #endif | ||||
|  	} | ||||
| +#endif /* __CYGWIN__ */ | ||||
|   | ||||
|  	if((thread = malloc((3 + processors) * sizeof(pthread_t))) == NULL) | ||||
|  		EXIT_UNSQUASH("Out of memory allocating thread descriptors\n"); | ||||
|  	thread = malloc((3 + processors) * sizeof(pthread_t)); | ||||
|  	if(thread == NULL) | ||||
| --- a/squashfs-tools/unsquashfs.h | ||||
| +++ b/squashfs-tools/unsquashfs.h | ||||
| @@ -45,10 +45,12 @@ | ||||
| @@ -46,15 +46,22 @@ | ||||
|  #include <sys/time.h> | ||||
|   | ||||
|  #ifndef linux | ||||
| @@ -142,7 +137,17 @@ | ||||
|  #define __BIG_ENDIAN BIG_ENDIAN | ||||
|  #define __LITTLE_ENDIAN LITTLE_ENDIAN | ||||
|  #include <sys/sysctl.h> | ||||
| +#endif /* __CYGWIN__ */ | ||||
| +#endif | ||||
|  #else | ||||
|  #include <endian.h> | ||||
|  #include <sys/sysinfo.h> | ||||
|  #endif | ||||
|   | ||||
| +#ifdef __CYGWIN__ | ||||
| +#include <sys/termios.h> | ||||
| +#define FNM_EXTMATCH  (1 << 5) | ||||
| +#endif | ||||
| + | ||||
|  #ifndef FNM_EXTMATCH | ||||
|  #define FNM_EXTMATCH 0 | ||||
|  #endif | ||||
|   | ||||
| @@ -1,91 +0,0 @@ | ||||
| --- a/squashfs-tools/lzma_wrapper.c | ||||
| +++ b/squashfs-tools/lzma_wrapper.c | ||||
| @@ -20,6 +20,8 @@ | ||||
|   */ | ||||
|   | ||||
|  #include <LzmaLib.h> | ||||
| +#include <stdio.h> | ||||
| +#include "compressor.h" | ||||
|   | ||||
|  #define LZMA_HEADER_SIZE	(LZMA_PROPS_SIZE + 8) | ||||
|   | ||||
| @@ -30,9 +32,18 @@ | ||||
|  	size_t props_size = LZMA_PROPS_SIZE, | ||||
|  		outlen = block_size - LZMA_HEADER_SIZE; | ||||
|  	int res; | ||||
| +	int lc; | ||||
| +	int lp; | ||||
| +	int pb; | ||||
| + | ||||
| +	if (!comp_args || sscanf(comp_args, "%d:%d:%d", &lc, &lp, &pb) != 3) { | ||||
| +		lc = 0; | ||||
| +		lp = 2; | ||||
| +		pb = 2; | ||||
| +	} | ||||
|   | ||||
|  	res = LzmaCompress(d + LZMA_HEADER_SIZE, &outlen, s, size, d, | ||||
| -		&props_size, 5, block_size, 3, 0, 2, 32, 1); | ||||
| +		&props_size, 5, block_size, lc, lp, pb, 32, 1); | ||||
|  	 | ||||
|  	if(res == SZ_ERROR_OUTPUT_EOF) { | ||||
|  		/* | ||||
| --- a/squashfs-tools/compressor.c | ||||
| +++ b/squashfs-tools/compressor.c | ||||
| @@ -25,6 +25,7 @@ | ||||
|  #include "compressor.h" | ||||
|  #include "squashfs_fs.h" | ||||
|   | ||||
| +char *comp_args = NULL; | ||||
|  extern int gzip_compress(void **, char *, char *, int, int, int *); | ||||
|  extern int gzip_uncompress(char *, char *, int, int, int *); | ||||
|  extern int lzma_compress(void **, char *, char *, int, int, int *); | ||||
| --- a/squashfs-tools/compressor.h | ||||
| +++ b/squashfs-tools/compressor.h | ||||
| @@ -31,3 +31,4 @@ | ||||
|  extern struct compressor *lookup_compressor(char *); | ||||
|  extern struct compressor *lookup_compressor_id(int); | ||||
|  extern void display_compressors(char *, char *); | ||||
| +extern char *comp_args; | ||||
| --- a/squashfs-tools/mksquashfs.c | ||||
| +++ b/squashfs-tools/mksquashfs.c | ||||
| @@ -4355,6 +4355,12 @@ | ||||
|  				exit(1); | ||||
|  			} | ||||
|  			comp_name = argv[i]; | ||||
| +		} else if(strcmp(argv[i], "-comp_args") == 0) { | ||||
| +			if(++i == argc) { | ||||
| +				ERROR("%s: -comp_args missing compression arguments\n", argv[0]); | ||||
| +				exit(1); | ||||
| +			} | ||||
| +			comp_args = argv[i]; | ||||
|  		} else if(strcmp(argv[i], "-pf") == 0) { | ||||
|  			if(++i == argc) { | ||||
|  				ERROR("%s: -pf missing filename\n", argv[0]); | ||||
| @@ -4574,6 +4580,7 @@ | ||||
|  				"[-e list of exclude\ndirs/files]\n", argv[0]); | ||||
|  			ERROR("\nFilesystem build options:\n"); | ||||
|  			ERROR("-comp <comp>\t\tselect <comp> compression\n"); | ||||
| +			ERROR("-comp_args <comp>\t\tselect compression arguments\n"); | ||||
|  			ERROR("\t\t\tCompressors available:\n"); | ||||
|  			display_compressors("\t\t\t", COMP_DEFAULT); | ||||
|  			ERROR("-b <block_size>\t\tset data block to " | ||||
| @@ -4736,7 +4743,8 @@ | ||||
|  		else if(strcmp(argv[i], "-root-becomes") == 0 || | ||||
|  				strcmp(argv[i], "-sort") == 0 || | ||||
|  				strcmp(argv[i], "-pf") == 0 || | ||||
| -				strcmp(argv[i], "-comp") == 0) | ||||
| +				strcmp(argv[i], "-comp") == 0 || | ||||
| +				strcmp(argv[i], "-comp_args") == 0) | ||||
|  			i++; | ||||
|   | ||||
|  	if(i != argc) { | ||||
| @@ -4761,7 +4769,8 @@ | ||||
|  		else if(strcmp(argv[i], "-root-becomes") == 0 || | ||||
|  				strcmp(argv[i], "-ef") == 0 || | ||||
|  				strcmp(argv[i], "-pf") == 0 || | ||||
| -				strcmp(argv[i], "-comp") == 0) | ||||
| +				strcmp(argv[i], "-comp") == 0 || | ||||
| +				strcmp(argv[i], "-comp_args") == 0) | ||||
|  			i++; | ||||
|   | ||||
|  #ifdef SQUASHFS_TRACE | ||||
| @@ -1,11 +0,0 @@ | ||||
| --- a/squashfs-tools/pseudo.c | ||||
| +++ b/squashfs-tools/pseudo.c | ||||
| @@ -374,7 +374,7 @@ | ||||
|  	} | ||||
|   | ||||
|   | ||||
| -	if(mode > 0777) { | ||||
| +	if(mode > 07777) { | ||||
|  		ERROR("Mode %o out of range\n", mode); | ||||
|  		goto error; | ||||
|  	} | ||||
| @@ -1,6 +1,6 @@ | ||||
| --- a/squashfs-tools/pseudo.c | ||||
| +++ b/squashfs-tools/pseudo.c | ||||
| @@ -31,6 +31,7 @@ | ||||
| @@ -32,6 +32,7 @@ | ||||
|  #include <stdlib.h> | ||||
|  #include <sys/types.h> | ||||
|  #include <sys/wait.h> | ||||
|   | ||||
							
								
								
									
										926
									
								
								tools/squashfs4/patches/160-expose_lzma_xz_options.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										926
									
								
								tools/squashfs4/patches/160-expose_lzma_xz_options.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,926 @@ | ||||
| --- /dev/null | ||||
| +++ b/squashfs-tools/lzma_xz_options.h | ||||
| @@ -0,0 +1,112 @@ | ||||
| +#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 | ||||
| +#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) | ||||
		Reference in New Issue
	
	Block a user
	 Felix Fietkau
					Felix Fietkau