lz4_compression.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Copyright 2019 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <algorithm>
  6. #include <lz4hc.h>
  7. #include "common/assert.h"
  8. #include "common/lz4_compression.h"
  9. namespace Common::Compression {
  10. std::vector<u8> CompressDataLZ4(const u8* source, std::size_t source_size) {
  11. ASSERT_MSG(source_size <= LZ4_MAX_INPUT_SIZE, "Source size exceeds LZ4 maximum input size");
  12. const auto source_size_int = static_cast<int>(source_size);
  13. const int max_compressed_size = LZ4_compressBound(source_size_int);
  14. std::vector<u8> compressed(max_compressed_size);
  15. const int compressed_size = LZ4_compress_default(reinterpret_cast<const char*>(source),
  16. reinterpret_cast<char*>(compressed.data()),
  17. source_size_int, max_compressed_size);
  18. if (compressed_size <= 0) {
  19. // Compression failed
  20. return {};
  21. }
  22. compressed.resize(compressed_size);
  23. return compressed;
  24. }
  25. std::vector<u8> CompressDataLZ4HC(const u8* source, std::size_t source_size,
  26. s32 compression_level) {
  27. ASSERT_MSG(source_size <= LZ4_MAX_INPUT_SIZE, "Source size exceeds LZ4 maximum input size");
  28. compression_level = std::clamp(compression_level, LZ4HC_CLEVEL_MIN, LZ4HC_CLEVEL_MAX);
  29. const auto source_size_int = static_cast<int>(source_size);
  30. const int max_compressed_size = LZ4_compressBound(source_size_int);
  31. std::vector<u8> compressed(max_compressed_size);
  32. const int compressed_size = LZ4_compress_HC(
  33. reinterpret_cast<const char*>(source), reinterpret_cast<char*>(compressed.data()),
  34. source_size_int, max_compressed_size, compression_level);
  35. if (compressed_size <= 0) {
  36. // Compression failed
  37. return {};
  38. }
  39. compressed.resize(compressed_size);
  40. return compressed;
  41. }
  42. std::vector<u8> CompressDataLZ4HCMax(const u8* source, std::size_t source_size) {
  43. return CompressDataLZ4HC(source, source_size, LZ4HC_CLEVEL_MAX);
  44. }
  45. std::vector<u8> DecompressDataLZ4(const std::vector<u8>& compressed,
  46. std::size_t uncompressed_size) {
  47. std::vector<u8> uncompressed(uncompressed_size);
  48. const int size_check = LZ4_decompress_safe(reinterpret_cast<const char*>(compressed.data()),
  49. reinterpret_cast<char*>(uncompressed.data()),
  50. static_cast<int>(compressed.size()),
  51. static_cast<int>(uncompressed.size()));
  52. if (static_cast<int>(uncompressed_size) != size_check) {
  53. // Decompression failed
  54. return {};
  55. }
  56. return uncompressed;
  57. }
  58. } // namespace Common::Compression