Prepare v2024.10
[platform/kernel/u-boot.git] / lib / zstd / zstd.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2021 Google LLC
4  */
5
6 #define LOG_CATEGORY    LOGC_BOOT
7
8 #include <abuf.h>
9 #include <log.h>
10 #include <malloc.h>
11 #include <linux/errno.h>
12 #include <linux/zstd.h>
13
14 int zstd_decompress(struct abuf *in, struct abuf *out)
15 {
16         zstd_dctx *ctx;
17         size_t wsize, len;
18         void *workspace;
19         int ret;
20
21         wsize = zstd_dctx_workspace_bound();
22         workspace = malloc(wsize);
23         if (!workspace) {
24                 debug("%s: cannot allocate workspace of size %zu\n", __func__,
25                         wsize);
26                 return -ENOMEM;
27         }
28
29         ctx = zstd_init_dctx(workspace, wsize);
30         if (!ctx) {
31                 log_err("%s: zstd_init_dctx() failed\n", __func__);
32                 ret = -EPERM;
33                 goto do_free;
34         }
35
36         /*
37          * Find out how large the frame actually is, there may be junk at
38          * the end of the frame that zstd_decompress_dctx() can't handle.
39          */
40         len = zstd_find_frame_compressed_size(abuf_data(in), abuf_size(in));
41         if (zstd_is_error(len)) {
42                 log_err("%s: failed to detect compressed size: %d\n", __func__,
43                         zstd_get_error_code(len));
44                 ret = -EINVAL;
45                 goto do_free;
46         }
47
48         len = zstd_decompress_dctx(ctx, abuf_data(out), abuf_size(out),
49                                    abuf_data(in), len);
50         if (zstd_is_error(len)) {
51                 log_err("%s: failed to decompress: %d\n", __func__,
52                         zstd_get_error_code(len));
53                 ret = -EINVAL;
54                 goto do_free;
55         }
56
57         ret = len;
58 do_free:
59         free(workspace);
60         return ret;
61 }