]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - SQUASHFS/squashfs-tools-4.4/squashfs-tools/lzma_xz_wrapper.c
2 * Copyright (c) 2010, 2013
3 * Phillip Lougher <phillip@squashfs.org.uk>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2,
8 * or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Support for LZMA1 compression using XZ Utils liblzma http://tukaani.org/xz/
28 #include "squashfs_fs.h"
29 #include "compressor.h"
31 #define LZMA_PROPS_SIZE 5
32 #define LZMA_UNCOMP_SIZE 8
33 #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + LZMA_UNCOMP_SIZE)
35 #define LZMA_OPTIONS 5
36 #define MEMLIMIT (32 * 1024 * 1024)
38 static int lzma_compress(void *dummy
, void *dest
, void *src
, int size
,
39 int block_size
, int *error
)
41 unsigned char *d
= (unsigned char *) dest
;
42 lzma_options_lzma opt
;
43 lzma_stream strm
= LZMA_STREAM_INIT
;
46 lzma_lzma_preset(&opt
, LZMA_OPTIONS
);
47 opt
.dict_size
= block_size
;
49 res
= lzma_alone_encoder(&strm
, &opt
);
56 strm
.avail_out
= block_size
;
60 res
= lzma_code(&strm
, LZMA_FINISH
);
63 if(res
== LZMA_STREAM_END
) {
65 * Fill in the 8 byte little endian uncompressed size field in
66 * the LZMA header. 8 bytes is excessively large for squashfs
67 * but this is the standard LZMA header and which is expected by
71 d
[LZMA_PROPS_SIZE
] = size
& 255;
72 d
[LZMA_PROPS_SIZE
+ 1] = (size
>> 8) & 255;
73 d
[LZMA_PROPS_SIZE
+ 2] = (size
>> 16) & 255;
74 d
[LZMA_PROPS_SIZE
+ 3] = (size
>> 24) & 255;
75 d
[LZMA_PROPS_SIZE
+ 4] = 0;
76 d
[LZMA_PROPS_SIZE
+ 5] = 0;
77 d
[LZMA_PROPS_SIZE
+ 6] = 0;
78 d
[LZMA_PROPS_SIZE
+ 7] = 0;
80 return (int) strm
.total_out
;
85 * Output buffer overflow. Return out of buffer space
91 * All other errors return failure, with the compressor
92 * specific error code in *error
99 static int lzma_uncompress(void *dest
, void *src
, int size
, int outsize
,
102 lzma_stream strm
= LZMA_STREAM_INIT
;
103 int uncompressed_size
= 0, res
;
104 unsigned char lzma_header
[LZMA_HEADER_SIZE
];
106 res
= lzma_alone_decoder(&strm
, MEMLIMIT
);
112 memcpy(lzma_header
, src
, LZMA_HEADER_SIZE
);
113 uncompressed_size
= lzma_header
[LZMA_PROPS_SIZE
] |
114 (lzma_header
[LZMA_PROPS_SIZE
+ 1] << 8) |
115 (lzma_header
[LZMA_PROPS_SIZE
+ 2] << 16) |
116 (lzma_header
[LZMA_PROPS_SIZE
+ 3] << 24);
118 if(uncompressed_size
> outsize
) {
123 memset(lzma_header
+ LZMA_PROPS_SIZE
, 255, LZMA_UNCOMP_SIZE
);
125 strm
.next_out
= dest
;
126 strm
.avail_out
= outsize
;
127 strm
.next_in
= lzma_header
;
128 strm
.avail_in
= LZMA_HEADER_SIZE
;
130 res
= lzma_code(&strm
, LZMA_RUN
);
132 if(res
!= LZMA_OK
|| strm
.avail_in
!= 0) {
137 strm
.next_in
= src
+ LZMA_HEADER_SIZE
;
138 strm
.avail_in
= size
- LZMA_HEADER_SIZE
;
140 res
= lzma_code(&strm
, LZMA_FINISH
);
143 if(res
== LZMA_STREAM_END
|| (res
== LZMA_OK
&&
144 strm
.total_out
>= uncompressed_size
&& strm
.avail_in
== 0))
145 return uncompressed_size
;
153 struct compressor lzma_comp_ops
= {
155 .compress
= lzma_compress
,
156 .uncompress
= lzma_uncompress
,
159 .id
= LZMA_COMPRESSION
,