]> wimlib.net Git - wimlib/blob - src/zstd_compress.c
[EXPERIMENTAL, FOR BENCHMARKING ONLY] Zstandard compression support
[wimlib] / src / zstd_compress.c
1 #ifdef HAVE_CONFIG_H
2 #  include "config.h"
3 #endif
4
5 #include "wimlib/error.h"
6 #include "wimlib/compressor_ops.h"
7 #include "wimlib/util.h"
8
9 #include <zstd.h>
10
11 struct zstd_compressor {
12         unsigned compression_level;
13         ZSTD_CCtx *cctx;
14 };
15
16 static u64
17 zstd_get_needed_memory(size_t max_bufsize, unsigned compression_level,
18                        bool destructive)
19 {
20         return sizeof(struct zstd_compressor);
21 }
22
23 static int
24 zstd_create_compressor(size_t max_bufsize, unsigned compression_level,
25                        bool destructive, void **c_ret)
26 {
27         struct zstd_compressor *c;
28
29         c = MALLOC(sizeof(*c));
30         if (!c)
31                 goto oom;
32
33         c->cctx = ZSTD_createCCtx();
34         if (!c->cctx)
35                 goto oom;
36
37         c->compression_level = compression_level / 5;
38         c->compression_level = max(c->compression_level, 1);
39         c->compression_level = min(c->compression_level, ZSTD_maxCLevel());
40
41         *c_ret = c;
42         return 0;
43
44 oom:
45         FREE(c);
46         return WIMLIB_ERR_NOMEM;
47 }
48
49 static size_t
50 zstd_compress(const void *in, size_t in_nbytes,
51               void *out, size_t out_nbytes_avail, void *_c)
52 {
53         struct zstd_compressor *c = _c;
54         size_t res;
55
56         res = ZSTD_compressCCtx(c->cctx, out, out_nbytes_avail, in, in_nbytes,
57                                 c->compression_level);
58
59         if (ZSTD_isError(res))
60                 return 0;
61         return res;
62 }
63
64 static void
65 zstd_free_compressor(void *_c)
66 {
67         struct zstd_compressor *c = _c;
68
69         FREE(c->cctx);
70         FREE(c);
71 }
72
73 const struct compressor_ops zstd_compressor_ops = {
74         .get_needed_memory      = zstd_get_needed_memory,
75         .create_compressor      = zstd_create_compressor,
76         .compress               = zstd_compress,
77         .free_compressor        = zstd_free_compressor,
78 };
79