2
0

Compression.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "Compression.h"
  2. #include "third_party/zlib/zlib.h"
  3. #include "TLSingleton.h"
  4. #pragma warning(disable:4190)
  5. USING_NS_BF;
  6. static TLSingleton<Array<uint8>> gCompression_TLDataReturn;
  7. bool Compression::Compress(Span<uint8> inData, Array<uint8>& outData)
  8. {
  9. outData.Reserve(128);
  10. z_stream zs;
  11. zs.zalloc = Z_NULL;
  12. zs.zfree = Z_NULL;
  13. zs.opaque = Z_NULL;
  14. zs.avail_in = (int)inData.mSize;
  15. zs.next_in = inData.mVals;
  16. zs.next_out = outData.mVals;
  17. zs.avail_out = outData.mAllocSize;
  18. deflateInit(&zs, Z_BEST_COMPRESSION);
  19. bool isDone = false;
  20. bool hadError = false;
  21. while (true)
  22. {
  23. bool isDone = zs.avail_in == 0;
  24. int err = deflate(&zs, isDone ? Z_FINISH : Z_NO_FLUSH);
  25. outData.mSize = (int)(zs.next_out - outData.mVals);
  26. if (err < 0)
  27. {
  28. hadError = true;
  29. break;
  30. }
  31. if ((isDone) && (err == Z_STREAM_END))
  32. break;
  33. if (zs.avail_out == 0)
  34. {
  35. outData.Reserve((int)outData.mAllocSize + (int)outData.mAllocSize / 2 + 1);
  36. zs.next_out = outData.mVals + outData.mSize;
  37. zs.avail_out = outData.mAllocSize - outData.mSize;
  38. }
  39. }
  40. deflateEnd(&zs);
  41. return !hadError;
  42. }
  43. bool Compression::Decompress(Span<uint8> inData, Array<uint8>& outData)
  44. {
  45. outData.Reserve(128);
  46. z_stream zs;
  47. zs.zalloc = Z_NULL;
  48. zs.zfree = Z_NULL;
  49. zs.opaque = Z_NULL;
  50. zs.avail_in = (int)inData.mSize;
  51. zs.next_in = inData.mVals;
  52. zs.next_out = outData.mVals;
  53. zs.avail_out = outData.mAllocSize;
  54. inflateInit(&zs);
  55. bool isDone = false;
  56. bool hadError = false;
  57. while (true)
  58. {
  59. bool isDone = zs.avail_in == 0;
  60. int err = inflate(&zs, isDone ? Z_FINISH : Z_NO_FLUSH);
  61. outData.mSize = (int)(zs.next_out - outData.mVals);
  62. if (err < 0)
  63. {
  64. hadError = true;
  65. break;
  66. }
  67. if ((isDone) && (err == Z_STREAM_END))
  68. break;
  69. if (zs.avail_out == 0)
  70. {
  71. outData.Reserve((int)outData.mAllocSize + (int)outData.mAllocSize / 2 + 1);
  72. zs.next_out = outData.mVals + outData.mSize;
  73. zs.avail_out = outData.mAllocSize - outData.mSize;
  74. }
  75. }
  76. inflateEnd(&zs);
  77. return !hadError;
  78. }
  79. //////////////////////////////////////////////////////////////////////////
  80. BF_EXPORT bool BF_CALLTYPE Compression_Compress(void* ptr, intptr size, void** outPtr, intptr* outSize)
  81. {
  82. auto& outData = *gCompression_TLDataReturn.Get();
  83. outData.Reserve(128);
  84. if (!Compression::Compress(Span<uint8>((uint8*)ptr, size), outData))
  85. return false;
  86. *outPtr = outData.mVals;
  87. *outSize = outData.mSize;
  88. return true;
  89. }
  90. BF_EXPORT bool BF_CALLTYPE Compression_Decompress(void* ptr, intptr size, void** outPtr, intptr* outSize)
  91. {
  92. auto& outData = *gCompression_TLDataReturn.Get();
  93. outData.Reserve(128);
  94. if (!Compression::Decompress(Span<uint8>((uint8*)ptr, size), outData))
  95. return false;
  96. *outPtr = outData.mVals;
  97. *outSize = outData.mSize;
  98. return true;
  99. }