blob: b4df4d03e0312d06ec3d7d612b47f09dd373e174 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001#include <linux/lzma.h>
2#include "compr.h"
3
4#ifdef __KERNEL__
5 static DEFINE_MUTEX(deflate_mutex);
6#endif
7
8Byte propsEncoded[LZMA_PROPS_SIZE];
9SizeT propsSize = sizeof(propsEncoded);
10CLzmaEncHandle *p;
11
12STATIC void lzma_free_workspace(void)
13{
14 LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc);
15}
16
17STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props_e)
18{
19 if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL)
20 {
21 PRINT_ERROR("Failed to allocate lzma deflate workspace\n");
22 return -ENOMEM;
23 }
24
25 if (LzmaEnc_SetProps(p, props_e) != SZ_OK)
26 {
27 lzma_free_workspace();
28 return -1;
29 }
30
31 if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK)
32 {
33 lzma_free_workspace();
34 return -1;
35 }
36
37 return 0;
38}
39
40STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out,
41 uint32_t srclen, uint32_t destlen)
42{
43 int ret;
44 SizeT dl = (SizeT)destlen;
45 SizeT sl = (SizeT)srclen;
46 ELzmaStatus status;
47
48 ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded,
49 propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc);
50
51 if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen)
52 return -1;
53
54 return 0;
55}
56
57STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out,
58 uint32_t *sourcelen, uint32_t *dstlen)
59{
60 SizeT compress_size = (SizeT)(*dstlen);
61 int ret;
62
63 #ifdef __KERNEL__
64 mutex_lock(&deflate_mutex);
65 #endif
66
67 ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen,
68 0, NULL, &lzma_alloc, &lzma_alloc);
69
70 #ifdef __KERNEL__
71 mutex_unlock(&deflate_mutex);
72 #endif
73
74 if (ret != SZ_OK)
75 return -1;
76
77 *dstlen = (uint32_t)compress_size;
78
79 return 0;
80}
81
82
83static struct jffs2_compressor jffs2_lzma_comp = {
84 .priority = JFFS2_LZMA_PRIORITY,
85 .name = "lzma",
86 .compr = JFFS2_COMPR_LZMA,
87 .compress = &jffs2_lzma_compress,
88 .decompress = &jffs2_lzma_decompress,
89 .disabled = 0,
90};
91
92void jffs2_lzma_exit(void)
93{
94 jffs2_unregister_compressor(&jffs2_lzma_comp);
95 lzma_free_workspace();
96}
97
98int INIT jffs2_lzma_init(void)
99{
100 int ret;
101 CLzmaEncProps props;
102 LzmaEncProps_Init(&props);
103
104 props.dictSize = LZMA_BEST_DICT(0x2000);
105 props.level = LZMA_BEST_LEVEL;
106 props.lc = LZMA_BEST_LC;
107 props.lp = LZMA_BEST_LP;
108 props.pb = LZMA_BEST_PB;
109 props.fb = LZMA_BEST_FB;
110
111 ret = lzma_alloc_workspace(&props);
112 if (ret < 0)
113 return ret;
114
115 ret = jffs2_register_compressor(&jffs2_lzma_comp);
116 if (ret)
117 lzma_free_workspace();
118
119 return ret;
120}