LzmaDecoder.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. // LzmaDecoder.cs
  2. using System;
  3. namespace SevenZip.Compression.LZMA
  4. {
  5. using RangeCoder;
  6. public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
  7. {
  8. class LenDecoder
  9. {
  10. BitDecoder m_Choice = new BitDecoder();
  11. BitDecoder m_Choice2 = new BitDecoder();
  12. BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
  13. BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
  14. BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
  15. uint m_NumPosStates = 0;
  16. public void Create(uint numPosStates)
  17. {
  18. for (uint posState = m_NumPosStates; posState < numPosStates; posState++)
  19. {
  20. m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);
  21. m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);
  22. }
  23. m_NumPosStates = numPosStates;
  24. }
  25. public void Init()
  26. {
  27. m_Choice.Init();
  28. for (uint posState = 0; posState < m_NumPosStates; posState++)
  29. {
  30. m_LowCoder[posState].Init();
  31. m_MidCoder[posState].Init();
  32. }
  33. m_Choice2.Init();
  34. m_HighCoder.Init();
  35. }
  36. public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
  37. {
  38. if (m_Choice.Decode(rangeDecoder) == 0)
  39. return m_LowCoder[posState].Decode(rangeDecoder);
  40. else
  41. {
  42. uint symbol = Base.kNumLowLenSymbols;
  43. if (m_Choice2.Decode(rangeDecoder) == 0)
  44. symbol += m_MidCoder[posState].Decode(rangeDecoder);
  45. else
  46. {
  47. symbol += Base.kNumMidLenSymbols;
  48. symbol += m_HighCoder.Decode(rangeDecoder);
  49. }
  50. return symbol;
  51. }
  52. }
  53. }
  54. class LiteralDecoder
  55. {
  56. struct Decoder2
  57. {
  58. BitDecoder[] m_Decoders;
  59. public void Create() { m_Decoders = new BitDecoder[0x300]; }
  60. public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); }
  61. public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
  62. {
  63. uint symbol = 1;
  64. do
  65. symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
  66. while (symbol < 0x100);
  67. return (byte)symbol;
  68. }
  69. public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
  70. {
  71. uint symbol = 1;
  72. do
  73. {
  74. uint matchBit = (uint)(matchByte >> 7) & 1;
  75. matchByte <<= 1;
  76. uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
  77. symbol = (symbol << 1) | bit;
  78. if (matchBit != bit)
  79. {
  80. while (symbol < 0x100)
  81. symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
  82. break;
  83. }
  84. }
  85. while (symbol < 0x100);
  86. return (byte)symbol;
  87. }
  88. }
  89. Decoder2[] m_Coders;
  90. int m_NumPrevBits;
  91. int m_NumPosBits;
  92. uint m_PosMask;
  93. public void Create(int numPosBits, int numPrevBits)
  94. {
  95. if (m_Coders != null && m_NumPrevBits == numPrevBits &&
  96. m_NumPosBits == numPosBits)
  97. return;
  98. m_NumPosBits = numPosBits;
  99. m_PosMask = ((uint)1 << numPosBits) - 1;
  100. m_NumPrevBits = numPrevBits;
  101. uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
  102. m_Coders = new Decoder2[numStates];
  103. for (uint i = 0; i < numStates; i++)
  104. m_Coders[i].Create();
  105. }
  106. public void Init()
  107. {
  108. uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
  109. for (uint i = 0; i < numStates; i++)
  110. m_Coders[i].Init();
  111. }
  112. uint GetState(uint pos, byte prevByte)
  113. { return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); }
  114. public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
  115. { return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
  116. public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
  117. { return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
  118. };
  119. LZ.OutWindow m_OutWindow = new LZ.OutWindow();
  120. RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder();
  121. BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
  122. BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates];
  123. BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates];
  124. BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates];
  125. BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates];
  126. BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
  127. BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
  128. BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
  129. BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
  130. LenDecoder m_LenDecoder = new LenDecoder();
  131. LenDecoder m_RepLenDecoder = new LenDecoder();
  132. LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
  133. uint m_DictionarySize;
  134. uint m_DictionarySizeCheck;
  135. uint m_PosStateMask;
  136. public Decoder()
  137. {
  138. m_DictionarySize = 0xFFFFFFFF;
  139. for (int i = 0; i < Base.kNumLenToPosStates; i++)
  140. m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
  141. }
  142. void SetDictionarySize(uint dictionarySize)
  143. {
  144. if (m_DictionarySize != dictionarySize)
  145. {
  146. m_DictionarySize = dictionarySize;
  147. m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1);
  148. uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12));
  149. m_OutWindow.Create(blockSize);
  150. }
  151. }
  152. void SetLiteralProperties(int lp, int lc)
  153. {
  154. if (lp > 8)
  155. throw new InvalidParamException();
  156. if (lc > 8)
  157. throw new InvalidParamException();
  158. m_LiteralDecoder.Create(lp, lc);
  159. }
  160. void SetPosBitsProperties(int pb)
  161. {
  162. if (pb > Base.kNumPosStatesBitsMax)
  163. throw new InvalidParamException();
  164. uint numPosStates = (uint)1 << pb;
  165. m_LenDecoder.Create(numPosStates);
  166. m_RepLenDecoder.Create(numPosStates);
  167. m_PosStateMask = numPosStates - 1;
  168. }
  169. bool _solid = false;
  170. void Init(System.IO.Stream inStream, System.IO.Stream outStream)
  171. {
  172. m_RangeDecoder.Init(inStream);
  173. m_OutWindow.Init(outStream, _solid);
  174. uint i;
  175. for (i = 0; i < Base.kNumStates; i++)
  176. {
  177. for (uint j = 0; j <= m_PosStateMask; j++)
  178. {
  179. uint index = (i << Base.kNumPosStatesBitsMax) + j;
  180. m_IsMatchDecoders[index].Init();
  181. m_IsRep0LongDecoders[index].Init();
  182. }
  183. m_IsRepDecoders[i].Init();
  184. m_IsRepG0Decoders[i].Init();
  185. m_IsRepG1Decoders[i].Init();
  186. m_IsRepG2Decoders[i].Init();
  187. }
  188. m_LiteralDecoder.Init();
  189. for (i = 0; i < Base.kNumLenToPosStates; i++)
  190. m_PosSlotDecoder[i].Init();
  191. // m_PosSpecDecoder.Init();
  192. for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
  193. m_PosDecoders[i].Init();
  194. m_LenDecoder.Init();
  195. m_RepLenDecoder.Init();
  196. m_PosAlignDecoder.Init();
  197. }
  198. public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
  199. Int64 inSize, Int64 outSize, ICodeProgress progress)
  200. {
  201. Init(inStream, outStream);
  202. Base.State state = new Base.State();
  203. state.Init();
  204. uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
  205. UInt64 nowPos64 = 0;
  206. UInt64 outSize64 = (UInt64)outSize;
  207. if (nowPos64 < outSize64)
  208. {
  209. if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
  210. throw new DataErrorException();
  211. state.UpdateChar();
  212. byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
  213. m_OutWindow.PutByte(b);
  214. nowPos64++;
  215. }
  216. while (nowPos64 < outSize64)
  217. {
  218. // UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
  219. // while(nowPos64 < next)
  220. {
  221. uint posState = (uint)nowPos64 & m_PosStateMask;
  222. if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
  223. {
  224. byte b;
  225. byte prevByte = m_OutWindow.GetByte(0);
  226. if (!state.IsCharState())
  227. b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder,
  228. (uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0));
  229. else
  230. b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte);
  231. m_OutWindow.PutByte(b);
  232. state.UpdateChar();
  233. nowPos64++;
  234. }
  235. else
  236. {
  237. uint len;
  238. if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1)
  239. {
  240. if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0)
  241. {
  242. if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
  243. {
  244. state.UpdateShortRep();
  245. m_OutWindow.PutByte(m_OutWindow.GetByte(rep0));
  246. nowPos64++;
  247. continue;
  248. }
  249. }
  250. else
  251. {
  252. UInt32 distance;
  253. if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0)
  254. {
  255. distance = rep1;
  256. }
  257. else
  258. {
  259. if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0)
  260. distance = rep2;
  261. else
  262. {
  263. distance = rep3;
  264. rep3 = rep2;
  265. }
  266. rep2 = rep1;
  267. }
  268. rep1 = rep0;
  269. rep0 = distance;
  270. }
  271. len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
  272. state.UpdateRep();
  273. }
  274. else
  275. {
  276. rep3 = rep2;
  277. rep2 = rep1;
  278. rep1 = rep0;
  279. len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
  280. state.UpdateMatch();
  281. uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
  282. if (posSlot >= Base.kStartPosModelIndex)
  283. {
  284. int numDirectBits = (int)((posSlot >> 1) - 1);
  285. rep0 = ((2 | (posSlot & 1)) << numDirectBits);
  286. if (posSlot < Base.kEndPosModelIndex)
  287. rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
  288. rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
  289. else
  290. {
  291. rep0 += (m_RangeDecoder.DecodeDirectBits(
  292. numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
  293. rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
  294. }
  295. }
  296. else
  297. rep0 = posSlot;
  298. }
  299. if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck)
  300. {
  301. if (rep0 == 0xFFFFFFFF)
  302. break;
  303. throw new DataErrorException();
  304. }
  305. m_OutWindow.CopyBlock(rep0, len);
  306. nowPos64 += len;
  307. }
  308. }
  309. }
  310. m_OutWindow.Flush();
  311. m_OutWindow.ReleaseStream();
  312. m_RangeDecoder.ReleaseStream();
  313. }
  314. public void SetDecoderProperties(byte[] properties)
  315. {
  316. if (properties.Length < 5)
  317. throw new InvalidParamException();
  318. int lc = properties[0] % 9;
  319. int remainder = properties[0] / 9;
  320. int lp = remainder % 5;
  321. int pb = remainder / 5;
  322. if (pb > Base.kNumPosStatesBitsMax)
  323. throw new InvalidParamException();
  324. UInt32 dictionarySize = 0;
  325. for (int i = 0; i < 4; i++)
  326. dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
  327. SetDictionarySize(dictionarySize);
  328. SetLiteralProperties(lp, lc);
  329. SetPosBitsProperties(pb);
  330. }
  331. public bool Train(System.IO.Stream stream)
  332. {
  333. _solid = true;
  334. return m_OutWindow.Train(stream);
  335. }
  336. /*
  337. public override bool CanRead { get { return true; }}
  338. public override bool CanWrite { get { return true; }}
  339. public override bool CanSeek { get { return true; }}
  340. public override long Length { get { return 0; }}
  341. public override long Position
  342. {
  343. get { return 0; }
  344. set { }
  345. }
  346. public override void Flush() { }
  347. public override int Read(byte[] buffer, int offset, int count)
  348. {
  349. return 0;
  350. }
  351. public override void Write(byte[] buffer, int offset, int count)
  352. {
  353. }
  354. public override long Seek(long offset, System.IO.SeekOrigin origin)
  355. {
  356. return 0;
  357. }
  358. public override void SetLength(long value) {}
  359. */
  360. }
  361. }