Index: squashfs4.0/squashfs-tools/mksquashfs.c =================================================================== --- squashfs4.0.orig/squashfs-tools/mksquashfs.c 2009-04-05 23:22:48.000000000 +0200 +++ squashfs4.0/squashfs-tools/mksquashfs.c 2009-09-14 17:21:46.210480446 +0200 @@ -64,6 +64,18 @@ #include "global.h" #include "sort.h" #include "pseudo.h" +#include "uncompress.h" + +#ifdef USE_LZMA +#include +#include +#define LZMA_DEFAULT_LEVEL 5 +#define LZMA_DEFAULT_DICT 0 +#define LZMA_DEFAULT_LC 1 +#define LZMA_DEFAULT_LP 2 +#define LZMA_DEFAULT_PB 2 +#define LZMA_DEFAULT_FB 32 +#endif #ifdef SQUASHFS_TRACE #define TRACE(s, args...) do { \ @@ -830,6 +842,19 @@ rotate = (rotate + 1) % 4; } +#ifdef USE_LZMA +static void *lzma_malloc(void *p, size_t size) +{ + (void)p; + return malloc(size); +} +static void lzma_free(void *p, void *addr) +{ + (void)p; + free(addr); +} +static ISzAlloc lzma_alloc = { lzma_malloc, lzma_free }; +#endif unsigned int mangle2(z_stream **strm, char *d, char *s, int size, int block_size, int uncompressed, int data_block) @@ -841,6 +866,50 @@ if(uncompressed) goto notcompressed; +#ifdef USE_LZMA + if (compression == LZMA_COMPRESSION) { + size_t outsize = block_size - LZMA_PROPS_SIZE; + size_t propsize = LZMA_PROPS_SIZE; + CLzmaEncProps props; + + LzmaEncProps_Init(&props); + props.level = LZMA_DEFAULT_LEVEL; + props.dictSize = LZMA_DEFAULT_DICT; + props.lc = LZMA_DEFAULT_LC; + props.lp = LZMA_DEFAULT_LP; + props.pb = LZMA_DEFAULT_PB; + props.fb = LZMA_DEFAULT_FB; + props.numThreads = 1; + + res = LzmaEncode((unsigned char *) d + LZMA_PROPS_SIZE, &outsize, + (unsigned char *) s, size, + &props, (unsigned char *) d, &propsize, + 1, NULL, &lzma_alloc, &lzma_alloc); + switch(res) { + case SZ_OK: + outsize += LZMA_PROPS_SIZE; + break; + case SZ_ERROR_DATA: + BAD_ERROR("lzma::compress failed, data error\n"); + break; + case SZ_ERROR_MEM: + BAD_ERROR("lzma::compress failed, memory allocation error\n"); + break; + case SZ_ERROR_PARAM: + BAD_ERROR("lzma::compress failed, invalid parameters\n"); + break; + case SZ_ERROR_OUTPUT_EOF: + goto notcompressed; + /* should not happen */ + default: + BAD_ERROR("lzma::compress failed, unknown error (%d)\n", res); + break; + } + + return outsize; + } +#endif + if(stream == NULL) { if((stream = *strm = malloc(sizeof(z_stream))) == NULL) BAD_ERROR("mangle::compress failed, not enough " @@ -1669,17 +1738,17 @@ else data = read_from_disk(start_block, size); - res = uncompress((unsigned char *) buffer->data, &bytes, + res = uncompress_wrapper((unsigned char *) buffer->data, &bytes, (const unsigned char *) data, size); if(res != Z_OK) { if(res == Z_MEM_ERROR) - BAD_ERROR("zlib::uncompress failed, not enough " + BAD_ERROR("uncompress failed, not enough " "memory\n"); else if(res == Z_BUF_ERROR) - BAD_ERROR("zlib::uncompress failed, not enough " + BAD_ERROR("uncompress failed, not enough " "room in output buffer\n"); else - BAD_ERROR("zlib::uncompress failed," + BAD_ERROR("uncompress failed," " unknown error %d\n", res); } } else if(compressed_buffer) @@ -4282,6 +4351,10 @@ argv[0]); exit(1); } +#ifdef USE_LZMA + } else if(strcmp(argv[i], "-lzma") == 0) { + compression = LZMA_COMPRESSION; +#endif } else if(strcmp(argv[i], "-ef") == 0) { if(++i == argc) { ERROR("%s: -ef missing filename\n", argv[0]); @@ -4410,6 +4483,9 @@ ERROR("-b \t\tset data block to " ". Default %d bytes\n", SQUASHFS_FILE_SIZE); +#ifdef USE_LZMA + ERROR("-lzma Enable LZMA compression\n"); +#endif ERROR("-processors \tUse processors." " By default will use number of\n"); ERROR("\t\t\tprocessors available\n"); @@ -4804,7 +4880,7 @@ sBlk.bytes_used = bytes; /* Only compression supported */ - sBlk.compression = ZLIB_COMPRESSION; + sBlk.compression = compression; /* Xattrs are not currently supported */ sBlk.xattr_table_start = SQUASHFS_INVALID_BLK; Index: squashfs4.0/squashfs-tools/squashfs_fs.h =================================================================== --- squashfs4.0.orig/squashfs-tools/squashfs_fs.h 2009-03-18 03:50:20.000000000 +0100 +++ squashfs4.0/squashfs-tools/squashfs_fs.h 2009-09-14 17:20:36.310480350 +0200 @@ -229,6 +229,7 @@ typedef long long squashfs_inode_t; #define ZLIB_COMPRESSION 1 +#define LZMA_COMPRESSION 2 struct squashfs_super_block { unsigned int s_magic; Index: squashfs4.0/squashfs-tools/Makefile =================================================================== --- squashfs4.0.orig/squashfs-tools/Makefile 2009-04-05 04:03:36.000000000 +0200 +++ squashfs4.0/squashfs-tools/Makefile 2009-09-14 17:20:36.310480350 +0200 @@ -4,14 +4,20 @@ CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2 +ifdef USE_LZMA + LZMA_CFLAGS = -DUSE_LZMA + LZMA_LIB = -llzma + CFLAGS += $(LZMA_CFLAGS) +endif + all: mksquashfs unsquashfs -mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o - $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o -lz -lpthread -lm -o $@ +mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o uncompress.o + $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o uncompress.o -lz -lpthread -lm $(LZMA_LIB) -o $@ -mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h Makefile +mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h uncompress.h Makefile -read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h Makefile +read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h uncompress.h Makefile sort.o: sort.c squashfs_fs.h global.h sort.h Makefile @@ -19,18 +25,20 @@ pseudo.o: pseudo.c pseudo.h Makefile -unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o - $(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o -lz -lpthread -lm -o $@ +uncompress.o: uncompress.c uncompress.h + +unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o uncompress.o + $(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o uncompress.o -lz -lpthread -lm $(LZMA_LIB) -o $@ -unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h Makefile +unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h uncompress.h Makefile -unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h Makefile +unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h uncompress.h Makefile -unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h Makefile +unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h uncompress.h Makefile -unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h Makefile +unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h uncompress.h Makefile -unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h Makefile +unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h uncompress.h Makefile clean: -rm -f *.o mksquashfs unsquashfs Index: squashfs4.0/squashfs-tools/read_fs.c =================================================================== --- squashfs4.0.orig/squashfs-tools/read_fs.c 2009-03-31 06:23:14.000000000 +0200 +++ squashfs4.0/squashfs-tools/read_fs.c 2009-09-14 17:20:36.310480350 +0200 @@ -51,6 +51,7 @@ #include "squashfs_swap.h" #include "read_fs.h" #include "global.h" +#include "uncompress.h" #include @@ -83,17 +84,17 @@ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); read_destination(fd, start + offset, c_byte, buffer); - res = uncompress(block, &bytes, (const unsigned char *) buffer, - c_byte); + res = uncompress_wrapper(block, &bytes, + (const unsigned char *) buffer, c_byte); if(res != Z_OK) { if(res == Z_MEM_ERROR) - ERROR("zlib::uncompress failed, not enough " + ERROR("uncompress failed, not enough " "memory\n"); else if(res == Z_BUF_ERROR) - ERROR("zlib::uncompress failed, not enough " + ERROR("uncompress failed, not enough " "room in output buffer\n"); else - ERROR("zlib::uncompress failed, unknown error " + ERROR("uncompress failed, unknown error " "%d\n", res); return 0; } Index: squashfs4.0/squashfs-tools/unsquashfs.c =================================================================== --- squashfs4.0.orig/squashfs-tools/unsquashfs.c 2009-04-05 23:23:06.000000000 +0200 +++ squashfs4.0/squashfs-tools/unsquashfs.c 2009-09-14 17:20:36.310480350 +0200 @@ -24,6 +24,7 @@ #include "unsquashfs.h" #include "squashfs_swap.h" #include "squashfs_compat.h" +#include "uncompress.h" #include "read_fs.h" struct cache *fragment_cache, *data_cache; @@ -597,18 +598,17 @@ if(read_bytes(start + offset, c_byte, buffer) == FALSE) goto failed; - res = uncompress((unsigned char *) block, &bytes, + res = uncompress_wrapper((unsigned char *) block, &bytes, (const unsigned char *) buffer, c_byte); - if(res != Z_OK) { if(res == Z_MEM_ERROR) - ERROR("zlib::uncompress failed, not enough " + ERROR("uncompress failed, not enough " "memory\n"); else if(res == Z_BUF_ERROR) - ERROR("zlib::uncompress failed, not enough " + ERROR("uncompress failed, not enough " "room in output buffer\n"); else - ERROR("zlib::uncompress failed, unknown error " + ERROR("uncompress failed, unknown error " "%d\n", res); goto failed; } @@ -645,18 +645,17 @@ if(read_bytes(start, c_byte, data) == FALSE) goto failed; - res = uncompress((unsigned char *) block, &bytes, + res = uncompress_wrapper((unsigned char *) block, &bytes, (const unsigned char *) data, c_byte); - if(res != Z_OK) { if(res == Z_MEM_ERROR) - ERROR("zlib::uncompress failed, not enough " + ERROR("uncompress failed, not enough " "memory\n"); else if(res == Z_BUF_ERROR) - ERROR("zlib::uncompress failed, not enough " + ERROR("uncompress failed, not enough " "room in output buffer\n"); else - ERROR("zlib::uncompress failed, unknown error " + ERROR("uncompress failed, unknown error " "%d\n", res); goto failed; } @@ -1459,7 +1458,7 @@ s_ops.read_inode = read_inode_4; s_ops.read_uids_guids = read_uids_guids_4; memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4)); - return TRUE; + goto done; } /* @@ -1548,6 +1547,9 @@ goto failed_mount; } +done: + compression = sBlk.compression; + return TRUE; failed_mount: @@ -1710,19 +1712,19 @@ int res; unsigned long bytes = block_size; - res = uncompress((unsigned char *) tmp, &bytes, + res = uncompress_wrapper((unsigned char *) tmp, &bytes, (const unsigned char *) entry->data, SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size)); if(res != Z_OK) { if(res == Z_MEM_ERROR) - ERROR("zlib::uncompress failed, not enough" + ERROR("uncompress failed, not enough" "memory\n"); else if(res == Z_BUF_ERROR) - ERROR("zlib::uncompress failed, not enough " + ERROR("uncompress failed, not enough " "room in output buffer\n"); else - ERROR("zlib::uncompress failed, unknown error " + ERROR("uncompress failed, unknown error " "%d\n", res); } else memcpy(entry->data, tmp, bytes); Index: squashfs4.0/squashfs-tools/mksquashfs.h =================================================================== --- squashfs4.0.orig/squashfs-tools/mksquashfs.h 2009-02-19 19:31:08.000000000 +0100 +++ squashfs4.0/squashfs-tools/mksquashfs.h 2009-09-14 17:20:36.310480350 +0200 @@ -41,4 +41,9 @@ #define SQUASHFS_SWAP_LONG_LONGS(s, d, n) \ memcpy(d, s, n * sizeof(long long)) #endif + +extern int uncompress_wrapper(unsigned char *dest, unsigned long *dest_len, + const unsigned char *src, unsigned long src_len); + + #endif Index: squashfs4.0/squashfs-tools/uncompress.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ squashfs4.0/squashfs-tools/uncompress.c 2009-09-14 17:20:36.310480350 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2009 Felix Fietkau + * + * 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. + * + * uncompress.c + */ + + + +#ifdef USE_LZMA +#include +#endif +#include +#include "squashfs_fs.h" + +/* compression algorithm */ +int compression = ZLIB_COMPRESSION; + + +int uncompress_wrapper(unsigned char *dest, unsigned long *dest_len, + const unsigned char *src, unsigned long src_len) +{ + int res; + +#ifdef USE_LZMA + if (compression == LZMA_COMPRESSION) { + size_t slen = src_len - LZMA_PROPS_SIZE; + res = LzmaUncompress((unsigned char *)dest, dest_len, + (const unsigned char *) src + LZMA_PROPS_SIZE, &slen, + (const unsigned char *) src, LZMA_PROPS_SIZE); + switch(res) { + case SZ_OK: + res = Z_OK; + break; + case SZ_ERROR_MEM: + res = Z_MEM_ERROR; + break; + } + } else +#endif + res = uncompress(dest, dest_len, src, src_len); + return res; +} + + Index: squashfs4.0/squashfs-tools/uncompress.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ squashfs4.0/squashfs-tools/uncompress.h 2009-09-14 17:20:36.310480350 +0200 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2009 Felix Fietkau + * + * 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. + * + * uncompress.h + */ + +#ifdef USE_LZMA +#include +#endif + +extern int compression; +extern int uncompress_wrapper(unsigned char *dest, unsigned long *dest_len, + const unsigned char *src, unsigned long src_len); + +