squashfs4: add lzma support (kernel support still missing)
[openwrt.git] / tools / squashfs4 / patches / 110-lzma.patch
1 --- a/squashfs-tools/mksquashfs.c
2 +++ b/squashfs-tools/mksquashfs.c
3 @@ -64,6 +64,18 @@
4  #include "global.h"
5  #include "sort.h"
6  #include "pseudo.h"
7 +#include "uncompress.h"
8 +
9 +#ifdef USE_LZMA
10 +#include <LzmaEnc.h>
11 +#include <LzmaDec.h>
12 +#define LZMA_DEFAULT_LEVEL     5
13 +#define LZMA_DEFAULT_DICT      0
14 +#define LZMA_DEFAULT_LC        1
15 +#define LZMA_DEFAULT_LP        2
16 +#define LZMA_DEFAULT_PB 2
17 +#define LZMA_DEFAULT_FB 32
18 +#endif
19  
20  #ifdef SQUASHFS_TRACE
21  #define TRACE(s, args...)      do { \
22 @@ -830,6 +842,19 @@ void sigalrm_handler()
23         rotate = (rotate + 1) % 4;
24  }
25  
26 +#ifdef USE_LZMA
27 +static void *lzma_malloc(void *p, size_t size)
28 +{
29 +       (void)p;
30 +       return malloc(size);
31 +}
32 +static void lzma_free(void *p, void *addr)
33 +{
34 +       (void)p;
35 +       free(addr);
36 +}
37 +static ISzAlloc lzma_alloc = { lzma_malloc, lzma_free };
38 +#endif
39  
40  unsigned int mangle2(z_stream **strm, char *d, char *s, int size,
41         int block_size, int uncompressed, int data_block)
42 @@ -841,6 +866,48 @@ unsigned int mangle2(z_stream **strm, ch
43         if(uncompressed)
44                 goto notcompressed;
45  
46 +#ifdef USE_LZMA
47 +       if (compression == LZMA_COMPRESSION) {
48 +               size_t outsize = block_size - LZMA_PROPS_SIZE;
49 +               size_t propsize = LZMA_PROPS_SIZE;
50 +               CLzmaEncProps props;
51 +
52 +               LzmaEncProps_Init(&props);
53 +               props.level = LZMA_DEFAULT_LEVEL;
54 +               props.dictSize = LZMA_DEFAULT_DICT;
55 +               props.lc = LZMA_DEFAULT_LC;
56 +               props.lp = LZMA_DEFAULT_LP;
57 +               props.pb = LZMA_DEFAULT_PB;
58 +               props.fb = LZMA_DEFAULT_FB;
59 +               props.numThreads = 1;
60 +
61 +               res = LzmaEncode((unsigned char *) d + LZMA_PROPS_SIZE, &outsize,
62 +                       (unsigned char *) s, size,
63 +                       &props, (unsigned char *) d, &propsize,
64 +                       1, NULL, &lzma_alloc, &lzma_alloc);
65 +               switch(res) {
66 +               case SZ_OK:
67 +                       outsize += LZMA_PROPS_SIZE;
68 +                       break;
69 +               case SZ_ERROR_DATA:
70 +                       BAD_ERROR("lzma::compress failed, data error\n");
71 +                       break;
72 +               case SZ_ERROR_MEM:
73 +                       BAD_ERROR("lzma::compress failed, memory allocation error\n");
74 +                       break;
75 +               case SZ_ERROR_PARAM:
76 +                       BAD_ERROR("lzma::compress failed, invalid parameters\n");
77 +                       break;
78 +               /* should not happen */
79 +               default:
80 +                       BAD_ERROR("lzma::compress failed, unknown error\n");
81 +                       break;
82 +               }
83 +
84 +               return outsize;
85 +       }
86 +#endif
87 +
88         if(stream == NULL) {
89                 if((stream = *strm = malloc(sizeof(z_stream))) == NULL)
90                         BAD_ERROR("mangle::compress failed, not enough "
91 @@ -1669,17 +1736,17 @@ struct file_buffer *get_fragment(struct 
92                 else
93                         data = read_from_disk(start_block, size);
94  
95 -               res = uncompress((unsigned char *) buffer->data, &bytes,
96 +               res = uncompress_wrapper((unsigned char *) buffer->data, &bytes,
97                         (const unsigned char *) data, size);
98                 if(res != Z_OK) {
99                         if(res == Z_MEM_ERROR)
100 -                               BAD_ERROR("zlib::uncompress failed, not enough "
101 +                               BAD_ERROR("uncompress failed, not enough "
102                                         "memory\n");
103                         else if(res == Z_BUF_ERROR)
104 -                               BAD_ERROR("zlib::uncompress failed, not enough "
105 +                               BAD_ERROR("uncompress failed, not enough "
106                                         "room in output buffer\n");
107                         else
108 -                               BAD_ERROR("zlib::uncompress failed,"
109 +                               BAD_ERROR("uncompress failed,"
110                                         "  unknown error %d\n", res);
111                 }
112         } else if(compressed_buffer)
113 @@ -4282,6 +4349,10 @@ int main(int argc, char *argv[])
114                                         argv[0]);
115                                 exit(1);
116                         }
117 +#ifdef USE_LZMA
118 +               } else if(strcmp(argv[i], "-lzma") == 0) {
119 +                       compression = LZMA_COMPRESSION;
120 +#endif
121                 } else if(strcmp(argv[i], "-ef") == 0) {
122                         if(++i == argc) {
123                                 ERROR("%s: -ef missing filename\n", argv[0]);
124 @@ -4410,6 +4481,9 @@ printOptions:
125                         ERROR("-b <block_size>\t\tset data block to "
126                                 "<block_size>.  Default %d bytes\n",
127                                 SQUASHFS_FILE_SIZE);
128 +#ifdef USE_LZMA
129 +                       ERROR("-lzma Enable LZMA compression\n");
130 +#endif
131                         ERROR("-processors <number>\tUse <number> processors."
132                                 "  By default will use number of\n");
133                         ERROR("\t\t\tprocessors available\n");
134 @@ -4804,7 +4878,7 @@ restore_filesystem:
135         sBlk.bytes_used = bytes;
136  
137         /* Only compression supported */
138 -       sBlk.compression = ZLIB_COMPRESSION;
139 +       sBlk.compression = compression;
140  
141         /* Xattrs are not currently supported */
142         sBlk.xattr_table_start = SQUASHFS_INVALID_BLK;
143 --- a/squashfs-tools/squashfs_fs.h
144 +++ b/squashfs-tools/squashfs_fs.h
145 @@ -229,6 +229,7 @@ typedef long long           squashfs_block_t;
146  typedef long long              squashfs_inode_t;
147  
148  #define ZLIB_COMPRESSION       1
149 +#define LZMA_COMPRESSION       2
150  
151  struct squashfs_super_block {
152         unsigned int            s_magic;
153 --- a/squashfs-tools/Makefile
154 +++ b/squashfs-tools/Makefile
155 @@ -4,14 +4,20 @@ INCLUDEDIR = .
156  
157  CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2
158  
159 +ifdef USE_LZMA
160 +  LZMA_CFLAGS = -DUSE_LZMA
161 +  LZMA_LIB = -llzma
162 +  CFLAGS += $(LZMA_CFLAGS)
163 +endif
164 +
165  all: mksquashfs unsquashfs
166  
167 -mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o
168 -       $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o -lz -lpthread -lm -o $@
169 +mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o uncompress.o
170 +       $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o uncompress.o -lz -lpthread -lm $(LZMA_LIB) -o $@
171  
172 -mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h Makefile
173 +mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h uncompress.h Makefile
174  
175 -read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h Makefile
176 +read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h uncompress.h Makefile
177  
178  sort.o: sort.c squashfs_fs.h global.h sort.h Makefile
179  
180 @@ -19,18 +25,20 @@ swap.o: swap.c Makefile
181  
182  pseudo.o: pseudo.c pseudo.h Makefile
183  
184 -unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o
185 -       $(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o -lz -lpthread -lm -o $@
186 +uncompress.o: uncompress.c uncompress.h
187 +
188 +unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o uncompress.o
189 +       $(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 $@
190  
191 -unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h Makefile
192 +unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h uncompress.h Makefile
193  
194 -unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h Makefile
195 +unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h uncompress.h Makefile
196  
197 -unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h Makefile
198 +unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h uncompress.h Makefile
199  
200 -unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h Makefile
201 +unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h uncompress.h Makefile
202  
203 -unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h Makefile
204 +unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h uncompress.h Makefile
205  
206  clean:
207         -rm -f *.o mksquashfs unsquashfs
208 --- a/squashfs-tools/read_fs.c
209 +++ b/squashfs-tools/read_fs.c
210 @@ -51,6 +51,7 @@ extern unsigned int get_guid(unsigned in
211  #include "squashfs_swap.h"
212  #include "read_fs.h"
213  #include "global.h"
214 +#include "uncompress.h"
215  
216  #include <stdlib.h>
217  
218 @@ -83,17 +84,17 @@ int read_block(int fd, long long start, 
219                 c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
220                 read_destination(fd, start + offset, c_byte, buffer);
221  
222 -               res = uncompress(block, &bytes, (const unsigned char *) buffer,
223 -                       c_byte);
224 +               res = uncompress_wrapper(block, &bytes,
225 +                       (const unsigned char *) buffer, c_byte);
226                 if(res != Z_OK) {
227                         if(res == Z_MEM_ERROR)
228 -                               ERROR("zlib::uncompress failed, not enough "
229 +                               ERROR("uncompress failed, not enough "
230                                         "memory\n");
231                         else if(res == Z_BUF_ERROR)
232 -                               ERROR("zlib::uncompress failed, not enough "
233 +                               ERROR("uncompress failed, not enough "
234                                         "room in output buffer\n");
235                         else
236 -                               ERROR("zlib::uncompress failed, unknown error "
237 +                               ERROR("uncompress failed, unknown error "
238                                         "%d\n", res);
239                         return 0;
240                 }
241 --- a/squashfs-tools/unsquashfs.c
242 +++ b/squashfs-tools/unsquashfs.c
243 @@ -24,6 +24,7 @@
244  #include "unsquashfs.h"
245  #include "squashfs_swap.h"
246  #include "squashfs_compat.h"
247 +#include "uncompress.h"
248  #include "read_fs.h"
249  
250  struct cache *fragment_cache, *data_cache;
251 @@ -597,18 +598,17 @@ int read_block(long long start, long lon
252                 if(read_bytes(start + offset, c_byte, buffer) == FALSE)
253                         goto failed;
254  
255 -               res = uncompress((unsigned char *) block, &bytes,
256 +               res = uncompress_wrapper((unsigned char *) block, &bytes,
257                         (const unsigned char *) buffer, c_byte);
258 -
259                 if(res != Z_OK) {
260                         if(res == Z_MEM_ERROR)
261 -                               ERROR("zlib::uncompress failed, not enough "
262 +                               ERROR("uncompress failed, not enough "
263                                         "memory\n");
264                         else if(res == Z_BUF_ERROR)
265 -                               ERROR("zlib::uncompress failed, not enough "
266 +                               ERROR("uncompress failed, not enough "
267                                         "room in output buffer\n");
268                         else
269 -                               ERROR("zlib::uncompress failed, unknown error "
270 +                               ERROR("uncompress failed, unknown error "
271                                         "%d\n", res);
272                         goto failed;
273                 }
274 @@ -645,18 +645,17 @@ int read_data_block(long long start, uns
275                 if(read_bytes(start, c_byte, data) == FALSE)
276                         goto failed;
277  
278 -               res = uncompress((unsigned char *) block, &bytes,
279 +               res = uncompress_wrapper((unsigned char *) block, &bytes,
280                         (const unsigned char *) data, c_byte);
281 -
282                 if(res != Z_OK) {
283                         if(res == Z_MEM_ERROR)
284 -                               ERROR("zlib::uncompress failed, not enough "
285 +                               ERROR("uncompress failed, not enough "
286                                         "memory\n");
287                         else if(res == Z_BUF_ERROR)
288 -                               ERROR("zlib::uncompress failed, not enough "
289 +                               ERROR("uncompress failed, not enough "
290                                         "room in output buffer\n");
291                         else
292 -                               ERROR("zlib::uncompress failed, unknown error "
293 +                               ERROR("uncompress failed, unknown error "
294                                         "%d\n", res);
295                         goto failed;
296                 }
297 @@ -1459,7 +1458,7 @@ int read_super(char *source)
298                 s_ops.read_inode = read_inode_4;
299                 s_ops.read_uids_guids = read_uids_guids_4;
300                 memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4));
301 -               return TRUE;
302 +               goto done;
303         }
304  
305         /*
306 @@ -1548,6 +1547,9 @@ int read_super(char *source)
307                 goto failed_mount;
308         }
309  
310 +done:
311 +       compression = sBlk.compression;
312 +
313         return TRUE;
314  
315  failed_mount:
316 @@ -1710,19 +1712,19 @@ void *deflator(void *arg)
317                 int res;
318                 unsigned long bytes = block_size;
319  
320 -               res = uncompress((unsigned char *) tmp, &bytes,
321 +               res = uncompress_wrapper((unsigned char *) tmp, &bytes,
322                         (const unsigned char *) entry->data,
323                         SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size));
324  
325                 if(res != Z_OK) {
326                         if(res == Z_MEM_ERROR)
327 -                               ERROR("zlib::uncompress failed, not enough"
328 +                               ERROR("uncompress failed, not enough"
329                                         "memory\n");
330                         else if(res == Z_BUF_ERROR)
331 -                               ERROR("zlib::uncompress failed, not enough "
332 +                               ERROR("uncompress failed, not enough "
333                                         "room in output buffer\n");
334                         else
335 -                               ERROR("zlib::uncompress failed, unknown error "
336 +                               ERROR("uncompress failed, unknown error "
337                                         "%d\n", res);
338                 } else
339                         memcpy(entry->data, tmp, bytes);
340 --- a/squashfs-tools/mksquashfs.h
341 +++ b/squashfs-tools/mksquashfs.h
342 @@ -41,4 +41,9 @@
343  #define SQUASHFS_SWAP_LONG_LONGS(s, d, n) \
344                                         memcpy(d, s, n * sizeof(long long))
345  #endif
346 +
347 +extern int uncompress_wrapper(unsigned char *dest, unsigned long *dest_len,
348 +    const unsigned char *src, unsigned long src_len);
349 +
350 +
351  #endif
352 --- /dev/null
353 +++ b/squashfs-tools/uncompress.c
354 @@ -0,0 +1,58 @@
355 +/*
356 + * Copyright (c) 2009  Felix Fietkau <nbd@openwrt.org>
357 + *
358 + * This program is free software; you can redistribute it and/or
359 + * modify it under the terms of the GNU General Public License
360 + * as published by the Free Software Foundation; either version 2,
361 + * or (at your option) any later version.
362 + *
363 + * This program is distributed in the hope that it will be useful,
364 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
365 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
366 + * GNU General Public License for more details.
367 + *
368 + * You should have received a copy of the GNU General Public License
369 + * along with this program; if not, write to the Free Software
370 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
371 + *
372 + * uncompress.c
373 + */
374 +
375 +
376 +
377 +#ifdef USE_LZMA
378 +#include <LzmaLib.h>
379 +#endif
380 +#include <zlib.h>
381 +#include "squashfs_fs.h"
382 +
383 +/* compression algorithm */
384 +int compression = ZLIB_COMPRESSION;
385 +
386 +
387 +int uncompress_wrapper(unsigned char *dest, unsigned long *dest_len,
388 +       const unsigned char *src, unsigned long src_len)
389 +{
390 +       int res;
391 +
392 +#ifdef USE_LZMA
393 +       if (compression == LZMA_COMPRESSION) {
394 +               size_t slen = src_len - LZMA_PROPS_SIZE;
395 +               res = LzmaUncompress((unsigned char *)dest, dest_len,
396 +                       (const unsigned char *) src + LZMA_PROPS_SIZE, &slen,
397 +                       (const unsigned char *) src, LZMA_PROPS_SIZE);
398 +               switch(res) {
399 +               case SZ_OK:
400 +                       res = Z_OK;
401 +                       break;
402 +               case SZ_ERROR_MEM:
403 +                       res = Z_MEM_ERROR;
404 +                       break;
405 +               }
406 +       } else
407 +#endif
408 +       res = uncompress(dest, dest_len, src, src_len);
409 +       return res;
410 +}
411 +
412 +
413 --- /dev/null
414 +++ b/squashfs-tools/uncompress.h
415 @@ -0,0 +1,29 @@
416 +/*
417 + * Copyright (c) 2009  Felix Fietkau <nbd@openwrt.org>
418 + *
419 + * This program is free software; you can redistribute it and/or
420 + * modify it under the terms of the GNU General Public License
421 + * as published by the Free Software Foundation; either version 2,
422 + * or (at your option) any later version.
423 + *
424 + * This program is distributed in the hope that it will be useful,
425 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
426 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
427 + * GNU General Public License for more details.
428 + *
429 + * You should have received a copy of the GNU General Public License
430 + * along with this program; if not, write to the Free Software
431 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
432 + *
433 + * uncompress.h
434 + */
435 +
436 +#ifdef USE_LZMA
437 +#include <LzmaLib.h>
438 +#endif
439 +
440 +extern int compression;
441 +extern int uncompress_wrapper(unsigned char *dest, unsigned long *dest_len,
442 +    const unsigned char *src, unsigned long src_len);
443 +
444 +