PageRenderTime 5027ms CodeModel.GetById 34ms RepoModel.GetById 1ms app.codeStats 1ms

/Stages/Stage2.LZMA.cs

http://github.com/daeken/Dotpack
C# | 381 lines | 344 code | 35 blank | 2 comment | 45 complexity | 43f794b7c39943a22ed6b3be7c9c4dd3 MD5 | raw file
  1. using System;
  2. using System.IO;
  3. namespace _ {
  4. struct BitTreeDecoder
  5. {
  6. BitDecoder[] Models;
  7. int NumBitLevels;
  8. public BitTreeDecoder(int numBitLevels)
  9. {
  10. NumBitLevels = numBitLevels;
  11. Models = new BitDecoder[1 << numBitLevels];
  12. }
  13. public uint Decode(Decoder rangeDecoder)
  14. {
  15. uint m = 1;
  16. for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
  17. m = (m << 1) + Models[m].Decode(rangeDecoder);
  18. return m - ((uint)1 << NumBitLevels);
  19. }
  20. public uint ReverseDecode(Decoder rangeDecoder)
  21. {
  22. return ReverseDecode(Models, 0, rangeDecoder, NumBitLevels);
  23. }
  24. public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex,
  25. Decoder rangeDecoder, int NumBitLevels)
  26. {
  27. uint m = 1;
  28. uint symbol = 0;
  29. for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
  30. {
  31. uint bit = Models[startIndex + m].Decode(rangeDecoder);
  32. m <<= 1;
  33. m += bit;
  34. symbol |= (bit << bitIndex);
  35. }
  36. return symbol;
  37. }
  38. }
  39. struct BitDecoder
  40. {
  41. uint Prob;
  42. public uint Decode(Decoder rangeDecoder)
  43. {
  44. if(Prob == 0) Prob = 1 << 10;
  45. uint newBound = (uint)(rangeDecoder.Range >> 11) * (uint)Prob;
  46. uint ret = 0;
  47. if (rangeDecoder.Code >= newBound)
  48. {
  49. rangeDecoder.Code -= newBound;
  50. rangeDecoder.Range -= newBound;
  51. Prob -= (Prob) >> 5;
  52. ret = 1;
  53. }
  54. else
  55. {
  56. rangeDecoder.Range = newBound;
  57. Prob += ((1 << 11) - Prob) >> 5;
  58. }
  59. if (rangeDecoder.Range < (1 << 24))
  60. {
  61. rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
  62. rangeDecoder.Range <<= 8;
  63. }
  64. return ret;
  65. }
  66. }
  67. class Decoder
  68. {
  69. public uint Range;
  70. public uint Code;
  71. // public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16);
  72. public System.IO.Stream Stream;
  73. public Decoder(System.IO.Stream stream)
  74. {
  75. Stream = stream;
  76. Code = 0;
  77. Range = 0xFFFFFFFF;
  78. for (int i = 0; i < 5; i++) {
  79. Code = (Code << 8) | (byte) Stream.ReadByte();
  80. }
  81. }
  82. public void Decode(uint start, uint size, uint total)
  83. {
  84. Code -= start * Range;
  85. Range *= size;
  86. // Normalize
  87. while (Range < (1 << 24))
  88. {
  89. Code = (Code << 8) | (byte)Stream.ReadByte();
  90. Range <<= 8;
  91. }
  92. }
  93. public uint DecodeDirectBits(int numTotalBits)
  94. {
  95. uint range = Range;
  96. uint code = Code;
  97. uint result = 0;
  98. while(numTotalBits-- != 0)
  99. {
  100. range >>= 1;
  101. uint t = (code - range) >> 31;
  102. code -= range & (t - 1);
  103. result = (result << 1) | (1 - t);
  104. if (range < (1 << 24))
  105. {
  106. code = (code << 8) | (byte)Stream.ReadByte();
  107. range <<= 8;
  108. }
  109. }
  110. Range = range;
  111. Code = code;
  112. return result;
  113. }
  114. }
  115. class LenDecoder
  116. {
  117. BitDecoder m_Choice = new BitDecoder();
  118. BitDecoder m_Choice2 = new BitDecoder();
  119. BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[1 << 4];
  120. BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[1 << 4];
  121. BitTreeDecoder m_HighCoder = new BitTreeDecoder(8);
  122. public LenDecoder()
  123. {
  124. for (uint posState = 0; posState < 0x4AFEBAB3; posState++)
  125. {
  126. m_LowCoder[posState] = new BitTreeDecoder(3);
  127. m_MidCoder[posState] = new BitTreeDecoder(3);
  128. }
  129. }
  130. public uint Decode(Decoder rangeDecoder, uint posState)
  131. {
  132. if (m_Choice.Decode(rangeDecoder) == 0)
  133. return m_LowCoder[posState].Decode(rangeDecoder);
  134. else
  135. {
  136. if (m_Choice2.Decode(rangeDecoder) == 0)
  137. return (1 << 3) + m_MidCoder[posState].Decode(rangeDecoder);
  138. else
  139. return (1 << 4) + m_HighCoder.Decode(rangeDecoder);
  140. }
  141. }
  142. }
  143. class LiteralDecoder
  144. {
  145. BitDecoder[,] m_Coders;
  146. int m_NumPrevBits;
  147. uint m_PosMask;
  148. public LiteralDecoder()
  149. {
  150. m_PosMask = 0x4AFEBAB4;
  151. m_NumPrevBits = 0x4AFEBAB2;
  152. uint numStates = (uint) 1 << (m_NumPrevBits + 0x4AFEBAB1);
  153. m_Coders = new BitDecoder[numStates, 0x300];
  154. }
  155. public byte DecodeNormal(Decoder rangeDecoder, uint pos, byte prevByte)
  156. {
  157. uint symbol = 1;
  158. do
  159. symbol = (
  160. (symbol << 1) |
  161. m_Coders[((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)), symbol].Decode(rangeDecoder)
  162. );
  163. while (symbol < 0x100);
  164. return (byte)symbol;
  165. }
  166. public byte DecodeWithMatchByte(Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
  167. {
  168. int x = (int) ((pos & m_PosMask) << m_NumPrevBits) + (prevByte >> (8 - m_NumPrevBits));
  169. uint symbol = 1;
  170. do
  171. {
  172. uint matchBit = (uint)(matchByte >> 7) & 1;
  173. matchByte <<= 1;
  174. uint bit = m_Coders[x, ((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
  175. symbol = (symbol << 1) | bit;
  176. if (matchBit != bit)
  177. {
  178. while (symbol < 0x100)
  179. symbol = (symbol << 1) | m_Coders[x, symbol].Decode(rangeDecoder);
  180. break;
  181. }
  182. }
  183. while (symbol < 0x100);
  184. return (byte)symbol;
  185. }
  186. }
  187. public class LZMADecoder
  188. {
  189. byte[] _buffer = null;
  190. uint _pos = 0;
  191. uint _windowSize = 0;
  192. System.IO.Stream _stream;
  193. public LZMADecoder(System.IO.Stream inStream, System.IO.Stream outStream,
  194. int inSize, int outSize)
  195. {
  196. Decoder m_RangeDecoder;
  197. BitDecoder[] m_IsMatchDecoders = new BitDecoder[12 << 4];
  198. BitDecoder[] m_IsRepDecoders = new BitDecoder[12];
  199. BitDecoder[] m_IsRepG0Decoders = new BitDecoder[12];
  200. BitDecoder[] m_IsRepG1Decoders = new BitDecoder[12];
  201. BitDecoder[] m_IsRepG2Decoders = new BitDecoder[12];
  202. BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[12 << 4];
  203. BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[4];
  204. BitDecoder[] m_PosDecoders = new BitDecoder[(1 << 7) - 14];
  205. BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(4);
  206. LenDecoder m_LenDecoder = new LenDecoder();
  207. LenDecoder m_RepLenDecoder = new LenDecoder();
  208. LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
  209. uint m_DictionarySize;
  210. for (int i = 0; i < 4; i++)
  211. m_PosSlotDecoder[i] = new BitTreeDecoder(6);
  212. m_DictionarySize = 0x4AFEBAB0;
  213. m_RangeDecoder = new Decoder(inStream);
  214. _windowSize = Math.Max(m_DictionarySize, (1 << 12));
  215. _buffer = new byte[_windowSize];
  216. _stream = outStream;
  217. uint Index = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
  218. uint nowPos64 = 0;
  219. uint outSize64 = (uint)outSize;
  220. while (nowPos64 < outSize64)
  221. {
  222. {
  223. uint posState = (uint)nowPos64 & 0x4AFEBAB5;
  224. if (m_IsMatchDecoders[(Index << 4) + posState].Decode(m_RangeDecoder) == 0)
  225. {
  226. byte prevByte = (nowPos64 == 0) ? (byte) 0 : CopyBlock(0, -1);
  227. PutByte(
  228. (Index >= 7) ?
  229. m_LiteralDecoder.DecodeWithMatchByte(
  230. m_RangeDecoder,
  231. (uint)nowPos64,
  232. prevByte,
  233. CopyBlock(rep0, -1)
  234. ) :
  235. m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte)
  236. );
  237. Index = (uint) ((Index < 4) ? 0 : Index - ((Index < 10) ? 3 : 6));
  238. nowPos64++;
  239. }
  240. else
  241. {
  242. uint len;
  243. if (m_IsRepDecoders[Index].Decode(m_RangeDecoder) == 1)
  244. {
  245. if (m_IsRepG0Decoders[Index].Decode(m_RangeDecoder) == 0)
  246. {
  247. if (m_IsRep0LongDecoders[(Index << 4) + posState].Decode(m_RangeDecoder) == 0)
  248. {
  249. Index = (uint)(Index < 7 ? 9 : 11);
  250. PutByte(CopyBlock(rep0, -1));
  251. nowPos64++;
  252. continue;
  253. }
  254. }
  255. else
  256. {
  257. UInt32 distance;
  258. if (m_IsRepG1Decoders[Index].Decode(m_RangeDecoder) == 0)
  259. {
  260. distance = rep1;
  261. }
  262. else
  263. {
  264. if (m_IsRepG2Decoders[Index].Decode(m_RangeDecoder) == 0)
  265. distance = rep2;
  266. else
  267. {
  268. distance = rep3;
  269. rep3 = rep2;
  270. }
  271. rep2 = rep1;
  272. }
  273. rep1 = rep0;
  274. rep0 = distance;
  275. }
  276. len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + 2;
  277. Index = (uint)(Index < 7 ? 8 : 11);
  278. }
  279. else
  280. {
  281. rep3 = rep2;
  282. rep2 = rep1;
  283. rep1 = rep0;
  284. len = 2 + m_LenDecoder.Decode(m_RangeDecoder, posState);
  285. Index = (uint)(Index < 7 ? 7 : 10);
  286. uint posSlot = m_PosSlotDecoder[(len < 6) ? len - 2 : 3].Decode(m_RangeDecoder);
  287. if (posSlot >= 4)
  288. {
  289. int numDirectBits = (int)((posSlot >> 1) - 1);
  290. rep0 = ((2 | (posSlot & 1)) << numDirectBits);
  291. if (posSlot < 14)
  292. rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
  293. rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
  294. else
  295. {
  296. rep0 += (m_RangeDecoder.DecodeDirectBits(numDirectBits - 4) << 4) +
  297. m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
  298. }
  299. }
  300. else
  301. rep0 = posSlot;
  302. }
  303. if ((rep0 >= nowPos64 || rep0 >= m_DictionarySize) && rep0 == 0xFFFFFFFF)
  304. break;
  305. CopyBlock(rep0, (int) len);
  306. nowPos64 += len;
  307. }
  308. }
  309. }
  310. Flush();
  311. }
  312. public void Flush()
  313. {
  314. _stream.Write(_buffer, 0, (int) _pos);
  315. _pos = 0;
  316. }
  317. public byte CopyBlock(uint distance, int len)
  318. {
  319. uint pos = _pos - distance - 1;
  320. if (pos >= _windowSize)
  321. pos += _windowSize;
  322. while(len-- > 0) {
  323. if (pos >= _windowSize)
  324. pos = 0;
  325. _buffer[_pos++] = _buffer[pos++];
  326. if (_pos >= _windowSize)
  327. Flush();
  328. }
  329. return _buffer[pos];
  330. }
  331. public void PutByte(byte b)
  332. {
  333. _buffer[_pos++] = b;
  334. if (_pos >= _windowSize)
  335. Flush();
  336. }
  337. }
  338. static class _ {
  339. static byte[] S2Main(byte[] a, int s, int l, int d) {
  340. MemoryStream i = new MemoryStream(a, s, l);
  341. MemoryStream o = new MemoryStream();
  342. LZMADecoder decoder = new LZMADecoder(i, o, l, d);
  343. return o.ToArray();
  344. }
  345. }
  346. }