ITCompression.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * ITCompression.h
  3. * ---------------
  4. * Purpose: Code for IT sample compression and decompression.
  5. * Notes : The original Python compression code was written by GreaseMonkey and has been released into the public domain.
  6. * Authors: OpenMPT Devs
  7. * Ben "GreaseMonkey" Russell
  8. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  9. */
  10. #pragma once
  11. #include "openmpt/all/BuildSettings.hpp"
  12. #include <vector>
  13. #include <iosfwd>
  14. #include "Snd_defs.h"
  15. #include "BitReader.h"
  16. OPENMPT_NAMESPACE_BEGIN
  17. struct ModSample;
  18. class ITCompression
  19. {
  20. public:
  21. ITCompression(const ModSample &sample, bool it215, std::ostream *f, SmpLength maxLength = 0);
  22. size_t GetCompressedSize() const { return packedTotalLength; }
  23. static constexpr size_t bufferSize = 2 + 0xFFFF; // Our output buffer can't be longer than this.
  24. static constexpr size_t blockSize = 0x8000; // Block size (in bytes) in which samples are being processed
  25. protected:
  26. std::vector<int8> bwt; // Bit width table for each sampling point
  27. std::vector<uint8> packedData; // Compressed data for current sample block
  28. std::ostream *file = nullptr; // File to which compressed data will be written (can be nullptr if you only want to find out the sample size)
  29. std::vector<int8> sampleData8; // Pre-processed sample data for currently compressed sample block
  30. std::vector<int16> sampleData16; // Pre-processed sample data for currently compressed sample block
  31. const ModSample &mptSample; // Sample that is being processed
  32. size_t packedLength = 0; // Size of currently compressed sample block
  33. size_t packedTotalLength = 0; // Size of all compressed data so far
  34. SmpLength baseLength = 0; // Length of the currently compressed sample block (in samples)
  35. // Bit writer
  36. int8 bitPos = 0; // Current bit position in this byte
  37. int8 remBits = 0; // Remaining bits in this byte
  38. uint8 byteVal = 0; // Current byte value to be written
  39. const bool is215; // Use IT2.15 compression (double deltas)
  40. template<typename Properties>
  41. void Compress(const typename Properties::sample_t *mptSampleData, SmpLength maxLength);
  42. template<typename T>
  43. static void CopySample(T *target, const T *source, SmpLength offset, SmpLength length, SmpLength skip);
  44. template<typename T>
  45. void Deltafy(T *sampleData);
  46. template<typename Properties>
  47. void CompressBlock(const typename Properties::sample_t *data, SmpLength offset, SmpLength actualLength, typename Properties::sample_t *sampleData);
  48. static int8 GetWidthChangeSize(int8 w, bool is16);
  49. template<typename Properties>
  50. void SquishRecurse(int8 sWidth, int8 lWidth, int8 rWidth, int8 width, SmpLength offset, SmpLength length, const typename Properties::sample_t *sampleData);
  51. static int8 ConvertWidth(int8 curWidth, int8 newWidth);
  52. void WriteBits(int8 width, int v);
  53. void WriteByte(uint8 v);
  54. };
  55. class ITDecompression
  56. {
  57. public:
  58. ITDecompression(FileReader &file, ModSample &sample, bool it215);
  59. protected:
  60. BitReader bitFile;
  61. ModSample &mptSample; // Sample that is being processed
  62. SmpLength writtenSamples = 0; // Number of samples so far written on this channel
  63. SmpLength writePos = 0; // Absolut write position in sample (for stereo samples)
  64. SmpLength curLength = 0; // Length of currently processed block
  65. unsigned int mem1 = 0, mem2 = 0; // Integrator memory
  66. const bool is215; // Use IT2.15 compression (double deltas)
  67. template<typename Properties>
  68. void Uncompress(typename Properties::sample_t *target);
  69. static void ChangeWidth(int &curWidth, int width);
  70. template<typename Properties>
  71. void Write(int v, int topbit, typename Properties::sample_t *target);
  72. };
  73. OPENMPT_NAMESPACE_END