lz4_compression.cpp 2.8 KB

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