Root/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)
930

Archive Download this file



interactive