DecompressorLZ4Impl.cpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "DecompressorLZ4Impl.h"
  9. #include <Compression/CompressionLZ4API.h>
  10. #include <lz4.h>
  11. namespace CompressionLZ4
  12. {
  13. // Definitions for LZ4 Compressor
  14. DecompressorLZ4::DecompressorLZ4() = default;
  15. Compression::CompressionAlgorithmId DecompressorLZ4::GetCompressionAlgorithmId() const
  16. {
  17. return GetLZ4CompressionAlgorithmId();
  18. }
  19. AZStd::string_view DecompressorLZ4::GetCompressionAlgorithmName() const
  20. {
  21. return GetLZ4CompressionAlgorithmName();
  22. }
  23. Compression::DecompressionResultData DecompressorLZ4::DecompressBlock(
  24. AZStd::span<AZStd::byte> decompressionBuffer, const AZStd::span<const AZStd::byte>& compressedData,
  25. [[maybe_unused]] const Compression::DecompressionOptions& decompressionOptions) const
  26. {
  27. Compression::DecompressionResultData resultData;
  28. if (decompressionBuffer.empty())
  29. {
  30. resultData.m_decompressionOutcome.m_resultString = Compression::DecompressionResultString(
  31. "Decompression buffer is empty, uncompressed content cannot be stored in it\n");
  32. // Do not return, but hold on to result string in case an error occurs in decompression
  33. }
  34. // Note that this returns a non-negative int so we are narrowing into a size_t here
  35. int decompressedSize = LZ4_decompress_safe(
  36. reinterpret_cast<const char*>(compressedData.data()),
  37. reinterpret_cast<char*>(decompressionBuffer.data()),
  38. static_cast<int>(compressedData.size()),
  39. static_cast<int>(decompressionBuffer.size()));
  40. if (decompressedSize < 0)
  41. {
  42. // LZ4_compress_HC returns a zero value for corrupt data and insufficient buffer
  43. resultData.m_decompressionOutcome.m_resultString += Compression::DecompressionResultString::format(
  44. "LZ4_decompress_safe call has failed. Either the decompression buffer cannot fit all decompressed content "
  45. "or the source stream is malformed. Dest buffer capacity: %zu, source stream size: %zu",
  46. decompressionBuffer.size(), compressedData.size());
  47. resultData.m_decompressionOutcome.m_result = Compression::DecompressionResult::Failed;
  48. return resultData;
  49. }
  50. // Update the result buffer span to point at the beginning of the compressed data and
  51. // the correct compressed size
  52. resultData.m_uncompressedBuffer = decompressionBuffer.subspan(0, decompressedSize);
  53. resultData.m_decompressionOutcome.m_result = Compression::DecompressionResult::Complete;
  54. return resultData;
  55. }
  56. } // namespace CompressionLZ4