OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 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 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/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) |