stages: 2/01-busybox: update .config
[dragora.git] / patches / squashfs-tools / squashfs-tools-4.4_lzip-0.diff
blobfc42014a2b0769ab295589df1d32ee6952614b71
1 diff -urdN squashfs-tools-4.4/squashfs-tools/Makefile squashfs-tools-4.4.new/squashfs-tools/Makefile
2 --- squashfs-tools-4.4/squashfs-tools/Makefile 2019-08-29 03:58:04.000000000 +0200
3 +++ squashfs-tools-4.4.new/squashfs-tools/Makefile 2019-09-07 18:49:55.000000000 +0200
4 @@ -17,6 +17,15 @@
6 GZIP_SUPPORT = 1
8 +########### Building LZIP support #############
9 +#
10 +# The lzlib library (http://www.nongnu.org/lzip/lzlib.html) is supported.
12 +# To build using lzlib - install the library and uncomment the
13 +# LZIP_SUPPORT line below.
15 +LZIP_SUPPORT = 1
17 ########### Building XZ support #############
19 # LZMA2 compression.
20 @@ -85,7 +94,7 @@
21 # in Mksquashfs. Obviously the compression algorithm must have been
22 # selected to be built
24 -COMP_DEFAULT = gzip
25 +COMP_DEFAULT = lzip
28 ###############################################
29 @@ -172,6 +181,14 @@
30 COMPRESSORS += gzip
31 endif
33 +ifeq ($(LZIP_SUPPORT),1)
34 +CFLAGS += -DLZIP_SUPPORT
35 +MKSQUASHFS_OBJS += lzip_wrapper.o
36 +UNSQUASHFS_OBJS += lzip_wrapper.o
37 +LIBS += -llz
38 +COMPRESSORS += lzip
39 +endif
41 ifeq ($(LZMA_SUPPORT),1)
42 LZMA_OBJS = $(LZMA_DIR)/C/Alloc.o $(LZMA_DIR)/C/LzFind.o \
43 $(LZMA_DIR)/C/LzmaDec.o $(LZMA_DIR)/C/LzmaEnc.o $(LZMA_DIR)/C/LzmaLib.o
44 @@ -321,6 +338,8 @@
46 gzip_wrapper.o: gzip_wrapper.c squashfs_fs.h gzip_wrapper.h compressor.h
48 +lzip_wrapper.o: lzip_wrapper.c squashfs_fs.h lzip_wrapper.h compressor.h
50 lzma_wrapper.o: lzma_wrapper.c compressor.h squashfs_fs.h
52 lzma_xz_wrapper.o: lzma_xz_wrapper.c compressor.h squashfs_fs.h
53 diff -urdN squashfs-tools-4.4/squashfs-tools/compressor.c squashfs-tools-4.4.new/squashfs-tools/compressor.c
54 --- squashfs-tools-4.4/squashfs-tools/compressor.c 2019-08-29 03:58:04.000000000 +0200
55 +++ squashfs-tools-4.4.new/squashfs-tools/compressor.c 2019-09-07 18:22:09.000000000 +0200
56 @@ -33,6 +33,14 @@
57 extern struct compressor gzip_comp_ops;
58 #endif
60 +#ifndef LZIP_SUPPORT
61 +static struct compressor lzip_comp_ops = {
62 + LZIP_COMPRESSION, "lzip"
63 +};
64 +#else
65 +extern struct compressor lzip_comp_ops;
66 +#endif
68 #ifndef LZMA_SUPPORT
69 static struct compressor lzma_comp_ops = {
70 LZMA_COMPRESSION, "lzma"
71 @@ -80,6 +88,7 @@
73 struct compressor *compressor[] = {
74 &gzip_comp_ops,
75 + &lzip_comp_ops,
76 &lzma_comp_ops,
77 &lzo_comp_ops,
78 &lz4_comp_ops,
79 diff -urdN squashfs-tools-4.4/squashfs-tools/lzip_wrapper.c squashfs-tools-4.4.new/squashfs-tools/lzip_wrapper.c
80 --- squashfs-tools-4.4/squashfs-tools/lzip_wrapper.c 1970-01-01 01:00:00.000000000 +0100
81 +++ squashfs-tools-4.4.new/squashfs-tools/lzip_wrapper.c 2019-09-07 18:22:09.000000000 +0200
82 @@ -0,0 +1,462 @@
83 +/*
84 + * Copyright (c) 2014
85 + * Phillip Lougher <phillip@squashfs.org.uk>
86 + * Copyright (C) 2018 Antonio Diaz Diaz
87 + *
88 + * This program is free software; you can redistribute it and/or
89 + * modify it under the terms of the GNU General Public License
90 + * as published by the Free Software Foundation; either version 2,
91 + * or (at your option) any later version.
92 + *
93 + * This program is distributed in the hope that it will be useful,
94 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
95 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
96 + * GNU General Public License for more details.
97 + *
98 + * You should have received a copy of the GNU General Public License
99 + * along with this program; if not, write to the Free Software
100 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
102 + * lzip_wrapper.c
104 + * Support for LZIP compression using lzlib
105 + * http://www.nongnu.org/lzip/lzlib.html
106 + */
108 +#include <limits.h>
109 +#include <stdint.h>
110 +#include <stdio.h>
111 +#include <stdlib.h>
112 +#include <string.h>
113 +#include <lzlib.h>
115 +#include "squashfs_fs.h"
116 +#include "lzip_wrapper.h"
117 +#include "compressor.h"
119 +static int dictionary_size = 0;
120 +static float dictionary_percent = 0;
122 +/* default compression level */
123 +static int compression_level = LZIP_DEFAULT_COMPRESSION_LEVEL;
125 +/* match_len_limit of each compression level */
126 +const int match_len[] = { 16, 5, 6, 8, 12, 20, 36, 68, 132, 273 };
128 +static inline int isvalid_ds( const int dictionary_size )
130 + return (dictionary_size >= LZ_min_dictionary_size() &&
131 + dictionary_size <= LZ_max_dictionary_size());
135 + * This function is called by the options parsing code in mksquashfs.c
136 + * to parse any -X compressor option.
138 + * Two specific options are supported:
139 + * -Xcompression-level
140 + * -Xdict-size
142 + * This function returns:
143 + * >=0 (number of additional args parsed) on success
144 + * -1 if the option was unrecognised, or
145 + * -2 if the option was recognised, but otherwise bad in
146 + * some way (e.g. invalid parameter)
148 + * Note: this function sets internal compressor state, but does not
149 + * pass back the results of the parsing other than success/failure.
150 + * The lzip_dump_options() function is called later to get the options in
151 + * a format suitable for writing to the filesystem.
152 + */
153 +static int lzip_options(char *argv[], int argc)
155 + if(strcmp(argv[0], "-Xcompression-level") == 0) {
156 + if(argc < 2) {
157 + fprintf(stderr, "lzip: -Xcompression-level missing "
158 + "compression level\n");
159 + fprintf(stderr, "lzip: -Xcompression-level it "
160 + "should be 0 <= n <= 9\n");
161 + goto failed;
164 + compression_level = atoi(argv[1]);
165 + if(compression_level < 0 || compression_level > 9) {
166 + fprintf(stderr, "lzip: -Xcompression-level invalid, it "
167 + "should be 0 <= n <= 9\n");
168 + goto failed;
170 + if(compression_level == 0) {
171 + dictionary_size = 65535;
172 + dictionary_percent = 0;
175 + return 1;
176 + } else if(strcmp(argv[0], "-Xdict-size") == 0) {
177 + char *b;
178 + float size;
180 + if(argc < 2) {
181 + fprintf(stderr, "lzip: -Xdict-size missing dict-size\n");
182 + goto failed;
185 + size = strtof(argv[1], &b);
186 + if(*b == '%') {
187 + if(size <= 0 || size > 100) {
188 + fprintf(stderr, "lzip: -Xdict-size percentage "
189 + "should be 0%% < dict-size <= 100%%\n");
190 + goto failed;
193 + dictionary_size = 0;
194 + dictionary_percent = size;
195 + } else {
196 + if((float) ((int) size) != size) {
197 + fprintf(stderr, "lzip: -Xdict-size can't be "
198 + "fractional unless a percentage of the"
199 + " block size\n");
200 + goto failed;
203 + dictionary_size = (int) size;
204 + dictionary_percent = 0;
206 + if(*b == 'k' || *b == 'K')
207 + dictionary_size *= 1024;
208 + else if(*b == 'm' || *b == 'M')
209 + dictionary_size *= 1024 * 1024;
210 + else if(*b != '\0') {
211 + fprintf(stderr, "lzip: -Xdict-size invalid "
212 + "dict-size\n");
213 + goto failed;
215 + if(!isvalid_ds(dictionary_size)) {
216 + fprintf(stderr, "lzip: -Xdict-size invalid, it "
217 + "should be %d <= n <= %d\n",
218 + LZ_min_dictionary_size(),
219 + LZ_max_dictionary_size());
220 + goto failed;
224 + return 1;
227 + return -1;
229 +failed:
230 + return -2;
235 + * This function is called after all options have been parsed.
236 + * It is used to do post-processing on the compressor options using
237 + * values that were not expected to be known at option parse time.
239 + * In this case block_size may not be known until after -Xdict-size has
240 + * been processed (in the case where -b is specified after -Xdict-size)
242 + * This function returns 0 on successful post processing, or
243 + * -1 on error
244 + */
245 +static int lzip_options_post(int block_size)
247 + /*
248 + * if -Xdict-size has been specified use this to compute the datablock
249 + * dictionary size
250 + */
251 + if(dictionary_size || dictionary_percent) {
252 + if(dictionary_size) {
253 + if(dictionary_size > block_size) {
254 + fprintf(stderr, "lzip: -Xdict-size is larger than"
255 + " block_size\n");
256 + goto failed;
258 + } else
259 + dictionary_size = block_size * dictionary_percent / 100;
261 + if(dictionary_size < 4096) {
262 + fprintf(stderr, "lzip: -Xdict-size should be 4096 bytes "
263 + "or larger\n");
264 + goto failed;
267 + } else
268 + /* No -Xdict-size specified, use defaults */
269 + dictionary_size = block_size;
271 + return 0;
273 +failed:
274 + return -1;
279 + * This function is called by mksquashfs to dump the parsed
280 + * compressor options in a format suitable for writing to the
281 + * compressor options field in the filesystem (stored immediately
282 + * after the superblock).
284 + * This function returns a pointer to the compression options structure
285 + * to be stored (and the size), or NULL if there are no compression
286 + * options
287 + */
288 +static void *lzip_dump_options(int block_size, int *size)
290 + static struct lzip_comp_opts comp_opts;
292 + /*
293 + * don't store compressor specific options in file system if the
294 + * default options are being used - no compressor options in the
295 + * file system means the default options are always assumed
297 + * Defaults are:
298 + * compression_level: LZIP_DEFAULT_COMPRESSION_LEVEL
299 + * metadata dictionary size: SQUASHFS_METADATA_SIZE
300 + * datablock dictionary size: block_size
301 + */
302 + if(dictionary_size == block_size &&
303 + compression_level == LZIP_DEFAULT_COMPRESSION_LEVEL)
304 + return NULL;
306 + comp_opts.dictionary_size = dictionary_size;
307 + comp_opts.compression_level = compression_level;
309 + SQUASHFS_INSWAP_COMP_OPTS(&comp_opts);
311 + *size = sizeof(comp_opts);
312 + return &comp_opts;
316 +/* Check and swap options read from the filesystem. */
317 +static int lzip_check_options(struct lzip_comp_opts *comp_opts, int size)
319 + /* check passed comp opts struct is of the correct length */
320 + if(size != sizeof(struct lzip_comp_opts))
321 + goto failed;
323 + SQUASHFS_INSWAP_COMP_OPTS(comp_opts);
325 + /* Check comp_opts structure for correctness */
326 + if(!isvalid_ds(comp_opts->dictionary_size)) {
327 + fprintf(stderr, "lzip: bad dictionary size in "
328 + "compression options structure\n");
329 + goto failed;
332 + if(comp_opts->compression_level > 9) {
333 + fprintf(stderr, "lzip: bad compression level in "
334 + "compression options structure\n");
335 + goto failed;
338 + return 1;
340 +failed:
341 + fprintf(stderr, "lzip: error reading stored compressor options from "
342 + "filesystem!\n");
343 + return 0;
348 + * This function is a helper specifically for the append mode of
349 + * mksquashfs. Its purpose is to set the internal compressor state
350 + * to the stored compressor options in the passed compressor options
351 + * structure.
353 + * In effect this function sets up the compressor options
354 + * to the same state they were when the filesystem was originally
355 + * generated, this is to ensure on appending, the compressor uses
356 + * the same compression options that were used to generate the
357 + * original filesystem.
359 + * Note, even if there are no compressor options, this function is still
360 + * called with an empty compressor structure (size == 0), to explicitly
361 + * set the default options, this is to ensure any user supplied
362 + * -X options on the appending mksquashfs command line are over-ridden
364 + * This function returns 0 on sucessful extraction of options, and
365 + * -1 on error
366 + */
367 +static int lzip_extract_options(int block_size, void *buffer, int size)
369 + if(size == 0) {
370 + /* set defaults */
371 + dictionary_size = block_size;
372 + compression_level = LZIP_DEFAULT_COMPRESSION_LEVEL;
373 + } else {
374 + struct lzip_comp_opts *comp_opts = buffer;
375 + if(!lzip_check_options(comp_opts, size))
376 + return -1;
378 + dictionary_size = comp_opts->dictionary_size;
379 + compression_level = comp_opts->compression_level;
382 + return 0;
386 +static void lzip_display_options(void *buffer, int size)
388 + struct lzip_comp_opts *comp_opts = buffer;
389 + if(!lzip_check_options(comp_opts, size))
390 + return;
392 + printf("\tcompression-level %d\n", comp_opts->compression_level);
393 + printf("\tDictionary size %d\n", comp_opts->dictionary_size);
398 + * This function is called by mksquashfs to allocate and initialise
399 + * a lzip_stream struct, before compress() is called.
401 + * This function returns 0 on success, and
402 + * -1 on error
403 + */
404 +static int lzip_init(void **strm, int block_size, int datablock)
406 + struct lzip_stream * const stream = malloc(sizeof(struct lzip_stream));
408 + if(!stream)
409 + return -1;
411 + /* dict == 65535 and match_len == 16 choose fast encoder */
412 + stream->dictionary_size =
413 + (datablock || (compression_level == 0 && dictionary_size == 65535)) ?
414 + dictionary_size : SQUASHFS_METADATA_SIZE;
415 + stream->match_len_limit = match_len[compression_level];
416 + *strm = stream;
417 + return 0;
421 +/* Can be called multiple times after each call to lzip_init */
422 +static int lzip_compress(void *strm, void *dest, void *src, int size,
423 + int block_size, int *error)
425 + int ipos = 0, opos = 0;
426 + struct lzip_stream * const stream = strm;
427 + struct LZ_Encoder * const encoder =
428 + LZ_compress_open(stream->dictionary_size,
429 + stream->match_len_limit, LLONG_MAX);
431 + if(!encoder || LZ_compress_errno(encoder) != LZ_ok) {
432 + *error = LZ_mem_error;
433 + goto failed2;
436 + for(;;) {
437 + int rd = LZ_compress_write(encoder, src + ipos, size - ipos);
438 + if(rd < 0)
439 + goto failed;
440 + ipos += rd;
441 + if(ipos >= size)
442 + LZ_compress_finish(encoder);
443 + rd = LZ_compress_read(encoder, dest + opos, block_size - opos);
444 + if(rd < 0)
445 + goto failed;
446 + opos += rd;
447 + if(LZ_compress_finished(encoder) == 1)
448 + break;
449 + if(opos >= block_size) {
450 + /* Output buffer overflow. Return out of buffer space */
451 + opos = 0;
452 + break;
456 + LZ_compress_close(encoder);
457 + return opos;
459 +failed:
460 + /*
461 + * All other errors return failure, with the compressor
462 + * specific error code in *error
463 + */
464 + *error = LZ_compress_errno(encoder);
465 +failed2:
466 + LZ_compress_close(encoder);
467 + return -1;
471 +static int lzip_uncompress(void *dest, void *src, int size, int outsize,
472 + int *error)
474 + int ipos = 0, opos = 0;
475 + struct LZ_Decoder * const decoder = LZ_decompress_open();
477 + if(!decoder || LZ_decompress_errno(decoder) != LZ_ok) {
478 + *error = LZ_mem_error;
479 + goto failed2;
482 + for(;;) {
483 + int rd = LZ_decompress_write(decoder, src + ipos, size - ipos);
484 + if(rd < 0)
485 + goto failed;
486 + ipos += rd;
487 + if(ipos >= size)
488 + LZ_decompress_finish(decoder);
489 + rd = LZ_decompress_read(decoder, dest + opos, outsize - opos);
490 + if(rd < 0)
491 + goto failed;
492 + opos += rd;
493 + if(LZ_decompress_finished(decoder) == 1)
494 + break;
495 + if(opos >= outsize) {
496 + /* Output buffer overflow. Return out of buffer space */
497 + *error = LZ_mem_error;
498 + goto failed2;
502 + LZ_decompress_close(decoder);
503 + return opos;
505 +failed:
506 + /*
507 + * All other errors return failure, with the compressor
508 + * specific error code in *error
509 + */
510 + *error = LZ_decompress_errno(decoder);
511 +failed2:
512 + LZ_decompress_close(decoder);
513 + return -1;
517 +static void lzip_usage()
519 + fprintf(stderr, "\t -Xcompression-level <compression-level>\n"
520 + "\t\t<compression-level> should be 0 .. 9 (default %d)\n",
521 + LZIP_DEFAULT_COMPRESSION_LEVEL);
522 + fprintf(stderr, "\t -Xdict-size <dict-size>\n"
523 + "\t\tUse <dict-size> as the LZIP dictionary size. The dictionary\n"
524 + "\t\tsize can be specified as a percentage of the block size, or\n"
525 + "\t\tas an absolute value. The dictionary size must be less than\n"
526 + "\t\tor equal to the block size and 4096 bytes or larger.\n"
527 + "\t\tExample dict-sizes are 25%%, 37.5%% or 8K, 32K, etc.\n");
531 +struct compressor lzip_comp_ops = {
532 + .init = lzip_init,
533 + .compress = lzip_compress,
534 + .uncompress = lzip_uncompress,
535 + .options = lzip_options,
536 + .options_post = lzip_options_post,
537 + .dump_options = lzip_dump_options,
538 + .extract_options = lzip_extract_options,
539 + .display_options = lzip_display_options,
540 + .usage = lzip_usage,
541 + .id = LZIP_COMPRESSION,
542 + .name = "lzip",
543 + .supported = 1
545 diff -urdN squashfs-tools-4.4/squashfs-tools/lzip_wrapper.h squashfs-tools-4.4.new/squashfs-tools/lzip_wrapper.h
546 --- squashfs-tools-4.4/squashfs-tools/lzip_wrapper.h 1970-01-01 01:00:00.000000000 +0100
547 +++ squashfs-tools-4.4.new/squashfs-tools/lzip_wrapper.h 2019-09-07 18:22:09.000000000 +0200
548 @@ -0,0 +1,58 @@
549 +#ifndef LZIP_WRAPPER_H
550 +#define LZIP_WRAPPER_H
552 + * Squashfs
554 + * Copyright (c) 2014
555 + * Phillip Lougher <phillip@squashfs.org.uk>
556 + * Copyright (C) 2018 Antonio Diaz Diaz
558 + * This program is free software; you can redistribute it and/or
559 + * modify it under the terms of the GNU General Public License
560 + * as published by the Free Software Foundation; either version 2,
561 + * or (at your option) any later version.
563 + * This program is distributed in the hope that it will be useful,
564 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
565 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
566 + * GNU General Public License for more details.
568 + * You should have received a copy of the GNU General Public License
569 + * along with this program; if not, write to the Free Software
570 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
572 + * lzip_wrapper.h
574 + */
576 +#ifndef linux
577 +#define __BYTE_ORDER BYTE_ORDER
578 +#define __BIG_ENDIAN BIG_ENDIAN
579 +#define __LITTLE_ENDIAN LITTLE_ENDIAN
580 +#else
581 +#include <endian.h>
582 +#endif
584 +#if __BYTE_ORDER == __BIG_ENDIAN
585 +extern unsigned int inswap_le32(unsigned int);
587 +#define SQUASHFS_INSWAP_COMP_OPTS(s) { \
588 + (s)->dictionary_size = inswap_le32((s)->dictionary_size); \
590 +#else
591 +#define SQUASHFS_INSWAP_COMP_OPTS(s)
592 +#endif
594 +/* Default compression */
595 +#define LZIP_DEFAULT_COMPRESSION_LEVEL 9
597 +struct lzip_comp_opts {
598 + int32_t dictionary_size;
599 + uint8_t compression_level;
602 +struct lzip_stream {
603 + int dictionary_size;
604 + short match_len_limit;
606 +#endif
607 diff -urdN squashfs-tools-4.4/squashfs-tools/squashfs_fs.h squashfs-tools-4.4.new/squashfs-tools/squashfs_fs.h
608 --- squashfs-tools-4.4/squashfs-tools/squashfs_fs.h 2019-08-29 03:58:04.000000000 +0200
609 +++ squashfs-tools-4.4.new/squashfs-tools/squashfs_fs.h 2019-09-07 18:22:09.000000000 +0200
610 @@ -285,6 +285,7 @@
611 #define XZ_COMPRESSION 4
612 #define LZ4_COMPRESSION 5
613 #define ZSTD_COMPRESSION 6
614 +#define LZIP_COMPRESSION 7
616 struct squashfs_super_block {
617 unsigned int s_magic;