blob: b7fe8d71e7cd362e6f6ba449e67838eb6eeb3958 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001--- /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 dict_size;
44+ uint32_t flags;
45+#define LZMA_OPT_FLT_MASK 0xffff
46+#define LZMA_OPT_PRE_OFF 16
47+#define LZMA_OPT_PRE_MASK (0xf << LZMA_OPT_PRE_OFF)
48+#define LZMA_OPT_EXTREME 20
49+ uint16_t bit_opts;
50+#define LZMA_OPT_LC_OFF 0
51+#define LZMA_OPT_LC_MASK (0x7 << LZMA_OPT_LC_OFF)
52+#define LZMA_OPT_LP_OFF 3
53+#define LZMA_OPT_LP_MASK (0x7 << LZMA_OPT_LP_OFF)
54+#define LZMA_OPT_PB_OFF 6
55+#define LZMA_OPT_PB_MASK (0x7 << LZMA_OPT_PB_OFF)
56+ uint16_t fb;
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/xz_wrapper_extended.c
488+++ b/squashfs-tools/xz_wrapper_extended.c
489@@ -32,6 +32,7 @@
490 #include "squashfs_fs.h"
491 #include "xz_wrapper.h"
492 #include "compressor.h"
493+#include "lzma_xz_options.h"
494
495 static struct bcj bcj[] = {
496 { "x86", LZMA_FILTER_X86, 0 },
497@@ -44,12 +45,6 @@ static struct bcj bcj[] = {
498 };
499
500 static int filter_count = 1;
501-static int dictionary_size = 0;
502-static float dictionary_percent = 0;
503-static int preset = LZMA_PRESET_DEFAULT;
504-static int lc = -1;
505-static int lp = -1;
506-static int pb = -1;
507
508 /*
509 * This function is called by the options parsing code in mksquashfs.c
510@@ -77,13 +72,13 @@ static int pb = -1;
511 */
512 static int xz_options(char *argv[], int argc)
513 {
514- int i;
515- char *name;
516-
517 if(strcmp(argv[0], "-Xbcj") == 0) {
518+ int i;
519+ char *name;
520+
521 if(argc < 2) {
522 fprintf(stderr, "xz: -Xbcj missing filter\n");
523- goto failed;
524+ return -2;
525 }
526
527 name = argv[1];
528@@ -104,138 +99,14 @@ static int xz_options(char *argv[], int argc)
529 if(bcj[i].name == NULL) {
530 fprintf(stderr, "xz: -Xbcj unrecognised "
531 "filter\n");
532- goto failed;
533- }
534- }
535-
536- return 1;
537- } else if(strcmp(argv[0], "-Xdict-size") == 0) {
538- char *b;
539- float size;
540-
541- if(argc < 2) {
542- fprintf(stderr, "xz: -Xdict-size missing dict-size\n");
543- goto failed;
544- }
545-
546- size = strtof(argv[1], &b);
547- if(*b == '%') {
548- if(size <= 0 || size > 100) {
549- fprintf(stderr, "xz: -Xdict-size percentage "
550- "should be 0 < dict-size <= 100\n");
551- goto failed;
552- }
553-
554- dictionary_percent = size;
555- dictionary_size = 0;
556- } else {
557- if((float) ((int) size) != size) {
558- fprintf(stderr, "xz: -Xdict-size can't be "
559- "fractional unless a percentage of the"
560- " block size\n");
561- goto failed;
562+ return -2;
563 }
564-
565- dictionary_percent = 0;
566- dictionary_size = (int) size;
567-
568- if(*b == 'k' || *b == 'K')
569- dictionary_size *= 1024;
570- else if(*b == 'm' || *b == 'M')
571- dictionary_size *= 1024 * 1024;
572- else if(*b != '\0') {
573- fprintf(stderr, "xz: -Xdict-size invalid "
574- "dict-size\n");
575- goto failed;
576- }
577- }
578-
579- return 1;
580- } else if(strcmp(argv[0], "-Xpreset") == 0) {
581- char *b;
582- long val;
583-
584- if(argc < 2) {
585- fprintf(stderr, "xz: -Xpreset missing preset-level "
586- "(valid value 0-9)\n");
587- goto failed;
588- }
589-
590- val = strtol(argv[1], &b, 10);
591- if (*b != '\0' || (int) val < 0 || (int) val & ~LZMA_PRESET_LEVEL_MASK) {
592- fprintf(stderr, "xz: -Xpreset can't be "
593- "negative or more than the max preset\n");
594- goto failed;
595- }
596-
597- preset &= ~LZMA_PRESET_LEVEL_MASK;
598- preset |= (int) val;
599-
600- return 1;
601- } else if(strcmp(argv[0], "-Xe") == 0) {
602- preset |= LZMA_PRESET_EXTREME;
603-
604- return 0;
605- } else if(strcmp(argv[0], "-Xlc") == 0) {
606- char *b;
607- long val;
608-
609- if(argc < 2) {
610- fprintf(stderr, "xz: -Xlc missing value\n");
611- goto failed;
612- }
613-
614- val = strtol(argv[1], &b, 10);
615- if (*b != '\0' || (int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) {
616- fprintf(stderr, "xz: -Xlc invalid value\n");
617- goto failed;
618- }
619-
620- lc = (int) val;
621-
622- return 1;
623- } else if(strcmp(argv[0], "-Xlp") == 0) {
624- char *b;
625- long val;
626-
627- if(argc < 2) {
628- fprintf(stderr, "xz: -Xlp missing value\n");
629- goto failed;
630- }
631-
632- val = strtol(argv[1], &b, 10);
633- if (*b != '\0' || (int) val < LZMA_LCLP_MIN || (int) val > LZMA_LCLP_MAX) {
634- fprintf(stderr, "xz: -Xlp invalid value\n");
635- goto failed;
636- }
637-
638- lp = (int) val;
639-
640- return 1;
641- } else if(strcmp(argv[0], "-Xpb") == 0) {
642- char *b;
643- long val;
644-
645- if(argc < 2) {
646- fprintf(stderr, "xz: -Xpb missing value\n");
647- goto failed;
648- }
649-
650- val = strtol(argv[1], &b, 10);
651- if (*b != '\0' || (int) val < LZMA_PB_MIN || (int) val > LZMA_PB_MAX) {
652- fprintf(stderr, "xz: -Xpb invalid value\n");
653- goto failed;
654 }
655
656- pb = (int) val;
657-
658 return 1;
659+ } else {
660+ return lzma_xz_options(argv, argc, LZMA_OPT_XZ);
661 }
662-
663- return -1;
664-
665-failed:
666- return -2;
667 }
668
669
670@@ -252,53 +123,7 @@ failed:
671 */
672 static int xz_options_post(int block_size)
673 {
674- /*
675- * if -Xdict-size has been specified use this to compute the datablock
676- * dictionary size
677- */
678- if(dictionary_size || dictionary_percent) {
679- int n;
680-
681- if(dictionary_size) {
682- if(dictionary_size > block_size) {
683- fprintf(stderr, "xz: -Xdict-size is larger than"
684- " block_size\n");
685- goto failed;
686- }
687- } else
688- dictionary_size = block_size * dictionary_percent / 100;
689-
690- if(dictionary_size < 8192) {
691- fprintf(stderr, "xz: -Xdict-size should be 8192 bytes "
692- "or larger\n");
693- goto failed;
694- }
695-
696- /*
697- * dictionary_size must be storable in xz header as either
698- * 2^n or as 2^n+2^(n+1)
699- */
700- n = ffs(dictionary_size) - 1;
701- if(dictionary_size != (1 << n) &&
702- dictionary_size != ((1 << n) + (1 << (n + 1)))) {
703- fprintf(stderr, "xz: -Xdict-size is an unsupported "
704- "value, dict-size must be storable in xz "
705- "header\n");
706- fprintf(stderr, "as either 2^n or as 2^n+2^(n+1). "
707- "Example dict-sizes are 75%%, 50%%, 37.5%%, "
708- "25%%,\n");
709- fprintf(stderr, "or 32K, 16K, 8K etc.\n");
710- goto failed;
711- }
712-
713- } else
714- /* No -Xdict-size specified, use defaults */
715- dictionary_size = block_size;
716-
717- return 0;
718-
719-failed:
720- return -1;
721+ return lzma_xz_options_post(block_size, LZMA_OPT_XZ);
722 }
723
724
725@@ -314,32 +139,12 @@ failed:
726 */
727 static void *xz_dump_options(int block_size, int *size)
728 {
729- static struct comp_opts comp_opts;
730 int flags = 0, i;
731
732- /*
733- * don't store compressor specific options in file system if the
734- * default options are being used - no compressor options in the
735- * file system means the default options are always assumed
736- *
737- * Defaults are:
738- * metadata dictionary size: SQUASHFS_METADATA_SIZE
739- * datablock dictionary size: block_size
740- * 1 filter
741- */
742- if(dictionary_size == block_size && filter_count == 1)
743- return NULL;
744-
745 for(i = 0; bcj[i].name; i++)
746 flags |= bcj[i].selected << i;
747
748- comp_opts.dictionary_size = dictionary_size;
749- comp_opts.flags = flags;
750-
751- SQUASHFS_INSWAP_COMP_OPTS(&comp_opts);
752-
753- *size = sizeof(comp_opts);
754- return &comp_opts;
755+ return lzma_xz_dump_options(block_size, size, flags);
756 }
757
758
759@@ -365,49 +170,20 @@ static void *xz_dump_options(int block_size, int *size)
760 */
761 static int xz_extract_options(int block_size, void *buffer, int size)
762 {
763- struct comp_opts *comp_opts = buffer;
764- int flags, i, n;
765-
766- if(size == 0) {
767- /* set defaults */
768- dictionary_size = block_size;
769- flags = 0;
770- } else {
771- /* check passed comp opts struct is of the correct length */
772- if(size != sizeof(struct comp_opts))
773- goto failed;
774-
775- SQUASHFS_INSWAP_COMP_OPTS(comp_opts);
776-
777- dictionary_size = comp_opts->dictionary_size;
778- flags = comp_opts->flags;
779-
780- /*
781- * check that the dictionary size seems correct - the dictionary
782- * size should 2^n or 2^n+2^(n+1)
783- */
784- n = ffs(dictionary_size) - 1;
785- if(dictionary_size != (1 << n) &&
786- dictionary_size != ((1 << n) + (1 << (n + 1))))
787- goto failed;
788- }
789-
790- filter_count = 1;
791- for(i = 0; bcj[i].name; i++) {
792- if((flags >> i) & 1) {
793- bcj[i].selected = 1;
794- filter_count ++;
795- } else
796- bcj[i].selected = 0;
797+ int ret = lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_XZ);
798+
799+ if (!ret) {
800+ int i;
801+ struct lzma_xz_options *opts = lzma_xz_get_options();
802+ for(i = 0; bcj[i].name; i++) {
803+ if((opts->flags >> i) & 1) {
804+ bcj[i].selected = 1;
805+ filter_count ++;
806+ } else
807+ bcj[i].selected = 0;
808+ }
809 }
810-
811- return 0;
812-
813-failed:
814- fprintf(stderr, "xz: error reading stored compressor options from "
815- "filesystem!\n");
816-
817- return -1;
818+ return ret;
819 }
820
821
822@@ -474,6 +250,7 @@ static int xz_init(void **strm, int block_size, int datablock)
823 int i, j, filters = datablock ? filter_count : 1;
824 struct filter *filter = malloc(filters * sizeof(struct filter));
825 struct xz_stream *stream;
826+ struct lzma_xz_options *opts = lzma_xz_get_options();
827
828 if(filter == NULL)
829 goto failed;
830@@ -487,7 +264,7 @@ static int xz_init(void **strm, int block_size, int datablock)
831
832 memset(filter, 0, filters * sizeof(struct filter));
833
834- stream->dictionary_size = datablock ? dictionary_size :
835+ stream->dictionary_size = datablock ? opts->dict_size :
836 SQUASHFS_METADATA_SIZE;
837
838 filter[0].filter[0].id = LZMA_FILTER_LZMA2;
839@@ -529,25 +306,27 @@ static int xz_compress(void *strm, void *dest, void *src, int size,
840 lzma_ret res = 0;
841 struct xz_stream *stream = strm;
842 struct filter *selected = NULL;
843+ struct lzma_xz_options *opts = lzma_xz_get_options();
844
845 stream->filter[0].buffer = dest;
846
847 for(i = 0; i < stream->filters; i++) {
848+ uint32_t preset = opts->preset;
849 struct filter *filter = &stream->filter[i];
850
851+ if (opts->extreme)
852+ preset |= LZMA_PRESET_EXTREME;
853+
854 if(lzma_lzma_preset(&stream->opt, preset))
855 goto failed;
856
857- stream->opt.dict_size = stream->dictionary_size;
858+ stream->opt.lc = opts->lc;
859+ stream->opt.lp = opts->lp;
860+ stream->opt.pb = opts->pb;
861+ if (opts->fb)
862+ stream->opt.nice_len = opts->fb;
863
864- if (lc >= 0)
865- stream->opt.lc = lc;
866-
867- if (lp >= 0)
868- stream->opt.lp = lp;
869-
870- if (pb >= 0)
871- stream->opt.pb = pb;
872+ stream->opt.dict_size = stream->dictionary_size;
873
874 filter->length = 0;
875 res = lzma_stream_buffer_encode(filter->filter,
876@@ -603,32 +382,13 @@ static int xz_uncompress(void *dest, void *src, int size, int outsize,
877
878 static void xz_usage(FILE *stream)
879 {
880+ lzma_xz_usage(LZMA_OPT_XZ);
881 fprintf(stream, "\t -Xbcj filter1,filter2,...,filterN\n");
882 fprintf(stream, "\t\tCompress using filter1,filter2,...,filterN in");
883 fprintf(stream, " turn\n\t\t(in addition to no filter), and choose");
884 fprintf(stream, " the best compression.\n");
885 fprintf(stream, "\t\tAvailable filters: x86, arm, armthumb,");
886 fprintf(stream, " powerpc, sparc, ia64\n");
887- fprintf(stream, "\t -Xdict-size <dict-size>\n");
888- fprintf(stream, "\t\tUse <dict-size> as the XZ dictionary size. The");
889- fprintf(stream, " dictionary size\n\t\tcan be specified as a");
890- fprintf(stream, " percentage of the block size, or as an\n\t\t");
891- fprintf(stream, "absolute value. The dictionary size must be less");
892- fprintf(stream, " than or equal\n\t\tto the block size and 8192 bytes");
893- fprintf(stream, " or larger. It must also be\n\t\tstorable in the xz");
894- fprintf(stream, " header as either 2^n or as 2^n+2^(n+1).\n\t\t");
895- fprintf(stream, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or");
896- fprintf(stream, " 32K, 16K, 8K\n\t\tetc.\n");
897- fprintf(stream, "\t -Xpreset <preset-level>\n");
898- fprintf(stream, "\t\tUse <preset-value> as the custom preset to use");
899- fprintf(stream, " on compress.\n\t\t<preset-level> should be 0 .. 9");
900- fprintf(stream, " (default 6)\n");
901- fprintf(stream, "\t -Xe\n");
902- fprintf(stream, "\t\tEnable additional compression settings by passing");
903- fprintf(stream, " the EXTREME\n\t\tflag to the compression flags.\n");
904- fprintf(stream, "\t -Xlc <value>\n");
905- fprintf(stream, "\t -Xlp <value>\n");
906- fprintf(stream, "\t -Xpb <value>\n");
907 }
908
909
910--- a/squashfs-tools/Makefile
911+++ b/squashfs-tools/Makefile
912@@ -263,6 +263,8 @@ COMPRESSORS += xz
913 endif
914
915 ifneq ($(LZMA_XZ_SUPPORT)$(XZ_SUPPORT),)
916+MKSQUASHFS_OBJS += lzma_xz_options.o
917+UNSQUASHFS_OBJS += lzma_xz_options.o
918 ifneq ($(LZMA_LIB),)
919 MKSQUASHFS_OBJS += $(LZMA_LIB)
920 UNSQUASHFS_OBJS += $(LZMA_LIB)