DataCompressor.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "DataCompressor.h"
  11. #include "DS_HuffmanEncodingTree.h"
  12. #include "RakAssert.h"
  13. #include <string.h> // Use string.h rather than memory.h for a console
  14. using namespace RakNet;
  15. STATIC_FACTORY_DEFINITIONS(DataCompressor,DataCompressor)
  16. void DataCompressor::Compress( unsigned char *userData, unsigned sizeInBytes, RakNet::BitStream * output )
  17. {
  18. // Don't use this for small files as you will just make them bigger!
  19. RakAssert(sizeInBytes > 2048);
  20. unsigned int frequencyTable[ 256 ];
  21. unsigned int i;
  22. memset(frequencyTable,0,256*sizeof(unsigned int));
  23. for (i=0; i < sizeInBytes; i++)
  24. ++frequencyTable[userData[i]];
  25. HuffmanEncodingTree tree;
  26. BitSize_t writeOffset1, writeOffset2, bitsUsed1, bitsUsed2;
  27. tree.GenerateFromFrequencyTable(frequencyTable);
  28. output->WriteCompressed(sizeInBytes);
  29. for (i=0; i < 256; i++)
  30. output->WriteCompressed(frequencyTable[i]);
  31. output->AlignWriteToByteBoundary();
  32. writeOffset1=output->GetWriteOffset();
  33. output->Write((unsigned int)0); // Dummy value
  34. bitsUsed1=output->GetNumberOfBitsUsed();
  35. tree.EncodeArray(userData, sizeInBytes, output);
  36. bitsUsed2=output->GetNumberOfBitsUsed();
  37. writeOffset2=output->GetWriteOffset();
  38. output->SetWriteOffset(writeOffset1);
  39. output->Write(bitsUsed2-bitsUsed1); // Go back and write how many bits were used for the encoding
  40. output->SetWriteOffset(writeOffset2);
  41. }
  42. unsigned DataCompressor::DecompressAndAllocate( RakNet::BitStream * input, unsigned char **output )
  43. {
  44. HuffmanEncodingTree tree;
  45. unsigned int bitsUsed, destinationSizeInBytes;
  46. unsigned int decompressedBytes;
  47. unsigned int frequencyTable[ 256 ];
  48. unsigned i;
  49. input->ReadCompressed(destinationSizeInBytes);
  50. for (i=0; i < 256; i++)
  51. input->ReadCompressed(frequencyTable[i]);
  52. input->AlignReadToByteBoundary();
  53. if (input->Read(bitsUsed)==false)
  54. {
  55. // Read error
  56. #ifdef _DEBUG
  57. RakAssert(0);
  58. #endif
  59. return 0;
  60. }
  61. *output = (unsigned char*) rakMalloc_Ex(destinationSizeInBytes, _FILE_AND_LINE_);
  62. tree.GenerateFromFrequencyTable(frequencyTable);
  63. decompressedBytes=tree.DecodeArray(input, bitsUsed, destinationSizeInBytes, *output );
  64. RakAssert(decompressedBytes==destinationSizeInBytes);
  65. return destinationSizeInBytes;
  66. }
粤ICP备19079148号