LZMADecoder.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // LZMA/Decoder.h
  2. #ifndef __LZMA_DECODER_H
  3. #define __LZMA_DECODER_H
  4. #include "../../../Common/MyCom.h"
  5. #include "../../ICoder.h"
  6. #include "../LZ/LZOutWindow.h"
  7. #include "../RangeCoder/RangeCoderBitTree.h"
  8. extern "C"
  9. {
  10. #include "../../../../C/Alloc.h"
  11. }
  12. #include "LZMA.h"
  13. namespace NCompress {
  14. namespace NLZMA {
  15. typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
  16. class CLiteralDecoder2
  17. {
  18. CMyBitDecoder _decoders[0x300];
  19. public:
  20. void Init()
  21. {
  22. for (int i = 0; i < 0x300; i++)
  23. _decoders[i].Init();
  24. }
  25. Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
  26. {
  27. UInt32 symbol = 1;
  28. RC_INIT_VAR
  29. do
  30. {
  31. // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
  32. RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
  33. }
  34. while (symbol < 0x100);
  35. RC_FLUSH_VAR
  36. return (Byte)symbol;
  37. }
  38. Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
  39. {
  40. UInt32 symbol = 1;
  41. RC_INIT_VAR
  42. do
  43. {
  44. UInt32 matchBit = (matchByte >> 7) & 1;
  45. matchByte <<= 1;
  46. // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
  47. // symbol = (symbol << 1) | bit;
  48. UInt32 bit;
  49. RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol,
  50. bit = 0, bit = 1)
  51. if (matchBit != bit)
  52. {
  53. while (symbol < 0x100)
  54. {
  55. // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
  56. RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
  57. }
  58. break;
  59. }
  60. }
  61. while (symbol < 0x100);
  62. RC_FLUSH_VAR
  63. return (Byte)symbol;
  64. }
  65. };
  66. class CLiteralDecoder
  67. {
  68. CLiteralDecoder2 *_coders;
  69. int _numPrevBits;
  70. int _numPosBits;
  71. UInt32 _posMask;
  72. public:
  73. CLiteralDecoder(): _coders(0) {}
  74. ~CLiteralDecoder() { Free(); }
  75. void Free()
  76. {
  77. MyFree(_coders);
  78. _coders = 0;
  79. }
  80. bool Create(int numPosBits, int numPrevBits)
  81. {
  82. if (_coders == 0 || (numPosBits + numPrevBits) !=
  83. (_numPrevBits + _numPosBits) )
  84. {
  85. Free();
  86. UInt32 numStates = 1 << (numPosBits + numPrevBits);
  87. _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
  88. }
  89. _numPosBits = numPosBits;
  90. _posMask = (1 << numPosBits) - 1;
  91. _numPrevBits = numPrevBits;
  92. return (_coders != 0);
  93. }
  94. void Init()
  95. {
  96. UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
  97. for (UInt32 i = 0; i < numStates; i++)
  98. _coders[i].Init();
  99. }
  100. UInt32 GetState(UInt32 pos, Byte prevByte) const
  101. { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
  102. Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
  103. { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
  104. Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
  105. { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
  106. };
  107. namespace NLength {
  108. class CDecoder
  109. {
  110. CMyBitDecoder _choice;
  111. CMyBitDecoder _choice2;
  112. NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesMax];
  113. NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax];
  114. NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder;
  115. public:
  116. void Init(UInt32 numPosStates)
  117. {
  118. _choice.Init();
  119. _choice2.Init();
  120. for (UInt32 posState = 0; posState < numPosStates; posState++)
  121. {
  122. _lowCoder[posState].Init();
  123. _midCoder[posState].Init();
  124. }
  125. _highCoder.Init();
  126. }
  127. UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
  128. {
  129. if(_choice.Decode(rangeDecoder) == 0)
  130. return _lowCoder[posState].Decode(rangeDecoder);
  131. if(_choice2.Decode(rangeDecoder) == 0)
  132. return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
  133. return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
  134. }
  135. };
  136. }
  137. class CDecoder:
  138. public ICompressCoder,
  139. public ICompressSetDecoderProperties2,
  140. public ICompressGetInStreamProcessedSize,
  141. #ifndef NO_READ_FROM_CODER
  142. public ICompressSetInStream,
  143. public ICompressSetOutStreamSize,
  144. public ISequentialInStream,
  145. #endif
  146. public CMyUnknownImp
  147. {
  148. CLZOutWindow _outWindowStream;
  149. NRangeCoder::CDecoder _rangeDecoder;
  150. CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
  151. CMyBitDecoder _isRep[kNumStates];
  152. CMyBitDecoder _isRepG0[kNumStates];
  153. CMyBitDecoder _isRepG1[kNumStates];
  154. CMyBitDecoder _isRepG2[kNumStates];
  155. CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
  156. NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
  157. CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
  158. NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
  159. NLength::CDecoder _lenDecoder;
  160. NLength::CDecoder _repMatchLenDecoder;
  161. CLiteralDecoder _literalDecoder;
  162. UInt32 _posStateMask;
  163. ///////////////////
  164. // State
  165. UInt32 _reps[4];
  166. CState _state;
  167. Int32 _remainLen; // -1 means end of stream. // -2 means need Init
  168. UInt64 _outSize;
  169. bool _outSizeDefined;
  170. void Init();
  171. HRESULT CodeSpec(UInt32 size);
  172. public:
  173. #ifndef NO_READ_FROM_CODER
  174. MY_UNKNOWN_IMP5(
  175. ICompressSetDecoderProperties2,
  176. ICompressGetInStreamProcessedSize,
  177. ICompressSetInStream,
  178. ICompressSetOutStreamSize,
  179. ISequentialInStream)
  180. #else
  181. MY_UNKNOWN_IMP2(
  182. ICompressSetDecoderProperties2,
  183. ICompressGetInStreamProcessedSize)
  184. #endif
  185. void ReleaseStreams()
  186. {
  187. _outWindowStream.ReleaseStream();
  188. ReleaseInStream();
  189. }
  190. class CDecoderFlusher
  191. {
  192. CDecoder *_decoder;
  193. public:
  194. bool NeedFlush;
  195. CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
  196. ~CDecoderFlusher()
  197. {
  198. if (NeedFlush)
  199. _decoder->Flush();
  200. _decoder->ReleaseStreams();
  201. }
  202. };
  203. HRESULT Flush() { return _outWindowStream.Flush(); }
  204. STDMETHOD(CodeReal)(ISequentialInStream *inStream,
  205. ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
  206. ICompressProgressInfo *progress);
  207. STDMETHOD(Code)(ISequentialInStream *inStream,
  208. ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
  209. ICompressProgressInfo *progress);
  210. STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
  211. STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
  212. STDMETHOD(SetInStream)(ISequentialInStream *inStream);
  213. STDMETHOD(ReleaseInStream)();
  214. STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
  215. #ifndef NO_READ_FROM_CODER
  216. STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
  217. #endif
  218. CDecoder(): _outSizeDefined(false) {}
  219. virtual ~CDecoder() {}
  220. };
  221. }}
  222. #endif