2
0

160-expose_lzma_xz_options.patch 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  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. #include "squashfs_fs.h"
  491. #include "compressor.h"
  492. +#include "lzma_xz_options.h"
  493. #define LZMA_PROPS_SIZE 5
  494. #define LZMA_UNCOMP_SIZE 8
  495. @@ -38,13 +39,27 @@
  496. static int lzma_compress(void *dummy, void *dest, void *src, int size,
  497. int block_size, int *error)
  498. {
  499. + uint32_t preset;
  500. unsigned char *d = (unsigned char *) dest;
  501. + struct lzma_xz_options *opts = lzma_xz_get_options();
  502. +
  503. lzma_options_lzma opt;
  504. lzma_stream strm = LZMA_STREAM_INIT;
  505. int res;
  506. - lzma_lzma_preset(&opt, LZMA_OPTIONS);
  507. - opt.dict_size = block_size;
  508. + preset = opts->preset;
  509. +
  510. + if (opts->extreme)
  511. + preset |= LZMA_PRESET_EXTREME;
  512. +
  513. + lzma_lzma_preset(&opt, opts->preset);
  514. + opt.lc = opts->lc;
  515. + opt.lp = opts->lp;
  516. + opt.pb = opts->pb;
  517. + if (opts->fb)
  518. + opt.nice_len = opts->fb;
  519. +
  520. + opt.dict_size = opts->dict_size;
  521. res = lzma_alone_encoder(&strm, &opt);
  522. if(res != LZMA_OK) {
  523. @@ -143,13 +158,45 @@ failed:
  524. return -1;
  525. }
  526. +static int lzma_options(char *argv[], int argc)
  527. +{
  528. + return lzma_xz_options(argv, argc, LZMA_OPT_LZMA);
  529. +}
  530. +
  531. +
  532. +static int lzma_options_post(int block_size)
  533. +{
  534. + return lzma_xz_options_post(block_size, LZMA_OPT_LZMA);
  535. +}
  536. +
  537. +
  538. +static void *lzma_dump_options(int block_size, int *size)
  539. +{
  540. + return lzma_xz_dump_options(block_size, size, 0);
  541. +}
  542. +
  543. +
  544. +static int lzma_extract_options(int block_size, void *buffer, int size)
  545. +{
  546. + return lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_LZMA);
  547. +}
  548. +
  549. +
  550. +void lzma_usage()
  551. +{
  552. + lzma_xz_usage(LZMA_OPT_LZMA);
  553. +}
  554. +
  555. struct compressor lzma_comp_ops = {
  556. .init = NULL,
  557. .compress = lzma_compress,
  558. .uncompress = lzma_uncompress,
  559. - .options = NULL,
  560. - .usage = NULL,
  561. + .options = lzma_options,
  562. + .options_post = lzma_options_post,
  563. + .dump_options = lzma_dump_options,
  564. + .extract_options = lzma_extract_options,
  565. + .usage = lzma_usage,
  566. .id = LZMA_COMPRESSION,
  567. .name = "lzma",
  568. .supported = 1
  569. --- a/squashfs-tools/xz_wrapper.h
  570. +++ b/squashfs-tools/xz_wrapper.h
  571. @@ -24,25 +24,6 @@
  572. *
  573. */
  574. -#ifndef linux
  575. -#define __BYTE_ORDER BYTE_ORDER
  576. -#define __BIG_ENDIAN BIG_ENDIAN
  577. -#define __LITTLE_ENDIAN LITTLE_ENDIAN
  578. -#else
  579. -#include <endian.h>
  580. -#endif
  581. -
  582. -#if __BYTE_ORDER == __BIG_ENDIAN
  583. -extern unsigned int inswap_le32(unsigned int);
  584. -
  585. -#define SQUASHFS_INSWAP_COMP_OPTS(s) { \
  586. - (s)->dictionary_size = inswap_le32((s)->dictionary_size); \
  587. - (s)->flags = inswap_le32((s)->flags); \
  588. -}
  589. -#else
  590. -#define SQUASHFS_INSWAP_COMP_OPTS(s)
  591. -#endif
  592. -
  593. #define MEMLIMIT (32 * 1024 * 1024)
  594. struct bcj {
  595. --- a/squashfs-tools/xz_wrapper.c
  596. +++ b/squashfs-tools/xz_wrapper.c
  597. @@ -30,6 +30,7 @@
  598. #include "squashfs_fs.h"
  599. #include "xz_wrapper.h"
  600. #include "compressor.h"
  601. +#include "lzma_xz_options.h"
  602. static struct bcj bcj[] = {
  603. { "x86", LZMA_FILTER_X86, 0 },
  604. @@ -41,22 +42,18 @@ static struct bcj bcj[] = {
  605. { NULL, LZMA_VLI_UNKNOWN, 0 }
  606. };
  607. -static struct comp_opts comp_opts;
  608. -
  609. static int filter_count = 1;
  610. -static int dictionary_size = 0;
  611. -static float dictionary_percent = 0;
  612. static int xz_options(char *argv[], int argc)
  613. {
  614. - int i;
  615. - char *name;
  616. -
  617. if(strcmp(argv[0], "-Xbcj") == 0) {
  618. + int i;
  619. + char *name;
  620. +
  621. if(argc < 2) {
  622. fprintf(stderr, "xz: -Xbcj missing filter\n");
  623. - goto failed;
  624. + return -2;
  625. }
  626. name = argv[1];
  627. @@ -76,190 +73,50 @@ static int xz_options(char *argv[], int
  628. }
  629. if(bcj[i].name == NULL) {
  630. fprintf(stderr, "xz: -Xbcj unrecognised "
  631. - "filter\n");
  632. - goto failed;
  633. - }
  634. - }
  635. -
  636. - return 1;
  637. - } else if(strcmp(argv[0], "-Xdict-size") == 0) {
  638. - char *b;
  639. - float size;
  640. -
  641. - if(argc < 2) {
  642. - fprintf(stderr, "xz: -Xdict-size missing dict-size\n");
  643. - goto failed;
  644. - }
  645. -
  646. - size = strtof(argv[1], &b);
  647. - if(*b == '%') {
  648. - if(size <= 0 || size > 100) {
  649. - fprintf(stderr, "xz: -Xdict-size percentage "
  650. - "should be 0 < dict-size <= 100\n");
  651. - goto failed;
  652. - }
  653. -
  654. - dictionary_percent = size;
  655. - dictionary_size = 0;
  656. - } else {
  657. - if((float) ((int) size) != size) {
  658. - fprintf(stderr, "xz: -Xdict-size can't be "
  659. - "fractional unless a percentage of the"
  660. - " block size\n");
  661. - goto failed;
  662. - }
  663. -
  664. - dictionary_percent = 0;
  665. - dictionary_size = (int) size;
  666. -
  667. - if(*b == 'k' || *b == 'K')
  668. - dictionary_size *= 1024;
  669. - else if(*b == 'm' || *b == 'M')
  670. - dictionary_size *= 1024 * 1024;
  671. - else if(*b != '\0') {
  672. - fprintf(stderr, "xz: -Xdict-size invalid "
  673. - "dict-size\n");
  674. - goto failed;
  675. + "filter\n");
  676. + return -2;
  677. }
  678. }
  679. -
  680. return 1;
  681. + } else {
  682. + return lzma_xz_options(argv, argc, LZMA_OPT_XZ);
  683. }
  684. -
  685. - return -1;
  686. -
  687. -failed:
  688. - return -2;
  689. }
  690. static int xz_options_post(int block_size)
  691. {
  692. - /*
  693. - * if -Xdict-size has been specified use this to compute the datablock
  694. - * dictionary size
  695. - */
  696. - if(dictionary_size || dictionary_percent) {
  697. - int n;
  698. -
  699. - if(dictionary_size) {
  700. - if(dictionary_size > block_size) {
  701. - fprintf(stderr, "xz: -Xdict-size is larger than"
  702. - " block_size\n");
  703. - goto failed;
  704. - }
  705. - } else
  706. - dictionary_size = block_size * dictionary_percent / 100;
  707. -
  708. - if(dictionary_size < 8192) {
  709. - fprintf(stderr, "xz: -Xdict-size should be 8192 bytes "
  710. - "or larger\n");
  711. - goto failed;
  712. - }
  713. -
  714. - /*
  715. - * dictionary_size must be storable in xz header as either
  716. - * 2^n or as 2^n+2^(n+1)
  717. - */
  718. - n = ffs(dictionary_size) - 1;
  719. - if(dictionary_size != (1 << n) &&
  720. - dictionary_size != ((1 << n) + (1 << (n + 1)))) {
  721. - fprintf(stderr, "xz: -Xdict-size is an unsupported "
  722. - "value, dict-size must be storable in xz "
  723. - "header\n");
  724. - fprintf(stderr, "as either 2^n or as 2^n+2^(n+1). "
  725. - "Example dict-sizes are 75%%, 50%%, 37.5%%, "
  726. - "25%%,\n");
  727. - fprintf(stderr, "or 32K, 16K, 8K etc.\n");
  728. - goto failed;
  729. - }
  730. -
  731. - } else
  732. - /* No -Xdict-size specified, use defaults */
  733. - dictionary_size = block_size;
  734. -
  735. - return 0;
  736. -
  737. -failed:
  738. - return -1;
  739. + return lzma_xz_options_post(block_size, LZMA_OPT_XZ);
  740. }
  741. static void *xz_dump_options(int block_size, int *size)
  742. {
  743. - int flags = 0, i;
  744. -
  745. - /*
  746. - * don't store compressor specific options in file system if the
  747. - * default options are being used - no compressor options in the
  748. - * file system means the default options are always assumed
  749. - *
  750. - * Defaults are:
  751. - * metadata dictionary size: SQUASHFS_METADATA_SIZE
  752. - * datablock dictionary size: block_size
  753. - * 1 filter
  754. - */
  755. - if(dictionary_size == block_size && filter_count == 1)
  756. - return NULL;
  757. + int i, flags = 0;
  758. for(i = 0; bcj[i].name; i++)
  759. flags |= bcj[i].selected << i;
  760. - comp_opts.dictionary_size = dictionary_size;
  761. - comp_opts.flags = flags;
  762. -
  763. - SQUASHFS_INSWAP_COMP_OPTS(&comp_opts);
  764. -
  765. - *size = sizeof(comp_opts);
  766. - return &comp_opts;
  767. + return lzma_xz_dump_options(block_size, size, flags);
  768. }
  769. static int xz_extract_options(int block_size, void *buffer, int size)
  770. {
  771. - struct comp_opts *comp_opts = buffer;
  772. - int flags, i, n;
  773. -
  774. - if(size == 0) {
  775. - /* set defaults */
  776. - dictionary_size = block_size;
  777. - flags = 0;
  778. - } else {
  779. - /* check passed comp opts struct is of the correct length */
  780. - if(size != sizeof(struct comp_opts))
  781. - goto failed;
  782. -
  783. - SQUASHFS_INSWAP_COMP_OPTS(comp_opts);
  784. -
  785. - dictionary_size = comp_opts->dictionary_size;
  786. - flags = comp_opts->flags;
  787. -
  788. - /*
  789. - * check that the dictionary size seems correct - the dictionary
  790. - * size should 2^n or 2^n+2^(n+1)
  791. - */
  792. - n = ffs(dictionary_size) - 1;
  793. - if(dictionary_size != (1 << n) &&
  794. - dictionary_size != ((1 << n) + (1 << (n + 1))))
  795. - goto failed;
  796. - }
  797. + int ret = lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_XZ);
  798. - filter_count = 1;
  799. - for(i = 0; bcj[i].name; i++) {
  800. - if((flags >> i) & 1) {
  801. - bcj[i].selected = 1;
  802. - filter_count ++;
  803. - } else
  804. - bcj[i].selected = 0;
  805. + if (!ret) {
  806. + int i;
  807. + struct lzma_xz_options *opts = lzma_xz_get_options();
  808. + for(i = 0; bcj[i].name; i++) {
  809. + if((opts->flags >> i) & 1) {
  810. + bcj[i].selected = 1;
  811. + filter_count ++;
  812. + } else
  813. + bcj[i].selected = 0;
  814. + }
  815. }
  816. -
  817. - return 0;
  818. -
  819. -failed:
  820. - fprintf(stderr, "xz: error reading stored compressor options from "
  821. - "filesystem!\n");
  822. -
  823. - return -1;
  824. + return ret;
  825. }
  826. @@ -268,6 +125,7 @@ static int xz_init(void **strm, int bloc
  827. int i, j, filters = datablock ? filter_count : 1;
  828. struct filter *filter = malloc(filters * sizeof(struct filter));
  829. struct xz_stream *stream;
  830. + struct lzma_xz_options *opts = lzma_xz_get_options();
  831. if(filter == NULL)
  832. goto failed;
  833. @@ -281,7 +139,7 @@ static int xz_init(void **strm, int bloc
  834. memset(filter, 0, filters * sizeof(struct filter));
  835. - stream->dictionary_size = datablock ? dictionary_size :
  836. + stream->dictionary_size = datablock ? opts->dict_size :
  837. SQUASHFS_METADATA_SIZE;
  838. filter[0].filter[0].id = LZMA_FILTER_LZMA2;
  839. @@ -323,14 +181,25 @@ static int xz_compress(void *strm, void
  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. stream->filter[0].buffer = dest;
  845. for(i = 0; i < stream->filters; i++) {
  846. + uint32_t preset = opts->preset;
  847. struct filter *filter = &stream->filter[i];
  848. - if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT))
  849. - goto failed;
  850. + if (opts->extreme)
  851. + preset |= LZMA_PRESET_EXTREME;
  852. +
  853. + if(lzma_lzma_preset(&stream->opt, preset))
  854. + goto failed;
  855. +
  856. + stream->opt.lc = opts->lc;
  857. + stream->opt.lp = opts->lp;
  858. + stream->opt.pb = opts->pb;
  859. + if (opts->fb)
  860. + stream->opt.nice_len = opts->fb;
  861. stream->opt.dict_size = stream->dictionary_size;
  862. @@ -384,22 +253,13 @@ static int xz_uncompress(void *dest, voi
  863. void xz_usage()
  864. {
  865. + lzma_xz_usage(LZMA_OPT_XZ);
  866. fprintf(stderr, "\t -Xbcj filter1,filter2,...,filterN\n");
  867. fprintf(stderr, "\t\tCompress using filter1,filter2,...,filterN in");
  868. fprintf(stderr, " turn\n\t\t(in addition to no filter), and choose");
  869. fprintf(stderr, " the best compression.\n");
  870. fprintf(stderr, "\t\tAvailable filters: x86, arm, armthumb,");
  871. fprintf(stderr, " powerpc, sparc, ia64\n");
  872. - fprintf(stderr, "\t -Xdict-size <dict-size>\n");
  873. - fprintf(stderr, "\t\tUse <dict-size> as the XZ dictionary size. The");
  874. - fprintf(stderr, " dictionary size\n\t\tcan be specified as a");
  875. - fprintf(stderr, " percentage of the block size, or as an\n\t\t");
  876. - fprintf(stderr, "absolute value. The dictionary size must be less");
  877. - fprintf(stderr, " than or equal\n\t\tto the block size and 8192 bytes");
  878. - fprintf(stderr, " or larger. It must also be\n\t\tstorable in the xz");
  879. - fprintf(stderr, " header as either 2^n or as 2^n+2^(n+1).\n\t\t");
  880. - fprintf(stderr, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or");
  881. - fprintf(stderr, " 32K, 16K, 8K\n\t\tetc.\n");
  882. }
  883. --- a/squashfs-tools/Makefile
  884. +++ b/squashfs-tools/Makefile
  885. @@ -140,6 +140,8 @@ COMPRESSORS += xz
  886. endif
  887. ifneq ($(LZMA_XZ_SUPPORT)$(XZ_SUPPORT),)
  888. +MKSQUASHFS_OBJS += lzma_xz_options.o
  889. +UNSQUASHFS_OBJS += lzma_xz_options.o
  890. ifneq ($(LZMA_LIB),)
  891. MKSQUASHFS_OBJS += $(LZMA_LIB)
  892. UNSQUASHFS_OBJS += $(LZMA_LIB)