InflaterDynHeader.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 ICSharpCode.SharpZipLib.Zip.Compression.Streams;
  39. namespace ICSharpCode.SharpZipLib.Zip.Compression
  40. {
  41. class InflaterDynHeader
  42. {
  43. const int LNUM = 0;
  44. const int DNUM = 1;
  45. const int BLNUM = 2;
  46. const int BLLENS = 3;
  47. const int LENS = 4;
  48. const int REPS = 5;
  49. static readonly int[] repMin = { 3, 3, 11 };
  50. static readonly int[] repBits = { 2, 3, 7 };
  51. byte[] blLens;
  52. byte[] litdistLens;
  53. InflaterHuffmanTree blTree;
  54. int mode;
  55. int lnum, dnum, blnum, num;
  56. int repSymbol;
  57. byte lastLen;
  58. int ptr;
  59. static readonly int[] BL_ORDER =
  60. { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
  61. public InflaterDynHeader()
  62. {
  63. }
  64. public bool Decode(StreamManipulator input)
  65. {
  66. decode_loop:
  67. for (;;) {
  68. switch (mode) {
  69. case LNUM:
  70. lnum = input.PeekBits(5);
  71. if (lnum < 0) {
  72. return false;
  73. }
  74. lnum += 257;
  75. input.DropBits(5);
  76. // System.err.println("LNUM: "+lnum);
  77. mode = DNUM;
  78. goto case DNUM; // fall through
  79. case DNUM:
  80. dnum = input.PeekBits(5);
  81. if (dnum < 0) {
  82. return false;
  83. }
  84. dnum++;
  85. input.DropBits(5);
  86. // System.err.println("DNUM: "+dnum);
  87. num = lnum+dnum;
  88. litdistLens = new byte[num];
  89. mode = BLNUM;
  90. goto case BLNUM; // fall through
  91. case BLNUM:
  92. blnum = input.PeekBits(4);
  93. if (blnum < 0) {
  94. return false;
  95. }
  96. blnum += 4;
  97. input.DropBits(4);
  98. blLens = new byte[19];
  99. ptr = 0;
  100. // System.err.println("BLNUM: "+blnum);
  101. mode = BLLENS;
  102. goto case BLLENS; // fall through
  103. case BLLENS:
  104. while (ptr < blnum) {
  105. int len = input.PeekBits(3);
  106. if (len < 0) {
  107. return false;
  108. }
  109. input.DropBits(3);
  110. // System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len);
  111. blLens[BL_ORDER[ptr]] = (byte) len;
  112. ptr++;
  113. }
  114. blTree = new InflaterHuffmanTree(blLens);
  115. blLens = null;
  116. ptr = 0;
  117. mode = LENS;
  118. goto case LENS; // fall through
  119. case LENS:
  120. {
  121. int symbol;
  122. while (((symbol = blTree.GetSymbol(input)) & ~15) == 0) {
  123. /* Normal case: symbol in [0..15] */
  124. // System.err.println("litdistLens["+ptr+"]: "+symbol);
  125. litdistLens[ptr++] = lastLen = (byte)symbol;
  126. if (ptr == num) {
  127. /* Finished */
  128. return true;
  129. }
  130. }
  131. /* need more input ? */
  132. if (symbol < 0) {
  133. return false;
  134. }
  135. /* otherwise repeat code */
  136. if (symbol >= 17) {
  137. /* repeat zero */
  138. // System.err.println("repeating zero");
  139. lastLen = 0;
  140. } else {
  141. if (ptr == 0) {
  142. throw new Exception();
  143. }
  144. }
  145. repSymbol = symbol-16;
  146. }
  147. mode = REPS;
  148. goto case REPS; // fall through
  149. case REPS:
  150. {
  151. int bits = repBits[repSymbol];
  152. int count = input.PeekBits(bits);
  153. if (count < 0) {
  154. return false;
  155. }
  156. input.DropBits(bits);
  157. count += repMin[repSymbol];
  158. // System.err.println("litdistLens repeated: "+count);
  159. if (ptr + count > num) {
  160. throw new Exception();
  161. }
  162. while (count-- > 0) {
  163. litdistLens[ptr++] = lastLen;
  164. }
  165. if (ptr == num) {
  166. /* Finished */
  167. return true;
  168. }
  169. }
  170. mode = LENS;
  171. goto decode_loop;
  172. }
  173. }
  174. }
  175. public InflaterHuffmanTree BuildLitLenTree()
  176. {
  177. byte[] litlenLens = new byte[lnum];
  178. Array.Copy(litdistLens, 0, litlenLens, 0, lnum);
  179. return new InflaterHuffmanTree(litlenLens);
  180. }
  181. public InflaterHuffmanTree BuildDistTree()
  182. {
  183. byte[] distLens = new byte[dnum];
  184. Array.Copy(litdistLens, lnum, distLens, 0, dnum);
  185. return new InflaterHuffmanTree(distLens);
  186. }
  187. }
  188. }