1 // SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
2 /*
3 * Copyright (C) 2018-2019 HUAWEI, Inc.
4 * http://www.huawei.com/
5 * Created by Gao Xiang <[email protected]>
6 */
7 #define LZ4_HC_STATIC_LINKING_ONLY (1)
8 #include <lz4hc.h>
9 #include "erofs/internal.h"
10 #include "erofs/print.h"
11 #include "compressor.h"
12
13 #ifndef LZ4_DISTANCE_MAX /* history window size */
14 #define LZ4_DISTANCE_MAX 65535 /* set to maximum value by default */
15 #endif
16
lz4hc_compress_destsize(const struct erofs_compress * c,const void * src,unsigned int * srcsize,void * dst,unsigned int dstsize)17 static int lz4hc_compress_destsize(const struct erofs_compress *c,
18 const void *src, unsigned int *srcsize,
19 void *dst, unsigned int dstsize)
20 {
21 int srcSize = (int)*srcsize;
22 int rc = LZ4_compress_HC_destSize(c->private_data, src, dst,
23 &srcSize, (int)dstsize,
24 c->compression_level);
25 if (!rc)
26 return -EFAULT;
27 *srcsize = srcSize;
28 return rc;
29 }
30
compressor_lz4hc_exit(struct erofs_compress * c)31 static int compressor_lz4hc_exit(struct erofs_compress *c)
32 {
33 if (!c->private_data)
34 return -EINVAL;
35
36 LZ4_freeStreamHC(c->private_data);
37 return 0;
38 }
39
compressor_lz4hc_init(struct erofs_compress * c)40 static int compressor_lz4hc_init(struct erofs_compress *c)
41 {
42 c->private_data = LZ4_createStreamHC();
43 if (!c->private_data)
44 return -ENOMEM;
45
46 c->sbi->lz4.max_distance = max_t(u16, c->sbi->lz4.max_distance,
47 LZ4_DISTANCE_MAX);
48 return 0;
49 }
50
compressor_lz4hc_setlevel(struct erofs_compress * c,int compression_level)51 static int compressor_lz4hc_setlevel(struct erofs_compress *c,
52 int compression_level)
53 {
54 if (compression_level > erofs_compressor_lz4hc.best_level) {
55 erofs_err("invalid compression level %d", compression_level);
56 return -EINVAL;
57 }
58
59 c->compression_level = compression_level < 0 ?
60 LZ4HC_CLEVEL_DEFAULT : compression_level;
61 return 0;
62 }
63
64 const struct erofs_compressor erofs_compressor_lz4hc = {
65 .default_level = LZ4HC_CLEVEL_DEFAULT,
66 .best_level = LZ4HC_CLEVEL_MAX,
67 .init = compressor_lz4hc_init,
68 .exit = compressor_lz4hc_exit,
69 .setlevel = compressor_lz4hc_setlevel,
70 .compress_destsize = lz4hc_compress_destsize,
71 };
72