uboot/lib/zstd/zstd.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2021 Google LLC
   4 */
   5
   6#define LOG_CATEGORY    LOGC_BOOT
   7
   8#include <common.h>
   9#include <abuf.h>
  10#include <log.h>
  11#include <malloc.h>
  12#include <linux/zstd.h>
  13
  14int zstd_decompress(struct abuf *in, struct abuf *out)
  15{
  16        ZSTD_DStream *dstream;
  17        ZSTD_inBuffer in_buf;
  18        ZSTD_outBuffer out_buf;
  19        void *workspace;
  20        size_t wsize;
  21        int ret;
  22
  23        wsize = ZSTD_DStreamWorkspaceBound(abuf_size(in));
  24        workspace = malloc(wsize);
  25        if (!workspace) {
  26                debug("%s: cannot allocate workspace of size %zu\n", __func__,
  27                        wsize);
  28                return -ENOMEM;
  29        }
  30
  31        dstream = ZSTD_initDStream(abuf_size(in), workspace, wsize);
  32        if (!dstream) {
  33                log_err("%s: ZSTD_initDStream failed\n", __func__);
  34                ret = -EPERM;
  35                goto do_free;
  36        }
  37
  38        in_buf.src = abuf_data(in);
  39        in_buf.pos = 0;
  40        in_buf.size = abuf_size(in);
  41
  42        out_buf.dst = abuf_data(out);
  43        out_buf.pos = 0;
  44        out_buf.size = abuf_size(out);
  45
  46        while (1) {
  47                size_t res;
  48
  49                res = ZSTD_decompressStream(dstream, &out_buf, &in_buf);
  50                if (ZSTD_isError(res)) {
  51                        ret = ZSTD_getErrorCode(res);
  52                        log_err("ZSTD_decompressStream error %d\n", ret);
  53                        goto do_free;
  54                }
  55
  56                if (in_buf.pos >= abuf_size(in) || !res)
  57                        break;
  58        }
  59
  60        ret = out_buf.pos;
  61do_free:
  62        free(workspace);
  63        return ret;
  64}
  65