zstd.c 1.3 KB

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