blob: e2200146c40bbfb4a051f71bc84f1404c603a38d [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * For licensing information, see the file 'LICENCE' in this directory.
5 *
6 * JFFS2 wrapper to the LZMA C SDK
7 *
8 */
9//#include <stdio.h>
10//#include <stdlib.h>
11//#include <linux/types.h>
12//#include <sys/stat.h>
13//#include <fcntl.h>
14#include <linux/lzma.h>
15
16/*
171.1. Header
18
19 +------------+----+----+----+----+--+--+--+--+--+--+--+--+
20 | Properties | Dictionary Size | Uncompressed Size |
21 +------------+----+----+----+----+--+--+--+--+--+--+--+--+
22
23
241.1.1. Properties
25
26 The Properties field contains three properties. An abbreviation
27 is given in parentheses, followed by the value range of the
28 property. The field consists of
29
30 1) the number of literal context bits (lc, [0, 8]);
31 2) the number of literal position bits (lp, [0, 4]); and
32 3) the number of position bits (pb, [0, 4]).
33
34 The properties are encoded using the following formula:
35
36 Properties = (pb * 5 + lp) * 9 + lc
37
38 The following C code illustrates a straightforward way to
39 decode the Properties field:
40
41 uint8_t lc, lp, pb;
42 uint8_t prop = get_lzma_properties();
43 if (prop > (4 * 5 + 4) * 9 + 8)
44 return LZMA_PROPERTIES_ERROR;
45
46 pb = prop / (9 * 5);
47 prop -= pb * 9 * 5;
48 lp = prop / 9;
49 lc = prop - lp * 9;
50*/
51#if 0
52#define ZTE_LZMA_DICT //(0x100000)
53#define ZTE_LZMA_LC //3
54#define ZTE_LZMA_LP //0
55#define ZTE_LZMA_PB //2
56#endif
57
58static CLzmaEncHandle *p_lzma;
59static Byte propsEncoded_lzma[LZMA_PROPS_SIZE];
60static SizeT propsSize_lzma = sizeof(propsEncoded_lzma);
61
62static void lzma_free_workspace(void)
63{
64 LzmaEnc_Destroy(p_lzma, &lzma_alloc, &lzma_alloc);
65}
66
67static int INIT lzma_alloc_workspace(CLzmaEncProps * props)
68{
69 if ((p_lzma = (CLzmaEncHandle *) LzmaEnc_Create(&lzma_alloc)) == NULL) {
70 PRINT_ERROR("Failed to allocate lzma deflate workspace\n");
71 return -ENOMEM;
72 }
73
74 if (LzmaEnc_SetProps(p_lzma, props) != SZ_OK) {
75 lzma_free_workspace();
76 return -1;
77 }
78
79 if (LzmaEnc_WriteProperties(p_lzma, propsEncoded_lzma, &propsSize_lzma) != SZ_OK) {
80 lzma_free_workspace();
81 return -1;
82 }
83
84 return 0;
85}
86
87static int lzma_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t * sourcelen, uint32_t * dstlen)
88{
89 SizeT compress_size = (SizeT) (*dstlen);
90 int ret;
91
92 ret = LzmaEnc_MemEncode(p_lzma, cpage_out, &compress_size, data_in, *sourcelen, 0, NULL, &lzma_alloc, &lzma_alloc);
93
94 if (ret != SZ_OK)
95 return -1;
96
97 *dstlen = (uint32_t) compress_size;
98
99 return 0;
100}
101
102int lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen)
103{
104 int ret;
105 SizeT dl = (SizeT) destlen;
106 SizeT sl = (SizeT) srclen;
107 ELzmaStatus status;
108
109 ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded_lzma, propsSize_lzma, LZMA_FINISH_ANY, &status, &lzma_alloc);
110
111 if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT) destlen)
112 {
113 return -1;
114 }
115
116 return 0;
117}
118
119int lzma_init(UInt32 *ztelzma_dict,int *ztelzma_lc,int *ztelzma_lp,int *ztelzma_pb)
120{
121 int ret = -1;
122 CLzmaEncProps props;
123 LzmaEncProps_Init(&props);
124
125 props.dictSize = LZMA_BEST_DICT(*ztelzma_dict);
126 props.level = LZMA_BEST_LEVEL;
127 props.lc = *ztelzma_lc; //ZTE_LZMA_LC; //LZMA_BEST_LC;
128 props.lp = *ztelzma_lp; //ZTE_LZMA_LP; //LZMA_BEST_LP;
129 props.pb = *ztelzma_pb; //ZTE_LZMA_PB; //LZMA_BEST_PB;
130 props.fb = LZMA_BEST_FB;
131
132 ret = lzma_alloc_workspace(&props);
133
134 return ret;
135}
136
137#if 0
138int main(int argc, char *argv[])
139{
140 int ret = -1;
141 struct stat stat_buf;
142 char *file_name = NULL;
143 char out_file[2048] = { 0 };
144 int fd1, fd2;
145 char *in;
146 uint32_t in_len;
147 char *out;
148 uint32_t out_len;
149 char *in2;
150 uint32_t in2_len;
151 int i, keep_flag = 0;
152
153 /*
154 LZMA compressed file format
155---------------------------
156Offset Size Description
157 0 1 Special LZMA properties (lc,lp, pb in encoded form)
158 1 4 Dictionary size (little endian)
159 5 8 Uncompressed size (little endian). -1 means unknown size
160 13 Compressed data
161 */
162 uint8_t lzmainfo[13];
163 uint32_t *p_dict = (uint32_t *)(&lzmainfo[1]);
164 uint64_t *p_uncompress_size = (uint64_t *)(&lzmainfo[5]);
165
166 if (argc < 2) {
167 printf("usage:\n\t %s [-k] file\n", argv[0]);
168 return -1;
169 }
170 for (i = 1; i < argc; i++) {
171 if (strcmp(argv[i], "-k") == 0)
172 keep_flag = 1;
173 }
174 file_name = argv[argc - 1];
175 ret = stat(file_name, &stat_buf);
176 if (ret < 0) {
177 printf("stat file %s failed\n", file_name);
178 return -1;
179 }
180
181 in_len = stat_buf.st_size;
182 in = malloc(in_len);
183 in2 = malloc(in_len);
184
185 fd1 = open(file_name, O_RDONLY, 0644);
186 if (fd1 < 0) {
187 perror("open file failed\n");
188 return -1;
189 }
190 ret = read(fd1, in, in_len);
191 if (ret < 0) {
192 perror("read file failed\n");
193 return -1;
194 }
195 close(fd1);
196
197 sprintf(out_file, "%s.lzma", file_name);
198 //printf("out_file is %s\n",out_file);
199 fd2 = open(out_file, O_RDWR | O_CREAT | O_TRUNC, 0666);
200 if (fd2 < 0) {
201 perror("open out file failed\n");
202 return -1;
203 }
204
205 ret = lzma_init();
206 if(ret < 0) {
207 printf("lzma_init failed\n");
208 return -1;
209 }
210
211 out = malloc(in_len * 2);
212 out_len = in_len * 2;
213 ret = lzma_compress(in, out, &in_len, &out_len);
214 if (ret < 0) {
215 printf("lzma compress fail\n");
216 return -1;
217 }
218
219 //(pb * 5 + lp) * 9 + lc;
220 lzmainfo[0] = (ZTE_LZMA_PB * 5 + ZTE_LZMA_LP) * 9 + ZTE_LZMA_LC;
221 *p_dict = ZTE_LZMA_DICT;
222 *p_uncompress_size = in_len;
223 ret = write(fd2, lzmainfo, sizeof(lzmainfo));
224 if(ret < sizeof(lzmainfo)) {
225 printf("write failed:%d\n",ret );
226 return -1;
227 }
228
229 ret = write(fd2, out, out_len);
230 if(ret < out_len) {
231 printf("write failed:%d\n",ret );
232 return -1;
233 }
234 close(fd2);
235
236 ret = lzma_decompress(out, in2, out_len, in_len);
237 if (ret < 0) {
238 printf("lzma decompress fail\n");
239 return -1;
240 }
241
242 if (memcmp(in, in2, in_len) != 0) {
243 printf("in in2 not same\n");
244 return -1;
245 }
246
247 if (!keep_flag)
248 unlink(file_name);
249 return 0;
250}
251#endif