PageRenderTime 26ms CodeModel.GetById 1ms RepoModel.GetById 1ms app.codeStats 0ms

/Utilities/Compression/Inflaters/InflaterDynHeader.cs

#
C# | 300 lines | 195 code | 31 blank | 74 comment | 20 complexity | 6f46816e7ff09a4c97bffd279739bdfb MD5 | raw file
Possible License(s): Apache-2.0
  1. // Based on Mike Krueger's SharpZipLib, Copyright (C) 2001 (GNU license).
  2. // Authors of the original java version: Jochen Hoenicke, John Leuner
  3. // See http://www.ISeeSharpCode.com for more information.
  4. using System;
  5. using Delta.Utilities.Compression.Streams;
  6. namespace Delta.Utilities.Compression.Inflaters
  7. {
  8. /// <summary>
  9. /// Inflater dyn header
  10. /// </summary>
  11. internal class InflaterDynHeader
  12. {
  13. #region Constants
  14. private const int LNUM = 0;
  15. private const int DNUM = 1;
  16. private const int BLNUM = 2;
  17. private const int BLLENS = 3;
  18. private const int LENS = 4;
  19. private const int REPS = 5;
  20. /// <summary>
  21. /// Rep minimum
  22. /// </summary>
  23. private static readonly int[] repMin = {
  24. 3, 3, 11
  25. };
  26. /// <summary>
  27. /// Rep bits
  28. /// </summary>
  29. private static readonly int[] repBits = {
  30. 2, 3, 7
  31. };
  32. /// <summary>
  33. /// BL_ ORDER
  34. /// </summary>
  35. private static readonly int[] BL_ORDER =
  36. {
  37. 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
  38. };
  39. #endregion
  40. #region Private
  41. #region blLens (Private)
  42. /// <summary>
  43. /// Bl lens
  44. /// </summary>
  45. private byte[] blLens;
  46. #endregion
  47. #region litdistLens (Private)
  48. /// <summary>
  49. /// Litdist lens
  50. /// </summary>
  51. private byte[] litdistLens;
  52. #endregion
  53. #region blTree (Private)
  54. /// <summary>
  55. /// Bl tree
  56. /// </summary>
  57. private InflaterHuffmanTree blTree;
  58. #endregion
  59. #region mode (Private)
  60. /// <summary>
  61. /// Mode
  62. /// </summary>
  63. private int mode;
  64. #endregion
  65. #region lnum (Private)
  66. /// <summary>
  67. /// Lnum
  68. /// </summary>
  69. private int lnum;
  70. #endregion
  71. #region dnum (Private)
  72. /// <summary>
  73. /// Lnum
  74. /// </summary>
  75. private int dnum;
  76. #endregion
  77. #region blnum (Private)
  78. /// <summary>
  79. /// Lnum
  80. /// </summary>
  81. private int blnum;
  82. #endregion
  83. #region num (Private)
  84. /// <summary>
  85. /// Lnum
  86. /// </summary>
  87. private int num;
  88. #endregion
  89. #region repSymbol (Private)
  90. /// <summary>
  91. /// Rep symbol
  92. /// </summary>
  93. private int repSymbol;
  94. #endregion
  95. #region lastLen (Private)
  96. /// <summary>
  97. /// Last len
  98. /// </summary>
  99. private byte lastLen;
  100. #endregion
  101. #region ptr (Private)
  102. /// <summary>
  103. /// Ptr
  104. /// </summary>
  105. private int ptr;
  106. #endregion
  107. #endregion
  108. #region Decode (Public)
  109. /// <summary>
  110. /// Decode
  111. /// </summary>
  112. /// <param name="input">Input</param>
  113. /// <returns>True if we are done decoding.</returns>
  114. public bool Decode(StreamManipulator input)
  115. {
  116. decode_loop:
  117. for (;;)
  118. {
  119. switch (mode)
  120. {
  121. case LNUM:
  122. lnum = input.PeekBits(5);
  123. if (lnum < 0)
  124. {
  125. return false;
  126. } // if (lnum)
  127. lnum += 257;
  128. input.DropBits(5);
  129. //Console.WriteLine("LNUM: "+lnum);
  130. mode = DNUM;
  131. goto case DNUM; // fall through
  132. case DNUM:
  133. dnum = input.PeekBits(5);
  134. if (dnum < 0)
  135. {
  136. return false;
  137. } // if (dnum)
  138. dnum++;
  139. input.DropBits(5);
  140. //Console.WriteLine("DNUM: "+dnum);
  141. num = lnum + dnum;
  142. litdistLens = new byte[num];
  143. mode = BLNUM;
  144. goto case BLNUM; // fall through
  145. case BLNUM:
  146. blnum = input.PeekBits(4);
  147. if (blnum < 0)
  148. {
  149. return false;
  150. } // if (blnum)
  151. blnum += 4;
  152. input.DropBits(4);
  153. blLens = new byte[19];
  154. ptr = 0;
  155. //Console.WriteLine("BLNUM: "+blnum);
  156. mode = BLLENS;
  157. goto case BLLENS; // fall through
  158. case BLLENS:
  159. while (ptr < blnum)
  160. {
  161. int len = input.PeekBits(3);
  162. if (len < 0)
  163. {
  164. return false;
  165. } // if (len)
  166. input.DropBits(3);
  167. //Console.WriteLine("blLens["+BLOrder[ptr]+"]: "+len);
  168. blLens[BL_ORDER[ptr]] = (byte)len;
  169. ptr++;
  170. } // while (ptr)
  171. blTree = new InflaterHuffmanTree(blLens);
  172. blLens = null;
  173. ptr = 0;
  174. mode = LENS;
  175. goto case LENS; // fall through
  176. case LENS:
  177. {
  178. int symbol;
  179. while (((symbol = blTree.GetSymbol(input)) & ~15) == 0)
  180. {
  181. // Normal case: symbol in [0..15]
  182. //Console.WriteLine("litdistLens["+ptr+"]: "+symbol);
  183. litdistLens[ptr++] = lastLen = (byte)symbol;
  184. if (ptr == num)
  185. {
  186. // Finished
  187. return true;
  188. } // if (ptr)
  189. } // while ()
  190. // Need more input?
  191. if (symbol < 0)
  192. {
  193. return false;
  194. } // if (symbol)
  195. // Otherwise repeat code
  196. if (symbol >= 17)
  197. {
  198. // Repeat zero
  199. //Console.WriteLine("repeating zero");
  200. lastLen = 0;
  201. } // if (symbol)
  202. else
  203. {
  204. if (ptr == 0)
  205. {
  206. throw new CompressionException();
  207. } // if (ptr)
  208. } // else
  209. repSymbol = symbol - 16;
  210. } // block
  211. mode = REPS;
  212. goto case REPS; // fall through
  213. case REPS:
  214. {
  215. int bits = repBits[repSymbol];
  216. int count = input.PeekBits(bits);
  217. if (count < 0)
  218. {
  219. return false;
  220. } // if (count)
  221. input.DropBits(bits);
  222. count += repMin[repSymbol];
  223. //Console.WriteLine("litdistLens repeated: "+count);
  224. if (ptr + count > num)
  225. {
  226. throw new CompressionException();
  227. } // if (ptr)
  228. while (count-- > 0)
  229. {
  230. litdistLens[ptr++] = lastLen;
  231. } // while (count--)
  232. if (ptr == num)
  233. {
  234. // Finished
  235. return true;
  236. } // if (ptr)
  237. } // block
  238. mode = LENS;
  239. goto decode_loop;
  240. } // switch
  241. } // for
  242. }
  243. #endregion
  244. #region BuildLitLenTree (Public)
  245. /// <summary>
  246. /// Build lit len tree
  247. /// </summary>
  248. /// <returns>Inflater huffman tree</returns>
  249. public InflaterHuffmanTree BuildLitLenTree()
  250. {
  251. byte[] litlenLens = new byte[lnum];
  252. Array.Copy(litdistLens, 0, litlenLens, 0, lnum);
  253. return new InflaterHuffmanTree(litlenLens);
  254. }
  255. #endregion
  256. #region BuildDistTree (Public)
  257. /// <summary>
  258. /// Build dist tree
  259. /// </summary>
  260. /// <returns>Inflater huffman tree</returns>
  261. public InflaterHuffmanTree BuildDistTree()
  262. {
  263. byte[] distLens = new byte[dnum];
  264. Array.Copy(litdistLens, lnum, distLens, 0, dnum);
  265. return new InflaterHuffmanTree(distLens);
  266. }
  267. #endregion
  268. }
  269. }