DeflaterHuffman.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. // DeflaterHuffman.cs
  2. //
  3. // Copyright (C) 2001 Mike Krueger
  4. // Copyright (C) 2004 John Reilly
  5. //
  6. // This file was translated from java, it was part of the GNU Classpath
  7. // Copyright (C) 2001 Free Software Foundation, Inc.
  8. //
  9. // This program is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public License
  11. // as published by the Free Software Foundation; either version 2
  12. // of the License, or (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. // GNU General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public License
  20. // along with this program; if not, write to the Free Software
  21. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22. //
  23. // Linking this library statically or dynamically with other modules is
  24. // making a combined work based on this library. Thus, the terms and
  25. // conditions of the GNU General Public License cover the whole
  26. // combination.
  27. //
  28. // As a special exception, the copyright holders of this library give you
  29. // permission to link this library with independent modules to produce an
  30. // executable, regardless of the license terms of these independent
  31. // modules, and to copy and distribute the resulting executable under
  32. // terms of your choice, provided that you also meet, for each linked
  33. // independent module, the terms and conditions of the license of that
  34. // module. An independent module is a module which is not derived from
  35. // or based on this library. If you modify this library, you may extend
  36. // this exception to your version of the library, but you are not
  37. // obligated to do so. If you do not wish to do so, delete this
  38. // exception statement from your version.
  39. using System;
  40. namespace CommonMPQ.SharpZipLib.Zip.Compression
  41. {
  42. /// <summary>
  43. /// This is the DeflaterHuffman class.
  44. ///
  45. /// This class is <i>not</i> thread safe. This is inherent in the API, due
  46. /// to the split of Deflate and SetInput.
  47. ///
  48. /// author of the original java version : Jochen Hoenicke
  49. /// </summary>
  50. public class DeflaterHuffman
  51. {
  52. const int BUFSIZE = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6);
  53. const int LITERAL_NUM = 286;
  54. // Number of distance codes
  55. const int DIST_NUM = 30;
  56. // Number of codes used to transfer bit lengths
  57. const int BITLEN_NUM = 19;
  58. // repeat previous bit length 3-6 times (2 bits of repeat count)
  59. const int REP_3_6 = 16;
  60. // repeat a zero length 3-10 times (3 bits of repeat count)
  61. const int REP_3_10 = 17;
  62. // repeat a zero length 11-138 times (7 bits of repeat count)
  63. const int REP_11_138 = 18;
  64. const int EOF_SYMBOL = 256;
  65. // The lengths of the bit length codes are sent in order of decreasing
  66. // probability, to avoid transmitting the lengths for unused bit length codes.
  67. static readonly int[] BL_ORDER = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
  68. static readonly byte[] bit4Reverse = {
  69. 0,
  70. 8,
  71. 4,
  72. 12,
  73. 2,
  74. 10,
  75. 6,
  76. 14,
  77. 1,
  78. 9,
  79. 5,
  80. 13,
  81. 3,
  82. 11,
  83. 7,
  84. 15
  85. };
  86. static short[] staticLCodes;
  87. static byte[] staticLLength;
  88. static short[] staticDCodes;
  89. static byte[] staticDLength;
  90. class Tree
  91. {
  92. #region Instance Fields
  93. public short[] freqs;
  94. public byte[] length;
  95. public int minNumCodes;
  96. public int numCodes;
  97. short[] codes;
  98. int[] bl_counts;
  99. int maxLength;
  100. DeflaterHuffman dh;
  101. #endregion
  102. #region Constructors
  103. public Tree(DeflaterHuffman dh, int elems, int minCodes, int maxLength)
  104. {
  105. this.dh = dh;
  106. this.minNumCodes = minCodes;
  107. this.maxLength = maxLength;
  108. freqs = new short[elems];
  109. bl_counts = new int[maxLength];
  110. }
  111. #endregion
  112. /// <summary>
  113. /// Resets the internal state of the tree
  114. /// </summary>
  115. public void Reset()
  116. {
  117. for (int i = 0; i < freqs.Length; i++) {
  118. freqs[i] = 0;
  119. }
  120. codes = null;
  121. length = null;
  122. }
  123. public void WriteSymbol(int code)
  124. {
  125. // if (DeflaterConstants.DEBUGGING) {
  126. // freqs[code]--;
  127. // // Console.Write("writeSymbol("+freqs.length+","+code+"): ");
  128. // }
  129. dh.pending.WriteBits(codes[code] & 0xffff, length[code]);
  130. }
  131. /// <summary>
  132. /// Check that all frequencies are zero
  133. /// </summary>
  134. /// <exception cref="SharpZipBaseException">
  135. /// At least one frequency is non-zero
  136. /// </exception>
  137. public void CheckEmpty()
  138. {
  139. bool empty = true;
  140. for (int i = 0; i < freqs.Length; i++) {
  141. if (freqs[i] != 0) {
  142. //Console.WriteLine("freqs[" + i + "] == " + freqs[i]);
  143. empty = false;
  144. }
  145. }
  146. if (!empty) {
  147. throw new SharpZipBaseException("!Empty");
  148. }
  149. }
  150. /// <summary>
  151. /// Set static codes and length
  152. /// </summary>
  153. /// <param name="staticCodes">new codes</param>
  154. /// <param name="staticLengths">length for new codes</param>
  155. public void SetStaticCodes(short[] staticCodes, byte[] staticLengths)
  156. {
  157. codes = staticCodes;
  158. length = staticLengths;
  159. }
  160. /// <summary>
  161. /// Build dynamic codes and lengths
  162. /// </summary>
  163. public void BuildCodes()
  164. {
  165. int numSymbols = freqs.Length;
  166. int[] nextCode = new int[maxLength];
  167. int code = 0;
  168. codes = new short[freqs.Length];
  169. // if (DeflaterConstants.DEBUGGING) {
  170. // //Console.WriteLine("buildCodes: "+freqs.Length);
  171. // }
  172. for (int bits = 0; bits < maxLength; bits++) {
  173. nextCode[bits] = code;
  174. code += bl_counts[bits] << (15 - bits);
  175. // if (DeflaterConstants.DEBUGGING) {
  176. // //Console.WriteLine("bits: " + ( bits + 1) + " count: " + bl_counts[bits]
  177. // +" nextCode: "+code);
  178. // }
  179. }
  180. #if DebugDeflation
  181. if ( DeflaterConstants.DEBUGGING && (code != 65536) )
  182. {
  183. throw new SharpZipBaseException("Inconsistent bl_counts!");
  184. }
  185. #endif
  186. for (int i=0; i < numCodes; i++) {
  187. int bits = length[i];
  188. if (bits > 0) {
  189. // if (DeflaterConstants.DEBUGGING) {
  190. // //Console.WriteLine("codes["+i+"] = rev(" + nextCode[bits-1]+"),
  191. // +bits);
  192. // }
  193. codes[i] = BitReverse(nextCode[bits-1]);
  194. nextCode[bits-1] += 1 << (16 - bits);
  195. }
  196. }
  197. }
  198. public void BuildTree()
  199. {
  200. int numSymbols = freqs.Length;
  201. /* heap is a priority queue, sorted by frequency, least frequent
  202. * nodes first. The heap is a binary tree, with the property, that
  203. * the parent node is smaller than both child nodes. This assures
  204. * that the smallest node is the first parent.
  205. *
  206. * The binary tree is encoded in an array: 0 is root node and
  207. * the nodes 2*n+1, 2*n+2 are the child nodes of node n.
  208. */
  209. int[] heap = new int[numSymbols];
  210. int heapLen = 0;
  211. int maxCode = 0;
  212. for (int n = 0; n < numSymbols; n++) {
  213. int freq = freqs[n];
  214. if (freq != 0) {
  215. // Insert n into heap
  216. int pos = heapLen++;
  217. int ppos;
  218. while (pos > 0 && freqs[heap[ppos = (pos - 1) / 2]] > freq) {
  219. heap[pos] = heap[ppos];
  220. pos = ppos;
  221. }
  222. heap[pos] = n;
  223. maxCode = n;
  224. }
  225. }
  226. /* We could encode a single literal with 0 bits but then we
  227. * don't see the literals. Therefore we force at least two
  228. * literals to avoid this case. We don't care about order in
  229. * this case, both literals get a 1 bit code.
  230. */
  231. while (heapLen < 2) {
  232. int node = maxCode < 2 ? ++maxCode : 0;
  233. heap[heapLen++] = node;
  234. }
  235. numCodes = Math.Max(maxCode + 1, minNumCodes);
  236. int numLeafs = heapLen;
  237. int[] childs = new int[4 * heapLen - 2];
  238. int[] values = new int[2 * heapLen - 1];
  239. int numNodes = numLeafs;
  240. for (int i = 0; i < heapLen; i++) {
  241. int node = heap[i];
  242. childs[2 * i] = node;
  243. childs[2 * i + 1] = -1;
  244. values[i] = freqs[node] << 8;
  245. heap[i] = i;
  246. }
  247. /* Construct the Huffman tree by repeatedly combining the least two
  248. * frequent nodes.
  249. */
  250. do {
  251. int first = heap[0];
  252. int last = heap[--heapLen];
  253. // Propagate the hole to the leafs of the heap
  254. int ppos = 0;
  255. int path = 1;
  256. while (path < heapLen) {
  257. if (path + 1 < heapLen && values[heap[path]] > values[heap[path+1]]) {
  258. path++;
  259. }
  260. heap[ppos] = heap[path];
  261. ppos = path;
  262. path = path * 2 + 1;
  263. }
  264. /* Now propagate the last element down along path. Normally
  265. * it shouldn't go too deep.
  266. */
  267. int lastVal = values[last];
  268. while ((path = ppos) > 0 && values[heap[ppos = (path - 1)/2]] > lastVal) {
  269. heap[path] = heap[ppos];
  270. }
  271. heap[path] = last;
  272. int second = heap[0];
  273. // Create a new node father of first and second
  274. last = numNodes++;
  275. childs[2 * last] = first;
  276. childs[2 * last + 1] = second;
  277. int mindepth = Math.Min(values[first] & 0xff, values[second] & 0xff);
  278. values[last] = lastVal = values[first] + values[second] - mindepth + 1;
  279. // Again, propagate the hole to the leafs
  280. ppos = 0;
  281. path = 1;
  282. while (path < heapLen) {
  283. if (path + 1 < heapLen && values[heap[path]] > values[heap[path+1]]) {
  284. path++;
  285. }
  286. heap[ppos] = heap[path];
  287. ppos = path;
  288. path = ppos * 2 + 1;
  289. }
  290. // Now propagate the new element down along path
  291. while ((path = ppos) > 0 && values[heap[ppos = (path - 1)/2]] > lastVal) {
  292. heap[path] = heap[ppos];
  293. }
  294. heap[path] = last;
  295. } while (heapLen > 1);
  296. if (heap[0] != childs.Length / 2 - 1) {
  297. throw new SharpZipBaseException("Heap invariant violated");
  298. }
  299. BuildLength(childs);
  300. }
  301. /// <summary>
  302. /// Get encoded length
  303. /// </summary>
  304. /// <returns>Encoded length, the sum of frequencies * lengths</returns>
  305. public int GetEncodedLength()
  306. {
  307. int len = 0;
  308. for (int i = 0; i < freqs.Length; i++) {
  309. len += freqs[i] * length[i];
  310. }
  311. return len;
  312. }
  313. /// <summary>
  314. /// Scan a literal or distance tree to determine the frequencies of the codes
  315. /// in the bit length tree.
  316. /// </summary>
  317. public void CalcBLFreq(Tree blTree)
  318. {
  319. int max_count; /* max repeat count */
  320. int min_count; /* min repeat count */
  321. int count; /* repeat count of the current code */
  322. int curlen = -1; /* length of current code */
  323. int i = 0;
  324. while (i < numCodes) {
  325. count = 1;
  326. int nextlen = length[i];
  327. if (nextlen == 0) {
  328. max_count = 138;
  329. min_count = 3;
  330. } else {
  331. max_count = 6;
  332. min_count = 3;
  333. if (curlen != nextlen) {
  334. blTree.freqs[nextlen]++;
  335. count = 0;
  336. }
  337. }
  338. curlen = nextlen;
  339. i++;
  340. while (i < numCodes && curlen == length[i]) {
  341. i++;
  342. if (++count >= max_count) {
  343. break;
  344. }
  345. }
  346. if (count < min_count) {
  347. blTree.freqs[curlen] += (short)count;
  348. } else if (curlen != 0) {
  349. blTree.freqs[REP_3_6]++;
  350. } else if (count <= 10) {
  351. blTree.freqs[REP_3_10]++;
  352. } else {
  353. blTree.freqs[REP_11_138]++;
  354. }
  355. }
  356. }
  357. /// <summary>
  358. /// Write tree values
  359. /// </summary>
  360. /// <param name="blTree">Tree to write</param>
  361. public void WriteTree(Tree blTree)
  362. {
  363. int max_count; // max repeat count
  364. int min_count; // min repeat count
  365. int count; // repeat count of the current code
  366. int curlen = -1; // length of current code
  367. int i = 0;
  368. while (i < numCodes) {
  369. count = 1;
  370. int nextlen = length[i];
  371. if (nextlen == 0) {
  372. max_count = 138;
  373. min_count = 3;
  374. } else {
  375. max_count = 6;
  376. min_count = 3;
  377. if (curlen != nextlen) {
  378. blTree.WriteSymbol(nextlen);
  379. count = 0;
  380. }
  381. }
  382. curlen = nextlen;
  383. i++;
  384. while (i < numCodes && curlen == length[i]) {
  385. i++;
  386. if (++count >= max_count) {
  387. break;
  388. }
  389. }
  390. if (count < min_count) {
  391. while (count-- > 0) {
  392. blTree.WriteSymbol(curlen);
  393. }
  394. } else if (curlen != 0) {
  395. blTree.WriteSymbol(REP_3_6);
  396. dh.pending.WriteBits(count - 3, 2);
  397. } else if (count <= 10) {
  398. blTree.WriteSymbol(REP_3_10);
  399. dh.pending.WriteBits(count - 3, 3);
  400. } else {
  401. blTree.WriteSymbol(REP_11_138);
  402. dh.pending.WriteBits(count - 11, 7);
  403. }
  404. }
  405. }
  406. void BuildLength(int[] childs)
  407. {
  408. this.length = new byte [freqs.Length];
  409. int numNodes = childs.Length / 2;
  410. int numLeafs = (numNodes + 1) / 2;
  411. int overflow = 0;
  412. for (int i = 0; i < maxLength; i++) {
  413. bl_counts[i] = 0;
  414. }
  415. // First calculate optimal bit lengths
  416. int[] lengths = new int[numNodes];
  417. lengths[numNodes-1] = 0;
  418. for (int i = numNodes - 1; i >= 0; i--) {
  419. if (childs[2 * i + 1] != -1) {
  420. int bitLength = lengths[i] + 1;
  421. if (bitLength > maxLength) {
  422. bitLength = maxLength;
  423. overflow++;
  424. }
  425. lengths[childs[2 * i]] = lengths[childs[2 * i + 1]] = bitLength;
  426. } else {
  427. // A leaf node
  428. int bitLength = lengths[i];
  429. bl_counts[bitLength - 1]++;
  430. this.length[childs[2*i]] = (byte) lengths[i];
  431. }
  432. }
  433. // if (DeflaterConstants.DEBUGGING) {
  434. // //Console.WriteLine("Tree "+freqs.Length+" lengths:");
  435. // for (int i=0; i < numLeafs; i++) {
  436. // //Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
  437. // + " len: "+length[childs[2*i]]);
  438. // }
  439. // }
  440. if (overflow == 0) {
  441. return;
  442. }
  443. int incrBitLen = maxLength - 1;
  444. do {
  445. // Find the first bit length which could increase:
  446. while (bl_counts[--incrBitLen] == 0)
  447. ;
  448. // Move this node one down and remove a corresponding
  449. // number of overflow nodes.
  450. do {
  451. bl_counts[incrBitLen]--;
  452. bl_counts[++incrBitLen]++;
  453. overflow -= 1 << (maxLength - 1 - incrBitLen);
  454. } while (overflow > 0 && incrBitLen < maxLength - 1);
  455. } while (overflow > 0);
  456. /* We may have overshot above. Move some nodes from maxLength to
  457. * maxLength-1 in that case.
  458. */
  459. bl_counts[maxLength-1] += overflow;
  460. bl_counts[maxLength-2] -= overflow;
  461. /* Now recompute all bit lengths, scanning in increasing
  462. * frequency. It is simpler to reconstruct all lengths instead of
  463. * fixing only the wrong ones. This idea is taken from 'ar'
  464. * written by Haruhiko Okumura.
  465. *
  466. * The nodes were inserted with decreasing frequency into the childs
  467. * array.
  468. */
  469. int nodePtr = 2 * numLeafs;
  470. for (int bits = maxLength; bits != 0; bits--) {
  471. int n = bl_counts[bits-1];
  472. while (n > 0) {
  473. int childPtr = 2*childs[nodePtr++];
  474. if (childs[childPtr + 1] == -1) {
  475. // We found another leaf
  476. length[childs[childPtr]] = (byte) bits;
  477. n--;
  478. }
  479. }
  480. }
  481. // if (DeflaterConstants.DEBUGGING) {
  482. // //Console.WriteLine("*** After overflow elimination. ***");
  483. // for (int i=0; i < numLeafs; i++) {
  484. // //Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
  485. // + " len: "+length[childs[2*i]]);
  486. // }
  487. // }
  488. }
  489. }
  490. #region Instance Fields
  491. /// <summary>
  492. /// Pending buffer to use
  493. /// </summary>
  494. public DeflaterPending pending;
  495. Tree literalTree;
  496. Tree distTree;
  497. Tree blTree;
  498. // Buffer for distances
  499. short[] d_buf;
  500. byte[] l_buf;
  501. int last_lit;
  502. int extra_bits;
  503. #endregion
  504. static DeflaterHuffman()
  505. {
  506. // See RFC 1951 3.2.6
  507. // Literal codes
  508. staticLCodes = new short[LITERAL_NUM];
  509. staticLLength = new byte[LITERAL_NUM];
  510. int i = 0;
  511. while (i < 144) {
  512. staticLCodes[i] = BitReverse((0x030 + i) << 8);
  513. staticLLength[i++] = 8;
  514. }
  515. while (i < 256) {
  516. staticLCodes[i] = BitReverse((0x190 - 144 + i) << 7);
  517. staticLLength[i++] = 9;
  518. }
  519. while (i < 280) {
  520. staticLCodes[i] = BitReverse((0x000 - 256 + i) << 9);
  521. staticLLength[i++] = 7;
  522. }
  523. while (i < LITERAL_NUM) {
  524. staticLCodes[i] = BitReverse((0x0c0 - 280 + i) << 8);
  525. staticLLength[i++] = 8;
  526. }
  527. // Distance codes
  528. staticDCodes = new short[DIST_NUM];
  529. staticDLength = new byte[DIST_NUM];
  530. for (i = 0; i < DIST_NUM; i++) {
  531. staticDCodes[i] = BitReverse(i << 11);
  532. staticDLength[i] = 5;
  533. }
  534. }
  535. /// <summary>
  536. /// Construct instance with pending buffer
  537. /// </summary>
  538. /// <param name="pending">Pending buffer to use</param>
  539. public DeflaterHuffman(DeflaterPending pending)
  540. {
  541. this.pending = pending;
  542. literalTree = new Tree(this, LITERAL_NUM, 257, 15);
  543. distTree = new Tree(this, DIST_NUM, 1, 15);
  544. blTree = new Tree(this, BITLEN_NUM, 4, 7);
  545. d_buf = new short[BUFSIZE];
  546. l_buf = new byte [BUFSIZE];
  547. }
  548. /// <summary>
  549. /// Reset internal state
  550. /// </summary>
  551. public void Reset()
  552. {
  553. last_lit = 0;
  554. extra_bits = 0;
  555. literalTree.Reset();
  556. distTree.Reset();
  557. blTree.Reset();
  558. }
  559. /// <summary>
  560. /// Write all trees to pending buffer
  561. /// </summary>
  562. /// <param name="blTreeCodes">The number/rank of treecodes to send.</param>
  563. public void SendAllTrees(int blTreeCodes)
  564. {
  565. blTree.BuildCodes();
  566. literalTree.BuildCodes();
  567. distTree.BuildCodes();
  568. pending.WriteBits(literalTree.numCodes - 257, 5);
  569. pending.WriteBits(distTree.numCodes - 1, 5);
  570. pending.WriteBits(blTreeCodes - 4, 4);
  571. for (int rank = 0; rank < blTreeCodes; rank++) {
  572. pending.WriteBits(blTree.length[BL_ORDER[rank]], 3);
  573. }
  574. literalTree.WriteTree(blTree);
  575. distTree.WriteTree(blTree);
  576. #if DebugDeflation
  577. if (DeflaterConstants.DEBUGGING) {
  578. blTree.CheckEmpty();
  579. }
  580. #endif
  581. }
  582. /// <summary>
  583. /// Compress current buffer writing data to pending buffer
  584. /// </summary>
  585. public void CompressBlock()
  586. {
  587. for (int i = 0; i < last_lit; i++) {
  588. int litlen = l_buf[i] & 0xff;
  589. int dist = d_buf[i];
  590. if (dist-- != 0) {
  591. // if (DeflaterConstants.DEBUGGING) {
  592. // Console.Write("["+(dist+1)+","+(litlen+3)+"]: ");
  593. // }
  594. int lc = Lcode(litlen);
  595. literalTree.WriteSymbol(lc);
  596. int bits = (lc - 261) / 4;
  597. if (bits > 0 && bits <= 5) {
  598. pending.WriteBits(litlen & ((1 << bits) - 1), bits);
  599. }
  600. int dc = Dcode(dist);
  601. distTree.WriteSymbol(dc);
  602. bits = dc / 2 - 1;
  603. if (bits > 0) {
  604. pending.WriteBits(dist & ((1 << bits) - 1), bits);
  605. }
  606. } else {
  607. // if (DeflaterConstants.DEBUGGING) {
  608. // if (litlen > 32 && litlen < 127) {
  609. // Console.Write("("+(char)litlen+"): ");
  610. // } else {
  611. // Console.Write("{"+litlen+"}: ");
  612. // }
  613. // }
  614. literalTree.WriteSymbol(litlen);
  615. }
  616. }
  617. #if DebugDeflation
  618. if (DeflaterConstants.DEBUGGING) {
  619. Console.Write("EOF: ");
  620. }
  621. #endif
  622. literalTree.WriteSymbol(EOF_SYMBOL);
  623. #if DebugDeflation
  624. if (DeflaterConstants.DEBUGGING) {
  625. literalTree.CheckEmpty();
  626. distTree.CheckEmpty();
  627. }
  628. #endif
  629. }
  630. /// <summary>
  631. /// Flush block to output with no compression
  632. /// </summary>
  633. /// <param name="stored">Data to write</param>
  634. /// <param name="storedOffset">Index of first byte to write</param>
  635. /// <param name="storedLength">Count of bytes to write</param>
  636. /// <param name="lastBlock">True if this is the last block</param>
  637. public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
  638. {
  639. #if DebugDeflation
  640. // if (DeflaterConstants.DEBUGGING) {
  641. // //Console.WriteLine("Flushing stored block "+ storedLength);
  642. // }
  643. #endif
  644. pending.WriteBits((DeflaterConstants.STORED_BLOCK << 1) + (lastBlock ? 1 : 0), 3);
  645. pending.AlignToByte();
  646. pending.WriteShort(storedLength);
  647. pending.WriteShort(~storedLength);
  648. pending.WriteBlock(stored, storedOffset, storedLength);
  649. Reset();
  650. }
  651. /// <summary>
  652. /// Flush block to output with compression
  653. /// </summary>
  654. /// <param name="stored">Data to flush</param>
  655. /// <param name="storedOffset">Index of first byte to flush</param>
  656. /// <param name="storedLength">Count of bytes to flush</param>
  657. /// <param name="lastBlock">True if this is the last block</param>
  658. public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
  659. {
  660. literalTree.freqs[EOF_SYMBOL]++;
  661. // Build trees
  662. literalTree.BuildTree();
  663. distTree.BuildTree();
  664. // Calculate bitlen frequency
  665. literalTree.CalcBLFreq(blTree);
  666. distTree.CalcBLFreq(blTree);
  667. // Build bitlen tree
  668. blTree.BuildTree();
  669. int blTreeCodes = 4;
  670. for (int i = 18; i > blTreeCodes; i--) {
  671. if (blTree.length[BL_ORDER[i]] > 0) {
  672. blTreeCodes = i+1;
  673. }
  674. }
  675. int opt_len = 14 + blTreeCodes * 3 + blTree.GetEncodedLength() +
  676. literalTree.GetEncodedLength() + distTree.GetEncodedLength() +
  677. extra_bits;
  678. int static_len = extra_bits;
  679. for (int i = 0; i < LITERAL_NUM; i++) {
  680. static_len += literalTree.freqs[i] * staticLLength[i];
  681. }
  682. for (int i = 0; i < DIST_NUM; i++) {
  683. static_len += distTree.freqs[i] * staticDLength[i];
  684. }
  685. if (opt_len >= static_len) {
  686. // Force static trees
  687. opt_len = static_len;
  688. }
  689. if (storedOffset >= 0 && storedLength + 4 < opt_len >> 3) {
  690. // Store Block
  691. // if (DeflaterConstants.DEBUGGING) {
  692. // //Console.WriteLine("Storing, since " + storedLength + " < " + opt_len
  693. // + " <= " + static_len);
  694. // }
  695. FlushStoredBlock(stored, storedOffset, storedLength, lastBlock);
  696. } else if (opt_len == static_len) {
  697. // Encode with static tree
  698. pending.WriteBits((DeflaterConstants.STATIC_TREES << 1) + (lastBlock ? 1 : 0), 3);
  699. literalTree.SetStaticCodes(staticLCodes, staticLLength);
  700. distTree.SetStaticCodes(staticDCodes, staticDLength);
  701. CompressBlock();
  702. Reset();
  703. } else {
  704. // Encode with dynamic tree
  705. pending.WriteBits((DeflaterConstants.DYN_TREES << 1) + (lastBlock ? 1 : 0), 3);
  706. SendAllTrees(blTreeCodes);
  707. CompressBlock();
  708. Reset();
  709. }
  710. }
  711. /// <summary>
  712. /// Get value indicating if internal buffer is full
  713. /// </summary>
  714. /// <returns>true if buffer is full</returns>
  715. public bool IsFull()
  716. {
  717. return last_lit >= BUFSIZE;
  718. }
  719. /// <summary>
  720. /// Add literal to buffer
  721. /// </summary>
  722. /// <param name="literal">Literal value to add to buffer.</param>
  723. /// <returns>Value indicating internal buffer is full</returns>
  724. public bool TallyLit(int literal)
  725. {
  726. // if (DeflaterConstants.DEBUGGING) {
  727. // if (lit > 32 && lit < 127) {
  728. // //Console.WriteLine("("+(char)lit+")");
  729. // } else {
  730. // //Console.WriteLine("{"+lit+"}");
  731. // }
  732. // }
  733. d_buf[last_lit] = 0;
  734. l_buf[last_lit++] = (byte)literal;
  735. literalTree.freqs[literal]++;
  736. return IsFull();
  737. }
  738. /// <summary>
  739. /// Add distance code and length to literal and distance trees
  740. /// </summary>
  741. /// <param name="distance">Distance code</param>
  742. /// <param name="length">Length</param>
  743. /// <returns>Value indicating if internal buffer is full</returns>
  744. public bool TallyDist(int distance, int length)
  745. {
  746. // if (DeflaterConstants.DEBUGGING) {
  747. // //Console.WriteLine("[" + distance + "," + length + "]");
  748. // }
  749. d_buf[last_lit] = (short)distance;
  750. l_buf[last_lit++] = (byte)(length - 3);
  751. int lc = Lcode(length - 3);
  752. literalTree.freqs[lc]++;
  753. if (lc >= 265 && lc < 285) {
  754. extra_bits += (lc - 261) / 4;
  755. }
  756. int dc = Dcode(distance - 1);
  757. distTree.freqs[dc]++;
  758. if (dc >= 4) {
  759. extra_bits += dc / 2 - 1;
  760. }
  761. return IsFull();
  762. }
  763. /// <summary>
  764. /// Reverse the bits of a 16 bit value.
  765. /// </summary>
  766. /// <param name="toReverse">Value to reverse bits</param>
  767. /// <returns>Value with bits reversed</returns>
  768. // public static short BitReverse(int toReverse)
  769. // {
  770. // return (short) (bit4Reverse[toReverse & 0xF] << 12 |
  771. // bit4Reverse[(toReverse >> 4) & 0xF] << 8 |
  772. // bit4Reverse[(toReverse >> 8) & 0xF] << 4 |
  773. // bit4Reverse[toReverse >> 12]);
  774. // }
  775. //2.DeflaterHuffman��BitReverse�����޸����£�
  776. public static short BitReverse(int toReverse)
  777. {
  778. int t1 = bit4Reverse[toReverse & 0xF];
  779. int t2 = bit4Reverse[(toReverse >> 4) & 0xF];
  780. int t3 = bit4Reverse[(toReverse >> 8) & 0xF];
  781. int t4 = bit4Reverse[(toReverse >> 12) & 0xF];
  782. int t5 = t1 << 12;
  783. int t6 = t2 << 8;
  784. int t7 = t3 << 4;
  785. int t8 = t4 << 0;
  786. return (short) (t5 | t6 | t7 | t8);
  787. }
  788. static int Lcode(int length)
  789. {
  790. if (length == 255) {
  791. return 285;
  792. }
  793. int code = 257;
  794. while (length >= 8) {
  795. code += 4;
  796. length >>= 1;
  797. }
  798. return code + length;
  799. }
  800. static int Dcode(int distance)
  801. {
  802. int code = 0;
  803. while (distance >= 4) {
  804. code += 2;
  805. distance >>= 1;
  806. }
  807. return code + distance;
  808. }
  809. }
  810. }