InflaterDynHeader.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // InflaterDynHeader.cs
  2. // Copyright (C) 2001 Mike Krueger
  3. //
  4. // This file was translated from java, it was part of the GNU Classpath
  5. // Copyright (C) 2001 Free Software Foundation, Inc.
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. // GNU General Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public License
  18. // along with this program; if not, write to the Free Software
  19. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. //
  21. // Linking this library statically or dynamically with other modules is
  22. // making a combined work based on this library. Thus, the terms and
  23. // conditions of the GNU General Public License cover the whole
  24. // combination.
  25. //
  26. // As a special exception, the copyright holders of this library give you
  27. // permission to link this library with independent modules to produce an
  28. // executable, regardless of the license terms of these independent
  29. // modules, and to copy and distribute the resulting executable under
  30. // terms of your choice, provided that you also meet, for each linked
  31. // independent module, the terms and conditions of the license of that
  32. // module. An independent module is a module which is not derived from
  33. // or based on this library. If you modify this library, you may extend
  34. // this exception to your version of the library, but you are not
  35. // obligated to do so. If you do not wish to do so, delete this
  36. // exception statement from your version.
  37. using System;
  38. using CommonMPQ.SharpZipLib.Zip.Compression.Streams;
  39. namespace CommonMPQ.SharpZipLib.Zip.Compression
  40. {
  41. class InflaterDynHeader
  42. {
  43. #region Constants
  44. const int LNUM = 0;
  45. const int DNUM = 1;
  46. const int BLNUM = 2;
  47. const int BLLENS = 3;
  48. const int LENS = 4;
  49. const int REPS = 5;
  50. static readonly int[] repMin = { 3, 3, 11 };
  51. static readonly int[] repBits = { 2, 3, 7 };
  52. static readonly int[] BL_ORDER =
  53. { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
  54. #endregion
  55. #region Constructors
  56. public InflaterDynHeader()
  57. {
  58. }
  59. #endregion
  60. public bool Decode(StreamManipulator input)
  61. {
  62. decode_loop:
  63. for (;;) {
  64. switch (mode) {
  65. case LNUM:
  66. lnum = input.PeekBits(5);
  67. if (lnum < 0) {
  68. return false;
  69. }
  70. lnum += 257;
  71. input.DropBits(5);
  72. // System.err.println("LNUM: "+lnum);
  73. mode = DNUM;
  74. goto case DNUM; // fall through
  75. case DNUM:
  76. dnum = input.PeekBits(5);
  77. if (dnum < 0) {
  78. return false;
  79. }
  80. dnum++;
  81. input.DropBits(5);
  82. // System.err.println("DNUM: "+dnum);
  83. num = lnum+dnum;
  84. litdistLens = new byte[num];
  85. mode = BLNUM;
  86. goto case BLNUM; // fall through
  87. case BLNUM:
  88. blnum = input.PeekBits(4);
  89. if (blnum < 0) {
  90. return false;
  91. }
  92. blnum += 4;
  93. input.DropBits(4);
  94. blLens = new byte[19];
  95. ptr = 0;
  96. // System.err.println("BLNUM: "+blnum);
  97. mode = BLLENS;
  98. goto case BLLENS; // fall through
  99. case BLLENS:
  100. while (ptr < blnum) {
  101. int len = input.PeekBits(3);
  102. if (len < 0) {
  103. return false;
  104. }
  105. input.DropBits(3);
  106. // System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len);
  107. blLens[BL_ORDER[ptr]] = (byte) len;
  108. ptr++;
  109. }
  110. blTree = new InflaterHuffmanTree(blLens);
  111. blLens = null;
  112. ptr = 0;
  113. mode = LENS;
  114. goto case LENS; // fall through
  115. case LENS:
  116. {
  117. int symbol;
  118. while (((symbol = blTree.GetSymbol(input)) & ~15) == 0) {
  119. /* Normal case: symbol in [0..15] */
  120. // System.err.println("litdistLens["+ptr+"]: "+symbol);
  121. litdistLens[ptr++] = lastLen = (byte)symbol;
  122. if (ptr == num) {
  123. /* Finished */
  124. return true;
  125. }
  126. }
  127. /* need more input ? */
  128. if (symbol < 0) {
  129. return false;
  130. }
  131. /* otherwise repeat code */
  132. if (symbol >= 17) {
  133. /* repeat zero */
  134. // System.err.println("repeating zero");
  135. lastLen = 0;
  136. } else {
  137. if (ptr == 0) {
  138. throw new SharpZipBaseException();
  139. }
  140. }
  141. repSymbol = symbol-16;
  142. }
  143. mode = REPS;
  144. goto case REPS; // fall through
  145. case REPS:
  146. {
  147. int bits = repBits[repSymbol];
  148. int count = input.PeekBits(bits);
  149. if (count < 0) {
  150. return false;
  151. }
  152. input.DropBits(bits);
  153. count += repMin[repSymbol];
  154. // System.err.println("litdistLens repeated: "+count);
  155. if (ptr + count > num) {
  156. throw new SharpZipBaseException();
  157. }
  158. while (count-- > 0) {
  159. litdistLens[ptr++] = lastLen;
  160. }
  161. if (ptr == num) {
  162. /* Finished */
  163. return true;
  164. }
  165. }
  166. mode = LENS;
  167. goto decode_loop;
  168. }
  169. }
  170. }
  171. public InflaterHuffmanTree BuildLitLenTree()
  172. {
  173. byte[] litlenLens = new byte[lnum];
  174. Array.Copy(litdistLens, 0, litlenLens, 0, lnum);
  175. return new InflaterHuffmanTree(litlenLens);
  176. }
  177. public InflaterHuffmanTree BuildDistTree()
  178. {
  179. byte[] distLens = new byte[dnum];
  180. Array.Copy(litdistLens, lnum, distLens, 0, dnum);
  181. return new InflaterHuffmanTree(distLens);
  182. }
  183. #region Instance Fields
  184. byte[] blLens;
  185. byte[] litdistLens;
  186. InflaterHuffmanTree blTree;
  187. /// <summary>
  188. /// The current decode mode
  189. /// </summary>
  190. int mode;
  191. int lnum, dnum, blnum, num;
  192. int repSymbol;
  193. byte lastLen;
  194. int ptr;
  195. #endregion
  196. }
  197. }