CompressorLZ4Impl.cpp 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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 "CompressorLZ4Impl.h"
  9. #include <Compression/CompressionLZ4API.h>
  10. #include <lz4.h>
  11. namespace CompressionLZ4
  12. {
  13. // Definitions for LZ4 Compressor
  14. CompressorLZ4::CompressorLZ4() = default;
  15. Compression::CompressionAlgorithmId CompressorLZ4::GetCompressionAlgorithmId() const
  16. {
  17. return GetLZ4CompressionAlgorithmId();
  18. }
  19. AZStd::string_view CompressorLZ4::GetCompressionAlgorithmName() const
  20. {
  21. return GetLZ4CompressionAlgorithmName();
  22. }
  23. [[nodiscard]] size_t CompressorLZ4::CompressBound([[maybe_unused]] size_t uncompressedBufferSize) const
  24. {
  25. return LZ4_compressBound(static_cast<int>(uncompressedBufferSize));
  26. }
  27. Compression::CompressionResultData CompressorLZ4::CompressBlock(
  28. AZStd::span<AZStd::byte> compressionBuffer, const AZStd::span<const AZStd::byte>& uncompressedData,
  29. [[maybe_unused]] const Compression::CompressionOptions& compressionOptions) const
  30. {
  31. Compression::CompressionResultData resultData;
  32. if (const int worstCaseCompressedSize = LZ4_compressBound(static_cast<int>(uncompressedData.size()));
  33. worstCaseCompressedSize == 0)
  34. {
  35. resultData.m_compressionOutcome.m_resultString = Compression::CompressionResultString::format(
  36. "Input buffer is too large to compress"
  37. " in a single call. The maximum lz4 input size is %d. The input size is %zu", LZ4_MAX_INPUT_SIZE, uncompressedData.size());
  38. resultData.m_compressionOutcome.m_result = Compression::CompressionResult::Failed;
  39. return resultData;
  40. }
  41. else if (compressionBuffer.size() < worstCaseCompressedSize)
  42. {
  43. resultData.m_compressionOutcome.m_resultString = Compression::CompressionResultString::format(
  44. "Output buffer capacity is less than the upper bound for worst case."
  45. " Worst case size is %d; output buffer capacity is %zu\n",
  46. worstCaseCompressedSize, compressionBuffer.size());
  47. }
  48. // Note that this returns a non-negative int so we are narrowing into a size_t here
  49. int compressedSize = LZ4_compress_default(
  50. reinterpret_cast<const char*>(uncompressedData.data()),
  51. reinterpret_cast<char*>(compressionBuffer.data()),
  52. static_cast<int>(uncompressedData.size()),
  53. static_cast<int>(compressionBuffer.size()));
  54. if (compressedSize == 0)
  55. {
  56. // LZ4_compress_HC returns a zero value for corrupt data and insufficient buffer
  57. resultData.m_compressionOutcome.m_resultString += Compression::CompressionResultString::format(
  58. "lz4_compress_default call has failed. The source buffer size is %zu and the output buffer"
  59. " has capacity of %zu", uncompressedData.size(), compressionBuffer.size());
  60. resultData.m_compressionOutcome.m_result = Compression::CompressionResult::Failed;
  61. return resultData;
  62. }
  63. // Update the result buffer span to point at the beginning of the compressed data and
  64. // the correct compressed size
  65. resultData.m_compressedBuffer = compressionBuffer.subspan(0, compressedSize);
  66. resultData.m_compressionOutcome.m_result = Compression::CompressionResult::Complete;
  67. return resultData;
  68. }
  69. } // namespace CompressionLZ4