Compression.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright (c) 2008-2022 the Urho3D project
  2. // License: MIT
  3. #include "../Precompiled.h"
  4. #include "../Container/ArrayPtr.h"
  5. #include "../IO/Compression.h"
  6. #include "../IO/Deserializer.h"
  7. #include "../IO/Serializer.h"
  8. #include "../IO/VectorBuffer.h"
  9. #include <LZ4/lz4.h>
  10. #include <LZ4/lz4hc.h>
  11. namespace Urho3D
  12. {
  13. unsigned EstimateCompressBound(unsigned srcSize)
  14. {
  15. return (unsigned)LZ4_compressBound(srcSize);
  16. }
  17. unsigned CompressData(void* dest, const void* src, unsigned srcSize)
  18. {
  19. if (!dest || !src || !srcSize)
  20. return 0;
  21. else
  22. return (unsigned)LZ4_compress_HC((const char*)src, (char*)dest, srcSize, LZ4_compressBound(srcSize), 0);
  23. }
  24. unsigned DecompressData(void* dest, const void* src, unsigned destSize)
  25. {
  26. if (!dest || !src || !destSize)
  27. return 0;
  28. else
  29. return (unsigned)LZ4_decompress_fast((const char*)src, (char*)dest, destSize);
  30. }
  31. bool CompressStream(Serializer& dest, Deserializer& src)
  32. {
  33. unsigned srcSize = src.GetSize() - src.GetPosition();
  34. // Prepend the source and dest. data size in the stream so that we know to buffer & uncompress the right amount
  35. if (!srcSize)
  36. {
  37. dest.WriteU32(0);
  38. dest.WriteU32(0);
  39. return true;
  40. }
  41. auto maxDestSize = (unsigned)LZ4_compressBound(srcSize);
  42. SharedArrayPtr<unsigned char> srcBuffer(new unsigned char[srcSize]);
  43. SharedArrayPtr<unsigned char> destBuffer(new unsigned char[maxDestSize]);
  44. if (src.Read(srcBuffer, srcSize) != srcSize)
  45. return false;
  46. auto destSize = (unsigned)LZ4_compress_HC((const char*)srcBuffer.Get(), (char*)destBuffer.Get(), srcSize, LZ4_compressBound(srcSize), 0);
  47. bool success = true;
  48. success &= dest.WriteU32(srcSize);
  49. success &= dest.WriteU32(destSize);
  50. success &= dest.Write(destBuffer, destSize) == destSize;
  51. return success;
  52. }
  53. bool DecompressStream(Serializer& dest, Deserializer& src)
  54. {
  55. if (src.IsEof())
  56. return false;
  57. unsigned destSize = src.ReadU32();
  58. unsigned srcSize = src.ReadU32();
  59. if (!srcSize || !destSize)
  60. return true; // No data
  61. if (srcSize > src.GetSize())
  62. return false; // Illegal source (packed data) size reported, possibly not valid data
  63. SharedArrayPtr<unsigned char> srcBuffer(new unsigned char[srcSize]);
  64. SharedArrayPtr<unsigned char> destBuffer(new unsigned char[destSize]);
  65. if (src.Read(srcBuffer, srcSize) != srcSize)
  66. return false;
  67. LZ4_decompress_fast((const char*)srcBuffer.Get(), (char*)destBuffer.Get(), destSize);
  68. return dest.Write(destBuffer, destSize) == destSize;
  69. }
  70. VectorBuffer CompressVectorBuffer(VectorBuffer& src)
  71. {
  72. VectorBuffer ret;
  73. src.Seek(0);
  74. CompressStream(ret, src);
  75. ret.Seek(0);
  76. return ret;
  77. }
  78. VectorBuffer DecompressVectorBuffer(VectorBuffer& src)
  79. {
  80. VectorBuffer ret;
  81. src.Seek(0);
  82. DecompressStream(ret, src);
  83. ret.Seek(0);
  84. return ret;
  85. }
  86. }