tools/squashfs4: refresh patches
[openwrt.git] / tools / squashfs4 / patches / 160-expose_lzma_xz_options.patch
1 --- /dev/null
2 +++ b/squashfs-tools/lzma_xz_options.h
3 @@ -0,0 +1,115 @@
4 +#ifndef LZMA_XZ_OPTIONS_H
5 +#define LZMA_XZ_OPTIONS_H
6 +/*
7 + * Copyright (c) 2011
8 + * Jonas Gorski <jonas.gorski@gmail.com>
9 + *
10 + * This program is free software; you can redistribute it and/or
11 + * modify it under the terms of the GNU General Public License
12 + * as published by the Free Software Foundation; either version 2,
13 + * or (at your option) any later version.
14 + *
15 + * This program is distributed in the hope that it will be useful,
16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 + * GNU General Public License for more details.
19 + *
20 + * You should have received a copy of the GNU General Public License
21 + * along with this program; if not, write to the Free Software
22 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 + *
24 + * lzma_options.h
25 + */
26 +
27 +#include <stdint.h>
28 +
29 +#ifndef linux
30 +#ifdef __FreeBSD__
31 +#include <machine/endian.h>
32 +#endif
33 +#define __BYTE_ORDER BYTE_ORDER
34 +#define __BIG_ENDIAN BIG_ENDIAN
35 +#define __LITTLE_ENDIAN LITTLE_ENDIAN
36 +#else
37 +#include <endian.h>
38 +#endif
39 +
40 +
41 +
42 +struct lzma_opts {
43 +       uint32_t flags;
44 +#define LZMA_OPT_FLT_MASK      0xffff
45 +#define LZMA_OPT_PRE_OFF       16
46 +#define LZMA_OPT_PRE_MASK      (0xf << LZMA_OPT_PRE_OFF)
47 +#define LZMA_OPT_EXTREME       20      
48 +       uint16_t bit_opts;
49 +#define LZMA_OPT_LC_OFF                0
50 +#define LZMA_OPT_LC_MASK       (0x7 << LZMA_OPT_LC_OFF)
51 +#define LZMA_OPT_LP_OFF                3
52 +#define LZMA_OPT_LP_MASK       (0x7 << LZMA_OPT_LP_OFF)
53 +#define LZMA_OPT_PB_OFF                6
54 +#define LZMA_OPT_PB_MASK       (0x7 << LZMA_OPT_PB_OFF)
55 +       uint16_t fb;
56 +       uint32_t dict_size;
57 +};
58 +
59 +#if __BYTE_ORDER == __BIG_ENDIAN
60 +extern unsigned int inswap_le32(unsigned int);
61 +
62 +#define SQUASHFS_INSWAP_LZMA_COMP_OPTS(s) { \
63 +       (s)->flags = inswap_le32((s)->flags); \
64 +       (s)->bit_opts = inswap_le16((s)->bit_opts); \
65 +       (s)->fb = inswap_le16((s)->fb); \
66 +       (s)->dict_size = inswap_le32((s)->dict_size); \
67 +}
68 +#else
69 +#define SQUASHFS_INSWAP_LZMA_COMP_OPTS(s)
70 +#endif
71 +
72 +#define MEMLIMIT (32 * 1024 * 1024)
73 +
74 +#define LZMA_OPT_LC_MIN                0
75 +#define LZMA_OPT_LC_MAX                4
76 +#define LZMA_OPT_LC_DEFAULT    3
77 +
78 +#define LZMA_OPT_LP_MIN                0
79 +#define LZMA_OPT_LP_MAX                4
80 +#define LZMA_OPT_LP_DEFAULT    0
81 +
82 +#define LZMA_OPT_PB_MIN                0
83 +#define LZMA_OPT_PB_MAX                4
84 +#define LZMA_OPT_PB_DEFAULT    2
85 +
86 +#define LZMA_OPT_FB_MIN                5
87 +#define LZMA_OPT_FB_MAX                273
88 +#define LZMA_OPT_FB_DEFAULT    64
89 +
90 +enum {
91 +       LZMA_OPT_LZMA = 1,
92 +       LZMA_OPT_XZ
93 +};
94 +
95 +struct lzma_xz_options {
96 +       int preset;
97 +       int extreme;
98 +       int lc;
99 +       int lp;
100 +       int pb;
101 +       int fb;
102 +       int dict_size;
103 +       int flags;
104 +};
105 +
106 +struct lzma_xz_options *lzma_xz_get_options(void);
107 +
108 +int lzma_xz_options(char *argv[], int argc, int lzmaver);
109 +
110 +int lzma_xz_options_post(int block_size, int lzmaver);
111 +
112 +void *lzma_xz_dump_options(int block_size, int *size, int flags);
113 +
114 +int lzma_xz_extract_options(int block_size, void *buffer, int size, int lzmaver);
115 +
116 +void lzma_xz_usage(int lzmaver);
117 +
118 +#endif
119 --- /dev/null
120 +++ b/squashfs-tools/lzma_xz_options.c
121 @@ -0,0 +1,365 @@
122 +/*
123 + * Copyright (c) 2011
124 + * Jonas Gorski <jonas.gorski@gmail.com>
125 + *
126 + * This program is free software; you can redistribute it and/or
127 + * modify it under the terms of the GNU General Public License
128 + * as published by the Free Software Foundation; either version 2,
129 + * or (at your option) any later version.
130 + *
131 + * This program is distributed in the hope that it will be useful,
132 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
133 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
134 + * GNU General Public License for more details.
135 + *
136 + * You should have received a copy of the GNU General Public License
137 + * along with this program; if not, write to the Free Software
138 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
139 + *
140 + * lzma_options.c
141 + * 
142 + * Common options for LZMA1 and 2 compressors. Based on xz_wrapper.c
143 + */
144 +
145 +#include <stdio.h>
146 +#include <string.h>
147 +#include <stdlib.h>
148 +
149 +#include <lzma.h>
150 +
151 +#include "lzma_xz_options.h"
152 +
153 +static const char const *lzmaver_str[] = { "", "lzma", "xz" };
154 +
155 +static struct lzma_xz_options options = {
156 +       .flags          = 0,
157 +       .preset         = 6,
158 +       .extreme        = 0,
159 +       .lc             = LZMA_OPT_LC_DEFAULT,
160 +       .lp             = LZMA_OPT_LP_DEFAULT,
161 +       .pb             = LZMA_OPT_PB_DEFAULT,
162 +       .fb             = LZMA_OPT_FB_DEFAULT,
163 +       .dict_size      = 0,
164 +};
165 +
166 +static float lzma_dict_percent = 0;
167 +
168 +struct lzma_xz_options *lzma_xz_get_options(void)
169 +{
170 +       return &options;
171 +}
172 +
173 +
174 +int lzma_xz_options(char *argv[], int argc, int lzmaver)
175 +{
176 +       const char *comp_name = lzmaver_str[lzmaver];
177 +       
178 +       if(strcmp(argv[0], "-Xpreset") == 0) {
179 +               int preset;
180 +               
181 +               if(argc < 2) {
182 +                       fprintf(stderr, "%s: -Xpreset missing preset\n", comp_name);
183 +                       goto failed;
184 +               }
185 +               
186 +               preset = atoi(argv[1]);
187 +               
188 +               if (preset < 0 || preset > 9) {
189 +                       fprintf(stderr, "%s: -Xpreset invalid value\n", comp_name);
190 +                       goto failed;
191 +               }
192 +               options.preset = preset;
193 +               return 1;
194 +       } else if(strcmp(argv[0], "-Xe") == 0) {
195 +               options.extreme = 1;
196 +               return 0;
197 +       } else if(strcmp(argv[0], "-Xlc") == 0) {
198 +               int lc;
199 +               
200 +               if(argc < 2) {
201 +                       fprintf(stderr, "%s: -Xlc missing lc\n", comp_name);
202 +                       goto failed;
203 +               }
204 +               
205 +               lc = atoi(argv[1]);
206 +               
207 +               if (lc < LZMA_OPT_LC_MIN || lc > LZMA_OPT_LC_MAX) {
208 +                       fprintf(stderr, "%s: -Xlc invalid value\n", comp_name);
209 +                       goto failed;
210 +               }
211 +               options.lc = lc;
212 +               return 1;
213 +       } else if(strcmp(argv[0], "-Xlp") == 0) {
214 +               int lp;
215 +               
216 +               if(argc < 2) {
217 +                       fprintf(stderr, "%s: -Xlp missing lp\n", comp_name);
218 +                       goto failed;
219 +               }
220 +               
221 +               lp = atoi(argv[1]);
222 +               
223 +               if (lp < LZMA_OPT_LP_MIN || lp > LZMA_OPT_LP_MAX) {
224 +                       fprintf(stderr, "%s: -Xlp invalid value\n", comp_name);
225 +                       goto failed;
226 +               }
227 +               options.lp = lp;
228 +               return 1;
229 +       } else if(strcmp(argv[0], "-Xpb") == 0) {
230 +               int pb;
231 +               
232 +               if(argc < 2) {
233 +                       fprintf(stderr, "%s: -Xpb missing pb\n", comp_name);
234 +                       goto failed;
235 +               }
236 +               
237 +               pb = atoi(argv[1]);
238 +               
239 +               if (pb < LZMA_OPT_PB_MIN || pb > LZMA_OPT_PB_MAX) {
240 +                       fprintf(stderr, "%s: -Xbp invalid value\n", comp_name);
241 +                       goto failed;
242 +               }
243 +               options.pb = pb;
244 +               return 1;       
245 +       } else if(strcmp(argv[0], "-Xfb") == 0) {
246 +               int fb;
247 +               
248 +               if(argc < 2) {
249 +                       fprintf(stderr, "%s: -Xfb missing fb\n", comp_name);
250 +                       goto failed;
251 +               }
252 +               
253 +               fb = atoi(argv[1]);
254 +               
255 +               if (fb < LZMA_OPT_FB_MIN || fb > LZMA_OPT_FB_MAX) {
256 +                       fprintf(stderr, "%s: -Xfb invalid value\n", comp_name);
257 +                       goto failed;
258 +               }
259 +               options.fb = fb;
260 +               return 1;
261 +       } else if(strcmp(argv[0], "-Xdict-size") == 0) {
262 +               char *b;
263 +               float size;
264 +
265 +               if(argc < 2) {
266 +                       fprintf(stderr, "%s: -Xdict-size missing dict-size\n", comp_name);
267 +                       goto failed;
268 +               }
269 +
270 +               size = strtof(argv[1], &b);
271 +               if(*b == '%') {
272 +                       if(size <= 0 || size > 100) {
273 +                               fprintf(stderr, "%s: -Xdict-size percentage "
274 +                                       "should be 0 < dict-size <= 100\n", comp_name);
275 +                               goto failed;
276 +                       }
277 +
278 +                       lzma_dict_percent = size;
279 +                       options.dict_size = 0;
280 +               } else {
281 +                       if((float) ((int) size) != size) {
282 +                               fprintf(stderr, "%s: -Xdict-size can't be "
283 +                                       "fractional unless a percentage of the"
284 +                                       " block size\n", comp_name);
285 +                               goto failed;
286 +                       }
287 +
288 +                       lzma_dict_percent = 0;
289 +                       options.dict_size = (int) size;
290 +
291 +                       if(*b == 'k' || *b == 'K')
292 +                               options.dict_size *= 1024;
293 +                       else if(*b == 'm' || *b == 'M')
294 +                               options.dict_size *= 1024 * 1024;
295 +                       else if(*b != '\0') {
296 +                               fprintf(stderr, "%s: -Xdict-size invalid "
297 +                                       "dict-size\n", comp_name);
298 +                               goto failed;
299 +                       }
300 +               }
301 +
302 +               return 1;
303 +       }
304 +       
305 +       return -1;
306 +       
307 +failed:
308 +       return -2;
309 +
310 +}
311 +
312 +int lzma_xz_options_post(int block_size, int lzmaver)
313 +{
314 +       const char *comp_name = lzmaver_str[lzmaver];
315 +       /*
316 +        * if -Xdict-size has been specified use this to compute the datablock
317 +        * dictionary size
318 +        */
319 +       if(options.dict_size || lzma_dict_percent) {
320 +               int dict_size_min = (lzmaver == 1 ? 4096 : 8192);
321 +               int n;
322 +
323 +               if(options.dict_size) {
324 +                       if(options.dict_size > block_size) {
325 +                               fprintf(stderr, "%s: -Xdict-size is larger than"
326 +                               " block_size\n", comp_name);
327 +                               goto failed;
328 +                       }
329 +               } else
330 +                       options.dict_size = block_size * lzma_dict_percent / 100;
331 +
332 +               if(options.dict_size < dict_size_min) {
333 +                       fprintf(stderr, "%s: -Xdict-size should be %i bytes "
334 +                               "or larger\n", comp_name, dict_size_min);
335 +                       goto failed;
336 +               }
337 +
338 +               /*
339 +                * dictionary_size must be storable in xz header as either
340 +                * 2^n or as  2^n+2^(n+1)
341 +               */
342 +               n = ffs(options.dict_size) - 1;
343 +               if(options.dict_size != (1 << n) &&
344 +                               options.dict_size != ((1 << n) + (1 << (n + 1)))) {
345 +                       fprintf(stderr, "%s: -Xdict-size is an unsupported "
346 +                               "value, dict-size must be storable in %s "
347 +                               "header\n", comp_name, comp_name);
348 +                       fprintf(stderr, "as either 2^n or as 2^n+2^(n+1).  "
349 +                               "Example dict-sizes are 75%%, 50%%, 37.5%%, "
350 +                               "25%%,\n");
351 +                       fprintf(stderr, "or 32K, 16K, 8K etc.\n");
352 +                       goto failed;
353 +               }
354 +
355 +       } else
356 +               /* No -Xdict-size specified, use defaults */
357 +               options.dict_size = block_size;
358 +
359 +       return 0;
360 +
361 +failed:
362 +       return -1;
363 +}
364 +
365 +static struct lzma_opts lzma_comp_opts;
366 +
367 +void *lzma_xz_dump_options(int block_size, int *size, int flags)
368 +{
369 +       /* No need to store default options */
370 +       if (options.preset == 6 &&
371 +                       options.extreme == 0 &&
372 +                       options.lc == LZMA_OPT_LC_DEFAULT &&
373 +                       options.lp == LZMA_OPT_LC_DEFAULT &&
374 +                       options.pb == LZMA_OPT_PB_DEFAULT &&
375 +                       options.fb == 0 &&
376 +                       options.dict_size == block_size &&
377 +                       flags == 0)
378 +               return NULL;
379 +       
380 +       *size = sizeof(struct lzma_opts);
381 +
382 +       lzma_comp_opts.flags |= flags;
383 +       
384 +       if (options.extreme)
385 +               lzma_comp_opts.flags |= LZMA_OPT_EXTREME;
386 +       
387 +       lzma_comp_opts.flags |= ((options.preset << LZMA_OPT_PRE_OFF) & LZMA_OPT_PRE_MASK);
388 +       
389 +       lzma_comp_opts.bit_opts = 
390 +                       ((options.lc << LZMA_OPT_LC_OFF) & LZMA_OPT_LC_MASK) |
391 +                       ((options.lp << LZMA_OPT_LP_OFF) & LZMA_OPT_LP_MASK) |
392 +                       ((options.pb << LZMA_OPT_PB_OFF) & LZMA_OPT_PB_MASK);
393 +       lzma_comp_opts.fb = options.fb;
394 +       lzma_comp_opts.dict_size = options.dict_size;
395 +       
396 +       SQUASHFS_INSWAP_LZMA_COMP_OPTS(&lzma_comp_opts);
397 +       
398 +       return &lzma_comp_opts;
399 +}
400 +
401 +int lzma_xz_extract_options(int block_size, void *buffer, int size, int lzmaver)
402 +{
403 +       if (size == 0) {
404 +               /* default options */
405 +               options.preset = 6;
406 +               options.extreme = 0;
407 +               options.lc = LZMA_OPT_LC_DEFAULT;
408 +               options.lp = LZMA_OPT_LC_DEFAULT;
409 +               options.pb = LZMA_OPT_PB_DEFAULT;
410 +               options.fb = LZMA_OPT_FB_DEFAULT;
411 +               options.dict_size = block_size;
412 +               options.flags = 0;
413 +       } else {
414 +               struct lzma_opts *comp_opts = buffer;
415 +               int n;
416 +               
417 +               if (size != sizeof(struct lzma_opts))
418 +                       goto failed;
419 +               
420 +               SQUASHFS_INSWAP_LZMA_COMP_OPTS(comp_opts);
421 +               
422 +               options.flags = comp_opts->flags & LZMA_OPT_FLT_MASK;
423 +               options.preset  = (comp_opts->flags & LZMA_OPT_PRE_MASK) >> LZMA_OPT_PRE_OFF;
424 +               options.extreme = !!(comp_opts->flags & LZMA_OPT_EXTREME);
425 +
426 +               options.lc = (comp_opts->bit_opts & LZMA_OPT_LC_MASK) >> LZMA_OPT_LC_OFF;
427 +               options.lp = (comp_opts->bit_opts & LZMA_OPT_LP_MASK) >> LZMA_OPT_LP_OFF;
428 +               options.pb = (comp_opts->bit_opts & LZMA_OPT_PB_MASK) >> LZMA_OPT_PB_OFF;
429 +               options.fb = comp_opts->fb;
430 +               options.dict_size = comp_opts->dict_size;
431 +               
432 +               /* check that the LZMA bit options are in range */
433 +               if (options.lc < LZMA_OPT_LC_MIN || options.lc > LZMA_OPT_LC_MAX ||
434 +                       options.lp < LZMA_OPT_LP_MIN || options.lp > LZMA_OPT_LP_MAX ||
435 +                       options.pb < LZMA_OPT_PB_MIN || options.pb > LZMA_OPT_PB_MAX ||
436 +                       options.fb < LZMA_OPT_FB_MIN || options.fb > LZMA_OPT_FB_MAX)
437 +                       goto failed;
438 +
439 +               /*
440 +                * check that the dictionary size seems correct - the dictionary
441 +                * size should 2^n or 2^n+2^(n+1)
442 +                */
443 +               n = ffs(options.dict_size) - 1;
444 +               if(options.dict_size != (1 << n) &&
445 +                               options.dict_size != ((1 << n) + (1 << (n + 1))))
446 +                       goto failed;
447 +               
448 +       }
449 +       
450 +       return 0;
451 +
452 +failed:
453 +       fprintf(stderr, "%s: error reading stored compressor options from "
454 +               "filesystem!\n", lzmaver_str[lzmaver]);
455 +       return -1;      
456 +}
457 +
458 +void lzma_xz_usage(int lzmaver)
459 +{
460 +       fprintf(stderr, "\t  -Xpreset <preset>\n");
461 +       fprintf(stderr, "\t\tcompression preset (0-9, default 6)\n");
462 +       fprintf(stderr, "\t  -Xe\n");
463 +       fprintf(stderr, "\t\tTry to improve compression ratio by using more ");
464 +       fprintf(stderr, "CPU time.\n");
465 +       fprintf(stderr, "\t  -Xlc <lc>\n");
466 +       fprintf(stderr, "\t\tNumber of literal context bits (0-4, default 3)\n");
467 +       fprintf(stderr, "\t  -Xlp <lp>\n");
468 +       fprintf(stderr, "\t\tNumber of literal position bits (0-4, default 0)\n");
469 +       fprintf(stderr, "\t  -Xpb <pb>\n");
470 +       fprintf(stderr, "\t\tNumber of position bits (0-4, default 2)\n");
471 +       fprintf(stderr, "\t  -Xnice <nice>\n");
472 +       fprintf(stderr, "\t\tNice length of a match (5-273, default 64)\n");
473 +       fprintf(stderr, "\t  -Xdict-size <dict-size>\n");
474 +       fprintf(stderr, "\t\tUse <dict-size> as the %s dictionary size.  The",
475 +                       lzmaver == LZMA_OPT_LZMA ? "LZMA" : "XZ");
476 +       fprintf(stderr, " dictionary size\n\t\tcan be specified as a");
477 +       fprintf(stderr, " percentage of the block size, or as an\n\t\t");
478 +       fprintf(stderr, "absolute value.  The dictionary size must be less");
479 +       fprintf(stderr, " than or equal\n\t\tto the block size and %d bytes", 
480 +                       lzmaver == LZMA_OPT_LZMA ? 4096 : 8192);
481 +       fprintf(stderr, " or larger.  It must also be\n\t\tstorable in the lzma");
482 +       fprintf(stderr, " header as either 2^n or as 2^n+2^(n+1).\n\t\t");
483 +       fprintf(stderr, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or");
484 +       fprintf(stderr, " 32K, 16K, 8K\n\t\tetc.\n");
485 +       
486 +}
487 --- a/squashfs-tools/lzma_xz_wrapper.c
488 +++ b/squashfs-tools/lzma_xz_wrapper.c
489 @@ -27,6 +27,7 @@
490  
491  #include "squashfs_fs.h"
492  #include "compressor.h"
493 +#include "lzma_xz_options.h"
494  
495  #define LZMA_PROPS_SIZE 5
496  #define LZMA_UNCOMP_SIZE 8
497 @@ -38,13 +39,27 @@
498  static int lzma_compress(void *dummy, void *dest, void *src,  int size,
499         int block_size, int *error)
500  {
501 +       uint32_t preset;
502         unsigned char *d = (unsigned char *) dest;
503 +       struct lzma_xz_options *opts = lzma_xz_get_options();
504 +
505         lzma_options_lzma opt;
506         lzma_stream strm = LZMA_STREAM_INIT;
507         int res;
508  
509 -       lzma_lzma_preset(&opt, LZMA_OPTIONS);
510 -       opt.dict_size = block_size;
511 +       preset = opts->preset;
512 +
513 +       if (opts->extreme)
514 +               preset |= LZMA_PRESET_EXTREME;
515 +
516 +       lzma_lzma_preset(&opt, opts->preset);
517 +       opt.lc = opts->lc;
518 +       opt.lp = opts->lp;
519 +       opt.pb = opts->pb;
520 +       if (opts->fb)
521 +               opt.nice_len = opts->fb;
522 +
523 +       opt.dict_size = opts->dict_size;
524  
525         res = lzma_alone_encoder(&strm, &opt);
526         if(res != LZMA_OK) {
527 @@ -143,13 +158,45 @@ failed:
528         return -1;
529  }
530  
531 +static int lzma_options(char *argv[], int argc)
532 +{
533 +       return lzma_xz_options(argv, argc, LZMA_OPT_LZMA);
534 +}
535 +
536 +
537 +static int lzma_options_post(int block_size)
538 +{
539 +       return lzma_xz_options_post(block_size, LZMA_OPT_LZMA);
540 +}
541 +
542 +
543 +static void *lzma_dump_options(int block_size, int *size)
544 +{
545 +       return lzma_xz_dump_options(block_size, size, 0);
546 +}
547 +
548 +
549 +static int lzma_extract_options(int block_size, void *buffer, int size)
550 +{
551 +       return lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_LZMA);
552 +}
553 +
554 +
555 +void lzma_usage()
556 +{
557 +       lzma_xz_usage(LZMA_OPT_LZMA);
558 +}
559 +
560  
561  struct compressor lzma_comp_ops = {
562         .init = NULL,
563         .compress = lzma_compress,
564         .uncompress = lzma_uncompress,
565 -       .options = NULL,
566 -       .usage = NULL,
567 +       .options = lzma_options,
568 +       .options_post = lzma_options_post,
569 +       .dump_options = lzma_dump_options,
570 +       .extract_options = lzma_extract_options,
571 +       .usage = lzma_usage,
572         .id = LZMA_COMPRESSION,
573         .name = "lzma",
574         .supported = 1
575 --- a/squashfs-tools/xz_wrapper.h
576 +++ b/squashfs-tools/xz_wrapper.h
577 @@ -24,25 +24,6 @@
578   *
579   */
580  
581 -#ifndef linux
582 -#define __BYTE_ORDER BYTE_ORDER
583 -#define __BIG_ENDIAN BIG_ENDIAN
584 -#define __LITTLE_ENDIAN LITTLE_ENDIAN
585 -#else
586 -#include <endian.h>
587 -#endif
588 -
589 -#if __BYTE_ORDER == __BIG_ENDIAN
590 -extern unsigned int inswap_le32(unsigned int);
591 -
592 -#define SQUASHFS_INSWAP_COMP_OPTS(s) { \
593 -       (s)->dictionary_size = inswap_le32((s)->dictionary_size); \
594 -       (s)->flags = inswap_le32((s)->flags); \
595 -}
596 -#else
597 -#define SQUASHFS_INSWAP_COMP_OPTS(s)
598 -#endif
599 -
600  #define MEMLIMIT (32 * 1024 * 1024)
601  
602  struct bcj {
603 --- a/squashfs-tools/xz_wrapper.c
604 +++ b/squashfs-tools/xz_wrapper.c
605 @@ -30,6 +30,7 @@
606  #include "squashfs_fs.h"
607  #include "xz_wrapper.h"
608  #include "compressor.h"
609 +#include "lzma_xz_options.h"
610  
611  static struct bcj bcj[] = {
612         { "x86", LZMA_FILTER_X86, 0 },
613 @@ -41,22 +42,18 @@ static struct bcj bcj[] = {
614         { NULL, LZMA_VLI_UNKNOWN, 0 }
615  };
616  
617 -static struct comp_opts comp_opts;
618 -
619  static int filter_count = 1;
620 -static int dictionary_size = 0;
621 -static float dictionary_percent = 0;
622  
623  
624  static int xz_options(char *argv[], int argc)
625  {
626 -       int i;
627 -       char *name;
628 -
629         if(strcmp(argv[0], "-Xbcj") == 0) {
630 +               int i;
631 +               char *name;
632 +
633                 if(argc < 2) {
634                         fprintf(stderr, "xz: -Xbcj missing filter\n");
635 -                       goto failed;
636 +                       return -2;
637                 }
638  
639                 name = argv[1];
640 @@ -76,190 +73,50 @@ static int xz_options(char *argv[], int
641                         }
642                         if(bcj[i].name == NULL) {
643                                 fprintf(stderr, "xz: -Xbcj unrecognised "
644 -                                       "filter\n");
645 -                               goto failed;
646 -                       }
647 -               }
648 -       
649 -               return 1;
650 -       } else if(strcmp(argv[0], "-Xdict-size") == 0) {
651 -               char *b;
652 -               float size;
653 -
654 -               if(argc < 2) {
655 -                       fprintf(stderr, "xz: -Xdict-size missing dict-size\n");
656 -                       goto failed;
657 -               }
658 -
659 -               size = strtof(argv[1], &b);
660 -               if(*b == '%') {
661 -                       if(size <= 0 || size > 100) {
662 -                               fprintf(stderr, "xz: -Xdict-size percentage "
663 -                                       "should be 0 < dict-size <= 100\n");
664 -                               goto failed;
665 -                       }
666 -
667 -                       dictionary_percent = size;
668 -                       dictionary_size = 0;
669 -               } else {
670 -                       if((float) ((int) size) != size) {
671 -                               fprintf(stderr, "xz: -Xdict-size can't be "
672 -                                       "fractional unless a percentage of the"
673 -                                       " block size\n");
674 -                               goto failed;
675 -                       }
676 -
677 -                       dictionary_percent = 0;
678 -                       dictionary_size = (int) size;
679 -
680 -                       if(*b == 'k' || *b == 'K')
681 -                               dictionary_size *= 1024;
682 -                       else if(*b == 'm' || *b == 'M')
683 -                               dictionary_size *= 1024 * 1024;
684 -                       else if(*b != '\0') {
685 -                               fprintf(stderr, "xz: -Xdict-size invalid "
686 -                                       "dict-size\n");
687 -                               goto failed;
688 +                                               "filter\n");
689 +                               return -2;
690                         }
691                 }
692 -
693                 return 1;
694 +       } else {
695 +               return lzma_xz_options(argv, argc, LZMA_OPT_XZ);
696         }
697 -
698 -       return -1;
699 -       
700 -failed:
701 -       return -2;
702  }
703  
704  
705  static int xz_options_post(int block_size)
706  {
707 -       /*
708 -        * if -Xdict-size has been specified use this to compute the datablock
709 -        * dictionary size
710 -        */
711 -       if(dictionary_size || dictionary_percent) {
712 -               int n;
713 -
714 -               if(dictionary_size) {
715 -                       if(dictionary_size > block_size) {
716 -                               fprintf(stderr, "xz: -Xdict-size is larger than"
717 -                               " block_size\n");
718 -                               goto failed;
719 -                       }
720 -               } else
721 -                       dictionary_size = block_size * dictionary_percent / 100;
722 -
723 -               if(dictionary_size < 8192) {
724 -                       fprintf(stderr, "xz: -Xdict-size should be 8192 bytes "
725 -                               "or larger\n");
726 -                       goto failed;
727 -               }
728 -
729 -               /*
730 -                * dictionary_size must be storable in xz header as either
731 -                * 2^n or as  2^n+2^(n+1)
732 -               */
733 -               n = ffs(dictionary_size) - 1;
734 -               if(dictionary_size != (1 << n) && 
735 -                               dictionary_size != ((1 << n) + (1 << (n + 1)))) {
736 -                       fprintf(stderr, "xz: -Xdict-size is an unsupported "
737 -                               "value, dict-size must be storable in xz "
738 -                               "header\n");
739 -                       fprintf(stderr, "as either 2^n or as 2^n+2^(n+1).  "
740 -                               "Example dict-sizes are 75%%, 50%%, 37.5%%, "
741 -                               "25%%,\n");
742 -                       fprintf(stderr, "or 32K, 16K, 8K etc.\n");
743 -                       goto failed;
744 -               }
745 -
746 -       } else
747 -               /* No -Xdict-size specified, use defaults */
748 -               dictionary_size = block_size;
749 -
750 -       return 0;
751 -
752 -failed:
753 -       return -1;
754 +       return lzma_xz_options_post(block_size, LZMA_OPT_XZ);
755  }
756  
757  
758  static void *xz_dump_options(int block_size, int *size)
759  {
760 -       int flags = 0, i;
761 -
762 -       /*
763 -        * don't store compressor specific options in file system if the
764 -        * default options are being used - no compressor options in the
765 -        * file system means the default options are always assumed
766 -        *
767 -        * Defaults are:
768 -        *  metadata dictionary size: SQUASHFS_METADATA_SIZE
769 -        *  datablock dictionary size: block_size
770 -        *  1 filter
771 -        */
772 -       if(dictionary_size == block_size && filter_count == 1)
773 -               return NULL;
774 +       int i, flags = 0;
775  
776         for(i = 0; bcj[i].name; i++)
777                 flags |= bcj[i].selected << i;
778  
779 -       comp_opts.dictionary_size = dictionary_size;
780 -       comp_opts.flags = flags;
781 -
782 -       SQUASHFS_INSWAP_COMP_OPTS(&comp_opts);
783 -
784 -       *size = sizeof(comp_opts);
785 -       return &comp_opts;
786 +       return lzma_xz_dump_options(block_size, size, flags);
787  }
788  
789  
790  static int xz_extract_options(int block_size, void *buffer, int size)
791  {
792 -       struct comp_opts *comp_opts = buffer;
793 -       int flags, i, n;
794 -
795 -       if(size == 0) {
796 -               /* set defaults */
797 -               dictionary_size = block_size;
798 -               flags = 0;
799 -       } else {
800 -               /* check passed comp opts struct is of the correct length */
801 -               if(size != sizeof(struct comp_opts))
802 -                       goto failed;
803 -                                        
804 -               SQUASHFS_INSWAP_COMP_OPTS(comp_opts);
805 -
806 -               dictionary_size = comp_opts->dictionary_size;
807 -               flags = comp_opts->flags;
808 -
809 -               /*
810 -                * check that the dictionary size seems correct - the dictionary
811 -                * size should 2^n or 2^n+2^(n+1)
812 -                */
813 -               n = ffs(dictionary_size) - 1;
814 -               if(dictionary_size != (1 << n) && 
815 -                               dictionary_size != ((1 << n) + (1 << (n + 1))))
816 -                       goto failed;
817 -       }
818 +       int ret = lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_XZ);
819  
820 -       filter_count = 1;
821 -       for(i = 0; bcj[i].name; i++) {
822 -               if((flags >> i) & 1) {
823 -                       bcj[i].selected = 1;
824 -                       filter_count ++;
825 -               } else
826 -                       bcj[i].selected = 0;
827 +       if (!ret) {
828 +               int i;
829 +               struct lzma_xz_options *opts = lzma_xz_get_options();
830 +               for(i = 0; bcj[i].name; i++) {
831 +                       if((opts->flags >> i) & 1) {
832 +                               bcj[i].selected = 1;
833 +                               filter_count ++;
834 +                       } else
835 +                               bcj[i].selected = 0;
836 +               }
837         }
838 -
839 -       return 0;
840 -
841 -failed:
842 -       fprintf(stderr, "xz: error reading stored compressor options from "
843 -               "filesystem!\n");
844 -
845 -       return -1;
846 +       return ret;
847  }
848  
849  
850 @@ -268,6 +125,7 @@ static int xz_init(void **strm, int bloc
851         int i, j, filters = datablock ? filter_count : 1;
852         struct filter *filter = malloc(filters * sizeof(struct filter));
853         struct xz_stream *stream;
854 +       struct lzma_xz_options *opts = lzma_xz_get_options();
855  
856         if(filter == NULL)
857                 goto failed;
858 @@ -281,7 +139,7 @@ static int xz_init(void **strm, int bloc
859  
860         memset(filter, 0, filters * sizeof(struct filter));
861  
862 -       stream->dictionary_size = datablock ? dictionary_size :
863 +       stream->dictionary_size = datablock ? opts->dict_size :
864                 SQUASHFS_METADATA_SIZE;
865  
866         filter[0].filter[0].id = LZMA_FILTER_LZMA2;
867 @@ -323,14 +181,25 @@ static int xz_compress(void *strm, void
868          lzma_ret res = 0;
869         struct xz_stream *stream = strm;
870         struct filter *selected = NULL;
871 +       struct lzma_xz_options *opts = lzma_xz_get_options();
872  
873         stream->filter[0].buffer = dest;
874  
875         for(i = 0; i < stream->filters; i++) {
876 +               uint32_t preset = opts->preset;
877                 struct filter *filter = &stream->filter[i];
878  
879 -               if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT))
880 -                       goto failed;
881 +               if (opts->extreme)
882 +                       preset |= LZMA_PRESET_EXTREME;
883 +
884 +        if(lzma_lzma_preset(&stream->opt, preset))
885 +                       goto failed;
886 +
887 +        stream->opt.lc = opts->lc;
888 +       stream->opt.lp = opts->lp;
889 +       stream->opt.pb = opts->pb;
890 +       if (opts->fb)
891 +               stream->opt.nice_len = opts->fb;
892  
893                 stream->opt.dict_size = stream->dictionary_size;
894  
895 @@ -384,22 +253,13 @@ static int xz_uncompress(void *dest, voi
896  
897  void xz_usage()
898  {
899 +       lzma_xz_usage(LZMA_OPT_XZ);
900         fprintf(stderr, "\t  -Xbcj filter1,filter2,...,filterN\n");
901         fprintf(stderr, "\t\tCompress using filter1,filter2,...,filterN in");
902         fprintf(stderr, " turn\n\t\t(in addition to no filter), and choose");
903         fprintf(stderr, " the best compression.\n");
904         fprintf(stderr, "\t\tAvailable filters: x86, arm, armthumb,");
905         fprintf(stderr, " powerpc, sparc, ia64\n");
906 -       fprintf(stderr, "\t  -Xdict-size <dict-size>\n");
907 -       fprintf(stderr, "\t\tUse <dict-size> as the XZ dictionary size.  The");
908 -       fprintf(stderr, " dictionary size\n\t\tcan be specified as a");
909 -       fprintf(stderr, " percentage of the block size, or as an\n\t\t");
910 -       fprintf(stderr, "absolute value.  The dictionary size must be less");
911 -       fprintf(stderr, " than or equal\n\t\tto the block size and 8192 bytes");
912 -       fprintf(stderr, " or larger.  It must also be\n\t\tstorable in the xz");
913 -       fprintf(stderr, " header as either 2^n or as 2^n+2^(n+1).\n\t\t");
914 -       fprintf(stderr, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or");
915 -       fprintf(stderr, " 32K, 16K, 8K\n\t\tetc.\n");
916  }
917  
918  
919 --- a/squashfs-tools/Makefile
920 +++ b/squashfs-tools/Makefile
921 @@ -140,6 +140,8 @@ COMPRESSORS += xz
922  endif
923  
924  ifneq ($(LZMA_XZ_SUPPORT)$(XZ_SUPPORT),)
925 +MKSQUASHFS_OBJS += lzma_xz_options.o
926 +UNSQUASHFS_OBJS += lzma_xz_options.o
927  ifneq ($(LZMA_LIB),)
928  MKSQUASHFS_OBJS += $(LZMA_LIB)
929  UNSQUASHFS_OBJS += $(LZMA_LIB)